QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h" |
| 6 | |
vasilvv | 872e7a3 | 2019-03-12 16:42:44 -0700 | [diff] [blame] | 7 | #include <string> |
| 8 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 9 | #include "net/third_party/quiche/src/quic/core/quic_utils.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 10 | #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 11 | #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" |
bnc | 4e9283d | 2019-12-17 07:08:57 -0800 | [diff] [blame] | 12 | #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" |
dmcardle | 904ef18 | 2019-12-13 08:34:33 -0800 | [diff] [blame] | 13 | #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h" |
dmcardle | 8f7df53 | 2020-01-07 13:28:57 -0800 | [diff] [blame] | 14 | #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 15 | |
| 16 | namespace quic { |
| 17 | namespace test { |
| 18 | namespace { |
| 19 | |
| 20 | class CryptoUtilsTest : public QuicTest {}; |
| 21 | |
| 22 | TEST_F(CryptoUtilsTest, TestExportKeyingMaterial) { |
| 23 | const struct TestVector { |
| 24 | // Input (strings of hexadecimal digits): |
| 25 | const char* subkey_secret; |
| 26 | const char* label; |
| 27 | const char* context; |
| 28 | size_t result_len; |
| 29 | |
| 30 | // Expected output (string of hexadecimal digits): |
| 31 | const char* expected; // Null if it should fail. |
| 32 | } test_vector[] = { |
| 33 | // Try a typical input |
| 34 | {"4823c1189ecc40fce888fbb4cf9ae6254f19ba12e6d9af54788f195a6f509ca3", |
| 35 | "e934f78d7a71dd85420fceeb8cea0317", |
| 36 | "b8d766b5d3c8aba0009c7ed3de553eba53b4de1030ea91383dcdf724cd8b7217", 32, |
| 37 | "a9979da0d5f1c1387d7cbe68f5c4163ddb445a03c4ad6ee72cb49d56726d679e"}, |
| 38 | // Don't let the label contain nulls |
| 39 | {"14fe51e082ffee7d1b4d8d4ab41f8c55", "3132333435363700", |
| 40 | "58585858585858585858585858585858", 16, nullptr}, |
| 41 | // Make sure nulls in the context are fine |
| 42 | {"d862c2e36b0a42f7827c67ebc8d44df7", "7a5b95e4e8378123", |
| 43 | "4142434445464700", 16, "12d418c6d0738a2e4d85b2d0170f76e1"}, |
| 44 | // ... and give a different result than without |
| 45 | {"d862c2e36b0a42f7827c67ebc8d44df7", "7a5b95e4e8378123", "41424344454647", |
| 46 | 16, "abfa1c479a6e3ffb98a11dee7d196408"}, |
| 47 | // Try weird lengths |
| 48 | {"d0ec8a34f6cc9a8c96", "49711798cc6251", |
| 49 | "933d4a2f30d22f089cfba842791116adc121e0", 23, |
| 50 | "c9a46ed0757bd1812f1f21b4d41e62125fec8364a21db7"}, |
| 51 | }; |
| 52 | |
bnc | 4e9283d | 2019-12-17 07:08:57 -0800 | [diff] [blame] | 53 | for (size_t i = 0; i < QUICHE_ARRAYSIZE(test_vector); i++) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 54 | // Decode the test vector. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 55 | std::string subkey_secret = |
dmcardle | 904ef18 | 2019-12-13 08:34:33 -0800 | [diff] [blame] | 56 | quiche::QuicheTextUtils::HexDecode(test_vector[i].subkey_secret); |
| 57 | std::string label = |
| 58 | quiche::QuicheTextUtils::HexDecode(test_vector[i].label); |
| 59 | std::string context = |
| 60 | quiche::QuicheTextUtils::HexDecode(test_vector[i].context); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 61 | size_t result_len = test_vector[i].result_len; |
| 62 | bool expect_ok = test_vector[i].expected != nullptr; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 63 | std::string expected; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 64 | if (expect_ok) { |
dmcardle | 904ef18 | 2019-12-13 08:34:33 -0800 | [diff] [blame] | 65 | expected = quiche::QuicheTextUtils::HexDecode(test_vector[i].expected); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 66 | } |
| 67 | |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 68 | std::string result; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 69 | bool ok = CryptoUtils::ExportKeyingMaterial(subkey_secret, label, context, |
| 70 | result_len, &result); |
| 71 | EXPECT_EQ(expect_ok, ok); |
| 72 | if (expect_ok) { |
| 73 | EXPECT_EQ(result_len, result.length()); |
dmcardle | 8f7df53 | 2020-01-07 13:28:57 -0800 | [diff] [blame] | 74 | quiche::test::CompareCharArraysWithHexError( |
| 75 | "HKDF output", result.data(), result.length(), expected.data(), |
| 76 | expected.length()); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 77 | } |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | TEST_F(CryptoUtilsTest, HandshakeFailureReasonToString) { |
| 82 | EXPECT_STREQ("HANDSHAKE_OK", |
| 83 | CryptoUtils::HandshakeFailureReasonToString(HANDSHAKE_OK)); |
| 84 | EXPECT_STREQ("CLIENT_NONCE_UNKNOWN_FAILURE", |
| 85 | CryptoUtils::HandshakeFailureReasonToString( |
| 86 | CLIENT_NONCE_UNKNOWN_FAILURE)); |
| 87 | EXPECT_STREQ("CLIENT_NONCE_INVALID_FAILURE", |
| 88 | CryptoUtils::HandshakeFailureReasonToString( |
| 89 | CLIENT_NONCE_INVALID_FAILURE)); |
| 90 | EXPECT_STREQ("CLIENT_NONCE_NOT_UNIQUE_FAILURE", |
| 91 | CryptoUtils::HandshakeFailureReasonToString( |
| 92 | CLIENT_NONCE_NOT_UNIQUE_FAILURE)); |
| 93 | EXPECT_STREQ("CLIENT_NONCE_INVALID_ORBIT_FAILURE", |
| 94 | CryptoUtils::HandshakeFailureReasonToString( |
| 95 | CLIENT_NONCE_INVALID_ORBIT_FAILURE)); |
| 96 | EXPECT_STREQ("CLIENT_NONCE_INVALID_TIME_FAILURE", |
| 97 | CryptoUtils::HandshakeFailureReasonToString( |
| 98 | CLIENT_NONCE_INVALID_TIME_FAILURE)); |
| 99 | EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT", |
| 100 | CryptoUtils::HandshakeFailureReasonToString( |
| 101 | CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT)); |
| 102 | EXPECT_STREQ("CLIENT_NONCE_STRIKE_REGISTER_FAILURE", |
| 103 | CryptoUtils::HandshakeFailureReasonToString( |
| 104 | CLIENT_NONCE_STRIKE_REGISTER_FAILURE)); |
| 105 | EXPECT_STREQ("SERVER_NONCE_DECRYPTION_FAILURE", |
| 106 | CryptoUtils::HandshakeFailureReasonToString( |
| 107 | SERVER_NONCE_DECRYPTION_FAILURE)); |
| 108 | EXPECT_STREQ("SERVER_NONCE_INVALID_FAILURE", |
| 109 | CryptoUtils::HandshakeFailureReasonToString( |
| 110 | SERVER_NONCE_INVALID_FAILURE)); |
| 111 | EXPECT_STREQ("SERVER_NONCE_NOT_UNIQUE_FAILURE", |
| 112 | CryptoUtils::HandshakeFailureReasonToString( |
| 113 | SERVER_NONCE_NOT_UNIQUE_FAILURE)); |
| 114 | EXPECT_STREQ("SERVER_NONCE_INVALID_TIME_FAILURE", |
| 115 | CryptoUtils::HandshakeFailureReasonToString( |
| 116 | SERVER_NONCE_INVALID_TIME_FAILURE)); |
| 117 | EXPECT_STREQ("SERVER_NONCE_REQUIRED_FAILURE", |
| 118 | CryptoUtils::HandshakeFailureReasonToString( |
| 119 | SERVER_NONCE_REQUIRED_FAILURE)); |
| 120 | EXPECT_STREQ("SERVER_CONFIG_INCHOATE_HELLO_FAILURE", |
| 121 | CryptoUtils::HandshakeFailureReasonToString( |
| 122 | SERVER_CONFIG_INCHOATE_HELLO_FAILURE)); |
| 123 | EXPECT_STREQ("SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE", |
| 124 | CryptoUtils::HandshakeFailureReasonToString( |
| 125 | SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE)); |
| 126 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_INVALID_FAILURE", |
| 127 | CryptoUtils::HandshakeFailureReasonToString( |
| 128 | SOURCE_ADDRESS_TOKEN_INVALID_FAILURE)); |
| 129 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE", |
| 130 | CryptoUtils::HandshakeFailureReasonToString( |
| 131 | SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE)); |
| 132 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_PARSE_FAILURE", |
| 133 | CryptoUtils::HandshakeFailureReasonToString( |
| 134 | SOURCE_ADDRESS_TOKEN_PARSE_FAILURE)); |
| 135 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE", |
| 136 | CryptoUtils::HandshakeFailureReasonToString( |
| 137 | SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE)); |
| 138 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE", |
| 139 | CryptoUtils::HandshakeFailureReasonToString( |
| 140 | SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE)); |
| 141 | EXPECT_STREQ("SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE", |
| 142 | CryptoUtils::HandshakeFailureReasonToString( |
| 143 | SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE)); |
| 144 | EXPECT_STREQ("INVALID_EXPECTED_LEAF_CERTIFICATE", |
| 145 | CryptoUtils::HandshakeFailureReasonToString( |
| 146 | INVALID_EXPECTED_LEAF_CERTIFICATE)); |
| 147 | EXPECT_STREQ("MAX_FAILURE_REASON", |
| 148 | CryptoUtils::HandshakeFailureReasonToString(MAX_FAILURE_REASON)); |
| 149 | EXPECT_STREQ( |
| 150 | "INVALID_HANDSHAKE_FAILURE_REASON", |
| 151 | CryptoUtils::HandshakeFailureReasonToString( |
| 152 | static_cast<HandshakeFailureReason>(MAX_FAILURE_REASON + 1))); |
| 153 | } |
| 154 | |
nharper | c1bbfe6 | 2019-09-27 16:48:40 -0700 | [diff] [blame] | 155 | TEST_F(CryptoUtilsTest, AuthTagLengths) { |
| 156 | for (const auto& version : AllSupportedVersions()) { |
| 157 | for (QuicTag algo : {kAESG, kCC20}) { |
| 158 | SCOPED_TRACE(version); |
| 159 | std::unique_ptr<QuicEncrypter> encrypter( |
| 160 | QuicEncrypter::Create(version, algo)); |
| 161 | size_t auth_tag_size = 12; |
| 162 | if (version.UsesInitialObfuscators()) { |
| 163 | auth_tag_size = 16; |
| 164 | } |
| 165 | EXPECT_EQ(encrypter->GetCiphertextSize(0), auth_tag_size); |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 170 | } // namespace |
| 171 | } // namespace test |
| 172 | } // namespace quic |