michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * buildChain.c michael@0: * michael@0: * Tests Cert Chain Building michael@0: * michael@0: */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "pkix_pl_generalname.h" michael@0: #include "pkix_pl_cert.h" michael@0: #include "pkix.h" michael@0: #include "testutil.h" michael@0: #include "prlong.h" michael@0: #include "plstr.h" michael@0: #include "prthread.h" michael@0: #include "nspr.h" michael@0: #include "prtypes.h" michael@0: #include "prtime.h" michael@0: #include "pk11func.h" michael@0: #include "secasn1.h" michael@0: #include "cert.h" michael@0: #include "cryptohi.h" michael@0: #include "secoid.h" michael@0: #include "certdb.h" michael@0: #include "secitem.h" michael@0: #include "keythi.h" michael@0: #include "nss.h" michael@0: michael@0: static void *plContext = NULL; michael@0: michael@0: static michael@0: void printUsage(void){ michael@0: (void) printf("\nUSAGE:\tbuildChain " michael@0: " \n\n"); michael@0: (void) printf michael@0: ("Builds a chain of certificates between " michael@0: " and \n" michael@0: "using the certs and CRLs in .\n"); michael@0: } michael@0: michael@0: static PKIX_PL_Cert * michael@0: createCert(char *inFileName) michael@0: { michael@0: PKIX_PL_ByteArray *byteArray = NULL; michael@0: void *buf = NULL; michael@0: PRFileDesc *inFile = NULL; michael@0: PKIX_UInt32 len; michael@0: SECItem certDER; michael@0: SECStatus rv; michael@0: /* default: NULL cert (failure case) */ michael@0: PKIX_PL_Cert *cert = NULL; michael@0: michael@0: PKIX_TEST_STD_VARS(); michael@0: michael@0: certDER.data = NULL; michael@0: michael@0: inFile = PR_Open(inFileName, PR_RDONLY, 0); michael@0: michael@0: if (!inFile){ michael@0: pkixTestErrorMsg = "Unable to open cert file"; michael@0: goto cleanup; michael@0: } else { michael@0: rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE, PR_FALSE); michael@0: if (!rv){ michael@0: buf = (void *)certDER.data; michael@0: len = certDER.len; michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create michael@0: (buf, len, &byteArray, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_Create michael@0: (byteArray, &cert, plContext)); michael@0: michael@0: SECITEM_FreeItem(&certDER, PR_FALSE); michael@0: } else { michael@0: pkixTestErrorMsg = "Unable to read DER from cert file"; michael@0: goto cleanup; michael@0: } michael@0: } michael@0: michael@0: cleanup: michael@0: michael@0: if (inFile){ michael@0: PR_Close(inFile); michael@0: } michael@0: michael@0: if (PKIX_TEST_ERROR_RECEIVED){ michael@0: SECITEM_FreeItem(&certDER, PR_FALSE); michael@0: } michael@0: michael@0: PKIX_TEST_DECREF_AC(byteArray); michael@0: michael@0: PKIX_TEST_RETURN(); michael@0: michael@0: return (cert); michael@0: } michael@0: michael@0: int build_chain(int argc, char *argv[]) michael@0: { michael@0: PKIX_BuildResult *buildResult = NULL; michael@0: PKIX_ComCertSelParams *certSelParams = NULL; michael@0: PKIX_CertSelector *certSelector = NULL; michael@0: PKIX_TrustAnchor *anchor = NULL; michael@0: PKIX_List *anchors = NULL; michael@0: PKIX_List *certs = NULL; michael@0: PKIX_PL_Cert *cert = NULL; michael@0: PKIX_ProcessingParams *procParams = NULL; michael@0: char *trustedCertFile = NULL; michael@0: char *targetCertFile = NULL; michael@0: char *storeDirAscii = NULL; michael@0: PKIX_PL_String *storeDirString = NULL; michael@0: PKIX_PL_Cert *trustedCert = NULL; michael@0: PKIX_PL_Cert *targetCert = NULL; michael@0: PKIX_UInt32 actualMinorVersion, numCerts, i; michael@0: PKIX_UInt32 j = 0; michael@0: PKIX_CertStore *certStore = NULL; michael@0: PKIX_List *certStores = NULL; michael@0: char * asciiResult = NULL; michael@0: PKIX_Boolean useArenas = PKIX_FALSE; michael@0: void *buildState = NULL; /* needed by pkix_build for non-blocking I/O */ michael@0: void *nbioContext = NULL; michael@0: michael@0: PKIX_TEST_STD_VARS(); michael@0: michael@0: if (argc < 4){ michael@0: printUsage(); michael@0: return (0); michael@0: } michael@0: michael@0: useArenas = PKIX_TEST_ARENAS_ARG(argv[1]); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_Initialize michael@0: (PKIX_TRUE, /* nssInitNeeded */ michael@0: useArenas, michael@0: PKIX_MAJOR_VERSION, michael@0: PKIX_MINOR_VERSION, michael@0: PKIX_MINOR_VERSION, michael@0: &actualMinorVersion, michael@0: &plContext)); michael@0: michael@0: /* create processing params with list of trust anchors */ michael@0: trustedCertFile = argv[j+1]; michael@0: trustedCert = createCert(trustedCertFile); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert michael@0: (trustedCert, &anchor, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem michael@0: (anchors, (PKIX_PL_Object *)anchor, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create michael@0: (anchors, &procParams, plContext)); michael@0: michael@0: michael@0: /* create CertSelector with target certificate in params */ michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ComCertSelParams_Create(&certSelParams, plContext)); michael@0: michael@0: targetCertFile = argv[j+2]; michael@0: targetCert = createCert(targetCertFile); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ComCertSelParams_SetCertificate michael@0: (certSelParams, targetCert, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams michael@0: (certSelector, certSelParams, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ProcessingParams_SetTargetCertConstraints michael@0: (procParams, certSelector, plContext)); michael@0: michael@0: /* create CertStores */ michael@0: michael@0: storeDirAscii = argv[j+3]; michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create michael@0: (PKIX_ESCASCII, storeDirAscii, 0, &storeDirString, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create michael@0: (storeDirString, &certStore, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem michael@0: (certStores, (PKIX_PL_Object *)certStore, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores michael@0: (procParams, certStores, plContext)); michael@0: michael@0: /* build cert chain using processing params and return buildResult */ michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildChain michael@0: (procParams, michael@0: &nbioContext, michael@0: &buildState, michael@0: &buildResult, michael@0: NULL, michael@0: plContext)); michael@0: michael@0: /* michael@0: * As long as we use only CertStores with blocking I/O, we can omit michael@0: * checking for completion with nbioContext. michael@0: */ michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_List_GetLength(certs, &numCerts, plContext)); michael@0: michael@0: printf("\n"); michael@0: michael@0: for (i = 0; i < numCerts; i++){ michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_List_GetItem michael@0: (certs, i, (PKIX_PL_Object**)&cert, plContext)); michael@0: michael@0: asciiResult = PKIX_Cert2ASCII(cert); michael@0: michael@0: printf("CERT[%d]:\n%s\n", i, asciiResult); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, plContext)); michael@0: asciiResult = NULL; michael@0: michael@0: PKIX_TEST_DECREF_BC(cert); michael@0: } michael@0: michael@0: cleanup: michael@0: michael@0: if (PKIX_TEST_ERROR_RECEIVED){ michael@0: (void) printf("FAILED TO BUILD CHAIN\n"); michael@0: } else { michael@0: (void) printf("SUCCESSFULLY BUILT CHAIN\n"); michael@0: } michael@0: michael@0: PKIX_PL_Free(asciiResult, plContext); michael@0: michael@0: PKIX_TEST_DECREF_AC(certs); michael@0: PKIX_TEST_DECREF_AC(cert); michael@0: PKIX_TEST_DECREF_AC(certStore); michael@0: PKIX_TEST_DECREF_AC(certStores); michael@0: PKIX_TEST_DECREF_AC(storeDirString); michael@0: PKIX_TEST_DECREF_AC(trustedCert); michael@0: PKIX_TEST_DECREF_AC(targetCert); michael@0: PKIX_TEST_DECREF_AC(anchor); michael@0: PKIX_TEST_DECREF_AC(anchors); michael@0: PKIX_TEST_DECREF_AC(procParams); michael@0: PKIX_TEST_DECREF_AC(certSelParams); michael@0: PKIX_TEST_DECREF_AC(certSelector); michael@0: PKIX_TEST_DECREF_AC(buildResult); michael@0: michael@0: PKIX_TEST_RETURN(); michael@0: michael@0: PKIX_Shutdown(plContext); michael@0: michael@0: return (0); michael@0: michael@0: }