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 | |