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