1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// found in the LICENSE file.
4513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/signature_creator.h"
6513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <openssl/evp.h>
8201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
9513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/logging.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/stl_util-inl.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/openssl_util.h"
13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto {
15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static
17513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  OpenSSLErrStackTracer err_tracer(FROM_HERE);
19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<SignatureCreator> result(new SignatureCreator);
20201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  result->key_ = key;
21201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!EVP_SignInit_ex(result->sign_context_, EVP_sha1(), NULL))
22201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return NULL;
23201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return result.release();
24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
26201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochSignatureCreator::SignatureCreator()
27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    : sign_context_(EVP_MD_CTX_create()) {
28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
30513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSignatureCreator::~SignatureCreator() {
31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EVP_MD_CTX_destroy(sign_context_);
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
34513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
35201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  OpenSSLErrStackTracer err_tracer(FROM_HERE);
36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return EVP_SignUpdate(sign_context_, data_part, data_part_len) == 1;
37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
39513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SignatureCreator::Final(std::vector<uint8>* signature) {
40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  OpenSSLErrStackTracer err_tracer(FROM_HERE);
41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EVP_PKEY* key = key_->key();
42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  signature->resize(EVP_PKEY_size(key));
43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  unsigned int len = 0;
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int rv = EVP_SignFinal(sign_context_, vector_as_array(signature), &len, key);
46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!rv) {
47201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    signature->clear();
48201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return false;
49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  signature->resize(len);
51201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return true;
52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace crypto
55