Skip to content

doc: Fully Expanded Passkey Objects + JSDoc types #6

@coolaj86

Description

@coolaj86

TODO:

  • Decode PEM to JWK
  • correct CBOR parser for credentialId

Partial at go-webauthn/webauthn#291 (comment)

aaguid lookup: https://passkeydeveloper.github.io/passkey-authenticator-aaguids/explorer/?combined

Passkey (WebAuthn Credential) Registration (Creation)

./fixtures/apple-m2-01-credential-creation-response.json (fully decoded):

{
  "authenticatorAttachment": "platform",

  "id": "BvvM60zMdJwPG8Z2eeBjXu9nyd8",
  "rawId": "BvvM60zMdJwPG8Z2eeBjXu9nyd8",
  "rawIdHex": "06fbcceb4ccc749c0f1bc67679e0635eef67c9df",

  "response": {

    "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYvyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jBdAAAAAPv8MAcVTk7MjAtuAgVX170AFAb7zOtMzHScDxvGdnngY17vZ8nfpQECAyYgASFYINbKXNDEO9D2GzLehw5365SM4scbsysvT4DsOVZkCZqHIlggr6WD8AitmkMfu8UIs-QgwdGtjUmkMrhz_lhP-jxMG-g",
    "attestationObjectHex": "a363666d74646e6f6e656761747453746d74a06861757468446174615898bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
    "attestation": {
      "fmt": "none",
      "attStmt": {},
      "authData": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
      "authenticator": {
        "rpidHash": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda30",
        "isUserPresent": true,
        "userVerified": true,
        "isMultiDeviceCredential": true,
        "isBackedUp": true,
        "hasAttestedCredential": true,
        "hasExtensionData": false,
        "signCount": 0,
        "attestedCredentialData": "fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9df",
        "attestedCredential": {
          "aaguid": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd",
          "credentialId": "06fbcceb4ccc749c0f1bc67679e0635eef67c9df",
          "publicKeyCBOR": "a5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
          "publicKeyCOSE": {
            "1": 2,
            "3": -7,
            "-1": 1,
            "-2": "6761747453746d74a06861757468446174615898bf2343ca3f7df297f41d21b4",
            "-3": "ad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b"
          },
          "publicKeyJWK": {
            "kty": "EC",
            "alg": "ES256",
            "x": "",
            "y": ""
          }
        },
        "extensions": null
      }
    },

    "authenticatorData": "vyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jBdAAAAAPv8MAcVTk7MjAtuAgVX170AFAb7zOtMzHScDxvGdnngY17vZ8nfpQECAyYgASFYINbKXNDEO9D2GzLehw5365SM4scbsysvT4DsOVZkCZqHIlggr6WD8AitmkMfu8UIs-QgwdGtjUmkMrhz_lhP-jxMG-g",
    "authenticatorDataHex": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
    "authenticator": {
      "rpidHash": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda30",
      "isUserPresent": true,
      "userVerified": true,
      "isMultiDeviceCredential": true,
      "isBackedUp": true,
      "hasAttestedCredential": true,
      "hasExtensionData": false,
      "signCount": 0,
      "attestedCredentialData": "fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9df",
      "attestedCredential": {
        "aaguid": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd",
        "credentialId": "06fbcceb4ccc749c0f1bc67679e0635eef67c9df",
        "publicKeyCBOR": "a5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
        "publicKey": {
          "1": 2,
          "3": -7,
          "-1": 1,
          "-2": "21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc300715",
          "-3": "8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa501"
        },
        "publicKeyJWK": {
          "kty": "EC",
          "alg": "ES256",
          "crv": "P-256",
          "x": "IbRSlIytECAdXKn1kO9mAMTQcSzaMF0AAAAA-_wwBxU",
          "y": "jAtuAgVX170AFAb7zOtMzHScDxvGdnngY17vZ8nfpQE"
        }
      }
    },

    "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidlZuWVVhWC1XMVZkcUtCWjdEdE5jcWdjR1MwbUVyNktCQzdmVmE5QkRHYyIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWwucG9ja2V0aWQuYXBwIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
    "clientDataJSONHex": "7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2276566e595561582d57315664714b425a3744744e637167634753306d4572364b4243376656613942444763222c226f726967696e223a2268747470733a2f2f6c6f63616c2e706f636b657469642e617070222c2263726f73734f726967696e223a66616c73657d",
    "clientDataJSONString": "{\"type\":\"webauthn.create\",\"challenge\":\"vVnYUaX-W1VdqKBZ7DtNcqgcGS0mEr6KBC7fVa9BDGc\",\"origin\":\"https://local.pocketid.app\",\"crossOrigin\":false}",
    "clientData": {
      "type": "webauthn.create",
      "challenge": "vVnYUaX-W1VdqKBZ7DtNcqgcGS0mEr6KBC7fVa9BDGc",
      "origin": "https://local.pocketid.app",
      "crossOrigin": false
    },

    "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1spc0MQ70PYbMt6HDnfrlIzixxuzKy9PgOw5VmQJmoevpYPwCK2aQx-7xQiz5CDB0a2NSaQyuHP-WE_6PEwb6A",
    "publicKeyHex": "3059301306072a8648ce3d020106082a8648ce3d03010703420004d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",
    "publicKeyDer": "3059301306072a8648ce3d020106082a8648ce3d03010703420004d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8",

    "publicKeyAlgorithm": -7,
    "publicKeyAlgo": "ES256",
    "publicKeyAlgorithmName": "ES256",

    "transports": [
      "hybrid",
      "internal"
    ]

  },

  "type": "public-key"
}

Passkey (WebAuthn Credential) Authentication (Attestation)

./fixtures/apple-m2-02-credential-request-response.json (fully decoded):

{
  "authenticatorAttachment": "platform",

  "id": "BvvM60zMdJwPG8Z2eeBjXu9nyd8",
  "rawId": "BvvM60zMdJwPG8Z2eeBjXu9nyd8",
  "rawIdHex": "06fbcceb4ccc749c0f1bc67679e0635eef67c9df",

  "response": {

    "authenticatorData": "vyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jAdAAAAAA",
    "authenticatorDataHex": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda301d00000000",
    "authenticator": {
      "rpidHash": "bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda30",
      "isUserPresent": true,
      "userVerified": true,
      "isMultiDeviceCredential": true,
      "isBackedUp": true,
      "hasAttestedCredential": false,
      "hasExtensionData": false,
      "signCount": 0,
      "attestedCredentialData": null,
      "attestedCredential": null
    },

    "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiY0pDM1Bwa3pLOVBQeWFwRDJOQXVlTjBqVmltMUJPLU1iWHh6NDRXMWNUdyIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWwucG9ja2V0aWQuYXBwIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
    "clientDataJSONHex": "7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22634a433350706b7a4b39505079617044324e4175654e306a56696d31424f2d4d6258787a34345731635477222c226f726967696e223a2268747470733a2f2f6c6f63616c2e706f636b657469642e617070222c2263726f73734f726967696e223a66616c73657d",
    "clientDataJSONString": "{\"type\":\"webauthn.get\",\"challenge\":\"cJC3PpkzK9PPyapD2NAueN0jVim1BO-MbXxz44W1cTw\",\"origin\":\"https://local.pocketid.app\",\"crossOrigin\":false}",
    "clientData": {
      "type": "webauthn.get",
      "challenge": "cJC3PpkzK9PPyapD2NAueN0jVim1BO-MbXxz44W1cTw",
      "origin": "https://local.pocketid.app",
      "crossOrigin": false
    },

    "hash": "e2eacf22fcb185ebab56d30ff6c3a48e370b55a5a7bb237cc891c57f4b145f13",

    "signature": "MEQCIEbaFzFqEPDuzy_CqEj4WcTGhIBw10YhHXS9H9RDK7uqAiAHTR4wgpiwITNvfGZCijobw66ovUnzeh2r8mdzl4al-Q",
    "signatureHex": "3044022046da17316a10f0eecf2fc2a848f859c4c6848070d746211d74bd1fd4432bbbaa0220074d1e308298b021336f7c66428a3a1bc3aea8bd49f37a1dabf267739786a5f9"

  },

  "type": "public-key"
}

Code Examples

Registration

'use strict';

let Passkey = require('$/src/lib/passkey.js');
let Bytes = require('$/src/lib/bytes.js');

// ./fixtures/apple-m2-01-credential-creation-response.json
let regResp = {
  authenticatorAttachment: 'platform',
  id: 'BvvM60zMdJwPG8Z2eeBjXu9nyd8',
  rawId: 'BvvM60zMdJwPG8Z2eeBjXu9nyd8',
  rawIdHex: '06fbcceb4ccc749c0f1bc67679e0635eef67c9df',
  response: {
    attestationObject:
      'o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYvyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jBdAAAAAPv8MAcVTk7MjAtuAgVX170AFAb7zOtMzHScDxvGdnngY17vZ8nfpQECAyYgASFYINbKXNDEO9D2GzLehw5365SM4scbsysvT4DsOVZkCZqHIlggr6WD8AitmkMfu8UIs-QgwdGtjUmkMrhz_lhP-jxMG-g',
    attestationObjectHex:
      'a363666d74646e6f6e656761747453746d74a06861757468446174615898bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8',
    authenticatorData:
      'vyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jBdAAAAAPv8MAcVTk7MjAtuAgVX170AFAb7zOtMzHScDxvGdnngY17vZ8nfpQECAyYgASFYINbKXNDEO9D2GzLehw5365SM4scbsysvT4DsOVZkCZqHIlggr6WD8AitmkMfu8UIs-QgwdGtjUmkMrhz_lhP-jxMG-g',
    authenticatorDataHex:
      'bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda305d00000000fbfc3007154e4ecc8c0b6e020557d7bd001406fbcceb4ccc749c0f1bc67679e0635eef67c9dfa5010203262001215820d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87225820afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8',
    clientDataJSON:
      'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidlZuWVVhWC1XMVZkcUtCWjdEdE5jcWdjR1MwbUVyNktCQzdmVmE5QkRHYyIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWwucG9ja2V0aWQuYXBwIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ',
    clientDataJSONHex:
      '7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2276566e595561582d57315664714b425a3744744e637167634753306d4572364b4243376656613942444763222c226f726967696e223a2268747470733a2f2f6c6f63616c2e706f636b657469642e617070222c2263726f73734f726967696e223a66616c73657d',
    publicKey:
      'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1spc0MQ70PYbMt6HDnfrlIzixxuzKy9PgOw5VmQJmoevpYPwCK2aQx-7xQiz5CDB0a2NSaQyuHP-WE_6PEwb6A',
    publicKeyHex:
      '3059301306072a8648ce3d020106082a8648ce3d03010703420004d6ca5cd0c43bd0f61b32de870e77eb948ce2c71bb32b2f4f80ec395664099a87afa583f008ad9a431fbbc508b3e420c1d1ad8d49a432b873fe584ffa3c4c1be8',
    publicKeyAlgorithm: -7,
    publicKeyAlgorithmName: 'ES256',
    transports: ['hybrid', 'internal'],
  },
  type: 'public-key',
};

let resp = Passkey.reg.parse(regResp);
Object.assign(regResp.response, resp);

function bytesToHex(key, val) {
  if (val instanceof Uint8Array) {
    return Bytes.bytesToHex(val);
  }
  return val;
}

let json = JSON.stringify(regResp, bytesToHex, 2);
console.log(json);

Authentication

'use strict';

let Passkey = require('$/src/lib/passkey.js');
let Bytes = require('$/src/lib/bytes.js');

// ./fixtures/apple-m2-02-credential-request-response.json
let authnResp = {
  authenticatorAttachment: 'platform',
  id: 'BvvM60zMdJwPG8Z2eeBjXu9nyd8',
  rawId: 'BvvM60zMdJwPG8Z2eeBjXu9nyd8',
  rawIdHex: '06fbcceb4ccc749c0f1bc67679e0635eef67c9df',
  response: {
    authenticatorData: 'vyNDyj998pf0HSG0UpSMrRAgHVyp9ZDvZgDE0HEs2jAdAAAAAA',
    authenticatorDataHex:
      'bf2343ca3f7df297f41d21b452948cad10201d5ca9f590ef6600c4d0712cda301d00000000',
    clientDataJSON:
      'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiY0pDM1Bwa3pLOVBQeWFwRDJOQXVlTjBqVmltMUJPLU1iWHh6NDRXMWNUdyIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWwucG9ja2V0aWQuYXBwIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ',
    clientDataJSONHex:
      '7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22634a433350706b7a4b39505079617044324e4175654e306a56696d31424f2d4d6258787a34345731635477222c226f726967696e223a2268747470733a2f2f6c6f63616c2e706f636b657469642e617070222c2263726f73734f726967696e223a66616c73657d',
    signature:
      'MEQCIEbaFzFqEPDuzy_CqEj4WcTGhIBw10YhHXS9H9RDK7uqAiAHTR4wgpiwITNvfGZCijobw66ovUnzeh2r8mdzl4al-Q',
    signatureHex:
      '3044022046da17316a10f0eecf2fc2a848f859c4c6848070d746211d74bd1fd4432bbbaa0220074d1e308298b021336f7c66428a3a1bc3aea8bd49f37a1dabf267739786a5f9',
  },
  type: 'public-key',
};

let resp = Passkey.authn.parse(authnResp);
Object.assign(authnResp.response, resp);

function bytesToHex(key, val) {
  if (val instanceof Uint8Array) {
    return Bytes.bytesToHex(val);
  }
  return val;
}

let json = JSON.stringify(authnResp, bytesToHex, 2);
console.log(json);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions