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.
5 #include "crypto/ec_signature_creator_impl.h"
15 #include "base/logging.h"
16 #include "crypto/ec_private_key.h"
17 #include "crypto/nss_util.h"
18 #include "crypto/scoped_nss_types.h"
24 SECStatus
SignData(SECItem
* result
,
26 SECKEYPrivateKey
* key
,
27 HASH_HashType hash_type
,
28 size_t* out_signature_len
) {
29 if (key
->keyType
!= ecKey
) {
30 DLOG(FATAL
) << "Should be using an EC key.";
31 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
36 std::vector
<uint8
> hash_data(HASH_ResultLen(hash_type
));
37 SECStatus rv
= HASH_HashBuf(
38 hash_type
, &hash_data
[0], input
->data
, input
->len
);
41 SECItem hash
= {siBuffer
, &hash_data
[0],
42 static_cast<unsigned int>(hash_data
.size())};
44 // Compute signature of hash.
45 int signature_len
= PK11_SignatureLen(key
);
46 std::vector
<uint8
> signature_data(signature_len
);
47 SECItem sig
= {siBuffer
, &signature_data
[0],
48 static_cast<unsigned int>(signature_len
)};
49 rv
= PK11_Sign(key
, &sig
, &hash
);
53 *out_signature_len
= sig
.len
;
55 // DER encode the signature.
56 return DSAU_EncodeDerSigWithLen(result
, &sig
, sig
.len
);
61 ECSignatureCreatorImpl::ECSignatureCreatorImpl(ECPrivateKey
* key
)
67 ECSignatureCreatorImpl::~ECSignatureCreatorImpl() {}
69 bool ECSignatureCreatorImpl::Sign(const uint8
* data
,
71 std::vector
<uint8
>* signature
) {
74 secret
.type
= siBuffer
;
75 secret
.len
= data_len
;
76 secret
.data
= const_cast<unsigned char*>(data
);
78 // SECItem to receive the output buffer.
80 result
.type
= siBuffer
;
84 // Sign the secret data and save it to |result|.
86 SignData(&result
, &secret
, key_
->key(), HASH_AlgSHA256
, &signature_len_
);
87 if (rv
!= SECSuccess
) {
88 DLOG(ERROR
) << "DerSignData: " << PORT_GetError();
92 // Copy the signed data into the output vector.
93 signature
->assign(result
.data
, result
.data
+ result
.len
);
94 SECITEM_FreeItem(&result
, PR_FALSE
/* only free |result.data| */);
98 bool ECSignatureCreatorImpl::DecodeSignature(
99 const std::vector
<uint8
>& der_sig
,
100 std::vector
<uint8
>* out_raw_sig
) {
101 SECItem der_sig_item
;
102 der_sig_item
.type
= siBuffer
;
103 der_sig_item
.len
= der_sig
.size();
104 der_sig_item
.data
= const_cast<uint8
*>(&der_sig
[0]);
106 SECItem
* raw_sig
= DSAU_DecodeDerSigToLen(&der_sig_item
, signature_len_
);
109 out_raw_sig
->assign(raw_sig
->data
, raw_sig
->data
+ raw_sig
->len
);
110 SECITEM_FreeItem(raw_sig
, PR_TRUE
/* free SECItem structure itself. */);
114 } // namespace crypto