OLD | NEW |
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 "net/ssl/token_binding.h" | 5 #include "net/ssl/token_binding.h" |
6 | 6 |
7 #include <openssl/bytestring.h> | 7 #include <openssl/bytestring.h> |
8 #include <openssl/ec.h> | 8 #include <openssl/ec.h> |
| 9 #include <openssl/ec_key.h> |
9 #include <openssl/evp.h> | 10 #include <openssl/evp.h> |
10 #include <openssl/mem.h> | 11 #include <openssl/mem.h> |
11 | 12 |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "crypto/scoped_openssl_types.h" | 14 #include "crypto/scoped_openssl_types.h" |
14 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
15 #include "net/ssl/ssl_config.h" | 16 #include "net/ssl/ssl_config.h" |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
| 22 const size_t kUncompressedPointLen = 65; |
| 23 |
21 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { | 24 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { |
22 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); | 25 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); |
23 DCHECK(ec_key); | 26 DCHECK(ec_key); |
24 | 27 |
| 28 uint8_t point_buf[kUncompressedPointLen]; |
| 29 if (EC_POINT_point2oct( |
| 30 EC_KEY_get0_group(ec_key), EC_KEY_get0_public_key(ec_key), |
| 31 POINT_CONVERSION_UNCOMPRESSED, point_buf, kUncompressedPointLen, |
| 32 NULL) != kUncompressedPointLen) { |
| 33 return false; |
| 34 } |
25 CBB ec_point; | 35 CBB ec_point; |
26 return CBB_add_u8(out, TB_PARAM_ECDSAP256) && | 36 return CBB_add_u8(out, TB_PARAM_ECDSAP256) && |
27 CBB_add_u8_length_prefixed(out, &ec_point) && | 37 CBB_add_u8_length_prefixed(out, &ec_point) && |
28 EC_POINT_point2cbb(&ec_point, EC_KEY_get0_group(ec_key), | 38 CBB_add_bytes(&ec_point, point_buf + 1, kUncompressedPointLen - 1) && |
29 EC_KEY_get0_public_key(ec_key), | |
30 POINT_CONVERSION_UNCOMPRESSED, nullptr) && | |
31 CBB_flush(out); | 39 CBB_flush(out); |
32 } | 40 } |
33 | 41 |
34 bool ECDSA_SIGToRaw(ECDSA_SIG* ec_sig, EC_KEY* ec, std::vector<uint8_t>* out) { | 42 bool ECDSA_SIGToRaw(ECDSA_SIG* ec_sig, EC_KEY* ec, std::vector<uint8_t>* out) { |
35 const EC_GROUP* group = EC_KEY_get0_group(ec); | 43 const EC_GROUP* group = EC_KEY_get0_group(ec); |
36 const BIGNUM* order = EC_GROUP_get0_order(group); | 44 const BIGNUM* order = EC_GROUP_get0_order(group); |
37 size_t len = BN_num_bytes(order); | 45 size_t len = BN_num_bytes(order); |
38 out->resize(2 * len); | 46 out->resize(2 * len); |
39 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || | 47 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || |
40 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { | 48 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 std::string(reinterpret_cast<const char*>(CBS_data(&signature)), | 163 std::string(reinterpret_cast<const char*>(CBS_data(&signature)), |
156 CBS_len(&signature)); | 164 CBS_len(&signature)); |
157 token_bindings->push_back(token_binding); | 165 token_bindings->push_back(token_binding); |
158 } | 166 } |
159 return true; | 167 return true; |
160 } | 168 } |
161 | 169 |
162 bool VerifyEKMSignature(base::StringPiece ec_point, | 170 bool VerifyEKMSignature(base::StringPiece ec_point, |
163 base::StringPiece signature, | 171 base::StringPiece signature, |
164 base::StringPiece ekm) { | 172 base::StringPiece ekm) { |
| 173 if (ec_point.size() != kUncompressedPointLen - 1) |
| 174 return false; |
| 175 uint8_t x9_62_ec_point[kUncompressedPointLen]; |
| 176 x9_62_ec_point[0] = 4; |
| 177 memcpy(x9_62_ec_point + 1, ec_point.data(), kUncompressedPointLen - 1); |
165 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); | 178 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); |
166 EC_KEY* keyp = key.get(); | 179 EC_KEY* keyp = key.get(); |
167 const uint8_t* ec_point_data = | 180 crypto::ScopedEC_POINT pub_key(EC_POINT_new(EC_KEY_get0_group(keyp))); |
168 reinterpret_cast<const uint8_t*>(ec_point.data()); | 181 if (!EC_POINT_oct2point(EC_KEY_get0_group(keyp), pub_key.get(), |
169 if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get()) | 182 x9_62_ec_point, kUncompressedPointLen, nullptr) || |
| 183 !EC_KEY_set_public_key(keyp, pub_key.get())) { |
170 return false; | 184 return false; |
| 185 } |
| 186 |
171 crypto::ScopedECDSA_SIG sig(RawToECDSA_SIG(keyp, signature)); | 187 crypto::ScopedECDSA_SIG sig(RawToECDSA_SIG(keyp, signature)); |
172 if (!sig) | 188 if (!sig) |
173 return false; | 189 return false; |
174 return !!ECDSA_do_verify(reinterpret_cast<const uint8_t*>(ekm.data()), | 190 return !!ECDSA_do_verify(reinterpret_cast<const uint8_t*>(ekm.data()), |
175 ekm.size(), sig.get(), keyp); | 191 ekm.size(), sig.get(), keyp); |
176 } | 192 } |
177 | 193 |
178 } // namespace net | 194 } // namespace net |
OLD | NEW |