You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
16 KiB
382 lines
16 KiB
/* |
|
* 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 <CoreFoundation/CoreFoundation.h> |
|
#include <Security/SecCertificate.h> |
|
#include <Security/SecTrust.h> |
|
#include <stdint.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
CF_ASSUME_NONNULL_BEGIN |
|
|
|
/* |
|
* Opaque reference to a CMS decoder object. |
|
* This is a CF object, with standard CF semantics; dispose of it |
|
* with CFRelease(). |
|
*/ |
|
typedef struct CF_BRIDGED_TYPE(id) _CMSDecoder *CMSDecoderRef; |
|
|
|
CFTypeID CMSDecoderGetTypeID(void); |
|
|
|
/* |
|
* Status of signature and signer information in a signed message. |
|
*/ |
|
typedef CF_ENUM(uint32_t, CMSSignerStatus) { |
|
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 */ |
|
}; |
|
|
|
/* |
|
* Create a CMSDecoder. Result must eventually be freed via CFRelease(). |
|
*/ |
|
OSStatus CMSDecoderCreate( |
|
CMSDecoderRef * __nonnull CF_RETURNS_RETAINED 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 * __nonnull CF_RETURNS_RETAINED 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 * __nullable signerStatusOut, /* optional; RETURNED */ |
|
SecTrustRef * __nullable CF_RETURNS_RETAINED secTrustOut, /* optional; RETURNED */ |
|
OSStatus * __nullable 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 * __nonnull CF_RETURNS_RETAINED 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 * __nonnull CF_RETURNS_RETAINED 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 * __nonnull CF_RETURNS_RETAINED 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 * __nonnull CF_RETURNS_RETAINED 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 * __nonnull CF_RETURNS_RETAINED 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 __nullable 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 * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */ |
|
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); |
|
|
|
CF_ASSUME_NONNULL_END |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif /* _CMS_DECODER_H_ */ |
|
|
|
|