| Index: components/gcm_driver/crypto/encryption_header_parsers_unittest.cc
|
| diff --git a/components/gcm_driver/crypto/encryption_header_parsers_unittest.cc b/components/gcm_driver/crypto/encryption_header_parsers_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5fe00ba696a7929e0f77a99d18a84b6ea5b7993f
|
| --- /dev/null
|
| +++ b/components/gcm_driver/crypto/encryption_header_parsers_unittest.cc
|
| @@ -0,0 +1,293 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/gcm_driver/crypto/encryption_header_parsers.h"
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/macros.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace gcm {
|
| +
|
| +namespace {
|
| +
|
| +const uint64_t kDefaultRecordSize = 4096;
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseValidEncryptionHeaders) {
|
| + struct {
|
| + const char* const header;
|
| + const char* const parsed_keyid;
|
| + const char* const parsed_salt;
|
| + uint64_t parsed_rs;
|
| + } expected_results[] = {
|
| + { "keyid=foo;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024",
|
| + "foo", "sixteencoolbytes", 1024 },
|
| + { "keyid=foo; salt=c2l4dGVlbmNvb2xieXRlcw; rs=1024",
|
| + "foo", "sixteencoolbytes", 1024 },
|
| + { "KEYID=foo;SALT=c2l4dGVlbmNvb2xieXRlcw;RS=1024",
|
| + "foo", "sixteencoolbytes", 1024 },
|
| + { " keyid = foo ; salt = c2l4dGVlbmNvb2xieXRlcw ; rs = 1024 ",
|
| + "foo", "sixteencoolbytes", 1024 },
|
| + { "keyid=foo", "foo", "", kDefaultRecordSize },
|
| + { "keyid=foo;", "foo", "", kDefaultRecordSize },
|
| + { "keyid=\"foo\"", "foo", "", kDefaultRecordSize },
|
| + { "keyid='foo'", "foo", "", kDefaultRecordSize },
|
| + { "salt=c2l4dGVlbmNvb2xieXRlcw",
|
| + "", "sixteencoolbytes", kDefaultRecordSize },
|
| + { "rs=2048", "", "", 2048 },
|
| + { "keyid=foo;someothervalue=1;rs=42", "foo", "", 42 },
|
| + { "keyid=foo;keyid=bar", "bar", "", kDefaultRecordSize },
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_results); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionHeaderValues> values;
|
| + ASSERT_TRUE(ParseEncryptionHeader(expected_results[i].header, &values));
|
| + ASSERT_EQ(1u, values.size());
|
| +
|
| + EXPECT_EQ(expected_results[i].parsed_keyid, values[0].keyid);
|
| + EXPECT_EQ(expected_results[i].parsed_salt, values[0].salt);
|
| + EXPECT_EQ(expected_results[i].parsed_rs, values[0].rs);
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseValidMultiValueEncryptionHeaders) {
|
| + const size_t kNumberOfValues = 2u;
|
| +
|
| + struct {
|
| + const char* const header;
|
| + struct {
|
| + const char* const keyid;
|
| + const char* const salt;
|
| + uint64_t rs;
|
| + } parsed_values[kNumberOfValues];
|
| + } expected_results[] = {
|
| + { "keyid=foo;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024,keyid=foo;salt=c2l4dGVlbm"
|
| + "Nvb2xieXRlcw;rs=1024",
|
| + { { "foo", "sixteencoolbytes", 1024 },
|
| + { "foo", "sixteencoolbytes", 1024 } } },
|
| + { "keyid=foo,salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024",
|
| + { { "foo", "", kDefaultRecordSize },
|
| + { "", "sixteencoolbytes", 1024 } } },
|
| + { "keyid=foo,keyid=bar;salt=c2l4dGVlbmNvb2xieXRlcw;rs=1024",
|
| + { { "foo", "", kDefaultRecordSize },
|
| + { "bar", "sixteencoolbytes", 1024 } } },
|
| + { "keyid=\"foo,keyid=bar\",salt=c2l4dGVlbmNvb2xieXRlcw",
|
| + { { "foo,keyid=bar", "", kDefaultRecordSize },
|
| + { "", "sixteencoolbytes", kDefaultRecordSize } } },
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_results); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionHeaderValues> values;
|
| + ASSERT_TRUE(ParseEncryptionHeader(expected_results[i].header, &values));
|
| + ASSERT_EQ(kNumberOfValues, values.size());
|
| +
|
| + for (size_t j = 0; j < kNumberOfValues; ++j) {
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].keyid, values[j].keyid);
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].salt, values[j].salt);
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].rs, values[j].rs);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseInvalidEncryptionHeaders) {
|
| + const char* const expected_failures[] = {
|
| + "keyid",
|
| + "keyid=",
|
| + "keyid=foo;novaluekey",
|
| + "keyid=foo,keyid",
|
| + "salt",
|
| + "salt=",
|
| + "salt=YmV/2ZXJ-sMDA",
|
| + "salt=dHdlbHZlY29vbGJ5dGVz=====",
|
| + "salt=123$xyz",
|
| + "salt=c2l4dGVlbmNvb2xieXRlcw,salt=123$xyz",
|
| + "rs",
|
| + "rs=",
|
| + "rs=0",
|
| + "rs=0x13",
|
| + "rs=1",
|
| + "rs=-1",
|
| + "rs=+5",
|
| + "rs=99999999999999999999999999999999",
|
| + "rs=2,rs=0",
|
| + "rs=foobar",
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_failures); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionHeaderValues> values;
|
| + EXPECT_FALSE(ParseEncryptionHeader(expected_failures[i], &values));
|
| + EXPECT_EQ(0u, values.size());
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseValidEncryptionKeyHeaders) {
|
| + struct {
|
| + const char* const header;
|
| + const char* const parsed_keyid;
|
| + const char* const parsed_key;
|
| + const char* const parsed_dh;
|
| + } expected_results[] = {
|
| + { "keyid=foo;key=c2l4dGVlbmNvb2xieXRlcw;dh=dHdlbHZlY29vbGJ5dGVz",
|
| + "foo", "sixteencoolbytes", "twelvecoolbytes" },
|
| + { "keyid=foo; key=c2l4dGVlbmNvb2xieXRlcw; dh=dHdlbHZlY29vbGJ5dGVz",
|
| + "foo", "sixteencoolbytes", "twelvecoolbytes" },
|
| + { "keyid = foo ; key = c2l4dGVlbmNvb2xieXRlcw ; dh = dHdlbHZlY29vbGJ5dGVz ",
|
| + "foo", "sixteencoolbytes", "twelvecoolbytes" },
|
| + { "KEYID=foo;KEY=c2l4dGVlbmNvb2xieXRlcw;DH=dHdlbHZlY29vbGJ5dGVz",
|
| + "foo", "sixteencoolbytes", "twelvecoolbytes" },
|
| + { "keyid=foo", "foo", "", "" },
|
| + { "key=c2l4dGVlbmNvb2xieXRlcw", "", "sixteencoolbytes", "" },
|
| + { "key=\"c2l4dGVlbmNvb2xieXRlcw\"", "", "sixteencoolbytes", "" },
|
| + { "key='c2l4dGVlbmNvb2xieXRlcw'", "", "sixteencoolbytes", "" },
|
| + { "dh=dHdlbHZlY29vbGJ5dGVz", "", "", "twelvecoolbytes" },
|
| + { "keyid=foo;someothervalue=bar;key=dHdlbHZlY29vbGJ5dGVz",
|
| + "foo", "twelvecoolbytes", "" },
|
| + { "keyid=foo;keyid=bar", "bar", "", "" },
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_results); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionKeyHeaderValues> values;
|
| + ASSERT_TRUE(ParseEncryptionKeyHeader(expected_results[i].header, &values));
|
| + ASSERT_EQ(1u, values.size());
|
| +
|
| + EXPECT_EQ(expected_results[i].parsed_keyid, values[0].keyid);
|
| + EXPECT_EQ(expected_results[i].parsed_key, values[0].key);
|
| + EXPECT_EQ(expected_results[i].parsed_dh, values[0].dh);
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseValidMultiValueEncryptionKeyHeaders) {
|
| + const size_t kNumberOfValues = 2u;
|
| +
|
| + struct {
|
| + const char* const header;
|
| + struct {
|
| + const char* const keyid;
|
| + const char* const key;
|
| + const char* const dh;
|
| + } parsed_values[kNumberOfValues];
|
| + } expected_results[] = {
|
| + { "keyid=foo;key=c2l4dGVlbmNvb2xieXRlcw;dh=dHdlbHZlY29vbGJ5dGVz,keyid=bar;"
|
| + "key=dHdlbHZlY29vbGJ5dGVz;dh=c2l4dGVlbmNvb2xieXRlcw",
|
| + { { "foo", "sixteencoolbytes", "twelvecoolbytes" },
|
| + { "bar", "twelvecoolbytes", "sixteencoolbytes" } } },
|
| + { "keyid=foo,key=c2l4dGVlbmNvb2xieXRlcw",
|
| + { { "foo", "", "" },
|
| + { "", "sixteencoolbytes", "" } } },
|
| + { "keyid=foo,keyid=bar;dh=dHdlbHZlY29vbGJ5dGVz",
|
| + { { "foo", "", "" },
|
| + { "bar", "", "twelvecoolbytes" } } },
|
| + { "keyid=\"foo,keyid=bar\",key=c2l4dGVlbmNvb2xieXRlcw",
|
| + { { "foo,keyid=bar", "", "" },
|
| + { "", "sixteencoolbytes", "" } } },
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_results); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionKeyHeaderValues> values;
|
| + ASSERT_TRUE(ParseEncryptionKeyHeader(expected_results[i].header, &values));
|
| + ASSERT_EQ(kNumberOfValues, values.size());
|
| +
|
| + for (size_t j = 0; j < kNumberOfValues; ++j) {
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].keyid, values[j].keyid);
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].key, values[j].key);
|
| + EXPECT_EQ(expected_results[i].parsed_values[j].dh, values[j].dh);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, ParseInvalidEncryptionKeyHeaders) {
|
| + const char* const expected_failures[] = {
|
| + "keyid",
|
| + "keyid=",
|
| + "keyid=foo,keyid",
|
| + "keyid=foo;novaluekey",
|
| + "key",
|
| + "key=",
|
| + "key=123$xyz",
|
| + "key=foobar,key=123$xyz",
|
| + "dh",
|
| + "dh=",
|
| + "dh=YmV/2ZXJ-sMDA",
|
| + "dh=dHdlbHZlY29vbGJ5dGVz=====",
|
| + "dh=123$xyz",
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(expected_failures); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + std::vector<EncryptionKeyHeaderValues> values;
|
| + EXPECT_FALSE(ParseEncryptionKeyHeader(expected_failures[i], &values));
|
| + EXPECT_EQ(0u, values.size());
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, SixValueHeader) {
|
| + const char* const header = "keyid=0,keyid=1,keyid=2,keyid=3,keyid=4,keyid=5";
|
| +
|
| + std::vector<EncryptionHeaderValues> encryption_values;
|
| + ASSERT_TRUE(ParseEncryptionHeader(header, &encryption_values));
|
| +
|
| + std::vector<EncryptionKeyHeaderValues> encryption_key_values;
|
| + ASSERT_TRUE(ParseEncryptionKeyHeader(header, &encryption_key_values));
|
| +
|
| + ASSERT_EQ(6u, encryption_values.size());
|
| + ASSERT_EQ(6u, encryption_key_values.size());
|
| +
|
| + for (size_t i = 0; i < encryption_values.size(); i++) {
|
| + SCOPED_TRACE(i);
|
| +
|
| + const std::string value = base::IntToString(i);
|
| +
|
| + EXPECT_EQ(value, encryption_values[i].keyid);
|
| + EXPECT_EQ(value, encryption_key_values[i].keyid);
|
| + }
|
| +}
|
| +
|
| +TEST(EncryptionHeaderParsersTest, InvalidHeadersDoNotModifyOutput) {
|
| + EncryptionHeaderValues encryption_value;
|
| + encryption_value.keyid = "mykeyid";
|
| + encryption_value.salt = "somesalt";
|
| + encryption_value.rs = 42u;
|
| +
|
| + std::vector<EncryptionHeaderValues> encryption_values;
|
| + encryption_values.push_back(encryption_value);
|
| +
|
| + ASSERT_FALSE(ParseEncryptionHeader("rs=foobar", &encryption_values));
|
| + ASSERT_EQ(1u, encryption_values.size());
|
| +
|
| + EXPECT_EQ("mykeyid", encryption_values[0].keyid);
|
| + EXPECT_EQ("somesalt", encryption_values[0].salt);
|
| + EXPECT_EQ(42u, encryption_values[0].rs);
|
| +
|
| + EncryptionKeyHeaderValues encryption_key_value;
|
| + encryption_key_value.keyid = "myotherkeyid";
|
| + encryption_key_value.key = "akey";
|
| + encryption_key_value.dh = "yourdh";
|
| +
|
| + std::vector<EncryptionKeyHeaderValues> encryption_key_values;
|
| + encryption_key_values.push_back(encryption_key_value);
|
| +
|
| + ASSERT_FALSE(ParseEncryptionKeyHeader("key=$$$", &encryption_key_values));
|
| + ASSERT_EQ(1u, encryption_key_values.size());
|
| +
|
| + EXPECT_EQ("myotherkeyid", encryption_key_values[0].keyid);
|
| + EXPECT_EQ("akey", encryption_key_values[0].key);
|
| + EXPECT_EQ("yourdh", encryption_key_values[0].dh);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace gcm
|
|
|