Example #1
0
/* would not do name in pluto, but dn */
static CERTCertList *get_trust_certlist(CERTCertDBHandle *handle,
				     const char *name)
{
	CERTCertList *trustcl = NULL;
	CERTCertList *tmpcl = NULL;
	CERTCertificate *ca = NULL;
	CERTCertListNode *node = NULL;

	if ((ca = CERT_FindCertByNickname(handle, name)) == NULL) {
		printf("CERT_FindCertByNickname failed %d\n",
				PORT_GetError());
		return NULL;
	}

	if (ca->isRoot) {
		printf("trust anchor: %s\n",ca->subjectName);
		trustcl = CERT_NewCertList();
		CERT_AddCertToListTail(trustcl, ca);
	} else {
		tmpcl = CERT_GetCertChainFromCert(ca, PR_Now(), certUsageAnyCA);
		if (tmpcl == NULL) {
			printf("CERT_GetCertChainFromCert failed %d\n",
					PORT_GetError());
			return NULL;
		}
		for (node = CERT_LIST_HEAD(tmpcl); !CERT_LIST_END(node, tmpcl);
				node = CERT_LIST_NEXT(node)) {
			printf("CERT list: %s\n", node->cert->subjectName);
			if (node->cert->isRoot) {
				trustcl = CERT_NewCertList();
				CERT_AddCertToListTail(trustcl, node->cert);
				break;
			}
		}
	}

	if (trustcl == NULL || CERT_LIST_EMPTY(trustcl)) {
		printf("Trust chain empty!\n");
		return NULL;
	}

	return trustcl;
}
/** Compares the common name specified in the subject DN for a certificate
  * with a specified hostname.
  */
SECStatus
CERT_VerifyCertName(const CERTCertificate *cert, const char *hostname)
{
    LOG_DEBUG(">> CERT_VerifyCertName: %s", hostname);
    static SECStatus (*VerifyCertName)(CERTCertificate *cert,
                                       const char *hostname) = NULL;
    if (!VerifyCertName)
        VerifyCertName = getfunc("CERT_VerifyCertName", LIBNSS3);
    if (!VerifyCertName)
        return SECFailure;

    SECStatus ret = VerifyCertName(cert, hostname);
    LOG_DEBUG(">>> result = %d", ret);

    PATROL_init();
    if (!cfg.loaded)
        PATROL_get_config(&cfg);

    PRNetAddr addr;
    if (PR_SUCCESS != PR_GetPeerName(nss_fd, &addr))
        return ret;

    PatrolData *chain = NULL;
    size_t chain_len
        = PATROL_NSS_convert_chain(CERT_GetCertChainFromCert(cert, PR_Now(),
                                                             certUsageSSLCA),
                                   &chain);

    PatrolRC pret = PATROL_check(&cfg, chain, chain_len, PATROL_CERT_X509,
                                 ret == SECSuccess ? PATROL_OK : PATROL_ERROR,
                                 hostname, 0, "tcp", // FIXME
                                 PR_ntohs((addr.raw.family == PR_AF_INET6)
                                          ? addr.ipv6.port : addr.inet.port));
    LOG_DEBUG(">>> patrol result = %d", pret);

    free(chain);
    PATROL_deinit();

    return pret == PATROL_OK ? SECSuccess : SECFailure;
}
Example #3
0
/* 
 * nsIEnumerator getChain(); 
 */
NS_IMETHODIMP
nsNSSCertificate::GetChain(nsIArray **_rvChain)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  NS_ENSURE_ARG(_rvChain);
  nsresult rv;
  /* Get the cert chain from NSS */
  CERTCertList *nssChain = NULL;
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting chain for \"%s\"\n", mCert->nickname));
  nssChain = CERT_GetCertChainFromCert(mCert, PR_Now(), certUsageSSLClient);
  if (!nssChain)
    return NS_ERROR_FAILURE;
  /* enumerate the chain for scripting purposes */
  nsCOMPtr<nsIMutableArray> array =
    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
  if (NS_FAILED(rv)) { 
    goto done; 
  }
  CERTCertListNode *node;
  for (node = CERT_LIST_HEAD(nssChain);
       !CERT_LIST_END(node, nssChain);
       node = CERT_LIST_NEXT(node)) {
    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("adding %s to chain\n", node->cert->nickname));
    nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(node->cert);
    array->AppendElement(cert, false);
  }
  *_rvChain = array;
  NS_IF_ADDREF(*_rvChain);
  rv = NS_OK;
done:
  if (nssChain)
    CERT_DestroyCertList(nssChain);
  return rv;
}
Example #4
0
SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
                                              PRBool checksig, PRBool isServer) {
  nsNSSShutDownPreventionLock locker;

  // first the default action
  SECStatus rv = SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);

  // We want to remember the CA certs in the temp db, so that the application can find the
  // complete chain at any time it might need it.
  // But we keep only those CA certs in the temp db, that we didn't already know.
  
  CERTCertificate *serverCert = SSL_PeerCertificate(fd);
  CERTCertificateCleaner serverCertCleaner(serverCert);

  if (serverCert) {
    nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
    nsRefPtr<nsSSLStatus> status = infoObject->SSLStatus();
    nsRefPtr<nsNSSCertificate> nsc;

    if (!status || !status->mServerCert) {
      nsc = new nsNSSCertificate(serverCert);
    }

    if (SECSuccess == rv) {
      if (nsc) {
        PRBool dummyIsEV;
        nsc->GetIsExtendedValidation(&dummyIsEV); // the nsc object will cache the status
      }
    
      CERTCertList *certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA);

      nsCOMPtr<nsINSSComponent> nssComponent;
      
      for (CERTCertListNode *node = CERT_LIST_HEAD(certList);
           !CERT_LIST_END(node, certList);
           node = CERT_LIST_NEXT(node)) {

        if (node->cert->slot) {
          // This cert was found on a token, no need to remember it in the temp db.
          continue;
        }

        if (node->cert->isperm) {
          // We don't need to remember certs already stored in perm db.
          continue;
        }
        
        if (node->cert == serverCert) {
          // We don't want to remember the server cert, 
          // the code that cares for displaying page info does this already.
          continue;
        }

        // We have found a signer cert that we want to remember.
        nsCAutoString nickname;
        nickname = nsNSSCertificate::defaultServerNickname(node->cert);
        if (!nickname.IsEmpty()) {
          PK11SlotInfo *slot = PK11_GetInternalKeySlot();
          if (slot) {
            PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, 
                            const_cast<char*>(nickname.get()), PR_FALSE);
            PK11_FreeSlot(slot);
          }
        }
      }

      CERT_DestroyCertList(certList);
    }

    // The connection may get terminated, for example, if the server requires
    // a client cert. Let's provide a minimal SSLStatus
    // to the caller that contains at least the cert and its status.
    if (!status) {
      status = new nsSSLStatus();
      infoObject->SetSSLStatus(status);
    }
    if (status && !status->mServerCert) {
      status->mServerCert = nsc;
      PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
             ("AuthCertificateCallback setting NEW cert %p\n", status->mServerCert.get()));
    }
  }

  return rv;
}
Example #5
0
static SECStatus
ClassicVerifyCert(CERTCertificate * cert,
                  const SECCertificateUsage usage,
                  const PRTime time,
                  nsIInterfaceRequestor * pinArg,
                  /*optional out*/ CERTCertList **validationChain,
                  /*optional out*/ CERTVerifyLog *verifyLog)
{
  SECStatus rv;
  SECCertUsage enumUsage;
  if (validationChain) {
    switch(usage){
      case  certificateUsageSSLClient:
        enumUsage = certUsageSSLClient;
        break;
      case  certificateUsageSSLServer:
        enumUsage = certUsageSSLServer;
        break;
      case certificateUsageSSLServerWithStepUp:
        enumUsage = certUsageSSLServerWithStepUp;
        break;
      case certificateUsageSSLCA:
        enumUsage = certUsageSSLCA;
        break;
      case certificateUsageEmailSigner:
        enumUsage = certUsageEmailSigner;
        break;
      case certificateUsageEmailRecipient:
        enumUsage = certUsageEmailRecipient;
        break;
      case certificateUsageObjectSigner:
        enumUsage = certUsageObjectSigner;
        break;
      case certificateUsageUserCertImport:
        enumUsage = certUsageUserCertImport;
        break;
      case certificateUsageVerifyCA:
        enumUsage = certUsageVerifyCA;
        break;
      case certificateUsageProtectedObjectSigner:
        enumUsage = certUsageProtectedObjectSigner;
        break;
      case certificateUsageStatusResponder:
        enumUsage = certUsageStatusResponder;
        break;
      case certificateUsageAnyCA:
        enumUsage = certUsageAnyCA;
        break;
       default:
        return SECFailure;
    }
  }
  if (usage == certificateUsageSSLServer) {
    /* SSL server cert verification has always used CERT_VerifyCert, so we
     * continue to use it for SSL cert verification to minimize the risk of
     * there being any differnce in results between CERT_VerifyCert and
     * CERT_VerifyCertificate.
     */
    rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), cert, true,
                         certUsageSSLServer, time, pinArg, verifyLog);
  } else {
    rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), cert, true,
                                usage, time, pinArg,
                                verifyLog, nullptr);
  }
  if (rv == SECSuccess && validationChain) {
    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: getting chain in 'classic' \n"));
    *validationChain = CERT_GetCertChainFromCert(cert, time, enumUsage);
    if (!*validationChain) {
      rv = SECFailure;
    }
  }
  return rv;
}