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

Side by Side Diff: crypto/signature_verifier_nss.cc

Issue 1882433002: Removing NSS files and USE_OPENSSL flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 8 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
« no previous file with comments | « crypto/signature_verifier.h ('k') | crypto/symmetric_key.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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_verifier.h"
6
7 #include <cryptohi.h>
8 #include <keyhi.h>
9 #include <pk11pub.h>
10 #include <secerr.h>
11 #include <sechash.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14
15 #include "base/logging.h"
16 #include "crypto/nss_util.h"
17 #include "crypto/third_party/nss/chromium-nss.h"
18
19 namespace crypto {
20
21 namespace {
22
23 HASH_HashType ToNSSHashType(SignatureVerifier::HashAlgorithm hash_alg) {
24 switch (hash_alg) {
25 case SignatureVerifier::SHA1:
26 return HASH_AlgSHA1;
27 case SignatureVerifier::SHA256:
28 return HASH_AlgSHA256;
29 }
30 return HASH_AlgNULL;
31 }
32
33 SECOidTag ToNSSSignatureType(SignatureVerifier::SignatureAlgorithm sig_alg) {
34 switch (sig_alg) {
35 case SignatureVerifier::RSA_PKCS1_SHA1:
36 return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
37 case SignatureVerifier::RSA_PKCS1_SHA256:
38 return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
39 case SignatureVerifier::ECDSA_SHA256:
40 return SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
41 }
42 return SEC_OID_UNKNOWN;
43 }
44
45 SECStatus VerifyRSAPSS_End(SECKEYPublicKey* public_key,
46 HASHContext* hash_context,
47 HASH_HashType mask_hash_alg,
48 unsigned int salt_len,
49 const unsigned char* signature,
50 unsigned int signature_len) {
51 unsigned int hash_len = HASH_ResultLenContext(hash_context);
52 std::vector<unsigned char> hash(hash_len);
53 HASH_End(hash_context, &hash[0], &hash_len, hash.size());
54
55 unsigned int modulus_len = SECKEY_PublicKeyStrength(public_key);
56 if (signature_len != modulus_len) {
57 PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
58 return SECFailure;
59 }
60 std::vector<unsigned char> enc(signature_len);
61 SECStatus rv = PK11_PubEncryptRaw(public_key, &enc[0],
62 const_cast<unsigned char*>(signature),
63 signature_len, NULL);
64 if (rv != SECSuccess) {
65 LOG(WARNING) << "PK11_PubEncryptRaw failed";
66 return rv;
67 }
68 return emsa_pss_verify(&hash[0], &enc[0], enc.size(),
69 HASH_GetType(hash_context), mask_hash_alg,
70 salt_len);
71 }
72
73 } // namespace
74
75 SignatureVerifier::SignatureVerifier()
76 : vfy_context_(NULL),
77 hash_alg_(SHA1),
78 mask_hash_alg_(SHA1),
79 salt_len_(0),
80 public_key_(NULL),
81 hash_context_(NULL) {
82 EnsureNSSInit();
83 }
84
85 SignatureVerifier::~SignatureVerifier() {
86 Reset();
87 }
88
89 bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
90 const uint8_t* signature,
91 int signature_len,
92 const uint8_t* public_key_info,
93 int public_key_info_len) {
94 if (vfy_context_ || hash_context_)
95 return false;
96
97 signature_.assign(signature, signature + signature_len);
98
99 SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info,
100 public_key_info_len);
101 if (!public_key)
102 return false;
103
104 SECItem sig;
105 sig.type = siBuffer;
106 sig.data = const_cast<uint8_t*>(signature);
107 sig.len = signature_len;
108 vfy_context_ = VFY_CreateContext(
109 public_key, &sig, ToNSSSignatureType(signature_algorithm), nullptr);
110 SECKEY_DestroyPublicKey(public_key); // Done with public_key.
111 if (!vfy_context_) {
112 // A corrupted RSA signature could be detected without the data, so
113 // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE
114 // (-8182).
115 return false;
116 }
117
118 if (VFY_Begin(vfy_context_) != SECSuccess) {
119 NOTREACHED();
120 return false;
121 }
122 return true;
123 }
124
125 bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
126 HashAlgorithm mask_hash_alg,
127 int salt_len,
128 const uint8_t* signature,
129 int signature_len,
130 const uint8_t* public_key_info,
131 int public_key_info_len) {
132 if (vfy_context_ || hash_context_)
133 return false;
134
135 signature_.assign(signature, signature + signature_len);
136
137 SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info,
138 public_key_info_len);
139 if (!public_key)
140 return false;
141
142 public_key_ = public_key;
143 hash_alg_ = hash_alg;
144 mask_hash_alg_ = mask_hash_alg;
145 salt_len_ = salt_len;
146 hash_context_ = HASH_Create(ToNSSHashType(hash_alg_));
147 if (!hash_context_)
148 return false;
149 HASH_Begin(hash_context_);
150 return true;
151 }
152
153 void SignatureVerifier::VerifyUpdate(const uint8_t* data_part,
154 int data_part_len) {
155 if (vfy_context_) {
156 SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len);
157 DCHECK_EQ(SECSuccess, rv);
158 } else {
159 HASH_Update(hash_context_, data_part, data_part_len);
160 }
161 }
162
163 bool SignatureVerifier::VerifyFinal() {
164 SECStatus rv;
165 if (vfy_context_) {
166 rv = VFY_End(vfy_context_);
167 } else {
168 rv = VerifyRSAPSS_End(public_key_, hash_context_,
169 ToNSSHashType(mask_hash_alg_), salt_len_,
170 signature_.data(),
171 signature_.size());
172 }
173 Reset();
174
175 // If signature verification fails, the error code is
176 // SEC_ERROR_BAD_SIGNATURE (-8182).
177 return (rv == SECSuccess);
178 }
179
180 // static
181 SECKEYPublicKey* SignatureVerifier::DecodePublicKeyInfo(
182 const uint8_t* public_key_info,
183 int public_key_info_len) {
184 CERTSubjectPublicKeyInfo* spki = NULL;
185 SECItem spki_der;
186 spki_der.type = siBuffer;
187 spki_der.data = const_cast<uint8_t*>(public_key_info);
188 spki_der.len = public_key_info_len;
189 spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
190 if (!spki)
191 return NULL;
192 SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki);
193 SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki.
194 return public_key;
195 }
196
197 void SignatureVerifier::Reset() {
198 if (vfy_context_) {
199 VFY_DestroyContext(vfy_context_, PR_TRUE);
200 vfy_context_ = NULL;
201 }
202 if (hash_context_) {
203 HASH_Destroy(hash_context_);
204 hash_context_ = NULL;
205 }
206 if (public_key_) {
207 SECKEY_DestroyPublicKey(public_key_);
208 public_key_ = NULL;
209 }
210 signature_.clear();
211 }
212
213 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/signature_verifier.h ('k') | crypto/symmetric_key.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698