#include "components/client_update_protocol/ecdsa.h"
#include <stdint.h>
#include <limits>
#include <memory>
#include "base/base64.h"
#include "base/base64url.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "crypto/random.h"
#include "crypto/secure_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace client_update_protocol {
namespace {
constexpr auto kCupEcdsaTestKey = std::to_array<uint8_t>({
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00, 0x04, 0x24, 0xd3, 0xa3, 0x2b, 0x23, 0x7a, 0x50, 0x7c, 0x94,
0x1a, 0x41, 0xa8, 0xc3, 0xec, 0x42, 0x99, 0x0b, 0x61, 0x41, 0x75, 0x28,
0xf6, 0xc7, 0x7b, 0x44, 0x85, 0xd2, 0xa5, 0x52, 0x0c, 0xef, 0xaf, 0x14,
0x95, 0xb1, 0x9b, 0xff, 0x92, 0x6b, 0x9c, 0x84, 0xa3, 0x49, 0x87, 0xa3,
0x09, 0xcf, 0xe9, 0xc5, 0x0a, 0x28, 0x23, 0xa9, 0x89, 0x4f, 0x35, 0x8b,
0xde, 0x96, 0x5b, 0xe5, 0x30, 0x35, 0x0c,
});
}
class CupEcdsaTest : public testing::Test {
protected:
Ecdsa& CUP() { return cup_; }
private:
Ecdsa cup_{8, kCupEcdsaTestKey};
};
TEST_F(CupEcdsaTest, SignRequest) {
static const char kRequest[] = "TestSequenceForCupEcdsaUnitTest";
static const char kRequestHash[] =
"cde1f7dc1311ed96813057ca321c2f5a17ea2c9c776ee0eb31965f7985a3074a";
static const char kRequestHashWithName[] =
"&cup2hreq="
"cde1f7dc1311ed96813057ca321c2f5a17ea2c9c776ee0eb31965f7985a3074a";
static const char kKeyId[] = "8:";
static const char kKeyIdWithName[] = "cup2key=8:";
std::string query;
CUP().SignRequest(kRequest, &query);
std::string query2;
CUP().SignRequest(kRequest, &query2);
Ecdsa::RequestParameters request_parameters = CUP().SignRequest(kRequest);
EXPECT_TRUE(base::StartsWith(query, kKeyIdWithName));
EXPECT_TRUE(base::StartsWith(query2, kKeyIdWithName));
EXPECT_TRUE(base::StartsWith(request_parameters.query_cup2key, kKeyId));
EXPECT_TRUE(base::EndsWith(query, kRequestHashWithName));
EXPECT_TRUE(base::EndsWith(query2, kRequestHashWithName));
EXPECT_EQ(request_parameters.hash_hex, kRequestHash);
std::string_view nonce_b64 = query;
nonce_b64.remove_prefix(strlen(kKeyIdWithName));
nonce_b64.remove_suffix(strlen(kRequestHashWithName));
std::string nonce;
EXPECT_TRUE(base::Base64UrlDecode(
nonce_b64, base::Base64UrlDecodePolicy::DISALLOW_PADDING, &nonce));
EXPECT_EQ(32u, nonce.size());
nonce_b64 = request_parameters.query_cup2key;
nonce_b64.remove_prefix(strlen(kKeyId));
EXPECT_TRUE(base::Base64UrlDecode(
nonce_b64, base::Base64UrlDecodePolicy::DISALLOW_PADDING, &nonce));
EXPECT_EQ(32u, nonce.size());
nonce_b64 = query2;
nonce_b64.remove_prefix(strlen(kKeyIdWithName));
nonce_b64.remove_suffix(strlen(kRequestHashWithName));
EXPECT_TRUE(base::Base64UrlDecode(
nonce_b64, base::Base64UrlDecodePolicy::DISALLOW_PADDING, &nonce));
EXPECT_EQ(32u, nonce.size());
EXPECT_NE(query, query2);
EXPECT_NE(query, base::StringPrintf("cup2key=%s&cup2hreq=%s",
request_parameters.query_cup2key.c_str(),
request_parameters.hash_hex.c_str()));
}
TEST_F(CupEcdsaTest, ValidateResponse_TestETagParsing) {
std::string query_discard;
CUP().SignRequest("Request_A", &query_discard);
CUP().OverrideNonceForTesting(8, 12345);
EXPECT_TRUE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse("Response_A", ""));
EXPECT_FALSE(CUP().ValidateResponse("Response_A", ":"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458__ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901d__7d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5ff"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"0500"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3048"
"202207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"202207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5ff"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"0406020100020100"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"06200123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"06200123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3046"
"02047fffffff"
"0220ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"30"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3000"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"02207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"
"02207fb15d24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3044"
"022000007f24e66c168ac150458c7ae51f843c4858e27d41be3f9396d4919bbd5656"
"02202291bae598e4a41118ea1df24ce8494d4055b2842dc046e0223f5e17e86bd10e"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
}
TEST_F(CupEcdsaTest, ValidateResponse_TestSigning) {
std::string query_discard;
CUP().SignRequest("Request_A", &query_discard);
CUP().OverrideNonceForTesting(8, 12345);
EXPECT_TRUE(CUP().ValidateResponse(
"Response_A",
"3045022077a2d004f1643a92af5d356877c3434c46519ce32882d6e30ef6d154ee9775e3"
"022100aca63c77d34152bdc0918ae0629e82b59314e5459f607cdc5ac95f1a4b7c31a2"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_B",
"3045022077a2d004f1643a92af5d356877c3434c46519ce32882d6e30ef6d154ee9775e3"
"022100aca63c77d34152bdc0918ae0629e82b59314e5459f607cdc5ac95f1a4b7c31a2"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_B",
"304402206289a7765f0371c7c48796779747f1166707d5937a99af518845f44af95876"
"8c0220139fe935fde3e6b416ee742f91c6a480113762d78d889a2661de37576866d21c"
":80e3ef1b373efe5f2a8383a0cf9c89fb2e0cbb8e85db4813655ff5dc05009e7e"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_B",
"304402206289a7765f0371c7c48796779747f1166707d5937a99af518845f44af95876"
"8c0220139fe935fde3e6b416ee742f91c6a480113762d78d889a2661de37576866d21c"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
EXPECT_FALSE(CUP().ValidateResponse(
"Response_A",
"3046022100d3bbb1fb4451c8e04a07fe95404cc39121ed0e0bc084f87de19d52eee50a97"
"bf022100dd7d41d467be2af98d9116b0c7ba09740d54578c02a02f74da5f089834be3403"
":2727bc2b3c33feb6800a830f4055901dd87d65a84184c5fbeb3f816db0a243f5"));
}
}