static int testMessageDigest(NSSLOWInitContext *initCtx, HASH_HashType algoType, unsigned int hashLen, const unsigned char *message, const PRUint8 expected[], PRUint8 results[]) { NSSLOWHASHContext *ctx; unsigned int len; int rv = 0; ctx = NSSLOWHASH_NewContext(initCtx, algoType); if (ctx == NULL) { SECU_PrintError(progName, "Couldn't get hash context\n"); return 1; } NSSLOWHASH_Begin(ctx); NSSLOWHASH_Update(ctx, message, PORT_Strlen((const char *)message)); NSSLOWHASH_End(ctx, results, &len, hashLen); PR_ASSERT(len == hashLen); PR_ASSERT(PORT_Memcmp(expected, results, len) == 0); if (PORT_Memcmp(expected, results, len) != 0) { SECU_PrintError(progName, "Hash mismatch\n"); SECU_PrintBuf(stdout, "Expected: ", expected, hashLen); SECU_PrintBuf(stdout, "Actual: ", results, len); rv = 1; } NSSLOWHASH_Destroy(ctx); NSSLOW_Shutdown(initCtx); return rv; }
/****************************************************************** * * G e n e r a t e K e y P a i r */ static SECStatus GenerateKeyPair(PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, int keysize) { PK11RSAGenParams rsaParams; if ( keysize == -1 ) { rsaParams.keySizeInBits = DEFAULT_RSA_KEY_SIZE; } else { rsaParams.keySizeInBits = keysize; } rsaParams.pe = 0x10001; if (PK11_Authenticate( slot, PR_FALSE /*loadCerts*/, &pwdata) != SECSuccess) { SECU_PrintError(progName, "failure authenticating to key database.\n"); exit(ERRX); } *privk = PK11_GenerateKeyPair (slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams, pubk, PR_TRUE /*isPerm*/, PR_TRUE /*isSensitive*/, &pwdata); if (*privk != NULL && *pubk != NULL) { if (verbosity >= 0) { PR_fprintf(outputFD, "generated public/private key pair\n"); } } else { SECU_PrintError(progName, "failure generating key pair\n"); exit (ERRX); } return SECSuccess; }
int ReadBuf(char *inFile, SECItem *item) { int len; int ret; PRFileDesc* fd = PR_Open(inFile, PR_RDONLY, 0); if (NULL == fd) { SECU_PrintError("symkeyutil", "PR_Open failed"); return -1; } len = GetLen(fd); if (len < 0) { SECU_PrintError("symkeyutil", "PR_GetOpenFileInfo failed"); return -1; } item->data = (unsigned char *)PORT_Alloc(len); if (item->data == NULL) { fprintf(stderr,"Failed to allocate %d to read file %s\n",len,inFile); return -1; } ret = PR_Read(fd,item->data,item->len); if (ret < 0) { SECU_PrintError("symkeyutil", "PR_Read failed"); PORT_Free(item->data); item->data = NULL; return -1; } PR_Close(fd); item->len = len; return 0; }
SECStatus outputPQGVerify(PQGVerify *pqgVerify, PRBool output_binary, PRBool output_raw, FILE *outFile) { SECStatus rv = SECSuccess; if (output_raw) { SECItem item; unsigned int counter; rv = PK11_PQG_GetHFromVerify(pqgVerify, &item); if (rv) { SECU_PrintError(progName, "PK11_PQG_GetHFromVerify"); return rv; } SECU_PrintInteger(outFile, &item, "h", 1); SECITEM_FreeItem(&item, PR_FALSE); rv = PK11_PQG_GetSeedFromVerify(pqgVerify, &item); if (rv) { SECU_PrintError(progName, "PK11_PQG_GetSeedFromVerify"); return rv; } SECU_PrintInteger(outFile, &item, "SEED", 1); fprintf(outFile, " g: %d\n", item.len * BPB); SECITEM_FreeItem(&item, PR_FALSE); counter = PK11_PQG_GetCounterFromVerify(pqgVerify); fprintf(outFile, " counter: %d\n", counter); fprintf(outFile, "\n"); } return rv; }
SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions) { CERTSignedCrl *crl = NULL; SECItem crlDER; PK11SlotInfo* slot = NULL; int rv; #if defined(DEBUG_jp96085) PRIntervalTime starttime, endtime, elapsed; PRUint32 mins, secs, msecs; #endif crlDER.data = NULL; /* Read in the entire file specified with the -f argument */ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE); if (rv != SECSuccess) { SECU_PrintError(progName, "unable to read input file"); return (SECFailure); } decodeOptions |= CRL_DECODE_DONT_COPY_DER; slot = PK11_GetInternalKeySlot(); #if defined(DEBUG_jp96085) starttime = PR_IntervalNow(); #endif crl = PK11_ImportCRL(slot, &crlDER, url, type, NULL, importOptions, NULL, decodeOptions); #if defined(DEBUG_jp96085) endtime = PR_IntervalNow(); elapsed = endtime - starttime; mins = PR_IntervalToSeconds(elapsed) / 60; secs = PR_IntervalToSeconds(elapsed) % 60; msecs = PR_IntervalToMilliseconds(elapsed) % 1000; printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs); #endif if (!crl) { const char *errString; rv = SECFailure; errString = SECU_Strerror(PORT_GetError()); if ( errString && PORT_Strlen (errString) == 0) SECU_PrintError (progName, "CRL is not imported (error: input CRL is not up to date.)"); else SECU_PrintError (progName, "unable to import CRL"); } else { SEC_DestroyCrl (crl); } if (slot) { PK11_FreeSlot(slot); } return (rv); }
static CERTSignedCrl * FindCRL(CERTCertDBHandle *certHandle, char *name, int type) { CERTSignedCrl *crl = NULL; CERTCertificate *cert = NULL; SECItem derName; derName.data = NULL; derName.len = 0; cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, name); if (!cert) { CERTName *certName = NULL; PLArenaPool *arena = NULL; SECStatus rv = SECSuccess; certName = CERT_AsciiToName(name); if (certName) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena) { SECItem *nameItem = SEC_ASN1EncodeItem(arena, NULL, (void *)certName, SEC_ASN1_GET(CERT_NameTemplate)); if (nameItem) { rv = SECITEM_CopyItem(NULL, &derName, nameItem); } PORT_FreeArena(arena, PR_FALSE); } CERT_DestroyName(certName); } if (rv != SECSuccess) { SECU_PrintError(progName, "SECITEM_CopyItem failed, out of memory"); return ((CERTSignedCrl *)NULL); } if (!derName.len || !derName.data) { SECU_PrintError(progName, "could not find certificate named '%s'", name); return ((CERTSignedCrl *)NULL); } } else { SECITEM_CopyItem(NULL, &derName, &cert->derSubject); CERT_DestroyCertificate(cert); } crl = SEC_FindCrlByName(certHandle, &derName, type); if (crl == NULL) SECU_PrintError(progName, "could not find %s's CRL", name); if (derName.data) { SECITEM_FreeItem(&derName, PR_FALSE); } return (crl); }
static int HashDecodeAndVerify(FILE *out, FILE *content, PRFileDesc *signature, SECCertUsage usage, char *progName) { SECItem derdata; SEC_PKCS7ContentInfo *cinfo; SEC_PKCS7SignedData *signedData; HASH_HashType digestType; SECItem digest; unsigned char buffer[32]; if (SECU_ReadDERFromFile(&derdata, signature, PR_FALSE) != SECSuccess) { SECU_PrintError(progName, "error reading signature file"); return -1; } cinfo = SEC_PKCS7DecodeItem(&derdata, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (cinfo == NULL) return -1; if (! SEC_PKCS7ContentIsSigned(cinfo)) { fprintf (out, "Signature file is pkcs7 data, but not signed.\n"); return -1; } signedData = cinfo->content.signedData; /* assume that there is only one digest algorithm for now */ digestType = AlgorithmToHashType(signedData->digestAlgorithms[0]); if (digestType == HASH_AlgNULL) { fprintf (out, "Invalid hash algorithmID\n"); return -1; } digest.data = buffer; if (DigestFile (digest.data, &digest.len, 32, content, digestType)) { SECU_PrintError (progName, "problem computing message digest"); return -1; } fprintf(out, "Signature is "); if (SEC_PKCS7VerifyDetachedSignature (cinfo, usage, &digest, digestType, PR_FALSE)) fprintf(out, "valid.\n"); else fprintf(out, "invalid (Reason: %s).\n", SECU_Strerror(PORT_GetError())); SEC_PKCS7DestroyContentInfo(cinfo); return 0; }
static CERTCertificate * FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl, char *certNickName) { CERTCertificate *cert = NULL, *certTemp = NULL; SECStatus rv = SECFailure; CERTAuthKeyID *authorityKeyID = NULL; SECItem *subject = NULL; PORT_Assert(certHandle != NULL); if (!certHandle || (!signCrl && !certNickName)) { SECU_PrintError(progName, "invalid args for function " "FindSigningCert \n"); return NULL; } if (signCrl) { #if 0 authorityKeyID = SECU_FindCRLAuthKeyIDExten(tmpArena, scrl); #endif subject = &signCrl->crl.derName; } else { certTemp = CERT_FindCertByNickname(certHandle, certNickName); if (!certTemp) { SECU_PrintError(progName, "could not find certificate \"%s\" " "in database", certNickName); goto loser; } subject = &certTemp->derSubject; } cert = SECU_FindCrlIssuer(certHandle, subject, authorityKeyID, PR_Now()); if (!cert) { SECU_PrintError(progName, "could not find signing certificate " "in database"); goto loser; } else { rv = SECSuccess; } loser: if (certTemp) CERT_DestroyCertificate(certTemp); if (cert && rv != SECSuccess) CERT_DestroyCertificate(cert); return cert; }
SECStatus DumpCRL(PRFileDesc *inFile) { int rv; PLArenaPool *arena = NULL; CERTSignedCrl *newCrl = NULL; SECItem crlDER; crlDER.data = NULL; /* Read in the entire file specified with the -f argument */ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE); if (rv != SECSuccess) { SECU_PrintError(progName, "unable to read input file"); return (SECFailure); } rv = SEC_ERROR_NO_MEMORY; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return rv; newCrl = CERT_DecodeDERCrlWithFlags(arena, &crlDER, SEC_CRL_TYPE, CRL_DECODE_DEFAULT_OPTIONS); if (!newCrl) return SECFailure; SECU_PrintCRLInfo (stdout, &newCrl->crl, "CRL file contents", 0); PORT_FreeArena (arena, PR_FALSE); return rv; }
/************************************************************************ * * R a w L i s t M o d u l e s * * Lists all the modules in the database, along with their slots and tokens. */ Error RawListModule(char *modulespec) { SECMODModule *module; char **moduleSpecList; module = SECMOD_LoadModule(modulespec, NULL, PR_FALSE); if (module == NULL) { /* handle error */ return NO_SUCH_MODULE_ERR; } moduleSpecList = SECMOD_GetModuleSpecList(module); if (!moduleSpecList || !moduleSpecList[0]) { SECU_PrintError("modutil", "no specs in secmod DB"); return NO_SUCH_MODULE_ERR; } for (; *moduleSpecList; moduleSpecList++) { printf("%s\n\n", *moduleSpecList); } return SUCCESS; }
static SECStatus UpdateCrl(CERTSignedCrl *signCrl, PRFileDesc *inCrlInitFile) { CRLGENGeneratorData *crlGenData = NULL; SECStatus rv; if (!signCrl || !inCrlInitFile) { PORT_SetError(SEC_ERROR_INVALID_ARGS); SECU_PrintError(progName, "invalid args for function " "CreateNewCrl\n"); return SECFailure; } crlGenData = CRLGEN_InitCrlGeneration(signCrl, inCrlInitFile); if (!crlGenData) { SECU_PrintError(progName, "can not initialize parser structure.\n"); return SECFailure; } rv = CRLGEN_ExtHandleInit(crlGenData); if (rv == SECFailure) { SECU_PrintError(progName, "can not initialize entries handle.\n"); goto loser; } rv = CRLGEN_StartCrlGen(crlGenData); if (rv != SECSuccess) { SECU_PrintError(progName, "crl generation failed"); goto loser; } loser: /* CommitExtensionsAndEntries is partially responsible for freeing * up memory that was used for CRL generation. Should be called regardless * of previouse call status, but only after initialization of * crlGenData was done. It will commit all changes that was done before * an error has occurred. */ if (SECSuccess != CRLGEN_CommitExtensionsAndEntries(crlGenData)) { SECU_PrintError(progName, "crl generation failed"); rv = SECFailure; } CRLGEN_FinalizeCrlGeneration(crlGenData); return rv; }
int WriteBuf(char *inFile, SECItem *item) { int ret; PRFileDesc* fd = PR_Open(inFile, PR_WRONLY|PR_CREATE_FILE, 0x200); if (NULL == fd) { SECU_PrintError("symkeyutil", "PR_Open failed"); return -1; } ret = PR_Write(fd,item->data,item->len); if (ret < 0) { SECU_PrintError("symkeyutil", "PR_Write failed"); return -1; } PR_Close(fd); return 0; }
int main(int argc, char **argv) { NSSLOWInitContext *initCtx; int rv = 0; /* counts the number of failures */ progName = strrchr(argv[0], '/'); progName = progName ? progName + 1 : argv[0]; initCtx = NSSLOW_Init(); if (initCtx == NULL) { SECU_PrintError(progName, "Couldn't initialize for hashing\n"); return 1; } if (argc || !argv[1] || strlen(argv[1]) == 0) { rv += testMD5(initCtx); rv += testSHA1(initCtx); rv += testSHA224(initCtx); rv += testSHA256(initCtx); rv += testSHA384(initCtx); rv += testSHA512(initCtx); } else if (strcmp(argv[1], "MD5") == 0) { rv += testMD5(initCtx); } else if (strcmp(argv[1], "SHA1") == 0) { rv += testSHA1(initCtx); } else if (strcmp(argv[1], "SHA224") == 0) { rv += testSHA224(initCtx); } else if (strcmp(argv[1], "SHA226") == 0) { rv += testSHA256(initCtx); } else if (strcmp(argv[1], "SHA384") == 0) { rv += testSHA384(initCtx); } else if (strcmp(argv[1], "SHA512") == 0) { rv += testSHA512(initCtx); } else { SECU_PrintError(progName, "Unsupported hash type %s\n", argv[0]); Usage(progName); } NSSLOW_Shutdown(initCtx); return (rv == 0) ? 0 : 1; }
static int test_long_message(NSSLOWInitContext *initCtx, HASH_HashType algoType, unsigned int hashLen, const PRUint8 expected[], PRUint8 results[]) { unsigned int len, i, rv = 0; NSSLOWHASHContext *ctx; /* The message is meant to be 'a' repeated 1,000,000 times. * This is too much to allocate on the stack so we will use a 1,000 char * buffer and call update 1,000 times. */ unsigned char buf[1000]; (void)PORT_Memset(buf, 'a', sizeof(buf)); ctx = NSSLOWHASH_NewContext(initCtx, algoType); if (ctx == NULL) { SECU_PrintError(progName, "Couldn't get hash context\n"); return 1; } NSSLOWHASH_Begin(ctx); for (i = 0; i < 1000; ++i) { NSSLOWHASH_Update(ctx, buf, 1000); } NSSLOWHASH_End(ctx, results, &len, hashLen); PR_ASSERT(len == hashLen); PR_ASSERT(PORT_Memcmp(expected, results, hashLen) == 0); if (PORT_Memcmp(expected, results, len) != 0) { SECU_PrintError(progName, "Hash mismatch\n"); SECU_PrintBuf(stdout, "Expected: ", expected, hashLen); SECU_PrintBuf(stdout, "Actual: ", results, len); rv = 1; } NSSLOWHASH_Destroy(ctx); NSSLOW_Shutdown(initCtx); return rv; }
static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type) { CERTSignedCrl *crl = NULL; SECStatus rv = SECFailure; crl = FindCRL (certHandle, name, type); if (!crl) { SECU_PrintError (progName, "could not find the issuer %s's CRL", name); return SECFailure; } rv = SEC_DeletePermCRL (crl); SEC_DestroyCrl(crl); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to delete the issuer %s's CRL " "from the perm database (reason: %s)", name, SECU_Strerror(PORT_GetError())); return SECFailure; } return (rv); }
void SECU_PrintPRandOSError(const char *progName) { char buffer[513]; PRInt32 errLen = PR_GetErrorTextLength(); if (errLen > 0 && errLen < sizeof buffer) { PR_GetErrorText(buffer); } SECU_PrintError(progName, "function failed"); if (errLen > 0 && errLen < sizeof buffer) { PR_fprintf(PR_STDERR, "\t%s\n", buffer); } }
/****************************************************************** * * m a k e _ c e r t _ r e q u e s t */ static CERTCertificateRequest* make_cert_request(char *subject, SECKEYPublicKey *pubk) { CERTName * subj; CERTSubjectPublicKeyInfo * spki; CERTCertificateRequest * req; /* Create info about public key */ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); if (!spki) { SECU_PrintError(progName, "unable to create subject public key"); exit (ERRX); } subj = CERT_AsciiToName (subject); if (subj == NULL) { FatalError("Invalid data in certificate description"); } /* Generate certificate request */ req = CERT_CreateCertificateRequest(subj, spki, 0); if (!req) { SECU_PrintError(progName, "unable to make certificate request"); exit (ERRX); } SECKEY_DestroySubjectPublicKeyInfo(spki); CERT_DestroyName(subj); if (verbosity >= 0) { PR_fprintf(outputFD, "certificate request generated\n"); } return req; }
int main(int argc, char **argv) { CERTCertDBHandle *certHandle; PRFileDesc *inFile; PRFileDesc *inCrlInitFile = NULL; int generateCRL; int modifyCRL; int listCRL; int importCRL; int showFileCRL; int deleteCRL; int rv; char *nickName; char *url; char *dbPrefix = ""; char *alg = NULL; char *outFile = NULL; char *slotName = NULL; int ascii = 0; int crlType; PLOptState *optstate; PLOptStatus status; SECStatus secstatus; PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS; PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS; PRBool quiet = PR_FALSE; PRBool test = PR_FALSE; PRBool erase = PR_FALSE; PRInt32 i = 0; PRInt32 iterations = 1; PRBool readonly = PR_FALSE; secuPWData pwdata = { PW_NONE, 0 }; progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; rv = 0; deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0; inFile = NULL; nickName = url = NULL; certHandle = NULL; crlType = SEC_CRL_TYPE; /* * Parse command line arguments */ optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': Usage(progName); break; case 'T': test = PR_TRUE; break; case 'E': erase = PR_TRUE; break; case 'B': importOptions |= CRL_IMPORT_BYPASS_CHECKS; break; case 'G': generateCRL = 1; break; case 'M': modifyCRL = 1; break; case 'D': deleteCRL = 1; break; case 'I': importCRL = 1; break; case 'S': showFileCRL = 1; break; case 'C': case 'L': listCRL = 1; break; case 'P': dbPrefix = strdup(optstate->value); break; case 'Z': alg = strdup(optstate->value); break; case 'a': ascii = 1; break; case 'c': inCrlInitFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!inCrlInitFile) { PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); PL_DestroyOptState(optstate); return -1; } break; case 'd': SECU_ConfigDirectory(optstate->value); break; case 'f': pwdata.source = PW_FROMFILE; pwdata.data = strdup(optstate->value); break; case 'h': slotName = strdup(optstate->value); break; case 'i': inFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!inFile) { PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); PL_DestroyOptState(optstate); return -1; } break; case 'n': nickName = strdup(optstate->value); break; case 'o': outFile = strdup(optstate->value); break; case 'p': decodeOptions |= CRL_DECODE_SKIP_ENTRIES; break; case 'r': { const char* str = optstate->value; if (str && atoi(str)>0) iterations = atoi(str); } break; case 't': { crlType = atoi(optstate->value); if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) { PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName); PL_DestroyOptState(optstate); return -1; } break; case 'q': quiet = PR_TRUE; break; case 'w': pwdata.source = PW_PLAINTEXT; pwdata.data = strdup(optstate->value); break; case 'u': url = strdup(optstate->value); break; } } } PL_DestroyOptState(optstate); if (deleteCRL && !nickName) Usage (progName); if (importCRL && !inFile) Usage (progName); if (showFileCRL && !inFile) Usage (progName); if ((generateCRL && !nickName) || (modifyCRL && !inFile && !nickName)) Usage (progName); if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL || modifyCRL || test || erase)) Usage (progName); if (listCRL || showFileCRL) { readonly = PR_TRUE; } PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(SECU_GetModulePassword); if (showFileCRL) { NSS_NoDB_Init(NULL); } else { secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix, "secmod.db", readonly ? NSS_INIT_READONLY : 0); if (secstatus != SECSuccess) { SECU_PrintPRandOSError(progName); return -1; } } SECU_RegisterDynamicOids(); certHandle = CERT_GetDefaultCertDB(); if (certHandle == NULL) { SECU_PrintError(progName, "unable to open the cert db"); /*ignoring return value of NSS_Shutdown() as code returns -1*/ (void) NSS_Shutdown(); return (-1); } CRLGEN_InitCrlGenParserLock(); for (i=0; i<iterations; i++) { /* Read in the private key info */ if (deleteCRL) DeleteCRL (certHandle, nickName, crlType); else if (listCRL) { rv = ListCRL (certHandle, nickName, crlType); } else if (importCRL) { rv = ImportCRL (certHandle, url, crlType, inFile, importOptions, decodeOptions, &pwdata); } else if (showFileCRL) { rv = DumpCRL (inFile); } else if (generateCRL || modifyCRL) { if (!inCrlInitFile) inCrlInitFile = PR_STDIN; rv = GenerateCRL (certHandle, nickName, inCrlInitFile, inFile, outFile, ascii, slotName, importOptions, alg, quiet, decodeOptions, url, &pwdata, modifyCRL); } else if (erase) { /* list and delete all CRLs */ ListCRLNames (certHandle, crlType, PR_TRUE); } #ifdef DEBUG else if (test) { /* list and delete all CRLs */ ListCRLNames (certHandle, crlType, PR_TRUE); /* list CRLs */ ListCRLNames (certHandle, crlType, PR_FALSE); /* import CRL as a blob */ rv = ImportCRL (certHandle, url, crlType, inFile, importOptions, decodeOptions, &pwdata); /* list CRLs */ ListCRLNames (certHandle, crlType, PR_FALSE); } #endif } CRLGEN_DestroyCrlGenParserLock(); if (NSS_Shutdown() != SECSuccess) { rv = SECFailure; } return (rv != SECSuccess); }
static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls) { CERTCrlHeadNode *crlList = NULL; CERTCrlNode *crlNode = NULL; CERTName *name = NULL; PLArenaPool *arena = NULL; SECStatus rv; do { arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); if (arena == NULL) { fprintf(stderr, "%s: fail to allocate memory\n", progName); break; } name = PORT_ArenaZAlloc (arena, sizeof(*name)); if (name == NULL) { fprintf(stderr, "%s: fail to allocate memory\n", progName); break; } name->arena = arena; rv = SEC_LookupCrls (certHandle, &crlList, crlType); if (rv != SECSuccess) { fprintf(stderr, "%s: fail to look up CRLs (%s)\n", progName, SECU_Strerror(PORT_GetError())); break; } /* just in case */ if (!crlList) break; crlNode = crlList->first; fprintf (stdout, "\n"); fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type"); while (crlNode) { char* asciiname = NULL; CERTCertificate *cert = NULL; if (crlNode->crl && &crlNode->crl->crl.derName) { cert = CERT_FindCertByName(certHandle, &crlNode->crl->crl.derName); if (!cert) { SECU_PrintError(progName, "could not find signing " "certificate in database"); } } if (cert) { char* certName = NULL; if (cert->nickname && PORT_Strlen(cert->nickname) > 0) { certName = cert->nickname; } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr) > 0) { certName = cert->emailAddr; } if (certName) { asciiname = PORT_Strdup(certName); } CERT_DestroyCertificate(cert); } if (!asciiname) { name = &crlNode->crl->crl.name; if (!name){ SECU_PrintError(progName, "fail to get the CRL " "issuer name"); continue; } asciiname = CERT_NameToAscii(name); } fprintf (stdout, "%-40s %-5s\n", asciiname, "CRL"); if (asciiname) { PORT_Free(asciiname); } if ( PR_TRUE == deletecrls) { CERTSignedCrl* acrl = NULL; SECItem* issuer = &crlNode->crl->crl.derName; acrl = SEC_FindCrlByName(certHandle, issuer, crlType); if (acrl) { SEC_DeletePermCRL(acrl); SEC_DestroyCrl(acrl); } } crlNode = crlNode->next; } } while (0); if (crlList) PORT_FreeArena (crlList->arena, PR_FALSE); PORT_FreeArena (arena, PR_FALSE); }
static SECStatus SignAndStoreCrl(CERTSignedCrl *signCrl, CERTCertificate *cert, char *outFileName, SECOidTag hashAlgTag, int ascii, char *slotName, char *url, secuPWData *pwdata) { PK11SlotInfo *slot = NULL; PRFileDesc *outFile = NULL; SECStatus rv; SignAndEncodeFuncExitStat errCode; PORT_Assert(signCrl && (!ascii || outFileName)); if (!signCrl || (ascii && !outFileName)) { SECU_PrintError(progName, "invalid args for function " "SignAndStoreCrl\n"); return SECFailure; } if (!slotName || !PL_strcmp(slotName, "internal")) slot = PK11_GetInternalKeySlot(); else slot = PK11_FindSlotByName(slotName); if (!slot) { SECU_PrintError(progName, "can not find requested slot"); return SECFailure; } if (PK11_NeedLogin(slot)) { rv = PK11_Authenticate(slot, PR_TRUE, pwdata); if (rv != SECSuccess) goto loser; } rv = SECU_SignAndEncodeCRL(cert, signCrl, hashAlgTag, &errCode); if (rv != SECSuccess) { char* errMsg = NULL; switch (errCode) { case noKeyFound: errMsg = "No private key found of signing cert"; break; case noSignatureMatch: errMsg = "Key and Algorithm OId are do not match"; break; default: case failToEncode: errMsg = "Failed to encode crl structure"; break; case failToSign: errMsg = "Failed to sign crl structure"; break; case noMem: errMsg = "Can not allocate memory"; break; } SECU_PrintError(progName, "%s\n", errMsg); goto loser; } if (outFileName) { outFile = PR_Open(outFileName, PR_WRONLY|PR_CREATE_FILE, PR_IRUSR | PR_IWUSR); if (!outFile) { SECU_PrintError(progName, "unable to open \"%s\" for writing\n", outFileName); goto loser; } } rv = SECU_StoreCRL(slot, signCrl->derCrl, outFile, ascii, url); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to save CRL\n"); } loser: if (outFile) PR_Close(outFile); if (slot) PK11_FreeSlot(slot); return rv; }
static SECStatus GenerateCRL (CERTCertDBHandle *certHandle, char *certNickName, PRFileDesc *inCrlInitFile, PRFileDesc *inFile, char *outFileName, int ascii, char *slotName, PRInt32 importOptions, char *alg, PRBool quiet, PRInt32 decodeOptions, char *url, secuPWData *pwdata, int modifyFlag) { CERTCertificate *cert = NULL; CERTSignedCrl *signCrl = NULL; PLArenaPool *arena = NULL; SECStatus rv; SECOidTag hashAlgTag = SEC_OID_UNKNOWN; if (alg) { hashAlgTag = SECU_StringToSignatureAlgTag(alg); if (hashAlgTag == SEC_OID_UNKNOWN) { SECU_PrintError(progName, "%s -Z: %s is not a recognized type.\n", progName, alg); return SECFailure; } } else { hashAlgTag = SEC_OID_UNKNOWN; } arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); if (!arena) { SECU_PrintError(progName, "fail to allocate memory\n"); return SECFailure; } if (modifyFlag == PR_TRUE) { signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName, inFile, decodeOptions, importOptions); if (signCrl == NULL) { goto loser; } } if (!cert) { cert = FindSigningCert(certHandle, signCrl, certNickName); if (cert == NULL) { goto loser; } } if (!signCrl) { if (modifyFlag == PR_TRUE) { if (!outFileName) { int len = strlen(certNickName) + 5; outFileName = PORT_ArenaAlloc(arena, len); PR_snprintf(outFileName, len, "%s.crl", certNickName); } SECU_PrintError(progName, "Will try to generate crl. " "It will be saved in file: %s", outFileName); } signCrl = CreateNewCrl(arena, certHandle, cert); if (!signCrl) goto loser; } rv = UpdateCrl(signCrl, inCrlInitFile); if (rv != SECSuccess) { goto loser; } rv = SignAndStoreCrl(signCrl, cert, outFileName, hashAlgTag, ascii, slotName, url, pwdata); if (rv != SECSuccess) { goto loser; } if (signCrl && !quiet) { SECU_PrintCRLInfo (stdout, &signCrl->crl, "CRL Info:\n", 0); } loser: if (arena && (!signCrl || !signCrl->arena)) PORT_FreeArena (arena, PR_FALSE); if (signCrl) SEC_DestroyCrl (signCrl); if (cert) CERT_DestroyCertificate (cert); return (rv); }
static CERTSignedCrl* CreateNewCrl(PLArenaPool *arena, CERTCertDBHandle *certHandle, CERTCertificate *cert) { CERTSignedCrl *signCrl = NULL; void *dummy = NULL; SECStatus rv; void* mark = NULL; /* if the CERTSignedCrl structure changes, this function will need to be updated as well */ if (!cert || !arena) { PORT_SetError(SEC_ERROR_INVALID_ARGS); SECU_PrintError(progName, "invalid args for function " "CreateNewCrl\n"); return NULL; } mark = PORT_ArenaMark(arena); signCrl = PORT_ArenaZNew(arena, CERTSignedCrl); if (signCrl == NULL) { SECU_PrintError(progName, "fail to allocate memory\n"); return NULL; } dummy = SEC_ASN1EncodeInteger(arena, &signCrl->crl.version, SEC_CRL_VERSION_2); /* set crl->version */ if (!dummy) { SECU_PrintError(progName, "fail to create crl version data " "container\n"); goto loser; } /* copy SECItem name from cert */ rv = SECITEM_CopyItem(arena, &signCrl->crl.derName, &cert->derSubject); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to duplicate der name from " "certificate.\n"); goto loser; } /* copy CERTName name structure from cert issuer */ rv = CERT_CopyName (arena, &signCrl->crl.name, &cert->subject); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to duplicate RD name from " "certificate.\n"); goto loser; } rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now()); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to encode current time\n"); goto loser; } /* set fields */ signCrl->arena = arena; signCrl->dbhandle = certHandle; signCrl->crl.arena = arena; return signCrl; loser: PORT_ArenaRelease(arena, mark); return NULL; }
int main(int argc, char **argv) { char *progName; FILE *contentFile, *outFile; PRFileDesc *signatureFile; SECCertUsage certUsage = certUsageEmailSigner; PLOptState *optstate; PLOptStatus status; SECStatus rv; progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; contentFile = NULL; signatureFile = NULL; outFile = NULL; /* * Parse command line arguments */ optstate = PL_CreateOptState(argc, argv, "c:d:o:s:u:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': Usage(progName); break; case 'c': contentFile = fopen(optstate->value, "r"); if (!contentFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); return -1; } break; case 'd': SECU_ConfigDirectory(optstate->value); break; case 'o': outFile = fopen(optstate->value, "w"); if (!outFile) { fprintf(stderr, "%s: unable to open \"%s\" for writing\n", progName, optstate->value); return -1; } break; case 's': signatureFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!signatureFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); return -1; } break; case 'u': { int usageType; usageType = atoi (strdup(optstate->value)); if (usageType < certUsageSSLClient || usageType > certUsageAnyCA) return -1; certUsage = (SECCertUsage)usageType; break; } } } if (!contentFile) Usage (progName); if (!signatureFile) Usage (progName); if (!outFile) outFile = stdout; /* Call the NSS initialization routines */ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); rv = NSS_Init(SECU_ConfigDirectory(NULL)); if (rv != SECSuccess) { SECU_PrintPRandOSError(progName); return -1; } if (HashDecodeAndVerify(outFile, contentFile, signatureFile, certUsage, progName)) { SECU_PrintError(progName, "problem decoding/verifying signature"); return -1; } if (NSS_Shutdown() != SECSuccess) { exit(1); } return 0; }
/* Time iter repetitions of operation op. */ SECStatus M_TimeOperation(void (*threadFunc)(void *), op_func opfunc, char *op, void *param1, void *param2, void *param3, int iters, int numThreads, PRLock *lock, CK_SESSION_HANDLE session, int isSign, double *rate) { double dUserTime; int i, total; PRIntervalTime startTime, totalTime; PRThread **threadIDs; ThreadData *threadData; pk11_op_func pk11_op = (pk11_op_func)opfunc; SECStatus rv; /* verify operation works before testing performance */ if (session) { rv = (*pk11_op)(session, param1, param2, param3); } else { rv = (*opfunc)(param1, param2, param3); } if (rv != SECSuccess) { SECU_PrintError("Error:", op); return rv; } /* get Data structures */ threadIDs = (PRThread **)PORT_Alloc(numThreads * sizeof(PRThread *)); threadData = (ThreadData *)PORT_Alloc(numThreads * sizeof(ThreadData)); startTime = PR_Now(); if (numThreads == 1) { for (i = 0; i < iters; i++) { if (session) { rv = (*pk11_op)(session, param1, param2, param3); } else { rv = (*opfunc)(param1, param2, param3); } } total = iters; } else { for (i = 0; i < numThreads; i++) { threadData[i].op = opfunc; threadData[i].p1 = (void *)param1; threadData[i].p2 = (void *)param2; threadData[i].p3 = (void *)param3; threadData[i].iters = iters; threadData[i].lock = lock; threadData[i].isSign = isSign; threadIDs[i] = PR_CreateThread(PR_USER_THREAD, threadFunc, (void *)&threadData[i], PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); } total = 0; for (i = 0; i < numThreads; i++) { PR_JoinThread(threadIDs[i]); /* check the status */ total += threadData[i].count; } PORT_Free(threadIDs); PORT_Free(threadData); } totalTime = PR_Now() - startTime; /* SecondsToInterval seems to be broken here ... */ dUserTime = (double)totalTime / (double)1000000; if (dUserTime) { printf(" %-15s count:%4d sec: %3.2f op/sec: %6.2f\n", op, total, dUserTime, (double)total / dUserTime); if (rate) { *rate = ((double)total) / dUserTime; } } return SECSuccess; }
static CERTSignedCrl* CreateModifiedCRLCopy(PLArenaPool *arena, CERTCertDBHandle *certHandle, CERTCertificate **cert, char *certNickName, PRFileDesc *inFile, PRInt32 decodeOptions, PRInt32 importOptions) { SECItem crlDER = {0, NULL, 0}; CERTSignedCrl *signCrl = NULL; CERTSignedCrl *modCrl = NULL; PLArenaPool *modArena = NULL; SECStatus rv = SECSuccess; if (!arena || !certHandle || !certNickName) { PORT_SetError(SEC_ERROR_INVALID_ARGS); SECU_PrintError(progName, "CreateModifiedCRLCopy: invalid args\n"); return NULL; } modArena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if (!modArena) { SECU_PrintError(progName, "fail to allocate memory\n"); return NULL; } if (inFile != NULL) { rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE); if (rv != SECSuccess) { SECU_PrintError(progName, "unable to read input file"); PORT_FreeArena(modArena, PR_FALSE); goto loser; } decodeOptions |= CRL_DECODE_DONT_COPY_DER; modCrl = CERT_DecodeDERCrlWithFlags(modArena, &crlDER, SEC_CRL_TYPE, decodeOptions); if (!modCrl) { SECU_PrintError(progName, "fail to decode CRL"); goto loser; } if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){ /* If caCert is a v2 certificate, make sure that it * can be used for crl signing purpose */ *cert = FindSigningCert(certHandle, modCrl, NULL); if (!*cert) { goto loser; } rv = CERT_VerifySignedData(&modCrl->signatureWrap, *cert, PR_Now(), NULL); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to verify signed data\n"); goto loser; } } } else { modCrl = FindCRL(certHandle, certNickName, SEC_CRL_TYPE); if (!modCrl) { SECU_PrintError(progName, "fail to find crl %s in database\n", certNickName); goto loser; } } signCrl = PORT_ArenaZNew(arena, CERTSignedCrl); if (signCrl == NULL) { SECU_PrintError(progName, "fail to allocate memory\n"); goto loser; } rv = SECU_CopyCRL(arena, &signCrl->crl, &modCrl->crl); if (rv != SECSuccess) { SECU_PrintError(progName, "unable to dublicate crl for " "modification."); goto loser; } /* Make sure the update time is current. It can be modified later * by "update <time>" command from crl generation script */ rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now()); if (rv != SECSuccess) { SECU_PrintError(progName, "fail to encode current time\n"); goto loser; } signCrl->arena = arena; loser: if (crlDER.data) { SECITEM_FreeItem(&crlDER, PR_FALSE); } if (modCrl) SEC_DestroyCrl(modCrl); if (rv != SECSuccess && signCrl) { SEC_DestroyCrl(signCrl); signCrl = NULL; } return signCrl; }
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 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; }
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; }
static int EncryptFile(FILE *outFile, FILE *inFile, struct recipient *recipients, char *progName) { SEC_PKCS7ContentInfo *cinfo; SEC_PKCS7EncoderContext *ecx; struct recipient *rcpt; SECStatus rv; if (outFile == NULL || inFile == NULL || recipients == NULL) return -1; /* XXX Need a better way to handle that certUsage stuff! */ /* XXX keysize? */ cinfo = SEC_PKCS7CreateEnvelopedData (recipients->cert, certUsageEmailRecipient, NULL, SEC_OID_DES_EDE3_CBC, 0, NULL, NULL); if (cinfo == NULL) return -1; for (rcpt = recipients->next; rcpt != NULL; rcpt = rcpt->next) { rv = SEC_PKCS7AddRecipient (cinfo, rcpt->cert, certUsageEmailRecipient, NULL); if (rv != SECSuccess) { SECU_PrintError(progName, "error adding recipient \"%s\"", rcpt->nickname); return -1; } } ecx = SEC_PKCS7EncoderStart (cinfo, EncryptOut, outFile, NULL); if (ecx == NULL) return -1; for (;;) { char ibuf[1024]; int nb; if (feof(inFile)) break; nb = fread(ibuf, 1, sizeof(ibuf), inFile); if (nb == 0) { if (ferror(inFile)) { PORT_SetError(SEC_ERROR_IO); rv = SECFailure; } break; } rv = SEC_PKCS7EncoderUpdate(ecx, ibuf, nb); if (rv != SECSuccess) break; } if (SEC_PKCS7EncoderFinish(ecx, NULL, NULL) != SECSuccess) rv = SECFailure; SEC_PKCS7DestroyContentInfo (cinfo); if (rv != SECSuccess) return -1; return 0; }
int main(int argc, char **argv) { char *progName; FILE *inFile, *outFile; char *certName; CERTCertDBHandle *certHandle; struct recipient *recipients, *rcpt; PLOptState *optstate; PLOptStatus status; SECStatus rv; progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; inFile = NULL; outFile = NULL; certName = NULL; recipients = NULL; rcpt = NULL; /* * Parse command line arguments * XXX This needs to be enhanced to allow selection of algorithms * and key sizes (or to look up algorithms and key sizes for each * recipient in the magic database). */ optstate = PL_CreateOptState(argc, argv, "d:i:o:r:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': Usage(progName); break; case 'd': SECU_ConfigDirectory(optstate->value); break; case 'i': inFile = fopen(optstate->value, "r"); if (!inFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); return -1; } break; case 'o': outFile = fopen(optstate->value, "wb"); if (!outFile) { fprintf(stderr, "%s: unable to open \"%s\" for writing\n", progName, optstate->value); return -1; } break; case 'r': if (rcpt == NULL) { recipients = rcpt = PORT_Alloc (sizeof(struct recipient)); } else { rcpt->next = PORT_Alloc (sizeof(struct recipient)); rcpt = rcpt->next; } if (rcpt == NULL) { fprintf(stderr, "%s: unable to allocate recipient struct\n", progName); return -1; } rcpt->nickname = strdup(optstate->value); rcpt->cert = NULL; rcpt->next = NULL; break; } } if (!recipients) Usage(progName); if (!inFile) inFile = stdin; if (!outFile) outFile = stdout; /* Call the NSS initialization routines */ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); rv = NSS_Init(SECU_ConfigDirectory(NULL)); if (rv != SECSuccess) { SECU_PrintPRandOSError(progName); return -1; } /* open cert database */ certHandle = CERT_GetDefaultCertDB(); if (certHandle == NULL) { return -1; } /* find certs */ for (rcpt = recipients; rcpt != NULL; rcpt = rcpt->next) { rcpt->cert = CERT_FindCertByNickname(certHandle, rcpt->nickname); if (rcpt->cert == NULL) { SECU_PrintError(progName, "the cert for name \"%s\" not found in database", rcpt->nickname); return -1; } } if (EncryptFile(outFile, inFile, recipients, progName)) { SECU_PrintError(progName, "problem encrypting data"); return -1; } return 0; }