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: * validateChain.c michael@0: * michael@0: * Tests Cert Chain Validation 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:\tvalidateChain " michael@0: " ... \n"); michael@0: (void) printf("\tValidates a chain of n certificates " michael@0: "using the given trust anchor.\n"); michael@0: 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 michael@0: (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 validate_chain(int argc, char *argv[]) michael@0: { michael@0: PKIX_TrustAnchor *anchor = NULL; michael@0: PKIX_List *anchors = NULL; michael@0: PKIX_List *certs = NULL; michael@0: PKIX_ProcessingParams *procParams = NULL; michael@0: PKIX_ValidateParams *valParams = NULL; michael@0: PKIX_ValidateResult *valResult = NULL; michael@0: PKIX_PL_X500Name *subject = NULL; michael@0: PKIX_ComCertSelParams *certSelParams = NULL; michael@0: PKIX_CertSelector *certSelector = NULL; michael@0: PKIX_VerifyNode *verifyTree = NULL; michael@0: PKIX_PL_String *verifyString = NULL; michael@0: michael@0: char *trustedCertFile = NULL; michael@0: char *chainCertFile = NULL; michael@0: PKIX_PL_Cert *trustedCert = NULL; michael@0: PKIX_PL_Cert *chainCert = NULL; michael@0: PKIX_UInt32 chainLength = 0; michael@0: PKIX_UInt32 i = 0; michael@0: PKIX_UInt32 j = 0; michael@0: PKIX_UInt32 actualMinorVersion; michael@0: michael@0: PKIX_TEST_STD_VARS(); michael@0: michael@0: if (argc < 3){ michael@0: printUsage(); michael@0: return (0); michael@0: } michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR( michael@0: PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); michael@0: michael@0: chainLength = (argc - j) - 2; michael@0: michael@0: /* create processing params with list of trust anchors */ michael@0: trustedCertFile = argv[1+j]; michael@0: trustedCert = createCert(trustedCertFile); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_PL_Cert_GetSubject(trustedCert, &subject, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ComCertSelParams_Create(&certSelParams, plContext)); michael@0: michael@0: #if 0 michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubject michael@0: (certSelParams, subject, plContext)); michael@0: #endif michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_CertSelector_Create michael@0: (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_DECREF_BC(subject); michael@0: PKIX_TEST_DECREF_BC(certSelParams); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert michael@0: (trustedCert, &anchor, plContext)); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext)); michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (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: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ProcessingParams_SetTargetCertConstraints michael@0: (procParams, certSelector, plContext)); michael@0: michael@0: PKIX_TEST_DECREF_BC(certSelector); michael@0: michael@0: /* create cert chain */ michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certs, plContext)); michael@0: for (i = 0; i < chainLength; i++){ michael@0: chainCertFile = argv[(i + j) + 2]; michael@0: chainCert = createCert(chainCertFile); michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem michael@0: (certs, michael@0: (PKIX_PL_Object *)chainCert, michael@0: plContext)); michael@0: michael@0: PKIX_TEST_DECREF_BC(chainCert); michael@0: chainCert = NULL; michael@0: } michael@0: /* create validate params with processing params and cert chain */ michael@0: PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_Create michael@0: (procParams, certs, &valParams, plContext)); michael@0: michael@0: PKIX_TEST_DECREF_BC(trustedCert); trustedCert = NULL; michael@0: PKIX_TEST_DECREF_BC(anchor); anchor = NULL; michael@0: PKIX_TEST_DECREF_BC(anchors); anchors = NULL; michael@0: PKIX_TEST_DECREF_BC(certs); certs = NULL; michael@0: PKIX_TEST_DECREF_BC(procParams); procParams = NULL; michael@0: michael@0: /* validate cert chain using processing params and return valResult */ michael@0: michael@0: PKIX_TEST_EXPECT_NO_ERROR michael@0: (PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext)); michael@0: michael@0: if (valResult != NULL){ michael@0: (void) printf("SUCCESSFULLY VALIDATED\n"); michael@0: } michael@0: michael@0: cleanup: michael@0: michael@0: if (PKIX_TEST_ERROR_RECEIVED){ michael@0: (void) printf("FAILED TO VALIDATE\n"); michael@0: (void) PKIX_PL_Object_ToString michael@0: ((PKIX_PL_Object*)verifyTree, &verifyString, plContext); michael@0: (void) printf("verifyTree is\n%s\n", verifyString->escAsciiString); michael@0: PKIX_TEST_DECREF_AC(verifyString); michael@0: michael@0: } michael@0: michael@0: PKIX_TEST_DECREF_AC(verifyTree); michael@0: PKIX_TEST_DECREF_AC(valResult); michael@0: PKIX_TEST_DECREF_AC(valParams); michael@0: michael@0: PKIX_TEST_RETURN(); michael@0: michael@0: PKIX_Shutdown(plContext); michael@0: michael@0: return (0); michael@0: michael@0: }