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> |
11 | 11 |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "crypto/scoped_openssl_types.h" | 13 #include "crypto/scoped_openssl_types.h" |
14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
15 #include "net/ssl/ssl_config.h" | 15 #include "net/ssl/ssl_config.h" |
16 | 16 |
17 namespace net { | 17 namespace net { |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 enum TokenBindingType { | 21 enum TokenBindingType { |
22 TB_TYPE_PROVIDED = 0, | 22 TB_TYPE_PROVIDED = 0, |
23 TB_TYPE_REFERRED = 1, | 23 TB_TYPE_REFERRED = 1, |
24 }; | 24 }; |
25 | 25 |
26 bool BuildTokenBindingID(TokenBindingType type, | 26 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { |
27 crypto::ECPrivateKey* key, | |
28 CBB* out) { | |
29 CBB ec_point; | 27 CBB ec_point; |
30 if (!CBB_add_u8(out, type) || !CBB_add_u8(out, TB_PARAM_ECDSAP256) || | 28 if (!CBB_add_u8(out, TB_PARAM_ECDSAP256) || |
31 !CBB_add_u8_length_prefixed(out, &ec_point)) { | 29 !CBB_add_u8_length_prefixed(out, &ec_point)) { |
32 return false; | 30 return false; |
33 } | 31 } |
34 | 32 |
35 EVP_PKEY* pkey = key->key(); | 33 EVP_PKEY* pkey = key->key(); |
36 static const int kExpectedKeyLength = 65; | 34 static const int kExpectedKeyLength = 65; |
37 uint8_t* buf; | 35 uint8_t* buf; |
38 // TODO(nharper): Replace i2o_ECPublicKey with EC_POINT_point2cbb. | 36 // TODO(nharper): Replace i2o_ECPublicKey with EC_POINT_point2cbb. |
39 if (pkey->type != EVP_PKEY_EC || | 37 if (pkey->type != EVP_PKEY_EC || |
40 i2o_ECPublicKey(pkey->pkey.ec, nullptr) != kExpectedKeyLength || | 38 i2o_ECPublicKey(pkey->pkey.ec, nullptr) != kExpectedKeyLength || |
41 !CBB_add_space(&ec_point, &buf, kExpectedKeyLength) || | 39 !CBB_add_space(&ec_point, &buf, kExpectedKeyLength) || |
42 i2o_ECPublicKey(pkey->pkey.ec, &buf) != kExpectedKeyLength || | 40 i2o_ECPublicKey(pkey->pkey.ec, &buf) != kExpectedKeyLength || |
43 !CBB_flush(out)) { | 41 !CBB_flush(out)) { |
44 return false; | 42 return false; |
45 } | 43 } |
46 return true; | 44 return true; |
47 } | 45 } |
48 | 46 |
| 47 Error BuildTokenBinding(TokenBindingType type, |
| 48 crypto::ECPrivateKey* key, |
| 49 const std::vector<uint8_t>& signed_ekm, |
| 50 std::string* out) { |
| 51 uint8_t* out_data; |
| 52 size_t out_len; |
| 53 CBB token_binding; |
| 54 if (!CBB_init(&token_binding, 0) || !CBB_add_u8(&token_binding, type) || |
| 55 !BuildTokenBindingID(key, &token_binding) || |
| 56 !CBB_add_u16(&token_binding, signed_ekm.size()) || |
| 57 !CBB_add_bytes(&token_binding, signed_ekm.data(), signed_ekm.size()) || |
| 58 // 0-length extensions |
| 59 !CBB_add_u16(&token_binding, 0) || |
| 60 !CBB_finish(&token_binding, &out_data, &out_len)) { |
| 61 CBB_cleanup(&token_binding); |
| 62 return ERR_FAILED; |
| 63 } |
| 64 out->assign(reinterpret_cast<char*>(out_data), out_len); |
| 65 OPENSSL_free(out_data); |
| 66 return OK; |
| 67 } |
| 68 |
49 } // namespace | 69 } // namespace |
50 | 70 |
51 Error BuildTokenBindingMessageFromTokenBindings( | 71 Error BuildTokenBindingMessageFromTokenBindings( |
52 const std::vector<base::StringPiece>& token_bindings, | 72 const std::vector<base::StringPiece>& token_bindings, |
53 std::string* out) { | 73 std::string* out) { |
54 CBB tb_message, child; | 74 CBB tb_message, child; |
55 if (!CBB_init(&tb_message, 0) || | 75 if (!CBB_init(&tb_message, 0) || |
56 !CBB_add_u16_length_prefixed(&tb_message, &child)) { | 76 !CBB_add_u16_length_prefixed(&tb_message, &child)) { |
57 CBB_cleanup(&tb_message); | 77 CBB_cleanup(&tb_message); |
58 return ERR_FAILED; | 78 return ERR_FAILED; |
(...skipping 14 matching lines...) Expand all Loading... |
73 return ERR_FAILED; | 93 return ERR_FAILED; |
74 } | 94 } |
75 out->assign(reinterpret_cast<char*>(out_data), out_len); | 95 out->assign(reinterpret_cast<char*>(out_data), out_len); |
76 OPENSSL_free(out_data); | 96 OPENSSL_free(out_data); |
77 return OK; | 97 return OK; |
78 } | 98 } |
79 | 99 |
80 Error BuildProvidedTokenBinding(crypto::ECPrivateKey* key, | 100 Error BuildProvidedTokenBinding(crypto::ECPrivateKey* key, |
81 const std::vector<uint8_t>& signed_ekm, | 101 const std::vector<uint8_t>& signed_ekm, |
82 std::string* out) { | 102 std::string* out) { |
83 uint8_t* out_data; | 103 return BuildTokenBinding(TB_TYPE_PROVIDED, key, signed_ekm, out); |
84 size_t out_len; | |
85 CBB token_binding; | |
86 if (!CBB_init(&token_binding, 0) || | |
87 !BuildTokenBindingID(TB_TYPE_PROVIDED, key, &token_binding) || | |
88 !CBB_add_u16(&token_binding, signed_ekm.size()) || | |
89 !CBB_add_bytes(&token_binding, signed_ekm.data(), signed_ekm.size()) || | |
90 // 0-length extensions | |
91 !CBB_add_u16(&token_binding, 0) || | |
92 !CBB_finish(&token_binding, &out_data, &out_len)) { | |
93 CBB_cleanup(&token_binding); | |
94 return ERR_FAILED; | |
95 } | |
96 out->assign(reinterpret_cast<char*>(out_data), out_len); | |
97 OPENSSL_free(out_data); | |
98 return OK; | |
99 } | 104 } |
100 | 105 |
101 bool ParseTokenBindingMessage(base::StringPiece token_binding_message, | 106 bool ParseTokenBindingMessage(base::StringPiece token_binding_message, |
102 base::StringPiece* ec_point_out, | 107 base::StringPiece* ec_point_out, |
103 base::StringPiece* signature_out) { | 108 base::StringPiece* signature_out) { |
104 CBS tb_message, tb, ec_point, signature; | 109 CBS tb_message, tb, ec_point, signature; |
105 uint8_t tb_type, tb_param; | 110 uint8_t tb_type, tb_param; |
106 CBS_init(&tb_message, | 111 CBS_init(&tb_message, |
107 reinterpret_cast<const uint8_t*>(token_binding_message.data()), | 112 reinterpret_cast<const uint8_t*>(token_binding_message.data()), |
108 token_binding_message.size()); | 113 token_binding_message.size()); |
(...skipping 29 matching lines...) Expand all Loading... |
138 !EVP_PKEY_verify( | 143 !EVP_PKEY_verify( |
139 pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()), | 144 pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()), |
140 signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()), | 145 signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()), |
141 ekm.size())) { | 146 ekm.size())) { |
142 return false; | 147 return false; |
143 } | 148 } |
144 return true; | 149 return true; |
145 } | 150 } |
146 | 151 |
147 } // namespace net | 152 } // namespace net |
OLD | NEW |