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

Side by Side Diff: net/ssl/ssl_platform_key_nss.cc

Issue 2391213002: Report curve types in ECDSA SSLPrivateKeys. (Closed)
Patch Set: rebase Created 4 years, 2 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 | « net/ssl/ssl_platform_key_mac.cc ('k') | net/ssl/ssl_platform_key_task_runner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 <cert.h>
5 #include <keyhi.h> 6 #include <keyhi.h>
6 #include <openssl/bn.h> 7 #include <openssl/bn.h>
8 #include <openssl/bytestring.h>
9 #include <openssl/ec.h>
10 #include <openssl/ec_key.h>
7 #include <openssl/ecdsa.h> 11 #include <openssl/ecdsa.h>
8 #include <openssl/mem.h> 12 #include <openssl/mem.h>
9 #include <openssl/nid.h> 13 #include <openssl/nid.h>
10 #include <openssl/rsa.h> 14 #include <openssl/rsa.h>
11 #include <pk11pub.h> 15 #include <pk11pub.h>
12 #include <prerror.h> 16 #include <prerror.h>
13 17
14 #include <utility> 18 #include <utility>
15 19
16 #include "base/logging.h" 20 #include "base/logging.h"
17 #include "base/macros.h" 21 #include "base/macros.h"
18 #include "base/memory/ptr_util.h" 22 #include "base/memory/ptr_util.h"
19 #include "base/sequenced_task_runner.h" 23 #include "base/sequenced_task_runner.h"
20 #include "crypto/scoped_nss_types.h" 24 #include "crypto/scoped_nss_types.h"
21 #include "net/cert/x509_certificate.h" 25 #include "net/cert/x509_certificate.h"
22 #include "net/ssl/client_key_store.h" 26 #include "net/ssl/client_key_store.h"
23 #include "net/ssl/ssl_platform_key.h" 27 #include "net/ssl/ssl_platform_key.h"
24 #include "net/ssl/ssl_platform_key_task_runner.h" 28 #include "net/ssl/ssl_platform_key_util.h"
25 #include "net/ssl/ssl_private_key.h" 29 #include "net/ssl/ssl_private_key.h"
26 #include "net/ssl/threaded_ssl_private_key.h" 30 #include "net/ssl/threaded_ssl_private_key.h"
27 31
28 namespace net { 32 namespace net {
29 33
30 namespace { 34 namespace {
31 35
32 void LogPRError() { 36 void LogPRError(const char* message) {
33 PRErrorCode err = PR_GetError(); 37 PRErrorCode err = PR_GetError();
34 const char* err_name = PR_ErrorToName(err); 38 const char* err_name = PR_ErrorToName(err);
35 if (err_name == nullptr) 39 if (err_name == nullptr)
36 err_name = ""; 40 err_name = "";
37 LOG(ERROR) << "Could not sign digest: " << err << " (" << err_name << ")"; 41 LOG(ERROR) << message << ": " << err << " (" << err_name << ")";
38 } 42 }
39 43
40 class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { 44 class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
41 public: 45 public:
42 SSLPlatformKeyNSS(SSLPrivateKey::Type type, 46 SSLPlatformKeyNSS(SSLPrivateKey::Type type,
47 size_t max_length,
43 crypto::ScopedSECKEYPrivateKey key) 48 crypto::ScopedSECKEYPrivateKey key)
44 : type_(type), key_(std::move(key)) {} 49 : type_(type), max_length_(max_length), key_(std::move(key)) {}
45 ~SSLPlatformKeyNSS() override {} 50 ~SSLPlatformKeyNSS() override {}
46 51
47 SSLPrivateKey::Type GetType() override { return type_; } 52 SSLPrivateKey::Type GetType() override { return type_; }
48 53
49 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { 54 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
50 static const SSLPrivateKey::Hash kHashes[] = { 55 static const SSLPrivateKey::Hash kHashes[] = {
51 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384, 56 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
52 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1}; 57 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1};
53 return std::vector<SSLPrivateKey::Hash>(kHashes, 58 return std::vector<SSLPrivateKey::Hash>(kHashes,
54 kHashes + arraysize(kHashes)); 59 kHashes + arraysize(kHashes));
55 } 60 }
56 61
57 size_t GetMaxSignatureLengthInBytes() override { 62 size_t GetMaxSignatureLengthInBytes() override { return max_length_; }
58 int len = PK11_SignatureLen(key_.get());
59 if (len <= 0)
60 return 0;
61 // NSS signs raw ECDSA signatures rather than a DER-encoded ECDSA-Sig-Value.
62 if (type_ == SSLPrivateKey::Type::ECDSA)
63 return ECDSA_SIG_max_len(static_cast<size_t>(len) / 2);
64 return static_cast<size_t>(len);
65 }
66 63
67 Error SignDigest(SSLPrivateKey::Hash hash, 64 Error SignDigest(SSLPrivateKey::Hash hash,
68 const base::StringPiece& input, 65 const base::StringPiece& input,
69 std::vector<uint8_t>* signature) override { 66 std::vector<uint8_t>* signature) override {
70 SECItem digest_item; 67 SECItem digest_item;
71 digest_item.data = 68 digest_item.data =
72 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input.data())); 69 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input.data()));
73 digest_item.len = input.size(); 70 digest_item.len = input.size();
74 71
75 bssl::UniquePtr<uint8_t> free_digest_info; 72 bssl::UniquePtr<uint8_t> free_digest_info;
(...skipping 24 matching lines...) Expand all
100 hash_nid, digest_item.data, digest_item.len)) { 97 hash_nid, digest_item.data, digest_item.len)) {
101 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 98 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
102 } 99 }
103 digest_item.len = prefix_len; 100 digest_item.len = prefix_len;
104 if (is_alloced) 101 if (is_alloced)
105 free_digest_info.reset(digest_item.data); 102 free_digest_info.reset(digest_item.data);
106 } 103 }
107 104
108 int len = PK11_SignatureLen(key_.get()); 105 int len = PK11_SignatureLen(key_.get());
109 if (len <= 0) { 106 if (len <= 0) {
110 LogPRError(); 107 LogPRError("PK11_SignatureLen failed");
111 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 108 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
112 } 109 }
113 signature->resize(len); 110 signature->resize(len);
114 SECItem signature_item; 111 SECItem signature_item;
115 signature_item.data = signature->data(); 112 signature_item.data = signature->data();
116 signature_item.len = signature->size(); 113 signature_item.len = signature->size();
117 114
118 SECStatus rv = PK11_Sign(key_.get(), &signature_item, &digest_item); 115 SECStatus rv = PK11_Sign(key_.get(), &signature_item, &digest_item);
119 if (rv != SECSuccess) { 116 if (rv != SECSuccess) {
120 LogPRError(); 117 LogPRError("PK11_Sign failed");
121 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 118 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
122 } 119 }
123 signature->resize(signature_item.len); 120 signature->resize(signature_item.len);
124 121
125 // NSS emits raw ECDSA signatures, but BoringSSL expects a DER-encoded 122 // NSS emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
126 // ECDSA-Sig-Value. 123 // ECDSA-Sig-Value.
127 if (type_ == SSLPrivateKey::Type::ECDSA) { 124 if (SSLPrivateKey::IsECDSAType(type_)) {
128 if (signature->size() % 2 != 0) { 125 if (signature->size() % 2 != 0) {
129 LOG(ERROR) << "Bad signature length"; 126 LOG(ERROR) << "Bad signature length";
130 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 127 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
131 } 128 }
132 size_t order_len = signature->size() / 2; 129 size_t order_len = signature->size() / 2;
133 130
134 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value. 131 // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
135 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); 132 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
136 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) || 133 if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
137 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) { 134 !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
138 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 135 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
139 } 136 }
140 137
141 int len = i2d_ECDSA_SIG(sig.get(), nullptr); 138 int len = i2d_ECDSA_SIG(sig.get(), nullptr);
142 if (len <= 0) 139 if (len <= 0)
143 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 140 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
144 signature->resize(len); 141 signature->resize(len);
145 uint8_t* ptr = signature->data(); 142 uint8_t* ptr = signature->data();
146 len = i2d_ECDSA_SIG(sig.get(), &ptr); 143 len = i2d_ECDSA_SIG(sig.get(), &ptr);
147 if (len <= 0) 144 if (len <= 0)
148 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; 145 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
149 signature->resize(len); 146 signature->resize(len);
150 } 147 }
151 148
152 return OK; 149 return OK;
153 } 150 }
154 151
155 private: 152 private:
156 SSLPrivateKey::Type type_; 153 SSLPrivateKey::Type type_;
154 size_t max_length_;
157 crypto::ScopedSECKEYPrivateKey key_; 155 crypto::ScopedSECKEYPrivateKey key_;
158 156
159 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyNSS); 157 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyNSS);
160 }; 158 };
161 159
162 } // namespace 160 } // namespace
163 161
164 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( 162 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
165 X509Certificate* certificate) { 163 X509Certificate* certificate) {
166 crypto::ScopedSECKEYPrivateKey key( 164 crypto::ScopedSECKEYPrivateKey key(
167 PK11_FindKeyByAnyCert(certificate->os_cert_handle(), nullptr)); 165 PK11_FindKeyByAnyCert(certificate->os_cert_handle(), nullptr));
168 if (!key) { 166 if (!key) {
169 return ClientKeyStore::GetInstance()->FetchClientCertPrivateKey( 167 return ClientKeyStore::GetInstance()->FetchClientCertPrivateKey(
170 *certificate); 168 *certificate);
171 } 169 }
172 170
173 KeyType nss_type = SECKEY_GetPrivateKeyType(key.get());
174 SSLPrivateKey::Type type; 171 SSLPrivateKey::Type type;
175 switch (nss_type) { 172 size_t max_length;
176 case rsaKey: 173 if (!GetClientCertInfo(certificate, &type, &max_length))
177 type = SSLPrivateKey::Type::RSA; 174 return nullptr;
178 break; 175
179 case ecKey:
180 type = SSLPrivateKey::Type::ECDSA;
181 break;
182 default:
183 LOG(ERROR) << "Unknown key type: " << nss_type;
184 return nullptr;
185 }
186 return make_scoped_refptr(new ThreadedSSLPrivateKey( 176 return make_scoped_refptr(new ThreadedSSLPrivateKey(
187 base::MakeUnique<SSLPlatformKeyNSS>(type, std::move(key)), 177 base::MakeUnique<SSLPlatformKeyNSS>(type, max_length, std::move(key)),
188 GetSSLPlatformKeyTaskRunner())); 178 GetSSLPlatformKeyTaskRunner()));
189 } 179 }
190 180
191 } // namespace net 181 } // namespace net
OLDNEW
« no previous file with comments | « net/ssl/ssl_platform_key_mac.cc ('k') | net/ssl/ssl_platform_key_task_runner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698