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 <stdlib.h>
8
9#include "base/logging.h"
10#include "base/memory/scoped_ptr.h"
11#include "crypto/cssm_init.h"
12
13namespace crypto {
14
15// static
16SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
17  scoped_ptr<SignatureCreator> result(new SignatureCreator);
18  result->key_ = key;
19
20  CSSM_RETURN crtn;
21  crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(),
22                                         CSSM_ALGID_SHA1WithRSA,
23                                         NULL,
24                                         key->key(),
25                                         &result->sig_handle_);
26  if (crtn) {
27    NOTREACHED();
28    return NULL;
29  }
30
31  crtn = CSSM_SignDataInit(result->sig_handle_);
32  if (crtn) {
33    NOTREACHED();
34    return NULL;
35  }
36
37  return result.release();
38}
39
40SignatureCreator::SignatureCreator() : sig_handle_(0) {
41  EnsureCSSMInit();
42}
43
44SignatureCreator::~SignatureCreator() {
45  CSSM_RETURN crtn;
46  if (sig_handle_) {
47    crtn = CSSM_DeleteContext(sig_handle_);
48    DCHECK(crtn == CSSM_OK);
49  }
50}
51
52bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
53  CSSM_DATA data;
54  data.Data = const_cast<uint8*>(data_part);
55  data.Length = data_part_len;
56  CSSM_RETURN crtn = CSSM_SignDataUpdate(sig_handle_, &data, 1);
57  DCHECK(crtn == CSSM_OK);
58  return true;
59}
60
61bool SignatureCreator::Final(std::vector<uint8>* signature) {
62  ScopedCSSMData sig;
63  CSSM_RETURN crtn = CSSM_SignDataFinal(sig_handle_, sig);
64
65  if (crtn) {
66    NOTREACHED();
67    return false;
68  }
69
70  signature->assign(sig->Data, sig->Data + sig->Length);
71  return true;
72}
73
74}  // namespace crypto
75