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 18 namespace crypto { 19 20 namespace { 21 22 const 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 32 int 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 45 SignatureCreator* 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 62 bool 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 82 SignatureCreator::SignatureCreator() 83 : sign_context_(EVP_MD_CTX_create()) { 84 } 85 86 SignatureCreator::~SignatureCreator() { 87 EVP_MD_CTX_destroy(sign_context_); 88 } 89 90 bool 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 95 bool 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