]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | /* | |
25 | * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the | |
26 | * Cryptographic Message Syntax (CMS), per RFC 3852. | |
27 | * | |
28 | * See CMSEncoder.h for general information about CMS messages. | |
29 | */ | |
30 | ||
31 | #ifndef _CMS_DECODER_H_ | |
32 | #define _CMS_DECODER_H_ | |
33 | ||
34 | #include <CoreFoundation/CoreFoundation.h> | |
35 | #include <Security/SecCertificate.h> | |
36 | #include <Security/SecTrust.h> | |
37 | #include <stdint.h> | |
38 | ||
39 | #ifdef __cplusplus | |
40 | extern "C" { | |
41 | #endif | |
42 | ||
43 | /* | |
44 | * Opaque reference to a CMS decoder object. | |
45 | * This is a CF object, with standard CF semantics; dispose of it | |
46 | * with CFRelease(). | |
47 | */ | |
48 | typedef struct _CMSDecoder *CMSDecoderRef; | |
49 | ||
50 | CFTypeID CMSDecoderGetTypeID(void); | |
51 | ||
52 | /* | |
53 | * Status of signature and signer information in a signed message. | |
54 | */ | |
55 | enum { | |
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 | |
59 | * to verify */ | |
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 */ | |
64 | }; | |
65 | typedef uint32_t CMSSignerStatus; | |
66 | ||
67 | /* | |
68 | * Create a CMSDecoder. Result must eventually be freed via CFRelease(). | |
69 | */ | |
70 | OSStatus CMSDecoderCreate( | |
71 | CMSDecoderRef *cmsDecoderOut) /* RETURNED */ | |
72 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
73 | ||
74 | /* | |
75 | * Feed raw bytes of the message to be decoded into the decoder. Can be called | |
76 | * multiple times. | |
77 | * Returns errSecUnknownFormat upon detection of improperly formatted CMS | |
78 | * message. | |
79 | */ | |
80 | OSStatus CMSDecoderUpdateMessage( | |
81 | CMSDecoderRef cmsDecoder, | |
82 | const void *msgBytes, | |
83 | size_t msgBytesLen) | |
84 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
85 | ||
86 | /* | |
87 | * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; | |
88 | * finish decoding the message. | |
89 | * Returns errSecUnknownFormat upon detection of improperly formatted CMS | |
90 | * message. | |
91 | */ | |
92 | OSStatus CMSDecoderFinalizeMessage( | |
93 | CMSDecoderRef cmsDecoder) | |
94 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
95 | ||
96 | /* | |
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. | |
100 | * | |
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(). | |
106 | */ | |
107 | OSStatus CMSDecoderSetDetachedContent( | |
108 | CMSDecoderRef cmsDecoder, | |
109 | CFDataRef detachedContent) | |
110 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
111 | ||
112 | /* | |
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. | |
116 | */ | |
117 | OSStatus CMSDecoderCopyDetachedContent( | |
118 | CMSDecoderRef cmsDecoder, | |
119 | CFDataRef *detachedContentOut) /* RETURNED */ | |
120 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
121 | ||
122 | /* | |
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 | |
127 | * certs. | |
128 | * If this is called, it must be called before CMSDecoderCopySignerStatus(). | |
129 | */ | |
130 | OSStatus CMSDecoderSetSearchKeychain( | |
131 | CMSDecoderRef cmsDecoder, | |
132 | CFTypeRef keychainOrArray) | |
133 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
134 | ||
135 | /* | |
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. | |
139 | */ | |
140 | OSStatus CMSDecoderGetNumSigners( | |
141 | CMSDecoderRef cmsDecoder, | |
142 | size_t *numSignersOut) /* RETURNED */ | |
143 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
144 | ||
145 | /* | |
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. | |
149 | * | |
150 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
151 | * | |
152 | * Note that signature and certificate verification of a decoded message | |
153 | * does *not* occur until this routine is called. | |
154 | * | |
155 | * All returned values are optional - pass NULL if you don't need a | |
156 | * particular parameter. | |
157 | * | |
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. | |
161 | * | |
162 | * Inputs: | |
163 | * ------- | |
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. | |
179 | * | |
180 | * Outputs: | |
181 | * -------- | |
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 | |
193 | * signers (minus 1). | |
194 | * | |
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. | |
200 | * | |
201 | * The certVerifyResultCode value can indicate a large number of errors; some of | |
202 | * the most common and interesting errors are: | |
203 | * | |
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 | |
208 | * a root cert. | |
209 | * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does | |
210 | * not self-verify. | |
211 | * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested | |
212 | * policy action. | |
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 | |
215 | * verification. | |
216 | * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at | |
217 | * the time of verification. | |
218 | */ | |
219 | OSStatus CMSDecoderCopySignerStatus( | |
220 | CMSDecoderRef cmsDecoder, | |
221 | size_t signerIndex, | |
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); | |
228 | ||
229 | /* | |
230 | * Obtain the email address of signer 'signerIndex' of a CMS message, if | |
231 | * present. | |
232 | * | |
427c49bc | 233 | * Returns errSecParam if the CMS message was not signed or if signerIndex |
b1ab9ed8 A |
234 | * is greater than the number of signers of the message minus one. |
235 | * | |
236 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
237 | */ | |
238 | OSStatus CMSDecoderCopySignerEmailAddress( | |
239 | CMSDecoderRef cmsDecoder, | |
240 | size_t signerIndex, | |
241 | CFStringRef *signerEmailAddressOut) /* RETURNED */ | |
242 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
243 | ||
244 | /* | |
245 | * Obtain the certificate of signer 'signerIndex' of a CMS message, if | |
246 | * present. | |
247 | * | |
427c49bc | 248 | * Returns errSecParam if the CMS message was not signed or if signerIndex |
b1ab9ed8 A |
249 | * is greater than the number of signers of the message minus one. |
250 | * | |
251 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
252 | */ | |
253 | OSStatus CMSDecoderCopySignerCert( | |
254 | CMSDecoderRef cmsDecoder, | |
255 | size_t signerIndex, | |
256 | SecCertificateRef *signerCertOut) /* RETURNED */ | |
257 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
258 | ||
259 | /* | |
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., | |
427c49bc | 262 | * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully |
b1ab9ed8 A |
263 | * decrypted. |
264 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
265 | */ | |
266 | OSStatus CMSDecoderIsContentEncrypted( | |
267 | CMSDecoderRef cmsDecoder, | |
268 | Boolean *isEncryptedOut) | |
269 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
270 | ||
271 | /* | |
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. | |
277 | */ | |
278 | OSStatus CMSDecoderCopyEncapsulatedContentType( | |
279 | CMSDecoderRef cmsDecoder, | |
280 | CFDataRef *eContentTypeOut) /* RETURNED */ | |
281 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
282 | ||
283 | /* | |
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 | |
427c49bc | 288 | * is NULL. The function will return errSecSuccess in this case. |
b1ab9ed8 A |
289 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. |
290 | */ | |
291 | OSStatus CMSDecoderCopyAllCerts( | |
292 | CMSDecoderRef cmsDecoder, | |
293 | CFArrayRef *certsOut) /* RETURNED */ | |
294 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
295 | ||
296 | /* | |
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. | |
301 | */ | |
302 | OSStatus CMSDecoderCopyContent( | |
303 | CMSDecoderRef cmsDecoder, | |
304 | CFDataRef *contentOut) /* RETURNED */ | |
305 | __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); | |
306 | ||
307 | /* | |
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. | |
311 | * | |
427c49bc | 312 | * Returns errSecParam if the CMS message was not signed or if signerIndex |
b1ab9ed8 A |
313 | * is greater than the number of signers of the message minus one. |
314 | * | |
315 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
316 | */ | |
317 | OSStatus CMSDecoderCopySignerSigningTime( | |
318 | CMSDecoderRef cmsDecoder, | |
319 | size_t signerIndex, | |
320 | CFAbsoluteTime *signingTime) /* RETURNED */ | |
321 | __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); | |
322 | ||
323 | /* | |
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. | |
327 | * | |
427c49bc | 328 | * Returns errSecParam if the CMS message was not signed or if signerIndex |
b1ab9ed8 A |
329 | * is greater than the number of signers of the message minus one. |
330 | * | |
331 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
332 | */ | |
333 | OSStatus CMSDecoderCopySignerTimestamp( | |
334 | CMSDecoderRef cmsDecoder, | |
335 | size_t signerIndex, | |
336 | CFAbsoluteTime *timestamp) /* RETURNED */ | |
337 | __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); | |
338 | ||
339 | /* | |
340 | * Obtain an array of the certificates in a timestamp response. Elements of the | |
341 | * returned array are SecCertificateRefs. The caller must CFRelease the returned | |
342 | * array. This timestamp is an authenticated timestamp provided by | |
343 | * a timestamping authority. | |
344 | * | |
427c49bc | 345 | * Returns errSecParam if the CMS message was not signed or if signerIndex |
b1ab9ed8 A |
346 | * is greater than the number of signers of the message minus one. It returns |
347 | * errSecItemNotFound if no certificates were found. | |
348 | * | |
349 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
350 | */ | |
351 | OSStatus CMSDecoderCopySignerTimestampCertificates( | |
352 | CMSDecoderRef cmsDecoder, | |
353 | size_t signerIndex, /* usually 0 */ | |
354 | CFArrayRef *certificateRefs) /* RETURNED */ | |
355 | __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); | |
356 | ||
357 | #ifdef __cplusplus | |
358 | } | |
359 | #endif | |
360 | ||
361 | #endif /* _CMS_DECODER_H_ */ | |
362 |