/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * PKCS7 encoding.
 */

#include "p7local.h"

#include "cert.h"
#include "cryptohi.h"
#include "keyhi.h"
#include "secasn1.h"
#include "secoid.h"
#include "secitem.h"
#include "pk11func.h"
#include "secerr.h"
#include "sechash.h" /* for HASH_GetHashObject() */

struct sec_pkcs7_encoder_output {
    SEC_PKCS7EncoderOutputCallback outputfn;
    void *outputarg;
};

struct SEC_PKCS7EncoderContextStr {
    SEC_ASN1EncoderContext *ecx;
    SEC_PKCS7ContentInfo *cinfo;
    struct sec_pkcs7_encoder_output output;
    sec_PKCS7CipherObject *encryptobj;
    const SECHashObject *digestobj;
    void *digestcx;
};

/*
 * The little output function that the ASN.1 encoder calls to hand
 * us bytes which we in turn hand back to our caller (via the callback
 * they gave us).
 */
static void
sec_pkcs7_encoder_out(void *arg, const char *buf, unsigned long len,
                      int depth, SEC_ASN1EncodingPart data_kind)
{
    struct sec_pkcs7_encoder_output *output;

    output = (struct sec_pkcs7_encoder_output *)arg;
    output->outputfn(output->outputarg, buf, len);
}

static sec_PKCS7CipherObject *
sec_pkcs7_encoder_start_encrypt(SEC_PKCS7ContentInfo *cinfo,
                                PK11SymKey *orig_bulkkey)
{
    SECOidTag kind;
    sec_PKCS7CipherObject *encryptobj;
    SEC_PKCS7RecipientInfo **recipientinfos, *ri;
    SEC_PKCS7EncryptedContentInfo *enccinfo;
    SECKEYPublicKey *publickey = NULL;
    SECKEYPrivateKey *ourPrivKey = NULL;
    PK11SymKey *bulkkey;
    void *mark;
    int i;
    PLArenaPool *arena = NULL;

    kind = SEC_PKCS7ContentType(cinfo);
    switch (kind) {
        default:
        case SEC_OID_PKCS7_DATA:
        case SEC_OID_PKCS7_DIGESTED_DATA:
        case SEC_OID_PKCS7_SIGNED_DATA:
            recipientinfos = NULL;
            enccinfo = NULL;
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA: {
            SEC_PKCS7EncryptedData *encdp;

            /* To do EncryptedData we *must* be given a bulk key. */
            PORT_Assert(orig_bulkkey != NULL);
            if (orig_bulkkey == NULL) {
                /* XXX error? */
                return NULL;
            }

            encdp = cinfo->content.encryptedData;
            recipientinfos = NULL;
            enccinfo = &(encdp->encContentInfo);
        } break;
        case SEC_OID_PKCS7_ENVELOPED_DATA: {
            SEC_PKCS7EnvelopedData *envdp;

            envdp = cinfo->content.envelopedData;
            recipientinfos = envdp->recipientInfos;
            enccinfo = &(envdp->encContentInfo);
        } break;
        case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: {
            SEC_PKCS7SignedAndEnvelopedData *saedp;

            saedp = cinfo->content.signedAndEnvelopedData;
            recipientinfos = saedp->recipientInfos;
            enccinfo = &(saedp->encContentInfo);
        } break;
    }

    if (enccinfo == NULL)
        return NULL;

    bulkkey = orig_bulkkey;
    if (bulkkey == NULL) {
        CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(enccinfo->encalg);
        PK11SlotInfo *slot;

        slot = PK11_GetBestSlot(type, cinfo->pwfn_arg);
        if (slot == NULL) {
            return NULL;
        }
        bulkkey = PK11_KeyGen(slot, type, NULL, enccinfo->keysize / 8,
                              cinfo->pwfn_arg);
        PK11_FreeSlot(slot);
        if (bulkkey == NULL) {
            return NULL;
        }
    }

    encryptobj = NULL;
    mark = PORT_ArenaMark(cinfo->poolp);

    /*
     * Encrypt the bulk key with the public key of each recipient.
     */
    for (i = 0; recipientinfos && (ri = recipientinfos[i]) != NULL; i++) {
        CERTCertificate *cert;
        SECOidTag certalgtag, encalgtag;
        SECStatus rv;
        int data_len;
        SECItem *params = NULL;

        cert = ri->cert;
        PORT_Assert(cert != NULL);
        if (cert == NULL)
            continue;

        /*
         * XXX Want an interface that takes a cert and some data and
         * fills in an algorithmID and encrypts the data with the public
         * key from the cert.  Or, give me two interfaces -- one which
         * gets the algorithm tag from a cert (I should not have to go
         * down into the subjectPublicKeyInfo myself) and another which
         * takes a public key and algorithm tag and data and encrypts
         * the data.  Or something like that.  The point is that all
         * of the following hardwired RSA stuff should be done elsewhere.
         */

        certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));

        switch (certalgtag) {
            case SEC_OID_PKCS1_RSA_ENCRYPTION:
                encalgtag = certalgtag;
                publickey = CERT_ExtractPublicKey(cert);
                if (publickey == NULL)
                    goto loser;

                data_len = SECKEY_PublicKeyStrength(publickey);
                ri->encKey.data =
                    (unsigned char *)PORT_ArenaAlloc(cinfo->poolp, data_len);
                ri->encKey.len = data_len;
                if (ri->encKey.data == NULL)
                    goto loser;

                rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(certalgtag), publickey,
                                        bulkkey, &ri->encKey);

                SECKEY_DestroyPublicKey(publickey);
                publickey = NULL;
                if (rv != SECSuccess)
                    goto loser;
                params = NULL; /* paranoia */
                break;
            default:
                PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                goto loser;
        }

        rv = SECOID_SetAlgorithmID(cinfo->poolp, &ri->keyEncAlg, encalgtag,
                                   params);
        if (rv != SECSuccess)
            goto loser;
        if (arena)
            PORT_FreeArena(arena, PR_FALSE);
        arena = NULL;
    }

    encryptobj = sec_PKCS7CreateEncryptObject(cinfo->poolp, bulkkey,
                                              enccinfo->encalg,
                                              &(enccinfo->contentEncAlg));
    if (encryptobj != NULL) {
        PORT_ArenaUnmark(cinfo->poolp, mark);
        mark = NULL; /* good one; do not want to release */
    }
/* fallthru */

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    if (publickey) {
        SECKEY_DestroyPublicKey(publickey);
    }
    if (ourPrivKey) {
        SECKEY_DestroyPrivateKey(ourPrivKey);
    }
    if (mark != NULL) {
        PORT_ArenaRelease(cinfo->poolp, mark);
    }
    if (orig_bulkkey == NULL) {
        if (bulkkey)
            PK11_FreeSymKey(bulkkey);
    }

    return encryptobj;
}

static void
sec_pkcs7_encoder_notify(void *arg, PRBool before, void *dest, int depth)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SEC_PKCS7ContentInfo *cinfo;
    SECOidTag kind;
    PRBool before_content;

    /*
     * We want to notice just before the content field.  After fields are
     * not interesting to us.
     */
    if (!before)
        return;

    p7ecx = (SEC_PKCS7EncoderContext *)arg;
    cinfo = p7ecx->cinfo;

    before_content = PR_FALSE;

    /*
     * Watch for the content field, at which point we want to instruct
     * the ASN.1 encoder to start taking bytes from the buffer.
     *
     * XXX The following assumes the inner content type is data;
     * if/when we want to handle fully nested types, this will have
     * to recurse until reaching the innermost data content.
     */
    kind = SEC_PKCS7ContentType(cinfo);
    switch (kind) {
        default:
        case SEC_OID_PKCS7_DATA:
            if (dest == &(cinfo->content.data))
                before_content = PR_TRUE;
            break;

        case SEC_OID_PKCS7_DIGESTED_DATA: {
            SEC_PKCS7DigestedData *digd;

            digd = cinfo->content.digestedData;
            if (digd == NULL)
                break;

            if (dest == &(digd->contentInfo.content))
                before_content = PR_TRUE;
        } break;

        case SEC_OID_PKCS7_ENCRYPTED_DATA: {
            SEC_PKCS7EncryptedData *encd;

            encd = cinfo->content.encryptedData;
            if (encd == NULL)
                break;

            if (dest == &(encd->encContentInfo.encContent))
                before_content = PR_TRUE;
        } break;

        case SEC_OID_PKCS7_ENVELOPED_DATA: {
            SEC_PKCS7EnvelopedData *envd;

            envd = cinfo->content.envelopedData;
            if (envd == NULL)
                break;

            if (dest == &(envd->encContentInfo.encContent))
                before_content = PR_TRUE;
        } break;

        case SEC_OID_PKCS7_SIGNED_DATA: {
            SEC_PKCS7SignedData *sigd;

            sigd = cinfo->content.signedData;
            if (sigd == NULL)
                break;

            if (dest == &(sigd->contentInfo.content))
                before_content = PR_TRUE;
        } break;

        case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: {
            SEC_PKCS7SignedAndEnvelopedData *saed;

            saed = cinfo->content.signedAndEnvelopedData;
            if (saed == NULL)
                break;

            if (dest == &(saed->encContentInfo.encContent))
                before_content = PR_TRUE;
        } break;
    }

    if (before_content) {
        /*
         * This will cause the next SEC_ASN1EncoderUpdate to take the
         * contents bytes from the passed-in buffer.
         */
        SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
        /*
         * And that is all we needed this notify function for.
         */
        SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx);
    }
}

static SEC_PKCS7EncoderContext *
sec_pkcs7_encoder_start_contexts(SEC_PKCS7ContentInfo *cinfo,
                                 PK11SymKey *bulkkey)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SECOidTag kind;
    PRBool encrypt;
    SECItem **digests;
    SECAlgorithmID *digestalg, **digestalgs;

    p7ecx =
        (SEC_PKCS7EncoderContext *)PORT_ZAlloc(sizeof(SEC_PKCS7EncoderContext));
    if (p7ecx == NULL)
        return NULL;

    digests = NULL;
    digestalg = NULL;
    digestalgs = NULL;
    encrypt = PR_FALSE;

    kind = SEC_PKCS7ContentType(cinfo);
    switch (kind) {
        default:
        case SEC_OID_PKCS7_DATA:
            break;
        case SEC_OID_PKCS7_DIGESTED_DATA:
            digestalg = &(cinfo->content.digestedData->digestAlg);
            break;
        case SEC_OID_PKCS7_SIGNED_DATA:
            digests = cinfo->content.signedData->digests;
            digestalgs = cinfo->content.signedData->digestAlgorithms;
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            encrypt = PR_TRUE;
            break;
        case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
            digests = cinfo->content.signedAndEnvelopedData->digests;
            digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms;
            encrypt = PR_TRUE;
            break;
    }

    if (encrypt) {
        p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt(cinfo, bulkkey);
        if (p7ecx->encryptobj == NULL) {
            PORT_Free(p7ecx);
            return NULL;
        }
    }

    if (digestalgs != NULL) {
        if (digests != NULL) {
            /* digests already created (probably for detached data) */
            digestalg = NULL;
        } else {
            /*
             * XXX Some day we should handle multiple digests; for now,
             * assume only one will be done.
             */
            PORT_Assert(digestalgs[0] != NULL && digestalgs[1] == NULL);
            digestalg = digestalgs[0];
        }
    }

    if (digestalg != NULL) {
        SECOidTag oidTag = SECOID_FindOIDTag(&(digestalg->algorithm));

        p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag);
        if (p7ecx->digestobj != NULL) {
            p7ecx->digestcx = (*p7ecx->digestobj->create)();
            if (p7ecx->digestcx == NULL)
                p7ecx->digestobj = NULL;
            else
                (*p7ecx->digestobj->begin)(p7ecx->digestcx);
        }
        if (p7ecx->digestobj == NULL) {
            if (p7ecx->encryptobj != NULL)
                sec_PKCS7DestroyEncryptObject(p7ecx->encryptobj);
            PORT_Free(p7ecx);
            return NULL;
        }
    }

    p7ecx->cinfo = cinfo;
    return p7ecx;
}

SEC_PKCS7EncoderContext *
SEC_PKCS7EncoderStart(SEC_PKCS7ContentInfo *cinfo,
                      SEC_PKCS7EncoderOutputCallback outputfn,
                      void *outputarg,
                      PK11SymKey *bulkkey)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SECStatus rv;

    p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey);
    if (p7ecx == NULL)
        return NULL;

    p7ecx->output.outputfn = outputfn;
    p7ecx->output.outputarg = outputarg;

    /*
     * Initialize the BER encoder.
     */
    p7ecx->ecx = SEC_ASN1EncoderStart(cinfo, sec_PKCS7ContentInfoTemplate,
                                      sec_pkcs7_encoder_out, &(p7ecx->output));
    if (p7ecx->ecx == NULL) {
        PORT_Free(p7ecx);
        return NULL;
    }

    /*
     * Indicate that we are streaming.  We will be streaming until we
     * get past the contents bytes.
     */
    SEC_ASN1EncoderSetStreaming(p7ecx->ecx);

    /*
     * The notify function will watch for the contents field.
     */
    SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx);

    /*
     * This will encode everything up to the content bytes.  (The notify
     * function will then cause the encoding to stop there.)  Then our
     * caller can start passing contents bytes to our Update, which we
     * will pass along.
     */
    rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
    if (rv != SECSuccess) {
        PORT_Free(p7ecx);
        return NULL;
    }

    return p7ecx;
}

/*
 * XXX If/when we support nested contents, this needs to be revised.
 */
static SECStatus
sec_pkcs7_encoder_work_data(SEC_PKCS7EncoderContext *p7ecx, SECItem *dest,
                            const unsigned char *data, unsigned long len,
                            PRBool final)
{
    unsigned char *buf = NULL;
    SECStatus rv;

    rv = SECSuccess; /* may as well be optimistic */

    /*
     * We should really have data to process, or we should be trying
     * to finish/flush the last block.  (This is an overly paranoid
     * check since all callers are in this file and simple inspection
     * proves they do it right.  But it could find a bug in future
     * modifications/development, that is why it is here.)
     */
    PORT_Assert((data != NULL && len) || final);

    /*
     * Update the running digest.
     * XXX This needs modification if/when we handle multiple digests.
     */
    if (len && p7ecx->digestobj != NULL) {
        (*p7ecx->digestobj->update)(p7ecx->digestcx, data, len);
    }

    /*
     * Encrypt this chunk.
     */
    if (p7ecx->encryptobj != NULL) {
        /* XXX the following lengths should all be longs? */
        unsigned int inlen;  /* length of data being encrypted */
        unsigned int outlen; /* length of encrypted data */
        unsigned int buflen; /* length available for encrypted data */

        inlen = len;
        buflen = sec_PKCS7EncryptLength(p7ecx->encryptobj, inlen, final);
        if (buflen == 0) {
            /*
             * No output is expected, but the input data may be buffered
             * so we still have to call Encrypt.
             */
            rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, &outlen, 0,
                                  data, inlen, final);
            if (final) {
                len = 0;
                goto done;
            }
            return rv;
        }

        if (dest != NULL)
            buf = (unsigned char *)PORT_ArenaAlloc(p7ecx->cinfo->poolp, buflen);
        else
            buf = (unsigned char *)PORT_Alloc(buflen);

        if (buf == NULL) {
            rv = SECFailure;
        } else {
            rv = sec_PKCS7Encrypt(p7ecx->encryptobj, buf, &outlen, buflen,
                                  data, inlen, final);
            data = buf;
            len = outlen;
        }
        if (rv != SECSuccess) {
            if (final)
                goto done;
            return rv;
        }
    }

    if (p7ecx->ecx != NULL) {
        /*
         * Encode the contents bytes.
         */
        if (len) {
            rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len);
        }
    }

done:
    if (p7ecx->encryptobj != NULL) {
        if (final)
            sec_PKCS7DestroyEncryptObject(p7ecx->encryptobj);
        if (dest != NULL) {
            dest->data = buf;
            dest->len = len;
        } else if (buf != NULL) {
            PORT_Free(buf);
        }
    }

    if (final && p7ecx->digestobj != NULL) {
        SECItem *digest, **digests, ***digestsp;
        unsigned char *digdata;
        SECOidTag kind;

        kind = SEC_PKCS7ContentType(p7ecx->cinfo);
        switch (kind) {
            default:
                PORT_Assert(0);
                return SECFailure;
            case SEC_OID_PKCS7_DIGESTED_DATA:
                digest = &(p7ecx->cinfo->content.digestedData->digest);
                digestsp = NULL;
                break;
            case SEC_OID_PKCS7_SIGNED_DATA:
                digest = NULL;
                digestsp = &(p7ecx->cinfo->content.signedData->digests);
                break;
            case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
                digest = NULL;
                digestsp = &(p7ecx->cinfo->content.signedAndEnvelopedData->digests);
                break;
        }

        digdata = (unsigned char *)PORT_ArenaAlloc(p7ecx->cinfo->poolp,
                                                   p7ecx->digestobj->length);
        if (digdata == NULL)
            return SECFailure;

        if (digestsp != NULL) {
            PORT_Assert(digest == NULL);

            digest = (SECItem *)PORT_ArenaAlloc(p7ecx->cinfo->poolp,
                                                sizeof(SECItem));
            digests = (SECItem **)PORT_ArenaAlloc(p7ecx->cinfo->poolp,
                                                  2 * sizeof(SECItem *));
            if (digests == NULL || digest == NULL)
                return SECFailure;

            digests[0] = digest;
            digests[1] = NULL;

            *digestsp = digests;
        }

        PORT_Assert(digest != NULL);

        digest->data = digdata;
        digest->len = p7ecx->digestobj->length;

        (*p7ecx->digestobj->end)(p7ecx->digestcx, digest->data,
                                 &(digest->len), digest->len);
        (*p7ecx->digestobj->destroy)(p7ecx->digestcx, PR_TRUE);
    }

    return rv;
}

SECStatus
SEC_PKCS7EncoderUpdate(SEC_PKCS7EncoderContext *p7ecx,
                       const char *data, unsigned long len)
{
    /* XXX Error handling needs help.  Return what?  Do "Finish" on failure? */
    return sec_pkcs7_encoder_work_data(p7ecx, NULL,
                                       (const unsigned char *)data, len,
                                       PR_FALSE);
}

static SECStatus
sec_pkcs7_encoder_sig_and_certs(SEC_PKCS7ContentInfo *cinfo,
                                SECKEYGetPasswordKey pwfn, void *pwfnarg)
{
    SECOidTag kind;
    CERTCertificate **certs;
    CERTCertificateList **certlists;
    SECAlgorithmID **digestalgs;
    SECItem **digests;
    SEC_PKCS7SignerInfo *signerinfo, **signerinfos;
    SECItem **rawcerts, ***rawcertsp;
    PLArenaPool *poolp;
    int certcount;
    int ci, cli, rci, si;

    kind = SEC_PKCS7ContentType(cinfo);
    switch (kind) {
        default:
        case SEC_OID_PKCS7_DATA:
        case SEC_OID_PKCS7_DIGESTED_DATA:
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            certs = NULL;
            certlists = NULL;
            digestalgs = NULL;
            digests = NULL;
            signerinfos = NULL;
            rawcertsp = NULL;
            break;
        case SEC_OID_PKCS7_SIGNED_DATA: {
            SEC_PKCS7SignedData *sdp;

            sdp = cinfo->content.signedData;
            certs = sdp->certs;
            certlists = sdp->certLists;
            digestalgs = sdp->digestAlgorithms;
            digests = sdp->digests;
            signerinfos = sdp->signerInfos;
            rawcertsp = &(sdp->rawCerts);
        } break;
        case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: {
            SEC_PKCS7SignedAndEnvelopedData *saedp;

            saedp = cinfo->content.signedAndEnvelopedData;
            certs = saedp->certs;
            certlists = saedp->certLists;
            digestalgs = saedp->digestAlgorithms;
            digests = saedp->digests;
            signerinfos = saedp->signerInfos;
            rawcertsp = &(saedp->rawCerts);
        } break;
    }

    if (certs == NULL && certlists == NULL && signerinfos == NULL)
        return SECSuccess; /* nothing for us to do! */

    poolp = cinfo->poolp;
    certcount = 0;

    if (signerinfos != NULL) {
        SECOidTag digestalgtag;
        int di;
        SECStatus rv;
        CERTCertificate *cert;
        SECKEYPrivateKey *privkey;
        SECItem signature;
        SECOidTag signalgtag;

        PORT_Assert(digestalgs != NULL && digests != NULL);

        /*
         * If one fails, we bail right then.  If we want to continue and
         * try to do subsequent signatures, this loop, and the departures
         * from it, will need to be reworked.
         */
        for (si = 0; signerinfos[si] != NULL; si++) {

            signerinfo = signerinfos[si];

            /* find right digest */
            digestalgtag = SECOID_GetAlgorithmTag(&(signerinfo->digestAlg));
            for (di = 0; digestalgs[di] != NULL; di++) {
                /* XXX Should I be comparing more than the tag? */
                if (digestalgtag == SECOID_GetAlgorithmTag(digestalgs[di]))
                    break;
            }
            if (digestalgs[di] == NULL) {
                /* XXX oops; do what? set an error? */
                return SECFailure;
            }
            PORT_Assert(digests[di] != NULL);

            cert = signerinfo->cert;
            privkey = PK11_FindKeyByAnyCert(cert, pwfnarg);
            if (privkey == NULL)
                return SECFailure;

            /*
             * XXX I think there should be a cert-level interface for this,
             * so that I do not have to know about subjectPublicKeyInfo...
             */
            signalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));

            if (signerinfo->authAttr != NULL) {
                SEC_PKCS7Attribute *attr;
                SECItem encoded_attrs;
                SECItem *dummy;
                SECOidTag algid;

                /*
                 * First, find and fill in the message digest attribute.
                 */
                attr = sec_PKCS7FindAttribute(signerinfo->authAttr,
                                              SEC_OID_PKCS9_MESSAGE_DIGEST,
                                              PR_TRUE);
                PORT_Assert(attr != NULL);
                if (attr == NULL) {
                    SECKEY_DestroyPrivateKey(privkey);
                    return SECFailure;
                }

                /*
                 * XXX The second half of the following assertion prevents
                 * the encoder from being called twice on the same content.
                 * Either just remove the second half the assertion, or
                 * change the code to check if the value already there is
                 * the same as digests[di], whichever seems more right.
                 */
                PORT_Assert(attr->values != NULL && attr->values[0] == NULL);
                attr->values[0] = digests[di];

                /*
                 * Before encoding, reorder the attributes so that when they
                 * are encoded, they will be conforming DER, which is required
                 * to have a specific order and that is what must be used for
                 * the hash/signature.  We do this here, rather than building
                 * it into EncodeAttributes, because we do not want to do
                 * such reordering on incoming messages (which also uses
                 * EncodeAttributes) or our old signatures (and other "broken"
                 * implementations) will not verify.  So, we want to guarantee
                 * that we send out good DER encodings of attributes, but not
                 * to expect to receive them.
                 */
                rv = sec_PKCS7ReorderAttributes(signerinfo->authAttr);
                if (rv != SECSuccess) {
                    SECKEY_DestroyPrivateKey(privkey);
                    return SECFailure;
                }

                encoded_attrs.data = NULL;
                encoded_attrs.len = 0;
                dummy = sec_PKCS7EncodeAttributes(NULL, &encoded_attrs,
                                                  &(signerinfo->authAttr));
                if (dummy == NULL) {
                    SECKEY_DestroyPrivateKey(privkey);
                    return SECFailure;
                }

                algid = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
                                                        digestalgtag);
                if (algid == SEC_OID_UNKNOWN) {
                    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
                    SECKEY_DestroyPrivateKey(privkey);
                    return SECFailure;
                }
                rv = SEC_SignData(&signature,
                                  encoded_attrs.data, encoded_attrs.len,
                                  privkey,
                                  algid);
                SECITEM_FreeItem(&encoded_attrs, PR_FALSE);
            } else {
                rv = SGN_Digest(privkey, digestalgtag, &signature,
                                digests[di]);
            }

            SECKEY_DestroyPrivateKey(privkey);

            if (rv != SECSuccess)
                return rv;

            rv = SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature);
            if (rv != SECSuccess)
                return rv;

            SECITEM_FreeItem(&signature, PR_FALSE);

            rv = SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg),
                                       signalgtag, NULL);
            if (rv != SECSuccess)
                return SECFailure;

            /*
             * Count the cert chain for this signer.
             */
            if (signerinfo->certList != NULL)
                certcount += signerinfo->certList->len;
        }
    }

    if (certs != NULL) {
        for (ci = 0; certs[ci] != NULL; ci++)
            certcount++;
    }

    if (certlists != NULL) {
        for (cli = 0; certlists[cli] != NULL; cli++)
            certcount += certlists[cli]->len;
    }

    if (certcount == 0)
        return SECSuccess; /* signing done; no certs */

    /*
     * Combine all of the certs and cert chains into rawcerts.
     * Note: certcount is an upper bound; we may not need that many slots
     * but we will allocate anyway to avoid having to do another pass.
     * (The temporary space saving is not worth it.)
     */
    rawcerts = (SECItem **)PORT_ArenaAlloc(poolp,
                                           (certcount + 1) * sizeof(SECItem *));
    if (rawcerts == NULL)
        return SECFailure;

    /*
     * XXX Want to check for duplicates and not add *any* cert that is
     * already in the set.  This will be more important when we start
     * dealing with larger sets of certs, dual-key certs (signing and
     * encryption), etc.  For the time being we can slide by...
     */
    rci = 0;
    if (signerinfos != NULL) {
        for (si = 0; signerinfos[si] != NULL; si++) {
            signerinfo = signerinfos[si];
            for (ci = 0; ci < signerinfo->certList->len; ci++)
                rawcerts[rci++] = &(signerinfo->certList->certs[ci]);
        }
    }

    if (certs != NULL) {
        for (ci = 0; certs[ci] != NULL; ci++)
            rawcerts[rci++] = &(certs[ci]->derCert);
    }

    if (certlists != NULL) {
        for (cli = 0; certlists[cli] != NULL; cli++) {
            for (ci = 0; ci < certlists[cli]->len; ci++)
                rawcerts[rci++] = &(certlists[cli]->certs[ci]);
        }
    }

    rawcerts[rci] = NULL;
    *rawcertsp = rawcerts;

    return SECSuccess;
}

SECStatus
SEC_PKCS7EncoderFinish(SEC_PKCS7EncoderContext *p7ecx,
                       SECKEYGetPasswordKey pwfn, void *pwfnarg)
{
    SECStatus rv;

    /*
     * Flush out any remaining data.
     */
    rv = sec_pkcs7_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE);

    /*
     * Turn off streaming stuff.
     */
    SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
    SEC_ASN1EncoderClearStreaming(p7ecx->ecx);

    if (rv != SECSuccess)
        goto loser;

    rv = sec_pkcs7_encoder_sig_and_certs(p7ecx->cinfo, pwfn, pwfnarg);
    if (rv != SECSuccess)
        goto loser;

    rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);

loser:
    SEC_ASN1EncoderFinish(p7ecx->ecx);
    PORT_Free(p7ecx);
    return rv;
}

/*
 * Abort the ASN.1 stream. Used by pkcs 12
 */
void
SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7ecx, int error)
{
    PORT_Assert(p7ecx);
    SEC_ASN1EncoderAbort(p7ecx->ecx, error);
}

/*
 * After this routine is called, the entire PKCS7 contentInfo is ready
 * to be encoded.  This is used internally, but can also be called from
 * elsewhere for those who want to be able to just have pointers to
 * the ASN1 template for pkcs7 contentInfo built into their own encodings.
 */
SECStatus
SEC_PKCS7PrepareForEncode(SEC_PKCS7ContentInfo *cinfo,
                          PK11SymKey *bulkkey,
                          SECKEYGetPasswordKey pwfn,
                          void *pwfnarg)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SECItem *content, *enc_content;
    SECStatus rv;

    p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey);
    if (p7ecx == NULL)
        return SECFailure;

    content = SEC_PKCS7GetContent(cinfo);

    if (p7ecx->encryptobj != NULL) {
        SECOidTag kind;
        SEC_PKCS7EncryptedContentInfo *enccinfo;

        kind = SEC_PKCS7ContentType(p7ecx->cinfo);
        switch (kind) {
            default:
                PORT_Assert(0);
                rv = SECFailure;
                goto loser;
            case SEC_OID_PKCS7_ENCRYPTED_DATA:
                enccinfo = &(p7ecx->cinfo->content.encryptedData->encContentInfo);
                break;
            case SEC_OID_PKCS7_ENVELOPED_DATA:
                enccinfo = &(p7ecx->cinfo->content.envelopedData->encContentInfo);
                break;
            case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
                enccinfo = &(p7ecx->cinfo->content.signedAndEnvelopedData->encContentInfo);
                break;
        }
        enc_content = &(enccinfo->encContent);
    } else {
        enc_content = NULL;
    }

    if (content != NULL && content->data != NULL && content->len) {
        rv = sec_pkcs7_encoder_work_data(p7ecx, enc_content,
                                         content->data, content->len, PR_TRUE);
        if (rv != SECSuccess)
            goto loser;
    }

    rv = sec_pkcs7_encoder_sig_and_certs(cinfo, pwfn, pwfnarg);

loser:
    PORT_Free(p7ecx);
    return rv;
}

/*
 * Encode a PKCS7 object, in one shot.  All necessary components
 * of the object must already be specified.  Either the data has
 * already been included (via SetContent), or the data is detached,
 * or there is no data at all (certs-only).
 *
 * "cinfo" specifies the object to be encoded.
 *
 * "outputfn" is where the encoded bytes will be passed.
 *
 * "outputarg" is an opaque argument to the above callback.
 *
 * "bulkkey" specifies the bulk encryption key to use.   This argument
 * can be NULL if no encryption is being done, or if the bulk key should
 * be generated internally (usually the case for EnvelopedData but never
 * for EncryptedData, which *must* provide a bulk encryption key).
 *
 * "pwfn" is a callback for getting the password which protects the
 * private key of the signer.  This argument can be NULL if it is known
 * that no signing is going to be done.
 *
 * "pwfnarg" is an opaque argument to the above callback.
 */
SECStatus
SEC_PKCS7Encode(SEC_PKCS7ContentInfo *cinfo,
                SEC_PKCS7EncoderOutputCallback outputfn,
                void *outputarg,
                PK11SymKey *bulkkey,
                SECKEYGetPasswordKey pwfn,
                void *pwfnarg)
{
    SECStatus rv;

    rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg);
    if (rv == SECSuccess) {
        struct sec_pkcs7_encoder_output outputcx;

        outputcx.outputfn = outputfn;
        outputcx.outputarg = outputarg;

        rv = SEC_ASN1Encode(cinfo, sec_PKCS7ContentInfoTemplate,
                            sec_pkcs7_encoder_out, &outputcx);
    }

    return rv;
}

/*
 * Encode a PKCS7 object, in one shot.  All necessary components
 * of the object must already be specified.  Either the data has
 * already been included (via SetContent), or the data is detached,
 * or there is no data at all (certs-only).  The output, rather than
 * being passed to an output function as is done above, is all put
 * into a SECItem.
 *
 * "pool" specifies a pool from which to allocate the result.
 * It can be NULL, in which case memory is allocated generically.
 *
 * "dest" specifies a SECItem in which to put the result data.
 * It can be NULL, in which case the entire item is allocated, too.
 *
 * "cinfo" specifies the object to be encoded.
 *
 * "bulkkey" specifies the bulk encryption key to use.   This argument
 * can be NULL if no encryption is being done, or if the bulk key should
 * be generated internally (usually the case for EnvelopedData but never
 * for EncryptedData, which *must* provide a bulk encryption key).
 *
 * "pwfn" is a callback for getting the password which protects the
 * private key of the signer.  This argument can be NULL if it is known
 * that no signing is going to be done.
 *
 * "pwfnarg" is an opaque argument to the above callback.
 */
SECItem *
SEC_PKCS7EncodeItem(PLArenaPool *pool,
                    SECItem *dest,
                    SEC_PKCS7ContentInfo *cinfo,
                    PK11SymKey *bulkkey,
                    SECKEYGetPasswordKey pwfn,
                    void *pwfnarg)
{
    SECStatus rv;

    rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg);
    if (rv != SECSuccess)
        return NULL;

    return SEC_ASN1EncodeItem(pool, dest, cinfo, sec_PKCS7ContentInfoTemplate);
}
