1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/signature_creator.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <cryptohi.h>
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <keyhi.h>
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto {
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSignatureCreator::~SignatureCreator() {
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (sign_context_) {
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SGN_DestroyContext(sign_context_, PR_TRUE);
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sign_context_ = NULL;
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<SignatureCreator> result(new SignatureCreator);
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result->key_ = key;
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      key->key());
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!result->sign_context_) {
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED();
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SECStatus rv = SGN_Begin(result->sign_context_);
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv != SECSuccess) {
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED();
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return result.release();
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(wtc): Remove this const_cast when we require NSS 3.12.5.
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SECStatus rv = SGN_Update(sign_context_,
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            const_cast<unsigned char*>(data_part),
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            data_part_len);
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv != SECSuccess) {
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED();
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SignatureCreator::Final(std::vector<uint8>* signature) {
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SECItem signature_item;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SECStatus rv = SGN_End(sign_context_, &signature_item);
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (rv != SECSuccess) {
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED();
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  signature->assign(signature_item.data,
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    signature_item.data + signature_item.len);
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  SECITEM_FreeItem(&signature_item, PR_FALSE);
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSignatureCreator::SignatureCreator() : sign_context_(NULL) {
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EnsureNSSInit();
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace crypto
77