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 "cms-hashagility-test.h"
26 #include <test/testmore.h>
27 #include <Security/SecBase.h>
28 #include <utilities/SecCFRelease.h>
29 #include <Security/CMSEncoder.h>
30 #include <Security/SecImportExport.h>
31 #include <Security/CMSPrivate.h>
32 #include <Security/SecCertificatePriv.h>
33 #include <Security/SecTrust.h>
34 #include <Security/SecPolicy.h>
35 #include <Security/SecKeychain.h>
36 #include <Security/SecIdentity.h>
38 #define TMP_KEYCHAIN_PATH "/tmp/cms_signer.keychain"
41 static void encode_test(void)
43 CMSEncoderRef encoder
= NULL
;
44 CFDataRef attributeData
= NULL
, message
= NULL
, p12Data
= NULL
;
45 CFArrayRef imported_items
= NULL
;
46 SecIdentityRef identity
= NULL
;
47 SecKeychainRef keychain
= NULL
;
48 SecExternalFormat sef
= kSecFormatPKCS12
;
49 SecItemImportExportKeyParameters keyParams
= {
50 .passphrase
= CFSTR("password")
54 ok_status(CMSEncoderCreate(&encoder
), "Create CMS encoder");
55 ok_status(CMSEncoderSetSignerAlgorithm(encoder
, kCMSEncoderDigestAlgorithmSHA256
),
56 "Set digest algorithm to SHA256");
58 /* Load identity and set as signer */
59 ok_status(SecKeychainCreate(TMP_KEYCHAIN_PATH
, 8, "password", false, NULL
, &keychain
),
60 "Create keychain for identity");
61 ok(p12Data
= CFDataCreate(NULL
, signing_identity_p12
, sizeof(signing_identity_p12
)),
63 ok_status(SecItemImport(p12Data
, NULL
, &sef
, NULL
, 0, &keyParams
, keychain
, &imported_items
),
65 is(CFArrayGetCount(imported_items
),1,"Imported 1 items");
66 is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items
, 0)), SecIdentityGetTypeID(),
67 "Got back an identity");
68 ok(identity
= (SecIdentityRef
) CFRetainSafe(CFArrayGetValueAtIndex(imported_items
, 0)),
70 ok_status(CMSEncoderAddSigners(encoder
, identity
), "Set Signer identity");
72 /* Add signing time attribute for 3 November 2015 */
73 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrSigningTime
),
74 "Set signing time flag");
75 ok_status(CMSEncoderSetSigningTime(encoder
, 468295000.0), "Set Signing time");
77 /* Add hash agility attribute */
78 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrAppleCodesigningHashAgility
),
79 "Set hash agility flag");
80 ok(attributeData
= CFDataCreate(NULL
, attribute
, sizeof(attribute
)),
81 "Create atttribute object");
82 ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder
, attributeData
),
83 "Set hash agility data");
86 ok_status(CMSEncoderSetHasDetachedContent(encoder
, true), "Set detached content");
87 ok_status(CMSEncoderUpdateContent(encoder
, content
, sizeof(content
)), "Set content");
89 /* output cms message */
90 ok_status(CMSEncoderCopyEncodedContent(encoder
, &message
), "Finish encoding and output message");
93 CMSDecoderRef decoder
= NULL
;
94 CFDataRef contentData
= NULL
;
95 isnt(message
, NULL
, "Encoded message exists");
96 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
97 ok_status(CMSDecoderUpdateMessage(decoder
, CFDataGetBytePtr(message
), CFDataGetLength(message
)),
98 "Update decoder with CMS message");
99 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
100 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
101 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
104 ok_status(SecKeychainDelete(keychain
), "Delete temporary keychain");
106 CFReleaseNull(encoder
);
107 CFReleaseNull(keychain
);
108 CFReleaseNull(p12Data
);
109 CFReleaseNull(imported_items
);
110 CFReleaseNull(identity
);
111 CFReleaseNull(attributeData
);
112 CFReleaseNull(message
);
113 CFReleaseNull(decoder
);
114 CFReleaseNull(contentData
);
117 static void decode_positive_test(void)
119 CMSDecoderRef decoder
= NULL
;
120 CFDataRef contentData
= NULL
, attrValue
= NULL
;
121 SecPolicyRef policy
= NULL
;
122 SecTrustRef trust
= NULL
;
123 CMSSignerStatus signerStatus
;
124 CFAbsoluteTime signingTime
= 0.0;
126 /* Create decoder and decode */
127 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
128 ok_status(CMSDecoderUpdateMessage(decoder
, valid_message
, sizeof(valid_message
)),
129 "Update decoder with CMS message");
130 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
131 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
132 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
134 /* Get signer status */
135 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
136 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
137 "Copy Signer status");
138 is(signerStatus
, kCMSSignerValid
, "Valid signature");
140 /* Get Hash Agility Attribute value */
141 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
142 "Copy hash agility attribute value");
143 is(CFDataGetLength(attrValue
), sizeof(attribute
), "Decoded attribute size");
144 is(memcmp(attribute
, CFDataGetBytePtr(attrValue
), sizeof(attribute
)), 0,
145 "Decoded value same as input value");
147 /* Get Signing Time Attribute value */
148 ok_status(CMSDecoderCopySignerSigningTime(decoder
, 0, &signingTime
),
149 "Copy signing time attribute value");
150 is(signingTime
, 468295000.0, "Decoded date same as input date");
152 CFReleaseNull(decoder
);
153 CFReleaseNull(contentData
);
154 CFReleaseNull(policy
);
155 CFReleaseNull(trust
);
156 CFReleaseNull(attrValue
);
159 static void decode_negative_test(void)
161 CMSDecoderRef decoder
= NULL
;
162 CFDataRef contentData
= NULL
;
163 SecPolicyRef policy
= NULL
;
164 SecTrustRef trust
= NULL
;
165 CMSSignerStatus signerStatus
;
167 /* Create decoder and decode */
168 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
169 ok_status(CMSDecoderUpdateMessage(decoder
, invalid_message
, sizeof(invalid_message
)),
170 "Update decoder with CMS message");
171 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
172 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
173 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
175 /* Get signer status */
176 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
177 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
178 "Copy Signer status");
179 is(signerStatus
, kCMSSignerInvalidSignature
, "Invalid signature");
181 CFReleaseNull(decoder
);
182 CFReleaseNull(contentData
);
183 CFReleaseNull(policy
);
184 CFReleaseNull(trust
);
187 static void decode_no_attr_test(void)
189 CMSDecoderRef decoder
= NULL
;
190 CFDataRef contentData
= NULL
, attrValue
= NULL
;
191 SecPolicyRef policy
= NULL
;
192 SecTrustRef trust
= NULL
;
193 CMSSignerStatus signerStatus
;
195 /* Create decoder and decode */
196 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
197 ok_status(CMSDecoderUpdateMessage(decoder
, valid_no_attr
, sizeof(valid_no_attr
)),
198 "Update decoder with CMS message");
199 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
200 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
201 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
203 /* Get signer status */
204 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
205 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
206 "Copy Signer status");
207 is(signerStatus
, kCMSSignerValid
, "Valid signature");
209 /* Get Hash Agility Attribute value */
210 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
211 "Copy empty hash agility attribute value");
212 is(attrValue
, NULL
, "NULL attribute value");
214 CFReleaseNull(decoder
);
215 CFReleaseNull(contentData
);
216 CFReleaseNull(policy
);
217 CFReleaseNull(trust
);
218 CFReleaseNull(attrValue
);
221 int cms_hash_agility_test(int argc
, char *const *argv
)
223 plan_tests(24+13+8+10);
226 decode_positive_test();
227 decode_negative_test();
228 decode_no_attr_test();