// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "verify_signed_data.h" #include <openssl/bytestring.h> #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/pki/signature_verify_cache.h> #include <openssl/rsa.h> #include <openssl/sha.h> #include "cert_errors.h" #include "input.h" #include "parse_values.h" #include "parser.h" #include "signature_algorithm.h" BSSL_NAMESPACE_BEGIN namespace { bool SHA256UpdateWithLengthPrefixedData(SHA256_CTX *s_ctx, const uint8_t *data, uint64_t length) { … } // Increase to make incompatible changes in the computation of the // cache key. constexpr uint32_t VerifyCacheKeyVersion = …; std::string SignatureVerifyCacheKey(std::string_view algorithm_name, der::Input signed_data, der::Input signature_value_bytes, EVP_PKEY *public_key) { … } // Place an instance of this class on the call stack to automatically clear // the OpenSSL error stack on function exit. // TODO(crbug.com/boringssl/38): Remove this when the library is more robust to // leaving things in the error queue. class OpenSSLErrStackTracer { … }; } // namespace // Parses an RSA public key or EC public key from SPKI to an EVP_PKEY. Returns // true on success. // // This function only recognizes the "pk-rsa" (rsaEncryption) flavor of RSA // public key from RFC 5912. // // pk-rsa PUBLIC-KEY ::= { // IDENTIFIER rsaEncryption // KEY RSAPublicKey // PARAMS TYPE NULL ARE absent // -- Private key format not in this module -- // CERT-KEY-USAGE {digitalSignature, nonRepudiation, // keyEncipherment, dataEncipherment, keyCertSign, cRLSign} // } // // COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value // of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent, // RFC 3279 says they must be NULL: // // The rsaEncryption OID is intended to be used in the algorithm field // of a value of type AlgorithmIdentifier. The parameters field MUST // have ASN.1 type NULL for this algorithm identifier. // // Following RFC 3279 in this case. // // In the case of parsing EC keys, RFC 5912 describes all the ECDSA // signature algorithms as requiring a public key of type "pk-ec": // // pk-ec PUBLIC-KEY ::= { // IDENTIFIER id-ecPublicKey // KEY ECPoint // PARAMS TYPE ECParameters ARE required // -- Private key format not in this module -- // CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyAgreement, // keyCertSign, cRLSign } // } // // Moreover RFC 5912 stipulates what curves are allowed. The ECParameters // MUST NOT use an implicitCurve or specificCurve for PKIX: // // ECParameters ::= CHOICE { // namedCurve CURVE.&id({NamedCurve}) // -- implicitCurve NULL // -- implicitCurve MUST NOT be used in PKIX // -- specifiedCurve SpecifiedCurve // -- specifiedCurve MUST NOT be used in PKIX // -- Details for specifiedCurve can be found in [X9.62] // -- Any future additions to this CHOICE should be coordinated // -- with ANSI X.9. // } // -- If you need to be able to decode ANSI X.9 parameter structures, // -- uncomment the implicitCurve and specifiedCurve above, and also // -- uncomment the following: // --(WITH COMPONENTS {namedCurve PRESENT}) // // The namedCurves are extensible. The ones described by RFC 5912 are: // // NamedCurve CURVE ::= { // { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } | // { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } | // { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } | // { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } | // { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 }, // ... -- Extensible // } bool ParsePublicKey(der::Input public_key_spki, bssl::UniquePtr<EVP_PKEY> *public_key) { … } bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data, const der::BitString &signature_value, EVP_PKEY *public_key, SignatureVerifyCache *cache) { … } bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data, const der::BitString &signature_value, der::Input public_key_spki, SignatureVerifyCache *cache) { … } BSSL_NAMESPACE_END