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 <cryptohi.h> 8 #include <keyhi.h> 9 #include <stdlib.h> 10 11 #include "base/logging.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "crypto/nss_util.h" 14 #include "crypto/rsa_private_key.h" 15 16 namespace crypto { 17 18 SignatureCreator::~SignatureCreator() { 19 if (sign_context_) { 20 SGN_DestroyContext(sign_context_, PR_TRUE); 21 sign_context_ = NULL; 22 } 23 } 24 25 // static 26 SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { 27 scoped_ptr<SignatureCreator> result(new SignatureCreator); 28 result->key_ = key; 29 30 result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, 31 key->key()); 32 if (!result->sign_context_) { 33 NOTREACHED(); 34 return NULL; 35 } 36 37 SECStatus rv = SGN_Begin(result->sign_context_); 38 if (rv != SECSuccess) { 39 NOTREACHED(); 40 return NULL; 41 } 42 43 return result.release(); 44 } 45 46 // static 47 bool SignatureCreator::Sign(RSAPrivateKey* key, 48 const uint8* data, 49 int data_len, 50 std::vector<uint8>* signature) { 51 SECItem data_item; 52 data_item.type = siBuffer; 53 data_item.data = const_cast<unsigned char*>(data); 54 data_item.len = data_len; 55 56 SECItem signature_item; 57 SECStatus rv = SGN_Digest(key->key(), SEC_OID_SHA1, &signature_item, 58 &data_item); 59 if (rv != SECSuccess) { 60 NOTREACHED(); 61 return false; 62 } 63 signature->assign(signature_item.data, 64 signature_item.data + signature_item.len); 65 SECITEM_FreeItem(&signature_item, PR_FALSE); 66 return true; 67 } 68 69 bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { 70 SECStatus rv = SGN_Update(sign_context_, data_part, data_part_len); 71 if (rv != SECSuccess) { 72 NOTREACHED(); 73 return false; 74 } 75 76 return true; 77 } 78 79 bool SignatureCreator::Final(std::vector<uint8>* signature) { 80 SECItem signature_item; 81 SECStatus rv = SGN_End(sign_context_, &signature_item); 82 if (rv != SECSuccess) { 83 return false; 84 } 85 signature->assign(signature_item.data, 86 signature_item.data + signature_item.len); 87 SECITEM_FreeItem(&signature_item, PR_FALSE); 88 return true; 89 } 90 91 SignatureCreator::SignatureCreator() 92 : key_(NULL), 93 sign_context_(NULL) { 94 EnsureNSSInit(); 95 } 96 97 } // namespace crypto 98