// Copyright (c) 2012 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 "crypto/ec_signature_creator_impl.h" #include #include #include #include #include #include #include #include "base/logging.h" #include "crypto/ec_private_key.h" #include "crypto/openssl_util.h" #include "crypto/scoped_openssl_types.h" namespace crypto { ECSignatureCreatorImpl::ECSignatureCreatorImpl(ECPrivateKey* key) : key_(key) { EnsureOpenSSLInit(); } ECSignatureCreatorImpl::~ECSignatureCreatorImpl() {} bool ECSignatureCreatorImpl::Sign(const uint8_t* data, int data_len, std::vector* signature) { OpenSSLErrStackTracer err_tracer(FROM_HERE); ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); size_t sig_len = 0; if (!ctx.get() || !EVP_DigestSignInit(ctx.get(), NULL, EVP_sha256(), NULL, key_->key()) || !EVP_DigestSignUpdate(ctx.get(), data, data_len) || !EVP_DigestSignFinal(ctx.get(), NULL, &sig_len)) { return false; } signature->resize(sig_len); if (!EVP_DigestSignFinal(ctx.get(), &signature->front(), &sig_len)) return false; // 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. signature->resize(sig_len); return true; } bool ECSignatureCreatorImpl::DecodeSignature( const std::vector& der_sig, std::vector* out_raw_sig) { OpenSSLErrStackTracer err_tracer(FROM_HERE); // Create ECDSA_SIG object from DER-encoded data. ScopedECDSA_SIG ecdsa_sig( ECDSA_SIG_from_bytes(der_sig.data(), der_sig.size())); if (!ecdsa_sig.get()) return false; // The result is made of two 32-byte vectors. const size_t kMaxBytesPerBN = 32; std::vector result(2 * kMaxBytesPerBN); if (!BN_bn2bin_padded(&result[0], kMaxBytesPerBN, ecdsa_sig->r) || !BN_bn2bin_padded(&result[kMaxBytesPerBN], kMaxBytesPerBN, ecdsa_sig->s)) { return false; } out_raw_sig->swap(result); return true; } } // namespace crypto