// Perform a hash of the provided cert, then search in the RootHashes.inc data
// structure for a matching bin number.
int32_t
RootCABinNumber(const SECItem* cert)
{
  Digest digest;

  // Compute SHA256 hash of the certificate
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->data, cert->len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return HASH_FAILURE;
  }

  // Compare against list of stored hashes
  size_t idx;

  PR_LOG(PublicKeyPinningTelemetryLog(), PR_LOG_DEBUG,
           ("pkpinTelem: First bytes %02hx %02hx %02hx %02hx\n",
            digest.get().data[0], digest.get().data[1], digest.get().data[2], digest.get().data[3]));

  if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
          BinaryHashSearchArrayComparator(
            reinterpret_cast<const uint8_t*>(digest.get().data), digest.get().len),
         &idx)) {

    PR_LOG(PublicKeyPinningTelemetryLog(), PR_LOG_DEBUG,
          ("pkpinTelem: Telemetry index was %lu, bin is %d\n",
           idx, ROOT_TABLE[idx].binNumber));
    return (int32_t) ROOT_TABLE[idx].binNumber;
  }

  // Didn't match.
  return UNKNOWN_ROOT;
}
// Perform a hash of the provided cert, then search in the RootHashes.inc data
// structure for a matching bin number.
int32_t
RootCABinNumber(const SECItem* cert)
{
  Digest digest;

  // Compute SHA256 hash of the certificate
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->data, cert->len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return ROOT_CERTIFICATE_HASH_FAILURE;
  }

  // Compare against list of stored hashes
  size_t idx;

  MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
           ("pkpinTelem: First bytes %02x %02x %02x %02x\n",
            digest.get().data[0], digest.get().data[1], digest.get().data[2], digest.get().data[3]));

  if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
        BinaryHashSearchArrayComparator(static_cast<uint8_t*>(digest.get().data),
                                        digest.get().len),
        &idx)) {

    MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
          ("pkpinTelem: Telemetry index was %" PRIuSIZE ", bin is %d\n",
           idx, ROOT_TABLE[idx].binNumber));
    return (int32_t) ROOT_TABLE[idx].binNumber;
  }

  // Didn't match.
  return ROOT_CERTIFICATE_UNKNOWN;
}
Example #3
0
nsresult
nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint, SECOidTag aHashAlg)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  aFingerprint.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(aHashAlg, mCert->derCert.data,
                                 mCert->derCert.len);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // CERT_Hexify's second argument is an int that is interpreted as a boolean
  char* fpStr = CERT_Hexify(const_cast<SECItem*>(&digest.get()), 1);
  if (!fpStr) {
    return NS_ERROR_FAILURE;
  }

  aFingerprint.AssignASCII(fpStr);
  PORT_Free(fpStr);
  return NS_OK;
}
NS_IMETHODIMP
nsDataSignatureVerifier::VerifySignature(const char* aRSABuf,
                                         uint32_t aRSABufLen,
                                         const char* aPlaintext,
                                         uint32_t aPlaintextLen,
                                         int32_t* aErrorCode,
                                         nsICertificatePrincipal** aPrincipal)
{
  if (!aPlaintext || !aPrincipal || !aErrorCode) {
    return NS_ERROR_INVALID_ARG;
  }

  *aErrorCode = VERIFY_ERROR_OTHER;
  *aPrincipal = nullptr;

  nsNSSShutDownPreventionLock locker;

  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA1,
                                 reinterpret_cast<const uint8_t*>(aPlaintext),
                                 aPlaintextLen);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  SECItem buffer = {
    siBuffer,
    reinterpret_cast<uint8_t*>(const_cast<char*>(aRSABuf)),
    aRSABufLen
  };

  VerifyCertificateContext context;
  // XXX: pinArg is missing
  rv = VerifyCMSDetachedSignatureIncludingCertificate(buffer, digest.get(),
                                                      VerifyCertificate,
                                                      &context, nullptr);
  if (NS_SUCCEEDED(rv)) {
    *aErrorCode = VERIFY_OK;
  } else if (NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_SECURITY) {
    if (rv == GetXPCOMFromNSSError(SEC_ERROR_UNKNOWN_ISSUER)) {
      *aErrorCode = VERIFY_ERROR_UNKNOWN_ISSUER;
    } else {
      *aErrorCode = VERIFY_ERROR_OTHER;
    }
    rv = NS_OK;
  }
  if (rv == NS_OK) {
    context.principal.forget(aPrincipal);
  }

  return rv;
}
/**
 Computes in the location specified by base64Out the SHA256 digest
 of the DER Encoded subject Public Key Info for the given cert
*/
static nsresult
GetBase64HashSPKI(const CERTCertificate* cert, nsACString& hashSPKIDigest)
{
  hashSPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->derPublicKey.data,
                                 cert->derPublicKey.len);
  if (NS_FAILED(rv)) {
    return rv;
  }
  return Base64Encode(nsDependentCSubstring(
                        reinterpret_cast<const char*>(digest.get().data),
                        digest.get().len),
                      hashSPKIDigest);
}
/**
 Computes in the location specified by base64Out the SHA256 digest
 of the DER Encoded subject Public Key Info for the given cert
*/
static SECStatus
GetBase64SHA256SPKI(const CERTCertificate* cert,
                    nsACString& aSha256SPKIDigest){
  aSha256SPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->derPublicKey.data,
                                 cert->derPublicKey.len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return SECFailure;
  }
  rv = Base64Encode(nsDependentCSubstring(
                      reinterpret_cast<const char*>(digest.get().data),
                      digest.get().len),
                      aSha256SPKIDigest);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return SECFailure;
  }
  return SECSuccess;
}
Example #7
0
NS_IMETHODIMP
nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(nsACString& aSha256SPKIDigest)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  aSha256SPKIDigest.Truncate();
  Digest digest;
  nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mCert->derPublicKey.data,
                                 mCert->derPublicKey.len);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  rv = Base64Encode(nsDependentCSubstring(
                      reinterpret_cast<const char*> (digest.get().data),
                      digest.get().len),
                    aSha256SPKIDigest);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  return NS_OK;
}