X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cms/lib/CMSDecoder.h diff --git a/Security/libsecurity_cms/lib/CMSDecoder.h b/Security/libsecurity_cms/lib/CMSDecoder.h new file mode 100644 index 00000000..3606fa0a --- /dev/null +++ b/Security/libsecurity_cms/lib/CMSDecoder.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the + * Cryptographic Message Syntax (CMS), per RFC 3852. + * + * See CMSEncoder.h for general information about CMS messages. + */ + +#ifndef _CMS_DECODER_H_ +#define _CMS_DECODER_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Opaque reference to a CMS decoder object. + * This is a CF object, with standard CF semantics; dispose of it + * with CFRelease(). + */ +typedef struct _CMSDecoder *CMSDecoderRef; + +CFTypeID CMSDecoderGetTypeID(void); + +/* + * Status of signature and signer information in a signed message. + */ +enum { + kCMSSignerUnsigned = 0, /* message was not signed */ + kCMSSignerValid, /* message was signed and signature verify OK */ + kCMSSignerNeedsDetachedContent, /* message was signed but needs detached content + * to verify */ + kCMSSignerInvalidSignature, /* message was signed but had a signature error */ + kCMSSignerInvalidCert, /* message was signed but an error occurred in verifying + * the signer's certificate */ + kCMSSignerInvalidIndex /* specified signer index out of range */ +}; +typedef uint32_t CMSSignerStatus; + +/* + * Create a CMSDecoder. Result must eventually be freed via CFRelease(). + */ +OSStatus CMSDecoderCreate( + CMSDecoderRef *cmsDecoderOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Feed raw bytes of the message to be decoded into the decoder. Can be called + * multiple times. + * Returns errSecUnknownFormat upon detection of improperly formatted CMS + * message. + */ +OSStatus CMSDecoderUpdateMessage( + CMSDecoderRef cmsDecoder, + const void *msgBytes, + size_t msgBytesLen) + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; + * finish decoding the message. + * Returns errSecUnknownFormat upon detection of improperly formatted CMS + * message. + */ +OSStatus CMSDecoderFinalizeMessage( + CMSDecoderRef cmsDecoder) + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * A signed CMS message optionally includes the data which was signed. If the + * message does not include the signed data, caller specifies the signed data + * (the "detached content") here. + * + * This can be called either before or after the actual decoding of the message + * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only + * restriction is that, if detached content is required, this function must + * be called befoere successfully ascertaining the signature status via + * CMSDecoderCopySignerStatus(). + */ +OSStatus CMSDecoderSetDetachedContent( + CMSDecoderRef cmsDecoder, + CFDataRef detachedContent) + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the detached content specified in CMSDecoderSetDetachedContent(). + * Returns a NULL detachedContent if no detached content has been specified. + * Caller must CFRelease() the result. + */ +OSStatus CMSDecoderCopyDetachedContent( + CMSDecoderRef cmsDecoder, + CFDataRef *detachedContentOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Optionally specify a SecKeychainRef, or an array of them, containing + * intermediate certs to be used in verifying a signed message's signer + * certs. By default, the default keychain search list is used for this. + * Specify an empty CFArrayRef to search *no* keychains for intermediate + * certs. + * If this is called, it must be called before CMSDecoderCopySignerStatus(). + */ +OSStatus CMSDecoderSetSearchKeychain( + CMSDecoderRef cmsDecoder, + CFTypeRef keychainOrArray) + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the number of signers of a message. A result of zero indicates that + * the message was not signed. + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderGetNumSigners( + CMSDecoderRef cmsDecoder, + size_t *numSignersOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the status of a CMS message's signature. A CMS message can + * be signed my multiple signers; this function returns the status + * associated with signer 'n' as indicated by the signerIndex parameter. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + * + * Note that signature and certificate verification of a decoded message + * does *not* occur until this routine is called. + * + * All returned values are optional - pass NULL if you don't need a + * particular parameter. + * + * Note that errors like "bad signature" and "bad cert" do NOT cause this + * routine to return a nonzero error status itself; such errors are reported + * in the various out parameters, listed below. + * + * Inputs: + * ------- + * cmsDecoder : a CMSDecoder which has successfully performed a + * CMSDecoderFinalizeMessage(). + * signerIndex : indicates which of 'n' signers is being examined. + * Range is 0...(numSigners-1). + * policyOrArray : Either a SecPolicyRef or a CFArray of them. + * These policies are used to verify the signer's certificate. + * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the + * evaluation of the signer cert to actually be evaluated + * via SecTrustEvaluate(). When FALSE, the caller performs + * the SecTrustEvaluate() operation on the SecTrust object + * returned via the secTrust out parameter. + * NOTE: it is hazardous and not recommended to pass in FALSE + * for the evaluateSecTrust parameter as well as NULL for the + * secTrust out parameter, since no evaluation of the signer + * cert can occur in that situation. + * + * Outputs: + * -------- + * signerStatusOut -- An enum indicating the overall status. + * kCMSSignerUnsigned : message was not signed. + * kCMSSignerValid : both signature and signer certificate verified OK. + * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent() + * is required to ascertain the signature status. + * kCMSSignerInvalidSignature : bad signature. + * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate. + * Further information available via the secTrust and + * certVerifyResultCode parameters. This will never be + * returned if evaluateSecTrust is FALSE. + * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of + * signers (minus 1). + * + * secTrustOut -- The SecTrust object used to verify the signer's + * certificate. Caller must CFRelease this. + * certVerifyResultCodeOut -- The result of the certificate verification. If + * the evaluateSecTrust argument is set to FALSE on + * input, this out parameter is undefined on return. + * + * The certVerifyResultCode value can indicate a large number of errors; some of + * the most common and interesting errors are: + * + * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a + * self-signed (root) cert which was present in the message, but + * that root cert is not a known, trusted root cert. + * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to + * a root cert. + * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does + * not self-verify. + * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested + * policy action. + * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert. + * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of + * verification. + * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at + * the time of verification. + */ +OSStatus CMSDecoderCopySignerStatus( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFTypeRef policyOrArray, + Boolean evaluateSecTrust, + CMSSignerStatus *signerStatusOut, /* optional; RETURNED */ + SecTrustRef *secTrustOut, /* optional; RETURNED */ + OSStatus *certVerifyResultCodeOut) /* optional; RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the email address of signer 'signerIndex' of a CMS message, if + * present. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerEmailAddress( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFStringRef *signerEmailAddressOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the certificate of signer 'signerIndex' of a CMS message, if + * present. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerCert( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + SecCertificateRef *signerCertOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. + * Note that if the message was encrypted, and the decoding succeeded, (i.e., + * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully + * decrypted. + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderIsContentEncrypted( + CMSDecoderRef cmsDecoder, + Boolean *isEncryptedOut) + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if + * present. If the message was not signed this will return NULL. + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + * The returned OID's data is in the same format as a CSSM_OID; i.e., it's + * the encoded content of the OID, not including the tag and length bytes. + */ +OSStatus CMSDecoderCopyEncapsulatedContentType( + CMSDecoderRef cmsDecoder, + CFDataRef *eContentTypeOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain an array of all of the certificates in a message. Elements of the + * returned array are SecCertificateRefs. The caller must CFRelease the returned + * array. If a message does not contain any certificates (which is the case for + * a message which is encrypted but not signed), the returned *certs value + * is NULL. The function will return errSecSuccess in this case. + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopyAllCerts( + CMSDecoderRef cmsDecoder, + CFArrayRef *certsOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the actual message content (payload), if any. If the message was + * signed with detached content this will return NULL. + * Caller must CFRelease the result. + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopyContent( + CMSDecoderRef cmsDecoder, + CFDataRef *contentOut) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + +/* + * Obtain the signing time of signer 'signerIndex' of a CMS message, if + * present. This is an unauthenticate time, although it is part of the + * signed attributes of the message. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerSigningTime( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *signingTime) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); + +/* + * Obtain the timestamp of signer 'signerIndex' of a CMS message, if + * present. This timestamp is an authenticated timestamp provided by + * a timestamping authority. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerTimestamp( + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *timestamp) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); + + /* + * Obtain the timestamp of signer 'signerIndex' of a CMS message, if + * present. This timestamp is an authenticated timestamp provided by + * a timestamping authority. Use the policy provided as a parameter + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerTimestampWithPolicy( + CMSDecoderRef cmsDecoder, + CFTypeRef timeStampPolicy, + size_t signerIndex, /* usually 0 */ + CFAbsoluteTime *timestamp) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); + +/* + * Obtain an array of the certificates in a timestamp response. Elements of the + * returned array are SecCertificateRefs. The caller must CFRelease the returned + * array. This timestamp is an authenticated timestamp provided by + * a timestamping authority. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. It returns + * errSecItemNotFound if no certificates were found. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerTimestampCertificates( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFArrayRef *certificateRefs) /* RETURNED */ + __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); + +#ifdef __cplusplus +} +#endif + +#endif /* _CMS_DECODER_H_ */ +