]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/makeExpiredCerts/makeExpiredCerts.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / makeExpiredCerts / makeExpiredCerts.cpp
1 /*
2 * makeExpiredCerts.cpp - Make expired certs to verify Radar 3622125.
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <utilLib/common.h>
10 #include <utilLib/cspwrap.h>
11 #include <security_cdsa_utils/cuFileIo.h>
12 #include <clAppUtils/CertBuilderApp.h>
13 #include <clAppUtils/clutils.h>
14 #include <Security/x509defs.h>
15 #include <Security/oidsattr.h>
16 #include <Security/oidscert.h>
17 #include <Security/oidsalg.h>
18
19 /*
20 * The certs we create and write.
21 * -- GOOD_ROOT and EXPIRED_ROOT use same key pair, subject, issuer name
22 * -- GOOD_CA and EXPIRED_CA use same key pair, subject, issuer name; both are
23 * verifiable by both GOOD_ROOT and EXPIRED_ROOT (temporal validity aside,
24 * that is)
25 * -- GOOD_LEAF and EXPIRED_LEAF use same key pair, subject, issuer name, both
26 * are verifiable by both GOOD_CA and EXPIRED_CA (temporal validity aside,
27 * that is)
28 */
29 #define GOOD_ROOT "ecGoodRoot.cer"
30 #define EXPIRED_ROOT "ecExpiredRoot.cer"
31 #define GOOD_CA "ecGoodCA.cer"
32 #define EXPIRED_CA "ecExpiredCA.cer"
33 #define GOOD_LEAF "ecGoodLeaf.cer"
34 #define EXPIRED_LEAF "ecExpiredLeaf.cer"
35
36 /*
37 * RDN components for root, CA, subject
38 */
39 CB_NameOid rootRdn[] =
40 {
41 { "Expired Cert Test Root", &CSSMOID_CommonName }
42 };
43 #define NUM_ROOT_NAMES (sizeof(rootRdn) / sizeof(CB_NameOid))
44
45 CB_NameOid caRdn[] =
46 {
47 { "Expired Cert Test CA", &CSSMOID_CommonName }
48 };
49 #define NUM_CA_NAMES (sizeof(caRdn) / sizeof(CB_NameOid))
50
51 CB_NameOid leafRdn[] =
52 {
53 { "Expired Cert Test Leaf", &CSSMOID_CommonName }
54 };
55 #define NUM_LEAF_NAMES (sizeof(leafRdn) / sizeof(CB_NameOid))
56
57 /* Key parameters */
58 #define LEAF_KEY_LABEL "Expired Cert Leaf"
59 #define CA_KEY_LABEL "Expired Cert CA"
60 #define ROOT_KEY_LABEL "Expired Cert Root"
61 #define SIG_ALG CSSM_ALGID_SHA1WithRSA
62 #define KEY_ALG CSSM_ALGID_RSA
63 #define KEY_SIZE 1024
64
65 static void usage(char **argv)
66 {
67 printf("usage: %s dstdir\n", argv[0]);
68 exit(1);
69 }
70
71 /* write cert to dstDir/fileName */
72 static int writeCert(
73 const CSSM_DATA *certData,
74 const char *fileName,
75 const char *dstDir)
76 {
77 unsigned pathLen = strlen(fileName) + strlen(dstDir) + 2;
78 char filePath[pathLen];
79 sprintf(filePath, "%s/%s", dstDir, fileName);
80 if(writeFile(filePath, certData->Data, certData->Length)) {
81 printf("***Error writing cert to %s\n", filePath);
82 return -1;
83 }
84 else {
85 printf("...wrote %lu bytes to %s.\n", (unsigned long)certData->Length, filePath);
86 return 0;
87 }
88 }
89
90 static int makeCert(
91 CSSM_CL_HANDLE clHand,
92 CSSM_CSP_HANDLE cspHand,
93 CSSM_X509_NAME *subject,
94 CSSM_X509_NAME *issuer,
95 uint32 serialNum,
96 CSSM_X509_TIME *notBefore,
97 CSSM_X509_TIME *notAfter,
98 CSSM_KEY_PTR privKey, /* signed with this */
99 CSSM_KEY_PTR pubKey, /* contains this */
100 bool isCA,
101 CSSM_DATA *certData, /* signed cert returned here */
102 const char *dstDir,
103 const char *fileName) /* and written here in dstDir/fileName */
104 {
105 CSSM_DATA_PTR tbsCert;
106 CSSM_X509_EXTENSION ext;
107 CE_BasicConstraints bc;
108
109 ext.extnId = CSSMOID_BasicConstraints;
110 ext.critical = CSSM_TRUE;
111 ext.format = CSSM_X509_DATAFORMAT_PARSED;
112 bc.cA = isCA ? CSSM_TRUE : CSSM_FALSE;
113 bc.pathLenConstraintPresent = CSSM_FALSE;
114 bc.pathLenConstraint = 0;
115 ext.value.parsedValue = &bc;
116 ext.BERvalue.Data = NULL;
117 ext.BERvalue.Length = 0;
118
119 tbsCert = CB_MakeCertTemplate(clHand,
120 serialNum,
121 issuer,
122 subject,
123 notBefore,
124 notAfter,
125 pubKey,
126 SIG_ALG,
127 NULL, // subjUniqueId
128 NULL, // issuerUniqueId
129 &ext, // extensions
130 1); // numExtensions
131 if(tbsCert == NULL) {
132 return -1;
133 }
134
135 CSSM_CC_HANDLE signContext;
136 CSSM_RETURN crtn;
137 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
138 SIG_ALG,
139 NULL, // AccessCred
140 privKey,
141 &signContext);
142 if(crtn) {
143 cssmPerror("CSSM_CSP_CreateSignatureContext", crtn);
144 /* this program is way sloppy about cleanup on errors */
145 return -1;
146 }
147 certData->Data = NULL;
148 certData->Length = 0;
149 crtn = CSSM_CL_CertSign(clHand,
150 signContext,
151 tbsCert, // CertToBeSigned
152 NULL, // SignScope
153 0, // ScopeSize,
154 certData);
155 if(crtn) {
156 cssmPerror("CSSM_CL_CertSign", crtn);
157 return -1;
158 }
159 CSSM_DeleteContext(signContext);
160 appFreeCssmData(tbsCert, CSSM_TRUE);
161 return writeCert(certData, fileName, dstDir);
162 }
163
164 int main(int argc, char **argv)
165 {
166 if(argc != 2) {
167 usage(argv);
168 }
169 const char *dstDir = argv[1];
170
171 CSSM_CL_HANDLE clHand = clStartup();
172 if(clHand == 0) {
173 return 0;
174 }
175 CSSM_CSP_HANDLE cspHand = cspStartup();
176 if(cspHand == 0) {
177 return 0;
178 }
179
180 /* Cook up 3 key pairs */
181 CSSM_KEY rootPrivKey;
182 CSSM_KEY rootPubKey;
183 CSSM_KEY caPrivKey;
184 CSSM_KEY caPubKey;
185 CSSM_KEY leafPrivKey;
186 CSSM_KEY leafPubKey;
187
188 CSSM_RETURN crtn = cspGenKeyPair(cspHand,
189 KEY_ALG,
190 ROOT_KEY_LABEL,
191 strlen(ROOT_KEY_LABEL),
192 KEY_SIZE,
193 &rootPubKey,
194 CSSM_FALSE, // pubIsRef
195 CSSM_KEYUSE_VERIFY,
196 CSSM_KEYBLOB_RAW_FORMAT_NONE,
197 &rootPrivKey,
198 CSSM_FALSE, // privIsRef
199 CSSM_KEYUSE_SIGN,
200 CSSM_KEYBLOB_RAW_FORMAT_NONE,
201 CSSM_FALSE);
202 if(crtn) {
203 exit(1);
204 }
205 crtn = cspGenKeyPair(cspHand,
206 KEY_ALG,
207 CA_KEY_LABEL,
208 strlen(CA_KEY_LABEL),
209 KEY_SIZE,
210 &caPubKey,
211 CSSM_FALSE, // pubIsRef
212 CSSM_KEYUSE_VERIFY,
213 CSSM_KEYBLOB_RAW_FORMAT_NONE,
214 &caPrivKey,
215 CSSM_FALSE, // privIsRef
216 CSSM_KEYUSE_SIGN,
217 CSSM_KEYBLOB_RAW_FORMAT_NONE,
218 CSSM_FALSE);
219 if(crtn) {
220 exit(1);
221 }
222 crtn = cspGenKeyPair(cspHand,
223 KEY_ALG,
224 LEAF_KEY_LABEL,
225 strlen(LEAF_KEY_LABEL),
226 KEY_SIZE,
227 &leafPubKey,
228 CSSM_FALSE, // pubIsRef
229 CSSM_KEYUSE_VERIFY,
230 CSSM_KEYBLOB_RAW_FORMAT_NONE,
231 &leafPrivKey,
232 CSSM_FALSE, // privIsRef
233 CSSM_KEYUSE_SIGN,
234 CSSM_KEYBLOB_RAW_FORMAT_NONE,
235 CSSM_FALSE);
236 if(crtn) {
237 exit(1);
238 }
239
240 /* now, subject and issuer names */
241 CSSM_X509_NAME *rootSubj = CB_BuildX509Name(rootRdn, NUM_ROOT_NAMES);
242 CSSM_X509_NAME *caSubj = CB_BuildX509Name(caRdn, NUM_CA_NAMES);
243 CSSM_X509_NAME *leafSubj = CB_BuildX509Name(leafRdn, NUM_LEAF_NAMES);
244
245 /* times: now (for all not before), +10 seconds (for expired), +10 years (for valid not after) */
246 CSSM_X509_TIME *nowTime = CB_BuildX509Time(0, NULL);
247 CSSM_X509_TIME *soonTime = CB_BuildX509Time(10, NULL);
248 CSSM_X509_TIME *futureTime = CB_BuildX509Time(60 * 60 * 24 * 365 * 10, NULL);
249
250 /* six certs */
251 CSSM_DATA goodRoot;
252 CSSM_DATA expiredRoot;
253 CSSM_DATA goodCA;
254 CSSM_DATA expiredCA;
255 CSSM_DATA goodLeaf;
256 CSSM_DATA expiredLeaf;
257 uint32 serialNum = 0;
258
259 if(makeCert(clHand, cspHand,
260 rootSubj, rootSubj, serialNum++, nowTime, futureTime,
261 &rootPrivKey, &rootPubKey, true,
262 &goodRoot, dstDir, GOOD_ROOT)) {
263 printf("***Error creating good root. Aborting.\n");
264 exit(1);
265 }
266 if(makeCert(clHand, cspHand,
267 rootSubj, rootSubj, serialNum++, nowTime, soonTime,
268 &rootPrivKey, &rootPubKey, true,
269 &expiredRoot, dstDir, EXPIRED_ROOT)) {
270 printf("***Error creating expired root. Aborting.\n");
271 exit(1);
272 }
273
274 /* CA signed by root */
275 if(makeCert(clHand, cspHand,
276 caSubj, rootSubj, serialNum++, nowTime, futureTime,
277 &rootPrivKey, &caPubKey, true,
278 &goodCA, dstDir, GOOD_CA)) {
279 printf("***Error creating good CA. Aborting.\n");
280 exit(1);
281 }
282 if(makeCert(clHand, cspHand,
283 caSubj, rootSubj, serialNum++, nowTime, soonTime,
284 &rootPrivKey, &caPubKey, true,
285 &expiredCA, dstDir, EXPIRED_CA)) {
286 printf("***Error creating expired CA. Aborting.\n");
287 exit(1);
288 }
289
290 /* Leaf signed by CA */
291 if(makeCert(clHand, cspHand,
292 leafSubj, caSubj, serialNum++, nowTime, futureTime,
293 &caPrivKey, &leafPubKey, false,
294 &goodLeaf, dstDir, GOOD_LEAF)) {
295 printf("***Error creating good leaf. Aborting.\n");
296 exit(1);
297 }
298 if(makeCert(clHand, cspHand,
299 leafSubj, caSubj, serialNum++, nowTime, soonTime,
300 &caPrivKey, &leafPubKey, false,
301 &expiredLeaf, dstDir, EXPIRED_LEAF)) {
302 printf("***Error creating expired leaf. Aborting.\n");
303 exit(1);
304 }
305
306 /* cleanup if you think you must */
307
308 return 0;
309 }