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 "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 namespace gcm { | |
13 | |
14 namespace { | |
15 | |
16 // URL-safe base64 encoded (and plaintext representation of -) salt, key and dh. | |
17 // Included as preprocessor string literals for more convenient concatenation. | |
18 #define ENCODED_SALT "c2l4dGVlbmNvb2xieXRlcw" | |
19 #define ENCODED_KEY "c2V2ZW50ZWVuYnl0ZXN5YXk" | |
20 #define ENCODED_DH "bXlkaWZmaWVoZWxsbWFu" | |
21 | |
22 const char kDecodedSalt[] = "sixteencoolbytes"; | |
23 const char kDecodedKey[] = "seventeenbytesyay"; | |
24 const char kDecodedDh[] = "mydiffiehellman"; | |
25 | |
26 EncryptionHeaderValue CreateEncryptionHeaderValue( | |
27 const std::string& keyid, const std::string& salt, int64_t rs) { | |
28 EncryptionHeaderValue parsed; | |
29 parsed.keyid = keyid; | |
30 parsed.salt = salt; | |
31 parsed.rs = rs; | |
32 | |
33 return parsed; | |
34 } | |
35 | |
36 EncryptionKeyHeaderValue CreateEncryptionKeyHeaderValue( | |
37 const std::string& keyid, const std::string& key, const std::string& dh) { | |
38 EncryptionKeyHeaderValue header; | |
39 header.keyid = keyid; | |
40 header.key = key; | |
41 header.dh = dh; | |
42 | |
43 return header; | |
44 } | |
45 | |
46 TEST(EncryptionHeaderParsersTest, ParseSingleEncryptionHeaders) { | |
47 struct { | |
48 const char* const header; | |
49 EncryptionHeaderValue parsed; | |
50 } expected_results[] = { | |
51 { "keyid=foo; salt=" ENCODED_SALT "; rs=1024", | |
johnme
2015/07/20 19:15:19
Are you sure "; " is allowed? https://tools.ietf.o
Peter Beverloo
2015/07/20 22:44:33
The examples in the same draft use spaces, and thi
| |
52 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
53 { "keyid='foo'; salt='" ENCODED_SALT "'; rs='1024'", | |
johnme
2015/07/20 19:15:19
It seems according to https://tools.ietf.org/html/
Peter Beverloo
2015/07/20 22:44:33
Good point. Will do.
Peter Beverloo
2015/07/21 17:51:30
Done.
| |
54 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
55 { "keyid=\"foo\"; salt=\"" ENCODED_SALT "\"; rs=\"1024\"", | |
56 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
57 { "keyid=foo;salt=" ENCODED_SALT ";rs=1024", | |
58 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
59 { "keyid=foo;salt=" ENCODED_SALT ";rs=1024;random=yes", | |
60 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
61 { "rs=1024; salt=" ENCODED_SALT "; keyid=foo", | |
62 CreateEncryptionHeaderValue("foo", kDecodedSalt, 1024) }, | |
63 { "salt=" ENCODED_SALT "; keyid='foo; rs=1024'", | |
64 CreateEncryptionHeaderValue("foo; rs=1024", kDecodedSalt, 4096) }, | |
65 { "salt=" ENCODED_SALT "; rs=1024", | |
66 CreateEncryptionHeaderValue("", kDecodedSalt, 1024) }, | |
67 { "salt=" ENCODED_SALT, | |
68 CreateEncryptionHeaderValue("", kDecodedSalt, 4096) } | |
69 }; | |
70 | |
71 for (size_t i = 0; i < arraysize(expected_results); i++) { | |
72 SCOPED_TRACE(i); | |
johnme
2015/07/21 14:34:43
Nice :)
| |
73 | |
74 std::vector<EncryptionHeaderValue> result; | |
75 ASSERT_TRUE(ParseEncryptionHeader(expected_results[i].header, &result)); | |
76 ASSERT_EQ(1u, result.size()); | |
77 | |
78 EXPECT_EQ(expected_results[i].parsed.keyid, result[0].keyid); | |
79 EXPECT_EQ(expected_results[i].parsed.salt, result[0].salt); | |
80 EXPECT_EQ(expected_results[i].parsed.rs, result[0].rs); | |
81 } | |
82 } | |
83 | |
84 TEST(EncryptionHeaderParsersTest, ParseInvalidSingleEncryptionHeaders) { | |
85 const char* const expected_failures[] = { | |
86 // The "salt" attribute is required. | |
87 "keyid=foo", | |
88 // The "salt" attribute must be exactly 16-bytes, base64 URL encoded. | |
89 "salt=foobar", | |
90 "salt='c2l4dGVlbmNvb2xieXRlcw=='", | |
91 // Non-decimal record sizes are not supported. | |
92 "salt=" ENCODED_SALT ";rs=bar", | |
93 // Record sizes smaller than 2 are not supported. | |
johnme
2015/07/21 14:34:43
Please also check that a record size of 9,223,372,
Peter Beverloo
2015/07/21 17:51:30
Done.
| |
94 "salt=" ENCODED_SALT ";rs=0" | |
95 }; | |
96 | |
97 for (size_t i = 0; i < arraysize(expected_failures); i++) { | |
98 SCOPED_TRACE(i); | |
99 | |
100 std::vector<EncryptionHeaderValue> result; | |
101 ASSERT_FALSE(ParseEncryptionHeader(expected_failures[i], &result)); | |
102 EXPECT_EQ(0u, result.size()); | |
103 } | |
104 } | |
105 | |
106 TEST(EncryptionHeaderParsersTest, ParseMultipleEncryptionHeaders) { | |
johnme
2015/07/20 19:15:19
Please add a test that you support the freaky empt
Peter Beverloo
2015/07/21 17:51:30
Added a comma.
| |
107 const char* const header = | |
108 "keyid=foo1; salt=" ENCODED_SALT "; rs=1024," | |
109 "keyid='foo2, '; salt=" ENCODED_SALT "; rs=2048"; | |
110 | |
111 std::vector<EncryptionHeaderValue> results; | |
112 ASSERT_TRUE(ParseEncryptionHeader(header, &results)); | |
113 ASSERT_EQ(2u, results.size()); | |
114 | |
115 EXPECT_EQ("foo1", results[0].keyid); | |
116 EXPECT_EQ(kDecodedSalt, results[0].salt); | |
117 EXPECT_EQ(1024, results[0].rs); | |
118 | |
119 EXPECT_EQ("foo2, ", results[1].keyid); | |
120 EXPECT_EQ(kDecodedSalt, results[1].salt); | |
121 EXPECT_EQ(2048, results[1].rs); | |
122 } | |
123 | |
124 TEST(EncryptionHeaderParsersTest, ParseSingleEncryptionKeyHeader) { | |
125 struct { | |
126 const char* const header; | |
127 EncryptionKeyHeaderValue parsed; | |
128 } expected_results[] = { | |
129 { "keyid=foo; key=" ENCODED_KEY "; dh=" ENCODED_DH, | |
johnme
2015/07/20 19:15:19
Similarly are you sure "; " is allowed?
Peter Beverloo
2015/07/20 22:44:33
See earlier comment.
| |
130 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
131 { "keyid='foo'; key='" ENCODED_KEY "'; dh='" ENCODED_DH "'", | |
132 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
133 { "keyid=\"foo\"; key=\"" ENCODED_KEY "\"; dh=\"" ENCODED_DH "\"", | |
134 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
135 { "keyid=foo;key=" ENCODED_KEY ";dh=" ENCODED_DH "", | |
136 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
137 { "keyid=foo;key=" ENCODED_KEY ";dh=" ENCODED_DH ";random=yes", | |
138 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
139 { "dh=" ENCODED_DH "; key=" ENCODED_KEY "; keyid=foo", | |
140 CreateEncryptionKeyHeaderValue("foo", kDecodedKey, kDecodedDh) }, | |
141 { "keyid=foo", | |
142 CreateEncryptionKeyHeaderValue("foo", "", "") }, | |
143 { "key=" ENCODED_KEY "", | |
144 CreateEncryptionKeyHeaderValue("", kDecodedKey, "") }, | |
145 { "dh=" ENCODED_DH "", | |
146 CreateEncryptionKeyHeaderValue("", "", kDecodedDh) } | |
147 }; | |
148 | |
149 for (size_t i = 0; i < arraysize(expected_results); i++) { | |
150 SCOPED_TRACE(i); | |
151 | |
152 std::vector<EncryptionKeyHeaderValue> result; | |
153 ASSERT_TRUE(ParseEncryptionKeyHeader(expected_results[i].header, &result)); | |
154 ASSERT_EQ(1u, result.size()); | |
155 | |
156 EXPECT_EQ(expected_results[i].parsed.keyid, result[0].keyid); | |
157 EXPECT_EQ(expected_results[i].parsed.key, result[0].key); | |
158 EXPECT_EQ(expected_results[i].parsed.dh, result[0].dh); | |
159 } | |
160 } | |
161 | |
162 TEST(EncryptionHeaderParsersTest, ParseInvalidSingleEncryptionKeyHeaders) { | |
163 const char* const expected_failures[] = { | |
164 // The "key" attribute must be at least 16-bytes, base64 URL encoded. | |
165 "key=foo/bar", | |
166 "key=c2hvcnRrZXk", | |
167 "key='c2l4dGVlbmNvb2xieXRlcw=='", | |
168 // The "dh" attribute must contain a base64 URL encoded-value. | |
169 "dh=foo/bar", | |
170 "dh='ZGg='" | |
171 }; | |
172 | |
173 for (size_t i = 0; i < arraysize(expected_failures); i++) { | |
174 SCOPED_TRACE(i); | |
175 | |
176 std::vector<EncryptionKeyHeaderValue> result; | |
177 ASSERT_FALSE(ParseEncryptionKeyHeader(expected_failures[i], &result)); | |
178 EXPECT_EQ(0u, result.size()); | |
179 } | |
180 } | |
181 | |
182 TEST(EncryptionHeaderParsersTest, ParseMultipleEncryptionKeyHeaders) { | |
183 const char* const header = | |
184 "keyid=foo1; key=" ENCODED_KEY "; dh=" ENCODED_DH "," | |
185 "keyid='foo2, '; key=c29tZW90aGVybG9uZ2tleQ; dh=ZGhmb29iYXI"; | |
186 | |
187 std::vector<EncryptionKeyHeaderValue> results; | |
188 ASSERT_TRUE(ParseEncryptionKeyHeader(header, &results)); | |
189 ASSERT_EQ(2u, results.size()); | |
190 | |
191 EXPECT_EQ("foo1", results[0].keyid); | |
192 EXPECT_EQ(kDecodedKey, results[0].key); | |
193 EXPECT_EQ(kDecodedDh, results[0].dh); | |
194 | |
195 EXPECT_EQ("foo2, ", results[1].keyid); | |
196 EXPECT_EQ("someotherlongkey", results[1].key); | |
197 EXPECT_EQ("dhfoobar", results[1].dh); | |
198 } | |
199 | |
200 } // namespace | |
201 | |
202 } // namespace gcm | |
OLD | NEW |