tweag / webauthn

A library for parsing and validating webauthn/fido2 credentials
Apache License 2.0
34 stars 11 forks source link

JSON pretty printing #77

Closed infinisil closed 2 years ago

infinisil commented 2 years ago

This adds pretty and simple (ideally derived) ToJSON instances to all the main types involved, allowing them to be pretty printed using any normal JSON formatter. These instances are then used to pretty-print the responses in the server, to get a result like this for a register, logout, login flow:

Register begin <= {
  "accountDisplayName": "arch",
  "accountName": "arch"
}
Register begin => {
  "pkcocAttestation": "AttestationConveyancePreferenceDirect",
  "pkcocAuthenticatorSelection": {
    "ascAuthenticatorAttachment": null,
    "ascResidentKey": "ResidentKeyRequirementDiscouraged",
    "ascUserVerification": "UserVerificationRequirementPreferred"
  },
  "pkcocChallenge": "6760d46100000000d221d9d26442cfea01f8081e735ed921",
  "pkcocExcludeCredentials": [],
  "pkcocExtensions": null,
  "pkcocPubKeyCredParams": [
    {
      "pkcpAlg": "COSEAlgorithmIdentifierES256",
      "pkcpTyp": "PublicKeyCredentialTypePublicKey"
    }
  ],
  "pkcocRp": {
    "pkcreId": null,
    "pkcreName": "ACME"
  },
  "pkcocTimeout": null,
  "pkcocUser": {
    "pkcueDisplayName": "arch",
    "pkcueId": "0995652597960310871eba805cfdc87f1e450c6feaa38903fe5c6163c191df559d56886de282649e41d8600c5a4e64cff1adc0e10968359e3b8ac4d9bfb856e8",
    "pkcueName": "arch"
  },
  "tag": "PublicKeyCredentialCreationOptions"
}
Register complete <={
  "pkcClientExtensionResults": {},
  "pkcIdentifier": "e5b2252f47d5cd72f32eccdc21dd79bfd4e3c3c0d175c1cc632f30782f6659ca18b032c965d7d38b4c5c7c7892950e7a39f8def39cfa4ea2add04964371882c9",
  "pkcResponse": {
    "arcAttestationObject": {
      "aoAttStmt": {
        "attestnCert": {
          "certExtensions": [
            {
              "extRawContent": "312e332e362e312e342e312e34313438322e312e37",
              "extRawOID": "1.3.6.1.4.1.41482.2"
            },
            {
              "extRawContent": "03020430",
              "extRawOID": "1.3.6.1.4.1.45724.2.1.1"
            },
            {
              "extRawContent": "04102fc0579f811347eab116bb5a8db9202a",
              "extRawOID": "1.3.6.1.4.1.45724.1.1.4"
            },
            {
              "extRawContent": "3000",
              "extRawOID": "2.5.29.19"
            }
          ],
          "certIssuerDN": {
            "DnCommonName": "Yubico U2F Root CA Serial 457200631"
          },
          "certSubjectDN": {
            "DnCommonName": "Yubico U2F EE Serial 512722740",
            "DnCountry": "SE",
            "DnOrganization": "Yubico AB",
            "DnOrganizationUnit": "Authenticator Attestation"
          },
          "certValidity": {
            "notAfter": "2050-09-04T00:00:00Z",
            "notBefore": "2014-08-01T00:00:00Z"
          }
        },
        "sig": "304602210097cbcaecb3ddf0657e9da9b4a0353d2170a06249c01c02c175f2303ddf24b54f022100927eca7a9ae062c2f7856bbc0e2b979ae3d57c4bd9c55d4cb0c7e37031ad6060"
      },
      "aoAuthData": {
        "adAttestedCredentialData": {
          "acdAaguid": "00000000-0000-0000-0000-000000000000",
          "acdCredentialId": "e5b2252f47d5cd72f32eccdc21dd79bfd4e3c3c0d175c1cc632f30782f6659ca18b032c965d7d38b4c5c7c7892950e7a39f8def39cfa4ea2add04964371882c9",
          "acdCredentialPublicKey": {
            "coseAlgorithmIdentifier": "COSEAlgorithmIdentifierES256",
            "key": {
              "keyType": "ECDSA",
              "x": "16825960575963806594879147400698846275905619332925501351590675870286023267995",
              "y": "305976574137243527472852874105170366199103807132923349232184059822804880705"
            }
          },
          "acdCredentialPublicKeyBytes": "<none>"
        },
        "adExtensions": null,
        "adFlags": {
          "adfUserPresent": true,
          "adfUserVerified": false
        },
        "adRawData": "<none>",
        "adRpIdHash": "7cdb803f9d5988898c4bbad5d1b887ee160def0dbc71aa45bec708459e51f47c",
        "adSignCount": 0.0
      },
      "aoFmt": "fido-u2f"
    },
    "arcClientData": {
      "ccdChallenge": "6760d46100000000d221d9d26442cfea01f8081e735ed921",
      "ccdCrossOrigin": false,
      "ccdOrigin": "https://infinisil.webauthn.dev.tweag.io",
      "ccdRawData": "<none>",
      "webauthnKind": "Create"
    }
  }
}
Register complete result: {
  "rAttestationStatement": {
    "asModel": {
      "tag": "verified",
      "vaIdentifier": {
        "idSubjectKeyIdentifier": "9be8c86f3b7da9f5026a56607b2b93f0ffd058ae",
        "tag": "AuthenticatorIdentifierFidoU2F"
      },
      "vaMetadata": {
        "meMetadataStatement": {
          "msAlternativeDescriptions": null,
          "msAttachmentHint": [
            "external",
            "wired",
            "wireless",
            "nfc"
          ],
          "msAttestationRootCertificates": [
            {
              "certExtensions": [
                {
                  "extRawContent": "04142022fcf46cd1898638294e892cc8aa4ff71bfda0",
                  "extRawOID": "2.5.29.14"
                },
                {
                  "extRawContent": "30060101ff020100",
                  "extRawOID": "2.5.29.19"
                },
                {
                  "extRawContent": "03020106",
                  "extRawOID": "2.5.29.15"
                }
              ],
              "certIssuerDN": {
                "DnCommonName": "Yubico U2F Root CA Serial 457200631"
              },
              "certSubjectDN": {
                "DnCommonName": "Yubico U2F Root CA Serial 457200631"
              },
              "certValidity": {
                "notAfter": "2050-09-04T00:00:00Z",
                "notBefore": "2014-08-01T00:00:00Z"
              }
            }
          ],
          "msAttestationTypes": [
            "WebauthnAttestationBasic"
          ],
          "msAuthenticationAlgorithms": [
            "secp256r1_ecdsa_sha256_raw"
          ],
          "msAuthenticatorGetInfo": null,
          "msAuthenticatorVersion": 2.0,
          "msCryptoStrength": 128.0,
          "msDescription": "YubiKey 5 Series with NFC",
          "msIcon": "89504e470d0a1a0a0000000d49484452000000200000001f08060000008656cf8c000000017352474200aece1ce90000000467414d410000b18f0bfc6105000000097048597300001d8600001d86015da21381000006cd494441545847a5577b4cd575143ff7779f70790488812f404005dc14b010662f5fa5e573d6d63f59366be56c6973b5b99272dae6323767ce6cad2da7336b23b56c194bb2141f81f8c429c4431e0301917be15eeeb3cf39bfdfe522706f549fc1e0fbfd9eeff99eeff99ef339e7a7f303f42fd076ff22b5f754528fa38e5c9e6e229d42166302c546665052ec23146fcdd62447875119d0d45546e76ab7505dfb69d22b24bf3a1cacd3e964ddeff7910f6abc3e1952d6b8555494b98d1e8a9ca24e101fa1ca0e455803baec37a8a46201ddeb6dc12d8d38d82287fa59a1ec0a6cd53d608cc7e72087cb4ba9630a68c5ac5232eaa3646d248434a0ece67aba50bb87ac660b0e3641b11fb77491dbd34f5eece0e314ed523c6618e019a33e02af6210dbbc3e27f5b9dcf4eccc2f2967fc1a5568084634e0f0b959d4da5d815b47cbcdbcbe7edca81f6f9c4d3326bd45a9898b29da32519356d165afa6daf6efa9aa7117e2e32e451823498121acdeeeb4515eea5a9a97b35f930e62980187ca73e96e4f15998d31b2d9e9b6514254262dcd3b8137cdd0a4c2e34ed7af74fcd252727b7bc9a48f1677f5f5db2837e5759a9bbd4f935201a705517a7d0da23c78385b5e94594c2fcdb935eac31913e3e7d29bf3ec949eb80c9eb3c95ca4299a2aea3fa7ea96af651cc080075abbcfd1813385702d2c06ecb07869ee219a9afca28cff2bcaaad75165fd5e8a30c7202e7cd06ba78dcf38115766591ff0c0d18aa729ca8c00c29bb3db1f9f5afcff0ed75ef6c9accf282d711e82d706ddcc197a3a5ab958d618e2819ab6124cae44c4c748c04521c056cfb9ad89103576fe4207cf2ec43a817c889ecade41f9a99bb4551587cbf3a9f57e250e918bd286450fc6f6ee933a32e8ad6284cd61a375f35ba12f49f5c0f9da6258669677e7685f32f3986c0a6052c202c44094f04084c94215753bb415153ebf078157091d6abe174d2996bf8331376b3f8cefc58d7590d321c53f927931a0f9de15e4b4098adc94189341f15159b2381805933f208fd7093923d2ac833a9176015435ec2223529fc39d3d5490be45e60763fac4b5c20d60137822826eb47c25f34a73d76f200f6c85eff880e9135e9385a1c84bdb24ca1966304e45ddc7ea00a86ad82d04e4f1f581869768b3c39191b41c324e9ca587a79d48d33e523aec7c7b5580b99cdd1d0ad3929f139a35e823e95ad30199b33b9ba9b3b789f43a03f5bbbd5498b15de647424ac2429ce161e2064991f08dc20a023cee838be2acd3e4ff9150905e8c43a000f2bc8583f36ad33e7884e9d883bdc934267aba263d1c71d6ac4072c8a57bfb9b49e11b7164066040a085c2d8d87c8a8e88231f6e613298e952fd4eba0962e1e876791c343b7d9b263932b8280dce0d2fce560c4a24acd2ea28e0c1bb84c3a3084697d72144d274af8c1cee4e71292bce99f08a2a14022e6f0f2483d02b11a444592648fa31f85dba7a83d13d127253de8691cc337e3142414031e7e7a6bca1498406eb0ec41b3f379fad2446cf9001438fc506bceb3f216bdc4a0946061bd2eff15361fa5619874363c7cf031592037e6c4c2e29e3e2e6e006aa2283de42d7ee7cae89874661c656ec5173929973627c3e594c09320e87db6dc725c6703c58d02ac426d13729215f1429683c3aedf5d461bb221b42a1b6fda8788be1f2b85031839c100a971bf788fb39e039ce72c6bf2af3620033573f14b14ea65aaee5e1505eb319cc67150a361b2d61b9238053d5eb91ae56f1b4d3ad322b430c484b5c82329c002fb8e1161375f735d01fb7de1581a1b8d97210b74657e8f78213fa9015ef6b2ba1f1ed8539d0abc7edf5b87d2faaeca281271b208015f9a520068758c8ad5879cd0eb0dd17da6a10579bf6826c26538c2505513c9666a5bda7ad8c8c93d756a3ab3e030ee0dbfbe0691ffa8c1fb4d5410d09e3149a874b0d7ba57be1596e4a66a7bf438f4dfd4493080556a105c52070475d77b714fad40ecb860e6b45fe11ca4c7a5e93186200e3c8f9226ae92e8717823d616ce40494e8e3a8943335a9f0f8abfd189db8bc4a62c4a4b15f2f2e5390be1197d98951d0e0610630bebbf80472f6340292bb624e353718cf4909d61474c5eba52b8e07af07c0aee5afa5daf61244fb6e543a3bde185d3121e7517eed4e3b15646c4097f5a9b62388110d609cbdbd997ebfb51d6d9a59188fc5b85fe0928d67140c66353694bf0bb8522aa88c2ccfe5d90992599ef70ddcfe822a3c04210d60f438eaa9e4cf05d46eabc19318d442c59f64581bba8deb01ffb037b8ce3bdd3eca7c783e2dcbfb49d82f549c84352000fe203d5ffb21dd6afb51d2866b86908a9644f832c4c16a3fc1df8d39e35f06396d07db25cb7a388cca80c1e8b45fc77b57a0b1ac474aa1bac1f766439c7c3724c516a05ca76892a301d1df2939fb7ea117bbd70000000049454e44ae426082",
          "msIsFreshUserVerificationRequired": null,
          "msIsKeyRestricted": null,
          "msKeyProtection": [
            "hardware",
            "secure_element",
            "remote_handle"
          ],
          "msLegalHeader": "https://fidoalliance.org/metadata/metadata-statement-legal-header/",
          "msMatcherProtection": [
            "on_chip"
          ],
          "msPublicKeyAlgAndEncodings": [
            "ecc_x962_raw"
          ],
          "msSupportedExtensions": null,
          "msTcDisplay": [],
          "msTcDisplayContentType": null,
          "msTcDisplayPNGCharacteristics": null,
          "msUpv": [
            "U2F 1.1"
          ],
          "msUserVerificationDetails": [
            [
              {
                "userVerificationMethod": "presence_internal"
              }
            ]
          ]
        },
        "meStatusReports": [
          {
            "srAuthenticatorVersion": null,
            "srCertificate": null,
            "srCertificateNumber": "U2F110020191017006",
            "srCertificationDescriptor": "YubiKey 5 NFC",
            "srCertificationPolicyVersion": "1.1.1",
            "srCertificationRequirementsVersion": "1.3",
            "srEffectiveDate": "2020-05-12",
            "srStatus": "FIDO_CERTIFIED_L1",
            "srUrl": null
          }
        ],
        "meTimeOfLastStatusChange": "2020-05-12"
      }
    },
    "asType": {
      "atvChain": [
        {
          "certExtensions": [
            {
              "extRawContent": "312e332e362e312e342e312e34313438322e312e37",
              "extRawOID": "1.3.6.1.4.1.41482.2"
            },
            {
              "extRawContent": "03020430",
              "extRawOID": "1.3.6.1.4.1.45724.2.1.1"
            },
            {
              "extRawContent": "04102fc0579f811347eab116bb5a8db9202a",
              "extRawOID": "1.3.6.1.4.1.45724.1.1.4"
            },
            {
              "extRawContent": "3000",
              "extRawOID": "2.5.29.19"
            }
          ],
          "certIssuerDN": {
            "DnCommonName": "Yubico U2F Root CA Serial 457200631"
          },
          "certSubjectDN": {
            "DnCommonName": "Yubico U2F EE Serial 512722740",
            "DnCountry": "SE",
            "DnOrganization": "Yubico AB",
            "DnOrganizationUnit": "Authenticator Attestation"
          },
          "certValidity": {
            "notAfter": "2050-09-04T00:00:00Z",
            "notBefore": "2014-08-01T00:00:00Z"
          }
        }
      ],
      "atvType": "VerifiableAttestationTypeBasic",
      "tag": "AttestationTypeVerifiable"
    }
  },
  "rEntry": {
    "ceCredentialId": "e5b2252f47d5cd72f32eccdc21dd79bfd4e3c3c0d175c1cc632f30782f6659ca18b032c965d7d38b4c5c7c7892950e7a39f8def39cfa4ea2add04964371882c9",
    "cePublicKeyBytes": "a5010203262001215820253327fc988c4262a7cedc2a35f9f9f02b8345634de260658e3e89f11b80969b22582000ad2d35e855efe024406f924500efd5d07000c8d4d0fa77af4356101174cd41",
    "ceSignCounter": 0.0,
    "ceUserHandle": "0995652597960310871eba805cfdc87f1e450c6feaa38903fe5c6163c191df559d56886de282649e41d8600c5a4e64cff1adc0e10968359e3b8ac4d9bfb856e8"
  }
}
Register complete => "success"
Logging out user: UserAccountName {unUserAccountName = "arch"}
Login begin <= "arch"
Login begin => {
  "pkcogAllowCredentials": [
    {
      "pkcdId": "e5b2252f47d5cd72f32eccdc21dd79bfd4e3c3c0d175c1cc632f30782f6659ca18b032c965d7d38b4c5c7c7892950e7a39f8def39cfa4ea2add04964371882c9",
      "pkcdTransports": null,
      "pkcdTyp": "PublicKeyCredentialTypePublicKey"
    }
  ],
  "pkcogChallenge": "d160d46100000000865f9cd9c458f4121295de0bd5d4faa7",
  "pkcogExtensions": null,
  "pkcogRpId": null,
  "pkcogTimeout": null,
  "pkcogUserVerification": "UserVerificationRequirementPreferred",
  "tag": "PublicKeyCredentialRequestOptions"
}
Login complete <= {
  "pkcClientExtensionResults": {},
  "pkcIdentifier": "e5b2252f47d5cd72f32eccdc21dd79bfd4e3c3c0d175c1cc632f30782f6659ca18b032c965d7d38b4c5c7c7892950e7a39f8def39cfa4ea2add04964371882c9",
  "pkcResponse": {
    "argAuthenticatorData": {
      "adAttestedCredentialData": null,
      "adExtensions": null,
      "adFlags": {
        "adfUserPresent": true,
        "adfUserVerified": false
      },
      "adRawData": "<none>",
      "adRpIdHash": "7cdb803f9d5988898c4bbad5d1b887ee160def0dbc71aa45bec708459e51f47c",
      "adSignCount": 2.0
    },
    "argClientData": {
      "ccdChallenge": "d160d46100000000865f9cd9c458f4121295de0bd5d4faa7",
      "ccdCrossOrigin": false,
      "ccdOrigin": "https://infinisil.webauthn.dev.tweag.io",
      "ccdRawData": "<none>",
      "webauthnKind": "Get"
    },
    "argSignature": "3046022100d7649b799e7246cbe47138445285a1157707a7a731d9a2c208d6cfdd03e95301022100d2537d05f713610a2898dbd71a1c9dc141b256d903d292f938a7f8bb4d38a5a8",
    "argUserHandle": null
  }
}
Login complete => "success"
infinisil commented 2 years ago

Other approaches were also considered for pretty-printing these structures: