tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

header-component.window.js (4821B)


      1 // META: script=helper.js
      2 
      3 // The following tests validate the behavior of arbitrary header components in
      4 // signatures. They rely on the test key from
      5 // https://www.rfc-editor.org/rfc/rfc9421.html#name-example-ed25519-test-key
      6 //
      7 // TODO: Replace the placeholder signatures below with real signatures.
      8 
      9 const kBody = "window.hello = `world`;";
     10 const kDigest = "sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:";
     11 
     12 const kSignatures = {
     13  // Signature Base:
     14  // "content-type": application/javascript
     15  // "unencoded-digest";sf: sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:
     16  // "@signature-params": ("content-type" "unencoded-digest";sf);keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri"
     17  ct_then_digest: "signature=:a5uYGT79upHlmAkq3PsPHr1xz5AXjqmjVbOr38e8HW94+YqthWLjPeYVRYkYprb0zDqrreptOB4m5d148uWAAQ==:",
     18 
     19  // Signature Base:
     20  // "unencoded-digest";sf: sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:
     21  // "content-type": application/javascript
     22  // "@signature-params": ("unencoded-digest";sf "content-type");keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri"
     23  digest_then_ct: "signature=:OuJoPVjT+cucaPpFGs3hyhdOGcEEgCAaLefYWCwEGdsBFunmFAT6hbMTg/vmhLM3raZKKzWqjFkzinWtia8fAA==:",
     24 
     25  // Signature Base:
     26  // "content-type": application/javascript
     27  // "x-extra-header": some-value
     28  // "unencoded-digest";sf: sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:
     29  // "@signature-params": ("content-type" "x-missing-header" "unencoded-digest";sf);keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri"
     30  with_extra_header: "signature=:9UFhYYWqUSxadNI4vyPSln1deZGswee7DpRg761SaORKykyewqhD6pEPJBXfEaV9wJrqgq4Nq+oJb2Pe25TjDA==:",
     31 };
     32 
     33 const kRequestsWithValidSignature = [
     34  {
     35    body: kBody,
     36    digest: kDigest,
     37    signature: kSignatures.ct_then_digest,
     38    signatureInput: `signature=("content-type" "unencoded-digest";sf);keyid="${kValidKeys["rfc"]}";tag="sri"`
     39  },
     40  {
     41    body: kBody,
     42    digest: kDigest,
     43    signature: kSignatures.digest_then_ct,
     44    signatureInput: `signature=("unencoded-digest";sf "content-type");keyid="${kValidKeys["rfc"]}";tag="sri"`
     45  }
     46 ];
     47 
     48 for (const request of kRequestsWithValidSignature) {
     49    // fetch():
     50    generate_fetch_test(request, {}, EXPECT_LOADED,
     51                        `Valid signature (${request.signatureInput}), no integrity check: loads.`);
     52    generate_fetch_test(request, {integrity:`ed25519-${kValidKeys["rfc"]}`}, EXPECT_LOADED,
     53                        `Valid signature (${request.signatureInput}), matching integrity check: loads.`);
     54    generate_fetch_test(request, {integrity:`ed25519-${kInvalidKey}`}, EXPECT_BLOCKED,
     55                        `Valid signature (${request.signatureInput}), mismatched integrity check: blocked.`);
     56 
     57    // <script>:
     58    generate_script_test(request, "", EXPECT_LOADED,
     59                        `Valid signature (${request.signatureInput}), no integrity check: loads.`);
     60    generate_script_test(request, `ed25519-${kValidKeys["rfc"]}`, EXPECT_LOADED,
     61                        `Valid signature (${request.signatureInput}), matching integrity check: loads.`);
     62    generate_script_test(request, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED,
     63                        `Valid signature (${request.signatureInput}), mismatched integrity check: blocked.`);
     64 }
     65 
     66 // Test cases for failure
     67 const kFailingRequests = [
     68    // Valid signature, but the "content-type" header value does not match what is signed.
     69    {
     70        body: kBody,
     71        digest: kDigest,
     72        signature: kSignatures.digest_then_ct,
     73        signatureInput: `signature=("unencoded-digest";sf "content-type");keyid="${kValidKeys["rfc"]}";tag="sri"`,
     74        type: "text/plain", // The signature was for "application/javascript"
     75        description: "Mismatched header value"
     76    },
     77    // Valid signature, but a signed header is missing from the response.
     78    {
     79        body: kBody,
     80        digest: kDigest,
     81        signature: kSignatures.with_extra_header,
     82        signatureInput: `signature=("content-type" "x-extra-header" "unencoded-digest";sf);keyid="${kValidKeys["rfc"]}";tag="sri"`,
     83        description: "Missing signed header"
     84    }
     85 ];
     86 
     87 for (const request of kFailingRequests) {
     88    const description = request.description;
     89    // fetch():
     90    generate_fetch_test(request, {}, EXPECT_BLOCKED,
     91                        `${description}: blocked.`);
     92    generate_fetch_test(request, {integrity:`ed25519-${kValidKeys["rfc"]}`}, EXPECT_BLOCKED,
     93                        `${description} with matching integrity: blocked.`);
     94 
     95    // <script>:
     96    generate_script_test(request, "", EXPECT_BLOCKED,
     97                        `${description}: blocked.`);
     98    generate_script_test(request, `ed25519-${kValidKeys["rfc"]}`, EXPECT_BLOCKED,
     99                        `${description} with matching integrity: blocked.`);
    100 }