tor-browser

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

public-key-credential-to-json.https.window.js (4451B)


      1 // META: script=/resources/testdriver.js
      2 // META: script=/resources/testdriver-vendor.js
      3 // META: script=/resources/utils.js
      4 // META: script=helpers.js
      5 
      6 function assertObjectKeysEq(a, b) {
      7  let a_keys = new Set(Object.keys(a));
      8  let b_keys = new Set(Object.keys(b));
      9  assert_true(
     10      a_keys.length == b_keys.length && [...a_keys].every(k => b_keys.has(k)),
     11      `keys differ: ${a_keys} != ${b_keys}`);
     12 }
     13 
     14 // Returns the JSON encoding for `value`. If `value` is a function, `optParent`
     15 // is the object to which execution should be bound.
     16 function convertValue(value, optParent) {
     17  switch (typeof value) {
     18    case 'undefined':
     19    case 'boolean':
     20    case 'number':
     21    case 'bigint':
     22    case 'string':
     23    case 'symbol':
     24      return value;
     25    case 'function':
     26      return value.apply(optParent);
     27    case 'object':
     28      if (value.__proto__.constructor === Object) {
     29        var result = {};
     30        Object.entries(value).map((k, v) => {
     31          result[k] = convertValue(k, v);
     32        });
     33        return result;
     34      }
     35      if (value instanceof Array) {
     36        return value.map(convertValue);
     37      }
     38      if (value instanceof ArrayBuffer) {
     39        return base64urlEncode(new Uint8Array(value));
     40      }
     41      throw `can't convert value ${value} in ${parent}`;
     42    default:
     43      throw `${value} has unexpected type`;
     44  }
     45 }
     46 
     47 // Conversion spec for a single attribute.
     48 // @typedef {Object} ConvertParam
     49 // @property {string} name - The name of the attribute to convert from
     50 // @property {string=} target - The name of the attribute to convert to, if
     51 // different from `name`
     52 // @property {function=} func - Method to convert this property. Defaults to
     53 // convertValue().
     54 
     55 // Returns the JSON object for `obj`.
     56 //
     57 // @param obj
     58 // @param {Array<(string|ConvertParam)>} keys - The names of parameters in
     59 // `obj` to convert, or instances of ConvertParam for complex cases.
     60 function convertObject(obj, params) {
     61  let result = {};
     62  params.forEach((param) => {
     63    switch (typeof (param)) {
     64      case 'string':
     65        assert_true(param in obj, `missing ${param}`);
     66        if (obj[param] !== null) {
     67          result[param] = convertValue(obj[param], obj);
     68        }
     69        break;
     70      case 'object':
     71        assert_true(param.name in obj, `missing ${param.name}`);
     72        const val = obj[param.name];
     73        const target_key = param.target || param.name;
     74        const convert_func = param.func || convertValue;
     75        try {
     76          result[target_key] =
     77              convert_func(((typeof val) == 'function' ? val.apply(obj) : val));
     78        } catch (e) {
     79          throw `failed to convert ${param.name}: ${e}`
     80        }
     81        break;
     82      default:
     83        throw `invalid key ${param}`;
     84    }
     85  });
     86  return result;
     87 }
     88 
     89 // Converts an AuthenticatorResponse instance into a JSON object.
     90 // @param {!AuthenticatorResponse}
     91 function authenticatorResponseToJson(response) {
     92  assert_true(
     93      (response instanceof AuthenticatorAttestationResponse) ||
     94      (response instanceof AuthenticatorAssertionResponse));
     95  const isAttestation = (response instanceof AuthenticatorAttestationResponse);
     96  const keys =
     97      (isAttestation ?
     98           [
     99             'clientDataJSON', 'attestationObject',
    100             {name: 'getAuthenticatorData', target: 'authenticatorData'},
    101             {name: 'getPublicKey', target: 'publicKey'},
    102             {name: 'getPublicKeyAlgorithm', target: 'publicKeyAlgorithm'},
    103             {name: 'getTransports', target: 'transports'}
    104           ] :
    105           ['clientDataJSON', 'authenticatorData', 'signature', 'userHandle']);
    106  return convertObject(response, keys);
    107 }
    108 
    109 // Converts a PublicKeyCredential instance to a JSON object.
    110 // @param {!PublicKeyCredential}
    111 function publicKeyCredentialToJson(cred) {
    112  const keys = [
    113    'id', 'rawId', {name: 'response', func: authenticatorResponseToJson},
    114    'authenticatorAttachment',
    115    {name: 'getClientExtensionResults', target: 'clientExtensionResults'},
    116    'type'
    117  ];
    118  return convertObject(cred, keys);
    119 }
    120 
    121 virtualAuthenticatorPromiseTest(
    122    async t => {
    123      let credential = await createCredential();
    124      assertJsonEquals(
    125          credential.toJSON(), publicKeyCredentialToJson(credential));
    126 
    127      let assertion = await assertCredential(credential);
    128      assertJsonEquals(
    129          assertion.toJSON(), publicKeyCredentialToJson(assertion));
    130    },
    131    {
    132      protocol: 'ctap2_1',
    133      transport: 'usb',
    134    },
    135    'toJSON()');