Index: net/ssl/token_binding.cc |
diff --git a/net/ssl/token_binding.cc b/net/ssl/token_binding.cc |
index 2c9a79f4a03050ee0db58385a6d8c66e7a3584e6..0c6dd81fafc3b1649a944ec70e7e8685f8bc2221 100644 |
--- a/net/ssl/token_binding.cc |
+++ b/net/ssl/token_binding.cc |
@@ -31,23 +31,46 @@ bool BuildTokenBindingID(crypto::ECPrivateKey* key, CBB* out) { |
CBB_flush(out); |
} |
+bool ECDSA_SIGToRaw(ECDSA_SIG* ec_sig, EC_KEY* ec, std::vector<uint8_t>* out) { |
+ const EC_GROUP* group = EC_KEY_get0_group(ec); |
+ const BIGNUM* order = EC_GROUP_get0_order(group); |
+ size_t len = BN_num_bytes(order); |
+ out->resize(2 * len); |
+ if (!BN_bn2bin_padded(out->data(), len, ec_sig->r) || |
+ !BN_bn2bin_padded(out->data() + len, len, ec_sig->s)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+ECDSA_SIG* RawToECDSA_SIG(EC_KEY* ec, base::StringPiece sig) { |
+ crypto::ScopedECDSA_SIG raw_sig(ECDSA_SIG_new()); |
+ const EC_GROUP* group = EC_KEY_get0_group(ec); |
+ const BIGNUM* order = EC_GROUP_get0_order(group); |
+ size_t group_size = BN_num_bytes(order); |
+ if (sig.size() != group_size * 2) |
+ return nullptr; |
+ const uint8_t* sigp = reinterpret_cast<const uint8_t*>(sig.data()); |
+ if (!BN_bin2bn(sigp, group_size, raw_sig->r) || |
+ !BN_bin2bn(sigp + group_size, group_size, raw_sig->s)) { |
+ return nullptr; |
+ } |
+ return raw_sig.release(); |
+} |
+ |
} // namespace |
bool SignTokenBindingEkm(base::StringPiece ekm, |
crypto::ECPrivateKey* key, |
std::vector<uint8_t>* out) { |
- size_t sig_len; |
const uint8_t* ekm_data = reinterpret_cast<const uint8_t*>(ekm.data()); |
- crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(key->key(), nullptr)); |
- if (!EVP_PKEY_sign_init(pctx.get()) || |
- !EVP_PKEY_sign(pctx.get(), nullptr, &sig_len, ekm_data, ekm.size())) { |
+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key->key()); |
+ if (!ec_key) |
return false; |
- } |
- out->resize(sig_len); |
- if (!EVP_PKEY_sign(pctx.get(), out->data(), &sig_len, ekm_data, ekm.size())) |
+ crypto::ScopedECDSA_SIG sig(ECDSA_do_sign(ekm_data, ekm.size(), ec_key)); |
+ if (!sig) |
return false; |
- out->resize(sig_len); |
- return true; |
+ return ECDSA_SIGToRaw(sig.get(), ec_key, out); |
} |
Error BuildTokenBindingMessageFromTokenBindings( |
@@ -145,18 +168,11 @@ bool VerifyEKMSignature(base::StringPiece ec_point, |
reinterpret_cast<const uint8_t*>(ec_point.data()); |
if (o2i_ECPublicKey(&keyp, &ec_point_data, ec_point.size()) != key.get()) |
return false; |
- crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
- if (!EVP_PKEY_assign_EC_KEY(pkey.get(), key.release())) |
+ crypto::ScopedECDSA_SIG sig(RawToECDSA_SIG(keyp, signature)); |
+ if (!sig) |
return false; |
- crypto::ScopedEVP_PKEY_CTX pctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); |
- if (!EVP_PKEY_verify_init(pctx.get()) || |
- !EVP_PKEY_verify( |
- pctx.get(), reinterpret_cast<const uint8_t*>(signature.data()), |
- signature.size(), reinterpret_cast<const uint8_t*>(ekm.data()), |
- ekm.size())) { |
- return false; |
- } |
- return true; |
+ return !!ECDSA_do_verify(reinterpret_cast<const uint8_t*>(ekm.data()), |
+ ekm.size(), sig.get(), keyp); |
} |
} // namespace net |