]> git.saurik.com Git - apple/security.git/blob - libsecurity_smime/lib/CMSDecoder.h
Security-58286.220.15.tar.gz
[apple/security.git] / libsecurity_smime / lib / CMSDecoder.h
1 /*
2 * Copyright (c) 2006-2016 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 <Security/SecCmsDecoder.h>
38 #include <Security/SecCmsMessage.h>
39 #include <AvailabilityMacros.h>
40 #include <stdint.h>
41
42 __BEGIN_DECLS
43
44 CF_ASSUME_NONNULL_BEGIN
45
46 /*
47 * Opaque reference to a CMS decoder object.
48 * This is a CF object, with standard CF semantics; dispose of it
49 * with CFRelease().
50 */
51 typedef struct CF_BRIDGED_TYPE(id) _CMSDecoder *CMSDecoderRef;
52
53 CFTypeID CMSDecoderGetTypeID(void);
54
55 /*
56 * Status of signature and signer information in a signed message.
57 */
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
62 * to verify */
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 */
67 };
68
69 /*
70 * Create a CMSDecoder. Result must eventually be freed via CFRelease().
71 */
72 OSStatus CMSDecoderCreate(CMSDecoderRef * __nonnull CF_RETURNS_RETAINED cmsDecoderOut) /* RETURNED */
73 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
74
75 /*
76 * Feed raw bytes of the message to be decoded into the decoder. Can be called
77 * multiple times.
78 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
79 * message.
80 */
81 OSStatus CMSDecoderUpdateMessage(
82 CMSDecoderRef cmsDecoder,
83 const void *msgBytes,
84 size_t msgBytesLen)
85 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
86
87 /*
88 * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming;
89 * finish decoding the message.
90 * Returns errSecUnknownFormat upon detection of improperly formatted CMS
91 * message.
92 */
93 OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder)
94 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
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_11_0);
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 * __nonnull CF_RETURNS_RETAINED detachedContentOut) /* RETURNED */
120 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
121
122 /*
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.
126 */
127 OSStatus CMSDecoderGetNumSigners(
128 CMSDecoderRef cmsDecoder,
129 size_t *numSignersOut) /* RETURNED */
130 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
131
132 /*
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.
136 *
137 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
138 *
139 * Note that signature and certificate verification of a decoded message
140 * does *not* occur until this routine is called.
141 *
142 * All returned values are optional - pass NULL if you don't need a
143 * particular parameter.
144 *
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.
148 *
149 * Inputs:
150 * -------
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.
166 *
167 * Outputs:
168 * --------
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
180 * signers (minus 1).
181 *
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.
187 *
188 * The certVerifyResultCode value can indicate a large number of errors; some of
189 * the most common and interesting errors are:
190 *
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
195 * a root cert.
196 * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does
197 * not self-verify.
198 * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested
199 * policy action.
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
202 * verification.
203 * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at
204 * the time of verification.
205 */
206 OSStatus CMSDecoderCopySignerStatus(
207 CMSDecoderRef cmsDecoder,
208 size_t signerIndex,
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);
215
216 /*
217 * Obtain the email address of signer 'signerIndex' of a CMS message, if
218 * present.
219 *
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.
222 *
223 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
224 */
225 OSStatus CMSDecoderCopySignerEmailAddress(
226 CMSDecoderRef cmsDecoder,
227 size_t signerIndex,
228 CFStringRef * __nonnull CF_RETURNS_RETAINED signerEmailAddressOut) /* RETURNED */
229 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
230
231 /*
232 * Obtain the certificate of signer 'signerIndex' of a CMS message, if
233 * present.
234 *
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.
237 *
238 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
239 */
240 OSStatus CMSDecoderCopySignerCert(
241 CMSDecoderRef cmsDecoder,
242 size_t signerIndex,
243 SecCertificateRef * __nonnull CF_RETURNS_RETAINED signerCertOut) /* RETURNED */
244 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
245
246 /*
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
250 * decrypted.
251 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
252 */
253 OSStatus CMSDecoderIsContentEncrypted(
254 CMSDecoderRef cmsDecoder,
255 Boolean *isEncryptedOut)
256 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
257
258 /*
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.
264 */
265 OSStatus CMSDecoderCopyEncapsulatedContentType(
266 CMSDecoderRef cmsDecoder,
267 CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */
268 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
269
270 /*
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.
277 */
278 OSStatus CMSDecoderCopyAllCerts(
279 CMSDecoderRef cmsDecoder,
280 CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */
281 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
282
283 /*
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.
288 */
289 OSStatus CMSDecoderCopyContent(
290 CMSDecoderRef cmsDecoder,
291 CFDataRef * __nonnull CF_RETURNS_RETAINED contentOut) /* RETURNED */
292 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0);
293
294 /*
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.
298 *
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.
301 *
302 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
303 */
304 OSStatus CMSDecoderCopySignerSigningTime(
305 CMSDecoderRef cmsDecoder,
306 size_t signerIndex,
307 CFAbsoluteTime *signingTime) /* RETURNED */
308 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_11_0);
309
310 #if TIMESTAMPING_SUPPORTED
311 /*
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.
315 *
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.
318 *
319 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
320 */
321 OSStatus CMSDecoderCopySignerTimestamp(
322 CMSDecoderRef cmsDecoder,
323 size_t signerIndex,
324 CFAbsoluteTime *timestamp) /* RETURNED */
325 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA);
326
327 /*
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
331 *
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.
334 *
335 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
336 */
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);
343
344 /*
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.
349 *
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.
353 *
354 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
355 */
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);
361 #endif
362
363 /*
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
369 * called.
370 *
371 * The CMSDecoder retains ownership of the returned SecCmsMessageRef.
372 */
373 OSStatus CMSDecoderGetCmsMessage(
374 CMSDecoderRef cmsDecoder,
375 SecCmsMessageRef _Nullable * _Nonnull cmsMessage); /* RETURNED */
376
377
378 /*
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.
383 */
384 OSStatus CMSDecoderSetDecoder(
385 CMSDecoderRef cmsDecoder,
386 SecCmsDecoderRef decoder);
387
388 /*
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.
393 */
394 OSStatus CMSDecoderGetDecoder(
395 CMSDecoderRef cmsDecoder,
396 SecCmsDecoderRef _Nullable * _Nonnull decoder); /* RETURNED */
397
398 /*
399 * Obtain the Hash Agility attribute value of signer 'signerIndex'
400 * of a CMS message, if present.
401 *
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.
404 *
405 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
406 */
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));
412
413 /*
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.
416 *
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.
419 *
420 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
421 */
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));
427
428 /*
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.
431 *
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.
434 *
435 * This cannot be called until after CMSDecoderFinalizeMessage() is called.
436 */
437 OSStatus CMSDecoderCopySignerAppleExpirationTime(
438 CMSDecoderRef cmsDecoder,
439 size_t signerIndex,
440 CFAbsoluteTime *expirationTime) /* RETURNED */
441 API_AVAILABLE(macos(10.14), ios(12.0));
442
443
444 CF_ASSUME_NONNULL_END
445
446 __END_DECLS
447
448 #endif /* _CMS_DECODER_H_ */
449