@simplewebauthn/server 7.4.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +11 -14
- package/README.md +20 -7
- package/{dist → esm}/authentication/generateAuthenticationOptions.d.ts +2 -2
- package/esm/authentication/generateAuthenticationOptions.js +36 -0
- package/{dist → esm}/authentication/verifyAuthenticationResponse.d.ts +2 -2
- package/esm/authentication/verifyAuthenticationResponse.js +164 -0
- package/esm/deps.d.ts +11 -0
- package/esm/deps.js +14 -0
- package/esm/helpers/convertAAGUIDToString.js +17 -0
- package/esm/helpers/convertCOSEtoPKCS.js +21 -0
- package/{dist → esm}/helpers/convertCertBufferToPEM.d.ts +1 -1
- package/esm/helpers/convertCertBufferToPEM.js +31 -0
- package/esm/helpers/convertPEMToBytes.js +11 -0
- package/{dist → esm}/helpers/convertX509PublicKeyToCOSE.d.ts +1 -1
- package/esm/helpers/convertX509PublicKeyToCOSE.js +70 -0
- package/{dist → esm}/helpers/cose.d.ts +2 -1
- package/esm/helpers/cose.js +81 -0
- package/{dist → esm}/helpers/decodeAttestationObject.d.ts +3 -0
- package/esm/helpers/decodeAttestationObject.js +13 -0
- package/esm/helpers/decodeAuthenticatorExtensions.js +34 -0
- package/{dist → esm}/helpers/decodeClientDataJSON.d.ts +3 -0
- package/esm/helpers/decodeClientDataJSON.js +13 -0
- package/esm/helpers/decodeCredentialPublicKey.d.ts +5 -0
- package/esm/helpers/decodeCredentialPublicKey.js +8 -0
- package/esm/helpers/fetch.d.ts +8 -0
- package/esm/helpers/fetch.js +12 -0
- package/esm/helpers/generateChallenge.d.ts +7 -0
- package/esm/helpers/generateChallenge.js +21 -0
- package/{dist → esm}/helpers/getCertificateInfo.d.ts +1 -1
- package/esm/helpers/getCertificateInfo.js +76 -0
- package/esm/helpers/index.d.ts +22 -0
- package/esm/helpers/index.js +16 -0
- package/{dist → esm}/helpers/isCertRevoked.d.ts +1 -1
- package/esm/helpers/isCertRevoked.js +98 -0
- package/{dist → esm}/helpers/iso/index.d.ts +4 -4
- package/esm/helpers/iso/index.js +11 -0
- package/esm/helpers/iso/isoBase64URL.js +57 -0
- package/{dist → esm}/helpers/iso/isoCBOR.d.ts +1 -1
- package/esm/helpers/iso/isoCBOR.js +44 -0
- package/{dist → esm}/helpers/iso/isoCrypto/digest.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/digest.js +14 -0
- package/{dist → esm}/helpers/iso/isoCrypto/getRandomValues.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/getRandomValues.js +11 -0
- package/esm/helpers/iso/isoCrypto/getWebCrypto.d.ts +6 -0
- package/esm/helpers/iso/isoCrypto/getWebCrypto.js +40 -0
- package/esm/helpers/iso/isoCrypto/importKey.js +8 -0
- package/esm/helpers/iso/isoCrypto/index.d.ts +3 -0
- package/esm/helpers/iso/isoCrypto/index.js +3 -0
- package/{dist → esm}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.d.ts +2 -2
- package/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js +20 -0
- package/{dist → esm}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.d.ts +2 -2
- package/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js +19 -0
- package/esm/helpers/iso/isoCrypto/structs.js +1 -0
- package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js +30 -0
- package/{dist → esm}/helpers/iso/isoCrypto/verify.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/verify.js +28 -0
- package/{dist → esm}/helpers/iso/isoCrypto/verifyEC2.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/verifyEC2.js +73 -0
- package/{dist → esm}/helpers/iso/isoCrypto/verifyOKP.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/verifyOKP.js +51 -0
- package/{dist → esm}/helpers/iso/isoCrypto/verifyRSA.d.ts +1 -1
- package/esm/helpers/iso/isoCrypto/verifyRSA.js +91 -0
- package/esm/helpers/iso/isoUint8Array.js +75 -0
- package/{dist → esm}/helpers/logging.d.ts +1 -1
- package/esm/helpers/logging.js +19 -0
- package/{dist → esm}/helpers/mapX509SignatureAlgToCOSEAlg.d.ts +1 -1
- package/esm/helpers/mapX509SignatureAlgToCOSEAlg.js +35 -0
- package/esm/helpers/matchExpectedRPID.js +41 -0
- package/{dist → esm}/helpers/parseAuthenticatorData.d.ts +4 -1
- package/esm/helpers/parseAuthenticatorData.js +71 -0
- package/{dist → esm}/helpers/parseBackupFlags.d.ts +4 -1
- package/esm/helpers/parseBackupFlags.js +25 -0
- package/{dist → esm}/helpers/toHash.d.ts +1 -1
- package/esm/helpers/toHash.js +12 -0
- package/esm/helpers/validateCertificatePath.js +122 -0
- package/{dist → esm}/helpers/verifySignature.d.ts +4 -1
- package/esm/helpers/verifySignature.js +32 -0
- package/esm/index.d.ts +17 -0
- package/esm/index.js +11 -0
- package/{dist → esm}/metadata/mdsTypes.d.ts +1 -1
- package/esm/metadata/mdsTypes.js +17 -0
- package/esm/metadata/parseJWT.js +12 -0
- package/{dist → esm}/metadata/verifyAttestationWithMetadata.d.ts +3 -3
- package/esm/metadata/verifyAttestationWithMetadata.js +159 -0
- package/esm/metadata/verifyJWT.js +37 -0
- package/esm/package.json +3 -0
- package/{dist → esm}/registration/generateRegistrationOptions.d.ts +2 -2
- package/esm/registration/generateRegistrationOptions.js +142 -0
- package/esm/registration/verifications/tpm/constants.js +182 -0
- package/esm/registration/verifications/tpm/parseCertInfo.js +58 -0
- package/esm/registration/verifications/tpm/parsePubArea.js +94 -0
- package/{dist → esm}/registration/verifications/tpm/verifyAttestationTPM.d.ts +1 -1
- package/esm/registration/verifications/tpm/verifyAttestationTPM.js +323 -0
- package/{dist → esm}/registration/verifications/verifyAttestationAndroidKey.d.ts +1 -1
- package/esm/registration/verifications/verifyAttestationAndroidKey.js +90 -0
- package/{dist → esm}/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts +1 -1
- package/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js +112 -0
- package/{dist → esm}/registration/verifications/verifyAttestationApple.d.ts +1 -1
- package/esm/registration/verifications/verifyAttestationApple.js +57 -0
- package/{dist → esm}/registration/verifications/verifyAttestationFIDOU2F.d.ts +1 -1
- package/esm/registration/verifications/verifyAttestationFIDOU2F.js +48 -0
- package/{dist → esm}/registration/verifications/verifyAttestationPacked.d.ts +1 -1
- package/esm/registration/verifications/verifyAttestationPacked.js +105 -0
- package/{dist → esm}/registration/verifyRegistrationResponse.d.ts +3 -3
- package/esm/registration/verifyRegistrationResponse.js +198 -0
- package/esm/services/defaultRootCerts/android-key.js +85 -0
- package/esm/services/defaultRootCerts/android-safetynet.js +32 -0
- package/esm/services/defaultRootCerts/apple.js +25 -0
- package/esm/services/defaultRootCerts/mds.js +32 -0
- package/{dist → esm}/services/metadataService.d.ts +1 -1
- package/{dist → esm}/services/metadataService.js +52 -36
- package/{dist → esm}/services/settingsService.d.ts +1 -1
- package/esm/services/settingsService.js +65 -0
- package/package.json +40 -42
- package/script/authentication/generateAuthenticationOptions.d.ts +23 -0
- package/{dist → script}/authentication/generateAuthenticationOptions.js +8 -9
- package/script/authentication/verifyAuthenticationResponse.d.ts +66 -0
- package/{dist → script}/authentication/verifyAuthenticationResponse.js +25 -23
- package/script/deps.d.ts +11 -0
- package/script/deps.js +71 -0
- package/script/helpers/convertAAGUIDToString.d.ts +4 -0
- package/{dist → script}/helpers/convertAAGUIDToString.js +2 -3
- package/script/helpers/convertCOSEtoPKCS.d.ts +4 -0
- package/{dist → script}/helpers/convertCOSEtoPKCS.js +7 -8
- package/script/helpers/convertCertBufferToPEM.d.ts +5 -0
- package/{dist → script}/helpers/convertCertBufferToPEM.js +5 -6
- package/script/helpers/convertPEMToBytes.d.ts +4 -0
- package/{dist → script}/helpers/convertPEMToBytes.js +2 -3
- package/script/helpers/convertX509PublicKeyToCOSE.d.ts +2 -0
- package/{dist → script}/helpers/convertX509PublicKeyToCOSE.js +21 -25
- package/script/helpers/cose.d.ts +98 -0
- package/{dist → script}/helpers/cose.js +1 -1
- package/script/helpers/decodeAttestationObject.d.ts +29 -0
- package/script/helpers/decodeAttestationObject.js +17 -0
- package/script/helpers/decodeAuthenticatorExtensions.d.ts +20 -0
- package/{dist → script}/helpers/decodeAuthenticatorExtensions.js +2 -3
- package/script/helpers/decodeClientDataJSON.d.ts +17 -0
- package/script/helpers/decodeClientDataJSON.js +17 -0
- package/script/helpers/decodeCredentialPublicKey.d.ts +5 -0
- package/script/helpers/decodeCredentialPublicKey.js +12 -0
- package/script/helpers/fetch.d.ts +8 -0
- package/script/helpers/fetch.js +16 -0
- package/script/helpers/generateChallenge.d.ts +7 -0
- package/{dist → script}/helpers/generateChallenge.js +9 -6
- package/script/helpers/getCertificateInfo.d.ts +31 -0
- package/{dist → script}/helpers/getCertificateInfo.js +4 -6
- package/script/helpers/index.d.ts +22 -0
- package/script/helpers/index.js +59 -0
- package/script/helpers/isCertRevoked.d.ts +8 -0
- package/{dist → script}/helpers/isCertRevoked.js +20 -25
- package/script/helpers/iso/index.d.ts +11 -0
- package/{dist → script}/helpers/iso/index.js +4 -5
- package/script/helpers/iso/isoBase64URL.d.ts +37 -0
- package/{dist → script}/helpers/iso/isoBase64URL.js +9 -13
- package/script/helpers/iso/isoCBOR.d.ts +12 -0
- package/{dist → script}/helpers/iso/isoCBOR.js +8 -28
- package/script/helpers/iso/isoCrypto/digest.d.ts +8 -0
- package/script/helpers/iso/isoCrypto/digest.js +18 -0
- package/script/helpers/iso/isoCrypto/getRandomValues.d.ts +6 -0
- package/script/helpers/iso/isoCrypto/getRandomValues.js +15 -0
- package/script/helpers/iso/isoCrypto/getWebCrypto.d.ts +6 -0
- package/script/helpers/iso/isoCrypto/getWebCrypto.js +44 -0
- package/script/helpers/iso/isoCrypto/importKey.d.ts +4 -0
- package/script/helpers/iso/isoCrypto/importKey.js +12 -0
- package/script/helpers/iso/isoCrypto/index.d.ts +3 -0
- package/{dist → script}/helpers/iso/isoCrypto/index.js +6 -7
- package/script/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.d.ts +6 -0
- package/{dist → script}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js +6 -6
- package/script/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.d.ts +6 -0
- package/{dist → script}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js +5 -6
- package/script/helpers/iso/isoCrypto/structs.d.ts +3 -0
- package/{dist → script}/helpers/iso/isoCrypto/structs.js +0 -1
- package/script/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +6 -0
- package/{dist → script}/helpers/iso/isoCrypto/unwrapEC2Signature.js +4 -6
- package/script/helpers/iso/isoCrypto/verify.d.ts +10 -0
- package/script/helpers/iso/isoCrypto/verify.js +32 -0
- package/script/helpers/iso/isoCrypto/verifyEC2.d.ts +10 -0
- package/{dist → script}/helpers/iso/isoCrypto/verifyEC2.js +19 -22
- package/script/helpers/iso/isoCrypto/verifyOKP.d.ts +6 -0
- package/{dist → script}/helpers/iso/isoCrypto/verifyOKP.js +13 -16
- package/script/helpers/iso/isoCrypto/verifyRSA.d.ts +10 -0
- package/{dist → script}/helpers/iso/isoCrypto/verifyRSA.js +19 -22
- package/script/helpers/iso/isoUint8Array.d.ts +36 -0
- package/{dist → script}/helpers/iso/isoUint8Array.js +7 -8
- package/script/helpers/logging.d.ts +17 -0
- package/{dist → script}/helpers/logging.js +2 -6
- package/script/helpers/mapX509SignatureAlgToCOSEAlg.d.ts +8 -0
- package/{dist → script}/helpers/mapX509SignatureAlgToCOSEAlg.js +8 -9
- package/script/helpers/matchExpectedRPID.d.ts +7 -0
- package/{dist → script}/helpers/matchExpectedRPID.js +5 -6
- package/script/helpers/parseAuthenticatorData.d.ts +28 -0
- package/{dist → script}/helpers/parseAuthenticatorData.js +19 -16
- package/script/helpers/parseBackupFlags.d.ts +19 -0
- package/{dist → script}/helpers/parseBackupFlags.js +2 -2
- package/script/helpers/toHash.d.ts +6 -0
- package/{dist → script}/helpers/toHash.js +4 -5
- package/script/helpers/validateCertificatePath.d.ts +6 -0
- package/{dist → script}/helpers/validateCertificatePath.js +13 -15
- package/script/helpers/verifySignature.d.ts +14 -0
- package/script/helpers/verifySignature.js +36 -0
- package/script/index.d.ts +17 -0
- package/script/index.js +19 -0
- package/script/metadata/mdsTypes.d.ts +216 -0
- package/{dist → script}/metadata/mdsTypes.js +0 -1
- package/script/metadata/parseJWT.d.ts +4 -0
- package/{dist → script}/metadata/parseJWT.js +3 -4
- package/script/metadata/verifyAttestationWithMetadata.d.ts +29 -0
- package/{dist → script}/metadata/verifyAttestationWithMetadata.js +24 -22
- package/script/metadata/verifyJWT.d.ts +10 -0
- package/script/metadata/verifyJWT.js +41 -0
- package/script/package.json +3 -0
- package/script/registration/generateRegistrationOptions.d.ts +43 -0
- package/{dist → script}/registration/generateRegistrationOptions.js +9 -10
- package/script/registration/verifications/tpm/constants.d.ts +47 -0
- package/{dist → script}/registration/verifications/tpm/constants.js +1 -2
- package/script/registration/verifications/tpm/parseCertInfo.d.ts +24 -0
- package/{dist → script}/registration/verifications/tpm/parseCertInfo.js +13 -14
- package/script/registration/verifications/tpm/parsePubArea.d.ts +43 -0
- package/{dist → script}/registration/verifications/tpm/parsePubArea.js +16 -17
- package/script/registration/verifications/tpm/verifyAttestationTPM.d.ts +2 -0
- package/{dist → script}/registration/verifications/tpm/verifyAttestationTPM.js +58 -58
- package/script/registration/verifications/verifyAttestationAndroidKey.d.ts +5 -0
- package/{dist → script}/registration/verifications/verifyAttestationAndroidKey.js +22 -26
- package/script/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts +5 -0
- package/{dist → script}/registration/verifications/verifyAttestationAndroidSafetyNet.js +22 -23
- package/script/registration/verifications/verifyAttestationApple.d.ts +2 -0
- package/{dist → script}/registration/verifications/verifyAttestationApple.js +15 -17
- package/script/registration/verifications/verifyAttestationFIDOU2F.d.ts +5 -0
- package/{dist → script}/registration/verifications/verifyAttestationFIDOU2F.js +12 -13
- package/script/registration/verifications/verifyAttestationPacked.d.ts +5 -0
- package/{dist → script}/registration/verifications/verifyAttestationPacked.js +17 -18
- package/script/registration/verifyRegistrationResponse.d.ts +85 -0
- package/{dist → script}/registration/verifyRegistrationResponse.js +39 -38
- package/script/services/defaultRootCerts/android-key.d.ts +24 -0
- package/{dist → script}/services/defaultRootCerts/android-key.js +0 -1
- package/script/services/defaultRootCerts/android-safetynet.d.ts +11 -0
- package/{dist → script}/services/defaultRootCerts/android-safetynet.js +0 -1
- package/script/services/defaultRootCerts/apple.d.ts +11 -0
- package/{dist → script}/services/defaultRootCerts/apple.js +0 -1
- package/script/services/defaultRootCerts/mds.d.ts +11 -0
- package/{dist → script}/services/defaultRootCerts/mds.js +0 -1
- package/script/services/metadataService.d.ts +53 -0
- package/script/services/metadataService.js +277 -0
- package/script/services/settingsService.d.ts +25 -0
- package/{dist → script}/services/settingsService.js +21 -13
- package/dist/authentication/generateAuthenticationOptions.js.map +0 -1
- package/dist/authentication/verifyAuthenticationResponse.js.map +0 -1
- package/dist/helpers/convertAAGUIDToString.js.map +0 -1
- package/dist/helpers/convertCOSEtoPKCS.js.map +0 -1
- package/dist/helpers/convertCertBufferToPEM.js.map +0 -1
- package/dist/helpers/convertPEMToBytes.js.map +0 -1
- package/dist/helpers/convertX509PublicKeyToCOSE.js.map +0 -1
- package/dist/helpers/cose.js.map +0 -1
- package/dist/helpers/decodeAttestationObject.js +0 -14
- package/dist/helpers/decodeAttestationObject.js.map +0 -1
- package/dist/helpers/decodeAuthenticatorExtensions.js.map +0 -1
- package/dist/helpers/decodeClientDataJSON.js +0 -14
- package/dist/helpers/decodeClientDataJSON.js.map +0 -1
- package/dist/helpers/decodeCredentialPublicKey.d.ts +0 -2
- package/dist/helpers/decodeCredentialPublicKey.js +0 -9
- package/dist/helpers/decodeCredentialPublicKey.js.map +0 -1
- package/dist/helpers/generateChallenge.d.ts +0 -4
- package/dist/helpers/generateChallenge.js.map +0 -1
- package/dist/helpers/getCertificateInfo.js.map +0 -1
- package/dist/helpers/index.d.ts +0 -22
- package/dist/helpers/index.js +0 -60
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/isCertRevoked.js.map +0 -1
- package/dist/helpers/iso/index.js.map +0 -1
- package/dist/helpers/iso/isoBase64URL.js.map +0 -1
- package/dist/helpers/iso/isoCBOR.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/digest.js +0 -21
- package/dist/helpers/iso/isoCrypto/digest.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/getRandomValues.js +0 -18
- package/dist/helpers/iso/isoCrypto/getRandomValues.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/importKey.js +0 -13
- package/dist/helpers/iso/isoCrypto/importKey.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/index.d.ts +0 -3
- package/dist/helpers/iso/isoCrypto/index.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/structs.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/unwrapEC2Signature.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/verify.js +0 -28
- package/dist/helpers/iso/isoCrypto/verify.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/verifyEC2.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/verifyOKP.js.map +0 -1
- package/dist/helpers/iso/isoCrypto/verifyRSA.js.map +0 -1
- package/dist/helpers/iso/isoUint8Array.js.map +0 -1
- package/dist/helpers/logging.js.map +0 -1
- package/dist/helpers/mapX509SignatureAlgToCOSEAlg.js.map +0 -1
- package/dist/helpers/matchExpectedRPID.js.map +0 -1
- package/dist/helpers/parseAuthenticatorData.js.map +0 -1
- package/dist/helpers/parseBackupFlags.js.map +0 -1
- package/dist/helpers/toHash.js.map +0 -1
- package/dist/helpers/validateCertificatePath.js.map +0 -1
- package/dist/helpers/verifySignature.js +0 -33
- package/dist/helpers/verifySignature.js.map +0 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.js +0 -20
- package/dist/index.js.map +0 -1
- package/dist/metadata/mdsTypes.js.map +0 -1
- package/dist/metadata/parseJWT.js.map +0 -1
- package/dist/metadata/verifyAttestationWithMetadata.js.map +0 -1
- package/dist/metadata/verifyJWT.js +0 -42
- package/dist/metadata/verifyJWT.js.map +0 -1
- package/dist/registration/generateRegistrationOptions.js.map +0 -1
- package/dist/registration/verifications/tpm/constants.js.map +0 -1
- package/dist/registration/verifications/tpm/parseCertInfo.js.map +0 -1
- package/dist/registration/verifications/tpm/parsePubArea.js.map +0 -1
- package/dist/registration/verifications/tpm/verifyAttestationTPM.js.map +0 -1
- package/dist/registration/verifications/verifyAttestationAndroidKey.js.map +0 -1
- package/dist/registration/verifications/verifyAttestationAndroidSafetyNet.js.map +0 -1
- package/dist/registration/verifications/verifyAttestationApple.js.map +0 -1
- package/dist/registration/verifications/verifyAttestationFIDOU2F.js.map +0 -1
- package/dist/registration/verifications/verifyAttestationPacked.js.map +0 -1
- package/dist/registration/verifyRegistrationResponse.js.map +0 -1
- package/dist/services/defaultRootCerts/android-key.js.map +0 -1
- package/dist/services/defaultRootCerts/android-safetynet.js.map +0 -1
- package/dist/services/defaultRootCerts/apple.js.map +0 -1
- package/dist/services/defaultRootCerts/mds.js.map +0 -1
- package/dist/services/metadataService.js.map +0 -1
- package/dist/services/settingsService.js.map +0 -1
- /package/{dist → esm}/helpers/convertAAGUIDToString.d.ts +0 -0
- /package/{dist → esm}/helpers/convertCOSEtoPKCS.d.ts +0 -0
- /package/{dist → esm}/helpers/convertPEMToBytes.d.ts +0 -0
- /package/{dist → esm}/helpers/decodeAuthenticatorExtensions.d.ts +0 -0
- /package/{dist → esm}/helpers/iso/isoBase64URL.d.ts +0 -0
- /package/{dist → esm}/helpers/iso/isoCrypto/importKey.d.ts +0 -0
- /package/{dist → esm}/helpers/iso/isoCrypto/structs.d.ts +0 -0
- /package/{dist → esm}/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +0 -0
- /package/{dist → esm}/helpers/iso/isoUint8Array.d.ts +0 -0
- /package/{dist → esm}/helpers/matchExpectedRPID.d.ts +0 -0
- /package/{dist → esm}/helpers/validateCertificatePath.d.ts +0 -0
- /package/{dist → esm}/metadata/parseJWT.d.ts +0 -0
- /package/{dist → esm}/metadata/verifyJWT.d.ts +0 -0
- /package/{dist → esm}/registration/verifications/tpm/constants.d.ts +0 -0
- /package/{dist → esm}/registration/verifications/tpm/parseCertInfo.d.ts +0 -0
- /package/{dist → esm}/registration/verifications/tpm/parsePubArea.d.ts +0 -0
- /package/{dist → esm}/services/defaultRootCerts/android-key.d.ts +0 -0
- /package/{dist → esm}/services/defaultRootCerts/android-safetynet.d.ts +0 -0
- /package/{dist → esm}/services/defaultRootCerts/apple.d.ts +0 -0
- /package/{dist → esm}/services/defaultRootCerts/mds.d.ts +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AsnParser, ECDSASigValue } from '../../../deps.js';
|
|
2
|
+
import { isoUint8Array } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* In WebAuthn, EC2 signatures are wrapped in ASN.1 structure so we need to peel r and s apart.
|
|
5
|
+
*
|
|
6
|
+
* See https://www.w3.org/TR/webauthn-2/#sctn-signature-attestation-types
|
|
7
|
+
*/
|
|
8
|
+
export function unwrapEC2Signature(signature) {
|
|
9
|
+
const parsedSignature = AsnParser.parse(signature, ECDSASigValue);
|
|
10
|
+
let rBytes = new Uint8Array(parsedSignature.r);
|
|
11
|
+
let sBytes = new Uint8Array(parsedSignature.s);
|
|
12
|
+
if (shouldRemoveLeadingZero(rBytes)) {
|
|
13
|
+
rBytes = rBytes.slice(1);
|
|
14
|
+
}
|
|
15
|
+
if (shouldRemoveLeadingZero(sBytes)) {
|
|
16
|
+
sBytes = sBytes.slice(1);
|
|
17
|
+
}
|
|
18
|
+
const finalSignature = isoUint8Array.concat([rBytes, sBytes]);
|
|
19
|
+
return finalSignature;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Determine if the DER-specific `00` byte at the start of an ECDSA signature byte sequence
|
|
23
|
+
* should be removed based on the following logic:
|
|
24
|
+
*
|
|
25
|
+
* "If the leading byte is 0x0, and the the high order bit on the second byte is not set to 0,
|
|
26
|
+
* then remove the leading 0x0 byte"
|
|
27
|
+
*/
|
|
28
|
+
function shouldRemoveLeadingZero(bytes) {
|
|
29
|
+
return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0;
|
|
30
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { COSEKEYS, isCOSEPublicKeyEC2, isCOSEPublicKeyOKP, isCOSEPublicKeyRSA, } from '../../cose.js';
|
|
2
|
+
import { verifyEC2 } from './verifyEC2.js';
|
|
3
|
+
import { verifyRSA } from './verifyRSA.js';
|
|
4
|
+
import { verifyOKP } from './verifyOKP.js';
|
|
5
|
+
import { unwrapEC2Signature } from './unwrapEC2Signature.js';
|
|
6
|
+
/**
|
|
7
|
+
* Verify signatures with their public key. Supports EC2 and RSA public keys.
|
|
8
|
+
*/
|
|
9
|
+
export function verify(opts) {
|
|
10
|
+
const { cosePublicKey, signature, data, shaHashOverride } = opts;
|
|
11
|
+
if (isCOSEPublicKeyEC2(cosePublicKey)) {
|
|
12
|
+
const unwrappedSignature = unwrapEC2Signature(signature);
|
|
13
|
+
return verifyEC2({
|
|
14
|
+
cosePublicKey,
|
|
15
|
+
signature: unwrappedSignature,
|
|
16
|
+
data,
|
|
17
|
+
shaHashOverride,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else if (isCOSEPublicKeyRSA(cosePublicKey)) {
|
|
21
|
+
return verifyRSA({ cosePublicKey, signature, data, shaHashOverride });
|
|
22
|
+
}
|
|
23
|
+
else if (isCOSEPublicKeyOKP(cosePublicKey)) {
|
|
24
|
+
return verifyOKP({ cosePublicKey, signature, data });
|
|
25
|
+
}
|
|
26
|
+
const kty = cosePublicKey.get(COSEKEYS.kty);
|
|
27
|
+
throw new Error(`Signature verification with public key of kty ${kty} is not supported by this method`);
|
|
28
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { COSECRV, COSEKEYS } from '../../cose.js';
|
|
2
|
+
import { mapCoseAlgToWebCryptoAlg } from './mapCoseAlgToWebCryptoAlg.js';
|
|
3
|
+
import { importKey } from './importKey.js';
|
|
4
|
+
import { isoBase64URL } from '../index.js';
|
|
5
|
+
import { getWebCrypto } from './getWebCrypto.js';
|
|
6
|
+
/**
|
|
7
|
+
* Verify a signature using an EC2 public key
|
|
8
|
+
*/
|
|
9
|
+
export async function verifyEC2(opts) {
|
|
10
|
+
const { cosePublicKey, signature, data, shaHashOverride } = opts;
|
|
11
|
+
const WebCrypto = await getWebCrypto();
|
|
12
|
+
// Import the public key
|
|
13
|
+
const alg = cosePublicKey.get(COSEKEYS.alg);
|
|
14
|
+
const crv = cosePublicKey.get(COSEKEYS.crv);
|
|
15
|
+
const x = cosePublicKey.get(COSEKEYS.x);
|
|
16
|
+
const y = cosePublicKey.get(COSEKEYS.y);
|
|
17
|
+
if (!alg) {
|
|
18
|
+
throw new Error('Public key was missing alg (EC2)');
|
|
19
|
+
}
|
|
20
|
+
if (!crv) {
|
|
21
|
+
throw new Error('Public key was missing crv (EC2)');
|
|
22
|
+
}
|
|
23
|
+
if (!x) {
|
|
24
|
+
throw new Error('Public key was missing x (EC2)');
|
|
25
|
+
}
|
|
26
|
+
if (!y) {
|
|
27
|
+
throw new Error('Public key was missing y (EC2)');
|
|
28
|
+
}
|
|
29
|
+
let _crv;
|
|
30
|
+
if (crv === COSECRV.P256) {
|
|
31
|
+
_crv = 'P-256';
|
|
32
|
+
}
|
|
33
|
+
else if (crv === COSECRV.P384) {
|
|
34
|
+
_crv = 'P-384';
|
|
35
|
+
}
|
|
36
|
+
else if (crv === COSECRV.P521) {
|
|
37
|
+
_crv = 'P-521';
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error(`Unexpected COSE crv value of ${crv} (EC2)`);
|
|
41
|
+
}
|
|
42
|
+
const keyData = {
|
|
43
|
+
kty: 'EC',
|
|
44
|
+
crv: _crv,
|
|
45
|
+
x: isoBase64URL.fromBuffer(x),
|
|
46
|
+
y: isoBase64URL.fromBuffer(y),
|
|
47
|
+
ext: false,
|
|
48
|
+
};
|
|
49
|
+
const keyAlgorithm = {
|
|
50
|
+
/**
|
|
51
|
+
* Note to future self: you can't use `mapCoseAlgToWebCryptoKeyAlgName()` here because some
|
|
52
|
+
* leaf certs from actual devices specified an RSA SHA value for `alg` (e.g. `-257`) which
|
|
53
|
+
* would then map here to `'RSASSA-PKCS1-v1_5'`. We always want `'ECDSA'` here so we'll
|
|
54
|
+
* hard-code this.
|
|
55
|
+
*/
|
|
56
|
+
name: 'ECDSA',
|
|
57
|
+
namedCurve: _crv,
|
|
58
|
+
};
|
|
59
|
+
const key = await importKey({
|
|
60
|
+
keyData,
|
|
61
|
+
algorithm: keyAlgorithm,
|
|
62
|
+
});
|
|
63
|
+
// Determine which SHA algorithm to use for signature verification
|
|
64
|
+
let subtleAlg = mapCoseAlgToWebCryptoAlg(alg);
|
|
65
|
+
if (shaHashOverride) {
|
|
66
|
+
subtleAlg = mapCoseAlgToWebCryptoAlg(shaHashOverride);
|
|
67
|
+
}
|
|
68
|
+
const verifyAlgorithm = {
|
|
69
|
+
name: 'ECDSA',
|
|
70
|
+
hash: { name: subtleAlg },
|
|
71
|
+
};
|
|
72
|
+
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
73
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { COSECRV, COSEKEYS, isCOSEAlg } from '../../cose.js';
|
|
2
|
+
import { isoBase64URL } from '../../index.js';
|
|
3
|
+
import { importKey } from './importKey.js';
|
|
4
|
+
import { getWebCrypto } from './getWebCrypto.js';
|
|
5
|
+
export async function verifyOKP(opts) {
|
|
6
|
+
const { cosePublicKey, signature, data } = opts;
|
|
7
|
+
const WebCrypto = await getWebCrypto();
|
|
8
|
+
const alg = cosePublicKey.get(COSEKEYS.alg);
|
|
9
|
+
const crv = cosePublicKey.get(COSEKEYS.crv);
|
|
10
|
+
const x = cosePublicKey.get(COSEKEYS.x);
|
|
11
|
+
if (!alg) {
|
|
12
|
+
throw new Error('Public key was missing alg (OKP)');
|
|
13
|
+
}
|
|
14
|
+
if (!isCOSEAlg(alg)) {
|
|
15
|
+
throw new Error(`Public key had invalid alg ${alg} (OKP)`);
|
|
16
|
+
}
|
|
17
|
+
if (!crv) {
|
|
18
|
+
throw new Error('Public key was missing crv (OKP)');
|
|
19
|
+
}
|
|
20
|
+
if (!x) {
|
|
21
|
+
throw new Error('Public key was missing x (OKP)');
|
|
22
|
+
}
|
|
23
|
+
// Pulled key import steps from here:
|
|
24
|
+
// https://wicg.github.io/webcrypto-secure-curves/#ed25519-operations
|
|
25
|
+
let _crv;
|
|
26
|
+
if (crv === COSECRV.ED25519) {
|
|
27
|
+
_crv = 'Ed25519';
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw new Error(`Unexpected COSE crv value of ${crv} (OKP)`);
|
|
31
|
+
}
|
|
32
|
+
const keyData = {
|
|
33
|
+
kty: 'OKP',
|
|
34
|
+
crv: _crv,
|
|
35
|
+
alg: 'EdDSA',
|
|
36
|
+
x: isoBase64URL.fromBuffer(x),
|
|
37
|
+
ext: false,
|
|
38
|
+
};
|
|
39
|
+
const keyAlgorithm = {
|
|
40
|
+
name: _crv,
|
|
41
|
+
namedCurve: _crv,
|
|
42
|
+
};
|
|
43
|
+
const key = await importKey({
|
|
44
|
+
keyData,
|
|
45
|
+
algorithm: keyAlgorithm,
|
|
46
|
+
});
|
|
47
|
+
const verifyAlgorithm = {
|
|
48
|
+
name: _crv,
|
|
49
|
+
};
|
|
50
|
+
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
51
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { COSEKEYS, isCOSEAlg } from '../../cose.js';
|
|
2
|
+
import { mapCoseAlgToWebCryptoAlg } from './mapCoseAlgToWebCryptoAlg.js';
|
|
3
|
+
import { importKey } from './importKey.js';
|
|
4
|
+
import { isoBase64URL } from '../index.js';
|
|
5
|
+
import { mapCoseAlgToWebCryptoKeyAlgName } from './mapCoseAlgToWebCryptoKeyAlgName.js';
|
|
6
|
+
import { getWebCrypto } from './getWebCrypto.js';
|
|
7
|
+
/**
|
|
8
|
+
* Verify a signature using an RSA public key
|
|
9
|
+
*/
|
|
10
|
+
export async function verifyRSA(opts) {
|
|
11
|
+
const { cosePublicKey, signature, data, shaHashOverride } = opts;
|
|
12
|
+
const WebCrypto = await getWebCrypto();
|
|
13
|
+
const alg = cosePublicKey.get(COSEKEYS.alg);
|
|
14
|
+
const n = cosePublicKey.get(COSEKEYS.n);
|
|
15
|
+
const e = cosePublicKey.get(COSEKEYS.e);
|
|
16
|
+
if (!alg) {
|
|
17
|
+
throw new Error('Public key was missing alg (RSA)');
|
|
18
|
+
}
|
|
19
|
+
if (!isCOSEAlg(alg)) {
|
|
20
|
+
throw new Error(`Public key had invalid alg ${alg} (RSA)`);
|
|
21
|
+
}
|
|
22
|
+
if (!n) {
|
|
23
|
+
throw new Error('Public key was missing n (RSA)');
|
|
24
|
+
}
|
|
25
|
+
if (!e) {
|
|
26
|
+
throw new Error('Public key was missing e (RSA)');
|
|
27
|
+
}
|
|
28
|
+
const keyData = {
|
|
29
|
+
kty: 'RSA',
|
|
30
|
+
alg: '',
|
|
31
|
+
n: isoBase64URL.fromBuffer(n),
|
|
32
|
+
e: isoBase64URL.fromBuffer(e),
|
|
33
|
+
ext: false,
|
|
34
|
+
};
|
|
35
|
+
const keyAlgorithm = {
|
|
36
|
+
name: mapCoseAlgToWebCryptoKeyAlgName(alg),
|
|
37
|
+
hash: { name: mapCoseAlgToWebCryptoAlg(alg) },
|
|
38
|
+
};
|
|
39
|
+
const verifyAlgorithm = {
|
|
40
|
+
name: mapCoseAlgToWebCryptoKeyAlgName(alg),
|
|
41
|
+
};
|
|
42
|
+
if (shaHashOverride) {
|
|
43
|
+
keyAlgorithm.hash.name = mapCoseAlgToWebCryptoAlg(shaHashOverride);
|
|
44
|
+
}
|
|
45
|
+
if (keyAlgorithm.name === 'RSASSA-PKCS1-v1_5') {
|
|
46
|
+
if (keyAlgorithm.hash.name === 'SHA-256') {
|
|
47
|
+
keyData.alg = 'RS256';
|
|
48
|
+
}
|
|
49
|
+
else if (keyAlgorithm.hash.name === 'SHA-384') {
|
|
50
|
+
keyData.alg = 'RS384';
|
|
51
|
+
}
|
|
52
|
+
else if (keyAlgorithm.hash.name === 'SHA-512') {
|
|
53
|
+
keyData.alg = 'RS512';
|
|
54
|
+
}
|
|
55
|
+
else if (keyAlgorithm.hash.name === 'SHA-1') {
|
|
56
|
+
keyData.alg = 'RS1';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (keyAlgorithm.name === 'RSA-PSS') {
|
|
60
|
+
/**
|
|
61
|
+
* salt length. The default value is 20 but the convention is to use hLen, the length of the
|
|
62
|
+
* output of the hash function in bytes. A salt length of zero is permitted and will result in
|
|
63
|
+
* a deterministic signature value. The actual salt length used can be determined from the
|
|
64
|
+
* signature value.
|
|
65
|
+
*
|
|
66
|
+
* From https://www.cryptosys.net/pki/manpki/pki_rsaschemes.html
|
|
67
|
+
*/
|
|
68
|
+
let saltLength = 0;
|
|
69
|
+
if (keyAlgorithm.hash.name === 'SHA-256') {
|
|
70
|
+
keyData.alg = 'PS256';
|
|
71
|
+
saltLength = 32; // 256 bits => 32 bytes
|
|
72
|
+
}
|
|
73
|
+
else if (keyAlgorithm.hash.name === 'SHA-384') {
|
|
74
|
+
keyData.alg = 'PS384';
|
|
75
|
+
saltLength = 48; // 384 bits => 48 bytes
|
|
76
|
+
}
|
|
77
|
+
else if (keyAlgorithm.hash.name === 'SHA-512') {
|
|
78
|
+
keyData.alg = 'PS512';
|
|
79
|
+
saltLength = 64; // 512 bits => 64 bytes
|
|
80
|
+
}
|
|
81
|
+
verifyAlgorithm.saltLength = saltLength;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new Error(`Unexpected RSA key algorithm ${alg} (${keyAlgorithm.name})`);
|
|
85
|
+
}
|
|
86
|
+
const key = await importKey({
|
|
87
|
+
keyData,
|
|
88
|
+
algorithm: keyAlgorithm,
|
|
89
|
+
});
|
|
90
|
+
return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
|
|
91
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make sure two Uint8Arrays are deeply equivalent
|
|
3
|
+
*/
|
|
4
|
+
export function areEqual(array1, array2) {
|
|
5
|
+
if (array1.length != array2.length) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return array1.every((val, i) => val === array2[i]);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Convert a Uint8Array to Hexadecimal.
|
|
12
|
+
*
|
|
13
|
+
* A replacement for `Buffer.toString('hex')`
|
|
14
|
+
*/
|
|
15
|
+
export function toHex(array) {
|
|
16
|
+
const hexParts = Array.from(array, (i) => i.toString(16).padStart(2, '0'));
|
|
17
|
+
// adce000235bcc60a648b0b25f1f05503
|
|
18
|
+
return hexParts.join('');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert a hexadecimal string to isoUint8Array.
|
|
22
|
+
*
|
|
23
|
+
* A replacement for `Buffer.from('...', 'hex')`
|
|
24
|
+
*/
|
|
25
|
+
export function fromHex(hex) {
|
|
26
|
+
if (!hex) {
|
|
27
|
+
return Uint8Array.from([]);
|
|
28
|
+
}
|
|
29
|
+
const isValid = hex.length !== 0 && hex.length % 2 === 0 &&
|
|
30
|
+
!/[^a-fA-F0-9]/u.test(hex);
|
|
31
|
+
if (!isValid) {
|
|
32
|
+
throw new Error('Invalid hex string');
|
|
33
|
+
}
|
|
34
|
+
const byteStrings = hex.match(/.{1,2}/g) ?? [];
|
|
35
|
+
return Uint8Array.from(byteStrings.map((byte) => parseInt(byte, 16)));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Combine multiple Uint8Arrays into a single Uint8Array
|
|
39
|
+
*/
|
|
40
|
+
export function concat(arrays) {
|
|
41
|
+
let pointer = 0;
|
|
42
|
+
const totalLength = arrays.reduce((prev, curr) => prev + curr.length, 0);
|
|
43
|
+
const toReturn = new Uint8Array(totalLength);
|
|
44
|
+
arrays.forEach((arr) => {
|
|
45
|
+
toReturn.set(arr, pointer);
|
|
46
|
+
pointer += arr.length;
|
|
47
|
+
});
|
|
48
|
+
return toReturn;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Convert bytes into a UTF-8 string
|
|
52
|
+
*/
|
|
53
|
+
export function toUTF8String(array) {
|
|
54
|
+
const decoder = new globalThis.TextDecoder('utf-8');
|
|
55
|
+
return decoder.decode(array);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Convert a UTF-8 string back into bytes
|
|
59
|
+
*/
|
|
60
|
+
export function fromUTF8String(utf8String) {
|
|
61
|
+
const encoder = new globalThis.TextEncoder();
|
|
62
|
+
return encoder.encode(utf8String);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert an ASCII string to Uint8Array
|
|
66
|
+
*/
|
|
67
|
+
export function fromASCIIString(value) {
|
|
68
|
+
return Uint8Array.from(value.split('').map((x) => x.charCodeAt(0)));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Prepare a DataView we can slice our way around in as we parse the bytes in a Uint8Array
|
|
72
|
+
*/
|
|
73
|
+
export function toDataView(array) {
|
|
74
|
+
return new DataView(array.buffer, array.byteOffset, array.length);
|
|
75
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { debug } from '../deps.js';
|
|
2
|
+
const defaultLogger = debug('SimpleWebAuthn');
|
|
3
|
+
/**
|
|
4
|
+
* Generate an instance of a `debug` logger that extends off of the "simplewebauthn" namespace for
|
|
5
|
+
* consistent naming.
|
|
6
|
+
*
|
|
7
|
+
* See https://www.npmjs.com/package/debug for information on how to control logging output when
|
|
8
|
+
* using @simplewebauthn/server
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
*
|
|
12
|
+
* ```
|
|
13
|
+
* const log = getLogger('mds');
|
|
14
|
+
* log('hello'); // simplewebauthn:mds hello +0ms
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function getLogger(name) {
|
|
18
|
+
return defaultLogger.extend(name);
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { COSEALG } from './cose.js';
|
|
2
|
+
/**
|
|
3
|
+
* Map X.509 signature algorithm OIDs to COSE algorithm IDs
|
|
4
|
+
*
|
|
5
|
+
* - EC2 OIDs: https://oidref.com/1.2.840.10045.4.3
|
|
6
|
+
* - RSA OIDs: https://oidref.com/1.2.840.113549.1.1
|
|
7
|
+
*/
|
|
8
|
+
export function mapX509SignatureAlgToCOSEAlg(signatureAlgorithm) {
|
|
9
|
+
let alg;
|
|
10
|
+
if (signatureAlgorithm === '1.2.840.10045.4.3.2') {
|
|
11
|
+
alg = COSEALG.ES256;
|
|
12
|
+
}
|
|
13
|
+
else if (signatureAlgorithm === '1.2.840.10045.4.3.3') {
|
|
14
|
+
alg = COSEALG.ES384;
|
|
15
|
+
}
|
|
16
|
+
else if (signatureAlgorithm === '1.2.840.10045.4.3.4') {
|
|
17
|
+
alg = COSEALG.ES512;
|
|
18
|
+
}
|
|
19
|
+
else if (signatureAlgorithm === '1.2.840.113549.1.1.11') {
|
|
20
|
+
alg = COSEALG.RS256;
|
|
21
|
+
}
|
|
22
|
+
else if (signatureAlgorithm === '1.2.840.113549.1.1.12') {
|
|
23
|
+
alg = COSEALG.RS384;
|
|
24
|
+
}
|
|
25
|
+
else if (signatureAlgorithm === '1.2.840.113549.1.1.13') {
|
|
26
|
+
alg = COSEALG.RS512;
|
|
27
|
+
}
|
|
28
|
+
else if (signatureAlgorithm === '1.2.840.113549.1.1.5') {
|
|
29
|
+
alg = COSEALG.RS1;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw new Error(`Unable to map X.509 signature algorithm ${signatureAlgorithm} to a COSE algorithm`);
|
|
33
|
+
}
|
|
34
|
+
return alg;
|
|
35
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { toHash } from './toHash.js';
|
|
2
|
+
import { isoUint8Array } from './iso/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Go through each expected RP ID and try to find one that matches. Returns the unhashed RP ID
|
|
5
|
+
* that matched the hash in the response.
|
|
6
|
+
*
|
|
7
|
+
* Raises an `UnexpectedRPIDHash` error if no match is found
|
|
8
|
+
*/
|
|
9
|
+
export async function matchExpectedRPID(rpIDHash, expectedRPIDs) {
|
|
10
|
+
try {
|
|
11
|
+
const matchedRPID = await Promise.any(expectedRPIDs.map((expected) => {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
toHash(isoUint8Array.fromASCIIString(expected)).then((expectedRPIDHash) => {
|
|
14
|
+
if (isoUint8Array.areEqual(rpIDHash, expectedRPIDHash)) {
|
|
15
|
+
resolve(expected);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
reject();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}));
|
|
23
|
+
return matchedRPID;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const _err = err;
|
|
27
|
+
// This means no matches were found
|
|
28
|
+
if (_err.name === 'AggregateError') {
|
|
29
|
+
throw new UnexpectedRPIDHash();
|
|
30
|
+
}
|
|
31
|
+
// An unexpected error occurred
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
class UnexpectedRPIDHash extends Error {
|
|
36
|
+
constructor() {
|
|
37
|
+
const message = 'Unexpected RP ID hash';
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = 'UnexpectedRPIDHash';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthenticationExtensionsAuthenticatorOutputs } from './decodeAuthenticatorExtensions';
|
|
1
|
+
import { AuthenticationExtensionsAuthenticatorOutputs } from './decodeAuthenticatorExtensions.js';
|
|
2
2
|
/**
|
|
3
3
|
* Make sense of the authData buffer contained in an Attestation
|
|
4
4
|
*/
|
|
@@ -23,3 +23,6 @@ export type ParsedAuthenticatorData = {
|
|
|
23
23
|
extensionsData?: AuthenticationExtensionsAuthenticatorOutputs;
|
|
24
24
|
extensionsDataBuffer?: Uint8Array;
|
|
25
25
|
};
|
|
26
|
+
export declare const _parseAuthenticatorDataInternals: {
|
|
27
|
+
stubThis: (value: ParsedAuthenticatorData) => ParsedAuthenticatorData;
|
|
28
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { decodeAuthenticatorExtensions, } from './decodeAuthenticatorExtensions.js';
|
|
2
|
+
import { isoCBOR, isoUint8Array } from './iso/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Make sense of the authData buffer contained in an Attestation
|
|
5
|
+
*/
|
|
6
|
+
export function parseAuthenticatorData(authData) {
|
|
7
|
+
if (authData.byteLength < 37) {
|
|
8
|
+
throw new Error(`Authenticator data was ${authData.byteLength} bytes, expected at least 37 bytes`);
|
|
9
|
+
}
|
|
10
|
+
let pointer = 0;
|
|
11
|
+
const dataView = isoUint8Array.toDataView(authData);
|
|
12
|
+
const rpIdHash = authData.slice(pointer, pointer += 32);
|
|
13
|
+
const flagsBuf = authData.slice(pointer, pointer += 1);
|
|
14
|
+
const flagsInt = flagsBuf[0];
|
|
15
|
+
// Bit positions can be referenced here:
|
|
16
|
+
// https://www.w3.org/TR/webauthn-2/#flags
|
|
17
|
+
const flags = {
|
|
18
|
+
up: !!(flagsInt & (1 << 0)),
|
|
19
|
+
uv: !!(flagsInt & (1 << 2)),
|
|
20
|
+
be: !!(flagsInt & (1 << 3)),
|
|
21
|
+
bs: !!(flagsInt & (1 << 4)),
|
|
22
|
+
at: !!(flagsInt & (1 << 6)),
|
|
23
|
+
ed: !!(flagsInt & (1 << 7)),
|
|
24
|
+
flagsInt,
|
|
25
|
+
};
|
|
26
|
+
const counterBuf = authData.slice(pointer, pointer + 4);
|
|
27
|
+
const counter = dataView.getUint32(pointer, false);
|
|
28
|
+
pointer += 4;
|
|
29
|
+
let aaguid = undefined;
|
|
30
|
+
let credentialID = undefined;
|
|
31
|
+
let credentialPublicKey = undefined;
|
|
32
|
+
if (flags.at) {
|
|
33
|
+
aaguid = authData.slice(pointer, pointer += 16);
|
|
34
|
+
const credIDLen = dataView.getUint16(pointer);
|
|
35
|
+
pointer += 2;
|
|
36
|
+
credentialID = authData.slice(pointer, pointer += credIDLen);
|
|
37
|
+
// Decode the next CBOR item in the buffer, then re-encode it back to a Buffer
|
|
38
|
+
const firstDecoded = isoCBOR.decodeFirst(authData.slice(pointer));
|
|
39
|
+
const firstEncoded = Uint8Array.from(isoCBOR.encode(firstDecoded));
|
|
40
|
+
credentialPublicKey = firstEncoded;
|
|
41
|
+
pointer += firstEncoded.byteLength;
|
|
42
|
+
}
|
|
43
|
+
let extensionsData = undefined;
|
|
44
|
+
let extensionsDataBuffer = undefined;
|
|
45
|
+
if (flags.ed) {
|
|
46
|
+
const firstDecoded = isoCBOR.decodeFirst(authData.slice(pointer));
|
|
47
|
+
extensionsDataBuffer = Uint8Array.from(isoCBOR.encode(firstDecoded));
|
|
48
|
+
extensionsData = decodeAuthenticatorExtensions(extensionsDataBuffer);
|
|
49
|
+
pointer += extensionsDataBuffer.byteLength;
|
|
50
|
+
}
|
|
51
|
+
// Pointer should be at the end of the authenticator data, otherwise too much data was sent
|
|
52
|
+
if (authData.byteLength > pointer) {
|
|
53
|
+
throw new Error('Leftover bytes detected while parsing authenticator data');
|
|
54
|
+
}
|
|
55
|
+
return _parseAuthenticatorDataInternals.stubThis({
|
|
56
|
+
rpIdHash,
|
|
57
|
+
flagsBuf,
|
|
58
|
+
flags,
|
|
59
|
+
counter,
|
|
60
|
+
counterBuf,
|
|
61
|
+
aaguid,
|
|
62
|
+
credentialID,
|
|
63
|
+
credentialPublicKey,
|
|
64
|
+
extensionsData,
|
|
65
|
+
extensionsDataBuffer,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Make it possible to stub the return value during testing
|
|
69
|
+
export const _parseAuthenticatorDataInternals = {
|
|
70
|
+
stubThis: (value) => value,
|
|
71
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CredentialDeviceType } from '
|
|
1
|
+
import type { CredentialDeviceType } from '../deps.js';
|
|
2
2
|
/**
|
|
3
3
|
* Make sense of Bits 3 and 4 in authenticator indicating:
|
|
4
4
|
*
|
|
@@ -14,3 +14,6 @@ export declare function parseBackupFlags({ be, bs }: {
|
|
|
14
14
|
credentialDeviceType: CredentialDeviceType;
|
|
15
15
|
credentialBackedUp: boolean;
|
|
16
16
|
};
|
|
17
|
+
export declare class InvalidBackupFlags extends Error {
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make sense of Bits 3 and 4 in authenticator indicating:
|
|
3
|
+
*
|
|
4
|
+
* - Whether the credential can be used on multiple devices
|
|
5
|
+
* - Whether the credential is backed up or not
|
|
6
|
+
*
|
|
7
|
+
* Invalid configurations will raise an `Error`
|
|
8
|
+
*/
|
|
9
|
+
export function parseBackupFlags({ be, bs }) {
|
|
10
|
+
const credentialBackedUp = bs;
|
|
11
|
+
let credentialDeviceType = 'singleDevice';
|
|
12
|
+
if (be) {
|
|
13
|
+
credentialDeviceType = 'multiDevice';
|
|
14
|
+
}
|
|
15
|
+
if (credentialDeviceType === 'singleDevice' && credentialBackedUp) {
|
|
16
|
+
throw new InvalidBackupFlags('Single-device credential indicated that it was backed up, which should be impossible.');
|
|
17
|
+
}
|
|
18
|
+
return { credentialDeviceType, credentialBackedUp };
|
|
19
|
+
}
|
|
20
|
+
export class InvalidBackupFlags extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'InvalidBackupFlags';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isoCrypto, isoUint8Array } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns hash digest of the given data, using the given algorithm when provided. Defaults to using
|
|
4
|
+
* SHA-256.
|
|
5
|
+
*/
|
|
6
|
+
export function toHash(data, algorithm = -7) {
|
|
7
|
+
if (typeof data === 'string') {
|
|
8
|
+
data = isoUint8Array.fromUTF8String(data);
|
|
9
|
+
}
|
|
10
|
+
const digest = isoCrypto.digest(data, algorithm);
|
|
11
|
+
return digest;
|
|
12
|
+
}
|