1/*
2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is the Netscape security libraries.
13 *
14 * The Initial Developer of the Original Code is Netscape
15 * Communications Corporation.  Portions created by Netscape are
16 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the
22 * terms of the GNU General Public License Version 2 or later (the
23 * "GPL"), in which case the provisions of the GPL are applicable
24 * instead of those above.  If you wish to allow use of your
25 * version of this file only under the terms of the GPL and not to
26 * allow others to use your version of this file under the MPL,
27 * indicate your decision by deleting the provisions above and
28 * replace them with the notice and other provisions required by
29 * the GPL.  If you do not delete the provisions above, a recipient
30 * may use your version of this file under either the MPL or the
31 * GPL.
32 */
33
34/*
35 * Header for CMS types.
36 */
37
38#ifndef _CMSTPRIV_H_
39#define _CMSTPRIV_H_
40
41#include <Security/SecCmsBase.h>
42#include <security_smime/secoidt.h>
43
44#include <Security/secasn1t.h>
45#include <security_asn1/plarenas.h>
46#include <Security/nameTemplates.h>
47
48#include <CoreFoundation/CFArray.h>
49#include <CoreFoundation/CFDate.h>
50#include <Security/SecCertificate.h>
51#include <Security/SecKey.h>
52
53/* rjr: PKCS #11 cert handling (pk11cert.c) does use SecCmsRecipientInfo's.
54 * This is because when we search the recipient list for the cert and key we
55 * want, we need to invert the order of the loops we used to have. The old
56 * loops were:
57 *
58 *  For each recipient {
59 *       find_cert = PK11_Find_AllCert(recipient->issuerSN);
60 *       [which unrolls to... ]
61 *       For each slot {
62 *            Log into slot;
63 *            search slot for cert;
64 *      }
65 *  }
66 *
67 *  the new loop searchs all the recipients at once on a slot. this allows
68 *  PKCS #11 to order slots in such a way that logout slots don't get checked
69 *  if we can find the cert on a logged in slot. This eliminates lots of
70 *  spurious password prompts when smart cards are installed... so why this
71 *  comment? If you make SecCmsRecipientInfo completely opaque, you need
72 *  to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
73 *  and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
74 *  function.
75 */
76
77typedef struct SecCmsContentInfoStr SecCmsContentInfo;
78typedef struct SecCmsMessageStr SecCmsMessage;
79typedef struct SecCmsSignedDataStr SecCmsSignedData;
80typedef struct SecCmsSignerInfoStr SecCmsSignerInfo;
81typedef struct SecCmsEnvelopedDataStr SecCmsEnvelopedData;
82typedef struct SecCmsRecipientInfoStr SecCmsRecipientInfo;
83typedef struct SecCmsDigestedDataStr SecCmsDigestedData;
84typedef struct SecCmsEncryptedDataStr SecCmsEncryptedData;
85
86typedef struct SecCmsIssuerAndSNStr SecCmsIssuerAndSN;
87typedef struct SecCmsOriginatorInfoStr SecCmsOriginatorInfo;
88typedef struct SecCmsAttributeStr SecCmsAttribute;
89
90typedef union SecCmsContentUnion SecCmsContent;
91typedef struct SecCmsSignerIdentifierStr SecCmsSignerIdentifier;
92
93typedef struct SecCmsSMIMEKEAParametersStr SecCmsSMIMEKEAParameters;
94
95typedef struct SecCmsCipherContextStr SecCmsCipherContext;
96typedef struct SecCmsCipherContextStr *SecCmsCipherContextRef;
97
98/* =============================================================================
99 * ENCAPSULATED CONTENTINFO & CONTENTINFO
100 */
101
102union SecCmsContentUnion {
103    /* either unstructured */
104    SecAsn1Item * 			data;
105    /* or structured data */
106    SecCmsDigestedDataRef 	digestedData;
107    SecCmsEncryptedDataRef 	encryptedData;
108    SecCmsEnvelopedDataRef 	envelopedData;
109    SecCmsSignedDataRef 		signedData;
110    /* or anonymous pointer to something */
111    void *			pointer;
112};
113
114struct SecCmsContentInfoStr {
115    SecAsn1Item			contentType;
116    SecCmsContent		content;
117    /* --------- local; not part of encoding --------- */
118    SecCmsMessageRef 	cmsg;			/* back pointer to message */
119    SECOidData *		contentTypeTag;
120
121    /* additional info for encryptedData and envelopedData */
122    /* we waste this space for signedData and digestedData. sue me. */
123
124    SECAlgorithmID		contentEncAlg;
125    SecAsn1Item * 			rawContent;		/* encrypted DER, optional */
126							/* XXXX bytes not encrypted, but encoded? */
127    /* --------- local; not part of encoding --------- */
128    SecSymmetricKeyRef		bulkkey;		/* bulk encryption key */
129    int				keysize;		/* size of bulk encryption key
130							 * (only used by creation code) */
131    SECOidTag			contentEncAlgTag;	/* oid tag of encryption algorithm
132							 * (only used by creation code) */
133    SecCmsCipherContextRef ciphcx;		/* context for en/decryption going on */
134    SecCmsDigestContextRef digcx;			/* context for digesting going on */
135    SecPrivateKeyRef		privkey;		/* @@@ private key is only here as a workaround for 3401088 */
136};
137
138/* =============================================================================
139 * MESSAGE
140 */
141
142struct SecCmsMessageStr {
143    SecCmsContentInfo	contentInfo;		/* "outer" cinfo */
144    /* --------- local; not part of encoding --------- */
145    PLArenaPool *	poolp;
146    int			refCount;
147    /* properties of the "inner" data */
148    void *		pwfn_arg;
149    SecCmsGetDecryptKeyCallback decrypt_key_cb;
150    void *		decrypt_key_cb_arg;
151};
152
153/* =============================================================================
154 * SIGNEDDATA
155 */
156
157struct SecCmsSignedDataStr {
158    SecCmsContentInfo		contentInfo;
159    SecAsn1Item			version;
160    SECAlgorithmID **		digestAlgorithms;
161    SecAsn1Item **		rawCerts;
162    SecAsn1Item **		rawCrls;
163    SecCmsSignerInfoRef *		signerInfos;
164    /* --------- local; not part of encoding --------- */
165    //SecCmsMessageRef 		cmsg;			/* back pointer to message */
166    SecAsn1Item **		digests;
167    CFMutableArrayRef		certs;
168};
169#define SEC_CMS_SIGNED_DATA_VERSION_BASIC	1	/* what we *create* */
170#define SEC_CMS_SIGNED_DATA_VERSION_EXT		3	/* what we *create* */
171
172typedef enum {
173    SecCmsSignerIDIssuerSN = 0,
174    SecCmsSignerIDSubjectKeyID = 1
175} SecCmsSignerIDSelector;
176
177struct SecCmsSignerIdentifierStr {
178    SecCmsSignerIDSelector identifierType;
179    union {
180	SecCmsIssuerAndSN *issuerAndSN;
181	SecAsn1Item * subjectKeyID;
182    } id;
183};
184
185struct SecCmsIssuerAndSNStr {
186	NSS_Name issuer;
187	SecAsn1Item serialNumber;
188    /* --------- local; not part of encoding --------- */
189	SecAsn1Item derIssuer;
190};
191
192struct SecCmsSignerInfoStr {
193    SecAsn1Item			version;
194    SecCmsSignerIdentifier	signerIdentifier;
195    SECAlgorithmID		digestAlg;
196    SecCmsAttribute **		authAttr;
197    SECAlgorithmID		digestEncAlg;
198    SecAsn1Item			encDigest;
199    SecCmsAttribute **		unAuthAttr;
200    /* --------- local; not part of encoding --------- */
201    //SecCmsMessageRef 		cmsg;			/* back pointer to message */
202	SecCmsSignedDataRef		signedData;		/* back pointer to signedData. */
203    SecCertificateRef		cert;
204    CFArrayRef			certList;
205    CFAbsoluteTime		signingTime;
206    SecCmsVerificationStatus	verificationStatus;
207    SecPrivateKeyRef		signingKey; /* Used if we're using subjKeyID*/
208    SecPublicKeyRef		pubKey;
209};
210#define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN	1	/* what we *create* */
211#define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY	3	/* what we *create* */
212
213/* =============================================================================
214 * ENVELOPED DATA
215 */
216struct SecCmsEnvelopedDataStr {
217    SecCmsContentInfo		contentInfo;
218    SecAsn1Item			version;
219    SecCmsOriginatorInfo *	originatorInfo;		/* optional */
220    SecCmsRecipientInfoRef *	recipientInfos;
221    SecCmsAttribute **		unprotectedAttr;
222    /* --------- local; not part of encoding --------- */
223    //SecCmsMessageRef 		cmsg;			/* back pointer to message */
224};
225#define SEC_CMS_ENVELOPED_DATA_VERSION_REG	0	/* what we *create* */
226#define SEC_CMS_ENVELOPED_DATA_VERSION_ADV	2	/* what we *create* */
227
228struct SecCmsOriginatorInfoStr {
229    SecAsn1Item **		rawCerts;
230    SecAsn1Item **		rawCrls;
231    /* --------- local; not part of encoding --------- */
232    SecCertificateRef *		certs;
233};
234
235/* -----------------------------------------------------------------------------
236 * key transport recipient info
237 */
238typedef enum {
239    SecCmsRecipientIDIssuerSN = 0,
240    SecCmsRecipientIDSubjectKeyID = 1
241} SecCmsRecipientIDSelector;
242
243struct SecCmsRecipientIdentifierStr {
244    SecCmsRecipientIDSelector	identifierType;
245    union {
246	SecCmsIssuerAndSN	*issuerAndSN;
247	SecAsn1Item * subjectKeyID;
248    } id;
249};
250typedef struct SecCmsRecipientIdentifierStr SecCmsRecipientIdentifier;
251
252struct SecCmsKeyTransRecipientInfoStr {
253    SecAsn1Item			version;
254    SecCmsRecipientIdentifier	recipientIdentifier;
255    SECAlgorithmID		keyEncAlg;
256    SecAsn1Item			encKey;
257};
258typedef struct SecCmsKeyTransRecipientInfoStr SecCmsKeyTransRecipientInfo;
259
260/*
261 * View comments before SecCmsRecipientInfoStr for purpose of this
262 * structure.
263 */
264struct SecCmsKeyTransRecipientInfoExStr {
265    SecCmsKeyTransRecipientInfo recipientInfo;
266    int version;  /* version of this structure (0) */
267    SecPublicKeyRef pubKey;
268};
269
270typedef struct SecCmsKeyTransRecipientInfoExStr SecCmsKeyTransRecipientInfoEx;
271
272#define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN	0	/* what we *create* */
273#define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY		2	/* what we *create* */
274
275/* -----------------------------------------------------------------------------
276 * key agreement recipient info
277 */
278struct SecCmsOriginatorPublicKeyStr {
279    SECAlgorithmID			algorithmIdentifier;
280    SecAsn1Item				publicKey;			/* bit string! */
281};
282typedef struct SecCmsOriginatorPublicKeyStr SecCmsOriginatorPublicKey;
283
284typedef enum {
285    SecCmsOriginatorIDOrKeyIssuerSN = 0,
286    SecCmsOriginatorIDOrKeySubjectKeyID = 1,
287    SecCmsOriginatorIDOrKeyOriginatorPublicKey = 2
288} SecCmsOriginatorIDOrKeySelector;
289
290struct SecCmsOriginatorIdentifierOrKeyStr {
291    SecCmsOriginatorIDOrKeySelector identifierType;
292    union {
293	SecCmsIssuerAndSN		*issuerAndSN;		/* static-static */
294	SecAsn1Item * subjectKeyID;		/* static-static */
295	SecCmsOriginatorPublicKey	originatorPublicKey;	/* ephemeral-static */
296    } id;
297};
298typedef struct SecCmsOriginatorIdentifierOrKeyStr SecCmsOriginatorIdentifierOrKey;
299
300struct SecCmsRecipientKeyIdentifierStr {
301    SecAsn1Item * 				subjectKeyIdentifier;
302    SecAsn1Item * 				date;			/* optional */
303    SecAsn1Item * 				other;			/* optional */
304};
305typedef struct SecCmsRecipientKeyIdentifierStr SecCmsRecipientKeyIdentifier;
306
307typedef enum {
308    SecCmsKeyAgreeRecipientIDIssuerSN = 0,
309    SecCmsKeyAgreeRecipientIDRKeyID = 1
310} SecCmsKeyAgreeRecipientIDSelector;
311
312struct SecCmsKeyAgreeRecipientIdentifierStr {
313    SecCmsKeyAgreeRecipientIDSelector	identifierType;
314    union {
315	SecCmsIssuerAndSN		*issuerAndSN;
316	SecCmsRecipientKeyIdentifier	recipientKeyIdentifier;
317    } id;
318};
319typedef struct SecCmsKeyAgreeRecipientIdentifierStr SecCmsKeyAgreeRecipientIdentifier;
320
321struct SecCmsRecipientEncryptedKeyStr {
322    SecCmsKeyAgreeRecipientIdentifier	recipientIdentifier;
323    SecAsn1Item				encKey;
324};
325typedef struct SecCmsRecipientEncryptedKeyStr SecCmsRecipientEncryptedKey;
326
327struct SecCmsKeyAgreeRecipientInfoStr {
328    SecAsn1Item				version;
329    SecCmsOriginatorIdentifierOrKey	originatorIdentifierOrKey;
330    SecAsn1Item * 				ukm;				/* optional */
331    SECAlgorithmID			keyEncAlg;
332    SecCmsRecipientEncryptedKey **	recipientEncryptedKeys;
333};
334typedef struct SecCmsKeyAgreeRecipientInfoStr SecCmsKeyAgreeRecipientInfo;
335
336#define SEC_CMS_KEYAGREE_RECIPIENT_INFO_VERSION	3	/* what we *create* */
337
338/* -----------------------------------------------------------------------------
339 * KEK recipient info
340 */
341struct SecCmsKEKIdentifierStr {
342    SecAsn1Item			keyIdentifier;
343    SecAsn1Item * 			date;			/* optional */
344    SecAsn1Item * 			other;			/* optional */
345};
346typedef struct SecCmsKEKIdentifierStr SecCmsKEKIdentifier;
347
348struct SecCmsKEKRecipientInfoStr {
349    SecAsn1Item			version;
350    SecCmsKEKIdentifier		kekIdentifier;
351    SECAlgorithmID		keyEncAlg;
352    SecAsn1Item			encKey;
353};
354typedef struct SecCmsKEKRecipientInfoStr SecCmsKEKRecipientInfo;
355
356#define SEC_CMS_KEK_RECIPIENT_INFO_VERSION	4	/* what we *create* */
357
358/* -----------------------------------------------------------------------------
359 * recipient info
360 */
361
362typedef enum {
363    SecCmsRecipientInfoIDKeyTrans = 0,
364    SecCmsRecipientInfoIDKeyAgree = 1,
365    SecCmsRecipientInfoIDKEK = 2
366} SecCmsRecipientInfoIDSelector;
367
368/*
369 * In order to preserve backwards binary compatibility when implementing
370 * creation of Recipient Info's that uses subjectKeyID in the
371 * keyTransRecipientInfo we need to stash a public key pointer in this
372 * structure somewhere.  We figured out that SecCmsKeyTransRecipientInfo
373 * is the smallest member of the ri union.  We're in luck since that's
374 * the very structure that would need to use the public key. So we created
375 * a new structure SecCmsKeyTransRecipientInfoEx which has a member
376 * SecCmsKeyTransRecipientInfo as the first member followed by a version
377 * and a public key pointer.  This way we can keep backwards compatibility
378 * without changing the size of this structure.
379 *
380 * BTW, size of structure:
381 * SecCmsKeyTransRecipientInfo:  9 ints, 4 pointers
382 * SecCmsKeyAgreeRecipientInfo: 12 ints, 8 pointers
383 * SecCmsKEKRecipientInfo:      10 ints, 7 pointers
384 *
385 * The new structure:
386 * SecCmsKeyTransRecipientInfoEx: sizeof(SecCmsKeyTransRecipientInfo) +
387 *                                1 int, 1 pointer
388 */
389
390struct SecCmsRecipientInfoStr {
391    SecCmsRecipientInfoIDSelector recipientInfoType;
392    union {
393	SecCmsKeyTransRecipientInfo keyTransRecipientInfo;
394	SecCmsKeyAgreeRecipientInfo keyAgreeRecipientInfo;
395	SecCmsKEKRecipientInfo kekRecipientInfo;
396	SecCmsKeyTransRecipientInfoEx keyTransRecipientInfoEx;
397    } ri;
398    /* --------- local; not part of encoding --------- */
399    //SecCmsMessageRef 		cmsg;			/* back pointer to message */
400	SecCmsEnvelopedDataRef	envelopedData;	/* back pointer to envelopedData */
401    SecCertificateRef 		cert;			/* recipient's certificate */
402};
403
404/* =============================================================================
405 * DIGESTED DATA
406 */
407struct SecCmsDigestedDataStr {
408    SecCmsContentInfo		contentInfo;
409    SecAsn1Item			version;
410    SECAlgorithmID		digestAlg;
411    SecAsn1Item			digest;
412    /* --------- local; not part of encoding --------- */
413    //SecCmsMessageRef 		cmsg;		/* back pointer */
414    SecAsn1Item			cdigest;	/* calculated digest */
415};
416#define SEC_CMS_DIGESTED_DATA_VERSION_DATA	0	/* what we *create* */
417#define SEC_CMS_DIGESTED_DATA_VERSION_ENCAP	2	/* what we *create* */
418
419/* =============================================================================
420 * ENCRYPTED DATA
421 */
422struct SecCmsEncryptedDataStr {
423    SecCmsContentInfo		contentInfo;
424    SecAsn1Item			version;
425    SecCmsAttribute **		unprotectedAttr;	/* optional */
426    /* --------- local; not part of encoding --------- */
427    //SecCmsMessageRef 		cmsg;		/* back pointer */
428};
429#define SEC_CMS_ENCRYPTED_DATA_VERSION		0	/* what we *create* */
430#define SEC_CMS_ENCRYPTED_DATA_VERSION_UPATTR	2	/* what we *create* */
431
432/* =============================================================================
433 * FORTEZZA KEA
434 */
435
436/* An enumerated type used to select templates based on the encryption
437   scenario and data specifics. */
438typedef enum {
439    SecCmsKEAInvalid = -1,
440    SecCmsKEAUsesSkipjack = 0,
441    SecCmsKEAUsesNonSkipjack = 1,
442    SecCmsKEAUsesNonSkipjackWithPaddedEncKey = 2
443} SecCmsKEATemplateSelector;
444
445/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
446                but I cannot think of a more appropriate place at this time. */
447struct SecCmsSMIMEKEAParametersStr {
448    SecAsn1Item originatorKEAKey;	/* sender KEA key (encrypted?) */
449    SecAsn1Item originatorRA;	/* random number generated by sender */
450    SecAsn1Item nonSkipjackIV;	/* init'n vector for SkipjackCBC64
451			           decryption of KEA key if Skipjack
452				   is not the bulk algorithm used on
453				   the message */
454    SecAsn1Item bulkKeySize;	/* if Skipjack is not the bulk
455			           algorithm used on the message,
456				   and the size of the bulk encryption
457				   key is not the same as that of
458				   originatorKEAKey (due to padding
459				   perhaps), this field will contain
460				   the real size of the bulk encryption
461				   key. */
462};
463
464/*
465 * *****************************************************************************
466 * *****************************************************************************
467 * *****************************************************************************
468 */
469
470/*
471 * See comment above about this type not really belonging to CMS.
472 */
473struct SecCmsAttributeStr {
474    /* The following fields make up an encoded Attribute: */
475    SecAsn1Item			type;
476    SecAsn1Item **		values;	/* data may or may not be encoded */
477    /* The following fields are not part of an encoded Attribute: */
478    SECOidData *		typeTag;
479    Boolean			encoded;	/* when true, values are encoded */
480};
481
482
483#endif /* _CMSTPRIV_H_ */
484