2 * Copyright (c) 2006-2013 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the
26 * Cryptographic Message Syntax (CMS), per RFC 3852.
28 * See CMSEncoder.h for general information about CMS messages.
31 #ifndef _CMS_DECODER_H_
32 #define _CMS_DECODER_H_
34 #include <CoreFoundation/CoreFoundation.h>
35 #include <Security/SecCertificate.h>
36 #include <Security/SecTrust.h>
43 CF_ASSUME_NONNULL_BEGIN
46 * Opaque reference to a CMS decoder object.
47 * This is a CF object, with standard CF semantics; dispose of it
50 typedef struct CF_BRIDGED_TYPE(id
) _CMSDecoder
*CMSDecoderRef
;
52 CFTypeID
CMSDecoderGetTypeID(void);
55 * Status of signature and signer information in a signed message.
57 typedef CF_ENUM(uint32_t, CMSSignerStatus
) {
58 kCMSSignerUnsigned
= 0, /* message was not signed */
59 kCMSSignerValid
, /* message was signed and signature verify OK */
60 kCMSSignerNeedsDetachedContent
, /* message was signed but needs detached content
62 kCMSSignerInvalidSignature
, /* message was signed but had a signature error */
63 kCMSSignerInvalidCert
, /* message was signed but an error occurred in verifying
64 * the signer's certificate */
65 kCMSSignerInvalidIndex
/* specified signer index out of range */
69 * Create a CMSDecoder. Result must eventually be freed via CFRelease().
71 OSStatus
CMSDecoderCreate(
72 CMSDecoderRef
* __nonnull CF_RETURNS_RETAINED cmsDecoderOut
) /* RETURNED */
73 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
76 * Feed raw bytes of the message to be decoded into the decoder. Can be called
78 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
81 OSStatus
CMSDecoderUpdateMessage(
82 CMSDecoderRef cmsDecoder
,
85 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
88 * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
89 * finish decoding the message.
90 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
93 OSStatus
CMSDecoderFinalizeMessage(
94 CMSDecoderRef cmsDecoder
)
95 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
98 * A signed CMS message optionally includes the data which was signed. If the
99 * message does not include the signed data, caller specifies the signed data
100 * (the "detached content") here.
102 * This can be called either before or after the actual decoding of the message
103 * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only
104 * restriction is that, if detached content is required, this function must
105 * be called befoere successfully ascertaining the signature status via
106 * CMSDecoderCopySignerStatus().
108 OSStatus
CMSDecoderSetDetachedContent(
109 CMSDecoderRef cmsDecoder
,
110 CFDataRef detachedContent
)
111 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
114 * Obtain the detached content specified in CMSDecoderSetDetachedContent().
115 * Returns a NULL detachedContent if no detached content has been specified.
116 * Caller must CFRelease() the result.
118 OSStatus
CMSDecoderCopyDetachedContent(
119 CMSDecoderRef cmsDecoder
,
120 CFDataRef
* __nonnull CF_RETURNS_RETAINED detachedContentOut
) /* RETURNED */
121 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
124 * This function no longer affects the behavior of the CMS Decoder. Please
127 OSStatus
CMSDecoderSetSearchKeychain(
128 CMSDecoderRef cmsDecoder
,
129 CFTypeRef keychainOrArray
)
130 __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_5
, __MAC_10_13
, __IPHONE_NA
, __IPHONE_NA
,
131 "To change the search keychains call SecKeychainSetSearchList.");
134 * Obtain the number of signers of a message. A result of zero indicates that
135 * the message was not signed.
136 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
138 OSStatus
CMSDecoderGetNumSigners(
139 CMSDecoderRef cmsDecoder
,
140 size_t *numSignersOut
) /* RETURNED */
141 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
144 * Obtain the status of a CMS message's signature. A CMS message can
145 * be signed my multiple signers; this function returns the status
146 * associated with signer 'n' as indicated by the signerIndex parameter.
148 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
150 * Note that signature and certificate verification of a decoded message
151 * does *not* occur until this routine is called.
153 * All returned values are optional - pass NULL if you don't need a
154 * particular parameter.
156 * Note that errors like "bad signature" and "bad cert" do NOT cause this
157 * routine to return a nonzero error status itself; such errors are reported
158 * in the various out parameters, listed below.
162 * cmsDecoder : a CMSDecoder which has successfully performed a
163 * CMSDecoderFinalizeMessage().
164 * signerIndex : indicates which of 'n' signers is being examined.
165 * Range is 0...(numSigners-1).
166 * policyOrArray : Either a SecPolicyRef or a CFArray of them.
167 * These policies are used to verify the signer's certificate.
168 * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the
169 * evaluation of the signer cert to actually be evaluated
170 * via SecTrustEvaluate(). When FALSE, the caller performs
171 * the SecTrustEvaluate() operation on the SecTrust object
172 * returned via the secTrust out parameter.
173 * NOTE: it is hazardous and not recommended to pass in FALSE
174 * for the evaluateSecTrust parameter as well as NULL for the
175 * secTrust out parameter, since no evaluation of the signer
176 * cert can occur in that situation.
180 * signerStatusOut -- An enum indicating the overall status.
181 * kCMSSignerUnsigned : message was not signed.
182 * kCMSSignerValid : both signature and signer certificate verified OK.
183 * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent()
184 * is required to ascertain the signature status.
185 * kCMSSignerInvalidSignature : bad signature.
186 * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate.
187 * Further information available via the secTrust and
188 * certVerifyResultCode parameters. This will never be
189 * returned if evaluateSecTrust is FALSE.
190 * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of
193 * secTrustOut -- The SecTrust object used to verify the signer's
194 * certificate. Caller must CFRelease this.
195 * certVerifyResultCodeOut -- The result of the certificate verification. If
196 * the evaluateSecTrust argument is set to FALSE on
197 * input, this out parameter is undefined on return.
199 * The certVerifyResultCode value can indicate a large number of errors; some of
200 * the most common and interesting errors are:
202 * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a
203 * self-signed (root) cert which was present in the message, but
204 * that root cert is not a known, trusted root cert.
205 * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to
207 * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does
209 * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested
211 * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert.
212 * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of
214 * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at
215 * the time of verification.
217 OSStatus
CMSDecoderCopySignerStatus(
218 CMSDecoderRef cmsDecoder
,
220 CFTypeRef policyOrArray
,
221 Boolean evaluateSecTrust
,
222 CMSSignerStatus
* __nullable signerStatusOut
, /* optional; RETURNED */
223 SecTrustRef
* __nullable CF_RETURNS_RETAINED secTrustOut
, /* optional; RETURNED */
224 OSStatus
* __nullable certVerifyResultCodeOut
) /* optional; RETURNED */
225 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
228 * Obtain the email address of signer 'signerIndex' of a CMS message, if
231 * Returns errSecParam if the CMS message was not signed or if signerIndex
232 * is greater than the number of signers of the message minus one.
234 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
236 OSStatus
CMSDecoderCopySignerEmailAddress(
237 CMSDecoderRef cmsDecoder
,
239 CFStringRef
* __nonnull CF_RETURNS_RETAINED signerEmailAddressOut
) /* RETURNED */
240 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
243 * Obtain the certificate of signer 'signerIndex' of a CMS message, if
246 * Returns errSecParam if the CMS message was not signed or if signerIndex
247 * is greater than the number of signers of the message minus one.
249 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
251 OSStatus
CMSDecoderCopySignerCert(
252 CMSDecoderRef cmsDecoder
,
254 SecCertificateRef
* __nonnull CF_RETURNS_RETAINED signerCertOut
) /* RETURNED */
255 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
258 * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not.
259 * Note that if the message was encrypted, and the decoding succeeded, (i.e.,
260 * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully
262 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
264 OSStatus
CMSDecoderIsContentEncrypted(
265 CMSDecoderRef cmsDecoder
,
266 Boolean
*isEncryptedOut
)
267 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
270 * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if
271 * present. If the message was not signed this will return NULL.
272 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
273 * The returned OID's data is in the same format as a CSSM_OID; i.e., it's
274 * the encoded content of the OID, not including the tag and length bytes.
276 OSStatus
CMSDecoderCopyEncapsulatedContentType(
277 CMSDecoderRef cmsDecoder
,
278 CFDataRef
* __nonnull CF_RETURNS_RETAINED eContentTypeOut
) /* RETURNED */
279 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
282 * Obtain an array of all of the certificates in a message. Elements of the
283 * returned array are SecCertificateRefs. The caller must CFRelease the returned
284 * array. If a message does not contain any certificates (which is the case for
285 * a message which is encrypted but not signed), the returned *certs value
286 * is NULL. The function will return errSecSuccess in this case.
287 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
289 OSStatus
CMSDecoderCopyAllCerts(
290 CMSDecoderRef cmsDecoder
,
291 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certsOut
) /* RETURNED */
292 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
295 * Obtain the actual message content (payload), if any. If the message was
296 * signed with detached content this will return NULL.
297 * Caller must CFRelease the result.
298 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
300 OSStatus
CMSDecoderCopyContent(
301 CMSDecoderRef cmsDecoder
,
302 CFDataRef
* __nonnull CF_RETURNS_RETAINED contentOut
) /* RETURNED */
303 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
306 * Obtain the signing time of signer 'signerIndex' of a CMS message, if
307 * present. This is an unauthenticate time, although it is part of the
308 * signed attributes of the message.
310 * Returns errSecParam if the CMS message was not signed or if signerIndex
311 * is greater than the number of signers of the message minus one.
313 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
315 OSStatus
CMSDecoderCopySignerSigningTime(
316 CMSDecoderRef cmsDecoder
,
318 CFAbsoluteTime
*signingTime
) /* RETURNED */
319 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
321 #define TIMESTAMPING_SUPPORTED 1
322 #if TIMESTAMPING_SUPPORTED
324 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if
325 * present. This timestamp is an authenticated timestamp provided by
326 * a timestamping authority.
328 * Returns errSecParam if the CMS message was not signed or if signerIndex
329 * is greater than the number of signers of the message minus one.
331 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
333 OSStatus
CMSDecoderCopySignerTimestamp(
334 CMSDecoderRef cmsDecoder
,
336 CFAbsoluteTime
*timestamp
) /* RETURNED */
337 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
340 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if
341 * present. This timestamp is an authenticated timestamp provided by
342 * a timestamping authority. Use the policy provided as a parameter
344 * Returns errSecParam if the CMS message was not signed or if signerIndex
345 * is greater than the number of signers of the message minus one.
347 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
349 OSStatus
CMSDecoderCopySignerTimestampWithPolicy(
350 CMSDecoderRef cmsDecoder
,
351 CFTypeRef __nullable timeStampPolicy
,
352 size_t signerIndex
, /* usually 0 */
353 CFAbsoluteTime
*timestamp
) /* RETURNED */
354 __OSX_AVAILABLE_STARTING(__MAC_10_10
, __IPHONE_NA
);
357 * Obtain an array of the certificates in a timestamp response. Elements of the
358 * returned array are SecCertificateRefs. The caller must CFRelease the returned
359 * array. This timestamp is an authenticated timestamp provided by
360 * a timestamping authority.
362 * Returns errSecParam if the CMS message was not signed or if signerIndex
363 * is greater than the number of signers of the message minus one. It returns
364 * errSecItemNotFound if no certificates were found.
366 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
368 OSStatus
CMSDecoderCopySignerTimestampCertificates(
369 CMSDecoderRef cmsDecoder
,
370 size_t signerIndex
, /* usually 0 */
371 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certificateRefs
) /* RETURNED */
372 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
373 #endif // TIMESTAMPING_SUPPORTED
375 CF_ASSUME_NONNULL_END
381 #endif /* _CMS_DECODER_H_ */