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 SecAsn1Item contentType
;
116 SecCmsContent content
;
117 /* --------- local; not part of encoding --------- */
118 SecCmsMessageRef cmsg
; /* back pointer to message */
119 SECOidData
* contentTypeTag
;
121 /* additional info for encryptedData and envelopedData */
122 /* we waste this space for signedData and digestedData. sue me. */
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 */
138 /* =============================================================================
142 struct SecCmsMessageStr
{
143 SecCmsContentInfo contentInfo
; /* "outer" cinfo */
144 /* --------- local; not part of encoding --------- */
147 /* properties of the "inner" data */
149 SecCmsGetDecryptKeyCallback decrypt_key_cb
;
150 void * decrypt_key_cb_arg
;
153 /* =============================================================================
157 struct SecCmsSignedDataStr
{
158 SecCmsContentInfo contentInfo
;
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
;
169 #define SEC_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */
170 #define SEC_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */
173 SecCmsSignerIDIssuerSN
= 0,
174 SecCmsSignerIDSubjectKeyID
= 1
175 } SecCmsSignerIDSelector
;
177 struct SecCmsSignerIdentifierStr
{
178 SecCmsSignerIDSelector identifierType
;
180 SecCmsIssuerAndSN
*issuerAndSN
;
181 SecAsn1Item
* subjectKeyID
;
185 struct SecCmsIssuerAndSNStr
{
187 SecAsn1Item serialNumber
;
188 /* --------- local; not part of encoding --------- */
189 SecAsn1Item derIssuer
;
192 struct SecCmsSignerInfoStr
{
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
;
205 CFAbsoluteTime signingTime
;
206 SecCmsVerificationStatus verificationStatus
;
207 SecPrivateKeyRef signingKey
; /* Used if we're using subjKeyID*/
208 SecPublicKeyRef pubKey
;
209 CFDataRef hashAgilityAttrValue
;
211 #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
212 #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
214 /* =============================================================================
217 struct SecCmsEnvelopedDataStr
{
218 SecCmsContentInfo contentInfo
;
220 SecCmsOriginatorInfo
* originatorInfo
; /* optional */
221 SecCmsRecipientInfoRef
* recipientInfos
;
222 SecCmsAttribute
** unprotectedAttr
;
223 /* --------- local; not part of encoding --------- */
224 //SecCmsMessageRef cmsg; /* back pointer to message */
226 #define SEC_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */
227 #define SEC_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */
229 struct SecCmsOriginatorInfoStr
{
230 SecAsn1Item
** rawCerts
;
231 SecAsn1Item
** rawCrls
;
232 /* --------- local; not part of encoding --------- */
233 SecCertificateRef
* certs
;
236 /* -----------------------------------------------------------------------------
237 * key transport recipient info
240 SecCmsRecipientIDIssuerSN
= 0,
241 SecCmsRecipientIDSubjectKeyID
= 1
242 } SecCmsRecipientIDSelector
;
244 struct SecCmsRecipientIdentifierStr
{
245 SecCmsRecipientIDSelector identifierType
;
247 SecCmsIssuerAndSN
*issuerAndSN
;
248 SecAsn1Item
* subjectKeyID
;
251 typedef struct SecCmsRecipientIdentifierStr SecCmsRecipientIdentifier
;
253 struct SecCmsKeyTransRecipientInfoStr
{
255 SecCmsRecipientIdentifier recipientIdentifier
;
256 SECAlgorithmID keyEncAlg
;
259 typedef struct SecCmsKeyTransRecipientInfoStr SecCmsKeyTransRecipientInfo
;
262 * View comments before SecCmsRecipientInfoStr for purpose of this
265 struct SecCmsKeyTransRecipientInfoExStr
{
266 SecCmsKeyTransRecipientInfo recipientInfo
;
267 int version
; /* version of this structure (0) */
268 SecPublicKeyRef pubKey
;
271 typedef struct SecCmsKeyTransRecipientInfoExStr SecCmsKeyTransRecipientInfoEx
;
273 #define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */
274 #define SEC_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */
276 /* -----------------------------------------------------------------------------
277 * key agreement recipient info
279 struct SecCmsOriginatorPublicKeyStr
{
280 SECAlgorithmID algorithmIdentifier
;
281 SecAsn1Item publicKey
; /* bit string! */
283 typedef struct SecCmsOriginatorPublicKeyStr SecCmsOriginatorPublicKey
;
286 SecCmsOriginatorIDOrKeyIssuerSN
= 0,
287 SecCmsOriginatorIDOrKeySubjectKeyID
= 1,
288 SecCmsOriginatorIDOrKeyOriginatorPublicKey
= 2
289 } SecCmsOriginatorIDOrKeySelector
;
291 struct SecCmsOriginatorIdentifierOrKeyStr
{
292 SecCmsOriginatorIDOrKeySelector identifierType
;
294 SecCmsIssuerAndSN
*issuerAndSN
; /* static-static */
295 SecAsn1Item
* subjectKeyID
; /* static-static */
296 SecCmsOriginatorPublicKey originatorPublicKey
; /* ephemeral-static */
299 typedef struct SecCmsOriginatorIdentifierOrKeyStr SecCmsOriginatorIdentifierOrKey
;
301 struct SecCmsRecipientKeyIdentifierStr
{
302 SecAsn1Item
* subjectKeyIdentifier
;
303 SecAsn1Item
* date
; /* optional */
304 SecAsn1Item
* other
; /* optional */
306 typedef struct SecCmsRecipientKeyIdentifierStr SecCmsRecipientKeyIdentifier
;
309 SecCmsKeyAgreeRecipientIDIssuerSN
= 0,
310 SecCmsKeyAgreeRecipientIDRKeyID
= 1
311 } SecCmsKeyAgreeRecipientIDSelector
;
313 struct SecCmsKeyAgreeRecipientIdentifierStr
{
314 SecCmsKeyAgreeRecipientIDSelector identifierType
;
316 SecCmsIssuerAndSN
*issuerAndSN
;
317 SecCmsRecipientKeyIdentifier recipientKeyIdentifier
;
320 typedef struct SecCmsKeyAgreeRecipientIdentifierStr SecCmsKeyAgreeRecipientIdentifier
;
322 struct SecCmsRecipientEncryptedKeyStr
{
323 SecCmsKeyAgreeRecipientIdentifier recipientIdentifier
;
326 typedef struct SecCmsRecipientEncryptedKeyStr SecCmsRecipientEncryptedKey
;
328 struct SecCmsKeyAgreeRecipientInfoStr
{
330 SecCmsOriginatorIdentifierOrKey originatorIdentifierOrKey
;
331 SecAsn1Item
* ukm
; /* optional */
332 SECAlgorithmID keyEncAlg
;
333 SecCmsRecipientEncryptedKey
** recipientEncryptedKeys
;
335 typedef struct SecCmsKeyAgreeRecipientInfoStr SecCmsKeyAgreeRecipientInfo
;
337 #define SEC_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
339 /* -----------------------------------------------------------------------------
342 struct SecCmsKEKIdentifierStr
{
343 SecAsn1Item keyIdentifier
;
344 SecAsn1Item
* date
; /* optional */
345 SecAsn1Item
* other
; /* optional */
347 typedef struct SecCmsKEKIdentifierStr SecCmsKEKIdentifier
;
349 struct SecCmsKEKRecipientInfoStr
{
351 SecCmsKEKIdentifier kekIdentifier
;
352 SECAlgorithmID keyEncAlg
;
355 typedef struct SecCmsKEKRecipientInfoStr SecCmsKEKRecipientInfo
;
357 #define SEC_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
359 /* -----------------------------------------------------------------------------
364 SecCmsRecipientInfoIDKeyTrans
= 0,
365 SecCmsRecipientInfoIDKeyAgree
= 1,
366 SecCmsRecipientInfoIDKEK
= 2
367 } SecCmsRecipientInfoIDSelector
;
370 * In order to preserve backwards binary compatibility when implementing
371 * creation of Recipient Info's that uses subjectKeyID in the
372 * keyTransRecipientInfo we need to stash a public key pointer in this
373 * structure somewhere. We figured out that SecCmsKeyTransRecipientInfo
374 * is the smallest member of the ri union. We're in luck since that's
375 * the very structure that would need to use the public key. So we created
376 * a new structure SecCmsKeyTransRecipientInfoEx which has a member
377 * SecCmsKeyTransRecipientInfo as the first member followed by a version
378 * and a public key pointer. This way we can keep backwards compatibility
379 * without changing the size of this structure.
381 * BTW, size of structure:
382 * SecCmsKeyTransRecipientInfo: 9 ints, 4 pointers
383 * SecCmsKeyAgreeRecipientInfo: 12 ints, 8 pointers
384 * SecCmsKEKRecipientInfo: 10 ints, 7 pointers
387 * SecCmsKeyTransRecipientInfoEx: sizeof(SecCmsKeyTransRecipientInfo) +
391 struct SecCmsRecipientInfoStr
{
392 SecCmsRecipientInfoIDSelector recipientInfoType
;
394 SecCmsKeyTransRecipientInfo keyTransRecipientInfo
;
395 SecCmsKeyAgreeRecipientInfo keyAgreeRecipientInfo
;
396 SecCmsKEKRecipientInfo kekRecipientInfo
;
397 SecCmsKeyTransRecipientInfoEx keyTransRecipientInfoEx
;
399 /* --------- local; not part of encoding --------- */
400 //SecCmsMessageRef cmsg; /* back pointer to message */
401 SecCmsEnvelopedDataRef envelopedData
; /* back pointer to envelopedData */
402 SecCertificateRef cert
; /* recipient's certificate */
405 /* =============================================================================
408 struct SecCmsDigestedDataStr
{
409 SecCmsContentInfo contentInfo
;
411 SECAlgorithmID digestAlg
;
413 /* --------- local; not part of encoding --------- */
414 //SecCmsMessageRef cmsg; /* back pointer */
415 SecAsn1Item cdigest
; /* calculated digest */
417 #define SEC_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */
418 #define SEC_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */
420 /* =============================================================================
423 struct SecCmsEncryptedDataStr
{
424 SecCmsContentInfo contentInfo
;
426 SecCmsAttribute
** unprotectedAttr
; /* optional */
427 /* --------- local; not part of encoding --------- */
428 //SecCmsMessageRef cmsg; /* back pointer */
430 #define SEC_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
431 #define SEC_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
433 /* =============================================================================
437 /* An enumerated type used to select templates based on the encryption
438 scenario and data specifics. */
440 SecCmsKEAInvalid
= -1,
441 SecCmsKEAUsesSkipjack
= 0,
442 SecCmsKEAUsesNonSkipjack
= 1,
443 SecCmsKEAUsesNonSkipjackWithPaddedEncKey
= 2
444 } SecCmsKEATemplateSelector
;
446 /* ### mwelch - S/MIME KEA parameters. These don't really fit here,
447 but I cannot think of a more appropriate place at this time. */
448 struct SecCmsSMIMEKEAParametersStr
{
449 SecAsn1Item originatorKEAKey
; /* sender KEA key (encrypted?) */
450 SecAsn1Item originatorRA
; /* random number generated by sender */
451 SecAsn1Item nonSkipjackIV
; /* init'n vector for SkipjackCBC64
452 decryption of KEA key if Skipjack
453 is not the bulk algorithm used on
455 SecAsn1Item bulkKeySize
; /* if Skipjack is not the bulk
456 algorithm used on the message,
457 and the size of the bulk encryption
458 key is not the same as that of
459 originatorKEAKey (due to padding
460 perhaps), this field will contain
461 the real size of the bulk encryption
466 * *****************************************************************************
467 * *****************************************************************************
468 * *****************************************************************************
472 * See comment above about this type not really belonging to CMS.
474 struct SecCmsAttributeStr
{
475 /* The following fields make up an encoded Attribute: */
477 SecAsn1Item
** values
; /* data may or may not be encoded */
478 /* The following fields are not part of an encoded Attribute: */
479 SECOidData
* typeTag
;
480 Boolean encoded
; /* when true, values are encoded */
484 #endif /* _CMSTPRIV_H_ */