OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/gcm_driver/crypto/encryption_header_parsers.h" |
| 6 |
| 7 #include <vector> |
| 8 |
| 9 #include "base/macros.h" |
| 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 |
| 13 namespace gcm { |
| 14 |
| 15 namespace { |
| 16 |
| 17 const uint64_t kDefaultRecordSize = 4096; |
| 18 |
| 19 TEST(EncryptionHeaderParsersTest, ParseValidEncryptionHeaders) { |
| 20 struct { |
| 21 const char* const header; |
| 22 const char* const parsed_keyid; |
| 23 const char* const parsed_salt; |
| 24 uint64_t parsed_rs; |
| 25 } expected_results[] = { |
| 26 { "keyid=foo;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024", |
| 27 "foo", "sixteencoolbytes", 1024 }, |
| 28 { "keyid=foo; salt=c2l4dGVlbmNvb2xieXRlcw; rs=1024", |
| 29 "foo", "sixteencoolbytes", 1024 }, |
| 30 { "KEYID=foo;SALT=c2l4dGVlbmNvb2xieXRlcw;RS=1024", |
| 31 "foo", "sixteencoolbytes", 1024 }, |
| 32 { " keyid = foo ; salt = c2l4dGVlbmNvb2xieXRlcw ; rs = 1024 ", |
| 33 "foo", "sixteencoolbytes", 1024 }, |
| 34 { "keyid=foo", "foo", "", kDefaultRecordSize }, |
| 35 { "keyid=foo;", "foo", "", kDefaultRecordSize }, |
| 36 { "keyid=\"foo\"", "foo", "", kDefaultRecordSize }, |
| 37 { "keyid='foo'", "foo", "", kDefaultRecordSize }, |
| 38 { "salt=c2l4dGVlbmNvb2xieXRlcw", |
| 39 "", "sixteencoolbytes", kDefaultRecordSize }, |
| 40 { "rs=2048", "", "", 2048 }, |
| 41 { "keyid=foo;someothervalue=1;rs=42", "foo", "", 42 }, |
| 42 { "keyid=foo;keyid=bar", "bar", "", kDefaultRecordSize }, |
| 43 }; |
| 44 |
| 45 for (size_t i = 0; i < arraysize(expected_results); i++) { |
| 46 SCOPED_TRACE(i); |
| 47 |
| 48 std::vector<EncryptionHeaderValues> values; |
| 49 ASSERT_TRUE(ParseEncryptionHeader(expected_results[i].header, &values)); |
| 50 ASSERT_EQ(1u, values.size()); |
| 51 |
| 52 EXPECT_EQ(expected_results[i].parsed_keyid, values[0].keyid); |
| 53 EXPECT_EQ(expected_results[i].parsed_salt, values[0].salt); |
| 54 EXPECT_EQ(expected_results[i].parsed_rs, values[0].rs); |
| 55 } |
| 56 } |
| 57 |
| 58 TEST(EncryptionHeaderParsersTest, ParseValidMultiValueEncryptionHeaders) { |
| 59 const size_t kNumberOfValues = 2u; |
| 60 |
| 61 struct { |
| 62 const char* const header; |
| 63 struct { |
| 64 const char* const keyid; |
| 65 const char* const salt; |
| 66 uint64_t rs; |
| 67 } parsed_values[kNumberOfValues]; |
| 68 } expected_results[] = { |
| 69 { "keyid=foo;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024,keyid=foo;salt=c2l4dGVlbm" |
| 70 "Nvb2xieXRlcw;rs=1024", |
| 71 { { "foo", "sixteencoolbytes", 1024 }, |
| 72 { "foo", "sixteencoolbytes", 1024 } } }, |
| 73 { "keyid=foo,salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024", |
| 74 { { "foo", "", kDefaultRecordSize }, |
| 75 { "", "sixteencoolbytes", 1024 } } }, |
| 76 { "keyid=foo,keyid=bar;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024", |
| 77 { { "foo", "", kDefaultRecordSize }, |
| 78 { "bar", "sixteencoolbytes", 1024 } } }, |
| 79 { "keyid=\"foo,keyid=bar\",salt=c2l4dGVlbmNvb2xieXRlcw", |
| 80 { { "foo,keyid=bar", "", kDefaultRecordSize }, |
| 81 { "", "sixteencoolbytes", kDefaultRecordSize } } }, |
| 82 }; |
| 83 |
| 84 for (size_t i = 0; i < arraysize(expected_results); i++) { |
| 85 SCOPED_TRACE(i); |
| 86 |
| 87 std::vector<EncryptionHeaderValues> values; |
| 88 ASSERT_TRUE(ParseEncryptionHeader(expected_results[i].header, &values)); |
| 89 ASSERT_EQ(kNumberOfValues, values.size()); |
| 90 |
| 91 for (size_t j = 0; j < kNumberOfValues; ++j) { |
| 92 EXPECT_EQ(expected_results[i].parsed_values[j].keyid, values[j].keyid); |
| 93 EXPECT_EQ(expected_results[i].parsed_values[j].salt, values[j].salt); |
| 94 EXPECT_EQ(expected_results[i].parsed_values[j].rs, values[j].rs); |
| 95 } |
| 96 } |
| 97 } |
| 98 |
| 99 TEST(EncryptionHeaderParsersTest, ParseInvalidEncryptionHeaders) { |
| 100 const char* const expected_failures[] = { |
| 101 "keyid", |
| 102 "keyid=", |
| 103 "keyid=foo;novaluekey", |
| 104 "keyid=foo,keyid", |
| 105 "salt", |
| 106 "salt=", |
| 107 "salt=YmV/2ZXJ-sMDA", |
| 108 "salt=dHdlbHZlY29vbGJ5dGVz=====", |
| 109 "salt=123$xyz", |
| 110 "salt=c2l4dGVlbmNvb2xieXRlcw,salt=123$xyz", |
| 111 "rs", |
| 112 "rs=", |
| 113 "rs=0", |
| 114 "rs=0x13", |
| 115 "rs=1", |
| 116 "rs=-1", |
| 117 "rs=+5", |
| 118 "rs=99999999999999999999999999999999", |
| 119 "rs=2,rs=0", |
| 120 "rs=foobar", |
| 121 }; |
| 122 |
| 123 for (size_t i = 0; i < arraysize(expected_failures); i++) { |
| 124 SCOPED_TRACE(i); |
| 125 |
| 126 std::vector<EncryptionHeaderValues> values; |
| 127 EXPECT_FALSE(ParseEncryptionHeader(expected_failures[i], &values)); |
| 128 EXPECT_EQ(0u, values.size()); |
| 129 } |
| 130 } |
| 131 |
| 132 TEST(EncryptionHeaderParsersTest, ParseValidEncryptionKeyHeaders) { |
| 133 struct { |
| 134 const char* const header; |
| 135 const char* const parsed_keyid; |
| 136 const char* const parsed_key; |
| 137 const char* const parsed_dh; |
| 138 } expected_results[] = { |
| 139 { "keyid=foo;key=c2l4dGVlbmNvb2xieXRlcw;dh=dHdlbHZlY29vbGJ5dGVz", |
| 140 "foo", "sixteencoolbytes", "twelvecoolbytes" }, |
| 141 { "keyid=foo; key=c2l4dGVlbmNvb2xieXRlcw; dh=dHdlbHZlY29vbGJ5dGVz", |
| 142 "foo", "sixteencoolbytes", "twelvecoolbytes" }, |
| 143 { "keyid = foo ; key = c2l4dGVlbmNvb2xieXRlcw ; dh = dHdlbHZlY29vbGJ5dGVz ", |
| 144 "foo", "sixteencoolbytes", "twelvecoolbytes" }, |
| 145 { "KEYID=foo;KEY=c2l4dGVlbmNvb2xieXRlcw;DH=dHdlbHZlY29vbGJ5dGVz", |
| 146 "foo", "sixteencoolbytes", "twelvecoolbytes" }, |
| 147 { "keyid=foo", "foo", "", "" }, |
| 148 { "key=c2l4dGVlbmNvb2xieXRlcw", "", "sixteencoolbytes", "" }, |
| 149 { "key=\"c2l4dGVlbmNvb2xieXRlcw\"", "", "sixteencoolbytes", "" }, |
| 150 { "key='c2l4dGVlbmNvb2xieXRlcw'", "", "sixteencoolbytes", "" }, |
| 151 { "dh=dHdlbHZlY29vbGJ5dGVz", "", "", "twelvecoolbytes" }, |
| 152 { "keyid=foo;someothervalue=bar;key=dHdlbHZlY29vbGJ5dGVz", |
| 153 "foo", "twelvecoolbytes", "" }, |
| 154 { "keyid=foo;keyid=bar", "bar", "", "" }, |
| 155 }; |
| 156 |
| 157 for (size_t i = 0; i < arraysize(expected_results); i++) { |
| 158 SCOPED_TRACE(i); |
| 159 |
| 160 std::vector<EncryptionKeyHeaderValues> values; |
| 161 ASSERT_TRUE(ParseEncryptionKeyHeader(expected_results[i].header, &values)); |
| 162 ASSERT_EQ(1u, values.size()); |
| 163 |
| 164 EXPECT_EQ(expected_results[i].parsed_keyid, values[0].keyid); |
| 165 EXPECT_EQ(expected_results[i].parsed_key, values[0].key); |
| 166 EXPECT_EQ(expected_results[i].parsed_dh, values[0].dh); |
| 167 } |
| 168 } |
| 169 |
| 170 TEST(EncryptionHeaderParsersTest, ParseValidMultiValueEncryptionKeyHeaders) { |
| 171 const size_t kNumberOfValues = 2u; |
| 172 |
| 173 struct { |
| 174 const char* const header; |
| 175 struct { |
| 176 const char* const keyid; |
| 177 const char* const key; |
| 178 const char* const dh; |
| 179 } parsed_values[kNumberOfValues]; |
| 180 } expected_results[] = { |
| 181 { "keyid=foo;key=c2l4dGVlbmNvb2xieXRlcw;dh=dHdlbHZlY29vbGJ5dGVz,keyid=bar;" |
| 182 "key=dHdlbHZlY29vbGJ5dGVz;dh=c2l4dGVlbmNvb2xieXRlcw", |
| 183 { { "foo", "sixteencoolbytes", "twelvecoolbytes" }, |
| 184 { "bar", "twelvecoolbytes", "sixteencoolbytes" } } }, |
| 185 { "keyid=foo,key=c2l4dGVlbmNvb2xieXRlcw", |
| 186 { { "foo", "", "" }, |
| 187 { "", "sixteencoolbytes", "" } } }, |
| 188 { "keyid=foo,keyid=bar;dh=dHdlbHZlY29vbGJ5dGVz", |
| 189 { { "foo", "", "" }, |
| 190 { "bar", "", "twelvecoolbytes" } } }, |
| 191 { "keyid=\"foo,keyid=bar\",key=c2l4dGVlbmNvb2xieXRlcw", |
| 192 { { "foo,keyid=bar", "", "" }, |
| 193 { "", "sixteencoolbytes", "" } } }, |
| 194 }; |
| 195 |
| 196 for (size_t i = 0; i < arraysize(expected_results); i++) { |
| 197 SCOPED_TRACE(i); |
| 198 |
| 199 std::vector<EncryptionKeyHeaderValues> values; |
| 200 ASSERT_TRUE(ParseEncryptionKeyHeader(expected_results[i].header, &values)); |
| 201 ASSERT_EQ(kNumberOfValues, values.size()); |
| 202 |
| 203 for (size_t j = 0; j < kNumberOfValues; ++j) { |
| 204 EXPECT_EQ(expected_results[i].parsed_values[j].keyid, values[j].keyid); |
| 205 EXPECT_EQ(expected_results[i].parsed_values[j].key, values[j].key); |
| 206 EXPECT_EQ(expected_results[i].parsed_values[j].dh, values[j].dh); |
| 207 } |
| 208 } |
| 209 } |
| 210 |
| 211 TEST(EncryptionHeaderParsersTest, ParseInvalidEncryptionKeyHeaders) { |
| 212 const char* const expected_failures[] = { |
| 213 "keyid", |
| 214 "keyid=", |
| 215 "keyid=foo,keyid", |
| 216 "keyid=foo;novaluekey", |
| 217 "key", |
| 218 "key=", |
| 219 "key=123$xyz", |
| 220 "key=foobar,key=123$xyz", |
| 221 "dh", |
| 222 "dh=", |
| 223 "dh=YmV/2ZXJ-sMDA", |
| 224 "dh=dHdlbHZlY29vbGJ5dGVz=====", |
| 225 "dh=123$xyz", |
| 226 }; |
| 227 |
| 228 for (size_t i = 0; i < arraysize(expected_failures); i++) { |
| 229 SCOPED_TRACE(i); |
| 230 |
| 231 std::vector<EncryptionKeyHeaderValues> values; |
| 232 EXPECT_FALSE(ParseEncryptionKeyHeader(expected_failures[i], &values)); |
| 233 EXPECT_EQ(0u, values.size()); |
| 234 } |
| 235 } |
| 236 |
| 237 TEST(EncryptionHeaderParsersTest, SixValueHeader) { |
| 238 const char* const header = "keyid=0,keyid=1,keyid=2,keyid=3,keyid=4,keyid=5"; |
| 239 |
| 240 std::vector<EncryptionHeaderValues> encryption_values; |
| 241 ASSERT_TRUE(ParseEncryptionHeader(header, &encryption_values)); |
| 242 |
| 243 std::vector<EncryptionKeyHeaderValues> encryption_key_values; |
| 244 ASSERT_TRUE(ParseEncryptionKeyHeader(header, &encryption_key_values)); |
| 245 |
| 246 ASSERT_EQ(6u, encryption_values.size()); |
| 247 ASSERT_EQ(6u, encryption_key_values.size()); |
| 248 |
| 249 for (size_t i = 0; i < encryption_values.size(); i++) { |
| 250 SCOPED_TRACE(i); |
| 251 |
| 252 const std::string value = base::IntToString(i); |
| 253 |
| 254 EXPECT_EQ(value, encryption_values[i].keyid); |
| 255 EXPECT_EQ(value, encryption_key_values[i].keyid); |
| 256 } |
| 257 } |
| 258 |
| 259 TEST(EncryptionHeaderParsersTest, InvalidHeadersDoNotModifyOutput) { |
| 260 EncryptionHeaderValues encryption_value; |
| 261 encryption_value.keyid = "mykeyid"; |
| 262 encryption_value.salt = "somesalt"; |
| 263 encryption_value.rs = 42u; |
| 264 |
| 265 std::vector<EncryptionHeaderValues> encryption_values; |
| 266 encryption_values.push_back(encryption_value); |
| 267 |
| 268 ASSERT_FALSE(ParseEncryptionHeader("rs=foobar", &encryption_values)); |
| 269 ASSERT_EQ(1u, encryption_values.size()); |
| 270 |
| 271 EXPECT_EQ("mykeyid", encryption_values[0].keyid); |
| 272 EXPECT_EQ("somesalt", encryption_values[0].salt); |
| 273 EXPECT_EQ(42u, encryption_values[0].rs); |
| 274 |
| 275 EncryptionKeyHeaderValues encryption_key_value; |
| 276 encryption_key_value.keyid = "myotherkeyid"; |
| 277 encryption_key_value.key = "akey"; |
| 278 encryption_key_value.dh = "yourdh"; |
| 279 |
| 280 std::vector<EncryptionKeyHeaderValues> encryption_key_values; |
| 281 encryption_key_values.push_back(encryption_key_value); |
| 282 |
| 283 ASSERT_FALSE(ParseEncryptionKeyHeader("key=$$$", &encryption_key_values)); |
| 284 ASSERT_EQ(1u, encryption_key_values.size()); |
| 285 |
| 286 EXPECT_EQ("myotherkeyid", encryption_key_values[0].keyid); |
| 287 EXPECT_EQ("akey", encryption_key_values[0].key); |
| 288 EXPECT_EQ("yourdh", encryption_key_values[0].dh); |
| 289 } |
| 290 |
| 291 } // namespace |
| 292 |
| 293 } // namespace gcm |
OLD | NEW |