• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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 "base/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/nss_util.h"
13 #include "base/scoped_ptr.h"
14 
15 namespace base {
16 
17 // static
Create(RSAPrivateKey * key)18 SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
19   scoped_ptr<SignatureCreator> result(new SignatureCreator);
20   result->key_ = key;
21 
22   result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
23       key->key());
24   if (!result->sign_context_) {
25     NOTREACHED();
26     return NULL;
27   }
28 
29   SECStatus rv = SGN_Begin(result->sign_context_);
30   if (rv != SECSuccess) {
31     NOTREACHED();
32     return NULL;
33   }
34 
35   return result.release();
36 }
37 
SignatureCreator()38 SignatureCreator::SignatureCreator() : sign_context_(NULL) {
39   EnsureNSSInit();
40 }
41 
~SignatureCreator()42 SignatureCreator::~SignatureCreator() {
43   if (sign_context_) {
44     SGN_DestroyContext(sign_context_, PR_TRUE);
45     sign_context_ = NULL;
46   }
47 }
48 
Update(const uint8 * data_part,int data_part_len)49 bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
50   // TODO(wtc): Remove this const_cast when we require NSS 3.12.5.
51   // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255
52   SECStatus rv = SGN_Update(sign_context_,
53                             const_cast<unsigned char*>(data_part),
54                             data_part_len);
55   if (rv != SECSuccess) {
56     NOTREACHED();
57     return false;
58   }
59 
60   return true;
61 }
62 
Final(std::vector<uint8> * signature)63 bool SignatureCreator::Final(std::vector<uint8>* signature) {
64   SECItem signature_item;
65   SECStatus rv = SGN_End(sign_context_, &signature_item);
66   if (rv != SECSuccess) {
67     NOTREACHED();
68     return false;
69   }
70   signature->assign(signature_item.data,
71                     signature_item.data + signature_item.len);
72   SECITEM_FreeItem(&signature_item, PR_FALSE);
73   return true;
74 }
75 
76 }  // namespace base
77