]> git.saurik.com Git - apple/security.git/blobdiff - CMS/CMSDecoder.h
Security-59306.11.20.tar.gz
[apple/security.git] / CMS / CMSDecoder.h
diff --git a/CMS/CMSDecoder.h b/CMS/CMSDecoder.h
new file mode 100644 (file)
index 0000000..031ad4a
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2006-2018 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 <AvailabilityMacros.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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)
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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)
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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)
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+#if SEC_OS_OSX
+/*
+ * This function no longer affects the behavior of the CMS Decoder. Please
+ * discontinue use.
+ */
+OSStatus CMSDecoderSetSearchKeychain(
+    CMSDecoderRef        cmsDecoder,
+    CFTypeRef            keychainOrArray)
+    API_DEPRECATED_WITH_REPLACEMENT("SecKeychainSetSearchList",macos(10.5, 10.13)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac);
+#endif // SEC_OS_OSX
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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)
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    __API_AVAILABLE(macos(10.8)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0));
+
+/*
+ * 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 */
+    API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac);
+
+/*
+ * 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 */
+    API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac);
+
+/*
+ * 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 */
+    API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac);
+
+CF_ASSUME_NONNULL_END
+
+__END_DECLS
+
+#endif /* _CMS_DECODER_H_ */
+