/** * deleteCrl * * Delete a Crl entry from the cert db. */ NS_IMETHODIMP nsCRLManager::DeleteCrl(uint32_t aCrlIndex) { nsNSSShutDownPreventionLock locker; CERTSignedCrl *realCrl = nullptr; CERTCrlHeadNode *head = nullptr; CERTCrlNode *node = nullptr; SECStatus sec_rv; uint32_t i; // Get the list of certs // sec_rv = SEC_LookupCrls(CERT_GetDefaultCertDB(), &head, -1); if (sec_rv != SECSuccess) { return NS_ERROR_FAILURE; } if (head) { for (i = 0, node=head->first; node; i++, node = node->next) { if (i != aCrlIndex) { continue; } realCrl = SEC_FindCrlByName(CERT_GetDefaultCertDB(), &(node->crl->crl.derName), node->type); SEC_DeletePermCRL(realCrl); SEC_DestroyCrl(realCrl); SSL_ClearSessionCache(); } PORT_FreeArena(head->arena, false); } return NS_OK; }
/* add given CRL to cache if it is not already there */ static SECStatus nss_cache_crl(SECItem *crlDER) { CERTCertDBHandle *db = CERT_GetDefaultCertDB(); CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crlDER, 0); if(crl) { /* CRL already cached */ SEC_DestroyCrl(crl); SECITEM_FreeItem(crlDER, PR_FALSE); return SECSuccess; } /* acquire lock before call of CERT_CacheCRL() */ PR_Lock(nss_crllock); if(SECSuccess != CERT_CacheCRL(db, crlDER)) { /* unable to cache CRL */ PR_Unlock(nss_crllock); SECITEM_FreeItem(crlDER, PR_FALSE); return SECFailure; } /* we need to clear session cache, so that the CRL could take effect */ SSL_ClearSessionCache(); PR_Unlock(nss_crllock); return SECSuccess; }
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 SECStatus DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType) { CERTSignedCrl *crl = NULL; crl = FindCRL (certHandle, nickName, crlType); if (crl) { SECU_PrintCRLInfo (stdout, &crl->crl, "CRL Info:\n", 0); SEC_DestroyCrl (crl); return SECSuccess; } return SECFailure; }
/* * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h) */ PKIX_Error * PKIX_PL_CRL_Create( PKIX_PL_ByteArray *byteArray, PKIX_PL_CRL **pCrl, void *plContext) { CERTSignedCrl *nssSignedCrl = NULL; SECItem derItem, *derCrl = NULL; PKIX_PL_CRL *crl = NULL; PKIX_ENTER(CRL, "PKIX_PL_CRL_Create"); PKIX_NULLCHECK_TWO(byteArray, pCrl); if (byteArray->length == 0){ PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING); } derItem.type = siBuffer; derItem.data = byteArray->array; derItem.len = byteArray->length; derCrl = SECITEM_DupItem(&derItem); if (!derCrl) { PKIX_ERROR(PKIX_ALLOCERROR); } nssSignedCrl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, SEC_CRL_TYPE, CRL_DECODE_DONT_COPY_DER | CRL_DECODE_SKIP_ENTRIES); if (!nssSignedCrl) { PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED); } PKIX_CHECK( pkix_pl_CRL_CreateWithSignedCRL(nssSignedCrl, derCrl, NULL, &crl, plContext), PKIX_CRLCREATEWITHSIGNEDCRLFAILED); nssSignedCrl = NULL; derCrl = NULL; *pCrl = crl; cleanup: if (derCrl) { SECITEM_FreeItem(derCrl, PR_TRUE); } if (nssSignedCrl) { SEC_DestroyCrl(nssSignedCrl); } PKIX_RETURN(CRL); }
static int import_crl(const char *url, unsigned char *buf, size_t len) { CERTSignedCrl *crl = NULL; SECItem si = {siBuffer, NULL, 0}; CERTCertDBHandle *handle = CERT_GetDefaultCertDB(); if (handle == NULL) return -1; si.data = buf; si.len = len; if ((crl = CERT_ImportCRL(handle, &si, (char *)url, SEC_CRL_TYPE, NULL)) == NULL) { return PORT_GetError(); } SEC_DestroyCrl(crl); return 0; }
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); }
/* * FUNCTION: pkix_pl_CRL_CreateToList * DESCRIPTION: * * This function decodes a DER-encoded Certificate Revocation List pointed to * by "derCrlItem", adding the resulting PKIX_PL_CRL, if the decoding was * successful, to the List (possibly empty) pointed to by "crlList". * * PARAMETERS: * "derCrlItem" * The address of the SECItem containing the DER-encoded Certificate * Revocation List. Must be non-NULL. * "crlList" * The address of the List to which the decoded CRL is added. May be * empty, but must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_CRL_CreateToList( SECItem *derCrlItem, PKIX_List *crlList, void *plContext) { CERTSignedCrl *nssCrl = NULL; PKIX_PL_CRL *crl = NULL; PKIX_ENTER(CRL, "pkix_pl_CRL_CreateToList"); PKIX_NULLCHECK_TWO(derCrlItem, crlList); nssCrl = CERT_DecodeDERCrl(NULL, derCrlItem, SEC_CRL_TYPE); if (nssCrl == NULL) { goto cleanup; } PKIX_CHECK(pkix_pl_CRL_CreateWithSignedCRL (nssCrl, &crl, plContext), PKIX_CRLCREATEWITHSIGNEDCRLFAILED); nssCrl = NULL; PKIX_CHECK(PKIX_List_AppendItem (crlList, (PKIX_PL_Object *) crl, plContext), PKIX_LISTAPPENDITEMFAILED); cleanup: if (nssCrl) { SEC_DestroyCrl(nssCrl); } PKIX_DECREF(crl); PKIX_RETURN(CRL); }
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 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* 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; }
NS_IMETHODIMP nsCRLManager::ImportCrl (PRUint8 *aData, PRUint32 aLength, nsIURI * aURI, PRUint32 aType, PRBool doSilentDonwload, const PRUnichar* crlKey) { nsNSSShutDownPreventionLock locker; nsresult rv; PRArenaPool *arena = NULL; CERTCertificate *caCert; SECItem derName = { siBuffer, NULL, 0 }; SECItem derCrl; CERTSignedData sd; SECStatus sec_rv; CERTSignedCrl *crl; nsCAutoString url; nsCOMPtr<nsICRLInfo> crlData; PRBool importSuccessful; PRInt32 errorCode; nsString errorMessage; nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv)); if (NS_FAILED(rv)) return rv; aURI->GetSpec(url); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { goto loser; } memset(&sd, 0, sizeof(sd)); derCrl.data = (unsigned char*)aData; derCrl.len = aLength; sec_rv = CERT_KeyFromDERCrl(arena, &derCrl, &derName); if (sec_rv != SECSuccess) { goto loser; } caCert = CERT_FindCertByName(CERT_GetDefaultCertDB(), &derName); if (!caCert) { if (aType == SEC_KRL_TYPE){ goto loser; } } else { sec_rv = SEC_ASN1DecodeItem(arena, &sd, SEC_ASN1_GET(CERT_SignedDataTemplate), &derCrl); if (sec_rv != SECSuccess) { goto loser; } sec_rv = CERT_VerifySignedData(&sd, caCert, PR_Now(), nsnull); if (sec_rv != SECSuccess) { goto loser; } } crl = SEC_NewCrl(CERT_GetDefaultCertDB(), const_cast<char*>(url.get()), &derCrl, aType); if (!crl) { goto loser; } crlData = new nsCRLInfo(crl); SSL_ClearSessionCache(); SEC_DestroyCrl(crl); importSuccessful = PR_TRUE; goto done; loser: importSuccessful = PR_FALSE; errorCode = PR_GetError(); switch (errorCode) { case SEC_ERROR_CRL_EXPIRED: nssComponent->GetPIPNSSBundleString("CrlImportFailureExpired", errorMessage); break; case SEC_ERROR_CRL_BAD_SIGNATURE: nssComponent->GetPIPNSSBundleString("CrlImportFailureBadSignature", errorMessage); break; case SEC_ERROR_CRL_INVALID: nssComponent->GetPIPNSSBundleString("CrlImportFailureInvalid", errorMessage); break; case SEC_ERROR_OLD_CRL: nssComponent->GetPIPNSSBundleString("CrlImportFailureOld", errorMessage); break; case SEC_ERROR_CRL_NOT_YET_VALID: nssComponent->GetPIPNSSBundleString("CrlImportFailureNotYetValid", errorMessage); break; default: nssComponent->GetPIPNSSBundleString("CrlImportFailureReasonUnknown", errorMessage); errorMessage.AppendInt(errorCode,16); break; } done: if(!doSilentDonwload){ if (!importSuccessful){ nsString message; nsString temp; nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); nsCOMPtr<nsIPrompt> prompter; if (wwatch){ wwatch->GetNewPrompter(0, getter_AddRefs(prompter)); nssComponent->GetPIPNSSBundleString("CrlImportFailure1x", message); message.Append(NS_LITERAL_STRING("\n").get()); message.Append(errorMessage); nssComponent->GetPIPNSSBundleString("CrlImportFailure2", temp); message.Append(NS_LITERAL_STRING("\n").get()); message.Append(temp); if(prompter) { nsPSMUITracker tracker; if (!tracker.isUIForbidden()) { prompter->Alert(0, message.get()); } } } } else { nsCOMPtr<nsICertificateDialogs> certDialogs; // Not being able to display the success dialog should not // be a fatal error, so don't return a failure code. { nsPSMUITracker tracker; if (tracker.isUIForbidden()) { rv = NS_ERROR_NOT_AVAILABLE; } else { rv = ::getNSSDialogs(getter_AddRefs(certDialogs), NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID); } } if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext(); certDialogs->CrlImportStatusDialog(cxt, crlData); } } } else { if(crlKey == nsnull){ return NS_ERROR_FAILURE; } nsCOMPtr<nsIPrefService> prefSvc = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv); nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv); if (NS_FAILED(rv)){ return rv; } nsCAutoString updateErrCntPrefStr(CRL_AUTOUPDATE_ERRCNT_PREF); updateErrCntPrefStr.AppendWithConversion(crlKey); if(importSuccessful){ PRUnichar *updateTime; nsCAutoString updateTimeStr; nsCString updateURL; PRInt32 timingTypePref; double dayCnt; char *dayCntStr; nsCAutoString updateTypePrefStr(CRL_AUTOUPDATE_TIMIINGTYPE_PREF); nsCAutoString updateTimePrefStr(CRL_AUTOUPDATE_TIME_PREF); nsCAutoString updateUrlPrefStr(CRL_AUTOUPDATE_URL_PREF); nsCAutoString updateDayCntPrefStr(CRL_AUTOUPDATE_DAYCNT_PREF); nsCAutoString updateFreqCntPrefStr(CRL_AUTOUPDATE_FREQCNT_PREF); updateTypePrefStr.AppendWithConversion(crlKey); updateTimePrefStr.AppendWithConversion(crlKey); updateUrlPrefStr.AppendWithConversion(crlKey); updateDayCntPrefStr.AppendWithConversion(crlKey); updateFreqCntPrefStr.AppendWithConversion(crlKey); pref->GetIntPref(updateTypePrefStr.get(),&timingTypePref); //Compute and update the next download instant if(timingTypePref == TYPE_AUTOUPDATE_TIME_BASED){ pref->GetCharPref(updateDayCntPrefStr.get(),&dayCntStr); }else{ pref->GetCharPref(updateFreqCntPrefStr.get(),&dayCntStr); } dayCnt = atof(dayCntStr); nsMemory::Free(dayCntStr); PRBool toBeRescheduled = PR_FALSE; if(NS_SUCCEEDED(ComputeNextAutoUpdateTime(crlData, timingTypePref, dayCnt, &updateTime))){ updateTimeStr.AssignWithConversion(updateTime); nsMemory::Free(updateTime); pref->SetCharPref(updateTimePrefStr.get(),updateTimeStr.get()); //Now, check if this update time is already in the past. This would //imply we have downloaded the same crl, or there is something wrong //with the next update date. We will not reschedule this crl in this //session anymore - or else, we land into a loop. It would anyway be //imported once the browser is restarted. PRTime nextTime; PR_ParseTimeString(updateTimeStr.get(),PR_TRUE, &nextTime); if(LL_CMP(nextTime, > , PR_Now())){ toBeRescheduled = PR_TRUE; } } //Update the url to download from, next time crlData->GetLastFetchURL(updateURL); pref->SetCharPref(updateUrlPrefStr.get(),updateURL.get()); pref->SetIntPref(updateErrCntPrefStr.get(),0); if (toBeRescheduled) { nsAutoString hashKey(crlKey); nssComponent->RemoveCrlFromList(hashKey); nssComponent->DefineNextTimer(); } } else{
CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena, PRInt32 decodeoptions) { CERTSignedCrl *newCrl, *crl; SECStatus rv; CERTCertificate *caCert = NULL; newCrl = crl = NULL; do { newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type, decodeoptions); if (newCrl == NULL) { if (type == SEC_CRL_TYPE) { /* only promote error when the error code is too generic */ if (PORT_GetError () == SEC_ERROR_BAD_DER) PORT_SetError(SEC_ERROR_CRL_INVALID); } else { PORT_SetError(SEC_ERROR_KRL_INVALID); } break; } if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){ CERTCertDBHandle* handle = CERT_GetDefaultCertDB(); PR_ASSERT(handle != NULL); caCert = CERT_FindCertByName (handle, &newCrl->crl.derName); if (caCert == NULL) { PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); break; } /* If caCert is a v3 certificate, make sure that it can be used for crl signing purpose */ rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN); if (rv != SECSuccess) { break; } rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert, PR_Now(), wincx); if (rv != SECSuccess) { if (type == SEC_CRL_TYPE) { PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); } else { PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); } break; } } crl = crl_storeCRL(slot, url, newCrl, derCRL, type); } while (0); if (crl == NULL) { SEC_DestroyCrl (newCrl); } if (caCert) { CERT_DestroyCertificate(caCert); } return (crl); }
/* * FUNCTION: pkix_pl_LdapCertStore_BuildCrlList * DESCRIPTION: * * This function takes a List of LdapResponse objects pointed to by * "responseList" and extracts and decodes the CRLs in those responses, storing * the List of those CRLs at "pCrls". If none of the objects can be decoded * into a CRL, the returned List is empty. * * PARAMETERS: * "responseList" * The address of the List of LdapResponses. Must be non-NULL. * "pCrls" * The address at which the result is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_LdapCertStore_BuildCrlList( PKIX_List *responseList, PKIX_List **pCrls, void *plContext) { PKIX_UInt32 numResponses = 0; PKIX_UInt32 respIx = 0; LdapAttrMask attrBits = 0; CERTSignedCrl *nssCrl = NULL; PKIX_PL_LdapResponse *response = NULL; PKIX_List *crlList = NULL; PKIX_PL_CRL *crl = NULL; LDAPMessage *message = NULL; LDAPSearchResponseEntry *sre = NULL; LDAPSearchResponseAttr **sreAttrArray = NULL; LDAPSearchResponseAttr *sreAttr = NULL; SECItem *attrType = NULL; SECItem **attrVal = NULL; SECItem *derCrlCopy = NULL; SECItem *derCrlItem = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCrlList"); PKIX_NULLCHECK_TWO(responseList, pCrls); PKIX_CHECK(PKIX_List_Create(&crlList, plContext), PKIX_LISTCREATEFAILED); /* extract crls from response */ PKIX_CHECK(PKIX_List_GetLength (responseList, &numResponses, plContext), PKIX_LISTGETLENGTHFAILED); for (respIx = 0; respIx < numResponses; respIx++) { PKIX_CHECK(PKIX_List_GetItem (responseList, respIx, (PKIX_PL_Object **)&response, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK(pkix_pl_LdapResponse_GetMessage (response, &message, plContext), PKIX_LDAPRESPONSEGETMESSAGEFAILED); sre = &(message->protocolOp.op.searchResponseEntryMsg); sreAttrArray = sre->attributes; /* Get next element of null-terminated array */ sreAttr = *sreAttrArray++; while (sreAttr != NULL) { attrType = &(sreAttr->attrType); PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit (attrType, &attrBits, plContext), PKIX_LDAPREQUESTATTRTYPETOBITFAILED); /* Is this attrVal a Revocation List? */ if (((LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST) & attrBits) == attrBits) { attrVal = sreAttr->val; derCrlItem = *attrVal++; while (derCrlItem != 0) { /* create a PKIX_PL_Crl from derCrl */ derCrlCopy = SECITEM_DupItem(derCrlItem); if (!derCrlCopy) { PKIX_ERROR(PKIX_ALLOCERROR); } /* crl will be based on derCrlCopy, but wont * own the der. */ nssCrl = CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE, CRL_DECODE_DONT_COPY_DER | CRL_DECODE_SKIP_ENTRIES); if (!nssCrl) { SECITEM_FreeItem(derCrlCopy, PKIX_TRUE); continue; } /* pkix crl own the der. */ PKIX_CHECK( pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, NULL, &crl, plContext), PKIX_CRLCREATEWITHSIGNEDCRLFAILED); /* Left control over memory pointed by derCrlCopy and * nssCrl to pkix crl. */ derCrlCopy = NULL; nssCrl = NULL; PKIX_CHECK(PKIX_List_AppendItem (crlList, (PKIX_PL_Object *) crl, plContext), PKIX_LISTAPPENDITEMFAILED); PKIX_DECREF(crl); derCrlItem = *attrVal++; } /* Clean up after PKIX_CHECK_ONLY_FATAL */ pkixTempErrorReceived = PKIX_FALSE; } sreAttr = *sreAttrArray++; } PKIX_DECREF(response); } *pCrls = crlList; crlList = NULL; cleanup: if (derCrlCopy) { SECITEM_FreeItem(derCrlCopy, PKIX_TRUE); } if (nssCrl) { SEC_DestroyCrl(nssCrl); } PKIX_DECREF(crl); PKIX_DECREF(crlList); PKIX_DECREF(response); PKIX_RETURN(CERTSTORE); }
static int nss_load_crl(const char* crlfilename, PRBool ascii) { PRFileDesc *infile; PRStatus prstat; PRFileInfo info; PRInt32 nb; int rv; SECItem crlDER; CERTSignedCrl *crl=NULL; PK11SlotInfo *slot=NULL; infile = PR_Open(crlfilename,PR_RDONLY,0); if (!infile) { return 0; } crlDER.data = NULL; prstat = PR_GetOpenFileInfo(infile,&info); if (prstat!=PR_SUCCESS) return 0; if (ascii) { SECItem filedata; char *asc,*body; filedata.data = NULL; if (!SECITEM_AllocItem(NULL,&filedata,info.size)) return 0; nb = PR_Read(infile,filedata.data,info.size); if (nb!=info.size) return 0; asc = (char*)filedata.data; if (!asc) return 0; body=strstr(asc,"-----BEGIN"); if (body != NULL) { char *trailer=NULL; asc = body; body = PORT_Strchr(asc,'\n'); if (!body) body = PORT_Strchr(asc,'\r'); if (body) trailer = strstr(++body,"-----END"); if (trailer!=NULL) *trailer='\0'; else return 0; } else { body = asc; } rv = ATOB_ConvertAsciiToItem(&crlDER,body); PORT_Free(filedata.data); if (rv) return 0; } else { if (!SECITEM_AllocItem(NULL,&crlDER,info.size)) return 0; nb = PR_Read(infile,crlDER.data,info.size); if (nb!=info.size) return 0; } slot = PK11_GetInternalKeySlot(); crl = PK11_ImportCRL(slot,&crlDER, NULL,SEC_CRL_TYPE, NULL,CRL_IMPORT_DEFAULT_OPTIONS, NULL,(CRL_DECODE_DEFAULT_OPTIONS| CRL_DECODE_DONT_COPY_DER)); if (slot) PK11_FreeSlot(slot); if (!crl) return 0; SEC_DestroyCrl(crl); return 1; }