1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "crypto/signature_creator.h" 6 7#include <openssl/evp.h> 8#include <openssl/rsa.h> 9#include <stddef.h> 10#include <stdint.h> 11 12#include "base/logging.h" 13#include "base/memory/scoped_ptr.h" 14#include "crypto/openssl_util.h" 15#include "crypto/rsa_private_key.h" 16#include "crypto/scoped_openssl_types.h" 17 18namespace crypto { 19 20namespace { 21 22const EVP_MD* ToOpenSSLDigest(SignatureCreator::HashAlgorithm hash_alg) { 23 switch (hash_alg) { 24 case SignatureCreator::SHA1: 25 return EVP_sha1(); 26 case SignatureCreator::SHA256: 27 return EVP_sha256(); 28 } 29 return NULL; 30} 31 32int ToOpenSSLDigestType(SignatureCreator::HashAlgorithm hash_alg) { 33 switch (hash_alg) { 34 case SignatureCreator::SHA1: 35 return NID_sha1; 36 case SignatureCreator::SHA256: 37 return NID_sha256; 38 } 39 return NID_undef; 40} 41 42} // namespace 43 44// static 45SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key, 46 HashAlgorithm hash_alg) { 47 OpenSSLErrStackTracer err_tracer(FROM_HERE); 48 scoped_ptr<SignatureCreator> result(new SignatureCreator); 49 const EVP_MD* const digest = ToOpenSSLDigest(hash_alg); 50 DCHECK(digest); 51 if (!digest) { 52 return NULL; 53 } 54 if (!EVP_DigestSignInit(result->sign_context_, NULL, digest, NULL, 55 key->key())) { 56 return NULL; 57 } 58 return result.release(); 59} 60 61// static 62bool SignatureCreator::Sign(RSAPrivateKey* key, 63 HashAlgorithm hash_alg, 64 const uint8_t* data, 65 int data_len, 66 std::vector<uint8_t>* signature) { 67 ScopedRSA rsa_key(EVP_PKEY_get1_RSA(key->key())); 68 if (!rsa_key) 69 return false; 70 signature->resize(RSA_size(rsa_key.get())); 71 72 unsigned int len = 0; 73 if (!RSA_sign(ToOpenSSLDigestType(hash_alg), data, data_len, 74 signature->data(), &len, rsa_key.get())) { 75 signature->clear(); 76 return false; 77 } 78 signature->resize(len); 79 return true; 80} 81 82SignatureCreator::SignatureCreator() 83 : sign_context_(EVP_MD_CTX_create()) { 84} 85 86SignatureCreator::~SignatureCreator() { 87 EVP_MD_CTX_destroy(sign_context_); 88} 89 90bool SignatureCreator::Update(const uint8_t* data_part, int data_part_len) { 91 OpenSSLErrStackTracer err_tracer(FROM_HERE); 92 return !!EVP_DigestSignUpdate(sign_context_, data_part, data_part_len); 93} 94 95bool SignatureCreator::Final(std::vector<uint8_t>* signature) { 96 OpenSSLErrStackTracer err_tracer(FROM_HERE); 97 98 // Determine the maximum length of the signature. 99 size_t len = 0; 100 if (!EVP_DigestSignFinal(sign_context_, NULL, &len)) { 101 signature->clear(); 102 return false; 103 } 104 signature->resize(len); 105 106 // Sign it. 107 if (!EVP_DigestSignFinal(sign_context_, signature->data(), &len)) { 108 signature->clear(); 109 return false; 110 } 111 signature->resize(len); 112 return true; 113} 114 115} // namespace crypto 116