]>
Commit | Line | Data |
---|---|---|
866f8763 | 1 | /* |
b54c578e | 2 | * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. |
866f8763 A |
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> | |
866f8763 A |
37 | #include <AvailabilityMacros.h> |
38 | #include <stdint.h> | |
39 | ||
40 | __BEGIN_DECLS | |
41 | ||
42 | CF_ASSUME_NONNULL_BEGIN | |
43 | ||
44 | /* | |
45 | * Opaque reference to a CMS decoder object. | |
46 | * This is a CF object, with standard CF semantics; dispose of it | |
47 | * with CFRelease(). | |
48 | */ | |
49 | typedef struct CF_BRIDGED_TYPE(id) _CMSDecoder *CMSDecoderRef; | |
50 | ||
51 | CFTypeID CMSDecoderGetTypeID(void); | |
52 | ||
53 | /* | |
54 | * Status of signature and signer information in a signed message. | |
55 | */ | |
b54c578e | 56 | typedef CF_ENUM(uint32_t, CMSSignerStatus) { |
866f8763 A |
57 | kCMSSignerUnsigned = 0, /* message was not signed */ |
58 | kCMSSignerValid, /* message was signed and signature verify OK */ | |
59 | kCMSSignerNeedsDetachedContent, /* message was signed but needs detached content | |
60 | * to verify */ | |
61 | kCMSSignerInvalidSignature, /* message was signed but had a signature error */ | |
62 | kCMSSignerInvalidCert, /* message was signed but an error occurred in verifying | |
63 | * the signer's certificate */ | |
64 | kCMSSignerInvalidIndex /* specified signer index out of range */ | |
65 | }; | |
66 | ||
67 | /* | |
68 | * Create a CMSDecoder. Result must eventually be freed via CFRelease(). | |
69 | */ | |
70 | OSStatus CMSDecoderCreate(CMSDecoderRef * __nonnull CF_RETURNS_RETAINED cmsDecoderOut) /* RETURNED */ | |
d64be36e | 71 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
72 | |
73 | /* | |
74 | * Feed raw bytes of the message to be decoded into the decoder. Can be called | |
75 | * multiple times. | |
76 | * Returns errSecUnknownFormat upon detection of improperly formatted CMS | |
77 | * message. | |
78 | */ | |
79 | OSStatus CMSDecoderUpdateMessage( | |
80 | CMSDecoderRef cmsDecoder, | |
81 | const void *msgBytes, | |
82 | size_t msgBytesLen) | |
d64be36e | 83 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
84 | |
85 | /* | |
86 | * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; | |
87 | * finish decoding the message. | |
88 | * Returns errSecUnknownFormat upon detection of improperly formatted CMS | |
89 | * message. | |
90 | */ | |
91 | OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder) | |
d64be36e | 92 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
93 | |
94 | /* | |
95 | * A signed CMS message optionally includes the data which was signed. If the | |
96 | * message does not include the signed data, caller specifies the signed data | |
97 | * (the "detached content") here. | |
98 | * | |
99 | * This can be called either before or after the actual decoding of the message | |
100 | * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only | |
101 | * restriction is that, if detached content is required, this function must | |
102 | * be called befoere successfully ascertaining the signature status via | |
103 | * CMSDecoderCopySignerStatus(). | |
104 | */ | |
105 | OSStatus CMSDecoderSetDetachedContent( | |
106 | CMSDecoderRef cmsDecoder, | |
107 | CFDataRef detachedContent) | |
d64be36e | 108 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
109 | |
110 | /* | |
111 | * Obtain the detached content specified in CMSDecoderSetDetachedContent(). | |
112 | * Returns a NULL detachedContent if no detached content has been specified. | |
113 | * Caller must CFRelease() the result. | |
114 | */ | |
115 | OSStatus CMSDecoderCopyDetachedContent( | |
116 | CMSDecoderRef cmsDecoder, | |
117 | CFDataRef * __nonnull CF_RETURNS_RETAINED detachedContentOut) /* RETURNED */ | |
d64be36e | 118 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
b54c578e A |
119 | |
120 | #if SEC_OS_OSX | |
121 | /* | |
122 | * This function no longer affects the behavior of the CMS Decoder. Please | |
123 | * discontinue use. | |
124 | */ | |
125 | OSStatus CMSDecoderSetSearchKeychain( | |
126 | CMSDecoderRef cmsDecoder, | |
127 | CFTypeRef keychainOrArray) | |
d64be36e | 128 | API_DEPRECATED_WITH_REPLACEMENT("SecKeychainSetSearchList",macos(10.5, 10.13)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); |
b54c578e | 129 | #endif // SEC_OS_OSX |
866f8763 A |
130 | |
131 | /* | |
132 | * Obtain the number of signers of a message. A result of zero indicates that | |
133 | * the message was not signed. | |
134 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
135 | */ | |
136 | OSStatus CMSDecoderGetNumSigners( | |
137 | CMSDecoderRef cmsDecoder, | |
138 | size_t *numSignersOut) /* RETURNED */ | |
d64be36e | 139 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
140 | |
141 | /* | |
142 | * Obtain the status of a CMS message's signature. A CMS message can | |
143 | * be signed my multiple signers; this function returns the status | |
144 | * associated with signer 'n' as indicated by the signerIndex parameter. | |
145 | * | |
146 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
147 | * | |
148 | * Note that signature and certificate verification of a decoded message | |
149 | * does *not* occur until this routine is called. | |
150 | * | |
151 | * All returned values are optional - pass NULL if you don't need a | |
152 | * particular parameter. | |
153 | * | |
154 | * Note that errors like "bad signature" and "bad cert" do NOT cause this | |
155 | * routine to return a nonzero error status itself; such errors are reported | |
156 | * in the various out parameters, listed below. | |
157 | * | |
158 | * Inputs: | |
159 | * ------- | |
160 | * cmsDecoder : a CMSDecoder which has successfully performed a | |
161 | * CMSDecoderFinalizeMessage(). | |
162 | * signerIndex : indicates which of 'n' signers is being examined. | |
163 | * Range is 0...(numSigners-1). | |
164 | * policyOrArray : Either a SecPolicyRef or a CFArray of them. | |
165 | * These policies are used to verify the signer's certificate. | |
166 | * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the | |
167 | * evaluation of the signer cert to actually be evaluated | |
168 | * via SecTrustEvaluate(). When FALSE, the caller performs | |
169 | * the SecTrustEvaluate() operation on the SecTrust object | |
170 | * returned via the secTrust out parameter. | |
171 | * NOTE: it is hazardous and not recommended to pass in FALSE | |
172 | * for the evaluateSecTrust parameter as well as NULL for the | |
173 | * secTrust out parameter, since no evaluation of the signer | |
174 | * cert can occur in that situation. | |
175 | * | |
176 | * Outputs: | |
177 | * -------- | |
178 | * signerStatusOut -- An enum indicating the overall status. | |
179 | * kCMSSignerUnsigned : message was not signed. | |
180 | * kCMSSignerValid : both signature and signer certificate verified OK. | |
181 | * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent() | |
182 | * is required to ascertain the signature status. | |
183 | * kCMSSignerInvalidSignature : bad signature. | |
184 | * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate. | |
185 | * Further information available via the secTrust and | |
186 | * certVerifyResultCode parameters. This will never be | |
187 | * returned if evaluateSecTrust is FALSE. | |
188 | * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of | |
189 | * signers (minus 1). | |
190 | * | |
191 | * secTrustOut -- The SecTrust object used to verify the signer's | |
192 | * certificate. Caller must CFRelease this. | |
193 | * certVerifyResultCodeOut -- The result of the certificate verification. If | |
194 | * the evaluateSecTrust argument is set to FALSE on | |
195 | * input, this out parameter is undefined on return. | |
196 | * | |
197 | * The certVerifyResultCode value can indicate a large number of errors; some of | |
198 | * the most common and interesting errors are: | |
199 | * | |
200 | * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a | |
201 | * self-signed (root) cert which was present in the message, but | |
202 | * that root cert is not a known, trusted root cert. | |
203 | * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to | |
204 | * a root cert. | |
205 | * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does | |
206 | * not self-verify. | |
207 | * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested | |
208 | * policy action. | |
209 | * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert. | |
210 | * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of | |
211 | * verification. | |
212 | * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at | |
213 | * the time of verification. | |
214 | */ | |
215 | OSStatus CMSDecoderCopySignerStatus( | |
216 | CMSDecoderRef cmsDecoder, | |
217 | size_t signerIndex, | |
218 | CFTypeRef policyOrArray, | |
219 | Boolean evaluateSecTrust, | |
220 | CMSSignerStatus * __nullable signerStatusOut, /* optional; RETURNED */ | |
221 | SecTrustRef * __nullable CF_RETURNS_RETAINED secTrustOut, /* optional; RETURNED */ | |
222 | OSStatus * __nullable certVerifyResultCodeOut) /* optional; RETURNED */ | |
d64be36e | 223 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
224 | |
225 | /* | |
226 | * Obtain the email address of signer 'signerIndex' of a CMS message, if | |
227 | * present. | |
228 | * | |
229 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
230 | * is greater than the number of signers of the message minus one. | |
231 | * | |
232 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
233 | */ | |
234 | OSStatus CMSDecoderCopySignerEmailAddress( | |
235 | CMSDecoderRef cmsDecoder, | |
236 | size_t signerIndex, | |
237 | CFStringRef * __nonnull CF_RETURNS_RETAINED signerEmailAddressOut) /* RETURNED */ | |
d64be36e | 238 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
239 | |
240 | /* | |
241 | * Obtain the certificate of signer 'signerIndex' of a CMS message, if | |
242 | * present. | |
243 | * | |
244 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
245 | * is greater than the number of signers of the message minus one. | |
246 | * | |
247 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
248 | */ | |
249 | OSStatus CMSDecoderCopySignerCert( | |
250 | CMSDecoderRef cmsDecoder, | |
251 | size_t signerIndex, | |
252 | SecCertificateRef * __nonnull CF_RETURNS_RETAINED signerCertOut) /* RETURNED */ | |
d64be36e | 253 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
254 | |
255 | /* | |
256 | * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. | |
257 | * Note that if the message was encrypted, and the decoding succeeded, (i.e., | |
258 | * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully | |
259 | * decrypted. | |
260 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
261 | */ | |
262 | OSStatus CMSDecoderIsContentEncrypted( | |
263 | CMSDecoderRef cmsDecoder, | |
264 | Boolean *isEncryptedOut) | |
d64be36e | 265 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
266 | |
267 | /* | |
268 | * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if | |
269 | * present. If the message was not signed this will return NULL. | |
270 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
271 | * The returned OID's data is in the same format as a CSSM_OID; i.e., it's | |
272 | * the encoded content of the OID, not including the tag and length bytes. | |
273 | */ | |
274 | OSStatus CMSDecoderCopyEncapsulatedContentType( | |
275 | CMSDecoderRef cmsDecoder, | |
276 | CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ | |
d64be36e | 277 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
278 | |
279 | /* | |
280 | * Obtain an array of all of the certificates in a message. Elements of the | |
281 | * returned array are SecCertificateRefs. The caller must CFRelease the returned | |
282 | * array. If a message does not contain any certificates (which is the case for | |
283 | * a message which is encrypted but not signed), the returned *certs value | |
284 | * is NULL. The function will return errSecSuccess in this case. | |
285 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
286 | */ | |
287 | OSStatus CMSDecoderCopyAllCerts( | |
288 | CMSDecoderRef cmsDecoder, | |
289 | CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ | |
d64be36e | 290 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
291 | |
292 | /* | |
293 | * Obtain the actual message content (payload), if any. If the message was | |
294 | * signed with detached content this will return NULL. | |
295 | * Caller must CFRelease the result. | |
296 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
297 | */ | |
298 | OSStatus CMSDecoderCopyContent( | |
299 | CMSDecoderRef cmsDecoder, | |
300 | CFDataRef * __nonnull CF_RETURNS_RETAINED contentOut) /* RETURNED */ | |
d64be36e | 301 | __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 A |
302 | |
303 | /* | |
304 | * Obtain the signing time of signer 'signerIndex' of a CMS message, if | |
305 | * present. This is an unauthenticate time, although it is part of the | |
306 | * signed attributes of the message. | |
307 | * | |
308 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
309 | * is greater than the number of signers of the message minus one. | |
310 | * | |
311 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
312 | */ | |
313 | OSStatus CMSDecoderCopySignerSigningTime( | |
314 | CMSDecoderRef cmsDecoder, | |
315 | size_t signerIndex, | |
316 | CFAbsoluteTime *signingTime) /* RETURNED */ | |
d64be36e | 317 | __API_AVAILABLE(macos(10.8)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), macCatalyst(11.0)); |
866f8763 | 318 | |
866f8763 A |
319 | /* |
320 | * Obtain the timestamp of signer 'signerIndex' of a CMS message, if | |
321 | * present. This timestamp is an authenticated timestamp provided by | |
322 | * a timestamping authority. | |
323 | * | |
324 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
325 | * is greater than the number of signers of the message minus one. | |
326 | * | |
327 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
328 | */ | |
329 | OSStatus CMSDecoderCopySignerTimestamp( | |
330 | CMSDecoderRef cmsDecoder, | |
331 | size_t signerIndex, | |
332 | CFAbsoluteTime *timestamp) /* RETURNED */ | |
d64be36e | 333 | API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); |
866f8763 A |
334 | |
335 | /* | |
336 | * Obtain the timestamp of signer 'signerIndex' of a CMS message, if | |
337 | * present. This timestamp is an authenticated timestamp provided by | |
338 | * a timestamping authority. Use the policy provided as a parameter | |
339 | * | |
340 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
341 | * is greater than the number of signers of the message minus one. | |
342 | * | |
343 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
344 | */ | |
345 | OSStatus CMSDecoderCopySignerTimestampWithPolicy( | |
346 | CMSDecoderRef cmsDecoder, | |
347 | CFTypeRef __nullable timeStampPolicy, | |
348 | size_t signerIndex, /* usually 0 */ | |
349 | CFAbsoluteTime *timestamp) /* RETURNED */ | |
d64be36e | 350 | API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); |
866f8763 A |
351 | |
352 | /* | |
353 | * Obtain an array of the certificates in a timestamp response. Elements of the | |
354 | * returned array are SecCertificateRefs. The caller must CFRelease the returned | |
355 | * array. This timestamp is an authenticated timestamp provided by | |
356 | * a timestamping authority. | |
357 | * | |
358 | * Returns errSecParam if the CMS message was not signed or if signerIndex | |
359 | * is greater than the number of signers of the message minus one. It returns | |
360 | * errSecItemNotFound if no certificates were found. | |
361 | * | |
362 | * This cannot be called until after CMSDecoderFinalizeMessage() is called. | |
363 | */ | |
364 | OSStatus CMSDecoderCopySignerTimestampCertificates( | |
365 | CMSDecoderRef cmsDecoder, | |
366 | size_t signerIndex, /* usually 0 */ | |
367 | CFArrayRef * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */ | |
d64be36e | 368 | API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, macCatalyst); |
866f8763 A |
369 | |
370 | CF_ASSUME_NONNULL_END | |
371 | ||
372 | __END_DECLS | |
373 | ||
374 | #endif /* _CMS_DECODER_H_ */ | |
375 |