Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/frame/SubresourceIntegrity.h" | 6 #include "core/frame/SubresourceIntegrity.h" |
| 7 | 7 |
| 8 #include "core/HTMLNames.h" | 8 #include "core/HTMLNames.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/fetch/Resource.h" | 10 #include "core/fetch/Resource.h" |
| 11 #include "core/fetch/ResourcePtr.h" | 11 #include "core/fetch/ResourcePtr.h" |
| 12 #include "core/html/HTMLScriptElement.h" | 12 #include "core/html/HTMLScriptElement.h" |
| 13 #include "platform/Crypto.h" | 13 #include "platform/Crypto.h" |
| 14 #include "platform/weborigin/KURL.h" | 14 #include "platform/weborigin/KURL.h" |
| 15 #include "platform/weborigin/SecurityOrigin.h" | 15 #include "platform/weborigin/SecurityOrigin.h" |
| 16 #include "wtf/RefPtr.h" | 16 #include "wtf/RefPtr.h" |
| 17 #include "wtf/Vector.h" | 17 #include "wtf/Vector.h" |
| 18 #include "wtf/dtoa/utils.h" | 18 #include "wtf/dtoa/utils.h" |
| 19 #include "wtf/text/WTFString.h" | 19 #include "wtf/text/WTFString.h" |
| 20 #include <gtest/gtest.h> | 20 #include <gtest/gtest.h> |
| 21 | 21 |
| 22 namespace blink { | 22 namespace blink { |
| 23 | 23 |
| 24 static const char kBasicScript[] = "alert('test');"; | 24 static const char kBasicScript[] = "alert('test');"; |
| 25 static const char kSha256Integrity[] = "sha256-GAF48QOoxRvu0gZAmQivUdJPyBacqznBA XwnkfpmQX4="; | 25 static const char kSha256Integrity[] = "sha256-GAF48QOoxRvu0gZAmQivUdJPyBacqznBA XwnkfpmQX4="; |
| 26 static const char kSha256IntegrityLenientSyntax[] = "sha256-GAF48QOoxRvu0gZAmQiv UdJPyBacqznBAXwnkfpmQX4="; | 26 static const char kSha256IntegrityLenientSyntax[] = "sha256-GAF48QOoxRvu0gZAmQiv UdJPyBacqznBAXwnkfpmQX4="; |
| 27 static const char kSha256IntegrityWithUnknownOptions[] = "sha256-GAF48QOoxRvu0gZ AmQivUdJPyBacqznBAXwnkfpmQX4=?foo=bar?baz=foz"; | |
|
Mike West
2015/05/11 03:25:29
Could you add another test with a single option?
jww
2015/05/11 05:39:08
Done.
| |
| 27 static const char kSha384Integrity[] = "sha384-nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD 4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; | 28 static const char kSha384Integrity[] = "sha384-nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD 4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
| 28 static const char kSha512Integrity[] = "sha512-TXkJw18PqlVlEUXXjeXbGetop1TKB3wYQ Ip1_ihxCOFGUfG9TYOaA1MlkpTAqSV6yaevLO8Tj5pgH1JmZ--ItA=="; | 29 static const char kSha512Integrity[] = "sha512-TXkJw18PqlVlEUXXjeXbGetop1TKB3wYQ Ip1_ihxCOFGUfG9TYOaA1MlkpTAqSV6yaevLO8Tj5pgH1JmZ--ItA=="; |
| 29 static const char kSha384IntegrityLabeledAs256[] = "sha256-nep3XpvhUxpCMOVXIFPec ThAqdY_uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; | 30 static const char kSha384IntegrityLabeledAs256[] = "sha256-nep3XpvhUxpCMOVXIFPec ThAqdY_uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
| 30 static const char kSha256AndSha384Integrities[] = "sha256-GAF48QOoxRvu0gZAmQivUd JPyBacqznBAXwnkfpmQX4= sha384-nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD4kXSqXpx0YJUWU4fT TaFgciTuZk7fmE"; | 31 static const char kSha256AndSha384Integrities[] = "sha256-GAF48QOoxRvu0gZAmQivUd JPyBacqznBAXwnkfpmQX4= sha384-nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD4kXSqXpx0YJUWU4fT TaFgciTuZk7fmE"; |
| 31 static const char kBadSha256AndGoodSha384Integrities[] = "sha256-deadbeef sha384 -nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; | 32 static const char kBadSha256AndGoodSha384Integrities[] = "sha256-deadbeef sha384 -nep3XpvhUxpCMOVXIFPecThAqdY_uVeiD4kXSqXpx0YJUWU4fTTaFgciTuZk7fmE"; |
| 32 static const char kGoodSha256AndBadSha384Integrities[] = "sha256-GAF48QOoxRvu0gZ AmQivUdJPyBacqznBAXwnkfpmQX4= sha384-deadbeef"; | 33 static const char kGoodSha256AndBadSha384Integrities[] = "sha256-GAF48QOoxRvu0gZ AmQivUdJPyBacqznBAXwnkfpmQX4= sha384-deadbeef"; |
| 33 static const char kBadSha256AndBadSha384Integrities[] = "sha256-deadbeef sha384- deadbeef"; | 34 static const char kBadSha256AndBadSha384Integrities[] = "sha256-deadbeef sha384- deadbeef"; |
| 34 static const char kUnsupportedHashFunctionIntegrity[] = "sha1-JfLW308qMPKfb4DaHp UBEESwuPc="; | 35 static const char kUnsupportedHashFunctionIntegrity[] = "sha1-JfLW308qMPKfb4DaHp UBEESwuPc="; |
| 35 | 36 |
| 36 class SubresourceIntegrityTest : public ::testing::Test { | 37 class SubresourceIntegrityTest : public ::testing::Test { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 Vector<UChar> characters; | 94 Vector<UChar> characters; |
| 94 text.appendTo(characters); | 95 text.appendTo(characters); |
| 95 const UChar* position = characters.data(); | 96 const UChar* position = characters.data(); |
| 96 const UChar* end = characters.end(); | 97 const UChar* end = characters.end(); |
| 97 String digest; | 98 String digest; |
| 98 | 99 |
| 99 EXPECT_FALSE(SubresourceIntegrity::parseDigest(position, end, digest)); | 100 EXPECT_FALSE(SubresourceIntegrity::parseDigest(position, end, digest)); |
| 100 EXPECT_TRUE(digest.isEmpty()); | 101 EXPECT_TRUE(digest.isEmpty()); |
| 101 } | 102 } |
| 102 | 103 |
| 103 void expectMimeType(const String& text, const char* expectedType) | 104 void expectOption(const String& text, const char* expectedKey, const char* e xpectedValue) |
| 104 { | 105 { |
| 105 Vector<UChar> characters; | 106 Vector<UChar> characters; |
| 106 text.appendTo(characters); | 107 text.appendTo(characters); |
| 107 const UChar* position = characters.data(); | 108 const UChar* position = characters.data(); |
| 108 const UChar* end = characters.end(); | 109 const UChar* end = characters.end(); |
| 109 String type; | 110 String key, value; |
| 110 | 111 |
| 111 EXPECT_TRUE(SubresourceIntegrity::parseMimeType(position, end, type)); | 112 EXPECT_TRUE(SubresourceIntegrity::parseOption(position, end, key, value) ); |
| 112 EXPECT_EQ(expectedType, type); | 113 EXPECT_EQ(expectedKey, key); |
| 114 EXPECT_EQ(expectedValue, value); | |
| 113 } | 115 } |
| 114 | 116 |
| 115 void expectMimeTypeFailure(const String& text) | 117 void expectOptionFailure(const String& text) |
| 116 { | 118 { |
| 117 Vector<UChar> characters; | 119 Vector<UChar> characters; |
| 118 text.appendTo(characters); | 120 text.appendTo(characters); |
| 119 const UChar* position = characters.data(); | 121 const UChar* position = characters.data(); |
| 120 const UChar* end = characters.end(); | 122 const UChar* end = characters.end(); |
| 121 String type; | 123 String key, value; |
| 122 | 124 |
| 123 EXPECT_FALSE(SubresourceIntegrity::parseMimeType(position, end, type)); | 125 EXPECT_FALSE(SubresourceIntegrity::parseOption(position, end, key, value )); |
| 124 EXPECT_TRUE(type.isEmpty()); | |
| 125 } | 126 } |
| 126 | 127 |
| 127 void expectParse(const char* integrityAttribute, const char* expectedDigest, HashAlgorithm expectedAlgorithm, const char* expectedType) | 128 |
| 129 void expectParse(const char* integrityAttribute, const char* expectedDigest, HashAlgorithm expectedAlgorithm) | |
| 128 { | 130 { |
| 129 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; | 131 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; |
| 130 | 132 |
| 131 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); | 133 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); |
| 132 EXPECT_EQ(1u, metadataList.size()); | 134 EXPECT_EQ(1u, metadataList.size()); |
| 133 if (metadataList.size() > 0) { | 135 if (metadataList.size() > 0) { |
| 134 EXPECT_EQ(expectedDigest, metadataList[0].digest); | 136 EXPECT_EQ(expectedDigest, metadataList[0].digest); |
| 135 EXPECT_EQ(expectedAlgorithm, metadataList[0].algorithm); | 137 EXPECT_EQ(expectedAlgorithm, metadataList[0].algorithm); |
| 136 EXPECT_EQ(expectedType, metadataList[0].type); | |
| 137 } | 138 } |
| 138 } | 139 } |
| 139 | 140 |
| 140 void expectParseMultipleHashes(const char* integrityAttribute, const Subreso urceIntegrity::IntegrityMetadata expectedMetadatArray[], size_t expectedMetadata ArraySize) | 141 void expectParseMultipleHashes(const char* integrityAttribute, const Subreso urceIntegrity::IntegrityMetadata expectedMetadataArray[], size_t expectedMetadat aArraySize) |
| 141 { | 142 { |
| 142 Vector<SubresourceIntegrity::IntegrityMetadata> expectedMetadataList; | 143 Vector<SubresourceIntegrity::IntegrityMetadata> expectedMetadataList; |
| 143 expectedMetadataList.append(expectedMetadatArray, expectedMetadataArrayS ize); | 144 expectedMetadataList.append(expectedMetadataArray, expectedMetadataArray Size); |
| 144 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; | 145 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; |
| 145 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); | 146 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); |
| 146 EXPECT_EQ(expectedMetadataList.size(), metadataList.size()); | 147 EXPECT_EQ(expectedMetadataList.size(), metadataList.size()); |
| 147 if (expectedMetadataList.size() == metadataList.size()) { | 148 if (expectedMetadataList.size() == metadataList.size()) { |
| 148 for (size_t i = 0; i < metadataList.size(); i++) { | 149 for (size_t i = 0; i < metadataList.size(); i++) { |
| 149 EXPECT_EQ(expectedMetadataList[i].digest, metadataList[i].digest ); | 150 EXPECT_EQ(expectedMetadataList[i].digest, metadataList[i].digest ); |
| 150 EXPECT_EQ(expectedMetadataList[i].algorithm, metadataList[i].alg orithm); | 151 EXPECT_EQ(expectedMetadataList[i].algorithm, metadataList[i].alg orithm); |
| 151 EXPECT_EQ(expectedMetadataList[i].type, metadataList[i].type); | |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 void expectParseFailure(const char* integrityAttribute) | 156 void expectParseFailure(const char* integrityAttribute) |
| 157 { | 157 { |
| 158 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; | 158 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; |
| 159 | 159 |
| 160 EXPECT_EQ(SubresourceIntegrity::IntegrityParseNoValidResult, Subresource Integrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)) ; | 160 EXPECT_EQ(SubresourceIntegrity::IntegrityParseNoValidResult, Subresource Integrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)) ; |
| 161 } | 161 } |
| 162 | 162 |
| 163 void expectEmptyParseResult(const char* integrityAttribute) | 163 void expectEmptyParseResult(const char* integrityAttribute) |
| 164 { | 164 { |
| 165 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; | 165 Vector<SubresourceIntegrity::IntegrityMetadata> metadataList; |
| 166 | 166 |
| 167 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); | 167 EXPECT_EQ(SubresourceIntegrity::IntegrityParseValidResult, SubresourceIn tegrity::parseIntegrityAttribute(integrityAttribute, metadataList, *document)); |
| 168 EXPECT_EQ(0u, metadataList.size()); | 168 EXPECT_EQ(0u, metadataList.size()); |
| 169 } | 169 } |
| 170 | 170 |
| 171 enum CorsStatus { | 171 enum CorsStatus { |
| 172 WithCors, | 172 WithCors, |
| 173 NoCors | 173 NoCors |
| 174 }; | 174 }; |
| 175 | 175 |
| 176 void expectIntegrity(const char* integrity, const char* script, const KURL& url, const KURL& requestorUrl, const String& mimeType = String(), CorsStatus cor sStatus = WithCors) | 176 void expectIntegrity(const char* integrity, const char* script, const KURL& url, const KURL& requestorUrl, CorsStatus corsStatus = WithCors) |
| 177 { | 177 { |
| 178 scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); | 178 scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); |
| 179 EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptEleme nt, script, url, mimeType, *createTestResource(url, requestorUrl, corsStatus).ge t())); | 179 EXPECT_TRUE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptEleme nt, script, url, *createTestResource(url, requestorUrl, corsStatus).get())); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void expectIntegrityFailure(const char* integrity, const char* script, const KURL& url, const KURL& requestorUrl, const String& mimeType = String(), CorsSta tus corsStatus = WithCors) | 182 void expectIntegrityFailure(const char* integrity, const char* script, const KURL& url, const KURL& requestorUrl, CorsStatus corsStatus = WithCors) |
| 183 { | 183 { |
| 184 scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); | 184 scriptElement->setAttribute(HTMLNames::integrityAttr, integrity); |
| 185 EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElem ent, script, url, mimeType, *createTestResource(url, requestorUrl, corsStatus).g et())); | 185 EXPECT_FALSE(SubresourceIntegrity::CheckSubresourceIntegrity(*scriptElem ent, script, url, *createTestResource(url, requestorUrl, corsStatus).get())); |
| 186 } | 186 } |
| 187 | 187 |
| 188 ResourcePtr<Resource> createTestResource(const KURL& url, const KURL& allowO riginUrl, CorsStatus corsStatus) | 188 ResourcePtr<Resource> createTestResource(const KURL& url, const KURL& allowO riginUrl, CorsStatus corsStatus) |
| 189 { | 189 { |
| 190 OwnPtr<ResourceResponse> response = adoptPtr(new ResourceResponse); | 190 OwnPtr<ResourceResponse> response = adoptPtr(new ResourceResponse); |
| 191 response->setURL(url); | 191 response->setURL(url); |
| 192 response->setHTTPStatusCode(200); | 192 response->setHTTPStatusCode(200); |
| 193 if (corsStatus == WithCors) { | 193 if (corsStatus == WithCors) { |
| 194 response->setHTTPHeaderField("access-control-allow-origin", Security Origin::create(allowOriginUrl)->toAtomicString()); | 194 response->setHTTPHeaderField("access-control-allow-origin", Security Origin::create(allowOriginUrl)->toAtomicString()); |
| 195 response->setHTTPHeaderField("access-control-allow-credentials", "tr ue"); | 195 response->setHTTPHeaderField("access-control-allow-credentials", "tr ue"); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 expectDigest("abcdefg", "abcdefg"); | 232 expectDigest("abcdefg", "abcdefg"); |
| 233 expectDigest("abcdefg?", "abcdefg"); | 233 expectDigest("abcdefg?", "abcdefg"); |
| 234 expectDigest("ab+de/g", "ab+de/g"); | 234 expectDigest("ab+de/g", "ab+de/g"); |
| 235 expectDigest("ab-de_g", "ab+de/g"); | 235 expectDigest("ab-de_g", "ab+de/g"); |
| 236 | 236 |
| 237 expectDigestFailure("?"); | 237 expectDigestFailure("?"); |
| 238 expectDigestFailure("&&&foobar&&&"); | 238 expectDigestFailure("&&&foobar&&&"); |
| 239 expectDigestFailure("\x01\x02\x03\x04"); | 239 expectDigestFailure("\x01\x02\x03\x04"); |
| 240 } | 240 } |
| 241 | 241 |
| 242 TEST_F(SubresourceIntegrityTest, ParseMimeType) | 242 TEST_F(SubresourceIntegrityTest, ParseOption) |
| 243 { | 243 { |
| 244 expectMimeType("?ct=application/javascript", "application/javascript"); | 244 expectOption("?ct=application/javascript", "ct", "application/javascript"); |
| 245 expectMimeType("?ct=application/xhtml+xml", "application/xhtml+xml"); | 245 expectOption("?ct=application/xhtml+xml", "ct", "application/xhtml+xml"); |
| 246 expectMimeType("?ct=text/vnd.abc", "text/vnd.abc"); | 246 expectOption("?ct=text/vnd.abc", "ct", "text/vnd.abc"); |
| 247 expectMimeType("?ct=video/x-ms-wmv", "video/x-ms-wmv"); | 247 expectOption("?ct=video/x-ms-wmv", "ct", "video/x-ms-wmv"); |
| 248 expectOption("?foo=bar", "foo", "bar"); | |
| 249 expectOption("?foo=bar?baz", "foo", "bar"); | |
| 250 expectOption("?foo=bar?baz=boo", "foo", "bar"); | |
| 251 expectOption("?foo=", "foo", ""); | |
| 252 expectOption("?foo=?baz=bar", "foo", ""); | |
| 248 | 253 |
| 249 expectMimeTypeFailure("application/javascript"); | 254 expectOptionFailure("application/javascript"); |
| 250 expectMimeTypeFailure("?application/javascript"); | 255 expectOptionFailure("?application/javascript"); |
| 251 expectMimeTypeFailure("?not-ct=application/javascript"); | 256 expectOptionFailure("?ct==application/javascript"); |
| 252 expectMimeTypeFailure("?ct==application/javascript"); | 257 expectOptionFailure("?yay=boo&ct=application/javascript"); |
| 253 expectMimeTypeFailure("?yay=boo&ct=application/javascript"); | 258 expectOptionFailure("?ct=application/javascript&yay=boo"); |
| 254 expectMimeTypeFailure("?ct=application/javascript&yay=boo"); | 259 expectOptionFailure("?foo=baz bar"); |
| 255 expectMimeTypeFailure("?ct=video%2Fx-ms-wmv"); | 260 expectOptionFailure("?=bar"); |
| 261 expectOptionFailure("?="); | |
| 256 } | 262 } |
| 257 | 263 |
| 258 // | 264 // |
| 259 // End-to-end parsing tests. | 265 // End-to-end parsing tests. |
| 260 // | 266 // |
| 261 | 267 |
| 262 TEST_F(SubresourceIntegrityTest, Parsing) | 268 TEST_F(SubresourceIntegrityTest, Parsing) |
| 263 { | 269 { |
| 264 expectParseFailure("not_really_a_valid_anything"); | 270 expectParseFailure("not_really_a_valid_anything"); |
| 265 expectParseFailure("sha256-&&&foobar&&&"); | 271 expectParseFailure("sha256-&&&foobar&&&"); |
| 266 expectParseFailure("sha256-\x01\x02\x03\x04"); | 272 expectParseFailure("sha256-\x01\x02\x03\x04"); |
| 267 expectParseFailure("sha256-!!! sha256-!!!"); | 273 expectParseFailure("sha256-!!! sha256-!!!"); |
| 268 | 274 |
| 269 expectEmptyParseResult("foobar:///sha256-abcdefg"); | 275 expectEmptyParseResult("foobar:///sha256-abcdefg"); |
| 270 expectEmptyParseResult("ni://sha256-abcdefg"); | 276 expectEmptyParseResult("ni://sha256-abcdefg"); |
| 271 expectEmptyParseResult("ni:///sha256-abcdefg"); | 277 expectEmptyParseResult("ni:///sha256-abcdefg"); |
| 272 expectEmptyParseResult("notsha256atall-abcdefg"); | 278 expectEmptyParseResult("notsha256atall-abcdefg"); |
| 273 | 279 |
| 274 expectParse( | 280 expectParse( |
| 275 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 281 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 276 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 282 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 277 HashAlgorithmSha256, | 283 HashAlgorithmSha256); |
| 278 ""); | |
| 279 | 284 |
| 280 expectParse( | 285 expectParse( |
| 281 "sha-256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 286 "sha-256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 282 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 287 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 283 HashAlgorithmSha256, | 288 HashAlgorithmSha256); |
| 284 ""); | |
| 285 | 289 |
| 286 expectParse( | 290 expectParse( |
| 287 " sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= ", | 291 " sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= ", |
| 288 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 292 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 289 HashAlgorithmSha256, | 293 HashAlgorithmSha256); |
| 290 ""); | |
| 291 | 294 |
| 292 expectParse( | 295 expectParse( |
| 293 "sha384-XVVXBGoYw6AJOh9J-Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_tA1v5GPr ", | 296 "sha384-XVVXBGoYw6AJOh9J-Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_tA1v5GPr ", |
| 294 "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", | 297 "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", |
| 295 HashAlgorithmSha384, | 298 HashAlgorithmSha384); |
| 296 ""); | |
| 297 | 299 |
| 298 expectParse( | 300 expectParse( |
| 299 "sha-384-XVVXBGoYw6AJOh9J_Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_tA1v5GP r", | 301 "sha-384-XVVXBGoYw6AJOh9J_Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup_tA1v5GP r", |
| 300 "XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", | 302 "XVVXBGoYw6AJOh9J/Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", |
| 301 HashAlgorithmSha384, | 303 HashAlgorithmSha384); |
| 302 ""); | |
| 303 | 304 |
| 304 expectParse( | 305 expectParse( |
| 305 "sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0M PaIrPAjcHqba5csorDWtKg==", | 306 "sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0M PaIrPAjcHqba5csorDWtKg==", |
| 306 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | 307 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", |
| 307 HashAlgorithmSha512, | 308 HashAlgorithmSha512); |
| 308 ""); | |
| 309 | 309 |
| 310 expectParse( | 310 expectParse( |
| 311 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==", | 311 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==", |
| 312 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | 312 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", |
| 313 HashAlgorithmSha512, | 313 HashAlgorithmSha512); |
| 314 ""); | |
| 315 | 314 |
| 316 expectParse( | 315 expectParse( |
| 317 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?ct=application/javascript", | 316 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?ct=application/javascript", |
| 318 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | 317 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", |
| 319 HashAlgorithmSha512, | 318 HashAlgorithmSha512); |
| 320 "application/javascript"); | 319 |
| 320 expectParse( | |
| 321 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?ct=application/xhtml+xml", | |
| 322 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | |
| 323 HashAlgorithmSha512); | |
| 324 | |
| 325 expectParse( | |
| 326 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?foo=bar?ct=application/xhtml+xml", | |
| 327 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | |
| 328 HashAlgorithmSha512); | |
| 329 | |
| 330 expectParse( | |
| 331 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?ct=application/xhtml+xml?foo=bar", | |
| 332 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | |
| 333 HashAlgorithmSha512); | |
| 334 | |
| 335 expectParse( | |
| 336 "sha-512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ-07yMK81ytlg0 MPaIrPAjcHqba5csorDWtKg==?baz=foz?ct=application/xhtml+xml?foo=bar", | |
| 337 "tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAj cHqba5csorDWtKg==", | |
| 338 HashAlgorithmSha512); | |
| 321 | 339 |
| 322 expectParseMultipleHashes("", 0, 0); | 340 expectParseMultipleHashes("", 0, 0); |
| 323 expectParseMultipleHashes(" ", 0, 0); | 341 expectParseMultipleHashes(" ", 0, 0); |
| 324 | 342 |
| 325 const SubresourceIntegrity::IntegrityMetadata kValidSha384AndSha512[] = { | 343 const SubresourceIntegrity::IntegrityMetadata kValidSha384AndSha512[] = { |
| 326 {"XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", Has hAlgorithmSha384, ""}, | 344 {"XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", Has hAlgorithmSha384}, |
| 327 {"tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPA jcHqba5csorDWtKg==", HashAlgorithmSha512, ""} | 345 {"tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPA jcHqba5csorDWtKg==", HashAlgorithmSha512} |
| 328 }; | 346 }; |
| 329 expectParseMultipleHashes( | 347 expectParseMultipleHashes( |
| 330 "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjc Hqba5csorDWtKg==", | 348 "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+07yMK81ytlg0MPaIrPAjc Hqba5csorDWtKg==", |
| 331 kValidSha384AndSha512, | 349 kValidSha384AndSha512, |
| 332 ARRAY_SIZE(kValidSha384AndSha512)); | 350 ARRAY_SIZE(kValidSha384AndSha512)); |
| 333 | 351 |
| 334 const SubresourceIntegrity::IntegrityMetadata kValidSha256AndSha256[] = { | 352 const SubresourceIntegrity::IntegrityMetadata kValidSha256AndSha256[] = { |
| 335 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256, "" }, | 353 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256}, |
| 336 {"deadbeef", HashAlgorithmSha256, ""} | 354 {"deadbeef", HashAlgorithmSha256} |
| 337 }; | 355 }; |
| 338 expectParseMultipleHashes( | 356 expectParseMultipleHashes( |
| 339 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-deadbeef", | 357 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-deadbeef", |
| 340 kValidSha256AndSha256, | 358 kValidSha256AndSha256, |
| 341 ARRAY_SIZE(kValidSha256AndSha256)); | 359 ARRAY_SIZE(kValidSha256AndSha256)); |
| 342 | 360 |
| 343 const SubresourceIntegrity::IntegrityMetadata kValidSha256AndInvalidSha256[] = { | 361 const SubresourceIntegrity::IntegrityMetadata kValidSha256AndInvalidSha256[] = { |
| 344 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256, "" } | 362 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256} |
| 345 }; | 363 }; |
| 346 expectParseMultipleHashes( | 364 expectParseMultipleHashes( |
| 347 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-!!!!", | 365 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-!!!!", |
| 348 kValidSha256AndInvalidSha256, | 366 kValidSha256AndInvalidSha256, |
| 349 ARRAY_SIZE(kValidSha256AndInvalidSha256)); | 367 ARRAY_SIZE(kValidSha256AndInvalidSha256)); |
| 350 | 368 |
| 351 const SubresourceIntegrity::IntegrityMetadata kInvalidSha256AndValidSha256[] = { | 369 const SubresourceIntegrity::IntegrityMetadata kInvalidSha256AndValidSha256[] = { |
| 352 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256, "" } | 370 {"BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", HashAlgorithmSha256} |
| 353 }; | 371 }; |
| 354 expectParseMultipleHashes( | 372 expectParseMultipleHashes( |
| 355 "sha256-!!! sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | 373 "sha256-!!! sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", |
| 356 kInvalidSha256AndValidSha256, | 374 kInvalidSha256AndValidSha256, |
| 357 ARRAY_SIZE(kInvalidSha256AndValidSha256)); | 375 ARRAY_SIZE(kInvalidSha256AndValidSha256)); |
| 376 | |
| 377 expectParse( | |
| 378 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar", | |
| 379 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | |
| 380 HashAlgorithmSha256); | |
| 381 | |
| 382 expectParse( | |
| 383 "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar?baz=foz", | |
| 384 "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", | |
| 385 HashAlgorithmSha256); | |
| 386 | |
| 387 expectParseFailure("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo= bar?"); | |
| 388 expectParseFailure("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo: bar"); | |
| 358 } | 389 } |
| 359 | 390 |
| 360 TEST_F(SubresourceIntegrityTest, ParsingBase64) | 391 TEST_F(SubresourceIntegrityTest, ParsingBase64) |
| 361 { | 392 { |
| 362 expectParse( | 393 expectParse( |
| 363 "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr ", | 394 "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr ", |
| 364 "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", | 395 "XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr", |
| 365 HashAlgorithmSha384, | 396 HashAlgorithmSha384); |
| 366 ""); | |
| 367 } | 397 } |
| 368 | 398 |
| 369 // | 399 // |
| 370 // End-to-end tests of ::CheckSubresourceIntegrity. | 400 // End-to-end tests of ::CheckSubresourceIntegrity. |
| 371 // | 401 // |
| 372 | 402 |
| 373 TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInSecureOrigin) | 403 TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInSecureOrigin) |
| 374 { | 404 { |
| 375 document->updateSecurityOrigin(secureOrigin->isolatedCopy()); | 405 document->updateSecurityOrigin(secureOrigin->isolatedCopy()); |
| 376 | 406 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 389 expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL , secureURL); | 419 expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL , secureURL); |
| 390 | 420 |
| 391 // With multiple values, at least one must match. | 421 // With multiple values, at least one must match. |
| 392 expectIntegrityFailure(kBadSha256AndBadSha384Integrities, kBasicScript, secu reURL, secureURL); | 422 expectIntegrityFailure(kBadSha256AndBadSha384Integrities, kBasicScript, secu reURL, secureURL); |
| 393 | 423 |
| 394 // Unsupported hash functions should succeed. | 424 // Unsupported hash functions should succeed. |
| 395 expectIntegrity(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL, secureURL); | 425 expectIntegrity(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL, secureURL); |
| 396 | 426 |
| 397 // All parameters are fine, and because this is not cross origin, CORS is | 427 // All parameters are fine, and because this is not cross origin, CORS is |
| 398 // not needed. | 428 // not needed. |
| 399 expectIntegrity(kSha256Integrity, kBasicScript, secureURL, secureURL, String (), NoCors); | 429 expectIntegrity(kSha256Integrity, kBasicScript, secureURL, secureURL, NoCors ); |
| 430 | |
| 431 // Unknown options should be ignored | |
| 432 expectIntegrity(kSha256IntegrityWithUnknownOptions, kBasicScript, secureURL, secureURL, NoCors); | |
| 400 } | 433 } |
| 401 | 434 |
| 402 TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInInsecureOrigin) | 435 TEST_F(SubresourceIntegrityTest, CheckSubresourceIntegrityInInsecureOrigin) |
| 403 { | 436 { |
| 404 // The same checks as CheckSubresourceIntegrityInSecureOrigin should pass | 437 // The same checks as CheckSubresourceIntegrityInSecureOrigin should pass |
| 405 // here, with the expection of the NoCors check at the end. | 438 // here, with the expection of the NoCors check at the end. |
| 406 document->updateSecurityOrigin(insecureOrigin->isolatedCopy()); | 439 document->updateSecurityOrigin(insecureOrigin->isolatedCopy()); |
| 407 | 440 |
| 408 expectIntegrity(kSha256Integrity, kBasicScript, secureURL, insecureURL); | 441 expectIntegrity(kSha256Integrity, kBasicScript, secureURL, insecureURL); |
| 409 expectIntegrity(kSha256IntegrityLenientSyntax, kBasicScript, secureURL, inse cureURL); | 442 expectIntegrity(kSha256IntegrityLenientSyntax, kBasicScript, secureURL, inse cureURL); |
| 410 expectIntegrity(kSha384Integrity, kBasicScript, secureURL, insecureURL); | 443 expectIntegrity(kSha384Integrity, kBasicScript, secureURL, insecureURL); |
| 411 expectIntegrity(kSha512Integrity, kBasicScript, secureURL, insecureURL); | 444 expectIntegrity(kSha512Integrity, kBasicScript, secureURL, insecureURL); |
| 412 expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL , insecureURL); | 445 expectIntegrityFailure(kSha384IntegrityLabeledAs256, kBasicScript, secureURL , insecureURL); |
| 413 expectIntegrity(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL, insecureURL); | 446 expectIntegrity(kUnsupportedHashFunctionIntegrity, kBasicScript, secureURL, insecureURL); |
| 414 | 447 |
| 415 expectIntegrity(kSha256AndSha384Integrities, kBasicScript, secureURL, insecu reURL); | 448 expectIntegrity(kSha256AndSha384Integrities, kBasicScript, secureURL, insecu reURL); |
| 416 expectIntegrity(kBadSha256AndGoodSha384Integrities, kBasicScript, secureURL, insecureURL); | 449 expectIntegrity(kBadSha256AndGoodSha384Integrities, kBasicScript, secureURL, insecureURL); |
| 417 expectIntegrity(kGoodSha256AndBadSha384Integrities, kBasicScript, secureURL, insecureURL); | 450 expectIntegrity(kGoodSha256AndBadSha384Integrities, kBasicScript, secureURL, insecureURL); |
| 418 | 451 |
| 419 // This check should fail because, unlike in the | 452 // This check should fail because, unlike in the |
| 420 // CheckSubresourceIntegrityInSecureOrigin case, this is cross origin | 453 // CheckSubresourceIntegrityInSecureOrigin case, this is cross origin |
| 421 // (secure origin requesting a resource on an insecure origin) | 454 // (secure origin requesting a resource on an insecure origin) |
| 422 expectIntegrityFailure(kSha256Integrity, kBasicScript, secureURL, insecureUR L, String(), NoCors); | 455 expectIntegrityFailure(kSha256Integrity, kBasicScript, secureURL, insecureUR L, NoCors); |
| 423 } | 456 } |
| 424 | 457 |
| 425 } // namespace blink | 458 } // namespace blink |
| OLD | NEW |