tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

p7local.c (44906B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /*
      6 * Support routines for PKCS7 implementation, none of which are exported.
      7 * This file should only contain things that are needed by both the
      8 * encoding/creation side *and* the decoding/decryption side.  Anything
      9 * else should be static routines in the appropriate file.
     10 */
     11 
     12 #include "p7local.h"
     13 
     14 #include "cryptohi.h"
     15 #include "secasn1.h"
     16 #include "secoid.h"
     17 #include "secitem.h"
     18 #include "pk11func.h"
     19 #include "secpkcs5.h"
     20 #include "secerr.h"
     21 
     22 #include <limits.h>
     23 
     24 /*
     25 * -------------------------------------------------------------------
     26 * Cipher stuff.
     27 */
     28 
     29 typedef SECStatus (*sec_pkcs7_cipher_function)(void *,
     30                                               unsigned char *,
     31                                               unsigned *,
     32                                               unsigned int,
     33                                               const unsigned char *,
     34                                               unsigned int);
     35 typedef SECStatus (*sec_pkcs7_cipher_destroy)(void *, PRBool);
     36 
     37 static SECStatus
     38 SECPKCS7Cipher_PK11_CipherOp(void *vctx, unsigned char *output,
     39                             unsigned int *outputLen, unsigned int maxOutputLen,
     40                             const unsigned char *input, unsigned int inputLen)
     41 {
     42    PK11Context *ctx = vctx;
     43    PORT_Assert(maxOutputLen <= INT_MAX);
     44    int signedOutputLen = maxOutputLen;
     45    SECStatus rv = PK11_CipherOp(ctx, output, &signedOutputLen, maxOutputLen, input, inputLen);
     46    PORT_Assert(signedOutputLen >= 0);
     47    *outputLen = signedOutputLen;
     48    return rv;
     49 }
     50 static SECStatus
     51 SECPKCS7Cipher_PK11_DestroyContext(void *vctx, PRBool freeit)
     52 {
     53    PK11Context *ctx = vctx;
     54    PK11_DestroyContext(ctx, freeit);
     55    return SECSuccess;
     56 }
     57 
     58 #define BLOCK_SIZE 4096
     59 
     60 struct sec_pkcs7_cipher_object {
     61    void *cx;
     62    sec_pkcs7_cipher_function doit;
     63    sec_pkcs7_cipher_destroy destroy;
     64    PRBool encrypt;
     65    int block_size;
     66    int pad_size;
     67    int pending_count;
     68    unsigned char pending_buf[BLOCK_SIZE];
     69 };
     70 
     71 SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
     72 SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
     73 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
     74 SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
     75 SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
     76 
     77 /*
     78 * Create a cipher object to do decryption,  based on the given bulk
     79 * encryption key and algorithm identifier (which may include an iv).
     80 *
     81 * XXX This interface, or one similar, would be really nice available
     82 * in general...  I tried to keep the pkcs7-specific stuff (mostly
     83 * having to do with padding) out of here.
     84 *
     85 * XXX Once both are working, it might be nice to combine this and the
     86 * function below (for starting up encryption) into one routine, and just
     87 * have two simple cover functions which call it.
     88 */
     89 sec_PKCS7CipherObject *
     90 sec_PKCS7CreateDecryptObject(PK11SymKey *key, SECAlgorithmID *algid)
     91 {
     92    sec_PKCS7CipherObject *result;
     93    SECOidTag algtag;
     94    void *ciphercx;
     95    CK_MECHANISM_TYPE cryptoMechType;
     96    PK11SlotInfo *slot;
     97    SECItem *param = NULL;
     98 
     99    result = (struct sec_pkcs7_cipher_object *)
    100        PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object));
    101    if (result == NULL)
    102        return NULL;
    103 
    104    ciphercx = NULL;
    105    algtag = SECOID_GetAlgorithmTag(algid);
    106 
    107    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
    108        SECItem *pwitem;
    109 
    110        pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
    111        if (!pwitem) {
    112            PORT_Free(result);
    113            return NULL;
    114        }
    115 
    116        cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
    117        if (cryptoMechType == CKM_INVALID_MECHANISM) {
    118            PORT_Free(result);
    119            SECITEM_FreeItem(param, PR_TRUE);
    120            return NULL;
    121        }
    122    } else {
    123        cryptoMechType = PK11_AlgtagToMechanism(algtag);
    124        param = PK11_ParamFromAlgid(algid);
    125        if (param == NULL) {
    126            PORT_Free(result);
    127            return NULL;
    128        }
    129    }
    130 
    131    result->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    132    slot = PK11_GetSlotFromKey(key);
    133    result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
    134    PK11_FreeSlot(slot);
    135    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
    136                                          key, param);
    137    SECITEM_FreeItem(param, PR_TRUE);
    138    if (ciphercx == NULL) {
    139        PORT_Free(result);
    140        return NULL;
    141    }
    142 
    143    result->cx = ciphercx;
    144    result->doit = SECPKCS7Cipher_PK11_CipherOp;
    145    result->destroy = SECPKCS7Cipher_PK11_DestroyContext;
    146    result->encrypt = PR_FALSE;
    147    result->pending_count = 0;
    148 
    149    return result;
    150 }
    151 
    152 /*
    153 * Create a cipher object to do encryption, based on the given bulk
    154 * encryption key and algorithm tag.  Fill in the algorithm identifier
    155 * (which may include an iv) appropriately.
    156 *
    157 * XXX This interface, or one similar, would be really nice available
    158 * in general...  I tried to keep the pkcs7-specific stuff (mostly
    159 * having to do with padding) out of here.
    160 *
    161 * XXX Once both are working, it might be nice to combine this and the
    162 * function above (for starting up decryption) into one routine, and just
    163 * have two simple cover functions which call it.
    164 */
    165 sec_PKCS7CipherObject *
    166 sec_PKCS7CreateEncryptObject(PLArenaPool *poolp, PK11SymKey *key,
    167                             SECOidTag algtag, SECAlgorithmID *algid)
    168 {
    169    sec_PKCS7CipherObject *result;
    170    void *ciphercx;
    171    SECStatus rv;
    172    CK_MECHANISM_TYPE cryptoMechType;
    173    PK11SlotInfo *slot;
    174    SECItem *param = NULL;
    175    PRBool needToEncodeAlgid = PR_FALSE;
    176 
    177    result = (struct sec_pkcs7_cipher_object *)
    178        PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object));
    179    if (result == NULL)
    180        return NULL;
    181 
    182    ciphercx = NULL;
    183    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
    184        SECItem *pwitem;
    185 
    186        pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
    187        if (!pwitem) {
    188            PORT_Free(result);
    189            return NULL;
    190        }
    191 
    192        cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
    193        if (cryptoMechType == CKM_INVALID_MECHANISM) {
    194            PORT_Free(result);
    195            SECITEM_FreeItem(param, PR_TRUE);
    196            return NULL;
    197        }
    198    } else {
    199        cryptoMechType = PK11_AlgtagToMechanism(algtag);
    200        param = PK11_GenerateNewParam(cryptoMechType, key);
    201        if (param == NULL) {
    202            PORT_Free(result);
    203            return NULL;
    204        }
    205        needToEncodeAlgid = PR_TRUE;
    206    }
    207 
    208    result->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    209    slot = PK11_GetSlotFromKey(key);
    210    result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
    211    PK11_FreeSlot(slot);
    212    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
    213                                          key, param);
    214    if (ciphercx == NULL) {
    215        PORT_Free(result);
    216        SECITEM_FreeItem(param, PR_TRUE);
    217        return NULL;
    218    }
    219 
    220    /*
    221     * These are placed after the CreateContextBySymKey() because some
    222     * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
    223     * Don't move it from here.
    224     */
    225    if (needToEncodeAlgid) {
    226        rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
    227        if (rv != SECSuccess) {
    228            PORT_Free(result);
    229            SECITEM_FreeItem(param, PR_TRUE);
    230            PK11_DestroyContext(ciphercx, PR_TRUE);
    231            return NULL;
    232        }
    233    }
    234    SECITEM_FreeItem(param, PR_TRUE);
    235 
    236    result->cx = ciphercx;
    237    result->doit = SECPKCS7Cipher_PK11_CipherOp;
    238    result->destroy = SECPKCS7Cipher_PK11_DestroyContext;
    239    result->encrypt = PR_TRUE;
    240    result->pending_count = 0;
    241 
    242    return result;
    243 }
    244 
    245 /*
    246 * Destroy the cipher object.
    247 */
    248 static void
    249 sec_pkcs7_destroy_cipher(sec_PKCS7CipherObject *obj)
    250 {
    251    (*obj->destroy)(obj->cx, PR_TRUE);
    252    PORT_Free(obj);
    253 }
    254 
    255 void
    256 sec_PKCS7DestroyDecryptObject(sec_PKCS7CipherObject *obj)
    257 {
    258    PORT_Assert(obj != NULL);
    259    if (obj == NULL)
    260        return;
    261    PORT_Assert(!obj->encrypt);
    262    sec_pkcs7_destroy_cipher(obj);
    263 }
    264 
    265 void
    266 sec_PKCS7DestroyEncryptObject(sec_PKCS7CipherObject *obj)
    267 {
    268    PORT_Assert(obj != NULL);
    269    if (obj == NULL)
    270        return;
    271    PORT_Assert(obj->encrypt);
    272    sec_pkcs7_destroy_cipher(obj);
    273 }
    274 
    275 /*
    276 * XXX I think all of the following lengths should be longs instead
    277 * of ints, but our current crypto interface uses ints, so I did too.
    278 */
    279 
    280 /*
    281 * What will be the output length of the next call to decrypt?
    282 * Result can be used to perform memory allocations.  Note that the amount
    283 * is exactly accurate only when not doing a block cipher or when final
    284 * is false, otherwise it is an upper bound on the amount because until
    285 * we see the data we do not know how many padding bytes there are
    286 * (always between 1 and bsize).
    287 *
    288 * Note that this can return zero, which does not mean that the decrypt
    289 * operation can be skipped!  (It simply means that there are not enough
    290 * bytes to make up an entire block; the bytes will be reserved until
    291 * there are enough to encrypt/decrypt at least one block.)  However,
    292 * if zero is returned it *does* mean that no output buffer need be
    293 * passed in to the subsequent decrypt operation, as no output bytes
    294 * will be stored.
    295 */
    296 unsigned int
    297 sec_PKCS7DecryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len,
    298                       PRBool final)
    299 {
    300    int blocks, block_size;
    301 
    302    PORT_Assert(!obj->encrypt);
    303 
    304    block_size = obj->block_size;
    305 
    306    /*
    307     * If this is not a block cipher, then we always have the same
    308     * number of output bytes as we had input bytes.
    309     */
    310    if (block_size == 0)
    311        return input_len;
    312 
    313    /*
    314     * On the final call, we will always use up all of the pending
    315     * bytes plus all of the input bytes, *but*, there will be padding
    316     * at the end and we cannot predict how many bytes of padding we
    317     * will end up removing.  The amount given here is actually known
    318     * to be at least 1 byte too long (because we know we will have
    319     * at least 1 byte of padding), but seemed clearer/better to me.
    320     */
    321    if (final)
    322        return obj->pending_count + input_len;
    323 
    324    /*
    325     * Okay, this amount is exactly what we will output on the
    326     * next cipher operation.  We will always hang onto the last
    327     * 1 - block_size bytes for non-final operations.  That is,
    328     * we will do as many complete blocks as we can *except* the
    329     * last block (complete or partial).  (This is because until
    330     * we know we are at the end, we cannot know when to interpret
    331     * and removing the padding byte(s), which are guaranteed to
    332     * be there.)
    333     */
    334    blocks = (obj->pending_count + input_len - 1) / block_size;
    335    return blocks * block_size;
    336 }
    337 
    338 /*
    339 * What will be the output length of the next call to encrypt?
    340 * Result can be used to perform memory allocations.
    341 *
    342 * Note that this can return zero, which does not mean that the encrypt
    343 * operation can be skipped!  (It simply means that there are not enough
    344 * bytes to make up an entire block; the bytes will be reserved until
    345 * there are enough to encrypt/decrypt at least one block.)  However,
    346 * if zero is returned it *does* mean that no output buffer need be
    347 * passed in to the subsequent encrypt operation, as no output bytes
    348 * will be stored.
    349 */
    350 unsigned int
    351 sec_PKCS7EncryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len,
    352                       PRBool final)
    353 {
    354    int blocks, block_size;
    355    int pad_size;
    356 
    357    PORT_Assert(obj->encrypt);
    358 
    359    block_size = obj->block_size;
    360    pad_size = obj->pad_size;
    361 
    362    /*
    363     * If this is not a block cipher, then we always have the same
    364     * number of output bytes as we had input bytes.
    365     */
    366    if (block_size == 0)
    367        return input_len;
    368 
    369    /*
    370     * On the final call, we only send out what we need for
    371     * remaining bytes plus the padding.  (There is always padding,
    372     * so even if we have an exact number of blocks as input, we
    373     * will add another full block that is just padding.)
    374     */
    375    if (final) {
    376        if (pad_size == 0) {
    377            return obj->pending_count + input_len;
    378        } else {
    379            blocks = (obj->pending_count + input_len) / pad_size;
    380            blocks++;
    381            return blocks * pad_size;
    382        }
    383    }
    384 
    385    /*
    386     * Now, count the number of complete blocks of data we have.
    387     */
    388    blocks = (obj->pending_count + input_len) / block_size;
    389 
    390    return blocks * block_size;
    391 }
    392 
    393 /*
    394 * Decrypt a given length of input buffer (starting at "input" and
    395 * containing "input_len" bytes), placing the decrypted bytes in
    396 * "output" and storing the output length in "*output_len_p".
    397 * "obj" is the return value from sec_PKCS7CreateDecryptObject.
    398 * When "final" is true, this is the last of the data to be decrypted.
    399 *
    400 * This is much more complicated than it sounds when the cipher is
    401 * a block-type, meaning that the decryption function will only
    402 * operate on whole blocks.  But our caller is operating stream-wise,
    403 * and can pass in any number of bytes.  So we need to keep track
    404 * of block boundaries.  We save excess bytes between calls in "obj".
    405 * We also need to determine which bytes are padding, and remove
    406 * them from the output.  We can only do this step when we know we
    407 * have the final block of data.  PKCS #7 specifies that the padding
    408 * used for a block cipher is a string of bytes, each of whose value is
    409 * the same as the length of the padding, and that all data is padded.
    410 * (Even data that starts out with an exact multiple of blocks gets
    411 * added to it another block, all of which is padding.)
    412 */
    413 SECStatus
    414 sec_PKCS7Decrypt(sec_PKCS7CipherObject *obj, unsigned char *output,
    415                 unsigned int *output_len_p, unsigned int max_output_len,
    416                 const unsigned char *input, unsigned int input_len,
    417                 PRBool final)
    418 {
    419    unsigned int blocks, bsize, pcount, padsize;
    420    unsigned int max_needed, ifraglen, ofraglen, output_len;
    421    unsigned char *pbuf;
    422    SECStatus rv;
    423 
    424    PORT_Assert(!obj->encrypt);
    425 
    426    /*
    427     * Check that we have enough room for the output.  Our caller should
    428     * already handle this; failure is really an internal error (i.e. bug).
    429     */
    430    max_needed = sec_PKCS7DecryptLength(obj, input_len, final);
    431    PORT_Assert(max_output_len >= max_needed);
    432    if (max_output_len < max_needed) {
    433        /* PORT_SetError (XXX); */
    434        return SECFailure;
    435    }
    436 
    437    /*
    438     * hardware encryption does not like small decryption sizes here, so we
    439     * allow both blocking and padding.
    440     */
    441    bsize = obj->block_size;
    442    padsize = obj->pad_size;
    443 
    444    /*
    445     * When no blocking or padding work to do, we can simply call the
    446     * cipher function and we are done.
    447     */
    448    if (bsize == 0) {
    449        return (*obj->doit)(obj->cx, output, output_len_p, max_output_len,
    450                            input, input_len);
    451    }
    452 
    453    pcount = obj->pending_count;
    454    pbuf = obj->pending_buf;
    455 
    456    output_len = 0;
    457 
    458    if (pcount) {
    459        /*
    460         * Try to fill in an entire block, starting with the bytes
    461         * we already have saved away.
    462         */
    463        while (input_len && pcount < bsize) {
    464            pbuf[pcount++] = *input++;
    465            input_len--;
    466        }
    467        /*
    468         * If we have at most a whole block and this is not our last call,
    469         * then we are done for now.  (We do not try to decrypt a lone
    470         * single block because we cannot interpret the padding bytes
    471         * until we know we are handling the very last block of all input.)
    472         */
    473        if (input_len == 0 && !final) {
    474            obj->pending_count = pcount;
    475            if (output_len_p)
    476                *output_len_p = 0;
    477            return SECSuccess;
    478        }
    479        /*
    480         * Given the logic above, we expect to have a full block by now.
    481         * If we do not, there is something wrong, either with our own
    482         * logic or with (length of) the data given to us.
    483         */
    484        if ((padsize != 0) && (pcount % padsize) != 0) {
    485            PORT_Assert(final);
    486            PORT_SetError(SEC_ERROR_BAD_DATA);
    487            return SECFailure;
    488        }
    489        /*
    490         * Decrypt the block.
    491         */
    492        rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len,
    493                          pbuf, pcount);
    494        if (rv != SECSuccess)
    495            return rv;
    496 
    497        /*
    498         * For now anyway, all of our ciphers have the same number of
    499         * bytes of output as they do input.  If this ever becomes untrue,
    500         * then sec_PKCS7DecryptLength needs to be made smarter!
    501         */
    502        PORT_Assert(ofraglen == pcount);
    503 
    504        /*
    505         * Account for the bytes now in output.
    506         */
    507        max_output_len -= ofraglen;
    508        output_len += ofraglen;
    509        output += ofraglen;
    510    }
    511 
    512    /*
    513     * If this is our last call, we expect to have an exact number of
    514     * blocks left to be decrypted; we will decrypt them all.
    515     *
    516     * If not our last call, we always save between 1 and bsize bytes
    517     * until next time.  (We must do this because we cannot be sure
    518     * that none of the decrypted bytes are padding bytes until we
    519     * have at least another whole block of data.  You cannot tell by
    520     * looking -- the data could be anything -- you can only tell by
    521     * context, knowing you are looking at the last block.)  We could
    522     * decrypt a whole block now but it is easier if we just treat it
    523     * the same way we treat partial block bytes.
    524     */
    525    if (final) {
    526        if (padsize) {
    527            blocks = input_len / padsize;
    528            ifraglen = blocks * padsize;
    529        } else
    530            ifraglen = input_len;
    531        PORT_Assert(ifraglen == input_len);
    532 
    533        if (ifraglen != input_len) {
    534            PORT_SetError(SEC_ERROR_BAD_DATA);
    535            return SECFailure;
    536        }
    537    } else {
    538        blocks = (input_len - 1) / bsize;
    539        ifraglen = blocks * bsize;
    540        PORT_Assert(ifraglen < input_len);
    541 
    542        pcount = input_len - ifraglen;
    543        PORT_Memcpy(pbuf, input + ifraglen, pcount);
    544        obj->pending_count = pcount;
    545    }
    546 
    547    if (ifraglen) {
    548        rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len,
    549                          input, ifraglen);
    550        if (rv != SECSuccess)
    551            return rv;
    552 
    553        /*
    554         * For now anyway, all of our ciphers have the same number of
    555         * bytes of output as they do input.  If this ever becomes untrue,
    556         * then sec_PKCS7DecryptLength needs to be made smarter!
    557         */
    558        PORT_Assert(ifraglen == ofraglen);
    559        if (ifraglen != ofraglen) {
    560            PORT_SetError(SEC_ERROR_BAD_DATA);
    561            return SECFailure;
    562        }
    563 
    564        output_len += ofraglen;
    565    } else {
    566        ofraglen = 0;
    567    }
    568 
    569    /*
    570     * If we just did our very last block, "remove" the padding by
    571     * adjusting the output length.
    572     */
    573    if (final && (padsize != 0)) {
    574        unsigned int padlen = *(output + ofraglen - 1);
    575        if (padlen == 0 || padlen > padsize) {
    576            PORT_SetError(SEC_ERROR_BAD_DATA);
    577            return SECFailure;
    578        }
    579        output_len -= padlen;
    580    }
    581 
    582    PORT_Assert(output_len_p != NULL || output_len == 0);
    583    if (output_len_p != NULL)
    584        *output_len_p = output_len;
    585 
    586    return SECSuccess;
    587 }
    588 
    589 /*
    590 * Encrypt a given length of input buffer (starting at "input" and
    591 * containing "input_len" bytes), placing the encrypted bytes in
    592 * "output" and storing the output length in "*output_len_p".
    593 * "obj" is the return value from sec_PKCS7CreateEncryptObject.
    594 * When "final" is true, this is the last of the data to be encrypted.
    595 *
    596 * This is much more complicated than it sounds when the cipher is
    597 * a block-type, meaning that the encryption function will only
    598 * operate on whole blocks.  But our caller is operating stream-wise,
    599 * and can pass in any number of bytes.  So we need to keep track
    600 * of block boundaries.  We save excess bytes between calls in "obj".
    601 * We also need to add padding bytes at the end.  PKCS #7 specifies
    602 * that the padding used for a block cipher is a string of bytes,
    603 * each of whose value is the same as the length of the padding,
    604 * and that all data is padded.  (Even data that starts out with
    605 * an exact multiple of blocks gets added to it another block,
    606 * all of which is padding.)
    607 *
    608 * XXX I would kind of like to combine this with the function above
    609 * which does decryption, since they have a lot in common.  But the
    610 * tricky parts about padding and filling blocks would be much
    611 * harder to read that way, so I left them separate.  At least for
    612 * now until it is clear that they are right.
    613 */
    614 SECStatus
    615 sec_PKCS7Encrypt(sec_PKCS7CipherObject *obj, unsigned char *output,
    616                 unsigned int *output_len_p, unsigned int max_output_len,
    617                 const unsigned char *input, unsigned int input_len,
    618                 PRBool final)
    619 {
    620    int blocks, bsize, padlen, pcount, padsize;
    621    unsigned int max_needed, ifraglen, ofraglen, output_len;
    622    unsigned char *pbuf;
    623    SECStatus rv;
    624 
    625    PORT_Assert(obj->encrypt);
    626 
    627    /*
    628     * Check that we have enough room for the output.  Our caller should
    629     * already handle this; failure is really an internal error (i.e. bug).
    630     */
    631    max_needed = sec_PKCS7EncryptLength(obj, input_len, final);
    632    PORT_Assert(max_output_len >= max_needed);
    633    if (max_output_len < max_needed) {
    634        /* PORT_SetError (XXX); */
    635        return SECFailure;
    636    }
    637 
    638    bsize = obj->block_size;
    639    padsize = obj->pad_size;
    640 
    641    /*
    642     * When no blocking and padding work to do, we can simply call the
    643     * cipher function and we are done.
    644     */
    645    if (bsize == 0) {
    646        return (*obj->doit)(obj->cx, output, output_len_p, max_output_len,
    647                            input, input_len);
    648    }
    649 
    650    pcount = obj->pending_count;
    651    pbuf = obj->pending_buf;
    652 
    653    output_len = 0;
    654 
    655    if (pcount) {
    656        /*
    657         * Try to fill in an entire block, starting with the bytes
    658         * we already have saved away.
    659         */
    660        while (input_len && pcount < bsize) {
    661            pbuf[pcount++] = *input++;
    662            input_len--;
    663        }
    664        /*
    665         * If we do not have a full block and we know we will be
    666         * called again, then we are done for now.
    667         */
    668        if (pcount < bsize && !final) {
    669            obj->pending_count = pcount;
    670            if (output_len_p != NULL)
    671                *output_len_p = 0;
    672            return SECSuccess;
    673        }
    674        /*
    675         * If we have a whole block available, encrypt it.
    676         */
    677        if ((padsize == 0) || (pcount % padsize) == 0) {
    678            rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len,
    679                              pbuf, pcount);
    680            if (rv != SECSuccess)
    681                return rv;
    682 
    683            /*
    684             * For now anyway, all of our ciphers have the same number of
    685             * bytes of output as they do input.  If this ever becomes untrue,
    686             * then sec_PKCS7EncryptLength needs to be made smarter!
    687             */
    688            PORT_Assert(ofraglen == pcount);
    689 
    690            /*
    691             * Account for the bytes now in output.
    692             */
    693            max_output_len -= ofraglen;
    694            output_len += ofraglen;
    695            output += ofraglen;
    696 
    697            pcount = 0;
    698        }
    699    }
    700 
    701    if (input_len) {
    702        PORT_Assert(pcount == 0);
    703 
    704        blocks = input_len / bsize;
    705        ifraglen = blocks * bsize;
    706 
    707        if (ifraglen) {
    708            rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len,
    709                              input, ifraglen);
    710            if (rv != SECSuccess)
    711                return rv;
    712 
    713            /*
    714             * For now anyway, all of our ciphers have the same number of
    715             * bytes of output as they do input.  If this ever becomes untrue,
    716             * then sec_PKCS7EncryptLength needs to be made smarter!
    717             */
    718            PORT_Assert(ifraglen == ofraglen);
    719 
    720            max_output_len -= ofraglen;
    721            output_len += ofraglen;
    722            output += ofraglen;
    723        }
    724 
    725        pcount = input_len - ifraglen;
    726        PORT_Assert(pcount < bsize);
    727        if (pcount)
    728            PORT_Memcpy(pbuf, input + ifraglen, pcount);
    729    }
    730 
    731    if (final) {
    732        if (padsize) {
    733            padlen = padsize - (pcount % padsize);
    734            PORT_Memset(pbuf + pcount, padlen, padlen);
    735        } else {
    736            padlen = 0;
    737        }
    738        rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len,
    739                          pbuf, pcount + padlen);
    740        if (rv != SECSuccess)
    741            return rv;
    742 
    743        /*
    744         * For now anyway, all of our ciphers have the same number of
    745         * bytes of output as they do input.  If this ever becomes untrue,
    746         * then sec_PKCS7EncryptLength needs to be made smarter!
    747         */
    748        PORT_Assert(ofraglen == (pcount + padlen));
    749        output_len += ofraglen;
    750    } else {
    751        obj->pending_count = pcount;
    752    }
    753 
    754    PORT_Assert(output_len_p != NULL || output_len == 0);
    755    if (output_len_p != NULL)
    756        *output_len_p = output_len;
    757 
    758    return SECSuccess;
    759 }
    760 
    761 /*
    762 * End of cipher stuff.
    763 * -------------------------------------------------------------------
    764 */
    765 
    766 /*
    767 * -------------------------------------------------------------------
    768 * XXX The following Attribute stuff really belongs elsewhere.
    769 * The Attribute type is *not* part of pkcs7 but rather X.501.
    770 * But for now, since PKCS7 is the only customer of attributes,
    771 * we define them here.  Once there is a use outside of PKCS7,
    772 * then change the attribute types and functions from internal
    773 * to external naming convention, and move them elsewhere!
    774 */
    775 
    776 /*
    777 * Look through a set of attributes and find one that matches the
    778 * specified object ID.  If "only" is true, then make sure that
    779 * there is not more than one attribute of the same type.  Otherwise,
    780 * just return the first one found. (XXX Does anybody really want
    781 * that first-found behavior?  It was like that when I found it...)
    782 */
    783 SEC_PKCS7Attribute *
    784 sec_PKCS7FindAttribute(SEC_PKCS7Attribute **attrs, SECOidTag oidtag,
    785                       PRBool only)
    786 {
    787    SECOidData *oid;
    788    SEC_PKCS7Attribute *attr1, *attr2;
    789 
    790    if (attrs == NULL)
    791        return NULL;
    792 
    793    oid = SECOID_FindOIDByTag(oidtag);
    794    if (oid == NULL)
    795        return NULL;
    796 
    797    while ((attr1 = *attrs++) != NULL) {
    798        if (attr1->type.len == oid->oid.len && PORT_Memcmp(attr1->type.data, oid->oid.data, oid->oid.len) == 0)
    799            break;
    800    }
    801 
    802    if (attr1 == NULL)
    803        return NULL;
    804 
    805    if (!only)
    806        return attr1;
    807 
    808    while ((attr2 = *attrs++) != NULL) {
    809        if (attr2->type.len == oid->oid.len && PORT_Memcmp(attr2->type.data, oid->oid.data, oid->oid.len) == 0)
    810            break;
    811    }
    812 
    813    if (attr2 != NULL)
    814        return NULL;
    815 
    816    return attr1;
    817 }
    818 
    819 /*
    820 * Return the single attribute value, doing some sanity checking first:
    821 * - Multiple values are *not* expected.
    822 * - Empty values are *not* expected.
    823 */
    824 SECItem *
    825 sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr)
    826 {
    827    SECItem *value;
    828 
    829    if (attr == NULL)
    830        return NULL;
    831 
    832    value = attr->values[0];
    833 
    834    if (value == NULL || value->data == NULL || value->len == 0)
    835        return NULL;
    836 
    837    if (attr->values[1] != NULL)
    838        return NULL;
    839 
    840    return value;
    841 }
    842 
    843 static const SEC_ASN1Template *
    844 sec_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
    845 {
    846    const SEC_ASN1Template *theTemplate;
    847 
    848    SEC_PKCS7Attribute *attribute;
    849    SECOidData *oiddata;
    850    PRBool encoded;
    851 
    852    PORT_Assert(src_or_dest != NULL);
    853    if (src_or_dest == NULL)
    854        return NULL;
    855 
    856    attribute = (SEC_PKCS7Attribute *)src_or_dest;
    857 
    858    if (encoding && attribute->encoded)
    859        return SEC_ASN1_GET(SEC_AnyTemplate);
    860 
    861    oiddata = attribute->typeTag;
    862    if (oiddata == NULL) {
    863        oiddata = SECOID_FindOID(&attribute->type);
    864        attribute->typeTag = oiddata;
    865    }
    866 
    867    if (oiddata == NULL) {
    868        encoded = PR_TRUE;
    869        theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
    870    } else {
    871        switch (oiddata->offset) {
    872            default:
    873                encoded = PR_TRUE;
    874                theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
    875                break;
    876            case SEC_OID_PKCS9_EMAIL_ADDRESS:
    877            case SEC_OID_RFC1274_MAIL:
    878            case SEC_OID_PKCS9_UNSTRUCTURED_NAME:
    879                encoded = PR_FALSE;
    880                theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
    881                break;
    882            case SEC_OID_PKCS9_CONTENT_TYPE:
    883                encoded = PR_FALSE;
    884                theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate);
    885                break;
    886            case SEC_OID_PKCS9_MESSAGE_DIGEST:
    887                encoded = PR_FALSE;
    888                theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
    889                break;
    890            case SEC_OID_PKCS9_SIGNING_TIME:
    891                encoded = PR_FALSE;
    892                theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate);
    893                break;
    894                /* XXX Want other types here, too */
    895        }
    896    }
    897 
    898    if (encoding) {
    899        /*
    900         * If we are encoding and we think we have an already-encoded value,
    901         * then the code which initialized this attribute should have set
    902         * the "encoded" property to true (and we would have returned early,
    903         * up above).  No devastating error, but that code should be fixed.
    904         * (It could indicate that the resulting encoded bytes are wrong.)
    905         */
    906        PORT_Assert(!encoded);
    907    } else {
    908        /*
    909         * We are decoding; record whether the resulting value is
    910         * still encoded or not.
    911         */
    912        attribute->encoded = encoded;
    913    }
    914    return theTemplate;
    915 }
    916 
    917 static const SEC_ASN1TemplateChooserPtr sec_attr_chooser = sec_attr_choose_attr_value_template;
    918 
    919 static const SEC_ASN1Template sec_pkcs7_attribute_template[] = {
    920    { SEC_ASN1_SEQUENCE,
    921      0, NULL, sizeof(SEC_PKCS7Attribute) },
    922    { SEC_ASN1_OBJECT_ID,
    923      offsetof(SEC_PKCS7Attribute, type) },
    924    { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,
    925      offsetof(SEC_PKCS7Attribute, values),
    926      &sec_attr_chooser },
    927    { 0 }
    928 };
    929 
    930 static const SEC_ASN1Template sec_pkcs7_set_of_attribute_template[] = {
    931    { SEC_ASN1_SET_OF, 0, sec_pkcs7_attribute_template },
    932 };
    933 
    934 /*
    935 * If you are wondering why this routine does not reorder the attributes
    936 * first, and might be tempted to make it do so, see the comment by the
    937 * call to ReorderAttributes in p7encode.c.  (Or, see who else calls this
    938 * and think long and hard about the implications of making it always
    939 * do the reordering.)
    940 */
    941 SECItem *
    942 sec_PKCS7EncodeAttributes(PLArenaPool *poolp, SECItem *dest, void *src)
    943 {
    944    return SEC_ASN1EncodeItem(poolp, dest, src,
    945                              sec_pkcs7_set_of_attribute_template);
    946 }
    947 
    948 /*
    949 * Make sure that the order of the attributes guarantees valid DER
    950 * (which must be in lexigraphically ascending order for a SET OF);
    951 * if reordering is necessary it will be done in place (in attrs).
    952 */
    953 SECStatus
    954 sec_PKCS7ReorderAttributes(SEC_PKCS7Attribute **attrs)
    955 {
    956    PLArenaPool *poolp;
    957    int num_attrs, i, pass, besti;
    958    unsigned int j;
    959    SECItem **enc_attrs;
    960    SEC_PKCS7Attribute **new_attrs;
    961 
    962    /*
    963     * I think we should not be called with NULL.  But if we are,
    964     * call it a success anyway, because the order *is* okay.
    965     */
    966    PORT_Assert(attrs != NULL);
    967    if (attrs == NULL)
    968        return SECSuccess;
    969 
    970    /*
    971     * Count how many attributes we are dealing with here.
    972     */
    973    num_attrs = 0;
    974    while (attrs[num_attrs] != NULL)
    975        num_attrs++;
    976 
    977    /*
    978     * Again, I think we should have some attributes here.
    979     * But if we do not, or if there is only one, then call it
    980     * a success because it also already has a fine order.
    981     */
    982    PORT_Assert(num_attrs);
    983    if (num_attrs == 0 || num_attrs == 1)
    984        return SECSuccess;
    985 
    986    /*
    987     * Allocate an arena for us to work with, so it is easy to
    988     * clean up all of the memory (fairly small pieces, really).
    989     */
    990    poolp = PORT_NewArena(1024); /* XXX what is right value? */
    991    if (poolp == NULL)
    992        return SECFailure; /* no memory; nothing we can do... */
    993 
    994    /*
    995     * Allocate arrays to hold the individual encodings which we will use
    996     * for comparisons and the reordered attributes as they are sorted.
    997     */
    998    enc_attrs = (SECItem **)PORT_ArenaZAlloc(poolp, num_attrs * sizeof(SECItem *));
    999    new_attrs = (SEC_PKCS7Attribute **)PORT_ArenaZAlloc(poolp,
   1000                                                        num_attrs * sizeof(SEC_PKCS7Attribute *));
   1001    if (enc_attrs == NULL || new_attrs == NULL) {
   1002        PORT_FreeArena(poolp, PR_FALSE);
   1003        return SECFailure;
   1004    }
   1005 
   1006    /*
   1007     * DER encode each individual attribute.
   1008     */
   1009    for (i = 0; i < num_attrs; i++) {
   1010        enc_attrs[i] = SEC_ASN1EncodeItem(poolp, NULL, attrs[i],
   1011                                          sec_pkcs7_attribute_template);
   1012        if (enc_attrs[i] == NULL) {
   1013            PORT_FreeArena(poolp, PR_FALSE);
   1014            return SECFailure;
   1015        }
   1016    }
   1017 
   1018    /*
   1019     * Now compare and sort them; this is not the most efficient sorting
   1020     * method, but it is just fine for the problem at hand, because the
   1021     * number of attributes is (always) going to be small.
   1022     */
   1023    for (pass = 0; pass < num_attrs; pass++) {
   1024        /*
   1025         * Find the first not-yet-accepted attribute.  (Once one is
   1026         * sorted into the other array, it is cleared from enc_attrs.)
   1027         */
   1028        for (i = 0; i < num_attrs; i++) {
   1029            if (enc_attrs[i] != NULL)
   1030                break;
   1031        }
   1032        PORT_Assert(i < num_attrs);
   1033        besti = i;
   1034 
   1035        /*
   1036         * Find the lowest (lexigraphically) encoding.  One that is
   1037         * shorter than all the rest is known to be "less" because each
   1038         * attribute is of the same type (a SEQUENCE) and so thus the
   1039         * first octet of each is the same, and the second octet is
   1040         * the length (or the length of the length with the high bit
   1041         * set, followed by the length, which also works out to always
   1042         * order the shorter first).  Two (or more) that have the
   1043         * same length need to be compared byte by byte until a mismatch
   1044         * is found.
   1045         */
   1046        for (i = besti + 1; i < num_attrs; i++) {
   1047            if (enc_attrs[i] == NULL) /* slot already handled */
   1048                continue;
   1049 
   1050            if (enc_attrs[i]->len != enc_attrs[besti]->len) {
   1051                if (enc_attrs[i]->len < enc_attrs[besti]->len)
   1052                    besti = i;
   1053                continue;
   1054            }
   1055 
   1056            for (j = 0; j < enc_attrs[i]->len; j++) {
   1057                if (enc_attrs[i]->data[j] < enc_attrs[besti]->data[j]) {
   1058                    besti = i;
   1059                    break;
   1060                }
   1061            }
   1062 
   1063            /*
   1064             * For this not to be true, we would have to have encountered
   1065             * two *identical* attributes, which I think we should not see.
   1066             * So assert if it happens, but even if it does, let it go
   1067             * through; the ordering of the two does not matter.
   1068             */
   1069            PORT_Assert(j < enc_attrs[i]->len);
   1070        }
   1071 
   1072        /*
   1073         * Now we have found the next-lowest one; copy it over and
   1074         * remove it from enc_attrs.
   1075         */
   1076        new_attrs[pass] = attrs[besti];
   1077        enc_attrs[besti] = NULL;
   1078    }
   1079 
   1080    /*
   1081     * Now new_attrs has the attributes in the order we want;
   1082     * copy them back into the attrs array we started with.
   1083     */
   1084    for (i = 0; i < num_attrs; i++)
   1085        attrs[i] = new_attrs[i];
   1086 
   1087    PORT_FreeArena(poolp, PR_FALSE);
   1088    return SECSuccess;
   1089 }
   1090 
   1091 /*
   1092 * End of attribute stuff.
   1093 * -------------------------------------------------------------------
   1094 */
   1095 
   1096 /*
   1097 * Templates and stuff.  Keep these at the end of the file.
   1098 */
   1099 
   1100 /* forward declaration */
   1101 static const SEC_ASN1Template *
   1102 sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding);
   1103 
   1104 static const SEC_ASN1TemplateChooserPtr sec_pkcs7_chooser = sec_pkcs7_choose_content_template;
   1105 
   1106 const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[] = {
   1107    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1108      0, NULL, sizeof(SEC_PKCS7ContentInfo) },
   1109    { SEC_ASN1_OBJECT_ID,
   1110      offsetof(SEC_PKCS7ContentInfo, contentType) },
   1111    { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
   1112      offsetof(SEC_PKCS7ContentInfo, content),
   1113      &sec_pkcs7_chooser },
   1114    { 0 }
   1115 };
   1116 
   1117 /* XXX These names should change from external to internal convention. */
   1118 
   1119 static const SEC_ASN1Template SEC_PKCS7SignerInfoTemplate[] = {
   1120    { SEC_ASN1_SEQUENCE,
   1121      0, NULL, sizeof(SEC_PKCS7SignerInfo) },
   1122    { SEC_ASN1_INTEGER,
   1123      offsetof(SEC_PKCS7SignerInfo, version) },
   1124    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
   1125      offsetof(SEC_PKCS7SignerInfo, issuerAndSN),
   1126      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
   1127    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
   1128      offsetof(SEC_PKCS7SignerInfo, digestAlg),
   1129      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1130    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
   1131      offsetof(SEC_PKCS7SignerInfo, authAttr),
   1132      sec_pkcs7_set_of_attribute_template },
   1133    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
   1134      offsetof(SEC_PKCS7SignerInfo, digestEncAlg),
   1135      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1136    { SEC_ASN1_OCTET_STRING,
   1137      offsetof(SEC_PKCS7SignerInfo, encDigest) },
   1138    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
   1139      offsetof(SEC_PKCS7SignerInfo, unAuthAttr),
   1140      sec_pkcs7_set_of_attribute_template },
   1141    { 0 }
   1142 };
   1143 
   1144 static const SEC_ASN1Template SEC_PKCS7SignedDataTemplate[] = {
   1145    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1146      0, NULL, sizeof(SEC_PKCS7SignedData) },
   1147    { SEC_ASN1_INTEGER,
   1148      offsetof(SEC_PKCS7SignedData, version) },
   1149    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
   1150      offsetof(SEC_PKCS7SignedData, digestAlgorithms),
   1151      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1152    { SEC_ASN1_INLINE,
   1153      offsetof(SEC_PKCS7SignedData, contentInfo),
   1154      sec_PKCS7ContentInfoTemplate },
   1155    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   1156          SEC_ASN1_XTRN | 0,
   1157      offsetof(SEC_PKCS7SignedData, rawCerts),
   1158      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
   1159    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   1160          SEC_ASN1_XTRN | 1,
   1161      offsetof(SEC_PKCS7SignedData, crls),
   1162      SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
   1163    { SEC_ASN1_SET_OF,
   1164      offsetof(SEC_PKCS7SignedData, signerInfos),
   1165      SEC_PKCS7SignerInfoTemplate },
   1166    { 0 }
   1167 };
   1168 
   1169 static const SEC_ASN1Template SEC_PointerToPKCS7SignedDataTemplate[] = {
   1170    { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedDataTemplate }
   1171 };
   1172 
   1173 static const SEC_ASN1Template SEC_PKCS7RecipientInfoTemplate[] = {
   1174    { SEC_ASN1_SEQUENCE,
   1175      0, NULL, sizeof(SEC_PKCS7RecipientInfo) },
   1176    { SEC_ASN1_INTEGER,
   1177      offsetof(SEC_PKCS7RecipientInfo, version) },
   1178    { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
   1179      offsetof(SEC_PKCS7RecipientInfo, issuerAndSN),
   1180      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
   1181    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
   1182      offsetof(SEC_PKCS7RecipientInfo, keyEncAlg),
   1183      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1184    { SEC_ASN1_OCTET_STRING,
   1185      offsetof(SEC_PKCS7RecipientInfo, encKey) },
   1186    { 0 }
   1187 };
   1188 
   1189 static const SEC_ASN1Template SEC_PKCS7EncryptedContentInfoTemplate[] = {
   1190    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1191      0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) },
   1192    { SEC_ASN1_OBJECT_ID,
   1193      offsetof(SEC_PKCS7EncryptedContentInfo, contentType) },
   1194    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
   1195      offsetof(SEC_PKCS7EncryptedContentInfo, contentEncAlg),
   1196      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1197    { SEC_ASN1_OPTIONAL | SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC |
   1198          SEC_ASN1_XTRN | 0,
   1199      offsetof(SEC_PKCS7EncryptedContentInfo, encContent),
   1200      SEC_ASN1_SUB(SEC_OctetStringTemplate) },
   1201    { 0 }
   1202 };
   1203 
   1204 static const SEC_ASN1Template SEC_PKCS7EnvelopedDataTemplate[] = {
   1205    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1206      0, NULL, sizeof(SEC_PKCS7EnvelopedData) },
   1207    { SEC_ASN1_INTEGER,
   1208      offsetof(SEC_PKCS7EnvelopedData, version) },
   1209    { SEC_ASN1_SET_OF,
   1210      offsetof(SEC_PKCS7EnvelopedData, recipientInfos),
   1211      SEC_PKCS7RecipientInfoTemplate },
   1212    { SEC_ASN1_INLINE,
   1213      offsetof(SEC_PKCS7EnvelopedData, encContentInfo),
   1214      SEC_PKCS7EncryptedContentInfoTemplate },
   1215    { 0 }
   1216 };
   1217 
   1218 static const SEC_ASN1Template SEC_PointerToPKCS7EnvelopedDataTemplate[] = {
   1219    { SEC_ASN1_POINTER, 0, SEC_PKCS7EnvelopedDataTemplate }
   1220 };
   1221 
   1222 static const SEC_ASN1Template SEC_PKCS7SignedAndEnvelopedDataTemplate[] = {
   1223    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1224      0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) },
   1225    { SEC_ASN1_INTEGER,
   1226      offsetof(SEC_PKCS7SignedAndEnvelopedData, version) },
   1227    { SEC_ASN1_SET_OF,
   1228      offsetof(SEC_PKCS7SignedAndEnvelopedData, recipientInfos),
   1229      SEC_PKCS7RecipientInfoTemplate },
   1230    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
   1231      offsetof(SEC_PKCS7SignedAndEnvelopedData, digestAlgorithms),
   1232      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1233    { SEC_ASN1_INLINE,
   1234      offsetof(SEC_PKCS7SignedAndEnvelopedData, encContentInfo),
   1235      SEC_PKCS7EncryptedContentInfoTemplate },
   1236    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   1237          SEC_ASN1_XTRN | 0,
   1238      offsetof(SEC_PKCS7SignedAndEnvelopedData, rawCerts),
   1239      SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
   1240    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   1241          SEC_ASN1_XTRN | 1,
   1242      offsetof(SEC_PKCS7SignedAndEnvelopedData, crls),
   1243      SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
   1244    { SEC_ASN1_SET_OF,
   1245      offsetof(SEC_PKCS7SignedAndEnvelopedData, signerInfos),
   1246      SEC_PKCS7SignerInfoTemplate },
   1247    { 0 }
   1248 };
   1249 
   1250 static const SEC_ASN1Template
   1251    SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate[] = {
   1252        { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedAndEnvelopedDataTemplate }
   1253    };
   1254 
   1255 static const SEC_ASN1Template SEC_PKCS7DigestedDataTemplate[] = {
   1256    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1257      0, NULL, sizeof(SEC_PKCS7DigestedData) },
   1258    { SEC_ASN1_INTEGER,
   1259      offsetof(SEC_PKCS7DigestedData, version) },
   1260    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
   1261      offsetof(SEC_PKCS7DigestedData, digestAlg),
   1262      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
   1263    { SEC_ASN1_INLINE,
   1264      offsetof(SEC_PKCS7DigestedData, contentInfo),
   1265      sec_PKCS7ContentInfoTemplate },
   1266    { SEC_ASN1_OCTET_STRING,
   1267      offsetof(SEC_PKCS7DigestedData, digest) },
   1268    { 0 }
   1269 };
   1270 
   1271 static const SEC_ASN1Template SEC_PointerToPKCS7DigestedDataTemplate[] = {
   1272    { SEC_ASN1_POINTER, 0, SEC_PKCS7DigestedDataTemplate }
   1273 };
   1274 
   1275 static const SEC_ASN1Template SEC_PKCS7EncryptedDataTemplate[] = {
   1276    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
   1277      0, NULL, sizeof(SEC_PKCS7EncryptedData) },
   1278    { SEC_ASN1_INTEGER,
   1279      offsetof(SEC_PKCS7EncryptedData, version) },
   1280    { SEC_ASN1_INLINE,
   1281      offsetof(SEC_PKCS7EncryptedData, encContentInfo),
   1282      SEC_PKCS7EncryptedContentInfoTemplate },
   1283    { 0 }
   1284 };
   1285 
   1286 static const SEC_ASN1Template SEC_PointerToPKCS7EncryptedDataTemplate[] = {
   1287    { SEC_ASN1_POINTER, 0, SEC_PKCS7EncryptedDataTemplate }
   1288 };
   1289 
   1290 static const SEC_ASN1Template *
   1291 sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding)
   1292 {
   1293    const SEC_ASN1Template *theTemplate;
   1294    SEC_PKCS7ContentInfo *cinfo;
   1295    SECOidTag kind;
   1296 
   1297    if (src_or_dest == NULL)
   1298        return NULL;
   1299 
   1300    cinfo = (SEC_PKCS7ContentInfo *)src_or_dest;
   1301    kind = SEC_PKCS7ContentType(cinfo);
   1302    switch (kind) {
   1303        default:
   1304            theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
   1305            break;
   1306        case SEC_OID_PKCS7_DATA:
   1307            theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
   1308            break;
   1309        case SEC_OID_PKCS7_SIGNED_DATA:
   1310            theTemplate = SEC_PointerToPKCS7SignedDataTemplate;
   1311            break;
   1312        case SEC_OID_PKCS7_ENVELOPED_DATA:
   1313            theTemplate = SEC_PointerToPKCS7EnvelopedDataTemplate;
   1314            break;
   1315        case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
   1316            theTemplate = SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate;
   1317            break;
   1318        case SEC_OID_PKCS7_DIGESTED_DATA:
   1319            theTemplate = SEC_PointerToPKCS7DigestedDataTemplate;
   1320            break;
   1321        case SEC_OID_PKCS7_ENCRYPTED_DATA:
   1322            theTemplate = SEC_PointerToPKCS7EncryptedDataTemplate;
   1323            break;
   1324    }
   1325    return theTemplate;
   1326 }
   1327 
   1328 /*
   1329 * End of templates.  Do not add stuff after this; put new code
   1330 * up above the start of the template definitions.
   1331 */