예제 #1
0
/**
 * 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;
}
예제 #2
0
파일: nss.c 프로젝트: 3s3s/simple_server
/* 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;
}
예제 #3
0
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);
}
예제 #4
0
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;
}
예제 #5
0
/*
 * 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);
}
예제 #6
0
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;
}
예제 #7
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);
}
예제 #8
0
/*
 * 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);
}
예제 #9
0
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);
}
예제 #10
0
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);
}
예제 #11
0
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;
}
예제 #12
0
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{
예제 #13
0
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);
}
예제 #15
0
파일: nss.c 프로젝트: 0w/moai-dev
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;
}