netwerk/test/TestSTSParser.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "TestHarness.h"
     6 #include <stdio.h>
     7 #include "nsNetUtil.h"
     8 #include "nsISiteSecurityService.h"
    10 #define EXPECT_SUCCESS(rv, ...) \
    11   PR_BEGIN_MACRO \
    12   if (NS_FAILED(rv)) { \
    13     fail(__VA_ARGS__); \
    14     return false; \
    15   } \
    16   PR_END_MACRO
    19 #define EXPECT_FAILURE(rv, ...) \
    20   PR_BEGIN_MACRO \
    21   if (NS_SUCCEEDED(rv)) { \
    22     fail(__VA_ARGS__); \
    23     return false; \
    24   } \
    25   PR_END_MACRO
    27 #define REQUIRE_EQUAL(a, b, ...) \
    28   PR_BEGIN_MACRO \
    29   if (a != b) { \
    30     fail(__VA_ARGS__); \
    31     return false; \
    32   } \
    33   PR_END_MACRO
    35 bool
    36 TestSuccess(const char* hdr, bool extraTokens,
    37             uint64_t expectedMaxAge, bool expectedIncludeSubdomains,
    38             nsISiteSecurityService* sss)
    39 {
    40   nsCOMPtr<nsIURI> dummyUri;
    41   nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
    42   EXPECT_SUCCESS(rv, "Failed to create URI");
    44   uint64_t maxAge = 0;
    45   bool includeSubdomains = false;
    46   rv = sss->ProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri, hdr,
    47                           0, &maxAge, &includeSubdomains);
    48   EXPECT_SUCCESS(rv, "Failed to process valid header: %s", hdr);
    50   REQUIRE_EQUAL(maxAge, expectedMaxAge, "Did not correctly parse maxAge");
    51   REQUIRE_EQUAL(includeSubdomains, expectedIncludeSubdomains, "Did not correctly parse presence/absence of includeSubdomains");
    53   if (extraTokens) {
    54     REQUIRE_EQUAL(rv, NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA,
    55                   "Extra tokens were expected when parsing, but were not encountered.");
    56   } else {
    57     REQUIRE_EQUAL(rv, NS_OK, "Unexpected tokens found during parsing.");
    58   }
    60   passed(hdr);
    61   return true;
    62 }
    64 bool TestFailure(const char* hdr,
    65                  nsISiteSecurityService* sss)
    66 {
    67   nsCOMPtr<nsIURI> dummyUri;
    68   nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
    69   EXPECT_SUCCESS(rv, "Failed to create URI");
    71   rv = sss->ProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri, hdr,
    72                           0, nullptr, nullptr);
    73   EXPECT_FAILURE(rv, "Parsed invalid header: %s", hdr);
    74   passed(hdr);
    75   return true;
    76 }
    79 int
    80 main(int32_t argc, char *argv[])
    81 {
    82     nsresult rv;
    83     ScopedXPCOM xpcom("STS Parser Tests");
    84     if (xpcom.failed())
    85       return -1;
    86     // Initialize a profile folder to ensure a clean shutdown.
    87     nsCOMPtr<nsIFile> profile = xpcom.GetProfileDirectory();
    88     if (!profile) {
    89       fail("Couldn't get the profile directory.");
    90       return -1;
    91     }
    93     // grab handle to the service
    94     nsCOMPtr<nsISiteSecurityService> sss;
    95     sss = do_GetService("@mozilla.org/ssservice;1", &rv);
    96     NS_ENSURE_SUCCESS(rv, -1);
    98     int rv0, rv1;
   100     nsTArray<bool> rvs(24);
   102     // *** parsing tests
   103     printf("*** Attempting to parse valid STS headers ...\n");
   105     // SHOULD SUCCEED:
   106     rvs.AppendElement(TestSuccess("max-age=100", false, 100, false, sss));
   107     rvs.AppendElement(TestSuccess("max-age  =100", false, 100, false, sss));
   108     rvs.AppendElement(TestSuccess(" max-age=100", false, 100, false, sss));
   109     rvs.AppendElement(TestSuccess("max-age = 100 ", false, 100, false, sss));
   110     rvs.AppendElement(TestSuccess("max-age = \"100\" ", false, 100, false, sss));
   111     rvs.AppendElement(TestSuccess("max-age=\"100\"", false, 100, false, sss));
   112     rvs.AppendElement(TestSuccess(" max-age =\"100\" ", false, 100, false, sss));
   113     rvs.AppendElement(TestSuccess("\tmax-age\t=\t\"100\"\t", false, 100, false, sss));
   114     rvs.AppendElement(TestSuccess("max-age  =       100             ", false, 100, false, sss));
   116     rvs.AppendElement(TestSuccess("maX-aGe=100", false, 100, false, sss));
   117     rvs.AppendElement(TestSuccess("MAX-age  =100", false, 100, false, sss));
   118     rvs.AppendElement(TestSuccess("max-AGE=100", false, 100, false, sss));
   119     rvs.AppendElement(TestSuccess("Max-Age = 100 ", false, 100, false, sss));
   120     rvs.AppendElement(TestSuccess("MAX-AGE = 100 ", false, 100, false, sss));
   122     rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains", false, 100, true, sss));
   123     rvs.AppendElement(TestSuccess("max-age=100\t; includeSubdomains", false, 100, true, sss));
   124     rvs.AppendElement(TestSuccess(" max-age=100; includeSubdomains", false, 100, true, sss));
   125     rvs.AppendElement(TestSuccess("max-age = 100 ; includeSubdomains", false, 100, true, sss));
   126     rvs.AppendElement(TestSuccess("max-age  =       100             ; includeSubdomains", false, 100, true, sss));
   128     rvs.AppendElement(TestSuccess("maX-aGe=100; includeSUBDOMAINS", false, 100, true, sss));
   129     rvs.AppendElement(TestSuccess("MAX-age  =100; includeSubDomains", false, 100, true, sss));
   130     rvs.AppendElement(TestSuccess("max-AGE=100; iNcLuDeSuBdoMaInS", false, 100, true, sss));
   131     rvs.AppendElement(TestSuccess("Max-Age = 100; includesubdomains ", false, 100, true, sss));
   132     rvs.AppendElement(TestSuccess("INCLUDESUBDOMAINS;MaX-AgE = 100 ", false, 100, true, sss));
   133     // Turns out, the actual directive is entirely optional (hence the
   134     // trailing semicolon)
   135     rvs.AppendElement(TestSuccess("max-age=100;includeSubdomains;", true, 100, true, sss));
   137     // these are weird tests, but are testing that some extended syntax is
   138     // still allowed (but it is ignored)
   139     rvs.AppendElement(TestSuccess("max-age=100 ; includesubdomainsSomeStuff", true, 100, false, sss));
   140     rvs.AppendElement(TestSuccess("\r\n\t\t    \tcompletelyUnrelated = foobar; max-age= 34520103    \t \t; alsoUnrelated;asIsThis;\tincludeSubdomains\t\t \t", true, 34520103, true, sss));
   141     rvs.AppendElement(TestSuccess("max-age=100; unrelated=\"quoted \\\"thingy\\\"\"", true, 100, false, sss));
   143     rv0 = rvs.Contains(false) ? 1 : 0;
   144     if (rv0 == 0)
   145       passed("Successfully Parsed STS headers with mixed case and LWS");
   147     rvs.Clear();
   149     // SHOULD FAIL:
   150     printf("*** Attempting to parse invalid STS headers (should not parse)...\n");
   151     // invalid max-ages
   152     rvs.AppendElement(TestFailure("max-age", sss));
   153     rvs.AppendElement(TestFailure("max-age ", sss));
   154     rvs.AppendElement(TestFailure("max-age=p", sss));
   155     rvs.AppendElement(TestFailure("max-age=*1p2", sss));
   156     rvs.AppendElement(TestFailure("max-age=.20032", sss));
   157     rvs.AppendElement(TestFailure("max-age=!20032", sss));
   158     rvs.AppendElement(TestFailure("max-age==20032", sss));
   160     // invalid headers
   161     rvs.AppendElement(TestFailure("foobar", sss));
   162     rvs.AppendElement(TestFailure("maxage=100", sss));
   163     rvs.AppendElement(TestFailure("maxa-ge=100", sss));
   164     rvs.AppendElement(TestFailure("max-ag=100", sss));
   165     rvs.AppendElement(TestFailure("includesubdomains", sss));
   166     rvs.AppendElement(TestFailure(";", sss));
   167     rvs.AppendElement(TestFailure("max-age=\"100", sss));
   168     // The max-age directive here doesn't conform to the spec, so it MUST
   169     // be ignored. Consequently, the REQUIRED max-age directive is not
   170     // present in this header, and so it is invalid.
   171     rvs.AppendElement(TestFailure("max-age=100, max-age=200; includeSubdomains", sss));
   172     rvs.AppendElement(TestFailure("max-age=100 includesubdomains", sss));
   173     rvs.AppendElement(TestFailure("max-age=100 bar foo", sss));
   174     rvs.AppendElement(TestFailure("max-age=100randomstuffhere", sss));
   175     // All directives MUST appear only once in an STS header field.
   176     rvs.AppendElement(TestFailure("max-age=100; max-age=200", sss));
   177     rvs.AppendElement(TestFailure("includeSubdomains; max-age=200; includeSubdomains", sss));
   178     rvs.AppendElement(TestFailure("max-age=200; includeSubdomains; includeSubdomains", sss));
   179     // The includeSubdomains directive is valueless.
   180     rvs.AppendElement(TestFailure("max-age=100; includeSubdomains=unexpected", sss));
   181     // LWS must have at least one space or horizontal tab
   182     rvs.AppendElement(TestFailure("\r\nmax-age=200", sss));
   184     rv1 = rvs.Contains(false) ? 1 : 0;
   185     if (rv1 == 0)
   186       passed("Avoided parsing invalid STS headers");
   188     return (rv0 + rv1);
   189 }

mercurial