Example #1
0
SECStatus
CheckPublicKeySize(const SECItem& subjectPublicKeyInfo,
                   /*out*/ ScopedSECKeyPublicKey& publicKey)
{
  ScopedPtr<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>
    spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&subjectPublicKeyInfo));
  if (!spki) {
    return SECFailure;
  }
  publicKey = SECKEY_ExtractPublicKey(spki.get());
  if (!publicKey) {
    return SECFailure;
  }

  static const unsigned int MINIMUM_NON_ECC_BITS = 1024;

  switch (publicKey.get()->keyType) {
    case ecKey:
      // TODO(bug 622859): We should check which curve.
      return SECSuccess;
    case dsaKey: // fall through
    case rsaKey:
      // TODO(bug 622859): Enforce a minimum of 2048 bits for EV certs.
      if (SECKEY_PublicKeyStrengthInBits(publicKey.get()) < MINIMUM_NON_ECC_BITS) {
        // TODO(bug 1031946): Create a new error code.
        PR_SetError(SEC_ERROR_INVALID_KEY, 0);
        return SECFailure;
      }
      break;
    case nullKey:
    case fortezzaKey:
    case dhKey:
    case keaKey:
    case rsaPssKey:
    case rsaOaepKey:
    default:
      PR_SetError(SEC_ERROR_UNSUPPORTED_KEYALG, 0);
      return SECFailure;
  }

  return SECSuccess;
}
Example #2
0
Result
VerifySignedData(const SignedDataWithSignature& sd,
                 Input subjectPublicKeyInfo, void* pkcs11PinArg)
{
  // See bug 921585.
  if (sd.data.GetLength() >
        static_cast<unsigned int>(std::numeric_limits<int>::max())) {
    return Result::FATAL_ERROR_INVALID_ARGS;
  }

  SECOidTag pubKeyAlg;
  SECOidTag digestAlg;
  switch (sd.algorithm) {
    case SignatureAlgorithm::ecdsa_with_sha512:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::ecdsa_with_sha384:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::ecdsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::ecdsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha512:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha384:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha256:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha1:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::dsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::dsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA1;
      break;
    default:
      PR_NOT_REACHED("unknown signature algorithm");
      return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
  }

  Result rv;
  ScopedSECKeyPublicKey pubKey;
  rv = CheckPublicKeySize(subjectPublicKeyInfo, pubKey);
  if (rv != Success) {
    return rv;
  }

  // The static_cast is safe according to the check above that references
  // bug 921585.
  SECItem dataSECItem(UnsafeMapInputToSECItem(sd.data));
  SECItem signatureSECItem(UnsafeMapInputToSECItem(sd.signature));
  SECStatus srv = VFY_VerifyDataDirect(dataSECItem.data,
                                       static_cast<int>(dataSECItem.len),
                                       pubKey.get(), &signatureSECItem,
                                       pubKeyAlg, digestAlg, nullptr,
                                       pkcs11PinArg);
  if (srv != SECSuccess) {
    return MapPRErrorCodeToResult(PR_GetError());
  }

  return Success;
}
Example #3
0
SECStatus
VerifySignedData(const SignedDataWithSignature& sd,
                 const SECItem& subjectPublicKeyInfo, void* pkcs11PinArg)
{
  if (!sd.data.data || !sd.signature.data) {
    PR_NOT_REACHED("invalid args to VerifySignedData");
    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    return SECFailure;
  }

  // See bug 921585.
  if (sd.data.len > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
    return SECFailure;
  }

  SECOidTag pubKeyAlg;
  SECOidTag digestAlg;
  switch (sd.algorithm) {
    case SignatureAlgorithm::ecdsa_with_sha512:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::ecdsa_with_sha384:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::ecdsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::ecdsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha512:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha384:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha256:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha1:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::dsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::dsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA1;
      break;
    default:
      PR_NOT_REACHED("unknown signature algorithm");
      PR_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, 0);
      return SECFailure;
  }

  ScopedSECKeyPublicKey pubKey;
  if (CheckPublicKeySize(subjectPublicKeyInfo, pubKey) != SECSuccess) {
    return SECFailure;
  }

  // The static_cast is safe according to the check above that references
  // bug 921585.
  return VFY_VerifyDataDirect(sd.data.data, static_cast<int>(sd.data.len),
                              pubKey.get(), &sd.signature, pubKeyAlg,
                              digestAlg, nullptr, pkcs11PinArg);
}
Example #4
0
Result
VerifySignedData(const SignedDataWithSignature& sd,
                 Input subjectPublicKeyInfo, void* pkcs11PinArg)
{
  SECOidTag pubKeyAlg;
  SECOidTag digestAlg;
  switch (sd.algorithm) {
    case SignatureAlgorithm::ecdsa_with_sha512:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::ecdsa_with_sha384:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::ecdsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::ecdsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha512:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA512;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha384:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA384;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha256:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::rsa_pkcs1_with_sha1:
      pubKeyAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
      digestAlg = SEC_OID_SHA1;
      break;
    case SignatureAlgorithm::dsa_with_sha256:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA256;
      break;
    case SignatureAlgorithm::dsa_with_sha1:
      pubKeyAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
      digestAlg = SEC_OID_SHA1;
      break;
    default:
      PR_NOT_REACHED("unknown signature algorithm");
      return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
  }

  Result rv;
  ScopedSECKeyPublicKey pubKey;
  rv = CheckPublicKeySize(subjectPublicKeyInfo, pubKey);
  if (rv != Success) {
    return rv;
  }

  // The static_cast is safe as long as the length of the data in sd.data can
  // fit in an int. Right now that length is stored as a uint16_t, so this
  // works. In the future this may change, hence the assertion.
  // See also bug 921585.
  static_assert(sizeof(decltype(sd.data.GetLength())) < sizeof(int),
                "sd.data.GetLength() must fit in an int");
  SECItem dataSECItem(UnsafeMapInputToSECItem(sd.data));
  SECItem signatureSECItem(UnsafeMapInputToSECItem(sd.signature));
  SECStatus srv = VFY_VerifyDataDirect(dataSECItem.data,
                                       static_cast<int>(dataSECItem.len),
                                       pubKey.get(), &signatureSECItem,
                                       pubKeyAlg, digestAlg, nullptr,
                                       pkcs11PinArg);
  if (srv != SECSuccess) {
    return MapPRErrorCodeToResult(PR_GetError());
  }

  return Success;
}