build_chain.c (7486B)
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 * buildChain.c 6 * 7 * Tests Cert Chain Building 8 * 9 */ 10 11 #include <stdio.h> 12 #include <string.h> 13 #include <stddef.h> 14 15 #include "pkix_pl_generalname.h" 16 #include "pkix_pl_cert.h" 17 #include "pkix.h" 18 #include "testutil.h" 19 #include "prlong.h" 20 #include "plstr.h" 21 #include "prthread.h" 22 #include "nspr.h" 23 #include "prtypes.h" 24 #include "prtime.h" 25 #include "pk11func.h" 26 #include "secasn1.h" 27 #include "cert.h" 28 #include "cryptohi.h" 29 #include "secoid.h" 30 #include "certdb.h" 31 #include "secitem.h" 32 #include "keythi.h" 33 #include "nss.h" 34 35 static void *plContext = NULL; 36 37 static void 38 printUsage(void) 39 { 40 (void)printf("\nUSAGE:\tbuildChain " 41 "<trustedCert> <targetCert> <certStoreDirectory>\n\n"); 42 (void)printf("Builds a chain of certificates between " 43 "<trustedCert> and <targetCert>\n" 44 "using the certs and CRLs in <certStoreDirectory>.\n"); 45 } 46 47 static PKIX_PL_Cert * 48 createCert(char *inFileName) 49 { 50 PKIX_PL_ByteArray *byteArray = NULL; 51 void *buf = NULL; 52 PRFileDesc *inFile = NULL; 53 PKIX_UInt32 len; 54 SECItem certDER; 55 SECStatus rv; 56 /* default: NULL cert (failure case) */ 57 PKIX_PL_Cert *cert = NULL; 58 59 PKIX_TEST_STD_VARS(); 60 61 certDER.data = NULL; 62 63 inFile = PR_Open(inFileName, PR_RDONLY, 0); 64 65 if (!inFile) { 66 pkixTestErrorMsg = "Unable to open cert file"; 67 goto cleanup; 68 } else { 69 rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE, PR_FALSE); 70 if (!rv) { 71 buf = (void *)certDER.data; 72 len = certDER.len; 73 74 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext)); 75 76 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_Create(byteArray, &cert, plContext)); 77 78 SECITEM_FreeItem(&certDER, PR_FALSE); 79 } else { 80 pkixTestErrorMsg = "Unable to read DER from cert file"; 81 goto cleanup; 82 } 83 } 84 85 cleanup: 86 87 if (inFile) { 88 PR_Close(inFile); 89 } 90 91 if (PKIX_TEST_ERROR_RECEIVED) { 92 SECITEM_FreeItem(&certDER, PR_FALSE); 93 } 94 95 PKIX_TEST_DECREF_AC(byteArray); 96 97 PKIX_TEST_RETURN(); 98 99 return (cert); 100 } 101 102 int 103 build_chain(int argc, char *argv[]) 104 { 105 PKIX_BuildResult *buildResult = NULL; 106 PKIX_ComCertSelParams *certSelParams = NULL; 107 PKIX_CertSelector *certSelector = NULL; 108 PKIX_TrustAnchor *anchor = NULL; 109 PKIX_List *anchors = NULL; 110 PKIX_List *certs = NULL; 111 PKIX_PL_Cert *cert = NULL; 112 PKIX_ProcessingParams *procParams = NULL; 113 char *trustedCertFile = NULL; 114 char *targetCertFile = NULL; 115 char *storeDirAscii = NULL; 116 PKIX_PL_String *storeDirString = NULL; 117 PKIX_PL_Cert *trustedCert = NULL; 118 PKIX_PL_Cert *targetCert = NULL; 119 PKIX_UInt32 actualMinorVersion, numCerts, i; 120 PKIX_UInt32 j = 0; 121 PKIX_CertStore *certStore = NULL; 122 PKIX_List *certStores = NULL; 123 char *asciiResult = NULL; 124 PKIX_Boolean useArenas = PKIX_FALSE; 125 void *buildState = NULL; /* needed by pkix_build for non-blocking I/O */ 126 void *nbioContext = NULL; 127 128 PKIX_TEST_STD_VARS(); 129 130 if (argc < 4) { 131 printUsage(); 132 return (0); 133 } 134 135 useArenas = PKIX_TEST_ARENAS_ARG(argv[1]); 136 137 PKIX_TEST_EXPECT_NO_ERROR(PKIX_Initialize(PKIX_TRUE, /* nssInitNeeded */ 138 useArenas, 139 PKIX_MAJOR_VERSION, 140 PKIX_MINOR_VERSION, 141 PKIX_MINOR_VERSION, 142 &actualMinorVersion, 143 &plContext)); 144 145 /* create processing params with list of trust anchors */ 146 trustedCertFile = argv[j + 1]; 147 trustedCert = createCert(trustedCertFile); 148 149 PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext)); 150 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext)); 151 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext)); 152 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext)); 153 154 /* create CertSelector with target certificate in params */ 155 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext)); 156 157 targetCertFile = argv[j + 2]; 158 targetCert = createCert(targetCertFile); 159 160 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext)); 161 162 PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext)); 163 164 PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext)); 165 166 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext)); 167 168 /* create CertStores */ 169 170 storeDirAscii = argv[j + 3]; 171 172 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, storeDirAscii, 0, &storeDirString, plContext)); 173 174 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(storeDirString, &certStore, plContext)); 175 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext)); 176 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext)); 177 178 PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext)); 179 180 /* build cert chain using processing params and return buildResult */ 181 182 PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildChain(procParams, 183 &nbioContext, 184 &buildState, 185 &buildResult, 186 NULL, 187 plContext)); 188 189 /* 190 * As long as we use only CertStores with blocking I/O, we can omit 191 * checking for completion with nbioContext. 192 */ 193 194 PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext)); 195 196 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext)); 197 198 printf("\n"); 199 200 for (i = 0; i < numCerts; i++) { 201 PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, i, (PKIX_PL_Object **)&cert, plContext)); 202 203 asciiResult = PKIX_Cert2ASCII(cert); 204 205 printf("CERT[%d]:\n%s\n", i, asciiResult); 206 207 PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, plContext)); 208 asciiResult = NULL; 209 210 PKIX_TEST_DECREF_BC(cert); 211 } 212 213 cleanup: 214 215 if (PKIX_TEST_ERROR_RECEIVED) { 216 (void)printf("FAILED TO BUILD CHAIN\n"); 217 } else { 218 (void)printf("SUCCESSFULLY BUILT CHAIN\n"); 219 } 220 221 PKIX_PL_Free(asciiResult, plContext); 222 223 PKIX_TEST_DECREF_AC(certs); 224 PKIX_TEST_DECREF_AC(cert); 225 PKIX_TEST_DECREF_AC(certStore); 226 PKIX_TEST_DECREF_AC(certStores); 227 PKIX_TEST_DECREF_AC(storeDirString); 228 PKIX_TEST_DECREF_AC(trustedCert); 229 PKIX_TEST_DECREF_AC(targetCert); 230 PKIX_TEST_DECREF_AC(anchor); 231 PKIX_TEST_DECREF_AC(anchors); 232 PKIX_TEST_DECREF_AC(procParams); 233 PKIX_TEST_DECREF_AC(certSelParams); 234 PKIX_TEST_DECREF_AC(certSelector); 235 PKIX_TEST_DECREF_AC(buildResult); 236 237 PKIX_TEST_RETURN(); 238 239 PKIX_Shutdown(plContext); 240 241 return (0); 242 }