Home | History | Annotate | Download | only in crypto
      1 // Copyright (c) 2012 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 #include "crypto/rsa_private_key.h"
     15 
     16 namespace crypto {
     17 
     18 SignatureCreator::~SignatureCreator() {
     19   if (sign_context_) {
     20     SGN_DestroyContext(sign_context_, PR_TRUE);
     21     sign_context_ = NULL;
     22   }
     23 }
     24 
     25 // static
     26 SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
     27   scoped_ptr<SignatureCreator> result(new SignatureCreator);
     28   result->key_ = key;
     29 
     30   result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
     31       key->key());
     32   if (!result->sign_context_) {
     33     NOTREACHED();
     34     return NULL;
     35   }
     36 
     37   SECStatus rv = SGN_Begin(result->sign_context_);
     38   if (rv != SECSuccess) {
     39     NOTREACHED();
     40     return NULL;
     41   }
     42 
     43   return result.release();
     44 }
     45 
     46 // static
     47 bool SignatureCreator::Sign(RSAPrivateKey* key,
     48                             const uint8* data,
     49                             int data_len,
     50                             std::vector<uint8>* signature) {
     51   SECItem data_item;
     52   data_item.type = siBuffer;
     53   data_item.data = const_cast<unsigned char*>(data);
     54   data_item.len = data_len;
     55 
     56   SECItem signature_item;
     57   SECStatus rv = SGN_Digest(key->key(), SEC_OID_SHA1, &signature_item,
     58                             &data_item);
     59   if (rv != SECSuccess) {
     60     NOTREACHED();
     61     return false;
     62   }
     63   signature->assign(signature_item.data,
     64                     signature_item.data + signature_item.len);
     65   SECITEM_FreeItem(&signature_item, PR_FALSE);
     66   return true;
     67 }
     68 
     69 bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
     70   SECStatus rv = SGN_Update(sign_context_, data_part, data_part_len);
     71   if (rv != SECSuccess) {
     72     NOTREACHED();
     73     return false;
     74   }
     75 
     76   return true;
     77 }
     78 
     79 bool SignatureCreator::Final(std::vector<uint8>* signature) {
     80   SECItem signature_item;
     81   SECStatus rv = SGN_End(sign_context_, &signature_item);
     82   if (rv != SECSuccess) {
     83     return false;
     84   }
     85   signature->assign(signature_item.data,
     86                     signature_item.data + signature_item.len);
     87   SECITEM_FreeItem(&signature_item, PR_FALSE);
     88   return true;
     89 }
     90 
     91 SignatureCreator::SignatureCreator()
     92     : key_(NULL),
     93       sign_context_(NULL) {
     94   EnsureNSSInit();
     95 }
     96 
     97 }  // namespace crypto
     98