| 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/bn.h> |
| 7 #include <openssl/bytestring.h> | 8 #include <openssl/bytestring.h> |
| 8 #include <openssl/ec.h> | 9 #include <openssl/ec.h> |
| 9 #include <openssl/ec_key.h> | 10 #include <openssl/ec_key.h> |
| 11 #include <openssl/ecdsa.h> |
| 10 #include <openssl/evp.h> | 12 #include <openssl/evp.h> |
| 11 #include <openssl/mem.h> | 13 #include <openssl/mem.h> |
| 12 | 14 |
| 13 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 14 #include "crypto/ec_private_key.h" | 16 #include "crypto/ec_private_key.h" |
| 15 #include "crypto/scoped_openssl_types.h" | |
| 16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 17 #include "net/ssl/ssl_config.h" | 18 #include "net/ssl/ssl_config.h" |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 const size_t kUncompressedPointLen = 65; | 24 const size_t kUncompressedPointLen = 65; |
| 24 | 25 |
| 25 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { | 26 bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 47 size_t len = BN_num_bytes(order); | 48 size_t len = BN_num_bytes(order); |
| 48 out->resize(2 * len); | 49 out->resize(2 * len); |
| 49 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || | 50 if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || |
| 50 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { | 51 !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { |
| 51 return false; | 52 return false; |
| 52 } | 53 } |
| 53 return true; | 54 return true; |
| 54 } | 55 } |
| 55 | 56 |
| 56 ECDSA_SIG* RawToECDSA_SIG(EC_KEY* ec, base::StringPiece sig) { | 57 ECDSA_SIG* RawToECDSA_SIG(EC_KEY* ec, base::StringPiece sig) { |
| 57 crypto::ScopedECDSA_SIG raw_sig(ECDSA_SIG_new()); | 58 bssl::UniquePtr<ECDSA_SIG> raw_sig(ECDSA_SIG_new()); |
| 58 const EC_GROUP* group = EC_KEY_get0_group(ec); | 59 const EC_GROUP* group = EC_KEY_get0_group(ec); |
| 59 const BIGNUM* order = EC_GROUP_get0_order(group); | 60 const BIGNUM* order = EC_GROUP_get0_order(group); |
| 60 size_t group_size = BN_num_bytes(order); | 61 size_t group_size = BN_num_bytes(order); |
| 61 if (sig.size() != group_size * 2) | 62 if (sig.size() != group_size * 2) |
| 62 return nullptr; | 63 return nullptr; |
| 63 const uint8_t* sigp = reinterpret_cast<const uint8_t*>(sig.data()); | 64 const uint8_t* sigp = reinterpret_cast<const uint8_t*>(sig.data()); |
| 64 if (!BN_bin2bn(sigp, group_size, raw_sig->r) || | 65 if (!BN_bin2bn(sigp, group_size, raw_sig->r) || |
| 65 !BN_bin2bn(sigp + group_size, group_size, raw_sig->s)) { | 66 !BN_bin2bn(sigp + group_size, group_size, raw_sig->s)) { |
| 66 return nullptr; | 67 return nullptr; |
| 67 } | 68 } |
| 68 return raw_sig.release(); | 69 return raw_sig.release(); |
| 69 } | 70 } |
| 70 | 71 |
| 71 } // namespace | 72 } // namespace |
| 72 | 73 |
| 73 bool CreateTokenBindingSignature(base::StringPiece ekm, | 74 bool CreateTokenBindingSignature(base::StringPiece ekm, |
| 74 TokenBindingType type, | 75 TokenBindingType type, |
| 75 crypto::ECPrivateKey* key, | 76 crypto::ECPrivateKey* key, |
| 76 std::vector<uint8_t>* out) { | 77 std::vector<uint8_t>* out) { |
| 77 crypto::ScopedEVP_MD_CTX digest_ctx(EVP_MD_CTX_create()); | 78 bssl::ScopedEVP_MD_CTX digest_ctx; |
| 78 uint8_t tb_type = static_cast<uint8_t>(type); | 79 uint8_t tb_type = static_cast<uint8_t>(type); |
| 79 uint8_t key_type = static_cast<uint8_t>(TB_PARAM_ECDSAP256); | 80 uint8_t key_type = static_cast<uint8_t>(TB_PARAM_ECDSAP256); |
| 80 uint8_t digest[EVP_MAX_MD_SIZE]; | 81 uint8_t digest[EVP_MAX_MD_SIZE]; |
| 81 unsigned int digest_len; | 82 unsigned int digest_len; |
| 82 if (!EVP_DigestInit(digest_ctx.get(), EVP_sha256()) || | 83 if (!EVP_DigestInit(digest_ctx.get(), EVP_sha256()) || |
| 83 !EVP_DigestUpdate(digest_ctx.get(), &tb_type, 1) || | 84 !EVP_DigestUpdate(digest_ctx.get(), &tb_type, 1) || |
| 84 !EVP_DigestUpdate(digest_ctx.get(), &key_type, 1) || | 85 !EVP_DigestUpdate(digest_ctx.get(), &key_type, 1) || |
| 85 !EVP_DigestUpdate(digest_ctx.get(), ekm.data(), ekm.size()) || | 86 !EVP_DigestUpdate(digest_ctx.get(), ekm.data(), ekm.size()) || |
| 86 !EVP_DigestFinal_ex(digest_ctx.get(), digest, &digest_len)) { | 87 !EVP_DigestFinal_ex(digest_ctx.get(), digest, &digest_len)) { |
| 87 return false; | 88 return false; |
| 88 } | 89 } |
| 89 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); | 90 EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); |
| 90 if (!ec_key) | 91 if (!ec_key) |
| 91 return false; | 92 return false; |
| 92 crypto::ScopedECDSA_SIG sig(ECDSA_do_sign(digest, digest_len, ec_key)); | 93 bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign(digest, digest_len, ec_key)); |
| 93 if (!sig) | 94 if (!sig) |
| 94 return false; | 95 return false; |
| 95 return ECDSA_SIGToRaw(sig.get(), ec_key, out); | 96 return ECDSA_SIGToRaw(sig.get(), ec_key, out); |
| 96 } | 97 } |
| 97 | 98 |
| 98 Error BuildTokenBindingMessageFromTokenBindings( | 99 Error BuildTokenBindingMessageFromTokenBindings( |
| 99 const std::vector<base::StringPiece>& token_bindings, | 100 const std::vector<base::StringPiece>& token_bindings, |
| 100 std::string* out) { | 101 std::string* out) { |
| 101 CBB tb_message, child; | 102 CBB tb_message, child; |
| 102 if (!CBB_init(&tb_message, 0) || | 103 if (!CBB_init(&tb_message, 0) || |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 | 186 |
| 186 bool VerifyTokenBindingSignature(base::StringPiece ec_point, | 187 bool VerifyTokenBindingSignature(base::StringPiece ec_point, |
| 187 base::StringPiece signature, | 188 base::StringPiece signature, |
| 188 TokenBindingType type, | 189 TokenBindingType type, |
| 189 base::StringPiece ekm) { | 190 base::StringPiece ekm) { |
| 190 if (ec_point.size() != kUncompressedPointLen - 1) | 191 if (ec_point.size() != kUncompressedPointLen - 1) |
| 191 return false; | 192 return false; |
| 192 uint8_t x9_62_ec_point[kUncompressedPointLen]; | 193 uint8_t x9_62_ec_point[kUncompressedPointLen]; |
| 193 x9_62_ec_point[0] = 4; | 194 x9_62_ec_point[0] = 4; |
| 194 memcpy(x9_62_ec_point + 1, ec_point.data(), kUncompressedPointLen - 1); | 195 memcpy(x9_62_ec_point + 1, ec_point.data(), kUncompressedPointLen - 1); |
| 195 crypto::ScopedEC_Key key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); | 196 bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); |
| 196 EC_KEY* keyp = key.get(); | 197 EC_KEY* keyp = key.get(); |
| 197 crypto::ScopedEC_POINT pub_key(EC_POINT_new(EC_KEY_get0_group(keyp))); | 198 bssl::UniquePtr<EC_POINT> pub_key(EC_POINT_new(EC_KEY_get0_group(keyp))); |
| 198 if (!EC_POINT_oct2point(EC_KEY_get0_group(keyp), pub_key.get(), | 199 if (!EC_POINT_oct2point(EC_KEY_get0_group(keyp), pub_key.get(), |
| 199 x9_62_ec_point, kUncompressedPointLen, nullptr) || | 200 x9_62_ec_point, kUncompressedPointLen, nullptr) || |
| 200 !EC_KEY_set_public_key(keyp, pub_key.get())) { | 201 !EC_KEY_set_public_key(keyp, pub_key.get())) { |
| 201 return false; | 202 return false; |
| 202 } | 203 } |
| 203 | 204 |
| 204 crypto::ScopedEVP_MD_CTX digest_ctx(EVP_MD_CTX_create()); | 205 bssl::ScopedEVP_MD_CTX digest_ctx; |
| 205 uint8_t tb_type = static_cast<uint8_t>(type); | 206 uint8_t tb_type = static_cast<uint8_t>(type); |
| 206 uint8_t key_type = static_cast<uint8_t>(TB_PARAM_ECDSAP256); | 207 uint8_t key_type = static_cast<uint8_t>(TB_PARAM_ECDSAP256); |
| 207 uint8_t digest[EVP_MAX_MD_SIZE]; | 208 uint8_t digest[EVP_MAX_MD_SIZE]; |
| 208 unsigned int digest_len; | 209 unsigned int digest_len; |
| 209 if (!EVP_DigestInit(digest_ctx.get(), EVP_sha256()) || | 210 if (!EVP_DigestInit(digest_ctx.get(), EVP_sha256()) || |
| 210 !EVP_DigestUpdate(digest_ctx.get(), &tb_type, 1) || | 211 !EVP_DigestUpdate(digest_ctx.get(), &tb_type, 1) || |
| 211 !EVP_DigestUpdate(digest_ctx.get(), &key_type, 1) || | 212 !EVP_DigestUpdate(digest_ctx.get(), &key_type, 1) || |
| 212 !EVP_DigestUpdate(digest_ctx.get(), ekm.data(), ekm.size()) || | 213 !EVP_DigestUpdate(digest_ctx.get(), ekm.data(), ekm.size()) || |
| 213 !EVP_DigestFinal_ex(digest_ctx.get(), digest, &digest_len)) { | 214 !EVP_DigestFinal_ex(digest_ctx.get(), digest, &digest_len)) { |
| 214 return false; | 215 return false; |
| 215 } | 216 } |
| 216 | 217 |
| 217 crypto::ScopedECDSA_SIG sig(RawToECDSA_SIG(keyp, signature)); | 218 bssl::UniquePtr<ECDSA_SIG> sig(RawToECDSA_SIG(keyp, signature)); |
| 218 if (!sig) | 219 if (!sig) |
| 219 return false; | 220 return false; |
| 220 return !!ECDSA_do_verify(digest, digest_len, sig.get(), keyp); | 221 return !!ECDSA_do_verify(digest, digest_len, sig.get(), keyp); |
| 221 } | 222 } |
| 222 | 223 |
| 223 } // namespace net | 224 } // namespace net |
| OLD | NEW |