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/
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.
12 * The Original Code is the Netscape security libraries.
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
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
35 * Header for CMS types.
41 #include <Security/SecCmsBase.h>
42 #include <security_smime/secoidt.h>
44 #include <Security/secasn1t.h>
45 #include <security_asn1/plarenas.h>
46 #include <Security/nameTemplates.h>
48 #include <CoreFoundation/CFArray.h>
49 #include <CoreFoundation/CFDate.h>
50 #include <Security/SecCertificate.h>
51 #include <Security/SecKey.h>
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
58 * For each recipient {
59 * find_cert = PK11_Find_AllCert(recipient->issuerSN);
60 * [which unrolls to... ]
63 * search slot for cert;
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
77 typedef struct SecCmsContentInfoStr SecCmsContentInfo
;
78 typedef struct SecCmsMessageStr SecCmsMessage
;
79 typedef struct SecCmsSignedDataStr SecCmsSignedData
;
80 typedef struct SecCmsSignerInfoStr SecCmsSignerInfo
;
81 typedef struct SecCmsEnvelopedDataStr SecCmsEnvelopedData
;
82 typedef struct SecCmsRecipientInfoStr SecCmsRecipientInfo
;
83 typedef struct SecCmsDigestedDataStr SecCmsDigestedData
;
84 typedef struct SecCmsEncryptedDataStr SecCmsEncryptedData
;
86 typedef struct SecCmsIssuerAndSNStr SecCmsIssuerAndSN
;
87 typedef struct SecCmsOriginatorInfoStr SecCmsOriginatorInfo
;
88 typedef struct SecCmsAttributeStr SecCmsAttribute
;
90 typedef union SecCmsContentUnion SecCmsContent
;
91 typedef struct SecCmsSignerIdentifierStr SecCmsSignerIdentifier
;
93 typedef struct SecCmsSMIMEKEAParametersStr SecCmsSMIMEKEAParameters
;
95 typedef struct SecCmsCipherContextStr SecCmsCipherContext
;
96 typedef struct SecCmsCipherContextStr
*SecCmsCipherContextRef
;
98 /* =============================================================================
99 * ENCAPSULATED CONTENTINFO & CONTENTINFO
102 union SecCmsContentUnion
{
103 /* either unstructured */
105 /* or structured data */
106 SecCmsDigestedDataRef digestedData
;
107 SecCmsEncryptedDataRef encryptedData
;
108 SecCmsEnvelopedDataRef envelopedData
;
109 SecCmsSignedDataRef signedData
;
110 /* or anonymous pointer to something */
114 struct SecCmsContentInfoStr
{
115 CSSM_DATA contentType
;
116 SecCmsContent content
;
117 /* --------- local; not part of encoding --------- */
118 SECOidData
* contentTypeTag
;
120 /* additional info for encryptedData and envelopedData */
121 /* we waste this space for signedData and digestedData. sue me. */
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 */
137 /* =============================================================================
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
149 typedef OSStatus (*SecCmsTSACallback
)(const void *context
, void *messageImprint
, uint64_t nonce
, CSSM_DATA
*tstoken
);
151 struct SecCmsMessageStr
{
152 SecCmsContentInfo contentInfo
; /* "outer" cinfo */
153 /* --------- local; not part of encoding --------- */
155 Boolean poolp_is_ours
;
157 /* properties of the "inner" data */
158 SECAlgorithmID
** detached_digestalgs
;
159 CSSM_DATA_PTR
* detached_digests
;
161 SecCmsGetDecryptKeyCallback decrypt_key_cb
;
162 void * decrypt_key_cb_arg
;
164 /* Fields for Time Stamping */
165 SecCmsTSACallback tsaCallback
;
166 CFTypeRef tsaContext
;
169 /* =============================================================================
173 struct SecCmsSignedDataStr
{
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
;
185 #define SEC_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */
186 #define SEC_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */
189 SecCmsSignerIDIssuerSN
= 0,
190 SecCmsSignerIDSubjectKeyID
= 1
191 } SecCmsSignerIDSelector
;
193 struct SecCmsSignerIdentifierStr
{
194 SecCmsSignerIDSelector identifierType
;
196 SecCmsIssuerAndSN
*issuerAndSN
;
197 CSSM_DATA_PTR subjectKeyID
;
201 struct SecCmsIssuerAndSNStr
{
203 CSSM_DATA serialNumber
;
204 /* --------- local; not part of encoding --------- */
208 struct SecCmsSignerInfoStr
{
210 SecCmsSignerIdentifier signerIdentifier
;
211 SECAlgorithmID digestAlg
;
212 SecCmsAttribute
** authAttr
;
213 SECAlgorithmID digestEncAlg
;
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
;
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 CFDataRef hashAgilityAttrValue
;
231 #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
232 #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
234 /* =============================================================================
237 struct SecCmsEnvelopedDataStr
{
239 SecCmsOriginatorInfo
* originatorInfo
; /* optional */
240 SecCmsRecipientInfoRef
* recipientInfos
;
241 SecCmsContentInfo contentInfo
;
242 SecCmsAttribute
** unprotectedAttr
;
243 /* --------- local; not part of encoding --------- */
244 SecCmsMessageRef cmsg
; /* back pointer to message */
246 #define SEC_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */
247 #define SEC_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */
249 struct SecCmsOriginatorInfoStr
{
250 CSSM_DATA_PTR
* rawCerts
;
251 CSSM_DATA_PTR
* rawCrls
;
252 /* --------- local; not part of encoding --------- */
253 SecCertificateRef
* certs
;
256 /* -----------------------------------------------------------------------------
257 * key transport recipient info
260 SecCmsRecipientIDIssuerSN
= 0,
261 SecCmsRecipientIDSubjectKeyID
= 1
262 } SecCmsRecipientIDSelector
;
264 struct SecCmsRecipientIdentifierStr
{
265 SecCmsRecipientIDSelector identifierType
;
267 SecCmsIssuerAndSN
*issuerAndSN
;
268 CSSM_DATA_PTR subjectKeyID
;
271 typedef struct SecCmsRecipientIdentifierStr SecCmsRecipientIdentifier
;
273 struct SecCmsKeyTransRecipientInfoStr
{
275 SecCmsRecipientIdentifier recipientIdentifier
;
276 SECAlgorithmID keyEncAlg
;
279 typedef struct SecCmsKeyTransRecipientInfoStr SecCmsKeyTransRecipientInfo
;
282 * View comments before SecCmsRecipientInfoStr for purpose of this
285 struct SecCmsKeyTransRecipientInfoExStr
{
286 SecCmsKeyTransRecipientInfo recipientInfo
;
287 int version
; /* version of this structure (0) */
288 SecPublicKeyRef pubKey
;
291 typedef struct SecCmsKeyTransRecipientInfoExStr SecCmsKeyTransRecipientInfoEx
;
293 #define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */
294 #define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */
296 /* -----------------------------------------------------------------------------
297 * key agreement recipient info
299 struct SecCmsOriginatorPublicKeyStr
{
300 SECAlgorithmID algorithmIdentifier
;
301 CSSM_DATA publicKey
; /* bit string! */
303 typedef struct SecCmsOriginatorPublicKeyStr SecCmsOriginatorPublicKey
;
306 SecCmsOriginatorIDOrKeyIssuerSN
= 0,
307 SecCmsOriginatorIDOrKeySubjectKeyID
= 1,
308 SecCmsOriginatorIDOrKeyOriginatorPublicKey
= 2
309 } SecCmsOriginatorIDOrKeySelector
;
311 struct SecCmsOriginatorIdentifierOrKeyStr
{
312 SecCmsOriginatorIDOrKeySelector identifierType
;
314 SecCmsIssuerAndSN
*issuerAndSN
; /* static-static */
315 CSSM_DATA subjectKeyID
; /* static-static */
316 SecCmsOriginatorPublicKey originatorPublicKey
; /* ephemeral-static */
319 typedef struct SecCmsOriginatorIdentifierOrKeyStr SecCmsOriginatorIdentifierOrKey
;
321 struct SecCmsRecipientKeyIdentifierStr
{
322 CSSM_DATA_PTR subjectKeyIdentifier
;
323 CSSM_DATA_PTR date
; /* optional */
324 CSSM_DATA_PTR other
; /* optional */
326 typedef struct SecCmsRecipientKeyIdentifierStr SecCmsRecipientKeyIdentifier
;
329 SecCmsKeyAgreeRecipientIDIssuerSN
= 0,
330 SecCmsKeyAgreeRecipientIDRKeyID
= 1
331 } SecCmsKeyAgreeRecipientIDSelector
;
333 struct SecCmsKeyAgreeRecipientIdentifierStr
{
334 SecCmsKeyAgreeRecipientIDSelector identifierType
;
336 SecCmsIssuerAndSN
*issuerAndSN
;
337 SecCmsRecipientKeyIdentifier recipientKeyIdentifier
;
340 typedef struct SecCmsKeyAgreeRecipientIdentifierStr SecCmsKeyAgreeRecipientIdentifier
;
342 struct SecCmsRecipientEncryptedKeyStr
{
343 SecCmsKeyAgreeRecipientIdentifier recipientIdentifier
;
346 typedef struct SecCmsRecipientEncryptedKeyStr SecCmsRecipientEncryptedKey
;
348 struct SecCmsKeyAgreeRecipientInfoStr
{
350 SecCmsOriginatorIdentifierOrKey originatorIdentifierOrKey
;
351 CSSM_DATA ukm
; /* optional */
352 SECAlgorithmID keyEncAlg
;
353 SecCmsRecipientEncryptedKey
** recipientEncryptedKeys
;
355 typedef struct SecCmsKeyAgreeRecipientInfoStr SecCmsKeyAgreeRecipientInfo
;
357 #define SEC_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
359 /* -----------------------------------------------------------------------------
362 struct SecCmsKEKIdentifierStr
{
363 CSSM_DATA keyIdentifier
;
364 CSSM_DATA_PTR date
; /* optional */
365 CSSM_DATA_PTR other
; /* optional */
367 typedef struct SecCmsKEKIdentifierStr SecCmsKEKIdentifier
;
369 struct SecCmsKEKRecipientInfoStr
{
371 SecCmsKEKIdentifier kekIdentifier
;
372 SECAlgorithmID keyEncAlg
;
375 typedef struct SecCmsKEKRecipientInfoStr SecCmsKEKRecipientInfo
;
377 #define SEC_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
379 /* -----------------------------------------------------------------------------
384 SecCmsRecipientInfoIDKeyTrans
= 0,
385 SecCmsRecipientInfoIDKeyAgree
= 1,
386 SecCmsRecipientInfoIDKEK
= 2
387 } SecCmsRecipientInfoIDSelector
;
390 * In order to preserve backwards binary compatibility when implementing
391 * creation of Recipient Info's that uses subjectKeyID in the
392 * keyTransRecipientInfo we need to stash a public key pointer in this
393 * structure somewhere. We figured out that SecCmsKeyTransRecipientInfo
394 * is the smallest member of the ri union. We're in luck since that's
395 * the very structure that would need to use the public key. So we created
396 * a new structure SecCmsKeyTransRecipientInfoEx which has a member
397 * SecCmsKeyTransRecipientInfo as the first member followed by a version
398 * and a public key pointer. This way we can keep backwards compatibility
399 * without changing the size of this structure.
401 * BTW, size of structure:
402 * SecCmsKeyTransRecipientInfo: 9 ints, 4 pointers
403 * SecCmsKeyAgreeRecipientInfo: 12 ints, 8 pointers
404 * SecCmsKEKRecipientInfo: 10 ints, 7 pointers
407 * SecCmsKeyTransRecipientInfoEx: sizeof(SecCmsKeyTransRecipientInfo) +
411 struct SecCmsRecipientInfoStr
{
412 SecCmsRecipientInfoIDSelector recipientInfoType
;
414 SecCmsKeyTransRecipientInfo keyTransRecipientInfo
;
415 SecCmsKeyAgreeRecipientInfo keyAgreeRecipientInfo
;
416 SecCmsKEKRecipientInfo kekRecipientInfo
;
417 SecCmsKeyTransRecipientInfoEx keyTransRecipientInfoEx
;
419 /* --------- local; not part of encoding --------- */
420 SecCmsMessageRef cmsg
; /* back pointer to message */
421 SecCertificateRef cert
; /* recipient's certificate */
424 /* =============================================================================
427 struct SecCmsDigestedDataStr
{
429 SECAlgorithmID digestAlg
;
430 SecCmsContentInfo contentInfo
;
432 /* --------- local; not part of encoding --------- */
433 SecCmsMessageRef cmsg
; /* back pointer */
434 CSSM_DATA cdigest
; /* calculated digest */
436 #define SEC_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */
437 #define SEC_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */
439 /* =============================================================================
442 struct SecCmsEncryptedDataStr
{
444 SecCmsContentInfo contentInfo
;
445 SecCmsAttribute
** unprotectedAttr
; /* optional */
446 /* --------- local; not part of encoding --------- */
447 SecCmsMessageRef cmsg
; /* back pointer */
449 #define SEC_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
450 #define SEC_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
452 /* =============================================================================
456 /* An enumerated type used to select templates based on the encryption
457 scenario and data specifics. */
459 SecCmsKEAInvalid
= -1,
460 SecCmsKEAUsesSkipjack
= 0,
461 SecCmsKEAUsesNonSkipjack
= 1,
462 SecCmsKEAUsesNonSkipjackWithPaddedEncKey
= 2
463 } SecCmsKEATemplateSelector
;
465 /* ### mwelch - S/MIME KEA parameters. These don't really fit here,
466 but I cannot think of a more appropriate place at this time. */
467 struct SecCmsSMIMEKEAParametersStr
{
468 CSSM_DATA originatorKEAKey
; /* sender KEA key (encrypted?) */
469 CSSM_DATA originatorRA
; /* random number generated by sender */
470 CSSM_DATA nonSkipjackIV
; /* init'n vector for SkipjackCBC64
471 decryption of KEA key if Skipjack
472 is not the bulk algorithm used on
474 CSSM_DATA bulkKeySize
; /* if Skipjack is not the bulk
475 algorithm used on the message,
476 and the size of the bulk encryption
477 key is not the same as that of
478 originatorKEAKey (due to padding
479 perhaps), this field will contain
480 the real size of the bulk encryption
485 * *****************************************************************************
486 * *****************************************************************************
487 * *****************************************************************************
491 * See comment above about this type not really belonging to CMS.
493 struct SecCmsAttributeStr
{
494 /* The following fields make up an encoded Attribute: */
496 CSSM_DATA_PTR
* values
; /* data may or may not be encoded */
497 /* The following fields are not part of an encoded Attribute: */
498 SECOidData
* typeTag
;
499 Boolean encoded
; /* when true, values are encoded */
503 #endif /* _CMSTPRIV_H_ */