diff options
author | eroman <eroman@chromium.org> | 2014-10-17 18:12:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-18 01:12:44 +0000 |
commit | 72ce4c6db27260e429a2269cf4ddcb59e9ba2581 (patch) | |
tree | 3496f7b2f8b3357bed92307918697d33df0db64d | |
parent | 1030b8fdea68fc3eaacde474fb57742e37e249f4 (diff) | |
download | chromium_src-72ce4c6db27260e429a2269cf4ddcb59e9ba2581.zip chromium_src-72ce4c6db27260e429a2269cf4ddcb59e9ba2581.tar.gz chromium_src-72ce4c6db27260e429a2269cf4ddcb59e9ba2581.tar.bz2 |
[webcrypto] Refactor RSA-SSA signing.
This extracts the signing/verification functions, so the subsequent RSA-PSS changelist is easier to follow.
BUG=399090
Review URL: https://codereview.chromium.org/662533002
Cr-Commit-Position: refs/heads/master@{#300194}
-rw-r--r-- | content/child/webcrypto/openssl/rsa_sign_openssl.cc | 105 | ||||
-rw-r--r-- | content/child/webcrypto/openssl/rsa_sign_openssl.h | 38 | ||||
-rw-r--r-- | content/child/webcrypto/openssl/rsa_ssa_openssl.cc | 79 | ||||
-rw-r--r-- | content/content_child.gypi | 2 |
4 files changed, 148 insertions, 76 deletions
diff --git a/content/child/webcrypto/openssl/rsa_sign_openssl.cc b/content/child/webcrypto/openssl/rsa_sign_openssl.cc new file mode 100644 index 0000000..b77aed1 --- /dev/null +++ b/content/child/webcrypto/openssl/rsa_sign_openssl.cc @@ -0,0 +1,105 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/webcrypto/crypto_data.h" +#include "content/child/webcrypto/openssl/key_openssl.h" +#include "content/child/webcrypto/openssl/rsa_key_openssl.h" +#include "content/child/webcrypto/openssl/rsa_sign_openssl.h" +#include "content/child/webcrypto/openssl/util_openssl.h" +#include "content/child/webcrypto/status.h" +#include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" +#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" + +namespace content { + +namespace webcrypto { + +namespace { + +// Extracts the OpenSSL key and digest from a WebCrypto key. The returned +// pointers will remain valid as long as |key| is alive. +Status GetPKeyAndDigest(const blink::WebCryptoKey& key, + EVP_PKEY** pkey, + const EVP_MD** digest) { + *pkey = AsymKeyOpenSsl::Cast(key)->key(); + + *digest = GetDigest(key.algorithm().rsaHashedParams()->hash().id()); + if (!*digest) + return Status::ErrorUnsupported(); + + return Status::Success(); +} + +} // namespace + +Status RsaSign(const blink::WebCryptoKey& key, + const CryptoData& data, + std::vector<uint8_t>* buffer) { + if (key.type() != blink::WebCryptoKeyTypePrivate) + return Status::ErrorUnexpectedKeyType(); + + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); + crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); + + EVP_PKEY* private_key = NULL; + const EVP_MD* digest = NULL; + Status status = GetPKeyAndDigest(key, &private_key, &digest); + if (status.IsError()) + return status; + + // NOTE: A call to EVP_DigestSignFinal() with a NULL second parameter + // returns a maximum allocation size, while the call without a NULL returns + // the real one, which may be smaller. + size_t sig_len = 0; + if (!ctx.get() || + !EVP_DigestSignInit(ctx.get(), NULL, digest, NULL, private_key) || + !EVP_DigestSignUpdate(ctx.get(), data.bytes(), data.byte_length()) || + !EVP_DigestSignFinal(ctx.get(), NULL, &sig_len)) { + return Status::OperationError(); + } + + buffer->resize(sig_len); + if (!EVP_DigestSignFinal(ctx.get(), &buffer->front(), &sig_len)) + return Status::OperationError(); + + buffer->resize(sig_len); + return Status::Success(); +} + +Status RsaVerify(const blink::WebCryptoKey& key, + const CryptoData& signature, + const CryptoData& data, + bool* signature_match) { + if (key.type() != blink::WebCryptoKeyTypePublic) + return Status::ErrorUnexpectedKeyType(); + + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); + crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); + + EVP_PKEY* public_key = NULL; + const EVP_MD* digest = NULL; + Status status = GetPKeyAndDigest(key, &public_key, &digest); + if (status.IsError()) + return status; + + if (!EVP_DigestVerifyInit(ctx.get(), NULL, digest, NULL, public_key)) + return Status::OperationError(); + + if (!EVP_DigestVerifyUpdate(ctx.get(), data.bytes(), data.byte_length())) + return Status::OperationError(); + + // Note that the return value can be: + // 1 --> Success + // 0 --> Verification failed + // <0 --> Operation error + int rv = EVP_DigestVerifyFinal( + ctx.get(), signature.bytes(), signature.byte_length()); + *signature_match = rv == 1; + return rv >= 0 ? Status::Success() : Status::OperationError(); +} + +} // namespace webcrypto + +} // namespace content diff --git a/content/child/webcrypto/openssl/rsa_sign_openssl.h b/content/child/webcrypto/openssl/rsa_sign_openssl.h new file mode 100644 index 0000000..d180ab4 --- /dev/null +++ b/content/child/webcrypto/openssl/rsa_sign_openssl.h @@ -0,0 +1,38 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_CHILD_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_ +#define CONTENT_CHILD_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_ + +#include <stdint.h> + +#include <vector> + +namespace blink { +class WebCryptoKey; +} + +namespace content { + +namespace webcrypto { + +class CryptoData; +class Status; + +// Helper functions for doing RSA-SSA signing and verification. + +Status RsaSign(const blink::WebCryptoKey& key, + const CryptoData& data, + std::vector<uint8_t>* buffer); + +Status RsaVerify(const blink::WebCryptoKey& key, + const CryptoData& signature, + const CryptoData& data, + bool* signature_match); + +} // namespace webcrypto + +} // namespace content + +#endif // CONTENT_CHILD_WEBCRYPTO_OPENSSL_RSA_SIGN_OPENSSL_H_ diff --git a/content/child/webcrypto/openssl/rsa_ssa_openssl.cc b/content/child/webcrypto/openssl/rsa_ssa_openssl.cc index fc574cd..be974cc 100644 --- a/content/child/webcrypto/openssl/rsa_ssa_openssl.cc +++ b/content/child/webcrypto/openssl/rsa_ssa_openssl.cc @@ -2,14 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/child/webcrypto/crypto_data.h" -#include "content/child/webcrypto/openssl/key_openssl.h" #include "content/child/webcrypto/openssl/rsa_key_openssl.h" -#include "content/child/webcrypto/openssl/util_openssl.h" +#include "content/child/webcrypto/openssl/rsa_sign_openssl.h" #include "content/child/webcrypto/status.h" -#include "crypto/openssl_util.h" -#include "crypto/scoped_openssl_types.h" -#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" namespace content { @@ -17,20 +12,6 @@ namespace webcrypto { namespace { -// Extracts the OpenSSL key and digest from a WebCrypto key. The returned -// pointers will remain valid as long as |key| is alive. -Status GetPKeyAndDigest(const blink::WebCryptoKey& key, - EVP_PKEY** pkey, - const EVP_MD** digest) { - *pkey = AsymKeyOpenSsl::Cast(key)->key(); - - *digest = GetDigest(key.algorithm().rsaHashedParams()->hash().id()); - if (!*digest) - return Status::ErrorUnsupported(); - - return Status::Success(); -} - class RsaSsaImplementation : public RsaHashedAlgorithm { public: RsaSsaImplementation() @@ -57,35 +38,7 @@ class RsaSsaImplementation : public RsaHashedAlgorithm { const blink::WebCryptoKey& key, const CryptoData& data, std::vector<uint8_t>* buffer) const override { - if (key.type() != blink::WebCryptoKeyTypePrivate) - return Status::ErrorUnexpectedKeyType(); - - crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); - - EVP_PKEY* private_key = NULL; - const EVP_MD* digest = NULL; - Status status = GetPKeyAndDigest(key, &private_key, &digest); - if (status.IsError()) - return status; - - // NOTE: A call to EVP_DigestSignFinal() with a NULL second parameter - // returns a maximum allocation size, while the call without a NULL returns - // the real one, which may be smaller. - size_t sig_len = 0; - if (!ctx.get() || - !EVP_DigestSignInit(ctx.get(), NULL, digest, NULL, private_key) || - !EVP_DigestSignUpdate(ctx.get(), data.bytes(), data.byte_length()) || - !EVP_DigestSignFinal(ctx.get(), NULL, &sig_len)) { - return Status::OperationError(); - } - - buffer->resize(sig_len); - if (!EVP_DigestSignFinal(ctx.get(), &buffer->front(), &sig_len)) - return Status::OperationError(); - - buffer->resize(sig_len); - return Status::Success(); + return RsaSign(key, data, buffer); } virtual Status Verify(const blink::WebCryptoAlgorithm& algorithm, @@ -93,33 +46,7 @@ class RsaSsaImplementation : public RsaHashedAlgorithm { const CryptoData& signature, const CryptoData& data, bool* signature_match) const override { - if (key.type() != blink::WebCryptoKeyTypePublic) - return Status::ErrorUnexpectedKeyType(); - - crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); - - EVP_PKEY* public_key = NULL; - const EVP_MD* digest = NULL; - Status status = GetPKeyAndDigest(key, &public_key, &digest); - if (status.IsError()) - return status; - - if (!EVP_DigestVerifyInit(ctx.get(), NULL, digest, NULL, public_key)) - return Status::OperationError(); - - if (!EVP_DigestVerifyUpdate(ctx.get(), data.bytes(), data.byte_length())) { - return Status::OperationError(); - } - - // Note that the return value can be: - // 1 --> Success - // 0 --> Verification failed - // <0 --> Operation error - int rv = EVP_DigestVerifyFinal( - ctx.get(), signature.bytes(), signature.byte_length()); - *signature_match = rv == 1; - return rv >= 0 ? Status::Success() : Status::OperationError(); + return RsaVerify(key, signature, data, signature_match); } }; diff --git a/content/content_child.gypi b/content/content_child.gypi index e2d0610..f99b61e 100644 --- a/content/content_child.gypi +++ b/content/content_child.gypi @@ -284,6 +284,8 @@ 'child/webcrypto/openssl/rsa_key_openssl.cc', 'child/webcrypto/openssl/rsa_key_openssl.h', 'child/webcrypto/openssl/rsa_oaep_openssl.cc', + 'child/webcrypto/openssl/rsa_sign_openssl.cc', + 'child/webcrypto/openssl/rsa_sign_openssl.h', 'child/webcrypto/openssl/rsa_ssa_openssl.cc', 'child/webcrypto/openssl/sha_openssl.cc', 'child/webcrypto/openssl/sym_key_openssl.cc', |