int crypto_init(cert_policy *policy) { SECStatus rv; DBG("Initializing NSS ..."); if (NSS_IsInitialized()) { app_has_NSS = 1; /* we should save the app's password function */ PK11_SetPasswordFunc(password_passthrough); DBG("... NSS is initialized"); return 0; } if (policy->nss_dir) { /* initialize with read only databases */ DBG1("Initializing NSS ... database=%s", policy->nss_dir); rv = NSS_Init(policy->nss_dir); } else { /* not database secified */ DBG("Initializing NSS ... with no db"); rv = NSS_NoDB_Init(NULL); } if (rv != SECSuccess) { DBG1("NSS_Initialize failed: %s", SECU_Strerror(PR_GetError())); return -1; } /* register a callback */ PK11_SetPasswordFunc(password_passthrough); if (policy->ocsp_policy == OCSP_ON) { CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); } DBG("... NSS Complete"); return 0; }
void SetClassicOCSPBehavior(CertVerifier::ocsp_download_config enabled, CertVerifier::ocsp_strict_config strict, CertVerifier::ocsp_get_config get) { CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); if (enabled == CertVerifier::ocsp_off) { CERT_DisableOCSPChecking(CERT_GetDefaultCertDB()); } else { CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); } SEC_OcspFailureMode failureMode = strict == CertVerifier::ocsp_strict ? ocspMode_FailureIsVerificationFailure : ocspMode_FailureIsNotAVerificationFailure; (void) CERT_SetOCSPFailureMode(failureMode); CERT_ForcePostMethodForOCSP(get != CertVerifier::ocsp_get_enabled); int OCSPTimeoutSeconds = 3; if (strict == CertVerifier::ocsp_strict) { OCSPTimeoutSeconds = 10; } CERT_SetOCSPTimeout(OCSPTimeoutSeconds); }
static void ssl_nss_init_nss(void) { #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) SSLVersionRange supported, enabled; #endif /* NSS >= 3.14 */ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); NSS_NoDB_Init("."); NSS_SetDomesticPolicy(); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_RSA_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_DES_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_DES_CBC_SHA, 1); #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) /* Get the ranges of supported and enabled SSL versions */ if ((SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) == SECSuccess) && (SSL_VersionRangeGetDefault(ssl_variant_stream, &enabled) == SECSuccess)) { purple_debug_info("nss", "TLS supported versions: " "0x%04hx through 0x%04hx\n", supported.min, supported.max); purple_debug_info("nss", "TLS versions allowed by default: " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); /* Make sure SSL 3.0 is disabled (it's old and everyone should be using at least TLS 1.0 by now), and make sure all versions of TLS supported by the local library are enabled (for some reason NSS doesn't enable newer versions of TLS by default -- more context in ticket #15909). */ if (enabled.min != SSL_LIBRARY_VERSION_TLS_1_0 || supported.max > enabled.max) { enabled.max = supported.max; if (SSL_VersionRangeSetDefault(ssl_variant_stream, &enabled) == SECSuccess) { purple_debug_info("nss", "Changed allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } else { purple_debug_error("nss", "Error setting allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } } } #endif /* NSS >= 3.14 */ /** Disable OCSP Checking until we can make that use our HTTP & Proxy stuff */ CERT_EnableOCSPChecking(PR_FALSE); _identity = PR_GetUniqueIdentity("Purple"); _nss_methods = PR_GetDefaultIOMethods(); }
int main (int argc, char **argv) { int retval; PRFileDesc *in_file; FILE *out_file; /* not PRFileDesc until SECU accepts it */ int crequest, dresponse; int prequest, presponse; int ccert, vcert; const char *db_dir, *date_str, *cert_usage_str, *name; const char *responder_name, *responder_url, *signer_name; PRBool add_acceptable_responses, add_service_locator; SECItem *data = NULL; PLOptState *optstate; SECStatus rv; CERTCertDBHandle *handle = NULL; SECCertUsage cert_usage; PRTime verify_time; CERTCertificate *cert = NULL; PRBool ascii = PR_FALSE; retval = -1; /* what we return/exit with on error */ program_name = PL_strrchr(argv[0], '/'); program_name = program_name ? (program_name + 1) : argv[0]; in_file = PR_STDIN; out_file = stdout; crequest = 0; dresponse = 0; prequest = 0; presponse = 0; ccert = 0; vcert = 0; db_dir = NULL; date_str = NULL; cert_usage_str = NULL; name = NULL; responder_name = NULL; responder_url = NULL; signer_name = NULL; add_acceptable_responses = PR_FALSE; add_service_locator = PR_FALSE; optstate = PL_CreateOptState (argc, argv, "AHLPR:S:V:d:l:pr:s:t:u:w:"); if (optstate == NULL) { SECU_PrintError (program_name, "PL_CreateOptState failed"); return retval; } while (PL_GetNextOpt (optstate) == PL_OPT_OK) { switch (optstate->option) { case '?': short_usage (program_name); return retval; case 'A': add_acceptable_responses = PR_TRUE; break; case 'H': long_usage (program_name); return retval; case 'L': add_service_locator = PR_TRUE; break; case 'P': presponse = 1; break; case 'R': dresponse = 1; name = optstate->value; break; case 'S': ccert = 1; name = optstate->value; break; case 'V': vcert = 1; name = optstate->value; break; case 'a': ascii = PR_TRUE; break; case 'd': db_dir = optstate->value; break; case 'l': responder_url = optstate->value; break; case 'p': prequest = 1; break; case 'r': crequest = 1; name = optstate->value; break; case 's': signer_name = optstate->value; break; case 't': responder_name = optstate->value; break; case 'u': cert_usage_str = optstate->value; break; case 'w': date_str = optstate->value; break; } } PL_DestroyOptState(optstate); if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) { PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n", program_name); short_usage (program_name); return retval; } if (vcert) { if (cert_usage_str == NULL) { PR_fprintf (PR_STDERR, "%s: verification requires cert usage\n\n", program_name); short_usage (program_name); return retval; } rv = cert_usage_from_char (cert_usage_str, &cert_usage); if (rv != SECSuccess) { PR_fprintf (PR_STDERR, "%s: invalid cert usage (\"%s\")\n\n", program_name, cert_usage_str); long_usage (program_name); return retval; } } if (ccert + vcert) { if (responder_url != NULL || responder_name != NULL) { /* * To do a full status check, both the URL and the cert name * of the responder must be specified if either one is. */ if (responder_url == NULL || responder_name == NULL) { if (responder_url == NULL) PR_fprintf (PR_STDERR, "%s: must also specify responder location\n\n", program_name); else PR_fprintf (PR_STDERR, "%s: must also specify responder name\n\n", program_name); short_usage (program_name); return retval; } } if (date_str != NULL) { rv = DER_AsciiToTime (&verify_time, (char *) date_str); if (rv != SECSuccess) { SECU_PrintError (program_name, "error converting time string"); PR_fprintf (PR_STDERR, "\n"); long_usage (program_name); return retval; } } else { verify_time = PR_Now(); } } retval = -2; /* errors change from usage to runtime */ /* * Initialize the NSPR and Security libraries. */ PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); db_dir = SECU_ConfigDirectory (db_dir); rv = NSS_Init (db_dir); if (rv != SECSuccess) { SECU_PrintError (program_name, "NSS_Init failed"); goto prdone; } SECU_RegisterDynamicOids(); if (prequest + presponse) { MAKE_FILE_BINARY(stdin); data = read_file_into_item (in_file, siBuffer); if (data == NULL) { SECU_PrintError (program_name, "problem reading input"); goto nssdone; } } if (crequest + dresponse + presponse + ccert + vcert) { handle = CERT_GetDefaultCertDB(); if (handle == NULL) { SECU_PrintError (program_name, "problem getting certdb handle"); goto nssdone; } /* * It would be fine to do the enable for all of these commands, * but this way we check that everything but an overall verify * can be done without it. That is, that the individual pieces * work on their own. */ if (vcert) { rv = CERT_EnableOCSPChecking (handle); if (rv != SECSuccess) { SECU_PrintError (program_name, "error enabling OCSP checking"); goto nssdone; } } if ((ccert + vcert) && (responder_name != NULL)) { rv = CERT_SetOCSPDefaultResponder (handle, responder_url, responder_name); if (rv != SECSuccess) { SECU_PrintError (program_name, "error setting default responder"); goto nssdone; } rv = CERT_EnableOCSPDefaultResponder (handle); if (rv != SECSuccess) { SECU_PrintError (program_name, "error enabling default responder"); goto nssdone; } } } #define NOTYET(opt) \ { \ PR_fprintf (PR_STDERR, "%s not yet working\n", opt); \ exit (-1); \ } if (name) { cert = find_certificate(handle, name, ascii); } if (crequest) { if (signer_name != NULL) { NOTYET("-s"); } rv = create_request (out_file, handle, cert, add_service_locator, add_acceptable_responses); } else if (dresponse) { if (signer_name != NULL) { NOTYET("-s"); } rv = dump_response (out_file, handle, cert, responder_url); } else if (prequest) { rv = print_request (out_file, data); } else if (presponse) { rv = print_response (out_file, data, handle); } else if (ccert) { if (signer_name != NULL) { NOTYET("-s"); } rv = get_cert_status (out_file, handle, cert, name, verify_time); } else if (vcert) { if (signer_name != NULL) { NOTYET("-s"); } rv = verify_cert (out_file, handle, cert, name, cert_usage, verify_time); } if (rv != SECSuccess) SECU_PrintError (program_name, "error performing requested operation"); else retval = 0; nssdone: if (cert) { CERT_DestroyCertificate(cert); } if (data != NULL) { SECITEM_FreeItem (data, PR_TRUE); } if (handle != NULL) { CERT_DisableOCSPDefaultResponder(handle); CERT_DisableOCSPChecking (handle); } if (NSS_Shutdown () != SECSuccess) { retval = 1; } prdone: PR_Cleanup (); return retval; }
/********************************************************************* * * m a i n */ int main(int argc, char *argv[]) { PRBool readOnly; int retval = 0; outputFD = PR_STDOUT; errorFD = PR_STDERR; progName = argv[0]; if (argc < 2) { Usage(); } excludeDirs = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); extensions = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); if (parse_args(argc, argv)) { retval = -1; goto cleanup; } /* Parse the command file if one was given */ if (cmdFile) { if (ProcessCommandFile()) { retval = -1; goto cleanup; } } /* Set up output redirection */ if (outfile) { if (PR_Access(outfile, PR_ACCESS_EXISTS) == PR_SUCCESS) { /* delete the file if it is already present */ PR_fprintf(errorFD, "warning: %s already exists and will be overwritten.\n", outfile); warningCount++; if (PR_Delete(outfile) != PR_SUCCESS) { PR_fprintf(errorFD, "ERROR: unable to delete %s.\n", outfile); errorCount++; exit(ERRX); } } outputFD = PR_Open(outfile, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777); if (!outputFD) { PR_fprintf(errorFD, "ERROR: Unable to create %s.\n", outfile); errorCount++; exit(ERRX); } errorFD = outputFD; } /* This seems to be a fairly common user error */ if (verify && list_certs > 0) { PR_fprintf(errorFD, "%s: Can't use -l and -v at the same time\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -J assumes -Z now */ if (javascript && zipfile) { PR_fprintf(errorFD, "%s: Can't use -J and -Z at the same time\n", PROGRAM_NAME); PR_fprintf(errorFD, "%s: -J option will create the jar files for you\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -X needs -Z */ if (xpi_arc && !zipfile) { PR_fprintf(errorFD, "%s: option XPI (-X) requires option jarfile (-Z)\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* Less common mixing of -L with various options */ if (list_certs > 0 && (tell_who || zipfile || javascript || scriptdir || extensionsGiven || exclusionsGiven || install_script)) { PR_fprintf(errorFD, "%s: Can't use -l or -L with that option\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } if (!cert_dir) cert_dir = get_default_cert_dir(); VerifyCertDir(cert_dir, keyName); if (compression_level < MIN_COMPRESSION_LEVEL || compression_level > MAX_COMPRESSION_LEVEL) { PR_fprintf(errorFD, "Compression level must be between %d and %d.\n", MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL); errorCount++; retval = -1; goto cleanup; } if (jartree && !keyName) { PR_fprintf(errorFD, "You must specify a key with which to sign.\n"); errorCount++; retval = -1; goto cleanup; } readOnly = (genkey == NULL); /* only key generation requires write */ if (InitCrypto(cert_dir, readOnly)) { PR_fprintf(errorFD, "ERROR: Cryptographic initialization failed.\n"); errorCount++; retval = -1; goto cleanup; } if (enableOCSP) { SECStatus rv = CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); if (rv != SECSuccess) { PR_fprintf(errorFD, "ERROR: Attempt to enable OCSP Checking failed.\n"); errorCount++; retval = -1; } } if (verify) { if (VerifyJar(verify)) { errorCount++; retval = -1; goto cleanup; } } else if (list_certs) { if (ListCerts(keyName, list_certs)) { errorCount++; retval = -1; goto cleanup; } } else if (list_modules) { JarListModules(); } else if (genkey) { if (GenerateCert(genkey, keySize, token)) { errorCount++; retval = -1; goto cleanup; } } else if (tell_who) { if (JarWho(tell_who)) { errorCount++; retval = -1; goto cleanup; } } else if (javascript && jartree) { /* make sure directory exists */ PRDir *dir; dir = PR_OpenDir(jartree); if (!dir) { PR_fprintf(errorFD, "ERROR: unable to open directory %s.\n", jartree); errorCount++; retval = -1; goto cleanup; } else { PR_CloseDir(dir); } /* undo junk from prior runs of signtool*/ if (RemoveAllArc(jartree)) { PR_fprintf(errorFD, "Error removing archive directories under %s\n", jartree); errorCount++; retval = -1; goto cleanup; } /* traverse all the htm|html files in the directory */ if (InlineJavaScript(jartree, !noRecurse)) { retval = -1; goto cleanup; } /* sign any resultant .arc directories created in above step */ if (SignAllArc(jartree, keyName, javascript, metafile, install_script, optimize, !noRecurse)) { retval = -1; goto cleanup; } if (!leaveArc) { RemoveAllArc(jartree); } if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); } } else if (jartree) { SignArchive(jartree, keyName, zipfile, javascript, metafile, install_script, optimize, !noRecurse); } else Usage(); cleanup: if (extensions) { PL_HashTableDestroy(extensions); extensions = NULL; } if (excludeDirs) { PL_HashTableDestroy(excludeDirs); excludeDirs = NULL; } if (outputFD != PR_STDOUT) { PR_Close(outputFD); } rm_dash_r(TMP_OUTPUT); if (retval == 0) { if (NSS_Shutdown() != SECSuccess) { exit(1); } } return retval; }
int main(int argc, char *argv[], char *envp[]) { char * certDir = NULL; char * progName = NULL; char * oidStr = NULL; CERTCertificate * cert; CERTCertificate * firstCert = NULL; CERTCertificate * issuerCert = NULL; CERTCertDBHandle * defaultDB = NULL; PRBool isAscii = PR_FALSE; PRBool trusted = PR_FALSE; SECStatus secStatus; SECCertificateUsage certUsage = certificateUsageSSLServer; PLOptState * optstate; PRTime time = 0; PLOptStatus status; int usePkix = 0; int rv = 1; int usage; CERTVerifyLog log; CERTCertList *builtChain = NULL; PRBool certFetching = PR_FALSE; int revDataIndex = 0; PRBool ocsp_fetchingFailureIsAFailure = PR_TRUE; PRBool useDefaultRevFlags = PR_TRUE; int vfyCounts = 1; PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); progName = PL_strdup(argv[0]); optstate = PL_CreateOptState(argc, argv, "ab:c:d:efg:h:i:m:o:prs:tu:vw:W:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch(optstate->option) { case 0 : /* positional parameter */ goto breakout; case 'a' : isAscii = PR_TRUE; break; case 'b' : secStatus = DER_AsciiToTime(&time, optstate->value); if (secStatus != SECSuccess) Usage(progName); break; case 'd' : certDir = PL_strdup(optstate->value); break; case 'e' : ocsp_fetchingFailureIsAFailure = PR_FALSE; break; case 'f' : certFetching = PR_TRUE; break; case 'g' : if (revMethodsData[revDataIndex].testTypeStr || revMethodsData[revDataIndex].methodTypeStr) { revDataIndex += 1; if (revDataIndex == REV_METHOD_INDEX_MAX) { fprintf(stderr, "Invalid revocation configuration" "specified.\n"); secStatus = SECFailure; break; } } useDefaultRevFlags = PR_FALSE; revMethodsData[revDataIndex]. testTypeStr = PL_strdup(optstate->value); break; case 'h' : revMethodsData[revDataIndex]. testFlagsStr = PL_strdup(optstate->value);break; case 'i' : vfyCounts = PORT_Atoi(optstate->value); break; break; case 'm' : if (revMethodsData[revDataIndex].methodTypeStr) { revDataIndex += 1; if (revDataIndex == REV_METHOD_INDEX_MAX) { fprintf(stderr, "Invalid revocation configuration" "specified.\n"); secStatus = SECFailure; break; } } useDefaultRevFlags = PR_FALSE; revMethodsData[revDataIndex]. methodTypeStr = PL_strdup(optstate->value); break; case 'o' : oidStr = PL_strdup(optstate->value); break; case 'p' : usePkix += 1; break; case 'r' : isAscii = PR_FALSE; break; case 's' : revMethodsData[revDataIndex]. methodFlagsStr = PL_strdup(optstate->value); break; case 't' : trusted = PR_TRUE; break; case 'u' : usage = PORT_Atoi(optstate->value); if (usage < 0 || usage > 62) Usage(progName); certUsage = ((SECCertificateUsage)1) << usage; if (certUsage > certificateUsageHighest) Usage(progName); break; case 'w': pwdata.source = PW_PLAINTEXT; pwdata.data = PORT_Strdup(optstate->value); break; case 'W': pwdata.source = PW_FROMFILE; pwdata.data = PORT_Strdup(optstate->value); break; case 'v' : verbose++; break; default : Usage(progName); break; } } breakout: if (status != PL_OPT_OK) Usage(progName); if (usePkix < 2) { if (oidStr) { fprintf(stderr, "Policy oid(-o) can be used only with" " CERT_PKIXVerifyChain(-pp) function.\n"); Usage(progName); } if (trusted) { fprintf(stderr, "Cert trust flag can be used only with" " CERT_PKIXVerifyChain(-pp) function.\n"); Usage(progName); } } if (!useDefaultRevFlags && parseRevMethodsAndFlags()) { fprintf(stderr, "Invalid revocation configuration specified.\n"); goto punt; } /* Set our password function callback. */ PK11_SetPasswordFunc(SECU_GetModulePassword); /* Initialize the NSS libraries. */ if (certDir) { secStatus = NSS_Init(certDir); } else { secStatus = NSS_NoDB_Init(NULL); /* load the builtins */ SECMOD_AddNewModule("Builtins", DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0); } if (secStatus != SECSuccess) { exitErr("NSS_Init"); } SECU_RegisterDynamicOids(); if (isOCSPEnabled()) { CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); if (!ocsp_fetchingFailureIsAFailure) { CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure); } } while (status == PL_OPT_OK) { switch(optstate->option) { default : Usage(progName); break; case 'a' : isAscii = PR_TRUE; break; case 'r' : isAscii = PR_FALSE; break; case 't' : trusted = PR_TRUE; break; case 0 : /* positional parameter */ if (usePkix < 2 && trusted) { fprintf(stderr, "Cert trust flag can be used only with" " CERT_PKIXVerifyChain(-pp) function.\n"); Usage(progName); } cert = getCert(optstate->value, isAscii, progName); if (!cert) goto punt; rememberCert(cert, trusted); if (!firstCert) firstCert = cert; trusted = PR_FALSE; } status = PL_GetNextOpt(optstate); } PL_DestroyOptState(optstate); if (status == PL_OPT_BAD || !firstCert) Usage(progName); /* Initialize log structure */ log.arena = PORT_NewArena(512); log.head = log.tail = NULL; log.count = 0; do { if (usePkix < 2) { /* NOW, verify the cert chain. */ if (usePkix) { /* Use old API with libpkix validation lib */ CERT_SetUsePKIXForValidation(PR_TRUE); } if (!time) time = PR_Now(); defaultDB = CERT_GetDefaultCertDB(); secStatus = CERT_VerifyCertificate(defaultDB, firstCert, PR_TRUE /* check sig */, certUsage, time, &pwdata, /* wincx */ &log, /* error log */ NULL);/* returned usages */ } else do { static CERTValOutParam cvout[4]; static CERTValInParam cvin[6]; SECOidTag oidTag; int inParamIndex = 0; static PRUint64 revFlagsLeaf[2]; static PRUint64 revFlagsChain[2]; static CERTRevocationFlags rev; if (oidStr) { PRArenaPool *arena; SECOidData od; memset(&od, 0, sizeof od); od.offset = SEC_OID_UNKNOWN; od.desc = "User Defined Policy OID"; od.mechanism = CKM_INVALID_MECHANISM; od.supportedExtension = INVALID_CERT_EXTENSION; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( !arena ) { fprintf(stderr, "out of memory"); goto punt; } secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0); if (secStatus != SECSuccess) { PORT_FreeArena(arena, PR_FALSE); fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr, SECU_Strerror(PORT_GetError())); break; } oidTag = SECOID_AddEntry(&od); PORT_FreeArena(arena, PR_FALSE); if (oidTag == SEC_OID_UNKNOWN) { fprintf(stderr, "Can not add new oid to the dynamic " "table: %s\n", oidStr); secStatus = SECFailure; break; } cvin[inParamIndex].type = cert_pi_policyOID; cvin[inParamIndex].value.arraySize = 1; cvin[inParamIndex].value.array.oids = &oidTag; inParamIndex++; } if (trustedCertList) { cvin[inParamIndex].type = cert_pi_trustAnchors; cvin[inParamIndex].value.pointer.chain = trustedCertList; inParamIndex++; } cvin[inParamIndex].type = cert_pi_useAIACertFetch; cvin[inParamIndex].value.scalar.b = certFetching; inParamIndex++; rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf; rev.chainTests.cert_rev_flags_per_method = revFlagsChain; secStatus = configureRevocationParams(&rev); if (secStatus) { fprintf(stderr, "Can not config revocation parameters "); break; } cvin[inParamIndex].type = cert_pi_revocationFlags; cvin[inParamIndex].value.pointer.revocation = &rev; inParamIndex++; if (time) { cvin[inParamIndex].type = cert_pi_date; cvin[inParamIndex].value.scalar.time = time; inParamIndex++; } cvin[inParamIndex].type = cert_pi_end; cvout[0].type = cert_po_trustAnchor; cvout[0].value.pointer.cert = NULL; cvout[1].type = cert_po_certList; cvout[1].value.pointer.chain = NULL; /* setting pointer to CERTVerifyLog. Initialized structure * will be used CERT_PKIXVerifyCert */ cvout[2].type = cert_po_errorLog; cvout[2].value.pointer.log = &log; cvout[3].type = cert_po_end; secStatus = CERT_PKIXVerifyCert(firstCert, certUsage, cvin, cvout, &pwdata); if (secStatus != SECSuccess) { break; } issuerCert = cvout[0].value.pointer.cert; builtChain = cvout[1].value.pointer.chain; } while (0); /* Display validation results */ if (secStatus != SECSuccess || log.count > 0) { CERTVerifyLogNode *node = NULL; PRIntn err = PR_GetError(); fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err)); SECU_displayVerifyLog(stderr, &log, verbose); /* Have cert refs in the log only in case of failure. * Destroy them. */ for (node = log.head; node; node = node->next) { if (node->cert) CERT_DestroyCertificate(node->cert); } rv = 1; } else { fprintf(stderr, "Chain is good!\n"); if (issuerCert) { if (verbose > 1) { rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate", NULL); if (rv != SECSuccess) { SECU_PrintError(progName, "problem printing certificate"); } } else if (verbose > 0) { SECU_PrintName(stdout, &issuerCert->subject, "Root " "Certificate Subject:", 0); } CERT_DestroyCertificate(issuerCert); } if (builtChain) { CERTCertListNode *node; int count = 0; char buff[256]; if (verbose) { for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain); node = CERT_LIST_NEXT(node), count++ ) { sprintf(buff, "Certificate %d Subject", count + 1); SECU_PrintName(stdout, &node->cert->subject, buff, 0); } } CERT_DestroyCertList(builtChain); } rv = 0; } } while (--vfyCounts > 0); /* Need to destroy CERTVerifyLog arena at the end */ PORT_FreeArena(log.arena, PR_FALSE); punt: forgetCerts(); if (NSS_Shutdown() != SECSuccess) { SECU_PrintError(progName, "NSS_Shutdown"); rv = 1; } PORT_Free(progName); PORT_Free(certDir); PORT_Free(oidStr); freeRevocationMethodData(); if (pwdata.data) { PORT_Free(pwdata.data); } PR_Cleanup(); return rv; }
int main(int argc, char **argv) { char * certDir = NULL; char * progName = NULL; int connections = 1; char * cipherString = NULL; char * respUrl = NULL; char * respCertName = NULL; SECStatus secStatus; PLOptState * optstate; PLOptStatus status; PRBool doOcspCheck = PR_FALSE; /* Call the NSPR initialization routines */ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); progName = PORT_Strdup(argv[0]); hostName = NULL; optstate = PL_CreateOptState(argc, argv, "C:cd:f:l:n:p:ot:w:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch(optstate->option) { case 'C' : cipherString = PL_strdup(optstate->value); break; case 'c' : dumpChain = PR_TRUE; break; case 'd' : certDir = PL_strdup(optstate->value); break; case 'l' : respUrl = PL_strdup(optstate->value); break; case 'p' : port = PORT_Atoi(optstate->value); break; case 'o' : doOcspCheck = PR_TRUE; break; case 't' : respCertName = PL_strdup(optstate->value); break; case 'w': pwdata.source = PW_PLAINTEXT; pwdata.data = PORT_Strdup(optstate->value); break; case 'f': pwdata.source = PW_FROMFILE; pwdata.data = PORT_Strdup(optstate->value); break; case '\0': hostName = PL_strdup(optstate->value); break; default : Usage(progName); } } if (port == 0) { port = 443; } if (port == 0 || hostName == NULL) Usage(progName); if (doOcspCheck && ((respCertName != NULL && respUrl == NULL) || (respUrl != NULL && respCertName == NULL))) { SECU_PrintError (progName, "options -l <url> and -t " "<responder> must be used together"); Usage(progName); } PK11_SetPasswordFunc(SECU_GetModulePassword); /* Initialize the NSS libraries. */ if (certDir) { secStatus = NSS_Init(certDir); } else { secStatus = NSS_NoDB_Init(NULL); /* load the builtins */ SECMOD_AddNewModule("Builtins", DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0); } if (secStatus != SECSuccess) { exitErr("NSS_Init"); } SECU_RegisterDynamicOids(); if (doOcspCheck == PR_TRUE) { SECStatus rv; CERTCertDBHandle *handle = CERT_GetDefaultCertDB(); if (handle == NULL) { SECU_PrintError (progName, "problem getting certdb handle"); goto cleanup; } rv = CERT_EnableOCSPChecking (handle); if (rv != SECSuccess) { SECU_PrintError (progName, "error enabling OCSP checking"); goto cleanup; } if (respUrl != NULL) { rv = CERT_SetOCSPDefaultResponder (handle, respUrl, respCertName); if (rv != SECSuccess) { SECU_PrintError (progName, "error setting default responder"); goto cleanup; } rv = CERT_EnableOCSPDefaultResponder (handle); if (rv != SECSuccess) { SECU_PrintError (progName, "error enabling default responder"); goto cleanup; } } } /* All cipher suites except RSA_NULL_MD5 are enabled by * Domestic Policy. */ NSS_SetDomesticPolicy(); SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE); /* all the SSL2 and SSL3 cipher suites are enabled by default. */ if (cipherString) { int ndx; /* disable all the ciphers, then enable the ones we want. */ disableAllSSLCiphers(); while (0 != (ndx = *cipherString++)) { int cipher; if (ndx == ':') { int ctmp; cipher = 0; HEXCHAR_TO_INT(*cipherString, ctmp) cipher |= (ctmp << 12); cipherString++; HEXCHAR_TO_INT(*cipherString, ctmp) cipher |= (ctmp << 8); cipherString++; HEXCHAR_TO_INT(*cipherString, ctmp) cipher |= (ctmp << 4); cipherString++; HEXCHAR_TO_INT(*cipherString, ctmp) cipher |= ctmp; cipherString++; } else { const int *cptr; if (! isalpha(ndx)) Usage(progName); cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites; for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) /* do nothing */; } if (cipher > 0) { SSL_CipherPrefSetDefault(cipher, PR_TRUE); } else { Usage(progName); } } } client_main(port, connections, hostName); cleanup: if (doOcspCheck) { CERTCertDBHandle *handle = CERT_GetDefaultCertDB(); CERT_DisableOCSPDefaultResponder(handle); CERT_DisableOCSPChecking (handle); } if (NSS_Shutdown() != SECSuccess) { exit(1); } PR_Cleanup(); PORT_Free(progName); return 0; }
int main(int argc, char *argv[]) { int opt; long fin = 0; int use_pkix = 0; SECStatus rv; char pbuf[1024]; PRBool crlcheck = PR_FALSE; PRBool ocspcheck = PR_FALSE; PRBool strict = PR_FALSE; CERTCertDBHandle *handle = NULL; CERTCertificate **certout = NULL; CERTVerifyLog vfy_log; CERTVerifyLog vfy_log2; CERTVerifyLog *cur_log; CERTValOutParam *pkixout = NULL; SECItem c1; SECItem c2; SECItem *certs[2]; certs[0] = &c1; certs[1] = &c2; int numcerts = 0; while ((opt = getopt(argc, argv, "u:d:e:pn:s:coSr")) != -1) { switch(opt) { /* usage type */ case 'u': set_usage(optarg); break; case 'd': db_dir = optarg; break; case 's': sub_file = optarg; break; case 'c': crlcheck = PR_TRUE; break; case 'o': ocspcheck = PR_TRUE; break; case 'S': strict = PR_TRUE; break; case 'e': end_file = optarg; break; case 'p': use_pkix = 1; break; case 'n': rightca_nick = optarg; break; case 'r': retry_verify = PR_TRUE; break; default: print_usage(); break; } } if (db_dir == NULL) db_dir = "testfiles/"; if (end_file == NULL) end_file = "testfiles/end.pem"; get_file(certs[numcerts++], end_file); if (sub_file != NULL) { get_file(certs[numcerts++], sub_file); } snprintf(pbuf, sizeof(pbuf), "sql:%s", db_dir); if (NSS_Initialize(pbuf, "", "", "secmod.db", 0x1) != SECSuccess) { printf("NSS_Initialize failed %d\n", PORT_GetError()); exit(-1); } if ((handle = CERT_GetDefaultCertDB()) == NULL) { printf("NULL handle\n"); exit(-1); } if (ocspcheck) { CERT_EnableOCSPChecking(handle); CERT_DisableOCSPDefaultResponder(handle); if (strict) CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure); } rv = CERT_ImportCerts(handle, 0, numcerts, certs, &certout, PR_FALSE, PR_FALSE, NULL); if (rv != SECSuccess) { printf("CERT_ImportCerts failed %d\n", PORT_GetError()); exit(-1); } vfy_log.count = 0; vfy_log.head = NULL; vfy_log.tail = NULL; vfy_log.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); vfy_log2.count = 0; vfy_log2.head = NULL; vfy_log2.tail = NULL; vfy_log2.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (use_pkix) { int in_idx = 0; CERTValInParam cvin[7]; CERTValOutParam cvout[3]; CERTCertList *trustcl = NULL; CERTRevocationFlags rev; PRUint64 revFlagsLeaf[2] = { 0, 0 }; PRUint64 revFlagsChain[2] = { 0, 0 }; zero(&cvin); /* ??? is this reasonable? */ zero(&cvout); /* ??? is this reasonable? */ zero(&rev); /* ??? is this reasonable? */ if (rightca_nick == NULL) rightca_nick = "root"; if ((trustcl = get_trust_certlist(handle, rightca_nick)) == NULL) { printf("Couldn't find trust anchor\n"); exit(-1); } cvin[in_idx].type = cert_pi_useAIACertFetch; cvin[in_idx++].value.scalar.b = PR_TRUE; cvin[in_idx].type = cert_pi_revocationFlags; cvin[in_idx++].value.pointer.revocation = &rev; cvin[in_idx].type = cert_pi_trustAnchors; cvin[in_idx++].value.pointer.chain = trustcl; cvin[in_idx].type = cert_pi_useOnlyTrustAnchors; cvin[in_idx++].value.scalar.b = PR_TRUE; set_rev_per_meth(&rev, revFlagsLeaf, revFlagsChain); set_rev_params(&rev, crlcheck, ocspcheck, strict); cvin[in_idx].type = cert_pi_end; cvout[0].type = cert_po_errorLog; cvout[0].value.pointer.log = &vfy_log; cur_log = &vfy_log; cvout[1].type = cert_po_certList; cvout[1].value.pointer.chain = NULL; cvout[2].type = cert_po_end; pkixout = &cvout[0]; pkixredo: rv = CERT_PKIXVerifyCert(*certout, pkixusage, cvin, cvout, NULL); //CERT_DestroyCertList(trustcl); } else { cur_log = &vfy_log; vfyredo: rv = CERT_VerifyCert(handle, *certout, PR_TRUE, usage, PR_Now(), NULL, cur_log); } if (rv != SECSuccess || cur_log->count > 0) { if (cur_log->count > 0 && cur_log->head != NULL) { fin = err_stat(cur_log->head); } else { fin = PORT_GetError(); } if (fin == SEC_ERROR_INADEQUATE_KEY_USAGE) { printf("SEC_ERROR_INADEQUATE_KEY_USAGE : Certificate key usage inadequate for attempted operation.\n" ); } else if (fin == SEC_ERROR_INADEQUATE_CERT_TYPE) { printf("SEC_ERROR_INADEQUATE_CERT_TYPE : Certificate type not approved for application.\n" ); } else { printf("OTHER : %ld", fin); } } if ((fin == SEC_ERROR_INADEQUATE_CERT_TYPE || fin == SEC_ERROR_INADEQUATE_KEY_USAGE) && retry_verify && !retried) { printf("Retrying verification\n"); fin = 0; retried = PR_TRUE; if (use_pkix) { pkixout[0].value.pointer.log = &vfy_log2; cur_log = &vfy_log2; pkixout[1].value.pointer.chain = NULL; if (pkixusage == certificateUsageSSLClient) { pkixusage = certificateUsageSSLServer; } else { pkixusage = certificateUsageSSLClient; } goto pkixredo; } else { if (usage == certUsageSSLClient) { usage = certUsageSSLServer; } else { usage = certUsageSSLClient; } goto vfyredo; } } PORT_FreeArena(vfy_log.arena, PR_FALSE); PORT_FreeArena(vfy_log2.arena, PR_FALSE); NSS_Shutdown(); exit(fin == 0 ? 0 : 1); }