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