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