]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c
Security-58286.230.21.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-95-cms-basic.c
1 /*
2 * Copyright (c) 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 #include "si-95-cms-basic.h"
25 #include "Security_regressions.h"
26
27 #include <AssertMacros.h>
28
29 #include <utilities/SecCFRelease.h>
30
31 #include <Security/SecBase.h>
32 #include <Security/SecImportExport.h>
33
34 #include <Security/SecIdentity.h>
35 #include <Security/SecPolicy.h>
36 #include <Security/SecItem.h>
37
38 #include <Security/SecCmsMessage.h>
39 #include <Security/SecCmsSignedData.h>
40 #include <Security/SecCmsContentInfo.h>
41 #include <Security/SecCmsSignerInfo.h>
42 #include <Security/SecCmsEncoder.h>
43 #include <Security/SecCmsDecoder.h>
44 #include <Security/SecCmsEnvelopedData.h>
45 #include <Security/SecCmsRecipientInfo.h>
46 #include <Security/SecAsn1Types.h>
47
48 #include <security_asn1/secerr.h>
49 #include <security_asn1/seccomon.h>
50
51 /* These tests are essentially the same as cms_01_basic in the OS X
52 * libsecurity_smime_regressions. They are not unified into a single
53 * test because libsecurity_smime diverges so much between the platforms
54 * that unifying the tests makes every third line a TARGET macro.
55 */
56
57 #define kNumberSetupTests 8
58 static CFDataRef setup_keychain(const uint8_t *p12, size_t p12_len, SecIdentityRef *identity, SecCertificateRef *cert) {
59 CFDictionaryRef p12Options = NULL, item_dict = NULL, query_dict = NULL;
60 CFArrayRef p12Items = NULL;
61 CFStringRef p12Password = NULL;
62 CFDataRef p12Data = NULL, identityPersistentRef = NULL;
63 CFTypeRef keychainItems = NULL;
64
65 /* load identity */
66 ok(p12Password = CFStringCreateWithCString(NULL, "password", kCFStringEncodingASCII),
67 "Create p12 password");
68 require_action(p12Options = CFDictionaryCreate(NULL, (const void **)&kSecImportExportPassphrase,
69 (const void **)&p12Password, 1,
70 &kCFTypeDictionaryKeyCallBacks,
71 &kCFTypeDictionaryValueCallBacks),
72 errOut, fail("Create p12 options dictionary"));
73 require_action(p12Data = CFDataCreate(NULL, p12, p12_len), errOut,
74 fail("Create p12 data"));
75 ok_status(SecPKCS12Import(p12Data, p12Options, &p12Items),
76 "import test identity");
77 ok(item_dict = CFArrayGetValueAtIndex(p12Items, 0),
78 "Get pkcs12 output");
79 ok(*identity = (SecIdentityRef)CFRetainSafe(CFDictionaryGetValue(item_dict, kSecImportItemIdentity)),
80 "Get identity from results");
81
82 /* add identity to keychain because libsecurity_smime needs it there */
83 const void *keys[] = { kSecValueRef, kSecReturnPersistentRef};
84 const void *values[] = { *identity, kCFBooleanTrue };
85 require_action(query_dict = CFDictionaryCreate(NULL, keys, values, 2,
86 &kCFTypeDictionaryKeyCallBacks,
87 &kCFTypeDictionaryValueCallBacks),
88 errOut, fail("Create SecItem query dictionary"));
89 ok_status(SecItemAdd(query_dict, &keychainItems),
90 "Add identity to keychain");
91 is(CFGetTypeID(keychainItems), CFDataGetTypeID(),
92 "Verify SecItem result type");
93 ok(identityPersistentRef = (CFDataRef)CFRetainSafe(keychainItems),
94 "Get persistent reference to identity");
95
96 /* get the certificate */
97 require_action(identity && *identity, errOut, fail("get identity failed"));
98 ok_status(SecIdentityCopyCertificate(*identity, cert),
99 "Copy certificate");
100
101 errOut:
102 CFReleaseNull(p12Password);
103 CFReleaseNull(p12Options);
104 CFReleaseNull(p12Data);
105 CFReleaseNull(p12Items);
106 CFReleaseNull(query_dict);
107 CFReleaseNull(keychainItems);
108 return identityPersistentRef;
109 }
110
111 #define kNumberCleanupTests 1
112 static void cleanup_keychain(CFDataRef identityPersistenRef, SecIdentityRef identity, SecCertificateRef cert) {
113 CFDictionaryRef query = NULL;
114 require_action(query = CFDictionaryCreate(NULL, (const void**)&kSecValuePersistentRef,
115 (const void**)&identityPersistenRef, 1,
116 &kCFTypeDictionaryKeyCallBacks,
117 &kCFTypeDictionaryValueCallBacks),
118 errOut, fail("Create SecItem dictionary"));
119 ok_status(SecItemDelete(query),
120 "Delete identity from keychain");
121
122 errOut:
123 CFReleaseNull(query);
124 CFReleaseNull(cert);
125 CFReleaseNull(identity);
126 }
127
128 static OSStatus sign_please(SecIdentityRef identity, SECOidTag digestAlgTag, bool withAttrs, uint8_t *expected_output, size_t expected_len) {
129 OSStatus status = SECFailure;
130 SecCmsMessageRef cmsg = NULL;
131 SecCmsSignedDataRef sigd = NULL;
132 SecCmsContentInfoRef cinfo = NULL;
133 SecCmsSignerInfoRef signerInfo = NULL;
134 SecCmsEncoderRef encoder = NULL;
135 CFMutableDataRef outCms = NULL;
136 uint8_t string_to_sign[] = "This message is signed. Ain't it pretty?";
137
138 /* setup the message */
139 require_action_string(cmsg = SecCmsMessageCreate(), out,
140 status = errSecAllocate, "Failed to create message");
141 require_action_string(sigd = SecCmsSignedDataCreate(cmsg), out,
142 status = errSecAllocate, "Failed to create signed data");
143 require_action_string(cinfo = SecCmsMessageGetContentInfo(cmsg), out,
144 status = errSecParam, "Failed to get cms content info");
145 require_noerr_string(status = SecCmsContentInfoSetContentSignedData(cinfo, sigd), out,
146 "Failed to set signed data into content info");
147 require_action_string(cinfo = SecCmsSignedDataGetContentInfo(sigd), out,
148 status = errSecParam, "Failed to get content info from signed data");
149 require_noerr_string(status = SecCmsContentInfoSetContentData(cinfo, NULL, false), out,
150 "Failed to set signed data content info");
151 require_action_string(signerInfo = SecCmsSignerInfoCreate(sigd, identity, digestAlgTag), out,
152 status = errSecAllocate, "Failed to create signer info");
153 require_noerr_string(status = SecCmsSignerInfoIncludeCerts(signerInfo, SecCmsCMCertOnly,
154 certUsageEmailSigner), out,
155 "Failed to put certs in signer info");
156
157 if(withAttrs) {
158 require_noerr_string(status = SecCmsSignerInfoAddSigningTime(signerInfo, 480000000.0), out,
159 "Couldn't add an attribute");
160 }
161
162 /* encode now */
163 require_action_string(outCms = CFDataCreateMutable(NULL, 0), out,
164 status = errSecAllocate, "Failed to create cms data");
165 require_noerr_string(status = SecCmsEncoderCreate(cmsg, NULL, NULL, outCms, NULL, NULL,
166 NULL, NULL, &encoder), out,
167 "Failed to create encoder");
168 require_noerr_string(status = SecCmsEncoderUpdate(encoder, string_to_sign, sizeof(string_to_sign)), out,
169 "Failed to add data ");
170 status = SecCmsEncoderFinish(encoder);
171 encoder = NULL; // SecCmsEncoderFinish always frees the encoder but doesn't NULL it.
172 require_noerr_quiet(status, out);
173
174 /* verify the output matches expected results */
175 if (expected_output) {
176 require_action_string((CFIndex)expected_len == CFDataGetLength(outCms), out,
177 status = -1, "Output size differs from expected");
178 require_noerr_action_string(memcmp(expected_output, CFDataGetBytePtr(outCms), expected_len), out,
179 status = -1, "Output differs from expected");
180 }
181
182 out:
183 if (encoder) {
184 SecCmsEncoderDestroy(encoder);
185 }
186 if (cmsg) {
187 SecCmsMessageDestroy(cmsg);
188 }
189 CFReleaseNull(outCms);
190 return status;
191
192 }
193
194 static OSStatus verify_please(SecKeychainRef keychain, uint8_t *data_to_verify, size_t length) {
195 OSStatus status = SECFailure;
196 SecCmsDecoderRef decoder = NULL;
197 SecCmsMessageRef cmsg = NULL;
198 SecCmsContentInfoRef cinfo = NULL;
199 SecCmsSignedDataRef sigd = NULL;
200 SecPolicyRef policy = NULL;
201 SecTrustRef trust = NULL;
202
203 if (!data_to_verify) {
204 return errSecSuccess; // reasons...
205 }
206
207 require_noerr_string(status = SecCmsDecoderCreate(NULL, NULL, NULL, NULL,
208 NULL, NULL, &decoder), out,
209 "Failed to create decoder");
210 require_noerr_string(status = SecCmsDecoderUpdate(decoder, data_to_verify, length), out,
211 "Failed to add data ");
212 status = SecCmsDecoderFinish(decoder, &cmsg);
213 decoder = NULL; // SecCmsDecoderFinish always frees the decoder
214 require_noerr_quiet(status, out);
215
216 require_action_string(cinfo = SecCmsMessageContentLevel(cmsg, 0), out,
217 status = errSecDecode, "Failed to get content info");
218 require_action_string(SEC_OID_PKCS7_SIGNED_DATA == SecCmsContentInfoGetContentTypeTag(cinfo), out,
219 status = errSecDecode, "Content type was pkcs7 signed data");
220 require_action_string(sigd = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(cinfo), out,
221 status = errSecDecode, "Failed to get signed data");
222 require_action_string(policy = SecPolicyCreateBasicX509(), out,
223 status = errSecAllocate, "Failed to create basic policy");
224 status = SecCmsSignedDataVerifySignerInfo(sigd, 0, keychain, policy, &trust);
225
226 out:
227 if (decoder) {
228 SecCmsDecoderDestroy(decoder);
229 }
230 if (cmsg) {
231 SecCmsMessageDestroy(cmsg);
232 }
233 CFReleaseNull(policy);
234 CFReleaseNull(trust);
235 return status;
236 }
237
238 static uint8_t *invalidate_signature(uint8_t *cms_data, size_t length) {
239 if (!cms_data || !length || (length < 10)) {
240 return NULL;
241 }
242 uint8_t *invalid_cms = NULL;
243
244 invalid_cms = malloc(length);
245 if (invalid_cms) {
246 memcpy(invalid_cms, cms_data, length);
247 /* This modifies the signature part of the test cms binaries */
248 invalid_cms[length - 10] = 0x00;
249 }
250
251 return invalid_cms;
252 }
253
254 static OSStatus invalidate_and_verify(SecKeychainRef kc, uint8_t *cms_data, size_t length) {
255 OSStatus status = SECFailure;
256 uint8_t *invalid_cms_data = NULL;
257
258 if (!cms_data) {
259 return SECFailure; // reasons...
260 }
261
262 require_action_string(invalid_cms_data = invalidate_signature(cms_data, length), out,
263 status = errSecAllocate, "Unable to allocate buffer for invalid cms data");
264 status = verify_please(kc, invalid_cms_data, length);
265
266 out:
267 if (invalid_cms_data) {
268 free(invalid_cms_data);
269 }
270 return status;
271 }
272
273 /* forward declaration */
274 static OSStatus decrypt_please(const uint8_t *data_to_decrypt, size_t length);
275
276 static OSStatus encrypt_please(SecCertificateRef recipient, SECOidTag encAlg, int keysize) {
277 OSStatus status = SECFailure;
278 SecCmsMessageRef cmsg = NULL;
279 SecCmsEnvelopedDataRef envd = NULL;
280 SecCmsContentInfoRef cinfo = NULL;
281 SecCmsRecipientInfoRef rinfo = NULL;
282 SecCmsEncoderRef encoder = NULL;
283 CFMutableDataRef outCms = NULL;
284
285 const uint8_t data_to_encrypt[] = "This data is encrypted. Is cool, no?";
286
287 /* set up the message */
288 require_action_string(cmsg = SecCmsMessageCreate(), out,
289 status = errSecAllocate, "Failed to create message");
290 require_action_string(envd = SecCmsEnvelopedDataCreate(cmsg, encAlg, keysize), out,
291 status = errSecAllocate, "Failed to create enveloped data");
292 require_action_string(cinfo = SecCmsMessageGetContentInfo(cmsg), out,
293 status = errSecParam, "Failed to get content info from cms message");
294 require_noerr_string(status = SecCmsContentInfoSetContentEnvelopedData(cinfo, envd), out,
295 "Failed to set enveloped data in cms message");
296 require_action_string(cinfo = SecCmsEnvelopedDataGetContentInfo(envd), out,
297 status = errSecParam, "Failed to get content info from enveloped data");
298 require_noerr_string(status = SecCmsContentInfoSetContentData(cinfo, NULL, false), out,
299 "Failed to set data type in envelope");
300 require_action_string(rinfo = SecCmsRecipientInfoCreate(envd, recipient), out,
301 status = errSecAllocate, "Failed to create recipient info");
302
303 /* encode the message */
304 require_action_string(outCms = CFDataCreateMutable(NULL, 0), out,
305 status = errSecAllocate, "Failed to create cms data");
306 require_noerr_string(status = SecCmsEncoderCreate(cmsg, NULL, NULL, outCms, NULL, NULL,
307 NULL, NULL, &encoder), out,
308 "Failed to create encoder");
309 require_noerr_string(status = SecCmsEncoderUpdate(encoder, data_to_encrypt, sizeof(data_to_encrypt)), out,
310 "Failed to update encoder with data");
311 status = SecCmsEncoderFinish(encoder);
312 encoder = NULL; // SecCmsEncoderFinish always frees the encoder but doesn't NULL it.
313 require_noerr_quiet(status, out);
314
315 require_noerr_string(status = decrypt_please(CFDataGetBytePtr(outCms), CFDataGetLength(outCms)), out,
316 "Failed to decrypt the data we just encrypted");
317
318 out:
319 if (encoder) {
320 SecCmsEncoderDestroy(encoder);
321 }
322 if (cmsg) {
323 SecCmsMessageDestroy(cmsg);
324 }
325 CFReleaseNull(outCms);
326 return status;
327 }
328
329 static OSStatus decrypt_please(const uint8_t *data_to_decrypt, size_t length) {
330 OSStatus status = SECFailure;
331 SecCmsDecoderRef decoder = NULL;
332 SecCmsMessageRef cmsg = NULL;
333 const SecAsn1Item *content = NULL;
334 const uint8_t encrypted_string[] = "This data is encrypted. Is cool, no?";
335
336 require_noerr_string(status = SecCmsDecoderCreate(NULL, NULL, NULL, NULL, NULL,
337 NULL, &decoder), out,
338 "Failed to create decoder");
339 require_noerr_string(status = SecCmsDecoderUpdate(decoder, data_to_decrypt, length), out,
340 "Failed to add data ");
341 status = SecCmsDecoderFinish(decoder, &cmsg);
342 decoder = NULL; // SecCmsDecoderFinish always frees the decoder
343 require_noerr_quiet(status, out);
344 require_action_string(content = SecCmsMessageGetContent(cmsg), out,
345 status = errSecDecode, "Unable to get message contents");
346
347 /* verify the output matches expected results */
348 require_action_string(sizeof(encrypted_string) == content->Length, out,
349 status = -1, "Output size differs from expected");
350 require_noerr_action_string(memcmp(encrypted_string, content->Data, content->Length), out,
351 status = -1, "Output differs from expected");
352
353 out:
354 if (cmsg) {
355 SecCmsMessageDestroy(cmsg);
356 }
357 return status;
358 }
359
360 /* Signing with attributes goes through a different code path than signing without,
361 * so we need to test both. */
362 #define kNumberSignTests 10
363 static void sign_tests(SecIdentityRef identity, bool isRSA) {
364
365 /* no attributes */
366 is(sign_please(identity, SEC_OID_MD5, false, NULL, 0),
367 SEC_ERROR_INVALID_ALGORITHM, "Signed with MD5. Not cool.");
368 is(sign_please(identity, SEC_OID_SHA1, false, (isRSA) ? rsa_sha1 : NULL,
369 (isRSA) ? sizeof(rsa_sha1) : 0),
370 errSecSuccess, "Signed with SHA-1");
371 is(sign_please(identity, SEC_OID_SHA256, false, (isRSA) ? rsa_sha256 : NULL,
372 (isRSA) ? sizeof(rsa_sha256) : 0),
373 errSecSuccess, "Signed with SHA-256");
374 is(sign_please(identity, SEC_OID_SHA384, false, NULL, 0), errSecSuccess, "Signed with SHA-384");
375 is(sign_please(identity, SEC_OID_SHA512, false, NULL, 0), errSecSuccess, "Signed with SHA-512");
376
377 /* with attributes */
378 is(sign_please(identity, SEC_OID_MD5, true, NULL, 0),
379 SEC_ERROR_INVALID_ALGORITHM, "Signed with MD5 and attributes. Not cool.");
380 is(sign_please(identity, SEC_OID_SHA1, true, (isRSA) ? rsa_sha1_attr : NULL,
381 (isRSA) ? sizeof(rsa_sha1_attr) : 0),
382 errSecSuccess, "Signed with SHA-1 and attributes");
383 is(sign_please(identity, SEC_OID_SHA256, true, (isRSA) ? rsa_sha256_attr : NULL,
384 (isRSA) ? sizeof(rsa_sha256_attr) : 0),
385 errSecSuccess, "Signed with SHA-256 and attributes");
386 is(sign_please(identity, SEC_OID_SHA384, true, NULL, 0),
387 errSecSuccess, "Signed with SHA-384 and attributes");
388 is(sign_please(identity, SEC_OID_SHA512, true, NULL, 0),
389 errSecSuccess, "Signed with SHA-512 and attributes");
390 }
391
392 /* Verifying with attributes goes through a different code path than verifying without,
393 * so we need to test both. */
394 #define kNumberVerifyTests 12
395 static void verify_tests(SecKeychainRef kc, bool isRsa) {
396 /* no attributes */
397 is(verify_please(kc, (isRsa) ? rsa_md5 : ec_md5,
398 (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
399 (isRsa) ? errSecSuccess : SECFailure, "Verify MD5, no attributes");
400 is(verify_please(kc, (isRsa) ? rsa_sha1 : ec_sha1,
401 (isRsa) ? sizeof(rsa_sha1) : sizeof(ec_sha1)),
402 errSecSuccess, "Verify SHA1, no attributes");
403 is(verify_please(kc, (isRsa) ? rsa_sha256 : ec_sha256,
404 (isRsa) ? sizeof(rsa_sha256) : sizeof(ec_sha256)),
405 errSecSuccess, "Verify SHA256, no attributes");
406
407 /* with attributes */
408 is(verify_please(kc, (isRsa) ? rsa_md5_attr : NULL,
409 (isRsa) ? sizeof(rsa_md5_attr) : 0),
410 errSecSuccess, "Verify MD5, with attributes");
411 is(verify_please(kc, (isRsa) ? rsa_sha1_attr : ec_sha1_attr,
412 (isRsa) ? sizeof(rsa_sha1_attr) : sizeof(ec_sha1_attr)),
413 errSecSuccess, "Verify SHA1, with attributes");
414 is(verify_please(kc, (isRsa) ? rsa_sha256_attr : ec_sha256_attr,
415 (isRsa) ? sizeof(rsa_sha256_attr) : sizeof(ec_sha256_attr)),
416 errSecSuccess, "Verify SHA256, with attributes");
417
418 /***** Once more, with validation errors *****/
419
420 /* no attributes */
421 is(invalidate_and_verify(kc, (isRsa) ? rsa_md5 : ec_md5,
422 (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
423 SECFailure, "Verify invalid MD5, no attributes");
424 is(invalidate_and_verify(kc, (isRsa) ? rsa_sha1 : ec_sha1,
425 (isRsa) ? sizeof(rsa_sha1) : sizeof(ec_sha1)),
426 SECFailure, "Verify invalid SHA1, no attributes");
427 is(invalidate_and_verify(kc, (isRsa) ? rsa_sha256 : ec_sha256,
428 (isRsa) ? sizeof(rsa_sha256) : sizeof(ec_sha256)),
429 SECFailure, "Verify invalid SHA256, no attributes");
430
431 /* with attributes */
432 is(invalidate_and_verify(kc, (isRsa) ? rsa_md5_attr : NULL,
433 (isRsa) ? sizeof(rsa_md5_attr) : 0),
434 SECFailure, "Verify invalid MD5, with attributes");
435 is(invalidate_and_verify(kc, (isRsa) ? rsa_sha1_attr : ec_sha1_attr,
436 (isRsa) ? sizeof(rsa_sha1_attr) : sizeof(ec_sha1_attr)),
437 SECFailure, "Verify invalid SHA1, with attributes");
438 is(invalidate_and_verify(kc, (isRsa) ? rsa_sha256_attr : ec_sha256_attr,
439 (isRsa) ? sizeof(rsa_sha256_attr) : sizeof(ec_sha256_attr)),
440 SECFailure, "Verify invalid SHA256, with attributes");
441 }
442
443 #define kNumberEncryptTests 5
444 static void encrypt_tests(SecCertificateRef certificate) {
445 is(encrypt_please(certificate, SEC_OID_DES_EDE3_CBC, 192),
446 errSecSuccess, "Encrypt with 3DES");
447 is(encrypt_please(certificate, SEC_OID_RC2_CBC, 128),
448 errSecDecode, "Encrypt with 128-bit RC2");
449 is(encrypt_please(certificate, SEC_OID_AES_128_CBC, 128),
450 errSecSuccess, "Encrypt with 128-bit AES");
451 is(encrypt_please(certificate, SEC_OID_AES_192_CBC, 192),
452 errSecSuccess, "Encrypt with 192-bit AES");
453 is(encrypt_please(certificate, SEC_OID_AES_256_CBC, 256),
454 errSecSuccess, "Encrypt with 256-bit AES");
455 }
456
457 #define kNumberDecryptTests 5
458 static void decrypt_tests(bool isRsa) {
459 is(decrypt_please((isRsa) ? rsa_3DES : ec_3DES,
460 (isRsa) ? sizeof(rsa_3DES) : sizeof(ec_3DES)),
461 errSecSuccess, "Decrypt 3DES");
462 is(decrypt_please((isRsa) ? rsa_RC2 : ec_RC2,
463 (isRsa) ? sizeof(rsa_RC2) : sizeof(ec_RC2)),
464 errSecDecode, "Decrypt 128-bit RC2");
465 is(decrypt_please((isRsa) ? rsa_AES_128 : ec_AES_128,
466 (isRsa) ? sizeof(rsa_AES_128) : sizeof(ec_AES_128)),
467 errSecSuccess, "Decrypt 128-bit AES");
468 is(decrypt_please((isRsa) ? rsa_AES_192 : ec_AES_192,
469 (isRsa) ? sizeof(rsa_AES_192) : sizeof(ec_AES_192)),
470 errSecSuccess, "Decrypt 192-bit AES");
471 is(decrypt_please((isRsa) ? rsa_AES_256 : ec_AES_256,
472 (isRsa) ? sizeof(rsa_AES_256) : sizeof(ec_AES_256)),
473 errSecSuccess, "Decrypt 256-bit AES");
474 }
475
476 int si_95_cms_basic(int argc, char *const *argv)
477 {
478 plan_tests(2*(kNumberSetupTests + kNumberSignTests + kNumberVerifyTests +
479 kNumberEncryptTests + kNumberDecryptTests + kNumberCleanupTests));
480
481 SecIdentityRef identity = NULL;
482 SecCertificateRef certificate = NULL;
483 CFDataRef persistentRef = NULL;
484
485 /* SecKeychainRef's aren't a thing on iOS. But the SecCms SPI takes one as
486 * an argument. It gets ignored down in the bowels of libsecurity_smime, so
487 * it's safe to just pass NULL. */
488 SecKeychainRef kc = NULL;
489
490 /* RSA tests */
491 persistentRef = setup_keychain(_rsa_identity, sizeof(_rsa_identity), &identity, &certificate);
492 sign_tests(identity, true);
493 verify_tests(kc, true);
494 encrypt_tests(certificate);
495 decrypt_tests(true);
496 cleanup_keychain(persistentRef, identity, certificate);
497
498 /* EC tests */
499 persistentRef = setup_keychain(_ec_identity, sizeof(_ec_identity), &identity, &certificate);
500 sign_tests(identity, false);
501 verify_tests(kc, false);
502 encrypt_tests(certificate);
503 decrypt_tests(false);
504 cleanup_keychain(persistentRef, identity, certificate);
505
506 return 0;
507 }