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