Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/push/test/xpcshell/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 25 kB image not shown  

Quelle  test_crypto.js   Sprache: JAVA

 
"use strict";

const { getCryptoParamsFromHeaders, PushCrypto } = ChromeUtils.importESModule(
  "resource://gre/modules/PushCrypto.sys.mjs"
);

const REJECT_PADDING = { padding: "reject" };

// A common key to decrypt some aesgcm and aesgcm128 messages. Other decryption
// tests have their own keys.
const LEGACY_PRIVATE_KEY = {
  kty: "EC",
  crv: "P-256",
  d: "4h23G_KkXC9TvBSK2v0Q7ImpS2YAuRd8hQyN0rFAwBg",
  x: "sd85ZCbEG6dEkGMCmDyGBIt454Qy-Yo-1xhbaT2Jlk4",
  y: "vr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs",
  ext: true,
};

const LEGACY_PUBLIC_KEY =
  "BLHfOWQmxBunRJBjApg8hgSLeOeEMvmKPtcYW2k9iZZOvr3cKpQ-Sp1kpZ9HipNjUCwSA55yy0uM8N9byE8dmLs";

async function assertDecrypts(test, headers) {
  let privateKey = test.privateKey;
  let publicKey = ChromeUtils.base64URLDecode(test.publicKey, REJECT_PADDING);
  let authSecret = null;
  if (test.authSecret) {
    authSecret = ChromeUtils.base64URLDecode(test.authSecret, REJECT_PADDING);
  }
  let payload = ChromeUtils.base64URLDecode(test.data, REJECT_PADDING);
  let result = await PushCrypto.decrypt(
    privateKey,
    publicKey,
    authSecret,
    headers,
    payload
  );
  let decoder = new TextDecoder("utf-8");
  equal(decoder.decode(new Uint8Array(result)), test.result, test.desc);
}

async function assertNotDecrypts(test, headers) {
  let authSecret = null;
  if (test.authSecret) {
    authSecret = ChromeUtils.base64URLDecode(test.authSecret, REJECT_PADDING);
  }
  let data = ChromeUtils.base64URLDecode(test.data, REJECT_PADDING);
  let publicKey = ChromeUtils.base64URLDecode(test.publicKey, REJECT_PADDING);
  let promise = PushCrypto.decrypt(
    test.privateKey,
    publicKey,
    authSecret,
    headers,
    data
  );
  await Assert.rejects(promise, test.expected, test.desc);
}

add_setup(async function () {
  // Per https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/instrumentation_tests.html#xpcshell-tests
  do_get_profile();
  Services.fog.initializeFOG();
});

add_task(async function test_crypto_getCryptoParamsFromHeaders() {
  // These headers should parse correctly.
  let shouldParse = [
    {
      desc: "aesgcm with multiple keys",
      headers: {
        encoding: "aesgcm",
        crypto_key: "keyid=p256dh;dh=Iy1Je2Kv11A,p256ecdsa=o2M8QfiEKuI",
        encryption: "keyid=p256dh;salt=upk1yFkp1xI",
      },
      params: {
        senderKey: "Iy1Je2Kv11A",
        salt: "upk1yFkp1xI",
        rs: 4096,
      },
    },
    {
      desc: "aesgcm with quoted key param",
      headers: {
        encoding: "aesgcm",
        crypto_key: 'dh="byfHbUffc-k"',
        encryption: "salt=C11AvAsp6Gc",
      },
      params: {
        senderKey: "byfHbUffc-k",
        salt: "C11AvAsp6Gc",
        rs: 4096,
      },
    },
    {
      desc: "aesgcm with Crypto-Key and rs = 24",
      headers: {
        encoding: "aesgcm",
        crypto_key: 'dh="ybuT4VDz-Bg"',
        encryption: "salt=H7U7wcIoIKs; rs=24",
      },
      params: {
        senderKey: "ybuT4VDz-Bg",
        salt: "H7U7wcIoIKs",
        rs: 24,
      },
    },
    {
      desc: "aesgcm with Crypto-Key and rs = 2",
      headers: {
        encoding: "aesgcm",
        crypto_key: "dh=LqrDQuVl9lY",
        encryption: "salt=YngI8B7YapM; rs=2",
      },
      params: {
        senderKey: "LqrDQuVl9lY",
        salt: "YngI8B7YapM",
        rs: 2,
      },
    },
  ];
  for (let test of shouldParse) {
    let params = getCryptoParamsFromHeaders(test.headers);
    let senderKey = ChromeUtils.base64URLDecode(
      test.params.senderKey,
      REJECT_PADDING
    );
    let salt = ChromeUtils.base64URLDecode(test.params.salt, REJECT_PADDING);
    deepEqual(
      new Uint8Array(params.senderKey),
      new Uint8Array(senderKey),
      "Sender key should match for " + test.desc
    );
    deepEqual(
      new Uint8Array(params.salt),
      new Uint8Array(salt),
      "Salt should match for " + test.desc
    );
    equal(
      params.rs,
      test.params.rs,
      "Record size should match for " + test.desc
    );
  }

  // These headers should be rejected.
  let shouldThrow = [
    {
      desc: "aesgcm128 with Crypto-Key",
      headers: {
        encoding: "aesgcm128",
        crypto_key: "keyid=v2; dh=VA6wmY1IpiE",
        encryption: "keyid=v2; salt=F0Im7RtGgNY",
      },
      exception: /Unexpected encoding/,
    },
    {
      desc: "aesgcm128 with Encryption-Key and rs = 2",
      headers: {
        encoding: "aesgcm128",
        encryption_key: "keyid=legacy; dh=LqrDQuVl9lY",
        encryption: "keyid=legacy; salt=YngI8B7YapM; rs=2",
      },
      exception: /Unexpected encoding/,
    },
    {
      desc: "aesgcm128 with Encryption-Key",
      headers: {
        encoding: "aesgcm128",
        encryption_key: "keyid=v2; dh=VA6wmY1IpiE",
        encryption: "keyid=v2; salt=khtpyXhpDKM",
      },
      exception: /Unexpected encoding/,
    },
    {
      desc: "Invalid encoding",
      headers: {
        encoding: "nonexistent",
      },
      exception: /Unexpected encoding/,
    },
    {
      desc: "Missing salt header",
      headers: {
        encoding: "aesgcm",
        crypto_key: "dh=pbmv1QkcEDY",
        encryption: "dh=Esao8aTBfIk;rs=32",
      },
      exception: /Invalid salt parameter/,
    },
    {
      desc: "Invalid record size",
      headers: {
        encoding: "aesgcm",
        crypto_key: "dh=pbmv1QkcEDY",
        encryption: "salt=Esao8aTBfIk;rs=bad",
      },
      exception: /rs parameter must be/,
    },
    {
      desc: "Zero record size",
      headers: {
        encoding: "aesgcm",
        crypto_key: "dh=pbmv1QkcEDY",
        encryption: "salt=Esao8aTBfIk;rs=0",
      },
      exception: /rs parameter must be/,
    },
    {
      desc: "Too big record size",
      headers: {
        encoding: "aesgcm",
        crypto_key: "dh=pbmv1QkcEDY",
        encryption: "salt=Esao8aTBfIk;rs=68719476736",
      },
      exception: /rs parameter must be/,
    },
    {
      desc: "aesgcm with Encryption-Key",
      headers: {
        encoding: "aesgcm",
        encryption_key: "dh=FplK5KkvUF0",
        encryption: "salt=p6YHhFF3BQY",
      },
      exception: /Missing Crypto-Key header/,
    },
  ];
  for (let test of shouldThrow) {
    throws(
      () => getCryptoParamsFromHeaders(test.headers),
      test.exception,
      test.desc
    );
  }
});

add_task(async function test_aes128gcm_ok() {
  Services.fog.testResetFOG();
  let expectedSuccesses = [
    {
      desc: "Example from draft-ietf-webpush-encryption-latest",
      result: "When I grow up, I want to be a watermelon",
      data: "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN",
      authSecret: "BTBZMqHH6r4Tts7J_aSIgg",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "q1dXpw3UpT5VOmu_cf_v6ih07Aems3njxI-JWgLcM94",
        x: "JXGyvs3942BVGq8e0PTNNmwRzr5VX4m8t7GGpTM5FzE",
        y: "aOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4",
        ext: true,
      },
      publicKey:
        "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4",
    },
    {
      desc: "rs = 24, pad = 0",
      result:
        "I am the very model of a modern Major-General; I've information vegetable, animal, and mineral",
      data: "goagSH7PP0ZGwUsgShmdkwAAABhBBDJVyIuUJbOSVMeWHP8VNPnxY-dZSw86doqOkEzZZZY1ALBWVXTVf0rUDH3oi68I9Hrp-01zA-mr8XKWl5kcH8cX0KiV2PtCwdkEyaQ73YF5fsDxgoWDiaTA3wPqMvuLDqGsZWHnE9Psnfoy7UMEqKlh2a1nE7ZOXiXcOBHLNj260jYzSJnEPV2eXixSXfyWpaSJHAwfj4wVdAAocmViIg6ywk8wFB1hgJpnX2UVEU_qIOcaP6AOIOr1UUQPfosQqC2MEHe5u9gHXF5pi-E267LAlkoYefq01KV_xK_vjbxpw8GAYfSjQEm0L8FG-CN37c8pnQ2Yf61MkihaXac9OctfNeWq_22cN6hn4qsOq0F7QoWIiZqWhB1vS9cJ3KUlyPQvKI9cvevDxw0fJHWeTFzhuwT9BjdILjjb2Vkqc0-qTDOawqD4c8WXsvdGDQCec5Y1x3UhdQXdjR_mhXypxFM37OZTvKJBr1vPCpRXl-bI6iOd7KScgtMM1x5luKhGzZyz25HyuFyj1ec82A",
      authSecret: "_tK2LDGoIt6be6agJ_nvGA",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "bGViEe3PvjjFJg8lcnLsqu71b2yqWGnZN9J2MTed-9s",
        x: "auB0GHF0AZ2LAocFnvOXDS7EeCMopnzbg-tS21FMHrU",
        y: "GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc",
        ext: true,
      },
      publicKey:
        "BGrgdBhxdAGdiwKHBZ7zlw0uxHgjKKZ824PrUttRTB61GpbhrW-_xKj3XhhXA-kDZSicKZ0kn0BuVhqzhLOB-Cc",
    },
    {
      desc: "rs = 49, pad = 84; ciphertext length falls on record boundary",
      result: "Hello, world",
      data: "-yiDzsHE_K3W0TcfbqSR4AAAADFBBC1EHuf5_2oDKaZJJ9BST9vnsixvtl4Qq0_cA4-UQgoMo_oo2tNshOyRoWLq4Hj6rSwc7XjegRPhlgKyDolPSXa5c-L89oL6DIzNmvPVv_Ht4W-tWjHOGdOLXh_h94pPrYQrvBAlTCxs3ZaitVKE2XLFPK2MO6yxD19X6w1KQzO2BBAroRfK4pEI-9n2Kai6aWDdAZRbOe03unBsQ0oQ_SvSCU_5JJvNrUUTX1_kX804Bx-LLTlBr9pDmBDXeqyvfOULVDJb9YyVAzN9BzeFoyPfo0M",
      authSecret: "lfF1cOUI72orKtG09creMw",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "ZwBKTqgg3u2OSdtelIDmPT6jzOGujhpgYJcT1SfQAe8",
        x: "AU6PFLktoHzgg7k_ljZ-h7IXpH9-8u6TqdNDqgY-V1o",
        y: "nzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE",
        ext: true,
      },
      publicKey:
        "BAFOjxS5LaB84IO5P5Y2foeyF6R_fvLuk6nTQ6oGPldanzDVnGkMajmz_IFbFQyn3RSWAXQTN7U1B6UfQbFzpyE",
    },
    {
      desc: "rs = 18, pad = 0",
      result: "1",
      data: "fK69vCCTjuNAqUbxvU9o8QAAABJBBDfP21Ij2fleqgL27ZQP8i6vBbNiLpSdw86fM15u-bJq6qzKD3QICos2RZLyzMbV7d1DAEtwuRiH0UTZ-pPxbDvH6mj0_VR6lOyoSxbhOKYIAXc",
      authSecret: "1loE35Xy215gSDn3F9zeeQ",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "J0M_q4lws8tShLYRg--0YoZWLNKnMw2MrpYJEaVXHQw",
        x: "UV1DJjVWUjmdoksr6SQeYztc8U-vDPOm_WAxe5VMCi8",
        y: "SEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8",
        ext: true,
      },
      publicKey:
        "BFFdQyY1VlI5naJLK-kkHmM7XPFPrwzzpv1gMXuVTAovSEhUgASyewz3SAvIEMa-wDqPt5yOoA_IsF4A-INFY-8",
    },
  ];
  for (let test of expectedSuccesses) {
    let privateKey = test.privateKey;
    let publicKey = ChromeUtils.base64URLDecode(test.publicKey, {
      padding: "reject",
    });
    let authSecret = ChromeUtils.base64URLDecode(test.authSecret, {
      padding: "reject",
    });
    let payload = ChromeUtils.base64URLDecode(test.data, {
      padding: "reject",
    });
    let result = await PushCrypto.decrypt(
      privateKey,
      publicKey,
      authSecret,
      {
        encoding: "aes128gcm",
      },
      payload
    );
    let decoder = new TextDecoder("utf-8");
    equal(decoder.decode(new Uint8Array(result)), test.result, test.desc);
  }
  Assert.equal(
    Glean.webPush.contentEncoding.aes128gcm.testGetValue(),
    4,
    "Glean counter should be increased for each decrypt"
  );
});

add_task(async function test_aes128gcm_err() {
  let expectedFailures = [
    {
      // Just the payload; no header at all.
      desc: "Missing header block",
      data: "RbdNK2m-mwdN47NaqH58FWEd",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "G-g_ODMu8JaB-vPzB7H_LhDKt4zHzatoOsDukqw_buE",
        x: "26mRyiFTQ_Nr3T6FfK_ePRi_V_GDWygzutQU8IhBYgU",
        y: "GslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw",
        ext: true,
      },
      publicKey:
        "BNupkcohU0Pza90-hXyv3j0Yv1fxg1soM7rUFPCIQWIFGslqCyRJADfQfPUo5OGOEAoaZOt0R0hUS_HiINq6zyw",
      authSecret: "NHG7mEgeAlM785VCvPPbpA",
      expected: /Truncated header/,
    },
    {
      // The sender key should be 65 bytes; this header contains an invalid key
      // that's only 1 byte.
      desc: "Truncated sender key",
      data: "3ltpa4fxoVy2revdedb5ngAAABIBALa8GCbDfJ9z3WtIWcK1BRgZUg",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "zojo4LMFekdS60yPqTHrYhwwLaWtA7ga9FnPZzVWDK4",
        x: "oyXZkITEDeDOcioELESNlKMmkXIcp54890XnjGmIYZQ",
        y: "sCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE",
        ext: true,
      },
      publicKey:
        "BKMl2ZCExA3gznIqBCxEjZSjJpFyHKeePPdF54xpiGGUsCzqGSJBdnlanU27sgc68szW-m8KTHxJaFVr5QKjuoE",
      authSecret: "XDHg2W2aE5iZrAlp01n3QA",
      expected: /Invalid sender public key/,
    },
    {
      // The message is encrypted with only the first 12 bytes of the 16-byte
      // auth secret, so the derived decryption key and nonce won't match.
      desc: "Encrypted with mismatched auth secret",
      data: "gRX0mIuMOSp7rLQ8jxrFZQAAABJBBBmUSDxUHpvDmmrwP_cTqndFwoThOKQqJDW3l7IMS2mM9RGLT4VVMXwZDqvr-rdJwWTT9r3r4NRBcZExo1fYiQoTxNvUsW_z3VqD98ka1uBArEJzCn8LPNMkXp-Nb_McdR1BDP0",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "YMdjalF95wOaCsLQ4wZEAHlMeOfgSTmBKaInzuD5qAE",
        x: "_dBBKKhcBYltf4H-EYvcuIe588H_QYOtxMgk0ShgcwA",
        y: "6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY",
        ext: true,
      },
      publicKey:
        "BP3QQSioXAWJbX-B_hGL3LiHufPB_0GDrcTIJNEoYHMA6Yay37WmEOWvQ-QIoAcwWE-T49_d_ERzfV8I-y1viRY",
      authSecret: "NVo4zW2b7xWZDi0zCNvWAA",
      expected: /Bad encryption/,
    },
    {
      // Multiple records; the first has padding delimiter = 2, but should be 1.
      desc: "Early final record",
      data: "2-IVUH0a09Lq6r6ubodNjwAAABJBBHvEND80qDSM3E5GL_x8QKpqjGGnOcTEHUUSVQX3Dp_F-e-oaFLdSI3Pjo6iyvt14Hq9XufJ1cA4uv7weVcbC9opRBHOmMdt0DHA5YBXekmAo3XkXtMEKb4OLunafm34aW0BuOw",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "XdodkYvEB7o82hLLgBTUmqfgJpACggMERmvIADTKkkA",
        x: "yVxlINrRHo9qG_gDGkDCpO4QRcGQO-BqHfp_gpzOst4",
        y: "Akga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU",
        ext: true,
      },
      publicKey:
        "BMlcZSDa0R6Pahv4AxpAwqTuEEXBkDvgah36f4KczrLeAkga5r0EdhIbEsVTLQsjF4gHfvoGg6W_4NYjObJRyzU",
      authSecret: "QMJB_eQmnuHm1yVZLZgnGA",
      expected: /Padding is wrong!/,
    },
  ];
  for (let test of expectedFailures) {
    await assertNotDecrypts(test, { encoding: "aes128gcm" });
  }
});

add_task(async function test_aesgcm_ok() {
  Services.fog.testResetFOG();
  let expectedSuccesses = [
    {
      desc: "padSize = 2, rs = 24, pad = 0",
      result: "Some message",
      data: "Oo34w2F9VVnTMFfKtdx48AZWQ9Li9M6DauWJVgXU",
      authSecret: "aTDc6JebzR6eScy2oLo4RQ",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BCHFVrflyxibGLlgztLwKelsRZp4gqX3tNfAKFaxAcBhpvYeN1yIUMrxaDKiLh4LNKPtj0BOXGdr-IQ-QP82Wjo",
        encryption: "salt=zCU18Rw3A5aB_Xi-vfixmA; rs=24",
        encoding: "aesgcm",
      },
    },
    {
      desc: "padSize = 2, rs = 8, pad = 16",
      result: "Yet another message",
      data: "uEC5B_tR-fuQ3delQcrzrDCp40W6ipMZjGZ78USDJ5sMj-6bAOVG3AK6JqFl9E6AoWiBYYvMZfwThVxmDnw6RHtVeLKFM5DWgl1EwkOohwH2EhiDD0gM3io-d79WKzOPZE9rDWUSv64JstImSfX_ADQfABrvbZkeaWxh53EG59QMOElFJqHue4dMURpsMXg",
      authSecret: "6plwZnSpVUbF7APDXus3UQ",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BEaA4gzA3i0JDuirGhiLgymS4hfFX7TNTdEhSk_HBlLpkjgCpjPL5c-GL9uBGIfa_fhGNKKFhXz1k9Kyens2ZpQ",
        encryption: "salt=ZFhzj0S-n29g9P2p4-I7tA; rs=8",
        encoding: "aesgcm",
      },
    },
    {
      desc: "padSize = 2, rs = 3, pad = 0",
      result: "Small record size",
      data: "oY4e5eDatDVt2fpQylxbPJM-3vrfhDasfPc8Q1PWt4tPfMVbz_sDNL_cvr0DXXkdFzS1lxsJsj550USx4MMl01ihjImXCjrw9R5xFgFrCAqJD3GwXA1vzS4T5yvGVbUp3SndMDdT1OCcEofTn7VC6xZ-zP8rzSQfDCBBxmPU7OISzr8Z4HyzFCGJeBfqiZ7yUfNlKF1x5UaZ4X6iU_TXx5KlQy_toV1dXZ2eEAMHJUcSdArvB6zRpFdEIxdcHcJyo1BIYgAYTDdAIy__IJVCPY_b2CE5W_6ohlYKB7xDyH8giNuWWXAgBozUfScLUVjPC38yJTpAUi6w6pXgXUWffende5FreQpnMFL1L4G-38wsI_-ISIOzdO8QIrXHxmtc1S5xzYu8bMqSgCinvCEwdeGFCmighRjj8t1zRWo0D14rHbQLPR_b1P5SvEeJTtS9Nm3iibM",
      authSecret: "g2rWVHUCpUxgcL9Tz7vyeQ",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BCg6ZIGuE2ZNm2ti6Arf4CDVD_8--aLXAGLYhpghwjl1xxVjTLLpb7zihuEOGGbyt8Qj0_fYHBP4ObxwJNl56bk",
        encryption: "salt=5LIDBXbvkBvvb7ZdD-T4PQ; rs=3",
        encoding: "aesgcm",
      },
    },
    {
      desc: "Example from draft-ietf-httpbis-encryption-encoding-02",
      result: "I am the walrus",
      data: "6nqAQUME8hNqw5J3kl8cpVVJylXKYqZOeseZG8UueKpA",
      authSecret: "R29vIGdvbyBnJyBqb29iIQ",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "9FWl15_QUQAWDaD3k3l50ZBZQJ4au27F1V4F0uLSD_M",
        x: "ISQGPMvxncL6iLZDugTm3Y2n6nuiyMYuD3epQ_TC-pE",
        y: "T21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU",
        ext: true,
      },
      publicKey:
        "BCEkBjzL8Z3C-oi2Q7oE5t2Np-p7osjGLg93qUP0wvqRT21EEWyf0cQDQcakQMqz4hQKYOQ3il2nNZct4HgAUQU",
      headers: {
        crypto_key:
          'keyid="dhkey"; dh="BNoRDbb84JGm8g5Z5CFxurSqsXWJ11ItfXEWYVLE85Y7CYkDjXsIEc4aqxYaQ1G8BqkXCJ6DPpDrWtdWj_mugHU"',
        encryption: 'keyid="dhkey"; salt="lngarbyKfMoi9Z75xYXmkg"',
        encoding: "aesgcm",
      },
    },
  ];
  for (let test of expectedSuccesses) {
    await assertDecrypts(test, test.headers);
  }
  Assert.equal(
    Glean.webPush.contentEncoding.aesgcm.testGetValue(),
    4,
    "Glean counter should be increased for each decrypt"
  );
});

add_task(async function test_aesgcm_err() {
  let expectedFailures = [
    {
      desc: "aesgcm128 message decrypted as aesgcm",
      data: "fwkuwTTChcLnrzsbDI78Y2EoQzfnbMI8Ax9Z27_rwX8",
      authSecret: "BhbpNTWyO5wVJmVKTV6XaA",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0",
        encryption: "salt=c6JQl9eJ0VvwrUVCQDxY7Q",
        encoding: "aesgcm",
      },
      expected: /Bad encryption/,
    },
    {
      // The plaintext is "O hai". The ciphertext is exactly `rs + 16` bytes,
      // but we didn't include the empty trailing block that aesgcm requires for
      // exact multiples.
      desc: "rs = 7, no trailing block",
      data: "YG4F-b06y590hRlnSsw_vuOw62V9Iz8",
      authSecret: "QoDi0u6vcslIVJKiouXMXw",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "2bu4paOAZbL2ef1u-wTzONuTIcDPc00o0zUJgg46XTc",
        x: "uEvLZUMVn1my0cwnLdcFT0mj1gSU5uzI3HeGwXC7jX8",
        y: "SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo",
        ext: true,
      },
      publicKey:
        "BLhLy2VDFZ9ZstHMJy3XBU9Jo9YElObsyNx3hsFwu41_SfNVLGL-FurydsuzciDfw8K1cUHyoDWnJJ_16UG6Dbo",
      headers: {
        crypto_key:
          "dh=BD_bsTUpxBMvSv8eksith3vijMLj44D4jhJjO51y7wK1ytbUlsyYBBYYyB5AAe5bnREA_WipTgemDVz00LiWcfM",
        encryption: "salt=xKWvs_jWWeg4KOsot_uBhA; rs=7",
        encoding: "aesgcm",
      },
      expected: /Encrypted data truncated/,
    },
    {
      // The last block is only 1 byte, but valid blocks must be at least 2 bytes.
      desc: "Pad size > last block length",
      data: "JvX9HsJ4lL5gzP8_uCKc6s15iRIaNhD4pFCgq5-dfwbUqEcNUkqv",
      authSecret: "QtGZeY8MQfCaq-XwKOVGBQ",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "CosERAVXgvTvoh7UkrRC2V-iXoNs0bXle9I68qzkles",
        x: "_D0YqEwirvTJQJdjG6xXrjstMVpeAzf221cUqZz6hgY",
        y: "9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c",
        ext: true,
      },
      publicKey:
        "BPw9GKhMIq70yUCXYxusV647LTFaXgM39ttXFKmc-oYG9MnFbM7U14uiYMDI5e2I4jN29tYmsM9F66QodhKmA-c",
      headers: {
        crypto_key:
          "dh=BBNZNEi5Ew_ID5S4Y9jWBi1NeVDje6Mjs7SDLViUn6A8VAZj-6X3QAuYQ3j20BblqjwTgYst7PRnY6UGrKyLbmU",
        encryption: "salt=ot8hzbwOo6CYe6ZhdlwKtg; rs=6",
        encoding: "aesgcm",
      },
      expected: /Decoded array is too short/,
    },
    {
      // The last block is 3 bytes (2 bytes for the pad length; 1 byte of data),
      // but claims its pad length is 2.
      desc: "Padding length > last block length",
      data: "oWSOFA-UO5oWq-kI79RHaFfwAejLiQJ4C7eTmrSTBl4gArLXfx7lZ-Y",
      authSecret: "gKG_P6-de5pyzS8hyH_NyQ",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "9l-ahcBM-I0ykwbWiDS9KRrPdhyvTZ0SxKiPpj2aeaI",
        x: "qx0tU4EDaQv6ayFA3xvLLBdMmn4mLxjn7SK6mIeIxeg",
        y: "ymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI",
        ext: true,
      },
      publicKey:
        "BKsdLVOBA2kL-mshQN8byywXTJp-Ji8Y5-0iupiHiMXoymbMcmUOEyh_-rLrBsi26NG4UFCis2MTDs5FG2VdDPI",
      headers: {
        crypto_key:
          "dh=BKe2IBO_cwmEzQyTVscSbQcj0Y3uBSzGZ_mHlANMciS8uGpb7U8_Bw7TNdlYfpwWDLd0cxM8YYWNDbNJ_p2Rp4o",
        encryption: "salt=z7QJ6UR89SiFRkd4RsC4Vg; rs=6",
        encoding: "aesgcm",
      },
      expected: /Padding is wrong/,
    },
    {
      // The first block has no padding, but claims its pad length is 1.
      desc: "Non-zero padding",
      data: "Qdvjh0LkZXKu_1Hvv56D0rOSF6Mww3y0F8xkxUNlwVu2U1iakOUUGRs",
      authSecret: "cMpWQW58BrpDbJ8KqbS9ig",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "IzuaxLqFJmjSu8GjLCo2oEaDZjDButW4m4T0qx02XsM",
        x: "Xy7vt_TJTynxwWsQyY069BcKmrhkRjhKPFuTi-AphoY",
        y: "0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk",
        ext: true,
      },
      publicKey:
        "BF8u77f0yU8p8cFrEMmNOvQXCpq4ZEY4Sjxbk4vgKYaG0M10IVM1ourR7Q5AUX2b2fgdmGyTWcYsdHcdFK_b4Hk",
      headers: {
        crypto_key:
          "dh=BBicj01QI0ryiFzAaty9VpW_crgq9XbU1bOCtEZI9UNE6tuOgp4lyN_UN0N905ECnLWK5v_sCPUIxnQgOuCseSo",
        encryption: "salt=SbkGHONbQBBsBcj9dLyIUw; rs=6",
        encoding: "aesgcm",
      },
      expected: /Padding is wrong/,
    },
    {
      // The first record is 22 bytes: 2 bytes for the pad length, 4 bytes of
      // data, and a 16-byte auth tag. The second "record" is missing the pad
      // and data, and contains just the auth tag.
      desc: "rs = 6, second record truncated to only auth tag",
      data: "C7u3j5AL4Yzh2yYB_umN6tzrVHxrt7D5baTEW9DE1Bk3up9fY4w",
      authSecret: "3rWhsRCU_KdaqfKPbd3zBQ",
      privateKey: {
        kty: "EC",
        crv: "P-256",
        d: "nhOT9171xuoQBJGkiZ3aqT5qw_ILJ94_PPiVNu1LFSY",
        x: "lCj7ctQTmRfwzTMcODlNfHjFMAHmgdI44OhTQXX_xpE",
        y: "WBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw",
        ext: true,
      },
      publicKey:
        "BJQo-3LUE5kX8M0zHDg5TXx4xTAB5oHSOODoU0F1_8aRWBdgz4GWGtGAisC63O9DtP5l--hnCzPZiV-YZ-a6Lcw",
      headers: {
        crypto_key:
          "dh=BI38Qs_OhDmQIxbszc6Nako-MrX3FzAE_8HzxM1wgoEIG4ocxyF-YAAVhfkpJUvDpRyKW2LDHIaoylaZuxQfRhE",
        encryption: "salt=QClh48OlvGpSjZ0Mg0e8rg; rs=6",
        encoding: "aesgcm",
      },
      expected: /Decoded array is too short/,
    },
  ];
  for (let test of expectedFailures) {
    await assertNotDecrypts(test, test.headers);
  }
});

add_task(async function test_aesgcm128_err() {
  let expectedFailures = [
    {
      desc: "padSize = 1, rs = 4096, pad = 2",
      result: "aesgcm128 encrypted message",
      data: "ljBJ44NPzJFH9EuyT5xWMU4vpZ90MdAqaq1TC1kOLRoPNHtNFXeJ0GtuSaE",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        encryption_key:
          "dh=BOmnfg02vNd6RZ7kXWWrCGFF92bI-rQ-bV0Pku3-KmlHwbGv4ejWqgasEdLGle5Rhmp6SKJunZw2l2HxKvrIjfI",
        encryption: "salt=btxxUtclbmgcc30b9rT3Bg; rs=4096",
        encoding: "aesgcm128",
      },
      expected: /Unsupported Content-Encoding/,
    },
    {
      // aesgcm128 doesn't use an auth secret, but we've mixed one in during
      // encryption, so the decryption key and nonce won't match.
      desc: "padSize = 1, rs = 4096, auth secret, pad = 8",
      data: "h0FmyldY8aT5EQ6CJrbfRn_IdDvytoLeHb9_q5CjtdFRfgDRknxLmOzavLaVG4oOiS0r",
      authSecret: "Sxb6u0gJIhGEogyLawjmCw",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BCXHk7O8CE-9AOp6xx7g7c-NCaNpns1PyyHpdcmDaijLbT6IdGq0ezGatBwtFc34BBfscFxdk4Tjksa2Mx5rRCM",
        encryption: "salt=aGBpoKklLtrLcAUCcCr7JQ",
        encoding: "aesgcm128",
      },
      expected: /Unsupported Content-Encoding/,
    },
    {
      // The first byte of each record must be the pad length.
      desc: "Missing padding",
      data: "anvsHj7oBQTPMhv7XSJEsvyMS4-8EtbC7HgFZsKaTg",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BMSqfc3ohqw2DDgu3nsMESagYGWubswQPGxrW1bAbYKD18dIHQBUmD3ul_lu7MyQiT5gNdzn5JTXQvCcpf-oZE4",
        encryption: "salt=Czx2i18rar8XWOXAVDnUuw",
        encoding: "aesgcm128",
      },
      expected: /Unsupported Content-Encoding/,
    },
    {
      desc: "Truncated input",
      data: "AlDjj6NvT5HGyrHbT8M5D6XBFSra6xrWS9B2ROaCIjwSu3RyZ1iyuv0",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BCHn-I-J3dfPRLJBlNZ3xFoAqaBLZ6qdhpaz9W7Q00JW1oD-hTxyEECn6KYJNK8AxKUyIDwn6Icx_PYWJiEYjQ0",
        encryption: "salt=c6JQl9eJ0VvwrUVCQDxY7Q; rs=25",
        encoding: "aesgcm128",
      },
      expected: /Unsupported Content-Encoding/,
    },
    {
      desc: "Padding length > rs",
      data: "Ct_h1g7O55e6GvuhmpjLsGnv8Rmwvxgw8iDESNKGxk_8E99iHKDzdV8wJPyHA-6b2E6kzuVa5UWiQ7s4Zms1xzJ4FKgoxvBObXkc_r_d4mnb-j245z3AcvRmcYGk5_HZ0ci26SfhAN3lCgxGzTHS4nuHBRkGwOb4Tj4SFyBRlLoTh2jyVK2jYugNjH9tTrGOBg7lP5lajLTQlxOi91-RYZSfFhsLX3LrAkXuRoN7G1CdiI7Y3_eTgbPIPabDcLCnGzmFBTvoJSaQF17huMl_UnWoCj2WovA4BwK_TvWSbdgElNnQ4CbArJ1h9OqhDOphVu5GUGr94iitXRQR-fqKPMad0ULLjKQWZOnjuIdV1RYEZ873r62Yyd31HoveJcSDb1T8l_QK2zVF8V4k0xmK9hGuC0rF5YJPYPHgl5__usknzxMBnRrfV5_MOL5uPZwUEFsu",
      privateKey: LEGACY_PRIVATE_KEY,
      publicKey: LEGACY_PUBLIC_KEY,
      headers: {
        crypto_key:
          "dh=BAcMdWLJRGx-kPpeFtwqR3GE1LWzd1TYh2rg6CEFu53O-y3DNLkNe_BtGtKRR4f7ZqpBMVS6NgfE2NwNPm3Ndls",
        encryption: "salt=NQVTKhB0rpL7ZzKkotTGlA; rs=1",
        encoding: "aesgcm128",
      },
      expected: /Unsupported Content-Encoding/,
    },
  ];
  for (let test of expectedFailures) {
    await assertNotDecrypts(test, test.headers);
  }
});

Messung V0.5
C=95 H=88 G=91

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.