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

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

Issue 1781003003: Implement referred Token Bindings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
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 "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 "base/strings/string_number_conversions.h"
davidben 2016/03/15 22:49:56 Where is this used?
nharper 2016/03/16 17:49:22 I used it for some temporary debugging and forgot
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
21 enum TokenBindingType {
22 TB_TYPE_PROVIDED = 0,
23 TB_TYPE_REFERRED = 1,
24 };
25
26 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { 22 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) {
27 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); 23 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key());
28 DCHECK(ec_key); 24 DCHECK(ec_key);
29 25
30 CBB ec_point; 26 CBB ec_point;
31 return CBB_add_u8(out, TB_PARAM_ECDSAP256) && 27 return CBB_add_u8(out, TB_PARAM_ECDSAP256) &&
32 CBB_add_u8_length_prefixed(out, &ec_point) && 28 CBB_add_u8_length_prefixed(out, &ec_point) &&
33 EC_POINT_point2cbb(&ec_point, EC_KEY_get0_group(ec_key), 29 EC_POINT_point2cbb(&ec_point, EC_KEY_get0_group(ec_key),
34 EC_KEY_get0_public_key(ec_key), 30 EC_KEY_get0_public_key(ec_key),
35 POINT_CONVERSION_UNCOMPRESSED, nullptr) && 31 POINT_CONVERSION_UNCOMPRESSED, nullptr) &&
36 CBB_flush(out); 32 CBB_flush(out);
37 } 33 }
38 34
39 Error BuildTokenBinding(TokenBindingType type,
40 crypto::ECPrivateKey* key,
41 const std::vector<uint8_t>& signed_ekm,
42 std::string* out) {
43 uint8_t* out_data;
44 size_t out_len;
45 CBB token_binding;
46 if (!CBB_init(&token_binding, 0) || !CBB_add_u8(&token_binding, type) ||
47 !BuildTokenBindingID(key, &token_binding) ||
48 !CBB_add_u16(&token_binding, signed_ekm.size()) ||
49 !CBB_add_bytes(&token_binding, signed_ekm.data(), signed_ekm.size()) ||
50 // 0-length extensions
51 !CBB_add_u16(&token_binding, 0) ||
52 !CBB_finish(&token_binding, &out_data, &out_len)) {
53 CBB_cleanup(&token_binding);
54 return ERR_FAILED;
55 }
56 out->assign(reinterpret_cast<char*>(out_data), out_len);
57 OPENSSL_free(out_data);
58 return OK;
59 }
60
61 } // namespace 35 } // namespace
62 36
63 bool IsTokenBindingSupported() { 37 bool IsTokenBindingSupported() {
64 return true; 38 return true;
65 } 39 }
66 40
67 bool SignTokenBindingEkm(base::StringPiece ekm, 41 bool SignTokenBindingEkm(base::StringPiece ekm,
68 crypto::ECPrivateKey* key, 42 crypto::ECPrivateKey* key,
69 std::vector<uint8_t>* out) { 43 std::vector<uint8_t>* out) {
70 size_t sig_len; 44 size_t sig_len;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 size_t out_len; 77 size_t out_len;
104 if (!CBB_finish(&tb_message, &out_data, &out_len)) { 78 if (!CBB_finish(&tb_message, &out_data, &out_len)) {
105 CBB_cleanup(&tb_message); 79 CBB_cleanup(&tb_message);
106 return ERR_FAILED; 80 return ERR_FAILED;
107 } 81 }
108 out->assign(reinterpret_cast<char*>(out_data), out_len); 82 out->assign(reinterpret_cast<char*>(out_data), out_len);
109 OPENSSL_free(out_data); 83 OPENSSL_free(out_data);
110 return OK; 84 return OK;
111 } 85 }
112 86
113 Error BuildProvidedTokenBinding(crypto::ECPrivateKey* key, 87 Error BuildTokenBinding(TokenBindingType type,
114 const std::vector<uint8_t>& signed_ekm, 88 crypto::ECPrivateKey* key,
115 std::string* out) { 89 const std::vector<uint8_t>& signed_ekm,
116 return BuildTokenBinding(TB_TYPE_PROVIDED, key, signed_ekm, out); 90 std::string* out) {
91 uint8_t* out_data;
92 size_t out_len;
93 CBB token_binding;
94 if (!CBB_init(&token_binding, 0) || !CBB_add_u8(&token_binding, type) ||
95 !BuildTokenBindingID(key, &token_binding) ||
96 !CBB_add_u16(&token_binding, signed_ekm.size()) ||
97 !CBB_add_bytes(&token_binding, signed_ekm.data(), signed_ekm.size()) ||
98 // 0-length extensions
99 !CBB_add_u16(&token_binding, 0) ||
100 !CBB_finish(&token_binding, &out_data, &out_len)) {
101 CBB_cleanup(&token_binding);
102 return ERR_FAILED;
103 }
104 out->assign(reinterpret_cast<char*>(out_data), out_len);
105 OPENSSL_free(out_data);
106 return OK;
117 } 107 }
118 108
109 TokenBinding::TokenBinding() {}
110
119 bool ParseTokenBindingMessage(base::StringPiece token_binding_message, 111 bool ParseTokenBindingMessage(base::StringPiece token_binding_message,
120 base::StringPiece* ec_point_out, 112 std::vector<TokenBinding>* token_bindings) {
121 base::StringPiece* signature_out) { 113 CBS tb_message, tb, ec_point, signature, extensions;
122 CBS tb_message, tb, ec_point, signature;
123 uint8_t tb_type, tb_param; 114 uint8_t tb_type, tb_param;
124 CBS_init(&tb_message, 115 CBS_init(&tb_message,
125 reinterpret_cast<const uint8_t*>(token_binding_message.data()), 116 reinterpret_cast<const uint8_t*>(token_binding_message.data()),
126 token_binding_message.size()); 117 token_binding_message.size());
127 if (!CBS_get_u16_length_prefixed(&tb_message, &tb) || 118 if (!CBS_get_u16_length_prefixed(&tb_message, &tb))
128 !CBS_get_u8(&tb, &tb_type) || !CBS_get_u8(&tb, &tb_param) ||
129 !CBS_get_u8_length_prefixed(&tb, &ec_point) ||
130 !CBS_get_u16_length_prefixed(&tb, &signature) ||
131 tb_type != TB_TYPE_PROVIDED || tb_param != TB_PARAM_ECDSAP256) {
132 return false; 119 return false;
120 while (CBS_len(&tb)) {
121 if (!CBS_get_u8(&tb, &tb_type) || !CBS_get_u8(&tb, &tb_param) ||
122 !CBS_get_u8_length_prefixed(&tb, &ec_point) ||
123 !CBS_get_u16_length_prefixed(&tb, &signature) ||
124 !CBS_get_u16_length_prefixed(&tb, &extensions) ||
125 tb_param != TB_PARAM_ECDSAP256) {
126 return false;
127 }
128
129 TokenBinding token_binding;
130 token_binding.type = TokenBindingType(tb_type);
davidben 2016/03/15 22:49:56 Since this is an enum, probably you should validat
nharper 2016/03/16 17:49:22 Done.
131 token_binding.ec_point = base::StringPiece(
132 reinterpret_cast<const char*>(CBS_data(&ec_point)), CBS_len(&ec_point));
133 token_binding.signature =
134 base::StringPiece(reinterpret_cast<const char*>(CBS_data(&signature)),
135 CBS_len(&signature));
136 token_bindings->push_back(token_binding);
133 } 137 }
134
135 *ec_point_out = base::StringPiece(
136 reinterpret_cast<const char*>(CBS_data(&ec_point)), CBS_len(&ec_point));
137 *signature_out = base::StringPiece(
138 reinterpret_cast<const char*>(CBS_data(&signature)), CBS_len(&signature));
139 return true; 138 return true;
140 } 139 }
141 140
142 bool VerifyEKMSignature(base::StringPiece ec_point, 141 bool VerifyEKMSignature(base::StringPiece ec_point,
143 base::StringPiece signature, 142 base::StringPiece signature,
144 base::StringPiece ekm) { 143 base::StringPiece ekm) {
145 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); 144 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
146 EC_KEY* keyp = key.get(); 145 EC_KEY* keyp = key.get();
147 const uint8_t* ec_point_data = 146 const uint8_t* ec_point_data =
148 reinterpret_cast<const uint8_t*>(ec_point.data()); 147 reinterpret_cast<const uint8_t*>(ec_point.data());
149 if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get()) 148 if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get())
150 return false; 149 return false;
151 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); 150 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
152 if (!EVP_PKEY_assign_EC_KEY(pkey.get(), key.release())) 151 if (!EVP_PKEY_assign_EC_KEY(pkey.get(), key.release()))
153 return false; 152 return false;
154 crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); 153 crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
155 if (!EVP_PKEY_verify_init(pctx.get()) || 154 if (!EVP_PKEY_verify_init(pctx.get()) ||
156 !EVP_PKEY_verify( 155 !EVP_PKEY_verify(
157 pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()), 156 pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
158 signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()), 157 signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()),
159 ekm.size())) { 158 ekm.size())) {
160 return false; 159 return false;
161 } 160 }
162 return true; 161 return true;
163 } 162 }
164 163
165 } // namespace net 164 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698