2 * Copyright (c) 2015-2017 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@
24 #import <AssertMacros.h>
25 #include <Foundation/Foundation.h>
26 #include <CoreFoundation/CoreFoundation.h>
27 #include <Security/Security.h>
28 #include <Security/SecCMS.h>
29 #include <Security/SecCmsBase.h>
30 #include <utilities/SecCFRelease.h>
32 #include "Security_regressions.h"
34 #include "si-89-cms-hash-agility.h"
36 static void ios_shim_tests(void)
38 CFDataRef message = NULL, contentData = NULL, hashAgilityOid = NULL, hashAgilityValue = NULL;
39 SecPolicyRef policy = NULL;
40 SecTrustRef trust = NULL;
41 CFDictionaryRef attrs = NULL;
42 CFArrayRef attrValues = NULL;
43 CFDateRef signingTime = NULL, expectedTime = NULL;
45 ok(message = CFDataCreate(NULL, valid_message, sizeof(valid_message)), "Create valid message");
46 ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
47 ok(policy = SecPolicyCreateBasicX509(), "Create policy");
49 /* verify the valid message and copy out attributes */
50 is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs),
51 errSecSuccess, "Verify valid CMS message and get attributes");
52 isnt(attrs, NULL, "Copy CMS attributes");
54 /* verify we can get the parsed attribute */
55 uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 };
56 ok(hashAgilityOid = CFDataCreate(NULL, appleHashAgilityOid, sizeof(appleHashAgilityOid)),
58 ok(attrValues = (CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid),
59 "Get hash agility value array");
60 is(CFArrayGetCount(attrValues), 1, "One attribute value");
61 ok(hashAgilityValue = CFArrayGetValueAtIndex(attrValues, 0), "Get hash agility value");
62 is((size_t)CFDataGetLength(hashAgilityValue), sizeof(attribute), "Verify size of parsed hash agility value");
63 is(memcmp(attribute, CFDataGetBytePtr(hashAgilityValue), sizeof(attribute)), 0,
64 "Verify correct hash agility value");
66 /* verify we can get the "cooked" parsed attribute */
67 ok(hashAgilityValue = (CFDataRef)CFDictionaryGetValue(attrs, kSecCMSHashAgility), "Get cooked hash agility value");
68 is((size_t)CFDataGetLength(hashAgilityValue), sizeof(attribute), "Verify size of parsed hash agility value");
69 is(memcmp(attribute, CFDataGetBytePtr(hashAgilityValue), sizeof(attribute)), 0,
70 "Verify correct hash agility value");
74 /*verify we can get the signing time attribute */
75 ok(signingTime = (CFDateRef) CFDictionaryGetValue(attrs, kSecCMSSignDate), "Get signing time");
76 ok(expectedTime = CFDateCreate(NULL, 468295000.0), "Set expected signing time");
77 is(CFDateCompare(signingTime, expectedTime, NULL), 0, "Verify signing time");
79 CFReleaseNull(message);
81 /* verify the invalid message */
82 ok(message = CFDataCreate(NULL, invalid_message, sizeof(invalid_message)), "Create invalid message");
83 is(SecCMSVerify(message, contentData, policy, &trust, NULL), errSecAuthFailed,
84 "Verify invalid CMS message");
86 CFReleaseNull(message);
88 /* verify the valid message with no hash agility attribute */
89 ok(message = CFDataCreate(NULL, valid_no_attr, sizeof(valid_no_attr)),
90 "Create valid message with no hash agility value");
91 is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs),
92 errSecSuccess, "Verify 2nd valid CMS message and get attributes");
93 isnt(attrs, NULL, "Copy 2nd CMS attributes");
95 /* verify we can't get the hash agility attribute */
96 is((CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid), NULL,
97 "Get hash agility value array");
98 is((CFDataRef) CFDictionaryGetValue(attrs, kSecCMSHashAgility), NULL,
99 "Get cooked hash agility value");
102 CFReleaseNull(message);
103 CFReleaseNull(contentData);
104 CFReleaseNull(hashAgilityOid);
105 CFReleaseNull(expectedTime);
106 CFReleaseNull(policy);
107 CFReleaseNull(trust);
108 CFReleaseNull(attrs);
111 /* MARK: macOS Shim tests */
112 #include <Security/CMSEncoder.h>
113 #include <Security/CMSDecoder.h>
116 static void encode_test(void)
118 CMSEncoderRef encoder = NULL;
119 CFDataRef attributeData = NULL, message = NULL, p12Data = NULL;
120 CFArrayRef imported_items = NULL;
121 SecIdentityRef identity = NULL;
122 CFStringRef password = CFSTR("password");
123 CFDictionaryRef options = CFDictionaryCreate(NULL,
124 (const void **)&kSecImportExportPassphrase,
125 (const void **)&password, 1,
126 &kCFTypeDictionaryKeyCallBacks,
127 &kCFTypeDictionaryValueCallBacks);
128 CFDictionaryRef itemDict = NULL;
132 ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder");
133 ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256),
134 "Set digest algorithm to SHA256");
136 /* Load identity and set as signer */
137 ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)),
139 ok_status(SecPKCS12Import(p12Data, options, &imported_items),
141 is(CFArrayGetCount(imported_items),1,"Imported 1 items");
142 is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), CFDictionaryGetTypeID(),
143 "Got back a dictionary");
144 ok(itemDict = CFArrayGetValueAtIndex(imported_items, 0), "Retreive item dictionary");
145 is(CFGetTypeID(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), SecIdentityGetTypeID(),
146 "Got back an identity");
147 ok(identity = (SecIdentityRef) CFRetainSafe(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)),
148 "Retrieve identity");
149 ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity");
151 /* Add signing time attribute for 3 November 2015 */
152 ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime),
153 "Set signing time flag");
154 ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time");
156 /* Add hash agility attribute */
157 ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility),
158 "Set hash agility flag");
159 ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)),
160 "Create atttribute object");
161 ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData),
162 "Set hash agility data");
165 ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content");
166 ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content");
168 /* output cms message */
169 ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message");
172 CMSDecoderRef decoder = NULL;
173 CFDataRef contentData = NULL;
174 isnt(message, NULL, "Encoded message exists");
175 ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
176 ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)),
177 "Update decoder with CMS message");
178 ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
179 ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
180 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
183 CFReleaseNull(encoder);
184 CFReleaseNull(p12Data);
185 CFReleaseNull(imported_items);
186 CFReleaseNull(identity);
187 CFReleaseNull(attributeData);
188 CFReleaseNull(message);
189 CFReleaseNull(decoder);
190 CFReleaseNull(contentData);
193 static void decode_positive_test(void)
195 CMSDecoderRef decoder = NULL;
196 CFDataRef contentData = NULL, attrValue = NULL;
197 SecPolicyRef policy = NULL;
198 SecTrustRef trust = NULL;
199 CMSSignerStatus signerStatus;
200 CFAbsoluteTime signingTime = 0.0;
202 /* Create decoder and decode */
203 ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
204 ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)),
205 "Update decoder with CMS message");
206 ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
207 ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
208 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
210 /* Get signer status */
211 ok(policy = SecPolicyCreateBasicX509(), "Create policy");
212 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
213 "Copy Signer status");
214 is(signerStatus, kCMSSignerValid, "Valid signature");
216 /* Get Hash Agility Attribute value */
217 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue),
218 "Copy hash agility attribute value");
219 is((size_t)CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size");
220 is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0,
221 "Decoded value same as input value");
223 /* Get Signing Time Attribute value */
224 ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime),
225 "Copy signing time attribute value");
226 is(signingTime, 468295000.0, "Decoded date same as input date");
228 CFReleaseNull(decoder);
229 CFReleaseNull(contentData);
230 CFReleaseNull(policy);
231 CFReleaseNull(trust);
232 CFReleaseNull(attrValue);
235 static void decode_negative_test(void)
237 CMSDecoderRef decoder = NULL;
238 CFDataRef contentData = NULL;
239 SecPolicyRef policy = NULL;
240 SecTrustRef trust = NULL;
241 CMSSignerStatus signerStatus;
243 /* Create decoder and decode */
244 ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
245 ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)),
246 "Update decoder with CMS message");
247 ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
248 ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
249 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
251 /* Get signer status */
252 ok(policy = SecPolicyCreateBasicX509(), "Create policy");
253 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
254 "Copy Signer status");
255 is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature");
257 CFReleaseNull(decoder);
258 CFReleaseNull(contentData);
259 CFReleaseNull(policy);
260 CFReleaseNull(trust);
263 static void decode_no_attr_test(void)
265 CMSDecoderRef decoder = NULL;
266 CFDataRef contentData = NULL, attrValue = NULL;
267 SecPolicyRef policy = NULL;
268 SecTrustRef trust = NULL;
269 CMSSignerStatus signerStatus;
271 /* Create decoder and decode */
272 ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder");
273 ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)),
274 "Update decoder with CMS message");
275 ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content");
276 ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content");
277 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
279 /* Get signer status */
280 ok(policy = SecPolicyCreateBasicX509(), "Create policy");
281 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
282 "Copy Signer status");
283 is(signerStatus, kCMSSignerValid, "Valid signature");
285 /* Get Hash Agility Attribute value */
286 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue),
287 "Copy empty hash agility attribute value");
288 is(attrValue, NULL, "NULL attribute value");
290 CFReleaseNull(decoder);
291 CFReleaseNull(contentData);
292 CFReleaseNull(policy);
293 CFReleaseNull(trust);
294 CFReleaseNull(attrValue);
297 static void macos_shim_tests(void) {
299 decode_positive_test();
300 decode_negative_test();
301 decode_no_attr_test();
304 /* MARK: V2 Attribute testing */
305 static void ios_shim_V2_tests(void) {
306 SecPolicyRef policy = NULL;
307 SecTrustRef trust = NULL;
308 CFDictionaryRef tmpAttrs = NULL;
309 NSMutableData *message = nil;
310 NSData *contentData = nil, *hashAgilityV2Oid = nil;
311 NSDictionary *attrs = nil, *hashAgilityValue = nil;
312 NSArray *attrValues = nil;
313 NSDate *signingTime = nil;
315 message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)];
316 contentData = [NSData dataWithBytes:content length:sizeof(content)];
317 policy = SecPolicyCreateBasicX509();
319 /* verify the valid message and copy out attributes */
320 is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs),
321 errSecSuccess, "Verify valid CMS message and get attributes");
322 attrs = CFBridgingRelease(tmpAttrs);
323 require_string(attrs, exit, "Copy CMS attributes");
325 /* verify we can get the parsed attribute */
326 uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x2 };
327 hashAgilityV2Oid = [NSData dataWithBytes:appleHashAgilityOid length:sizeof(appleHashAgilityOid)];
328 attrValues = attrs[hashAgilityV2Oid];
329 require_string([attrValues count] == (size_t)1, exit, "One attribute value");
330 require_string(hashAgilityValue = attrValues[0], exit, "Get hash agility value");
331 ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]],
332 "Got wrong SHA1 agility value");
333 ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]],
334 "Got wrong SHA256 agility value");
336 /* verify we can get the "cooked" parsed attribute */
337 require_string(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit,
338 "Get cooked hash agility value");
339 ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]],
340 "Got wrong SHA1 agility value");
341 ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]],
342 "Got wrong SHA256 agility value");
346 /*verify we can get the signing time attribute */
347 require_string(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, "Failed to get signing time");
348 ok([signingTime isEqualToDate:[NSDate dateWithTimeIntervalSinceReferenceDate:530700000.0]], "Got wrong signing time");
350 /* verify the invalid message */
351 message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)];
352 [message resetBytesInRange:NSMakeRange(2110, 0)]; /* reset byte in hash agility attribute */
353 is(SecCMSVerify((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL), errSecAuthFailed,
354 "Verify invalid CMS message");
356 /* verify the valid message with no hash agility attribute */
357 message = [NSMutableData dataWithBytes:valid_no_attr length:sizeof(valid_no_attr)];
358 is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs),
359 errSecSuccess, "Verify 2nd valid CMS message and get attributes");
360 attrs = CFBridgingRelease(tmpAttrs);
361 isnt(attrs, NULL, "Copy 2nd CMS attributes");
363 /* verify we can't get the hash agility attribute */
364 is(attrs[hashAgilityV2Oid], NULL, "Got hash agility V2 attribute");
365 is(attrs[(__bridge NSString*)kSecCMSHashAgilityV2], NULL, "Got cooked hash agility V2 attribute");
368 CFReleaseNull(policy);
369 CFReleaseNull(trust);
372 /* macOS shim test - encode */
373 static void encode_V2_test(void) {
374 CMSEncoderRef encoder = NULL;
375 CMSDecoderRef decoder = NULL;
376 NSData *p12Data = nil;
377 CFArrayRef tmp_imported_items = NULL;
378 NSArray *imported_items = nil;
379 SecIdentityRef identity = NULL;
380 CFDataRef message = NULL;
381 NSDictionary *attrValues = nil, *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" };
384 require_noerr_string(CMSEncoderCreate(&encoder), exit, "Failed to create CMS encoder");
385 require_noerr_string(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit,
386 "Failed to set digest algorithm to SHA256");
388 /* Load identity and set as signer */
389 p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)];
390 require_noerr_string(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options,
391 &tmp_imported_items), exit,
392 "Failed to import identity");
393 imported_items = CFBridgingRelease(tmp_imported_items);
394 require_noerr_string([imported_items count] == 0 &&
395 [imported_items[0] isKindOfClass:[NSDictionary class]], exit,
396 "Wrong imported items output");
397 identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]);
398 require_string(identity, exit, "Failed to get identity");
399 require_noerr_string(CMSEncoderAddSigners(encoder, identity), exit, "Failed to add signer identity");
401 /* Add signing time attribute for 26 October 2017 */
402 require_noerr_string(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit,
403 "Failed to set signing time flag");
404 require_noerr_string(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, "Failed to set signing time");
406 /* Add hash agility attribute */
407 attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20],
408 @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32],
410 ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2),
411 "Set hash agility flag");
412 ok_status(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues),
413 "Set hash agility data");
416 require_noerr_string(CMSEncoderSetHasDetachedContent(encoder, true), exit, "Failed to set detached content");
417 require_noerr_string(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, "Failed to set content");
419 /* output cms message */
420 ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message");
421 isnt(message, NULL, "Encoded message exists");
424 require_noerr_string(CMSDecoderCreate(&decoder), exit, "Create CMS decoder");
425 require_noerr_string(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message),
426 CFDataGetLength(message)), exit,
427 "Update decoder with CMS message");
428 require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content
429 length:sizeof(content)]),
430 exit, "Set detached content");
431 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
434 CFReleaseNull(encoder);
435 CFReleaseNull(identity);
436 CFReleaseNull(message);
437 CFReleaseNull(decoder);
440 /* macOS shim test - decode positive */
441 static void decode_V2_positive_test(void) {
442 CMSDecoderRef decoder = NULL;
443 SecPolicyRef policy = NULL;
444 SecTrustRef trust = NULL;
445 CMSSignerStatus signerStatus;
446 NSData *contentData = nil;
447 CFDictionaryRef tmpAttrValue = NULL;
448 NSDictionary *attrValue = nil;
450 /* Create decoder and decode */
451 require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder");
452 require_noerr_string(CMSDecoderUpdateMessage(decoder, _V2_valid_message, sizeof(_V2_valid_message)), exit,
453 "Failed to update decoder with CMS message");
454 contentData = [NSData dataWithBytes:content length:sizeof(content)];
455 require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
456 "Failed to set detached content");
457 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
459 /* Get signer status */
460 require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
461 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
462 "Copy Signer status");
463 is(signerStatus, kCMSSignerValid, "Valid signature");
465 /* Get Hash Agility Attribute value */
466 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &tmpAttrValue),
467 "Copy hash agility attribute value");
468 attrValue = CFBridgingRelease(tmpAttrValue);
469 ok([attrValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]],
470 "Got wrong SHA1 agility value");
471 ok([attrValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]],
472 "Got wrong SHA256 agility value");
475 CFReleaseNull(decoder);
476 CFReleaseNull(policy);
477 CFReleaseNull(trust);
480 /* macOS shim test - decode negative */
481 static void decode_V2_negative_test(void) {
482 CMSDecoderRef decoder = NULL;
483 SecPolicyRef policy = NULL;
484 SecTrustRef trust = NULL;
485 CMSSignerStatus signerStatus;
486 NSData *contentData = nil;
487 NSMutableData *invalid_message = nil;
489 /* Create decoder and decode */
490 invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)];
491 [invalid_message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */
492 require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder");
493 require_noerr_string(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit,
494 "Failed to update decoder with CMS message");
495 contentData = [NSData dataWithBytes:content length:sizeof(content)];
496 require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
497 "Failed to set detached content");
498 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
500 /* Get signer status */
501 require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
502 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
503 "Copy Signer status");
504 is(signerStatus, kCMSSignerInvalidSignature, "Valid signature");
507 CFReleaseNull(decoder);
508 CFReleaseNull(policy);
509 CFReleaseNull(trust);
512 /* macOS shim test - no attribute */
513 static void decodeV2_no_attr_test(void) {
514 CMSDecoderRef decoder = NULL;
515 SecPolicyRef policy = NULL;
516 SecTrustRef trust = NULL;
517 CMSSignerStatus signerStatus;
518 NSData *contentData = nil;
519 CFDictionaryRef attrValue = NULL;
521 /* Create decoder and decode */
522 require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder");
523 require_noerr_string(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), exit,
524 "Failed to update decoder with CMS message");
525 contentData = [NSData dataWithBytes:content length:sizeof(content)];
526 require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit,
527 "Failed to set detached content");
528 ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder");
530 /* Get signer status */
531 require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy");
532 ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL),
533 "Copy Signer status");
534 is(signerStatus, kCMSSignerValid, "Valid signature");
536 /* Get Hash Agility Attribute value */
537 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &attrValue),
538 "Copy hash agility attribute value");
539 is(attrValue, NULL, "NULL attribute value");
542 CFReleaseNull(decoder);
543 CFReleaseNull(policy);
544 CFReleaseNull(trust);
545 CFReleaseNull(attrValue);
548 static void macOS_shim_V2_tests(void) {
550 decode_V2_positive_test();
551 decode_V2_negative_test();
552 decodeV2_no_attr_test();
555 int si_89_cms_hash_agility(int argc, char *const *argv)
562 macOS_shim_V2_tests();