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; }
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; }