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>
44 * Opaque reference to a CMS decoder object.
45 * This is a CF object, with standard CF semantics; dispose of it
48 typedef struct _CMSDecoder
*CMSDecoderRef
;
50 CFTypeID
CMSDecoderGetTypeID(void);
53 * Status of signature and signer information in a signed message.
56 kCMSSignerUnsigned
= 0, /* message was not signed */
57 kCMSSignerValid
, /* message was signed and signature verify OK */
58 kCMSSignerNeedsDetachedContent
, /* message was signed but needs detached content
60 kCMSSignerInvalidSignature
, /* message was signed but had a signature error */
61 kCMSSignerInvalidCert
, /* message was signed but an error occurred in verifying
62 * the signer's certificate */
63 kCMSSignerInvalidIndex
/* specified signer index out of range */
65 typedef uint32_t CMSSignerStatus
;
68 * Create a CMSDecoder. Result must eventually be freed via CFRelease().
70 OSStatus
CMSDecoderCreate(
71 CMSDecoderRef
*cmsDecoderOut
) /* RETURNED */
72 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
75 * Feed raw bytes of the message to be decoded into the decoder. Can be called
77 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
80 OSStatus
CMSDecoderUpdateMessage(
81 CMSDecoderRef cmsDecoder
,
84 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
87 * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
88 * finish decoding the message.
89 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
92 OSStatus
CMSDecoderFinalizeMessage(
93 CMSDecoderRef cmsDecoder
)
94 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
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_NA
);
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
*detachedContentOut
) /* RETURNED */
120 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
123 * Optionally specify a SecKeychainRef, or an array of them, containing
124 * intermediate certs to be used in verifying a signed message's signer
125 * certs. By default, the default keychain search list is used for this.
126 * Specify an empty CFArrayRef to search *no* keychains for intermediate
128 * If this is called, it must be called before CMSDecoderCopySignerStatus().
130 OSStatus
CMSDecoderSetSearchKeychain(
131 CMSDecoderRef cmsDecoder
,
132 CFTypeRef keychainOrArray
)
133 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
136 * Obtain the number of signers of a message. A result of zero indicates that
137 * the message was not signed.
138 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
140 OSStatus
CMSDecoderGetNumSigners(
141 CMSDecoderRef cmsDecoder
,
142 size_t *numSignersOut
) /* RETURNED */
143 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
146 * Obtain the status of a CMS message's signature. A CMS message can
147 * be signed my multiple signers; this function returns the status
148 * associated with signer 'n' as indicated by the signerIndex parameter.
150 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
152 * Note that signature and certificate verification of a decoded message
153 * does *not* occur until this routine is called.
155 * All returned values are optional - pass NULL if you don't need a
156 * particular parameter.
158 * Note that errors like "bad signature" and "bad cert" do NOT cause this
159 * routine to return a nonzero error status itself; such errors are reported
160 * in the various out parameters, listed below.
164 * cmsDecoder : a CMSDecoder which has successfully performed a
165 * CMSDecoderFinalizeMessage().
166 * signerIndex : indicates which of 'n' signers is being examined.
167 * Range is 0...(numSigners-1).
168 * policyOrArray : Either a SecPolicyRef or a CFArray of them.
169 * These policies are used to verify the signer's certificate.
170 * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the
171 * evaluation of the signer cert to actually be evaluated
172 * via SecTrustEvaluate(). When FALSE, the caller performs
173 * the SecTrustEvaluate() operation on the SecTrust object
174 * returned via the secTrust out parameter.
175 * NOTE: it is hazardous and not recommended to pass in FALSE
176 * for the evaluateSecTrust parameter as well as NULL for the
177 * secTrust out parameter, since no evaluation of the signer
178 * cert can occur in that situation.
182 * signerStatusOut -- An enum indicating the overall status.
183 * kCMSSignerUnsigned : message was not signed.
184 * kCMSSignerValid : both signature and signer certificate verified OK.
185 * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent()
186 * is required to ascertain the signature status.
187 * kCMSSignerInvalidSignature : bad signature.
188 * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate.
189 * Further information available via the secTrust and
190 * certVerifyResultCode parameters. This will never be
191 * returned if evaluateSecTrust is FALSE.
192 * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of
195 * secTrustOut -- The SecTrust object used to verify the signer's
196 * certificate. Caller must CFRelease this.
197 * certVerifyResultCodeOut -- The result of the certificate verification. If
198 * the evaluateSecTrust argument is set to FALSE on
199 * input, this out parameter is undefined on return.
201 * The certVerifyResultCode value can indicate a large number of errors; some of
202 * the most common and interesting errors are:
204 * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a
205 * self-signed (root) cert which was present in the message, but
206 * that root cert is not a known, trusted root cert.
207 * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to
209 * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does
211 * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested
213 * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert.
214 * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of
216 * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at
217 * the time of verification.
219 OSStatus
CMSDecoderCopySignerStatus(
220 CMSDecoderRef cmsDecoder
,
222 CFTypeRef policyOrArray
,
223 Boolean evaluateSecTrust
,
224 CMSSignerStatus
*signerStatusOut
, /* optional; RETURNED */
225 SecTrustRef
*secTrustOut
, /* optional; RETURNED */
226 OSStatus
*certVerifyResultCodeOut
) /* optional; RETURNED */
227 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
230 * Obtain the email address of signer 'signerIndex' of a CMS message, if
233 * Returns errSecParam if the CMS message was not signed or if signerIndex
234 * is greater than the number of signers of the message minus one.
236 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
238 OSStatus
CMSDecoderCopySignerEmailAddress(
239 CMSDecoderRef cmsDecoder
,
241 CFStringRef
*signerEmailAddressOut
) /* RETURNED */
242 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
245 * Obtain the certificate of signer 'signerIndex' of a CMS message, if
248 * Returns errSecParam if the CMS message was not signed or if signerIndex
249 * is greater than the number of signers of the message minus one.
251 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
253 OSStatus
CMSDecoderCopySignerCert(
254 CMSDecoderRef cmsDecoder
,
256 SecCertificateRef
*signerCertOut
) /* RETURNED */
257 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
260 * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not.
261 * Note that if the message was encrypted, and the decoding succeeded, (i.e.,
262 * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully
264 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
266 OSStatus
CMSDecoderIsContentEncrypted(
267 CMSDecoderRef cmsDecoder
,
268 Boolean
*isEncryptedOut
)
269 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
272 * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if
273 * present. If the message was not signed this will return NULL.
274 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
275 * The returned OID's data is in the same format as a CSSM_OID; i.e., it's
276 * the encoded content of the OID, not including the tag and length bytes.
278 OSStatus
CMSDecoderCopyEncapsulatedContentType(
279 CMSDecoderRef cmsDecoder
,
280 CFDataRef
*eContentTypeOut
) /* RETURNED */
281 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
284 * Obtain an array of all of the certificates in a message. Elements of the
285 * returned array are SecCertificateRefs. The caller must CFRelease the returned
286 * array. If a message does not contain any certificates (which is the case for
287 * a message which is encrypted but not signed), the returned *certs value
288 * is NULL. The function will return errSecSuccess in this case.
289 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
291 OSStatus
CMSDecoderCopyAllCerts(
292 CMSDecoderRef cmsDecoder
,
293 CFArrayRef
*certsOut
) /* RETURNED */
294 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
297 * Obtain the actual message content (payload), if any. If the message was
298 * signed with detached content this will return NULL.
299 * Caller must CFRelease the result.
300 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
302 OSStatus
CMSDecoderCopyContent(
303 CMSDecoderRef cmsDecoder
,
304 CFDataRef
*contentOut
) /* RETURNED */
305 __OSX_AVAILABLE_STARTING(__MAC_10_5
, __IPHONE_NA
);
308 * Obtain the signing time of signer 'signerIndex' of a CMS message, if
309 * present. This is an unauthenticate time, although it is part of the
310 * signed attributes of the message.
312 * Returns errSecParam if the CMS message was not signed or if signerIndex
313 * is greater than the number of signers of the message minus one.
315 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
317 OSStatus
CMSDecoderCopySignerSigningTime(
318 CMSDecoderRef cmsDecoder
,
320 CFAbsoluteTime
*signingTime
) /* RETURNED */
321 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
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 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
*certificateRefs
) /* RETURNED */
372 __OSX_AVAILABLE_STARTING(__MAC_10_8
, __IPHONE_NA
);
378 #endif /* _CMS_DECODER_H_ */