CMSDecoder.h
1 /* 2 * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 /* 25 * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the 26 * Cryptographic Message Syntax (CMS), per RFC 3852. 27 * 28 * See CMSEncoder.h for general information about CMS messages. 29 */ 30 31 #ifndef _CMS_DECODER_H_ 32 #define _CMS_DECODER_H_ 33 34 #include <CoreFoundation/CoreFoundation.h> 35 #include <Security/SecCertificate.h> 36 #include <Security/SecTrust.h> 37 #include <AvailabilityMacros.h> 38 #include <stdint.h> 39 40 __BEGIN_DECLS 41 42 CF_ASSUME_NONNULL_BEGIN 43 44 /* 45 * Opaque reference to a CMS decoder object. 46 * This is a CF object, with standard CF semantics; dispose of it 47 * with CFRelease(). 48 */ 49 typedef struct CF_BRIDGED_TYPE(id) _CMSDecoder *CMSDecoderRef; 50 51 CFTypeID CMSDecoderGetTypeID(void); 52 53 /* 54 * Status of signature and signer information in a signed message. 55 */ 56 typedef CF_ENUM(uint32_t, CMSSignerStatus) { 57 kCMSSignerUnsigned = 0, /* message was not signed */ 58 kCMSSignerValid, /* message was signed and signature verify OK */ 59 kCMSSignerNeedsDetachedContent, /* message was signed but needs detached content 60 * to verify */ 61 kCMSSignerInvalidSignature, /* message was signed but had a signature error */ 62 kCMSSignerInvalidCert, /* message was signed but an error occurred in verifying 63 * the signer's certificate */ 64 kCMSSignerInvalidIndex /* specified signer index out of range */ 65 }; 66 67 /* 68 * Create a CMSDecoder. Result must eventually be freed via CFRelease(). 69 */ 70 OSStatus CMSDecoderCreate(CMSDecoderRef * __nonnull CF_RETURNS_RETAINED cmsDecoderOut) /* RETURNED */ 71 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 72 73 /* 74 * Feed raw bytes of the message to be decoded into the decoder. Can be called 75 * multiple times. 76 * Returns errSecUnknownFormat upon detection of improperly formatted CMS 77 * message. 78 */ 79 OSStatus CMSDecoderUpdateMessage( 80 CMSDecoderRef cmsDecoder, 81 const void *msgBytes, 82 size_t msgBytesLen) 83 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 84 85 /* 86 * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; 87 * finish decoding the message. 88 * Returns errSecUnknownFormat upon detection of improperly formatted CMS 89 * message. 90 */ 91 OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder) 92 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 93 94 /* 95 * A signed CMS message optionally includes the data which was signed. If the 96 * message does not include the signed data, caller specifies the signed data 97 * (the "detached content") here. 98 * 99 * This can be called either before or after the actual decoding of the message 100 * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only 101 * restriction is that, if detached content is required, this function must 102 * be called befoere successfully ascertaining the signature status via 103 * CMSDecoderCopySignerStatus(). 104 */ 105 OSStatus CMSDecoderSetDetachedContent( 106 CMSDecoderRef cmsDecoder, 107 CFDataRef detachedContent) 108 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 109 110 /* 111 * Obtain the detached content specified in CMSDecoderSetDetachedContent(). 112 * Returns a NULL detachedContent if no detached content has been specified. 113 * Caller must CFRelease() the result. 114 */ 115 OSStatus CMSDecoderCopyDetachedContent( 116 CMSDecoderRef cmsDecoder, 117 CFDataRef * __nonnull CF_RETURNS_RETAINED detachedContentOut) /* RETURNED */ 118 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 119 120 #if SEC_OS_OSX 121 /* 122 * This function no longer affects the behavior of the CMS Decoder. Please 123 * discontinue use. 124 */ 125 OSStatus CMSDecoderSetSearchKeychain( 126 CMSDecoderRef cmsDecoder, 127 CFTypeRef keychainOrArray) 128 API_DEPRECATED_WITH_REPLACEMENT("SecKeychainSetSearchList",macos(10.5, 10.13)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); 129 #endif // SEC_OS_OSX 130 131 /* 132 * Obtain the number of signers of a message. A result of zero indicates that 133 * the message was not signed. 134 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 135 */ 136 OSStatus CMSDecoderGetNumSigners( 137 CMSDecoderRef cmsDecoder, 138 size_t *numSignersOut) /* RETURNED */ 139 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 140 141 /* 142 * Obtain the status of a CMS message's signature. A CMS message can 143 * be signed my multiple signers; this function returns the status 144 * associated with signer 'n' as indicated by the signerIndex parameter. 145 * 146 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 147 * 148 * Note that signature and certificate verification of a decoded message 149 * does *not* occur until this routine is called. 150 * 151 * All returned values are optional - pass NULL if you don't need a 152 * particular parameter. 153 * 154 * Note that errors like "bad signature" and "bad cert" do NOT cause this 155 * routine to return a nonzero error status itself; such errors are reported 156 * in the various out parameters, listed below. 157 * 158 * Inputs: 159 * ------- 160 * cmsDecoder : a CMSDecoder which has successfully performed a 161 * CMSDecoderFinalizeMessage(). 162 * signerIndex : indicates which of 'n' signers is being examined. 163 * Range is 0...(numSigners-1). 164 * policyOrArray : Either a SecPolicyRef or a CFArray of them. 165 * These policies are used to verify the signer's certificate. 166 * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the 167 * evaluation of the signer cert to actually be evaluated 168 * via SecTrustEvaluate(). When FALSE, the caller performs 169 * the SecTrustEvaluate() operation on the SecTrust object 170 * returned via the secTrust out parameter. 171 * NOTE: it is hazardous and not recommended to pass in FALSE 172 * for the evaluateSecTrust parameter as well as NULL for the 173 * secTrust out parameter, since no evaluation of the signer 174 * cert can occur in that situation. 175 * 176 * Outputs: 177 * -------- 178 * signerStatusOut -- An enum indicating the overall status. 179 * kCMSSignerUnsigned : message was not signed. 180 * kCMSSignerValid : both signature and signer certificate verified OK. 181 * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent() 182 * is required to ascertain the signature status. 183 * kCMSSignerInvalidSignature : bad signature. 184 * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate. 185 * Further information available via the secTrust and 186 * certVerifyResultCode parameters. This will never be 187 * returned if evaluateSecTrust is FALSE. 188 * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of 189 * signers (minus 1). 190 * 191 * secTrustOut -- The SecTrust object used to verify the signer's 192 * certificate. Caller must CFRelease this. 193 * certVerifyResultCodeOut -- The result of the certificate verification. If 194 * the evaluateSecTrust argument is set to FALSE on 195 * input, this out parameter is undefined on return. 196 * 197 * The certVerifyResultCode value can indicate a large number of errors; some of 198 * the most common and interesting errors are: 199 * 200 * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a 201 * self-signed (root) cert which was present in the message, but 202 * that root cert is not a known, trusted root cert. 203 * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to 204 * a root cert. 205 * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does 206 * not self-verify. 207 * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested 208 * policy action. 209 * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert. 210 * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of 211 * verification. 212 * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at 213 * the time of verification. 214 */ 215 OSStatus CMSDecoderCopySignerStatus( 216 CMSDecoderRef cmsDecoder, 217 size_t signerIndex, 218 CFTypeRef policyOrArray, 219 Boolean evaluateSecTrust, 220 CMSSignerStatus * __nullable signerStatusOut, /* optional; RETURNED */ 221 SecTrustRef * __nullable CF_RETURNS_RETAINED secTrustOut, /* optional; RETURNED */ 222 OSStatus * __nullable certVerifyResultCodeOut) /* optional; RETURNED */ 223 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 224 225 /* 226 * Obtain the email address of signer 'signerIndex' of a CMS message, if 227 * present. 228 * 229 * Returns errSecParam if the CMS message was not signed or if signerIndex 230 * is greater than the number of signers of the message minus one. 231 * 232 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 233 */ 234 OSStatus CMSDecoderCopySignerEmailAddress( 235 CMSDecoderRef cmsDecoder, 236 size_t signerIndex, 237 CFStringRef * __nonnull CF_RETURNS_RETAINED signerEmailAddressOut) /* RETURNED */ 238 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 239 240 /* 241 * Obtain the certificate of signer 'signerIndex' of a CMS message, if 242 * present. 243 * 244 * Returns errSecParam if the CMS message was not signed or if signerIndex 245 * is greater than the number of signers of the message minus one. 246 * 247 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 248 */ 249 OSStatus CMSDecoderCopySignerCert( 250 CMSDecoderRef cmsDecoder, 251 size_t signerIndex, 252 SecCertificateRef * __nonnull CF_RETURNS_RETAINED signerCertOut) /* RETURNED */ 253 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 254 255 /* 256 * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. 257 * Note that if the message was encrypted, and the decoding succeeded, (i.e., 258 * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully 259 * decrypted. 260 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 261 */ 262 OSStatus CMSDecoderIsContentEncrypted( 263 CMSDecoderRef cmsDecoder, 264 Boolean *isEncryptedOut) 265 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 266 267 /* 268 * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if 269 * present. If the message was not signed this will return NULL. 270 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 271 * The returned OID's data is in the same format as a CSSM_OID; i.e., it's 272 * the encoded content of the OID, not including the tag and length bytes. 273 */ 274 OSStatus CMSDecoderCopyEncapsulatedContentType( 275 CMSDecoderRef cmsDecoder, 276 CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ 277 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 278 279 /* 280 * Obtain an array of all of the certificates in a message. Elements of the 281 * returned array are SecCertificateRefs. The caller must CFRelease the returned 282 * array. If a message does not contain any certificates (which is the case for 283 * a message which is encrypted but not signed), the returned *certs value 284 * is NULL. The function will return errSecSuccess in this case. 285 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 286 */ 287 OSStatus CMSDecoderCopyAllCerts( 288 CMSDecoderRef cmsDecoder, 289 CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ 290 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 291 292 /* 293 * Obtain the actual message content (payload), if any. If the message was 294 * signed with detached content this will return NULL. 295 * Caller must CFRelease the result. 296 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 297 */ 298 OSStatus CMSDecoderCopyContent( 299 CMSDecoderRef cmsDecoder, 300 CFDataRef * __nonnull CF_RETURNS_RETAINED contentOut) /* RETURNED */ 301 __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 302 303 /* 304 * Obtain the signing time of signer 'signerIndex' of a CMS message, if 305 * present. This is an unauthenticate time, although it is part of the 306 * signed attributes of the message. 307 * 308 * Returns errSecParam if the CMS message was not signed or if signerIndex 309 * is greater than the number of signers of the message minus one. 310 * 311 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 312 */ 313 OSStatus CMSDecoderCopySignerSigningTime( 314 CMSDecoderRef cmsDecoder, 315 size_t signerIndex, 316 CFAbsoluteTime *signingTime) /* RETURNED */ 317 __API_AVAILABLE(macos(10.8)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); 318 319 /* 320 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if 321 * present. This timestamp is an authenticated timestamp provided by 322 * a timestamping authority. 323 * 324 * Returns errSecParam if the CMS message was not signed or if signerIndex 325 * is greater than the number of signers of the message minus one. 326 * 327 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 328 */ 329 OSStatus CMSDecoderCopySignerTimestamp( 330 CMSDecoderRef cmsDecoder, 331 size_t signerIndex, 332 CFAbsoluteTime *timestamp) /* RETURNED */ 333 API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); 334 335 /* 336 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if 337 * present. This timestamp is an authenticated timestamp provided by 338 * a timestamping authority. Use the policy provided as a parameter 339 * 340 * Returns errSecParam if the CMS message was not signed or if signerIndex 341 * is greater than the number of signers of the message minus one. 342 * 343 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 344 */ 345 OSStatus CMSDecoderCopySignerTimestampWithPolicy( 346 CMSDecoderRef cmsDecoder, 347 CFTypeRef __nullable timeStampPolicy, 348 size_t signerIndex, /* usually 0 */ 349 CFAbsoluteTime *timestamp) /* RETURNED */ 350 API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); 351 352 /* 353 * Obtain an array of the certificates in a timestamp response. Elements of the 354 * returned array are SecCertificateRefs. The caller must CFRelease the returned 355 * array. This timestamp is an authenticated timestamp provided by 356 * a timestamping authority. 357 * 358 * Returns errSecParam if the CMS message was not signed or if signerIndex 359 * is greater than the number of signers of the message minus one. It returns 360 * errSecItemNotFound if no certificates were found. 361 * 362 * This cannot be called until after CMSDecoderFinalizeMessage() is called. 363 */ 364 OSStatus CMSDecoderCopySignerTimestampCertificates( 365 CMSDecoderRef cmsDecoder, 366 size_t signerIndex, /* usually 0 */ 367 CFArrayRef * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */ 368 API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); 369 370 CF_ASSUME_NONNULL_END 371 372 __END_DECLS 373 374 #endif /* _CMS_DECODER_H_ */ 375