1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * test_buildchain.c
6 *
7 * Test BuildChain function
8 *
9 */
10
11 /* #define debuggingWithoutRevocation */
12
13 #include "testutil.h"
14 #include "testutil_nss.h"
15
16 #define LDAP_PORT 389
17 static PKIX_Boolean usebind = PKIX_FALSE;
18 static PKIX_Boolean useLDAP = PKIX_FALSE;
19 static char buf[PR_NETDB_BUF_SIZE];
20 static char *serverName = NULL;
21 static char *sepPtr = NULL;
22 static PRNetAddr netAddr;
23 static PRHostEnt hostent;
24 static PKIX_UInt32 portNum = 0;
25 static PRIntn hostenum = 0;
26 static PRStatus prstatus = PR_FAILURE;
27 static void *ipaddr = NULL;
28
29 static void *plContext = NULL;
30
31 static void
printUsage(void)32 printUsage(void)
33 {
34 (void)printf("\nUSAGE:\ttest_buildchain [-arenas] [usebind] "
35 "servername[:port] <testName> [ENE|EE]\n"
36 "\t <certStoreDirectory> <targetCert>"
37 " <intermediate Certs...> <trustedCert>\n\n");
38 (void)printf("Builds a chain of certificates from <targetCert> to <trustedCert>\n"
39 "using the certs and CRLs in <certStoreDirectory>. "
40 "servername[:port] gives\n"
41 "the address of an LDAP server. If port is not"
42 " specified, port 389 is used. \"-\" means no LDAP server.\n"
43 "If ENE is specified, then an Error is Not Expected. "
44 "EE indicates an Error is Expected.\n");
45 }
46
47 static PKIX_Error *
createLdapCertStore(char * hostname,PRIntervalTime timeout,PKIX_CertStore ** pLdapCertStore,void * plContext)48 createLdapCertStore(
49 char *hostname,
50 PRIntervalTime timeout,
51 PKIX_CertStore **pLdapCertStore,
52 void *plContext)
53 {
54 PRIntn backlog = 0;
55
56 char *bindname = "";
57 char *auth = "";
58
59 LDAPBindAPI bindAPI;
60 LDAPBindAPI *bindPtr = NULL;
61 PKIX_PL_LdapDefaultClient *ldapClient = NULL;
62 PKIX_CertStore *ldapCertStore = NULL;
63
64 PKIX_TEST_STD_VARS();
65
66 if (usebind) {
67 bindPtr = &bindAPI;
68 bindAPI.selector = SIMPLE_AUTH;
69 bindAPI.chooser.simple.bindName = bindname;
70 bindAPI.chooser.simple.authentication = auth;
71 }
72
73 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapDefaultClient_CreateByName(hostname, timeout, bindPtr, &ldapClient, plContext));
74
75 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapCertStore_Create((PKIX_PL_LdapClient *)ldapClient,
76 &ldapCertStore,
77 plContext));
78
79 *pLdapCertStore = ldapCertStore;
80 cleanup:
81
82 PKIX_TEST_DECREF_AC(ldapClient);
83
84 PKIX_TEST_RETURN();
85
86 return (pkixTestErrorResult);
87 }
88
89 int
test_buildchain(int argc,char * argv[])90 test_buildchain(int argc, char *argv[])
91 {
92 PKIX_BuildResult *buildResult = NULL;
93 PKIX_ComCertSelParams *certSelParams = NULL;
94 PKIX_CertSelector *certSelector = NULL;
95 PKIX_TrustAnchor *anchor = NULL;
96 PKIX_PL_PublicKey *trustedPubKey = NULL;
97 PKIX_List *anchors = NULL;
98 PKIX_List *certs = NULL;
99 PKIX_RevocationChecker *revChecker = NULL;
100 PKIX_PL_Cert *cert = NULL;
101 PKIX_ProcessingParams *procParams = NULL;
102 char *dirName = NULL;
103 PKIX_PL_String *dirNameString = NULL;
104 PKIX_PL_Cert *trustedCert = NULL;
105 PKIX_PL_Cert *targetCert = NULL;
106 PKIX_UInt32 actualMinorVersion = 0;
107 PKIX_UInt32 numCerts = 0;
108 PKIX_UInt32 i = 0;
109 PKIX_UInt32 j = 0;
110 PKIX_UInt32 k = 0;
111 PKIX_CertStore *ldapCertStore = NULL;
112 PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; /* blocking */
113 /* PRIntervalTime timeout = PR_INTERVAL_NO_WAIT; =0 for non-blocking */
114 PKIX_CertStore *certStore = NULL;
115 PKIX_List *certStores = NULL;
116 PKIX_List *revCheckers = NULL;
117 char *asciiResult = NULL;
118 PKIX_Boolean result = PKIX_FALSE;
119 PKIX_Boolean testValid = PKIX_TRUE;
120 PKIX_List *expectedCerts = NULL;
121 PKIX_PL_Cert *dirCert = NULL;
122 PKIX_VerifyNode *verifyTree = NULL;
123 PKIX_PL_String *verifyString = NULL;
124 PKIX_PL_String *actualCertsString = NULL;
125 PKIX_PL_String *expectedCertsString = NULL;
126 void *state = NULL;
127 char *actualCertsAscii = NULL;
128 char *expectedCertsAscii = NULL;
129 PRPollDesc *pollDesc = NULL;
130
131 PKIX_TEST_STD_VARS();
132
133 if (argc < 5) {
134 printUsage();
135 return (0);
136 }
137
138 startTests("BuildChain");
139
140 PKIX_TEST_EXPECT_NO_ERROR(
141 PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
142
143 /*
144 * arguments:
145 * [optional] -arenas
146 * [optional] usebind
147 * servername or servername:port ( - for no server)
148 * testname
149 * EE or ENE
150 * cert directory
151 * target cert (end entity)
152 * intermediate certs
153 * trust anchor
154 */
155
156 /* optional argument "usebind" for Ldap CertStore */
157 if (argv[j + 1]) {
158 if (PORT_Strcmp(argv[j + 1], "usebind") == 0) {
159 usebind = PKIX_TRUE;
160 j++;
161 }
162 }
163
164 if (PORT_Strcmp(argv[++j], "-") == 0) {
165 useLDAP = PKIX_FALSE;
166 } else {
167 serverName = argv[j];
168 useLDAP = PKIX_TRUE;
169 }
170
171 subTest(argv[++j]);
172
173 /* ENE = expect no error; EE = expect error */
174 if (PORT_Strcmp(argv[++j], "ENE") == 0) {
175 testValid = PKIX_TRUE;
176 } else if (PORT_Strcmp(argv[j], "EE") == 0) {
177 testValid = PKIX_FALSE;
178 } else {
179 printUsage();
180 return (0);
181 }
182
183 dirName = argv[++j];
184
185 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext));
186
187 for (k = ++j; k < (PKIX_UInt32)argc; k++) {
188
189 dirCert = createCert(dirName, argv[k], plContext);
190
191 if (k == (PKIX_UInt32)(argc - 1)) {
192 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
193 trustedCert = dirCert;
194 } else {
195
196 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedCerts,
197 (PKIX_PL_Object *)dirCert,
198 plContext));
199
200 if (k == j) {
201 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
202 targetCert = dirCert;
203 }
204 }
205
206 PKIX_TEST_DECREF_BC(dirCert);
207 }
208
209 /* create processing params with list of trust anchors */
210
211 PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
212 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
213 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
214 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
215
216 /* create CertSelector with target certificate in params */
217
218 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
219
220 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
221
222 PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
223
224 PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
225
226 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
227
228 /* create CertStores */
229
230 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, dirName, 0, &dirNameString, plContext));
231
232 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
233
234 if (useLDAP == PKIX_TRUE) {
235 PKIX_TEST_EXPECT_NO_ERROR(createLdapCertStore(serverName, timeout, &ldapCertStore, plContext));
236
237 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores,
238 (PKIX_PL_Object *)ldapCertStore,
239 plContext));
240 } else {
241 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirNameString, &certStore, plContext));
242 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
243 }
244
245 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
246
247 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
248
249 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(trustedCert, &trustedPubKey, plContext));
250
251 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(expectedCerts, &numCerts, plContext));
252
253 PKIX_TEST_EXPECT_NO_ERROR(pkix_DefaultRevChecker_Initialize(certStores,
254 NULL, /* testDate, may be NULL */
255 trustedPubKey,
256 numCerts,
257 &revChecker,
258 plContext));
259
260 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
261
262 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
263
264 #ifdef debuggingWithoutRevocation
265 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
266 #endif
267
268 /* build cert chain using processing params and return buildResult */
269
270 pkixTestErrorResult = PKIX_BuildChain(procParams,
271 (void **)&pollDesc,
272 &state,
273 &buildResult,
274 &verifyTree,
275 plContext);
276
277 while (pollDesc != NULL) {
278
279 if (PR_Poll(pollDesc, 1, 0) < 0) {
280 testError("PR_Poll failed");
281 }
282
283 pkixTestErrorResult = PKIX_BuildChain(procParams,
284 (void **)&pollDesc,
285 &state,
286 &buildResult,
287 &verifyTree,
288 plContext);
289 }
290
291 if (pkixTestErrorResult) {
292 if (testValid == PKIX_FALSE) { /* EE */
293 (void)printf("EXPECTED ERROR RECEIVED!\n");
294 } else { /* ENE */
295 testError("UNEXPECTED ERROR RECEIVED");
296 }
297 } else {
298 if (testValid == PKIX_TRUE) { /* ENE */
299 (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
300 } else { /* EE */
301 (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
302 }
303 }
304
305 subTest("Displaying VerifyNode objects");
306
307 if (verifyTree == NULL) {
308 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, "(null)", 0, &verifyString, plContext));
309 } else {
310 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
311 }
312
313 (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
314
315 if (pkixTestErrorResult) {
316 PKIX_TEST_DECREF_BC(pkixTestErrorResult);
317 goto cleanup;
318 }
319
320 if (buildResult) {
321
322 PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
323
324 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
325
326 printf("\n");
327
328 for (i = 0; i < numCerts; i++) {
329 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
330 i,
331 (PKIX_PL_Object **)&cert,
332 plContext));
333
334 asciiResult = PKIX_Cert2ASCII(cert);
335
336 printf("CERT[%d]:\n%s\n", i, asciiResult);
337
338 /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
339 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
340 asciiResult = NULL;
341
342 PKIX_TEST_DECREF_BC(cert);
343 }
344
345 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)certs,
346 (PKIX_PL_Object *)expectedCerts,
347 &result,
348 plContext));
349
350 if (!result) {
351 testError("BUILT CERTCHAIN IS "
352 "NOT THE ONE THAT WAS EXPECTED");
353
354 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)certs,
355 &actualCertsString,
356 plContext));
357
358 actualCertsAscii = PKIX_String2ASCII(actualCertsString, plContext);
359 if (actualCertsAscii == NULL) {
360 pkixTestErrorMsg = "PKIX_String2ASCII Failed";
361 goto cleanup;
362 }
363
364 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)expectedCerts,
365 &expectedCertsString,
366 plContext));
367
368 expectedCertsAscii = PKIX_String2ASCII(expectedCertsString, plContext);
369 if (expectedCertsAscii == NULL) {
370 pkixTestErrorMsg = "PKIX_String2ASCII Failed";
371 goto cleanup;
372 }
373
374 (void)printf("Actual value:\t%s\n", actualCertsAscii);
375 (void)printf("Expected value:\t%s\n",
376 expectedCertsAscii);
377 }
378 }
379
380 cleanup:
381 PKIX_TEST_DECREF_AC(verifyString);
382 PKIX_TEST_DECREF_AC(verifyTree);
383
384 PKIX_PL_Free(asciiResult, NULL);
385 PKIX_PL_Free(actualCertsAscii, plContext);
386 PKIX_PL_Free(expectedCertsAscii, plContext);
387
388 PKIX_TEST_DECREF_AC(state);
389 PKIX_TEST_DECREF_AC(actualCertsString);
390 PKIX_TEST_DECREF_AC(expectedCertsString);
391 PKIX_TEST_DECREF_AC(expectedCerts);
392 PKIX_TEST_DECREF_AC(buildResult);
393 PKIX_TEST_DECREF_AC(procParams);
394 PKIX_TEST_DECREF_AC(certStores);
395 PKIX_TEST_DECREF_AC(revCheckers);
396 PKIX_TEST_DECREF_AC(revChecker);
397 PKIX_TEST_DECREF_AC(ldapCertStore);
398 PKIX_TEST_DECREF_AC(certStore);
399 PKIX_TEST_DECREF_AC(dirNameString);
400 PKIX_TEST_DECREF_AC(certSelParams);
401 PKIX_TEST_DECREF_AC(certSelector);
402 PKIX_TEST_DECREF_AC(anchors);
403 PKIX_TEST_DECREF_AC(anchor);
404 PKIX_TEST_DECREF_AC(trustedCert);
405 PKIX_TEST_DECREF_AC(trustedPubKey);
406
407 PKIX_TEST_DECREF_AC(certs);
408 PKIX_TEST_DECREF_AC(cert);
409 PKIX_TEST_DECREF_AC(targetCert);
410
411 PKIX_TEST_RETURN();
412
413 PKIX_Shutdown(plContext);
414
415 endTests("BuildChain");
416
417 return (0);
418 }
419