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  * Header for CMS types.
7  */
8 
9 #ifndef _CMST_H_
10 #define _CMST_H_
11 
12 #include "seccomon.h"
13 #include "secoidt.h"
14 #include "certt.h"
15 #include "secmodt.h"
16 #include "secmodt.h"
17 
18 #include "plarena.h"
19 
20 /* Non-opaque objects.  NOTE, though: I want them to be treated as
21  * opaque as much as possible.  If I could hide them completely,
22  * I would.  (I tried, but ran into trouble that was taking me too
23  * much time to get out of.)  I still intend to try to do so.
24  * In fact, the only type that "outsiders" should even *name* is
25  * NSSCMSMessage, and they should not reference its fields.
26  */
27 /* rjr: PKCS #11 cert handling (pk11cert.c) does use NSSCMSRecipientInfo's.
28  * This is because when we search the recipient list for the cert and key we
29  * want, we need to invert the order of the loops we used to have. The old
30  * loops were:
31  *
32  *  For each recipient {
33  *       find_cert = PK11_Find_AllCert(recipient->issuerSN);
34  *       [which unrolls to... ]
35  *       For each slot {
36  *            Log into slot;
37  *            search slot for cert;
38  *      }
39  *  }
40  *
41  *  the new loop searchs all the recipients at once on a slot. this allows
42  *  PKCS #11 to order slots in such a way that logout slots don't get checked
43  *  if we can find the cert on a logged in slot. This eliminates lots of
44  *  spurious password prompts when smart cards are installed... so why this
45  *  comment? If you make NSSCMSRecipientInfo completely opaque, you need
46  *  to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
47  *  and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
48  *  function.
49  */
50 
51 typedef struct NSSCMSMessageStr NSSCMSMessage;
52 
53 typedef union NSSCMSContentUnion NSSCMSContent;
54 typedef struct NSSCMSContentInfoStr NSSCMSContentInfo;
55 
56 typedef struct NSSCMSSignedDataStr NSSCMSSignedData;
57 typedef struct NSSCMSSignerInfoStr NSSCMSSignerInfo;
58 typedef struct NSSCMSSignerIdentifierStr NSSCMSSignerIdentifier;
59 
60 typedef struct NSSCMSEnvelopedDataStr NSSCMSEnvelopedData;
61 typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo;
62 typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo;
63 
64 typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData;
65 typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData;
66 
67 typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData;
68 
69 typedef struct NSSCMSAttributeStr NSSCMSAttribute;
70 
71 typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext;
72 typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext;
73 
74 typedef struct NSSCMSCipherContextStr NSSCMSCipherContext;
75 typedef struct NSSCMSDigestContextStr NSSCMSDigestContext;
76 
77 typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate;
78 
79 typedef SECStatus (*NSSCMSGenericWrapperDataCallback)(NSSCMSGenericWrapperData *);
80 typedef void (*NSSCMSGenericWrapperDataDestroy)(NSSCMSGenericWrapperData *);
81 
82 extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[];
83 extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[];
84 
85 SEC_ASN1_CHOOSER_DECLARE(NSS_PointerToCMSGenericWrapperDataTemplate)
86 SEC_ASN1_CHOOSER_DECLARE(NSSCMSGenericWrapperDataTemplate)
87 
88 /*
89  * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart.
90  * If specified, this is where the content bytes (only) will be "sent"
91  * as they are recovered during the decoding.
92  * And:
93  * Type of function passed to NSSCMSEncode or NSSCMSEncoderStart.
94  * This is where the DER-encoded bytes will be "sent".
95  *
96  * XXX Should just combine this with NSSCMSEncoderContentCallback type
97  * and use a simpler, common name.
98  */
99 typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len);
100 
101 /*
102  * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart
103  * to retrieve the decryption key.  This function is intended to be
104  * used for EncryptedData content info's which do not have a key available
105  * in a certificate, etc.
106  */
107 typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
108 
109 /* =============================================================================
110  * ENCAPSULATED CONTENTINFO & CONTENTINFO
111  */
112 
113 union NSSCMSContentUnion {
114     /* either unstructured */
115     SECItem *data;
116     /* or structured data */
117     NSSCMSDigestedData *digestedData;
118     NSSCMSEncryptedData *encryptedData;
119     NSSCMSEnvelopedData *envelopedData;
120     NSSCMSSignedData *signedData;
121     NSSCMSGenericWrapperData *genericData;
122     /* or anonymous pointer to something */
123     void *pointer;
124 };
125 
126 struct NSSCMSContentInfoStr {
127     SECItem contentType;
128     NSSCMSContent content;
129     /* --------- local; not part of encoding --------- */
130     SECOidData *contentTypeTag;
131 
132     /* additional info for encryptedData and envelopedData */
133     /* we waste this space for signedData and digestedData. sue me. */
134 
135     SECAlgorithmID contentEncAlg;
136     SECItem *rawContent; /* encrypted DER, optional */
137                          /* XXXX bytes not encrypted, but encoded? */
138     /* --------- local; not part of encoding --------- */
139     PK11SymKey *bulkkey;                   /* bulk encryption key */
140     int keysize;                           /* size of bulk encryption key
141                                            * (only used by creation code) */
142     SECOidTag contentEncAlgTag;            /* oid tag of encryption algorithm
143                                            * (only used by creation code) */
144     NSSCMSContentInfoPrivate *privateInfo; /* place for NSS private info */
145     void *reserved;                        /* keep binary compatibility */
146 };
147 
148 /* =============================================================================
149  * MESSAGE
150  */
151 
152 struct NSSCMSMessageStr {
153     NSSCMSContentInfo contentInfo; /* "outer" cinfo */
154     /* --------- local; not part of encoding --------- */
155     PLArenaPool *poolp;
156     PRBool poolp_is_ours;
157     int refCount;
158     /* properties of the "inner" data */
159     SECAlgorithmID **detached_digestalgs;
160     SECItem **detached_digests;
161     void *pwfn_arg;
162     NSSCMSGetDecryptKeyCallback decrypt_key_cb;
163     void *decrypt_key_cb_arg;
164 };
165 
166 /* ============================================================================
167  * GENERIC WRAPPER
168  *
169  * used for user defined types.
170  */
171 struct NSSCMSGenericWrapperDataStr {
172     NSSCMSContentInfo contentInfo;
173     /* ---- local; not part of encoding ------ */
174     NSSCMSMessage *cmsg;
175     /* wrapperspecific data starts here */
176 };
177 
178 /* =============================================================================
179  * SIGNEDDATA
180  */
181 
182 struct NSSCMSSignedDataStr {
183     SECItem version;
184     SECAlgorithmID **digestAlgorithms;
185     NSSCMSContentInfo contentInfo;
186     SECItem **rawCerts;
187     CERTSignedCrl **crls;
188     NSSCMSSignerInfo **signerInfos;
189     /* --------- local; not part of encoding --------- */
190     NSSCMSMessage *cmsg; /* back pointer to message */
191     SECItem **digests;
192     CERTCertificate **certs;
193     CERTCertificateList **certLists;
194     CERTCertificate **tempCerts; /* temporary certs, needed
195                                   * for example for signature
196                                   * verification */
197 };
198 #define NSS_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */
199 #define NSS_CMS_SIGNED_DATA_VERSION_EXT 3   /* what we *create* */
200 
201 typedef enum {
202     NSSCMSVS_Unverified = 0,
203     NSSCMSVS_GoodSignature = 1,
204     NSSCMSVS_BadSignature = 2,
205     NSSCMSVS_DigestMismatch = 3,
206     NSSCMSVS_SigningCertNotFound = 4,
207     NSSCMSVS_SigningCertNotTrusted = 5,
208     NSSCMSVS_SignatureAlgorithmUnknown = 6,
209     NSSCMSVS_SignatureAlgorithmUnsupported = 7,
210     NSSCMSVS_MalformedSignature = 8,
211     NSSCMSVS_ProcessingError = 9
212 } NSSCMSVerificationStatus;
213 
214 typedef enum {
215     NSSCMSSignerID_IssuerSN = 0,
216     NSSCMSSignerID_SubjectKeyID = 1
217 } NSSCMSSignerIDSelector;
218 
219 struct NSSCMSSignerIdentifierStr {
220     NSSCMSSignerIDSelector identifierType;
221     union {
222         CERTIssuerAndSN *issuerAndSN;
223         SECItem *subjectKeyID;
224     } id;
225 };
226 
227 struct NSSCMSSignerInfoStr {
228     SECItem version;
229     NSSCMSSignerIdentifier signerIdentifier;
230     SECAlgorithmID digestAlg;
231     NSSCMSAttribute **authAttr;
232     SECAlgorithmID digestEncAlg;
233     SECItem encDigest;
234     NSSCMSAttribute **unAuthAttr;
235     /* --------- local; not part of encoding --------- */
236     NSSCMSMessage *cmsg; /* back pointer to message */
237     CERTCertificate *cert;
238     CERTCertificateList *certList;
239     PRTime signingTime;
240     NSSCMSVerificationStatus verificationStatus;
241     SECKEYPrivateKey *signingKey; /* Used if we're using subjKeyID*/
242     SECKEYPublicKey *pubKey;
243 };
244 #define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
245 #define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3  /* what we *create* */
246 
247 typedef enum {
248     NSSCMSCM_None = 0,
249     NSSCMSCM_CertOnly = 1,
250     NSSCMSCM_CertChain = 2,
251     NSSCMSCM_CertChainWithRoot = 3
252 } NSSCMSCertChainMode;
253 
254 /* =============================================================================
255  * ENVELOPED DATA
256  */
257 struct NSSCMSEnvelopedDataStr {
258     SECItem version;
259     NSSCMSOriginatorInfo *originatorInfo; /* optional */
260     NSSCMSRecipientInfo **recipientInfos;
261     NSSCMSContentInfo contentInfo;
262     NSSCMSAttribute **unprotectedAttr;
263     /* --------- local; not part of encoding --------- */
264     NSSCMSMessage *cmsg; /* back pointer to message */
265 };
266 #define NSS_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */
267 #define NSS_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */
268 
269 struct NSSCMSOriginatorInfoStr {
270     SECItem **rawCerts;
271     CERTSignedCrl **crls;
272     /* --------- local; not part of encoding --------- */
273     CERTCertificate **certs;
274 };
275 
276 /* -----------------------------------------------------------------------------
277  * key transport recipient info
278  */
279 typedef enum {
280     NSSCMSRecipientID_IssuerSN = 0,
281     NSSCMSRecipientID_SubjectKeyID = 1,
282     NSSCMSRecipientID_BrandNew = 2
283 } NSSCMSRecipientIDSelector;
284 
285 struct NSSCMSRecipientIdentifierStr {
286     NSSCMSRecipientIDSelector identifierType;
287     union {
288         CERTIssuerAndSN *issuerAndSN;
289         SECItem *subjectKeyID;
290     } id;
291 };
292 typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier;
293 
294 struct NSSCMSKeyTransRecipientInfoStr {
295     SECItem version;
296     NSSCMSRecipientIdentifier recipientIdentifier;
297     SECAlgorithmID keyEncAlg;
298     SECItem encKey;
299 };
300 typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo;
301 
302 /*
303  * View comments before NSSCMSRecipientInfoStr for purpose of this
304  * structure.
305  */
306 struct NSSCMSKeyTransRecipientInfoExStr {
307     NSSCMSKeyTransRecipientInfo recipientInfo;
308     int version; /* version of this structure (0) */
309     SECKEYPublicKey *pubKey;
310 };
311 
312 typedef struct NSSCMSKeyTransRecipientInfoExStr NSSCMSKeyTransRecipientInfoEx;
313 
314 #define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */
315 #define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2  /* what we *create* */
316 
317 /* -----------------------------------------------------------------------------
318  * key agreement recipient info
319  */
320 struct NSSCMSOriginatorPublicKeyStr {
321     SECAlgorithmID algorithmIdentifier;
322     SECItem publicKey; /* bit string! */
323 };
324 typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey;
325 
326 typedef enum {
327     NSSCMSOriginatorIDOrKey_IssuerSN = 0,
328     NSSCMSOriginatorIDOrKey_SubjectKeyID = 1,
329     NSSCMSOriginatorIDOrKey_OriginatorPublicKey = 2
330 } NSSCMSOriginatorIDOrKeySelector;
331 
332 struct NSSCMSOriginatorIdentifierOrKeyStr {
333     NSSCMSOriginatorIDOrKeySelector identifierType;
334     union {
335         CERTIssuerAndSN *issuerAndSN;                  /* static-static */
336         SECItem *subjectKeyID;                         /* static-static */
337         NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */
338     } id;
339 };
340 typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey;
341 
342 struct NSSCMSRecipientKeyIdentifierStr {
343     SECItem *subjectKeyIdentifier;
344     SECItem *date;  /* optional */
345     SECItem *other; /* optional */
346 };
347 typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier;
348 
349 typedef enum {
350     NSSCMSKeyAgreeRecipientID_IssuerSN = 0,
351     NSSCMSKeyAgreeRecipientID_RKeyID = 1
352 } NSSCMSKeyAgreeRecipientIDSelector;
353 
354 struct NSSCMSKeyAgreeRecipientIdentifierStr {
355     NSSCMSKeyAgreeRecipientIDSelector identifierType;
356     union {
357         CERTIssuerAndSN *issuerAndSN;
358         NSSCMSRecipientKeyIdentifier recipientKeyIdentifier;
359     } id;
360 };
361 typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier;
362 
363 struct NSSCMSRecipientEncryptedKeyStr {
364     NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier;
365     SECItem encKey;
366 };
367 typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey;
368 
369 struct NSSCMSKeyAgreeRecipientInfoStr {
370     SECItem version;
371     NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey;
372     SECItem *ukm; /* optional */
373     SECAlgorithmID keyEncAlg;
374     NSSCMSRecipientEncryptedKey **recipientEncryptedKeys;
375 };
376 typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo;
377 
378 #define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
379 
380 /* -----------------------------------------------------------------------------
381  * KEK recipient info
382  */
383 struct NSSCMSKEKIdentifierStr {
384     SECItem keyIdentifier;
385     SECItem *date;  /* optional */
386     SECItem *other; /* optional */
387 };
388 typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier;
389 
390 struct NSSCMSKEKRecipientInfoStr {
391     SECItem version;
392     NSSCMSKEKIdentifier kekIdentifier;
393     SECAlgorithmID keyEncAlg;
394     SECItem encKey;
395 };
396 typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo;
397 
398 #define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
399 
400 /* -----------------------------------------------------------------------------
401  * recipient info
402  */
403 
404 typedef enum {
405     NSSCMSRecipientInfoID_KeyTrans = 0,
406     NSSCMSRecipientInfoID_KeyAgree = 1,
407     NSSCMSRecipientInfoID_KEK = 2
408 } NSSCMSRecipientInfoIDSelector;
409 
410 /*
411  * In order to preserve backwards binary compatibility when implementing
412  * creation of Recipient Info's that uses subjectKeyID in the
413  * keyTransRecipientInfo we need to stash a public key pointer in this
414  * structure somewhere.  We figured out that NSSCMSKeyTransRecipientInfo
415  * is the smallest member of the ri union.  We're in luck since that's
416  * the very structure that would need to use the public key. So we created
417  * a new structure NSSCMSKeyTransRecipientInfoEx which has a member
418  * NSSCMSKeyTransRecipientInfo as the first member followed by a version
419  * and a public key pointer.  This way we can keep backwards compatibility
420  * without changing the size of this structure.
421  *
422  * BTW, size of structure:
423  * NSSCMSKeyTransRecipientInfo:  9 ints, 4 pointers
424  * NSSCMSKeyAgreeRecipientInfo: 12 ints, 8 pointers
425  * NSSCMSKEKRecipientInfo:      10 ints, 7 pointers
426  *
427  * The new structure:
428  * NSSCMSKeyTransRecipientInfoEx: sizeof(NSSCMSKeyTransRecipientInfo) +
429  *                                1 int, 1 pointer
430  */
431 
432 struct NSSCMSRecipientInfoStr {
433     NSSCMSRecipientInfoIDSelector recipientInfoType;
434     union {
435         NSSCMSKeyTransRecipientInfo keyTransRecipientInfo;
436         NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo;
437         NSSCMSKEKRecipientInfo kekRecipientInfo;
438         NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx;
439     } ri;
440     /* --------- local; not part of encoding --------- */
441     NSSCMSMessage *cmsg;   /* back pointer to message */
442     CERTCertificate *cert; /* recipient's certificate */
443 };
444 
445 /* =============================================================================
446  * DIGESTED DATA
447  */
448 struct NSSCMSDigestedDataStr {
449     SECItem version;
450     SECAlgorithmID digestAlg;
451     NSSCMSContentInfo contentInfo;
452     SECItem digest;
453     /* --------- local; not part of encoding --------- */
454     NSSCMSMessage *cmsg; /* back pointer */
455     SECItem cdigest;     /* calculated digest */
456 };
457 #define NSS_CMS_DIGESTED_DATA_VERSION_DATA 0  /* what we *create* */
458 #define NSS_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */
459 
460 /* =============================================================================
461  * ENCRYPTED DATA
462  */
463 struct NSSCMSEncryptedDataStr {
464     SECItem version;
465     NSSCMSContentInfo contentInfo;
466     NSSCMSAttribute **unprotectedAttr; /* optional */
467     /* --------- local; not part of encoding --------- */
468     NSSCMSMessage *cmsg; /* back pointer */
469 };
470 #define NSS_CMS_ENCRYPTED_DATA_VERSION 0        /* what we *create* */
471 #define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
472 
473 /*
474  * *****************************************************************************
475  * *****************************************************************************
476  * *****************************************************************************
477  */
478 
479 /*
480  * See comment above about this type not really belonging to CMS.
481  */
482 struct NSSCMSAttributeStr {
483     /* The following fields make up an encoded Attribute: */
484     SECItem type;
485     SECItem **values; /* data may or may not be encoded */
486     /* The following fields are not part of an encoded Attribute: */
487     SECOidData *typeTag;
488     PRBool encoded; /* when true, values are encoded */
489 };
490 
491 #endif /* _CMST_H_ */
492