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