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    CSSM_DATA_PTR 			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    CSSM_DATA			contentType;
116    SecCmsContent		content;
117    /* --------- local; not part of encoding --------- */
118    SECOidData *		contentTypeTag;
119
120    /* additional info for encryptedData and envelopedData */
121    /* we waste this space for signedData and digestedData. sue me. */
122
123    SECAlgorithmID		contentEncAlg;
124    CSSM_DATA_PTR 			rawContent;		/* encrypted DER, optional */
125							/* XXXX bytes not encrypted, but encoded? */
126    /* --------- local; not part of encoding --------- */
127    SecSymmetricKeyRef		bulkkey;		/* bulk encryption key */
128    int				keysize;		/* size of bulk encryption key
129							 * (only used by creation code) */
130    SECOidTag			contentEncAlgTag;	/* oid tag of encryption algorithm
131							 * (only used by creation code) */
132    SecCmsCipherContextRef ciphcx;		/* context for en/decryption going on */
133    SecCmsDigestContextRef digcx;			/* context for digesting going on */
134    SecPrivateKeyRef		privkey;		/* @@@ private key is only here as a workaround for 3401088 */
135};
136
137/* =============================================================================
138 * MESSAGE
139 */
140
141/*!
142    @typedef
143    @discussion    Type of function called inside SecCmsSignedDataEncodeAfterData to
144                    fire up XPC service to talk to TimeStamping server, etc.
145    @param context  Typically a CFDictionary with URL, etc.
146    @param messageImprint   a SecAsn1TSAMessageImprint with the algorithm and hash value
147    @param tstoken  The returned TimeStampToken
148 */
149typedef OSStatus (*SecCmsTSACallback)(const void *context, void *messageImprint, uint64_t nonce, CSSM_DATA *tstoken);
150
151struct SecCmsMessageStr {
152    SecCmsContentInfo	contentInfo;		/* "outer" cinfo */
153    /* --------- local; not part of encoding --------- */
154    PLArenaPool *	poolp;
155    Boolean		poolp_is_ours;
156    int			refCount;
157    /* properties of the "inner" data */
158    SECAlgorithmID **	detached_digestalgs;
159    CSSM_DATA_PTR *	detached_digests;
160    void *		pwfn_arg;
161    SecCmsGetDecryptKeyCallback decrypt_key_cb;
162    void *		decrypt_key_cb_arg;
163
164    /* Fields for Time Stamping */
165    SecCmsTSACallback tsaCallback;
166    CFTypeRef tsaContext;
167};
168
169/* =============================================================================
170 * SIGNEDDATA
171 */
172
173struct SecCmsSignedDataStr {
174    CSSM_DATA			version;
175    SECAlgorithmID **		digestAlgorithms;
176    SecCmsContentInfo		contentInfo;
177    CSSM_DATA_PTR *		rawCerts;
178    CSSM_DATA_PTR *		rawCrls;
179    SecCmsSignerInfoRef *		signerInfos;
180    /* --------- local; not part of encoding --------- */
181    SecCmsMessageRef 		cmsg;			/* back pointer to message */
182    CSSM_DATA_PTR *		digests;
183    CFMutableArrayRef		certs;
184};
185#define SEC_CMS_SIGNED_DATA_VERSION_BASIC	1	/* what we *create* */
186#define SEC_CMS_SIGNED_DATA_VERSION_EXT		3	/* what we *create* */
187
188typedef enum {
189    SecCmsSignerIDIssuerSN = 0,
190    SecCmsSignerIDSubjectKeyID = 1
191} SecCmsSignerIDSelector;
192
193struct SecCmsSignerIdentifierStr {
194    SecCmsSignerIDSelector identifierType;
195    union {
196	SecCmsIssuerAndSN *issuerAndSN;
197	CSSM_DATA_PTR subjectKeyID;
198    } id;
199};
200
201struct SecCmsIssuerAndSNStr {
202	NSS_Name issuer;
203	CSSM_DATA serialNumber;
204    /* --------- local; not part of encoding --------- */
205	CSSM_DATA derIssuer;
206};
207
208struct SecCmsSignerInfoStr {
209    CSSM_DATA			version;
210    SecCmsSignerIdentifier	signerIdentifier;
211    SECAlgorithmID		digestAlg;
212    SecCmsAttribute **		authAttr;
213    SECAlgorithmID		digestEncAlg;
214    CSSM_DATA			encDigest;
215    SecCmsAttribute **		unAuthAttr;
216    /* --------- local; not part of encoding --------- */
217    SecCmsMessageRef 		cmsg;			/* back pointer to message */
218    SecCmsSignedDataRef		sigd;			/* back pointer to SignedData */
219    SecCertificateRef		cert;
220    CFArrayRef			certList;
221    CFAbsoluteTime		signingTime;
222    SecCmsVerificationStatus	verificationStatus;
223    SecPrivateKeyRef		signingKey; /* Used if we're using subjKeyID*/
224    SecPublicKeyRef		pubKey;
225    CFAbsoluteTime		timestampTime;
226    CFAbsoluteTime		tsaLeafNotBefore;   /* Start date for Timestamp Authority leaf */
227    CFAbsoluteTime		tsaLeafNotAfter;    /* Expiration date for Timestamp Authority leaf */
228    CFMutableArrayRef	timestampCertList;
229};
230#define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN	1	/* what we *create* */
231#define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY	3	/* what we *create* */
232
233/* =============================================================================
234 * ENVELOPED DATA
235 */
236struct SecCmsEnvelopedDataStr {
237    CSSM_DATA			version;
238    SecCmsOriginatorInfo *	originatorInfo;		/* optional */
239    SecCmsRecipientInfoRef *	recipientInfos;
240    SecCmsContentInfo		contentInfo;
241    SecCmsAttribute **		unprotectedAttr;
242    /* --------- local; not part of encoding --------- */
243    SecCmsMessageRef 		cmsg;			/* back pointer to message */
244};
245#define SEC_CMS_ENVELOPED_DATA_VERSION_REG	0	/* what we *create* */
246#define SEC_CMS_ENVELOPED_DATA_VERSION_ADV	2	/* what we *create* */
247
248struct SecCmsOriginatorInfoStr {
249    CSSM_DATA_PTR *		rawCerts;
250    CSSM_DATA_PTR *		rawCrls;
251    /* --------- local; not part of encoding --------- */
252    SecCertificateRef *		certs;
253};
254
255/* -----------------------------------------------------------------------------
256 * key transport recipient info
257 */
258typedef enum {
259    SecCmsRecipientIDIssuerSN = 0,
260    SecCmsRecipientIDSubjectKeyID = 1
261} SecCmsRecipientIDSelector;
262
263struct SecCmsRecipientIdentifierStr {
264    SecCmsRecipientIDSelector	identifierType;
265    union {
266	SecCmsIssuerAndSN	*issuerAndSN;
267	CSSM_DATA_PTR subjectKeyID;
268    } id;
269};
270typedef struct SecCmsRecipientIdentifierStr SecCmsRecipientIdentifier;
271
272struct SecCmsKeyTransRecipientInfoStr {
273    CSSM_DATA			version;
274    SecCmsRecipientIdentifier	recipientIdentifier;
275    SECAlgorithmID		keyEncAlg;
276    CSSM_DATA			encKey;
277};
278typedef struct SecCmsKeyTransRecipientInfoStr SecCmsKeyTransRecipientInfo;
279
280/*
281 * View comments before SecCmsRecipientInfoStr for purpose of this
282 * structure.
283 */
284struct SecCmsKeyTransRecipientInfoExStr {
285    SecCmsKeyTransRecipientInfo recipientInfo;
286    int version;  /* version of this structure (0) */
287    SecPublicKeyRef pubKey;
288};
289
290typedef struct SecCmsKeyTransRecipientInfoExStr SecCmsKeyTransRecipientInfoEx;
291
292#define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN	0	/* what we *create* */
293#define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY		2	/* what we *create* */
294
295/* -----------------------------------------------------------------------------
296 * key agreement recipient info
297 */
298struct SecCmsOriginatorPublicKeyStr {
299    SECAlgorithmID			algorithmIdentifier;
300    CSSM_DATA				publicKey;			/* bit string! */
301};
302typedef struct SecCmsOriginatorPublicKeyStr SecCmsOriginatorPublicKey;
303
304typedef enum {
305    SecCmsOriginatorIDOrKeyIssuerSN = 0,
306    SecCmsOriginatorIDOrKeySubjectKeyID = 1,
307    SecCmsOriginatorIDOrKeyOriginatorPublicKey = 2
308} SecCmsOriginatorIDOrKeySelector;
309
310struct SecCmsOriginatorIdentifierOrKeyStr {
311    SecCmsOriginatorIDOrKeySelector identifierType;
312    union {
313	SecCmsIssuerAndSN			*issuerAndSN;			/* static-static */
314	CSSM_DATA					subjectKeyID;			/* static-static */
315	SecCmsOriginatorPublicKey	originatorPublicKey;	/* ephemeral-static */
316    } id;
317};
318typedef struct SecCmsOriginatorIdentifierOrKeyStr SecCmsOriginatorIdentifierOrKey;
319
320struct SecCmsRecipientKeyIdentifierStr {
321    CSSM_DATA_PTR 				subjectKeyIdentifier;
322    CSSM_DATA_PTR 				date;			/* optional */
323    CSSM_DATA_PTR 				other;			/* optional */
324};
325typedef struct SecCmsRecipientKeyIdentifierStr SecCmsRecipientKeyIdentifier;
326
327typedef enum {
328    SecCmsKeyAgreeRecipientIDIssuerSN = 0,
329    SecCmsKeyAgreeRecipientIDRKeyID = 1
330} SecCmsKeyAgreeRecipientIDSelector;
331
332struct SecCmsKeyAgreeRecipientIdentifierStr {
333    SecCmsKeyAgreeRecipientIDSelector	identifierType;
334    union {
335	SecCmsIssuerAndSN		*issuerAndSN;
336	SecCmsRecipientKeyIdentifier	recipientKeyIdentifier;
337    } id;
338};
339typedef struct SecCmsKeyAgreeRecipientIdentifierStr SecCmsKeyAgreeRecipientIdentifier;
340
341struct SecCmsRecipientEncryptedKeyStr {
342    SecCmsKeyAgreeRecipientIdentifier	recipientIdentifier;
343    CSSM_DATA				encKey;
344};
345typedef struct SecCmsRecipientEncryptedKeyStr SecCmsRecipientEncryptedKey;
346
347struct SecCmsKeyAgreeRecipientInfoStr {
348    CSSM_DATA				version;
349    SecCmsOriginatorIdentifierOrKey	originatorIdentifierOrKey;
350    CSSM_DATA 				ukm;				/* optional */
351    SECAlgorithmID			keyEncAlg;
352    SecCmsRecipientEncryptedKey **	recipientEncryptedKeys;
353};
354typedef struct SecCmsKeyAgreeRecipientInfoStr SecCmsKeyAgreeRecipientInfo;
355
356#define SEC_CMS_KEYAGREE_RECIPIENT_INFO_VERSION	3	/* what we *create* */
357
358/* -----------------------------------------------------------------------------
359 * KEK recipient info
360 */
361struct SecCmsKEKIdentifierStr {
362    CSSM_DATA			keyIdentifier;
363    CSSM_DATA_PTR 			date;			/* optional */
364    CSSM_DATA_PTR 			other;			/* optional */
365};
366typedef struct SecCmsKEKIdentifierStr SecCmsKEKIdentifier;
367
368struct SecCmsKEKRecipientInfoStr {
369    CSSM_DATA			version;
370    SecCmsKEKIdentifier		kekIdentifier;
371    SECAlgorithmID		keyEncAlg;
372    CSSM_DATA			encKey;
373};
374typedef struct SecCmsKEKRecipientInfoStr SecCmsKEKRecipientInfo;
375
376#define SEC_CMS_KEK_RECIPIENT_INFO_VERSION	4	/* what we *create* */
377
378/* -----------------------------------------------------------------------------
379 * recipient info
380 */
381
382typedef enum {
383    SecCmsRecipientInfoIDKeyTrans = 0,
384    SecCmsRecipientInfoIDKeyAgree = 1,
385    SecCmsRecipientInfoIDKEK = 2
386} SecCmsRecipientInfoIDSelector;
387
388/*
389 * In order to preserve backwards binary compatibility when implementing
390 * creation of Recipient Info's that uses subjectKeyID in the
391 * keyTransRecipientInfo we need to stash a public key pointer in this
392 * structure somewhere.  We figured out that SecCmsKeyTransRecipientInfo
393 * is the smallest member of the ri union.  We're in luck since that's
394 * the very structure that would need to use the public key. So we created
395 * a new structure SecCmsKeyTransRecipientInfoEx which has a member
396 * SecCmsKeyTransRecipientInfo as the first member followed by a version
397 * and a public key pointer.  This way we can keep backwards compatibility
398 * without changing the size of this structure.
399 *
400 * BTW, size of structure:
401 * SecCmsKeyTransRecipientInfo:  9 ints, 4 pointers
402 * SecCmsKeyAgreeRecipientInfo: 12 ints, 8 pointers
403 * SecCmsKEKRecipientInfo:      10 ints, 7 pointers
404 *
405 * The new structure:
406 * SecCmsKeyTransRecipientInfoEx: sizeof(SecCmsKeyTransRecipientInfo) +
407 *                                1 int, 1 pointer
408 */
409
410struct SecCmsRecipientInfoStr {
411    SecCmsRecipientInfoIDSelector recipientInfoType;
412    union {
413	SecCmsKeyTransRecipientInfo keyTransRecipientInfo;
414	SecCmsKeyAgreeRecipientInfo keyAgreeRecipientInfo;
415	SecCmsKEKRecipientInfo kekRecipientInfo;
416	SecCmsKeyTransRecipientInfoEx keyTransRecipientInfoEx;
417    } ri;
418    /* --------- local; not part of encoding --------- */
419    SecCmsMessageRef 		cmsg;			/* back pointer to message */
420    SecCertificateRef 		cert;			/* recipient's certificate */
421};
422
423/* =============================================================================
424 * DIGESTED DATA
425 */
426struct SecCmsDigestedDataStr {
427    CSSM_DATA			version;
428    SECAlgorithmID		digestAlg;
429    SecCmsContentInfo		contentInfo;
430    CSSM_DATA			digest;
431    /* --------- local; not part of encoding --------- */
432    SecCmsMessageRef 		cmsg;		/* back pointer */
433    CSSM_DATA			cdigest;	/* calculated digest */
434};
435#define SEC_CMS_DIGESTED_DATA_VERSION_DATA	0	/* what we *create* */
436#define SEC_CMS_DIGESTED_DATA_VERSION_ENCAP	2	/* what we *create* */
437
438/* =============================================================================
439 * ENCRYPTED DATA
440 */
441struct SecCmsEncryptedDataStr {
442    CSSM_DATA			version;
443    SecCmsContentInfo		contentInfo;
444    SecCmsAttribute **		unprotectedAttr;	/* optional */
445    /* --------- local; not part of encoding --------- */
446    SecCmsMessageRef 		cmsg;		/* back pointer */
447};
448#define SEC_CMS_ENCRYPTED_DATA_VERSION		0	/* what we *create* */
449#define SEC_CMS_ENCRYPTED_DATA_VERSION_UPATTR	2	/* what we *create* */
450
451/* =============================================================================
452 * FORTEZZA KEA
453 */
454
455/* An enumerated type used to select templates based on the encryption
456   scenario and data specifics. */
457typedef enum {
458    SecCmsKEAInvalid = -1,
459    SecCmsKEAUsesSkipjack = 0,
460    SecCmsKEAUsesNonSkipjack = 1,
461    SecCmsKEAUsesNonSkipjackWithPaddedEncKey = 2
462} SecCmsKEATemplateSelector;
463
464/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
465                but I cannot think of a more appropriate place at this time. */
466struct SecCmsSMIMEKEAParametersStr {
467    CSSM_DATA originatorKEAKey;	/* sender KEA key (encrypted?) */
468    CSSM_DATA originatorRA;	/* random number generated by sender */
469    CSSM_DATA nonSkipjackIV;	/* init'n vector for SkipjackCBC64
470			           decryption of KEA key if Skipjack
471				   is not the bulk algorithm used on
472				   the message */
473    CSSM_DATA bulkKeySize;	/* if Skipjack is not the bulk
474			           algorithm used on the message,
475				   and the size of the bulk encryption
476				   key is not the same as that of
477				   originatorKEAKey (due to padding
478				   perhaps), this field will contain
479				   the real size of the bulk encryption
480				   key. */
481};
482
483/*
484 * *****************************************************************************
485 * *****************************************************************************
486 * *****************************************************************************
487 */
488
489/*
490 * See comment above about this type not really belonging to CMS.
491 */
492struct SecCmsAttributeStr {
493    /* The following fields make up an encoded Attribute: */
494    CSSM_DATA			type;
495    CSSM_DATA_PTR *		values;	/* data may or may not be encoded */
496    /* The following fields are not part of an encoded Attribute: */
497    SECOidData *		typeTag;
498    Boolean			encoded;	/* when true, values are encoded */
499};
500
501
502#endif /* _CMSTPRIV_H_ */
503