Home | History | Annotate | Download | only in crypto
      1 // Copyright (c) 2009 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 "base/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/nss_util.h"
     13 #include "base/scoped_ptr.h"
     14 
     15 namespace base {
     16 
     17 // static
     18 SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
     19   scoped_ptr<SignatureCreator> result(new SignatureCreator);
     20   result->key_ = key;
     21 
     22   result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
     23       key->key());
     24   if (!result->sign_context_) {
     25     NOTREACHED();
     26     return NULL;
     27   }
     28 
     29   SECStatus rv = SGN_Begin(result->sign_context_);
     30   if (rv != SECSuccess) {
     31     NOTREACHED();
     32     return NULL;
     33   }
     34 
     35   return result.release();
     36 }
     37 
     38 SignatureCreator::SignatureCreator() : sign_context_(NULL) {
     39   EnsureNSSInit();
     40 }
     41 
     42 SignatureCreator::~SignatureCreator() {
     43   if (sign_context_) {
     44     SGN_DestroyContext(sign_context_, PR_TRUE);
     45     sign_context_ = NULL;
     46   }
     47 }
     48 
     49 bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
     50   // TODO(wtc): Remove this const_cast when we require NSS 3.12.5.
     51   // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255
     52   SECStatus rv = SGN_Update(sign_context_,
     53                             const_cast<unsigned char*>(data_part),
     54                             data_part_len);
     55   if (rv != SECSuccess) {
     56     NOTREACHED();
     57     return false;
     58   }
     59 
     60   return true;
     61 }
     62 
     63 bool SignatureCreator::Final(std::vector<uint8>* signature) {
     64   SECItem signature_item;
     65   SECStatus rv = SGN_End(sign_context_, &signature_item);
     66   if (rv != SECSuccess) {
     67     NOTREACHED();
     68     return false;
     69   }
     70   signature->assign(signature_item.data,
     71                     signature_item.data + signature_item.len);
     72   SECITEM_FreeItem(&signature_item, PR_FALSE);
     73   return true;
     74 }
     75 
     76 }  // namespace base
     77