2 * Copyright (c) 2015 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 #include <CoreFoundation/CoreFoundation.h>
25 #include <Security/Security.h>
26 #include <Security/SecCMS.h>
27 #include <utilities/SecCFRelease.h>
29 #include "Security_regressions.h"
31 #include "si-89-cms-hash-agility.h"
33 static void ios_shim_tests(void)
35 CFDataRef message
= NULL
, contentData
= NULL
, hashAgilityOid
= NULL
, hashAgilityValue
= NULL
;
36 SecPolicyRef policy
= NULL
;
37 SecTrustRef trust
= NULL
;
38 CFDictionaryRef attrs
= NULL
;
39 CFArrayRef attrValues
= NULL
;
40 CFDateRef signingTime
= NULL
, expectedTime
= NULL
;
42 ok(message
= CFDataCreate(NULL
, valid_message
, sizeof(valid_message
)), "Create valid message");
43 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
44 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
46 /* verify the valid message and copy out attributes */
47 is(SecCMSVerifyCopyDataAndAttributes(message
, contentData
, policy
, &trust
, NULL
, &attrs
),
48 errSecSuccess
, "Verify valid CMS message and get attributes");
49 isnt(attrs
, NULL
, "Copy CMS attributes");
51 /* verify we can get the parsed attribute */
52 uint8_t appleHashAgilityOid
[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 };
53 ok(hashAgilityOid
= CFDataCreate(NULL
, appleHashAgilityOid
, sizeof(appleHashAgilityOid
)),
55 ok(attrValues
= (CFArrayRef
) CFDictionaryGetValue(attrs
, hashAgilityOid
),
56 "Get hash agility value array");
57 is(CFArrayGetCount(attrValues
), 1, "One attribute value");
58 ok(hashAgilityValue
= CFArrayGetValueAtIndex(attrValues
, 0), "Get hash agility value");
59 is((size_t)CFDataGetLength(hashAgilityValue
), sizeof(attribute
), "Verify size of parsed hash agility value");
60 is(memcmp(attribute
, CFDataGetBytePtr(hashAgilityValue
), sizeof(attribute
)), 0,
61 "Verify correct hash agility value");
65 /*verify we can get the signing time attribute */
66 ok(signingTime
= (CFDateRef
) CFDictionaryGetValue(attrs
, kSecCMSSignDate
), "Get signing time");
67 ok(expectedTime
= CFDateCreate(NULL
, 468295000.0), "Set expected signing time");
68 is(CFDateCompare(signingTime
, expectedTime
, NULL
), 0, "Verify signing time");
70 CFReleaseNull(message
);
72 /* verify the invalid message */
73 ok(message
= CFDataCreate(NULL
, invalid_message
, sizeof(invalid_message
)), "Create invalid message");
74 is(SecCMSVerify(message
, contentData
, policy
, &trust
, NULL
), errSecAuthFailed
,
75 "Verify invalid CMS message");
77 CFReleaseNull(message
);
79 /* verify the valid message with no hash agility attribute */
80 ok(message
= CFDataCreate(NULL
, valid_no_attr
, sizeof(valid_no_attr
)),
81 "Create valid message with no hash agility value");
82 is(SecCMSVerifyCopyDataAndAttributes(message
, contentData
, policy
, &trust
, NULL
, &attrs
),
83 errSecSuccess
, "Verify 2nd valid CMS message and get attributes");
84 isnt(attrs
, NULL
, "Copy 2nd CMS attributes");
86 /* verify we can't get the hash agility attribute */
87 is((CFArrayRef
) CFDictionaryGetValue(attrs
, hashAgilityOid
), NULL
,
88 "Get hash agility value array");
91 CFReleaseNull(message
);
92 CFReleaseNull(contentData
);
93 CFReleaseNull(hashAgilityOid
);
94 CFReleaseNull(expectedTime
);
95 CFReleaseNull(policy
);
100 /* MARK: macOS Shim tests */
101 #include <Security/CMSEncoder.h>
102 #include <Security/CMSDecoder.h>
105 static void encode_test(void)
107 CMSEncoderRef encoder
= NULL
;
108 CFDataRef attributeData
= NULL
, message
= NULL
, p12Data
= NULL
;
109 CFArrayRef imported_items
= NULL
;
110 SecIdentityRef identity
= NULL
;
111 CFStringRef password
= CFSTR("password");
112 CFDictionaryRef options
= CFDictionaryCreate(NULL
,
113 (const void **)&kSecImportExportPassphrase
,
114 (const void **)&password
, 1,
115 &kCFTypeDictionaryKeyCallBacks
,
116 &kCFTypeDictionaryValueCallBacks
);
117 CFDictionaryRef itemDict
= NULL
;
121 ok_status(CMSEncoderCreate(&encoder
), "Create CMS encoder");
122 ok_status(CMSEncoderSetSignerAlgorithm(encoder
, kCMSEncoderDigestAlgorithmSHA256
),
123 "Set digest algorithm to SHA256");
125 /* Load identity and set as signer */
126 ok(p12Data
= CFDataCreate(NULL
, signing_identity_p12
, sizeof(signing_identity_p12
)),
128 ok_status(SecPKCS12Import(p12Data
, options
, &imported_items
),
130 is(CFArrayGetCount(imported_items
),1,"Imported 1 items");
131 is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items
, 0)), CFDictionaryGetTypeID(),
132 "Got back a dictionary");
133 ok(itemDict
= CFArrayGetValueAtIndex(imported_items
, 0), "Retreive item dictionary");
134 is(CFGetTypeID(CFDictionaryGetValue(itemDict
, kSecImportItemIdentity
)), SecIdentityGetTypeID(),
135 "Got back an identity");
136 ok(identity
= (SecIdentityRef
) CFRetainSafe(CFDictionaryGetValue(itemDict
, kSecImportItemIdentity
)),
137 "Retrieve identity");
138 ok_status(CMSEncoderAddSigners(encoder
, identity
), "Set Signer identity");
140 /* Add signing time attribute for 3 November 2015 */
141 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrSigningTime
),
142 "Set signing time flag");
143 ok_status(CMSEncoderSetSigningTime(encoder
, 468295000.0), "Set Signing time");
145 /* Add hash agility attribute */
146 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrAppleCodesigningHashAgility
),
147 "Set hash agility flag");
148 ok(attributeData
= CFDataCreate(NULL
, attribute
, sizeof(attribute
)),
149 "Create atttribute object");
150 ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder
, attributeData
),
151 "Set hash agility data");
154 ok_status(CMSEncoderSetHasDetachedContent(encoder
, true), "Set detached content");
155 ok_status(CMSEncoderUpdateContent(encoder
, content
, sizeof(content
)), "Set content");
157 /* output cms message */
158 ok_status(CMSEncoderCopyEncodedContent(encoder
, &message
), "Finish encoding and output message");
161 CMSDecoderRef decoder
= NULL
;
162 CFDataRef contentData
= NULL
;
163 isnt(message
, NULL
, "Encoded message exists");
164 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
165 ok_status(CMSDecoderUpdateMessage(decoder
, CFDataGetBytePtr(message
), CFDataGetLength(message
)),
166 "Update decoder with CMS message");
167 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
168 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
169 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
172 CFReleaseNull(encoder
);
173 CFReleaseNull(p12Data
);
174 CFReleaseNull(imported_items
);
175 CFReleaseNull(identity
);
176 CFReleaseNull(attributeData
);
177 CFReleaseNull(message
);
178 CFReleaseNull(decoder
);
179 CFReleaseNull(contentData
);
182 static void decode_positive_test(void)
184 CMSDecoderRef decoder
= NULL
;
185 CFDataRef contentData
= NULL
, attrValue
= NULL
;
186 SecPolicyRef policy
= NULL
;
187 SecTrustRef trust
= NULL
;
188 CMSSignerStatus signerStatus
;
189 CFAbsoluteTime signingTime
= 0.0;
191 /* Create decoder and decode */
192 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
193 ok_status(CMSDecoderUpdateMessage(decoder
, valid_message
, sizeof(valid_message
)),
194 "Update decoder with CMS message");
195 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
196 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
197 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
199 /* Get signer status */
200 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
201 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
202 "Copy Signer status");
203 is(signerStatus
, kCMSSignerValid
, "Valid signature");
205 /* Get Hash Agility Attribute value */
206 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
207 "Copy hash agility attribute value");
208 is((size_t)CFDataGetLength(attrValue
), sizeof(attribute
), "Decoded attribute size");
209 is(memcmp(attribute
, CFDataGetBytePtr(attrValue
), sizeof(attribute
)), 0,
210 "Decoded value same as input value");
212 /* Get Signing Time Attribute value */
213 ok_status(CMSDecoderCopySignerSigningTime(decoder
, 0, &signingTime
),
214 "Copy signing time attribute value");
215 is(signingTime
, 468295000.0, "Decoded date same as input date");
217 CFReleaseNull(decoder
);
218 CFReleaseNull(contentData
);
219 CFReleaseNull(policy
);
220 CFReleaseNull(trust
);
221 CFReleaseNull(attrValue
);
224 static void decode_negative_test(void)
226 CMSDecoderRef decoder
= NULL
;
227 CFDataRef contentData
= NULL
;
228 SecPolicyRef policy
= NULL
;
229 SecTrustRef trust
= NULL
;
230 CMSSignerStatus signerStatus
;
232 /* Create decoder and decode */
233 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
234 ok_status(CMSDecoderUpdateMessage(decoder
, invalid_message
, sizeof(invalid_message
)),
235 "Update decoder with CMS message");
236 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
237 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
238 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
240 /* Get signer status */
241 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
242 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
243 "Copy Signer status");
244 is(signerStatus
, kCMSSignerInvalidSignature
, "Invalid signature");
246 CFReleaseNull(decoder
);
247 CFReleaseNull(contentData
);
248 CFReleaseNull(policy
);
249 CFReleaseNull(trust
);
252 static void decode_no_attr_test(void)
254 CMSDecoderRef decoder
= NULL
;
255 CFDataRef contentData
= NULL
, attrValue
= NULL
;
256 SecPolicyRef policy
= NULL
;
257 SecTrustRef trust
= NULL
;
258 CMSSignerStatus signerStatus
;
260 /* Create decoder and decode */
261 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
262 ok_status(CMSDecoderUpdateMessage(decoder
, valid_no_attr
, sizeof(valid_no_attr
)),
263 "Update decoder with CMS message");
264 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
265 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
266 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
268 /* Get signer status */
269 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
270 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
271 "Copy Signer status");
272 is(signerStatus
, kCMSSignerValid
, "Valid signature");
274 /* Get Hash Agility Attribute value */
275 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
276 "Copy empty hash agility attribute value");
277 is(attrValue
, NULL
, "NULL attribute value");
279 CFReleaseNull(decoder
);
280 CFReleaseNull(contentData
);
281 CFReleaseNull(policy
);
282 CFReleaseNull(trust
);
283 CFReleaseNull(attrValue
);
286 static void macos_shim_tests(void) {
288 decode_positive_test();
289 decode_negative_test();
290 decode_no_attr_test();
293 int si_89_cms_hash_agility(int argc
, char *const *argv
)
295 plan_tests(20+24+13+8+10);