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 unlink(TMP_KEYCHAIN_PATH
);
60 ok_status(SecKeychainCreate(TMP_KEYCHAIN_PATH
, 8, "password", false, NULL
, &keychain
),
61 "Create keychain for identity");
62 ok(p12Data
= CFDataCreate(NULL
, signing_identity_p12
, sizeof(signing_identity_p12
)),
64 ok_status(SecItemImport(p12Data
, NULL
, &sef
, NULL
, 0, &keyParams
, keychain
, &imported_items
),
66 is(CFArrayGetCount(imported_items
),1,"Imported 1 items");
67 is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items
, 0)), SecIdentityGetTypeID(),
68 "Got back an identity");
69 ok(identity
= (SecIdentityRef
) CFRetainSafe(CFArrayGetValueAtIndex(imported_items
, 0)),
71 ok_status(CMSEncoderAddSigners(encoder
, identity
), "Set Signer identity");
73 /* Add signing time attribute for 3 November 2015 */
74 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrSigningTime
),
75 "Set signing time flag");
76 ok_status(CMSEncoderSetSigningTime(encoder
, 468295000.0), "Set Signing time");
78 /* Add hash agility attribute */
79 ok_status(CMSEncoderAddSignedAttributes(encoder
, kCMSAttrAppleCodesigningHashAgility
),
80 "Set hash agility flag");
81 ok(attributeData
= CFDataCreate(NULL
, attribute
, sizeof(attribute
)),
82 "Create atttribute object");
83 ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder
, attributeData
),
84 "Set hash agility data");
87 ok_status(CMSEncoderSetHasDetachedContent(encoder
, true), "Set detached content");
88 ok_status(CMSEncoderUpdateContent(encoder
, content
, sizeof(content
)), "Set content");
90 /* output cms message */
91 ok_status(CMSEncoderCopyEncodedContent(encoder
, &message
), "Finish encoding and output message");
94 CMSDecoderRef decoder
= NULL
;
95 CFDataRef contentData
= NULL
;
96 isnt(message
, NULL
, "Encoded message exists");
97 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
98 ok_status(CMSDecoderUpdateMessage(decoder
, CFDataGetBytePtr(message
), CFDataGetLength(message
)),
99 "Update decoder with CMS message");
100 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
101 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
102 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
105 ok_status(SecKeychainDelete(keychain
), "Delete temporary keychain");
107 CFReleaseNull(encoder
);
108 CFReleaseNull(keychain
);
109 CFReleaseNull(p12Data
);
110 CFReleaseNull(imported_items
);
111 CFReleaseNull(identity
);
112 CFReleaseNull(attributeData
);
113 CFReleaseNull(message
);
114 CFReleaseNull(decoder
);
115 CFReleaseNull(contentData
);
118 static void decode_positive_test(void)
120 CMSDecoderRef decoder
= NULL
;
121 CFDataRef contentData
= NULL
, attrValue
= NULL
;
122 SecPolicyRef policy
= NULL
;
123 SecTrustRef trust
= NULL
;
124 CMSSignerStatus signerStatus
;
125 CFAbsoluteTime signingTime
= 0.0;
127 /* Create decoder and decode */
128 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
129 ok_status(CMSDecoderUpdateMessage(decoder
, valid_message
, sizeof(valid_message
)),
130 "Update decoder with CMS message");
131 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
132 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
133 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
135 /* Get signer status */
136 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
137 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
138 "Copy Signer status");
139 is(signerStatus
, kCMSSignerValid
, "Valid signature");
141 /* Get Hash Agility Attribute value */
142 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
143 "Copy hash agility attribute value");
144 is(CFDataGetLength(attrValue
), sizeof(attribute
), "Decoded attribute size");
145 is(memcmp(attribute
, CFDataGetBytePtr(attrValue
), sizeof(attribute
)), 0,
146 "Decoded value same as input value");
148 /* Get Signing Time Attribute value */
149 ok_status(CMSDecoderCopySignerSigningTime(decoder
, 0, &signingTime
),
150 "Copy signing time attribute value");
151 is(signingTime
, 468295000.0, "Decoded date same as input date");
153 CFReleaseNull(decoder
);
154 CFReleaseNull(contentData
);
155 CFReleaseNull(policy
);
156 CFReleaseNull(trust
);
157 CFReleaseNull(attrValue
);
160 static void decode_negative_test(void)
162 CMSDecoderRef decoder
= NULL
;
163 CFDataRef contentData
= NULL
;
164 SecPolicyRef policy
= NULL
;
165 SecTrustRef trust
= NULL
;
166 CMSSignerStatus signerStatus
;
168 /* Create decoder and decode */
169 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
170 ok_status(CMSDecoderUpdateMessage(decoder
, invalid_message
, sizeof(invalid_message
)),
171 "Update decoder with CMS message");
172 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
173 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
174 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
176 /* Get signer status */
177 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
178 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
179 "Copy Signer status");
180 is(signerStatus
, kCMSSignerInvalidSignature
, "Invalid signature");
182 CFReleaseNull(decoder
);
183 CFReleaseNull(contentData
);
184 CFReleaseNull(policy
);
185 CFReleaseNull(trust
);
188 static void decode_no_attr_test(void)
190 CMSDecoderRef decoder
= NULL
;
191 CFDataRef contentData
= NULL
, attrValue
= NULL
;
192 SecPolicyRef policy
= NULL
;
193 SecTrustRef trust
= NULL
;
194 CMSSignerStatus signerStatus
;
196 /* Create decoder and decode */
197 ok_status(CMSDecoderCreate(&decoder
), "Create CMS decoder");
198 ok_status(CMSDecoderUpdateMessage(decoder
, valid_no_attr
, sizeof(valid_no_attr
)),
199 "Update decoder with CMS message");
200 ok(contentData
= CFDataCreate(NULL
, content
, sizeof(content
)), "Create detached content");
201 ok_status(CMSDecoderSetDetachedContent(decoder
, contentData
), "Set detached content");
202 ok_status(CMSDecoderFinalizeMessage(decoder
), "Finalize decoder");
204 /* Get signer status */
205 ok(policy
= SecPolicyCreateBasicX509(), "Create policy");
206 ok_status(CMSDecoderCopySignerStatus(decoder
, 0, policy
, false, &signerStatus
, &trust
, NULL
),
207 "Copy Signer status");
208 is(signerStatus
, kCMSSignerValid
, "Valid signature");
210 /* Get Hash Agility Attribute value */
211 ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder
, 0, &attrValue
),
212 "Copy empty hash agility attribute value");
213 is(attrValue
, NULL
, "NULL attribute value");
215 CFReleaseNull(decoder
);
216 CFReleaseNull(contentData
);
217 CFReleaseNull(policy
);
218 CFReleaseNull(trust
);
219 CFReleaseNull(attrValue
);
222 int cms_hash_agility_test(int argc
, char *const *argv
)
224 plan_tests(24+13+8+10);
227 decode_positive_test();
228 decode_negative_test();
229 decode_no_attr_test();