summaryrefslogtreecommitdiffstats
path: root/crypto/signature_creator_mac.cc
blob: fa0bded678b9cd1a2977cc5473656cdead54cb2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "crypto/signature_creator.h"

#include <stdlib.h>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/cssm_init.h"

namespace crypto {

// static
SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
  scoped_ptr<SignatureCreator> result(new SignatureCreator);
  result->key_ = key;

  CSSM_RETURN crtn;
  crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(),
                                         CSSM_ALGID_SHA1WithRSA,
                                         NULL,
                                         key->key(),
                                         &result->sig_handle_);
  if (crtn) {
    NOTREACHED();
    return NULL;
  }

  crtn = CSSM_SignDataInit(result->sig_handle_);
  if (crtn) {
    NOTREACHED();
    return NULL;
  }

  return result.release();
}

SignatureCreator::SignatureCreator() : sig_handle_(0) {
  EnsureCSSMInit();
}

SignatureCreator::~SignatureCreator() {
  CSSM_RETURN crtn;
  if (sig_handle_) {
    crtn = CSSM_DeleteContext(sig_handle_);
    DCHECK(crtn == CSSM_OK);
  }
}

bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
  CSSM_DATA data;
  data.Data = const_cast<uint8*>(data_part);
  data.Length = data_part_len;
  CSSM_RETURN crtn = CSSM_SignDataUpdate(sig_handle_, &data, 1);
  DCHECK(crtn == CSSM_OK);
  return true;
}

bool SignatureCreator::Final(std::vector<uint8>* signature) {
  ScopedCSSMData sig;
  CSSM_RETURN crtn = CSSM_SignDataFinal(sig_handle_, sig);

  if (crtn) {
    NOTREACHED();
    return false;
  }

  signature->assign(sig->Data, sig->Data + sig->Length);
  return true;
}

}  // namespace crypto