2 * Copyright (c) 2006-2016 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>
37 #include <Security/SecCmsDecoder.h>
38 #include <Security/SecCmsMessage.h>
39 #include <AvailabilityMacros.h>
44 CF_ASSUME_NONNULL_BEGIN
47 * Opaque reference to a CMS decoder object.
48 * This is a CF object, with standard CF semantics; dispose of it
51 typedef struct CF_BRIDGED_TYPE(id
) _CMSDecoder
*CMSDecoderRef
;
53 CFTypeID
CMSDecoderGetTypeID(void);
56 * Status of signature and signer information in a signed message.
58 typedef CF_ENUM(int32_t, CMSSignerStatus
) {
59 kCMSSignerUnsigned
= 0, /* message was not signed */
60 kCMSSignerValid
, /* message was signed and signature verify OK */
61 kCMSSignerNeedsDetachedContent
, /* message was signed but needs detached content
63 kCMSSignerInvalidSignature
, /* message was signed but had a signature error */
64 kCMSSignerInvalidCert
, /* message was signed but an error occurred in verifying
65 * the signer's certificate */
66 kCMSSignerInvalidIndex
/* specified signer index out of range */
70 * Create a CMSDecoder. Result must eventually be freed via CFRelease().
72 OSStatus
CMSDecoderCreate(CMSDecoderRef
* __nonnull CF_RETURNS_RETAINED cmsDecoderOut
) /* RETURNED */
73 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
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_11_0
);
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(CMSDecoderRef cmsDecoder
)
94 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
97 * A signed CMS message optionally includes the data which was signed. If the
98 * message does not include the signed data, caller specifies the signed data
99 * (the "detached content") here.
101 * This can be called either before or after the actual decoding of the message
102 * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only
103 * restriction is that, if detached content is required, this function must
104 * be called befoere successfully ascertaining the signature status via
105 * CMSDecoderCopySignerStatus().
107 OSStatus
CMSDecoderSetDetachedContent(
108 CMSDecoderRef cmsDecoder
,
109 CFDataRef detachedContent
)
110 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
113 * Obtain the detached content specified in CMSDecoderSetDetachedContent().
114 * Returns a NULL detachedContent if no detached content has been specified.
115 * Caller must CFRelease() the result.
117 OSStatus
CMSDecoderCopyDetachedContent(
118 CMSDecoderRef cmsDecoder
,
119 CFDataRef
* __nonnull CF_RETURNS_RETAINED detachedContentOut
) /* RETURNED */
120 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
123 * Obtain the number of signers of a message. A result of zero indicates that
124 * the message was not signed.
125 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
127 OSStatus
CMSDecoderGetNumSigners(
128 CMSDecoderRef cmsDecoder
,
129 size_t *numSignersOut
) /* RETURNED */
130 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
133 * Obtain the status of a CMS message's signature. A CMS message can
134 * be signed my multiple signers; this function returns the status
135 * associated with signer 'n' as indicated by the signerIndex parameter.
137 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
139 * Note that signature and certificate verification of a decoded message
140 * does *not* occur until this routine is called.
142 * All returned values are optional - pass NULL if you don't need a
143 * particular parameter.
145 * Note that errors like "bad signature" and "bad cert" do NOT cause this
146 * routine to return a nonzero error status itself; such errors are reported
147 * in the various out parameters, listed below.
151 * cmsDecoder : a CMSDecoder which has successfully performed a
152 * CMSDecoderFinalizeMessage().
153 * signerIndex : indicates which of 'n' signers is being examined.
154 * Range is 0...(numSigners-1).
155 * policyOrArray : Either a SecPolicyRef or a CFArray of them.
156 * These policies are used to verify the signer's certificate.
157 * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the
158 * evaluation of the signer cert to actually be evaluated
159 * via SecTrustEvaluate(). When FALSE, the caller performs
160 * the SecTrustEvaluate() operation on the SecTrust object
161 * returned via the secTrust out parameter.
162 * NOTE: it is hazardous and not recommended to pass in FALSE
163 * for the evaluateSecTrust parameter as well as NULL for the
164 * secTrust out parameter, since no evaluation of the signer
165 * cert can occur in that situation.
169 * signerStatusOut -- An enum indicating the overall status.
170 * kCMSSignerUnsigned : message was not signed.
171 * kCMSSignerValid : both signature and signer certificate verified OK.
172 * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent()
173 * is required to ascertain the signature status.
174 * kCMSSignerInvalidSignature : bad signature.
175 * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate.
176 * Further information available via the secTrust and
177 * certVerifyResultCode parameters. This will never be
178 * returned if evaluateSecTrust is FALSE.
179 * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of
182 * secTrustOut -- The SecTrust object used to verify the signer's
183 * certificate. Caller must CFRelease this.
184 * certVerifyResultCodeOut -- The result of the certificate verification. If
185 * the evaluateSecTrust argument is set to FALSE on
186 * input, this out parameter is undefined on return.
188 * The certVerifyResultCode value can indicate a large number of errors; some of
189 * the most common and interesting errors are:
191 * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a
192 * self-signed (root) cert which was present in the message, but
193 * that root cert is not a known, trusted root cert.
194 * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to
196 * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does
198 * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested
200 * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert.
201 * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of
203 * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at
204 * the time of verification.
206 OSStatus
CMSDecoderCopySignerStatus(
207 CMSDecoderRef cmsDecoder
,
209 CFTypeRef policyOrArray
,
210 Boolean evaluateSecTrust
,
211 CMSSignerStatus
* __nullable signerStatusOut
, /* optional; RETURNED */
212 SecTrustRef
* __nullable CF_RETURNS_RETAINED secTrustOut
, /* optional; RETURNED */
213 OSStatus
* __nullable certVerifyResultCodeOut
) /* optional; RETURNED */
214 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
217 * Obtain the email address of signer 'signerIndex' of a CMS message, if
220 * Returns errSecParam if the CMS message was not signed or if signerIndex
221 * is greater than the number of signers of the message minus one.
223 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
225 OSStatus
CMSDecoderCopySignerEmailAddress(
226 CMSDecoderRef cmsDecoder
,
228 CFStringRef
* __nonnull CF_RETURNS_RETAINED signerEmailAddressOut
) /* RETURNED */
229 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
232 * Obtain the certificate of signer 'signerIndex' of a CMS message, if
235 * Returns errSecParam if the CMS message was not signed or if signerIndex
236 * is greater than the number of signers of the message minus one.
238 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
240 OSStatus
CMSDecoderCopySignerCert(
241 CMSDecoderRef cmsDecoder
,
243 SecCertificateRef
* __nonnull CF_RETURNS_RETAINED signerCertOut
) /* RETURNED */
244 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
247 * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not.
248 * Note that if the message was encrypted, and the decoding succeeded, (i.e.,
249 * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully
251 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
253 OSStatus
CMSDecoderIsContentEncrypted(
254 CMSDecoderRef cmsDecoder
,
255 Boolean
*isEncryptedOut
)
256 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
259 * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if
260 * present. If the message was not signed this will return NULL.
261 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
262 * The returned OID's data is in the same format as a CSSM_OID; i.e., it's
263 * the encoded content of the OID, not including the tag and length bytes.
265 OSStatus
CMSDecoderCopyEncapsulatedContentType(
266 CMSDecoderRef cmsDecoder
,
267 CFDataRef
* __nonnull CF_RETURNS_RETAINED eContentTypeOut
) /* RETURNED */
268 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
271 * Obtain an array of all of the certificates in a message. Elements of the
272 * returned array are SecCertificateRefs. The caller must CFRelease the returned
273 * array. If a message does not contain any certificates (which is the case for
274 * a message which is encrypted but not signed), the returned *certs value
275 * is NULL. The function will return errSecSuccess in this case.
276 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
278 OSStatus
CMSDecoderCopyAllCerts(
279 CMSDecoderRef cmsDecoder
,
280 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certsOut
) /* RETURNED */
281 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
284 * Obtain the actual message content (payload), if any. If the message was
285 * signed with detached content this will return NULL.
286 * Caller must CFRelease the result.
287 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
289 OSStatus
CMSDecoderCopyContent(
290 CMSDecoderRef cmsDecoder
,
291 CFDataRef
* __nonnull CF_RETURNS_RETAINED contentOut
) /* RETURNED */
292 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_11_0
);
295 * Obtain the signing time of signer 'signerIndex' of a CMS message, if
296 * present. This is an unauthenticate time, although it is part of the
297 * signed attributes of the message.
299 * Returns errSecParam if the CMS message was not signed or if signerIndex
300 * is greater than the number of signers of the message minus one.
302 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
304 OSStatus
CMSDecoderCopySignerSigningTime(
305 CMSDecoderRef cmsDecoder
,
307 CFAbsoluteTime
*signingTime
) /* RETURNED */
308 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_11_0
);
310 #if TIMESTAMPING_SUPPORTED
312 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if
313 * present. This timestamp is an authenticated timestamp provided by
314 * a timestamping authority.
316 * Returns errSecParam if the CMS message was not signed or if signerIndex
317 * is greater than the number of signers of the message minus one.
319 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
321 OSStatus
CMSDecoderCopySignerTimestamp(
322 CMSDecoderRef cmsDecoder
,
324 CFAbsoluteTime
*timestamp
) /* RETURNED */
325 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
328 * Obtain the timestamp of signer 'signerIndex' of a CMS message, if
329 * present. This timestamp is an authenticated timestamp provided by
330 * a timestamping authority. Use the policy provided as a parameter
332 * Returns errSecParam if the CMS message was not signed or if signerIndex
333 * is greater than the number of signers of the message minus one.
335 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
337 OSStatus
CMSDecoderCopySignerTimestampWithPolicy(
338 CMSDecoderRef cmsDecoder
,
339 CFTypeRef __nullable timeStampPolicy
,
340 size_t signerIndex
, /* usually 0 */
341 CFAbsoluteTime
*timestamp
) /* RETURNED */
342 __OSX_AVAILABLE_STARTING(__MAC_10_10
, __IPHONE_NA
);
345 * Obtain an array of the certificates in a timestamp response. Elements of the
346 * returned array are SecCertificateRefs. The caller must CFRelease the returned
347 * array. This timestamp is an authenticated timestamp provided by
348 * a timestamping authority.
350 * Returns errSecParam if the CMS message was not signed or if signerIndex
351 * is greater than the number of signers of the message minus one. It returns
352 * errSecItemNotFound if no certificates were found.
354 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
356 OSStatus
CMSDecoderCopySignerTimestampCertificates(
357 CMSDecoderRef cmsDecoder
,
358 size_t signerIndex
, /* usually 0 */
359 CFArrayRef
* __nonnull CF_RETURNS_RETAINED certificateRefs
) /* RETURNED */
360 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
364 * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended
365 * to be called after decoding the message (i.e., after
366 * CMSDecoderFinalizeMessage() to gain finer access to the contents of the
367 * SecCmsMessageRef than is otherwise available via the CMSDecoder interface.
368 * Returns a NULL SecCmsMessageRef if CMSDecoderFinalizeMessage() has not been
371 * The CMSDecoder retains ownership of the returned SecCmsMessageRef.
373 OSStatus
CMSDecoderGetCmsMessage(
374 CMSDecoderRef cmsDecoder
,
375 SecCmsMessageRef _Nullable
* _Nonnull cmsMessage
); /* RETURNED */
379 * Optionally specify a SecCmsDecoderRef to use with a CMSDecoderRef.
380 * If this is called, it must be called before the first call to
381 * CMSDecoderUpdateMessage(). The CMSDecoderRef takes ownership of the
382 * incoming SecCmsDecoderRef.
384 OSStatus
CMSDecoderSetDecoder(
385 CMSDecoderRef cmsDecoder
,
386 SecCmsDecoderRef decoder
);
389 * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef.
390 * Returns a NULL SecCmsDecoderRef if neither CMSDecoderSetDecoder() nor
391 * CMSDecoderUpdateMessage() has been called.
392 * The CMSDecoderRef retains ownership of the SecCmsDecoderRef.
394 OSStatus
CMSDecoderGetDecoder(
395 CMSDecoderRef cmsDecoder
,
396 SecCmsDecoderRef _Nullable
* _Nonnull decoder
); /* RETURNED */
399 * Obtain the Hash Agility attribute value of signer 'signerIndex'
400 * of a CMS message, if present.
402 * Returns errSecParam if the CMS message was not signed or if signerIndex
403 * is greater than the number of signers of the message minus one.
405 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
407 OSStatus
CMSDecoderCopySignerAppleCodesigningHashAgility(
408 CMSDecoderRef cmsDecoder
,
409 size_t signerIndex
, /* usually 0 */
410 CFDataRef _Nullable CF_RETURNS_RETAINED
* _Nonnull hashAgilityAttrValue
) /* RETURNED */
411 API_AVAILABLE(macos(10.12.4), ios(11.0));
414 * Obtain the Hash Agility v2 attribute value of signer 'signerIndex'
415 * of a CMS message, if present. V2 encodes the hash agility values using DER.
417 * Returns errSecParam if the CMS message was not signed or if signerIndex
418 * is greater than the number of signers of the message minus one.
420 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
422 OSStatus
CMSDecoderCopySignerAppleCodesigningHashAgilityV2(
423 CMSDecoderRef cmsDecoder
,
424 size_t signerIndex
, /* usually 0 */
425 CFDictionaryRef _Nullable CF_RETURNS_RETAINED
* _Nonnull hashAgilityAttrValues
) /* RETURNED */
426 API_AVAILABLE(macos(10.13.4), ios(11.3));
429 * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
430 * present. This is part of the signed attributes of the message.
432 * Returns errSecParam if the CMS message was not signed or if signerIndex
433 * is greater than the number of signers of the message minus one.
435 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
437 OSStatus
CMSDecoderCopySignerAppleExpirationTime(
438 CMSDecoderRef cmsDecoder
,
440 CFAbsoluteTime
*expirationTime
) /* RETURNED */
441 API_AVAILABLE(macos(10.14), ios(12.0));
444 CF_ASSUME_NONNULL_END
448 #endif /* _CMS_DECODER_H_ */