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_SIG_to_raw(ECDSA_SIG* ec_sig, | |
davidben
2016/06/27 23:39:14
Since these are Chromium functions, probably name
nharper
2016/06/27 23:58:30
Done.
| |
35 EC_KEY* ec, | |
36 std::vector<uint8_t>* out) { | |
37 const EC_GROUP* group = EC_KEY_get0_group(ec); | |
38 const BIGNUM* order = EC_GROUP_get0_order(group); | |
39 size_t len = BN_num_bytes(order); | |
40 out->resize(2 * len); | |
41 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || | |
42 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { | |
43 return false; | |
44 } | |
45 return true; | |
46 } | |
47 | |
48 ECDSA_SIG* raw_to_ECDSA_SIG(EC_KEY* ec, base::StringPiece sig) { | |
49 crypto::ScopedECDSA_SIG raw_sig(ECDSA_SIG_new()); | |
50 const EC_GROUP* group = EC_KEY_get0_group(ec); | |
51 const BIGNUM* order = EC_GROUP_get0_order(group); | |
52 size_t group_size = BN_num_bytes(order); | |
53 if (sig.size() != group_size * 2) | |
54 return nullptr; | |
55 const uint8_t* sigp = reinterpret_cast<const uint8_t*>(sig.data()); | |
56 if (BN_bin2bn(sigp, group_size, raw_sig->r) == nullptr || | |
57 BN_bin2bn(sigp + group_size, group_size, raw_sig->s) == nullptr) { | |
davidben
2016/06/27 23:39:15
Nit: I think Chromium prefers if (!BN_bin2bn(...)
nharper
2016/06/27 23:58:30
Done.
| |
58 return nullptr; | |
59 } | |
60 return raw_sig.release(); | |
61 } | |
62 | |
34 } // namespace | 63 } // namespace |
35 | 64 |
36 bool SignTokenBindingEkm(base::StringPiece ekm, | 65 bool SignTokenBindingEkm(base::StringPiece ekm, |
37 crypto::ECPrivateKey* key, | 66 crypto::ECPrivateKey* key, |
38 std::vector<uint8_t>* out) { | 67 std::vector<uint8_t>* out) { |
39 size_t sig_len; | |
40 const uint8_t* ekm_data = reinterpret_cast<const uint8_t*>(ekm.data()); | 68 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)); | 69 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); |
42 if (!EVP_PKEY_sign_init(pctx.get()) || | 70 if (!ec_key) |
43 !EVP_PKEY_sign(pctx.get(), nullptr, &sig_len, ekm_data, ekm.size())) { | |
44 return false; | 71 return false; |
45 } | 72 crypto::ScopedECDSA_SIG sig(ECDSA_do_sign(ekm_data, ekm.size(), ec_key)); |
46 out->resize(sig_len); | 73 return ECDSA_SIG_to_raw(sig.get(), ec_key, out); |
davidben
2016/06/27 23:39:15
Nit: Check for !sig in case that failed? (I'm like
nharper
2016/06/27 23:58:30
Done.
| |
47 if (!EVP_PKEY_sign(pctx.get(), out->data(), &sig_len, ekm_data, ekm.size())) | |
48 return false; | |
49 out->resize(sig_len); | |
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(raw_to_ECDSA_SIG(keyp, signature)); |
149 if (!EVP_PKEY_assign_EC_KEY(pkey.get(), key.release())) | 172 if (!sig.get()) |
davidben
2016/06/27 23:39:15
Nit: if (!sig)
nharper
2016/06/27 23:58:30
Done.
| |
150 return false; | 173 return false; |
151 crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); | 174 return 0 != ECDSA_do_verify(reinterpret_cast<const uint8_t*>(ekm.data()), |
152 if (!EVP_PKEY_verify_init(pctx.get()) || | 175 ekm.size(), sig.get(), keyp); |
davidben
2016/06/27 23:39:15
Nit: I think I've usually seen !! as the "cast int
nharper
2016/06/27 23:58:30
Done.
| |
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 |