Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: crypto/signature_verifier_nss.cc

Issue 17776003: Add SignatureVerifier::VerifyInitRSAPSS for verifying RSA-PSS signatures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "crypto/signature_verifier.h" 5 #include "crypto/signature_verifier.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <keyhi.h> 8 #include <keyhi.h>
9 #include <pk11pub.h>
10 #include <secerr.h>
11 #include <sechash.h>
9 #include <stdlib.h> 12 #include <stdlib.h>
10 13
11 #include "base/logging.h" 14 #include "base/logging.h"
12 #include "crypto/nss_util.h" 15 #include "crypto/nss_util.h"
16 #include "crypto/third_party/nss/chromium-nss.h"
13 17
14 namespace crypto { 18 namespace crypto {
15 19
16 SignatureVerifier::SignatureVerifier() : vfy_context_(NULL) { 20 namespace {
21
22 HASH_HashType ToNSSHashType(SignatureVerifier::HashAlgorithm hash_alg) {
23 switch (hash_alg) {
24 case SignatureVerifier::SHA1:
25 return HASH_AlgSHA1;
26 case SignatureVerifier::SHA256:
27 return HASH_AlgSHA256;
28 default:
29 return HASH_AlgNULL;
30 }
31 }
32
33 SECStatus VerifyRSAPSS_End(SECKEYPublicKey* public_key,
34 HASHContext* hash_context,
35 HASH_HashType mask_hash_alg,
36 unsigned int salt_len,
37 const unsigned char* signature,
38 unsigned int signature_len) {
39 unsigned int hash_len = HASH_ResultLenContext(hash_context);
40 std::vector<unsigned char> hash(hash_len);
41 HASH_End(hash_context, &hash[0], &hash_len, hash.size());
42
43 unsigned int modulus_len = SECKEY_PublicKeyStrength(public_key);
44 if (signature_len != modulus_len) {
45 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
46 return SECFailure;
47 }
48 std::vector<unsigned char> enc(signature_len);
49 SECStatus rv = PK11_PubEncryptRaw(public_key, &enc[0],
50 const_cast<unsigned char*>(signature),
51 signature_len, NULL);
52 if (rv != SECSuccess) {
53 LOG(WARNING) << "PK11_PubEncryptRaw failed";
54 return rv;
55 }
56 return emsa_pss_verify(&hash[0], &enc[0], enc.size(),
57 HASH_GetType(hash_context), mask_hash_alg,
58 salt_len);
59 }
60
61 } // namespace
62
63 SignatureVerifier::SignatureVerifier()
64 : vfy_context_(NULL),
65 hash_alg_(SHA1),
66 mask_hash_alg_(SHA1),
67 salt_len_(0),
68 public_key_(NULL),
69 hash_context_(NULL) {
17 EnsureNSSInit(); 70 EnsureNSSInit();
18 } 71 }
19 72
20 SignatureVerifier::~SignatureVerifier() { 73 SignatureVerifier::~SignatureVerifier() {
21 Reset(); 74 Reset();
22 } 75 }
23 76
24 bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, 77 // static
25 int signature_algorithm_len, 78 SECKEYPublicKey* SignatureVerifier::DecodePublicKeyInfo(
26 const uint8* signature, 79 const uint8* public_key_info,
27 int signature_len, 80 int public_key_info_len) {
28 const uint8* public_key_info,
29 int public_key_info_len) {
30 signature_.assign(signature, signature + signature_len);
31
32 CERTSubjectPublicKeyInfo* spki = NULL; 81 CERTSubjectPublicKeyInfo* spki = NULL;
33 SECItem spki_der; 82 SECItem spki_der;
34 spki_der.type = siBuffer; 83 spki_der.type = siBuffer;
35 spki_der.data = const_cast<uint8*>(public_key_info); 84 spki_der.data = const_cast<uint8*>(public_key_info);
36 spki_der.len = public_key_info_len; 85 spki_der.len = public_key_info_len;
37 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der); 86 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
38 if (!spki) 87 if (!spki)
39 return false; 88 return NULL;
40 SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki); 89 SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki);
41 SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki. 90 SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki.
91 return public_key;
92 }
93
94 bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
95 int signature_algorithm_len,
96 const uint8* signature,
97 int signature_len,
98 const uint8* public_key_info,
99 int public_key_info_len) {
Ryan Sleevi 2013/06/26 19:48:28 Can you make it an error to call VerifyInit() and
wtc 2013/06/27 02:23:51 Done.
100 signature_.assign(signature, signature + signature_len);
101
102 SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info,
103 public_key_info_len);
42 if (!public_key) 104 if (!public_key)
43 return false; 105 return false;
44 106
45 PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 107 PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
46 if (!arena) { 108 if (!arena) {
47 SECKEY_DestroyPublicKey(public_key); 109 SECKEY_DestroyPublicKey(public_key);
48 return false; 110 return false;
49 } 111 }
50 112
51 SECItem sig_alg_der; 113 SECItem sig_alg_der;
(...skipping 29 matching lines...) Expand all
81 } 143 }
82 144
83 rv = VFY_Begin(vfy_context_); 145 rv = VFY_Begin(vfy_context_);
84 if (rv != SECSuccess) { 146 if (rv != SECSuccess) {
85 NOTREACHED(); 147 NOTREACHED();
86 return false; 148 return false;
87 } 149 }
88 return true; 150 return true;
89 } 151 }
90 152
153 bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
154 HashAlgorithm mask_hash_alg,
155 int salt_len,
156 const uint8* signature,
157 int signature_len,
158 const uint8* public_key_info,
159 int public_key_info_len) {
160 signature_.assign(signature, signature + signature_len);
161
162 SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info,
163 public_key_info_len);
164 if (!public_key)
165 return false;
166
167 public_key_ = public_key;
168 hash_alg_ = hash_alg;
169 mask_hash_alg_ = mask_hash_alg;
170 salt_len_ = salt_len;
171 hash_context_ = HASH_Create(ToNSSHashType(hash_alg_));
172 if (!hash_context_)
173 return false;
174 HASH_Begin(hash_context_);
175 return true;
176 }
177
91 void SignatureVerifier::VerifyUpdate(const uint8* data_part, 178 void SignatureVerifier::VerifyUpdate(const uint8* data_part,
92 int data_part_len) { 179 int data_part_len) {
93 SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len); 180 if (vfy_context_) {
94 DCHECK_EQ(SECSuccess, rv); 181 SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len);
182 DCHECK_EQ(SECSuccess, rv);
183 } else {
184 HASH_Update(hash_context_, data_part, data_part_len);
185 }
95 } 186 }
96 187
97 bool SignatureVerifier::VerifyFinal() { 188 bool SignatureVerifier::VerifyFinal() {
98 SECStatus rv = VFY_End(vfy_context_); 189 SECStatus rv;
190 if (vfy_context_) {
191 rv = VFY_End(vfy_context_);
192 } else {
193 rv = VerifyRSAPSS_End(public_key_, hash_context_,
194 ToNSSHashType(mask_hash_alg_), salt_len_,
195 signature_.data(),
196 signature_.size());
197 }
99 Reset(); 198 Reset();
100 199
101 // If signature verification fails, the error code is 200 // If signature verification fails, the error code is
102 // SEC_ERROR_BAD_SIGNATURE (-8182). 201 // SEC_ERROR_BAD_SIGNATURE (-8182).
103 return (rv == SECSuccess); 202 return (rv == SECSuccess);
104 } 203 }
105 204
106 void SignatureVerifier::Reset() { 205 void SignatureVerifier::Reset() {
107 if (vfy_context_) { 206 if (vfy_context_) {
108 VFY_DestroyContext(vfy_context_, PR_TRUE); 207 VFY_DestroyContext(vfy_context_, PR_TRUE);
109 vfy_context_ = NULL; 208 vfy_context_ = NULL;
110 } 209 }
210 if (hash_context_) {
211 HASH_Destroy(hash_context_);
212 hash_context_ = NULL;
213 }
214 if (public_key_) {
215 SECKEY_DestroyPublicKey(public_key_);
216 public_key_ = NULL;
217 }
111 signature_.clear(); 218 signature_.clear();
Ryan Sleevi 2013/06/26 19:48:28 LEAK? What happens to public_key_ here. Seems like
wtc 2013/06/27 02:23:51 public_key_ is destroyed on lines 214-217 above.
112 } 219 }
113 220
114 } // namespace crypto 221 } // namespace crypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698