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/evp.h> | 9 #include <openssl/evp.h> |
10 #include <openssl/mem.h> | 10 #include <openssl/mem.h> |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 CBB ec_point; | 25 CBB ec_point; |
26 return CBB_add_u8(out, TB_PARAM_ECDSAP256) && | 26 return CBB_add_u8(out, TB_PARAM_ECDSAP256) && |
27 CBB_add_u8_length_prefixed(out, &ec_point) && | 27 CBB_add_u8_length_prefixed(out, &ec_point) && |
28 EC_POINT_point2cbb(&ec_point, EC_KEY_get0_group(ec_key), | 28 EC_POINT_point2cbb(&ec_point, EC_KEY_get0_group(ec_key), |
29 EC_KEY_get0_public_key(ec_key), | 29 EC_KEY_get0_public_key(ec_key), |
30 POINT_CONVERSION_UNCOMPRESSED, nullptr) && | 30 POINT_CONVERSION_UNCOMPRESSED, nullptr) && |
31 CBB_flush(out); | 31 CBB_flush(out); |
32 } | 32 } |
33 | 33 |
| 34 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); |
| 36 const BIGNUM* order = EC_GROUP_get0_order(group); |
| 37 size_t len = BN_num_bytes(order); |
| 38 out->resize(2 * len); |
| 39 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || |
| 40 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { |
| 41 return false; |
| 42 } |
| 43 return true; |
| 44 } |
| 45 |
| 46 ECDSA_SIG* RawToECDSA_SIG(EC_KEY* ec, base::StringPiece sig) { |
| 47 crypto::ScopedECDSA_SIG raw_sig(ECDSA_SIG_new()); |
| 48 const EC_GROUP* group = EC_KEY_get0_group(ec); |
| 49 const BIGNUM* order = EC_GROUP_get0_order(group); |
| 50 size_t group_size = BN_num_bytes(order); |
| 51 if (sig.size() != group_size * 2) |
| 52 return nullptr; |
| 53 const uint8_t* sigp = reinterpret_cast<const uint8_t*>(sig.data()); |
| 54 if (!BN_bin2bn(sigp, group_size, raw_sig->r) || |
| 55 !BN_bin2bn(sigp + group_size, group_size, raw_sig->s)) { |
| 56 return nullptr; |
| 57 } |
| 58 return raw_sig.release(); |
| 59 } |
| 60 |
34 } // namespace | 61 } // namespace |
35 | 62 |
36 bool SignTokenBindingEkm(base::StringPiece ekm, | 63 bool SignTokenBindingEkm(base::StringPiece ekm, |
37 crypto::ECPrivateKey* key, | 64 crypto::ECPrivateKey* key, |
38 std::vector<uint8_t>* out) { | 65 std::vector<uint8_t>* out) { |
39 size_t sig_len; | |
40 const uint8_t* ekm_data = reinterpret_cast<const uint8_t*>(ekm.data()); | 66 const uint8_t* ekm_data = reinterpret_cast<const uint8_t*>(ekm.data()); |
41 crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(key->key(), nullptr)); | 67 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); |
42 if (!EVP_PKEY_sign_init(pctx.get()) || | 68 if (!ec_key) |
43 !EVP_PKEY_sign(pctx.get(), nullptr, &sig_len, ekm_data, ekm.size())) { | |
44 return false; | 69 return false; |
45 } | 70 crypto::ScopedECDSA_SIG sig(ECDSA_do_sign(ekm_data, ekm.size(), ec_key)); |
46 out->resize(sig_len); | 71 if (!sig) |
47 if (!EVP_PKEY_sign(pctx.get(), out->data(), &sig_len, ekm_data, ekm.size())) | |
48 return false; | 72 return false; |
49 out->resize(sig_len); | 73 return ECDSA_SIGToRaw(sig.get(), ec_key, out); |
50 return true; | |
51 } | 74 } |
52 | 75 |
53 Error BuildTokenBindingMessageFromTokenBindings( | 76 Error BuildTokenBindingMessageFromTokenBindings( |
54 const std::vector<base::StringPiece>& token_bindings, | 77 const std::vector<base::StringPiece>& token_bindings, |
55 std::string* out) { | 78 std::string* out) { |
56 CBB tb_message, child; | 79 CBB tb_message, child; |
57 if (!CBB_init(&tb_message, 0) || | 80 if (!CBB_init(&tb_message, 0) || |
58 !CBB_add_u16_length_prefixed(&tb_message, &child)) { | 81 !CBB_add_u16_length_prefixed(&tb_message, &child)) { |
59 CBB_cleanup(&tb_message); | 82 CBB_cleanup(&tb_message); |
60 return ERR_FAILED; | 83 return ERR_FAILED; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 161 |
139 bool VerifyEKMSignature(base::StringPiece ec_point, | 162 bool VerifyEKMSignature(base::StringPiece ec_point, |
140 base::StringPiece signature, | 163 base::StringPiece signature, |
141 base::StringPiece ekm) { | 164 base::StringPiece ekm) { |
142 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); | 165 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); |
143 EC_KEY* keyp = key.get(); | 166 EC_KEY* keyp = key.get(); |
144 const uint8_t* ec_point_data = | 167 const uint8_t* ec_point_data = |
145 reinterpret_cast<const uint8_t*>(ec_point.data()); | 168 reinterpret_cast<const uint8_t*>(ec_point.data()); |
146 if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get()) | 169 if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get()) |
147 return false; | 170 return false; |
148 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); | 171 crypto::ScopedECDSA_SIG sig(RawToECDSA_SIG(keyp, signature)); |
149 if (!EVP_PKEY_assign_EC_KEY(pkey.get(), key.release())) | 172 if (!sig) |
150 return false; | 173 return false; |
151 crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); | 174 return !!ECDSA_do_verify(reinterpret_cast<const uint8_t*>(ekm.data()), |
152 if (!EVP_PKEY_verify_init(pctx.get()) || | 175 ekm.size(), sig.get(), keyp); |
153 !EVP_PKEY_verify( | |
154 pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()), | |
155 signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()), | |
156 ekm.size())) { | |
157 return false; | |
158 } | |
159 return true; | |
160 } | 176 } |
161 | 177 |
162 } // namespace net | 178 } // namespace net |
OLD | NEW |