@simplewebauthn/server 7.4.0 → 8.0.0-alpha.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 +6 -2
- 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 +10 -0
- package/esm/deps.js +12 -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 -45
- 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 +10 -0
- package/script/deps.js +68 -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 +0 -1
- 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
package/LICENSE.md
CHANGED
|
@@ -2,20 +2,17 @@ MIT License
|
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2020 Matthew Miller
|
|
4
4
|
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
10
9
|
furnished to do so, subject to the following conditions:
|
|
11
10
|
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
+
portions of the Software.
|
|
14
13
|
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
|
17
|
+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<!-- omit in toc -->
|
|
2
|
+
|
|
2
3
|
# @simplewebauthn/server
|
|
3
4
|
|
|
4
5
|

|
|
@@ -20,11 +21,14 @@ npm install @simplewebauthn/server
|
|
|
20
21
|
|
|
21
22
|
## Usage
|
|
22
23
|
|
|
23
|
-
You can find in-depth documentation on this package here:
|
|
24
|
+
You can find in-depth documentation on this package here:
|
|
25
|
+
https://simplewebauthn.dev/docs/packages/server
|
|
24
26
|
|
|
25
27
|
## Supported Attestation Formats
|
|
26
28
|
|
|
27
|
-
SimpleWebAuthn supports
|
|
29
|
+
SimpleWebAuthn supports
|
|
30
|
+
[all current WebAuthn attestation formats](https://w3c.github.io/webauthn/#sctn-defined-attestation-formats),
|
|
31
|
+
including:
|
|
28
32
|
|
|
29
33
|
- **Android Key**
|
|
30
34
|
- **Android SafetyNet**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthenticationExtensionsClientInputs,
|
|
1
|
+
import type { AuthenticationExtensionsClientInputs, PublicKeyCredentialDescriptorFuture, PublicKeyCredentialRequestOptionsJSON, UserVerificationRequirement } from '../deps.js';
|
|
2
2
|
export type GenerateAuthenticationOptionsOpts = {
|
|
3
3
|
allowCredentials?: PublicKeyCredentialDescriptorFuture[];
|
|
4
4
|
challenge?: string | Uint8Array;
|
|
@@ -20,4 +20,4 @@ export type GenerateAuthenticationOptionsOpts = {
|
|
|
20
20
|
* @param extensions Additional plugins the authenticator or browser should use during authentication
|
|
21
21
|
* @param rpID Valid domain name (after `https://`)
|
|
22
22
|
*/
|
|
23
|
-
export declare function generateAuthenticationOptions(options?: GenerateAuthenticationOptionsOpts): PublicKeyCredentialRequestOptionsJSON
|
|
23
|
+
export declare function generateAuthenticationOptions(options?: GenerateAuthenticationOptionsOpts): Promise<PublicKeyCredentialRequestOptionsJSON>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { isoBase64URL, isoUint8Array } from '../helpers/iso/index.js';
|
|
2
|
+
import { generateChallenge } from '../helpers/generateChallenge.js';
|
|
3
|
+
/**
|
|
4
|
+
* Prepare a value to pass into navigator.credentials.get(...) for authenticator "login"
|
|
5
|
+
*
|
|
6
|
+
* @param allowCredentials Authenticators previously registered by the user, if any. If undefined
|
|
7
|
+
* the client will ask the user which credential they want to use
|
|
8
|
+
* @param challenge Random value the authenticator needs to sign and pass back
|
|
9
|
+
* user for authentication
|
|
10
|
+
* @param timeout How long (in ms) the user can take to complete authentication
|
|
11
|
+
* @param userVerification Set to `'discouraged'` when asserting as part of a 2FA flow, otherwise
|
|
12
|
+
* set to `'preferred'` or `'required'` as desired.
|
|
13
|
+
* @param extensions Additional plugins the authenticator or browser should use during authentication
|
|
14
|
+
* @param rpID Valid domain name (after `https://`)
|
|
15
|
+
*/
|
|
16
|
+
export async function generateAuthenticationOptions(options = {}) {
|
|
17
|
+
const { allowCredentials, challenge = await generateChallenge(), timeout = 60000, userVerification = 'preferred', extensions, rpID, } = options;
|
|
18
|
+
/**
|
|
19
|
+
* Preserve ability to specify `string` values for challenges
|
|
20
|
+
*/
|
|
21
|
+
let _challenge = challenge;
|
|
22
|
+
if (typeof _challenge === 'string') {
|
|
23
|
+
_challenge = isoUint8Array.fromUTF8String(_challenge);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
challenge: isoBase64URL.fromBuffer(_challenge),
|
|
27
|
+
allowCredentials: allowCredentials?.map((cred) => ({
|
|
28
|
+
...cred,
|
|
29
|
+
id: isoBase64URL.fromBuffer(cred.id),
|
|
30
|
+
})),
|
|
31
|
+
timeout,
|
|
32
|
+
userVerification,
|
|
33
|
+
extensions,
|
|
34
|
+
rpId: rpID,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AuthenticationResponseJSON, AuthenticatorDevice, CredentialDeviceType, UserVerificationRequirement } from '
|
|
2
|
-
import { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions';
|
|
1
|
+
import type { AuthenticationResponseJSON, AuthenticatorDevice, CredentialDeviceType, UserVerificationRequirement } from '../deps.js';
|
|
2
|
+
import { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions.js';
|
|
3
3
|
export type VerifyAuthenticationResponseOpts = {
|
|
4
4
|
response: AuthenticationResponseJSON;
|
|
5
5
|
expectedChallenge: string | ((challenge: string) => boolean);
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { decodeClientDataJSON } from '../helpers/decodeClientDataJSON.js';
|
|
2
|
+
import { toHash } from '../helpers/toHash.js';
|
|
3
|
+
import { verifySignature } from '../helpers/verifySignature.js';
|
|
4
|
+
import { parseAuthenticatorData } from '../helpers/parseAuthenticatorData.js';
|
|
5
|
+
import { parseBackupFlags } from '../helpers/parseBackupFlags.js';
|
|
6
|
+
import { matchExpectedRPID } from '../helpers/matchExpectedRPID.js';
|
|
7
|
+
import { isoBase64URL, isoUint8Array } from '../helpers/iso/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Verify that the user has legitimately completed the login process
|
|
10
|
+
*
|
|
11
|
+
* **Options:**
|
|
12
|
+
*
|
|
13
|
+
* @param response Response returned by **@simplewebauthn/browser**'s `startAssertion()`
|
|
14
|
+
* @param expectedChallenge The base64url-encoded `options.challenge` returned by
|
|
15
|
+
* `generateAuthenticationOptions()`
|
|
16
|
+
* @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
|
|
17
|
+
* @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
|
|
18
|
+
* @param authenticator An internal {@link AuthenticatorDevice} matching the credential's ID
|
|
19
|
+
* @param requireUserVerification (Optional) Enforce user verification by the authenticator
|
|
20
|
+
* (via PIN, fingerprint, etc...)
|
|
21
|
+
* @param advancedFIDOConfig (Optional) Options for satisfying more stringent FIDO RP feature
|
|
22
|
+
* requirements
|
|
23
|
+
* @param advancedFIDOConfig.userVerification (Optional) Enable alternative rules for evaluating the
|
|
24
|
+
* User Presence and User Verified flags in authenticator data: UV (and UP) flags are optional
|
|
25
|
+
* unless this value is `"required"`
|
|
26
|
+
*/
|
|
27
|
+
export async function verifyAuthenticationResponse(options) {
|
|
28
|
+
const { response, expectedChallenge, expectedOrigin, expectedRPID, authenticator, requireUserVerification = true, advancedFIDOConfig, } = options;
|
|
29
|
+
const { id, rawId, type: credentialType, response: assertionResponse } = response;
|
|
30
|
+
// Ensure credential specified an ID
|
|
31
|
+
if (!id) {
|
|
32
|
+
throw new Error('Missing credential ID');
|
|
33
|
+
}
|
|
34
|
+
// Ensure ID is base64url-encoded
|
|
35
|
+
if (id !== rawId) {
|
|
36
|
+
throw new Error('Credential ID was not base64url-encoded');
|
|
37
|
+
}
|
|
38
|
+
// Make sure credential type is public-key
|
|
39
|
+
if (credentialType !== 'public-key') {
|
|
40
|
+
throw new Error(`Unexpected credential type ${credentialType}, expected "public-key"`);
|
|
41
|
+
}
|
|
42
|
+
if (!response) {
|
|
43
|
+
throw new Error('Credential missing response');
|
|
44
|
+
}
|
|
45
|
+
if (typeof assertionResponse?.clientDataJSON !== 'string') {
|
|
46
|
+
throw new Error('Credential response clientDataJSON was not a string');
|
|
47
|
+
}
|
|
48
|
+
const clientDataJSON = decodeClientDataJSON(assertionResponse.clientDataJSON);
|
|
49
|
+
const { type, origin, challenge, tokenBinding } = clientDataJSON;
|
|
50
|
+
// Make sure we're handling an authentication
|
|
51
|
+
if (type !== 'webauthn.get') {
|
|
52
|
+
throw new Error(`Unexpected authentication response type: ${type}`);
|
|
53
|
+
}
|
|
54
|
+
// Ensure the device provided the challenge we gave it
|
|
55
|
+
if (typeof expectedChallenge === 'function') {
|
|
56
|
+
if (!expectedChallenge(challenge)) {
|
|
57
|
+
throw new Error(`Custom challenge verifier returned false for registration response challenge "${challenge}"`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (challenge !== expectedChallenge) {
|
|
61
|
+
throw new Error(`Unexpected authentication response challenge "${challenge}", expected "${expectedChallenge}"`);
|
|
62
|
+
}
|
|
63
|
+
// Check that the origin is our site
|
|
64
|
+
if (Array.isArray(expectedOrigin)) {
|
|
65
|
+
if (!expectedOrigin.includes(origin)) {
|
|
66
|
+
const joinedExpectedOrigin = expectedOrigin.join(', ');
|
|
67
|
+
throw new Error(`Unexpected authentication response origin "${origin}", expected one of: ${joinedExpectedOrigin}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (origin !== expectedOrigin) {
|
|
72
|
+
throw new Error(`Unexpected authentication response origin "${origin}", expected "${expectedOrigin}"`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!isoBase64URL.isBase64url(assertionResponse.authenticatorData)) {
|
|
76
|
+
throw new Error('Credential response authenticatorData was not a base64url string');
|
|
77
|
+
}
|
|
78
|
+
if (!isoBase64URL.isBase64url(assertionResponse.signature)) {
|
|
79
|
+
throw new Error('Credential response signature was not a base64url string');
|
|
80
|
+
}
|
|
81
|
+
if (assertionResponse.userHandle &&
|
|
82
|
+
typeof assertionResponse.userHandle !== 'string') {
|
|
83
|
+
throw new Error('Credential response userHandle was not a string');
|
|
84
|
+
}
|
|
85
|
+
if (tokenBinding) {
|
|
86
|
+
if (typeof tokenBinding !== 'object') {
|
|
87
|
+
throw new Error('ClientDataJSON tokenBinding was not an object');
|
|
88
|
+
}
|
|
89
|
+
if (['present', 'supported', 'notSupported'].indexOf(tokenBinding.status) < 0) {
|
|
90
|
+
throw new Error(`Unexpected tokenBinding status ${tokenBinding.status}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const authDataBuffer = isoBase64URL.toBuffer(assertionResponse.authenticatorData);
|
|
94
|
+
const parsedAuthData = parseAuthenticatorData(authDataBuffer);
|
|
95
|
+
const { rpIdHash, flags, counter, extensionsData } = parsedAuthData;
|
|
96
|
+
// Make sure the response's RP ID is ours
|
|
97
|
+
let expectedRPIDs = [];
|
|
98
|
+
if (typeof expectedRPID === 'string') {
|
|
99
|
+
expectedRPIDs = [expectedRPID];
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
expectedRPIDs = expectedRPID;
|
|
103
|
+
}
|
|
104
|
+
const matchedRPID = await matchExpectedRPID(rpIdHash, expectedRPIDs);
|
|
105
|
+
if (advancedFIDOConfig !== undefined) {
|
|
106
|
+
const { userVerification: fidoUserVerification } = advancedFIDOConfig;
|
|
107
|
+
/**
|
|
108
|
+
* Use FIDO Conformance-defined rules for verifying UP and UV flags
|
|
109
|
+
*/
|
|
110
|
+
if (fidoUserVerification === 'required') {
|
|
111
|
+
// Require `flags.uv` be true (implies `flags.up` is true)
|
|
112
|
+
if (!flags.uv) {
|
|
113
|
+
throw new Error('User verification required, but user could not be verified');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (fidoUserVerification === 'preferred' ||
|
|
117
|
+
fidoUserVerification === 'discouraged') {
|
|
118
|
+
// Ignore `flags.uv`
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
/**
|
|
123
|
+
* Use WebAuthn spec-defined rules for verifying UP and UV flags
|
|
124
|
+
*/
|
|
125
|
+
// WebAuthn only requires the user presence flag be true
|
|
126
|
+
if (!flags.up) {
|
|
127
|
+
throw new Error('User not present during authentication');
|
|
128
|
+
}
|
|
129
|
+
// Enforce user verification if required
|
|
130
|
+
if (requireUserVerification && !flags.uv) {
|
|
131
|
+
throw new Error('User verification required, but user could not be verified');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const clientDataHash = await toHash(isoBase64URL.toBuffer(assertionResponse.clientDataJSON));
|
|
135
|
+
const signatureBase = isoUint8Array.concat([authDataBuffer, clientDataHash]);
|
|
136
|
+
const signature = isoBase64URL.toBuffer(assertionResponse.signature);
|
|
137
|
+
if ((counter > 0 || authenticator.counter > 0) &&
|
|
138
|
+
counter <= authenticator.counter) {
|
|
139
|
+
// Error out when the counter in the DB is greater than or equal to the counter in the
|
|
140
|
+
// dataStruct. It's related to how the authenticator maintains the number of times its been
|
|
141
|
+
// used for this client. If this happens, then someone's somehow increased the counter
|
|
142
|
+
// on the device without going through this site
|
|
143
|
+
throw new Error(`Response counter value ${counter} was lower than expected ${authenticator.counter}`);
|
|
144
|
+
}
|
|
145
|
+
const { credentialDeviceType, credentialBackedUp } = parseBackupFlags(flags);
|
|
146
|
+
const toReturn = {
|
|
147
|
+
verified: await verifySignature({
|
|
148
|
+
signature,
|
|
149
|
+
data: signatureBase,
|
|
150
|
+
credentialPublicKey: authenticator.credentialPublicKey,
|
|
151
|
+
}),
|
|
152
|
+
authenticationInfo: {
|
|
153
|
+
newCounter: counter,
|
|
154
|
+
credentialID: authenticator.credentialID,
|
|
155
|
+
userVerified: flags.uv,
|
|
156
|
+
credentialDeviceType,
|
|
157
|
+
credentialBackedUp,
|
|
158
|
+
authenticatorExtensionResults: extensionsData,
|
|
159
|
+
origin: clientDataJSON.origin,
|
|
160
|
+
rpID: matchedRPID,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
return toReturn;
|
|
164
|
+
}
|
package/esm/deps.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { AttestationConveyancePreference, AuthenticationExtensionsClientInputs, AuthenticationResponseJSON, AuthenticatorDevice, AuthenticatorSelectionCriteria, Base64URLString, COSEAlgorithmIdentifier, CredentialDeviceType, Crypto, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialDescriptorFuture, PublicKeyCredentialParameters, PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON, UserVerificationRequirement, } from '@simplewebauthn/typescript-types';
|
|
2
|
+
export * as cborx from 'cbor-x';
|
|
3
|
+
export { fetch as crossFetch } from 'cross-fetch';
|
|
4
|
+
export { default as debug } from 'debug';
|
|
5
|
+
export type { Debugger } from '@types/debug';
|
|
6
|
+
export { AsnParser, AsnSerializer } from '@peculiar/asn1-schema';
|
|
7
|
+
export { AuthorityKeyIdentifier, BasicConstraints, Certificate, CertificateList, CRLDistributionPoints, ExtendedKeyUsage, id_ce_authorityKeyIdentifier, id_ce_basicConstraints, id_ce_cRLDistributionPoints, id_ce_extKeyUsage, id_ce_subjectAltName, id_ce_subjectKeyIdentifier, Name, SubjectAlternativeName, SubjectKeyIdentifier, } from '@peculiar/asn1-x509';
|
|
8
|
+
export { ECDSASigValue, ECParameters, id_ecPublicKey, id_secp256r1, id_secp384r1, } from '@peculiar/asn1-ecc';
|
|
9
|
+
export { RSAPublicKey } from '@peculiar/asn1-rsa';
|
|
10
|
+
export { id_ce_keyDescription, KeyDescription } from '@peculiar/asn1-android';
|
package/esm/deps.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// cbor (a.k.a. cbor-x in Node land)
|
|
2
|
+
export * as cborx from 'cbor-x';
|
|
3
|
+
// cross-fetch
|
|
4
|
+
export { fetch as crossFetch } from 'cross-fetch';
|
|
5
|
+
// debug
|
|
6
|
+
export { default as debug } from 'debug';
|
|
7
|
+
// @peculiar libraries
|
|
8
|
+
export { AsnParser, AsnSerializer } from '@peculiar/asn1-schema';
|
|
9
|
+
export { AuthorityKeyIdentifier, BasicConstraints, Certificate, CertificateList, CRLDistributionPoints, ExtendedKeyUsage, id_ce_authorityKeyIdentifier, id_ce_basicConstraints, id_ce_cRLDistributionPoints, id_ce_extKeyUsage, id_ce_subjectAltName, id_ce_subjectKeyIdentifier, Name, SubjectAlternativeName, SubjectKeyIdentifier, } from '@peculiar/asn1-x509';
|
|
10
|
+
export { ECDSASigValue, ECParameters, id_ecPublicKey, id_secp256r1, id_secp384r1, } from '@peculiar/asn1-ecc';
|
|
11
|
+
export { RSAPublicKey } from '@peculiar/asn1-rsa';
|
|
12
|
+
export { id_ce_keyDescription, KeyDescription } from '@peculiar/asn1-android';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isoUint8Array } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert the aaguid buffer in authData into a UUID string
|
|
4
|
+
*/
|
|
5
|
+
export function convertAAGUIDToString(aaguid) {
|
|
6
|
+
// Raw Hex: adce000235bcc60a648b0b25f1f05503
|
|
7
|
+
const hex = isoUint8Array.toHex(aaguid);
|
|
8
|
+
const segments = [
|
|
9
|
+
hex.slice(0, 8),
|
|
10
|
+
hex.slice(8, 12),
|
|
11
|
+
hex.slice(12, 16),
|
|
12
|
+
hex.slice(16, 20),
|
|
13
|
+
hex.slice(20, 32), // 8
|
|
14
|
+
];
|
|
15
|
+
// Formatted: adce0002-35bc-c60a-648b-0b25f1f05503
|
|
16
|
+
return segments.join('-');
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isoCBOR, isoUint8Array } from './iso/index.js';
|
|
2
|
+
import { COSEKEYS } from './cose.js';
|
|
3
|
+
/**
|
|
4
|
+
* Takes COSE-encoded public key and converts it to PKCS key
|
|
5
|
+
*/
|
|
6
|
+
export function convertCOSEtoPKCS(cosePublicKey) {
|
|
7
|
+
// This is a little sloppy, I'm using COSEPublicKeyEC2 since it could have both x and y, but when
|
|
8
|
+
// there's no y it means it's probably better typed as COSEPublicKeyOKP. I'll leave this for now
|
|
9
|
+
// and revisit it later if it ever becomes an actual problem.
|
|
10
|
+
const struct = isoCBOR.decodeFirst(cosePublicKey);
|
|
11
|
+
const tag = Uint8Array.from([0x04]);
|
|
12
|
+
const x = struct.get(COSEKEYS.x);
|
|
13
|
+
const y = struct.get(COSEKEYS.y);
|
|
14
|
+
if (!x) {
|
|
15
|
+
throw new Error('COSE public key was missing x');
|
|
16
|
+
}
|
|
17
|
+
if (y) {
|
|
18
|
+
return isoUint8Array.concat([tag, x, y]);
|
|
19
|
+
}
|
|
20
|
+
return isoUint8Array.concat([tag, x]);
|
|
21
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isoBase64URL } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert buffer to an OpenSSL-compatible PEM text format.
|
|
4
|
+
*/
|
|
5
|
+
export function convertCertBufferToPEM(certBuffer) {
|
|
6
|
+
let b64cert;
|
|
7
|
+
/**
|
|
8
|
+
* Get certBuffer to a base64 representation
|
|
9
|
+
*/
|
|
10
|
+
if (typeof certBuffer === 'string') {
|
|
11
|
+
if (isoBase64URL.isBase64url(certBuffer)) {
|
|
12
|
+
b64cert = isoBase64URL.toBase64(certBuffer);
|
|
13
|
+
}
|
|
14
|
+
else if (isoBase64URL.isBase64(certBuffer)) {
|
|
15
|
+
b64cert = certBuffer;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
throw new Error('Certificate is not a valid base64 or base64url string');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
b64cert = isoBase64URL.fromBuffer(certBuffer, 'base64');
|
|
23
|
+
}
|
|
24
|
+
let PEMKey = '';
|
|
25
|
+
for (let i = 0; i < Math.ceil(b64cert.length / 64); i += 1) {
|
|
26
|
+
const start = 64 * i;
|
|
27
|
+
PEMKey += `${b64cert.substr(start, 64)}\n`;
|
|
28
|
+
}
|
|
29
|
+
PEMKey = `-----BEGIN CERTIFICATE-----\n${PEMKey}-----END CERTIFICATE-----\n`;
|
|
30
|
+
return PEMKey;
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isoBase64URL } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Take a certificate in PEM format and convert it to bytes
|
|
4
|
+
*/
|
|
5
|
+
export function convertPEMToBytes(pem) {
|
|
6
|
+
const certBase64 = pem
|
|
7
|
+
.replace('-----BEGIN CERTIFICATE-----', '')
|
|
8
|
+
.replace('-----END CERTIFICATE-----', '')
|
|
9
|
+
.replace(/[\n ]/g, '');
|
|
10
|
+
return isoBase64URL.toBuffer(certBase64, 'base64');
|
|
11
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { COSEPublicKey } from './cose';
|
|
1
|
+
import { COSEPublicKey } from './cose.js';
|
|
2
2
|
export declare function convertX509PublicKeyToCOSE(x509Certificate: Uint8Array): COSEPublicKey;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { AsnParser, Certificate, ECParameters, id_ecPublicKey, id_secp256r1, id_secp384r1, RSAPublicKey, } from '../deps.js';
|
|
2
|
+
import { COSECRV, COSEKEYS, COSEKTY, } from './cose.js';
|
|
3
|
+
import { mapX509SignatureAlgToCOSEAlg } from './mapX509SignatureAlgToCOSEAlg.js';
|
|
4
|
+
export function convertX509PublicKeyToCOSE(x509Certificate) {
|
|
5
|
+
let cosePublicKey = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Time to extract the public key from an X.509 certificate
|
|
8
|
+
*/
|
|
9
|
+
const x509 = AsnParser.parse(x509Certificate, Certificate);
|
|
10
|
+
const { tbsCertificate } = x509;
|
|
11
|
+
const { subjectPublicKeyInfo, signature: _tbsSignature } = tbsCertificate;
|
|
12
|
+
const signatureAlgorithm = _tbsSignature.algorithm;
|
|
13
|
+
const publicKeyAlgorithmID = subjectPublicKeyInfo.algorithm.algorithm;
|
|
14
|
+
if (publicKeyAlgorithmID === id_ecPublicKey) {
|
|
15
|
+
/**
|
|
16
|
+
* EC2 Public Key
|
|
17
|
+
*/
|
|
18
|
+
if (!subjectPublicKeyInfo.algorithm.parameters) {
|
|
19
|
+
throw new Error('Certificate public key was missing parameters (EC2)');
|
|
20
|
+
}
|
|
21
|
+
const ecParameters = AsnParser.parse(new Uint8Array(subjectPublicKeyInfo.algorithm.parameters), ECParameters);
|
|
22
|
+
let crv = -999;
|
|
23
|
+
const { namedCurve } = ecParameters;
|
|
24
|
+
if (namedCurve === id_secp256r1) {
|
|
25
|
+
crv = COSECRV.P256;
|
|
26
|
+
}
|
|
27
|
+
else if (namedCurve === id_secp384r1) {
|
|
28
|
+
crv = COSECRV.P384;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new Error(`Certificate public key contained unexpected namedCurve ${namedCurve} (EC2)`);
|
|
32
|
+
}
|
|
33
|
+
const subjectPublicKey = new Uint8Array(subjectPublicKeyInfo.subjectPublicKey);
|
|
34
|
+
let x;
|
|
35
|
+
let y;
|
|
36
|
+
if (subjectPublicKey[0] === 0x04) {
|
|
37
|
+
// Public key is in "uncompressed form", so we can split the remaining bytes in half
|
|
38
|
+
let pointer = 1;
|
|
39
|
+
const halfLength = (subjectPublicKey.length - 1) / 2;
|
|
40
|
+
x = subjectPublicKey.slice(pointer, pointer += halfLength);
|
|
41
|
+
y = subjectPublicKey.slice(pointer);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new Error('TODO: Figure out how to handle public keys in "compressed form"');
|
|
45
|
+
}
|
|
46
|
+
const coseEC2PubKey = new Map();
|
|
47
|
+
coseEC2PubKey.set(COSEKEYS.kty, COSEKTY.EC2);
|
|
48
|
+
coseEC2PubKey.set(COSEKEYS.alg, mapX509SignatureAlgToCOSEAlg(signatureAlgorithm));
|
|
49
|
+
coseEC2PubKey.set(COSEKEYS.crv, crv);
|
|
50
|
+
coseEC2PubKey.set(COSEKEYS.x, x);
|
|
51
|
+
coseEC2PubKey.set(COSEKEYS.y, y);
|
|
52
|
+
cosePublicKey = coseEC2PubKey;
|
|
53
|
+
}
|
|
54
|
+
else if (publicKeyAlgorithmID === '1.2.840.113549.1.1.1') {
|
|
55
|
+
/**
|
|
56
|
+
* RSA public key
|
|
57
|
+
*/
|
|
58
|
+
const rsaPublicKey = AsnParser.parse(subjectPublicKeyInfo.subjectPublicKey, RSAPublicKey);
|
|
59
|
+
const coseRSAPubKey = new Map();
|
|
60
|
+
coseRSAPubKey.set(COSEKEYS.kty, COSEKTY.RSA);
|
|
61
|
+
coseRSAPubKey.set(COSEKEYS.alg, mapX509SignatureAlgToCOSEAlg(signatureAlgorithm));
|
|
62
|
+
coseRSAPubKey.set(COSEKEYS.n, new Uint8Array(rsaPublicKey.modulus));
|
|
63
|
+
coseRSAPubKey.set(COSEKEYS.e, new Uint8Array(rsaPublicKey.publicExponent));
|
|
64
|
+
cosePublicKey = coseRSAPubKey;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error(`Certificate public key contained unexpected algorithm ID ${publicKeyAlgorithmID}`);
|
|
68
|
+
}
|
|
69
|
+
return cosePublicKey;
|
|
70
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export function isCOSEPublicKeyOKP(cosePublicKey) {
|
|
2
|
+
const kty = cosePublicKey.get(COSEKEYS.kty);
|
|
3
|
+
return isCOSEKty(kty) && kty === COSEKTY.OKP;
|
|
4
|
+
}
|
|
5
|
+
export function isCOSEPublicKeyEC2(cosePublicKey) {
|
|
6
|
+
const kty = cosePublicKey.get(COSEKEYS.kty);
|
|
7
|
+
return isCOSEKty(kty) && kty === COSEKTY.EC2;
|
|
8
|
+
}
|
|
9
|
+
export function isCOSEPublicKeyRSA(cosePublicKey) {
|
|
10
|
+
const kty = cosePublicKey.get(COSEKEYS.kty);
|
|
11
|
+
return isCOSEKty(kty) && kty === COSEKTY.RSA;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* COSE Keys
|
|
15
|
+
*
|
|
16
|
+
* https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters
|
|
17
|
+
* https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
|
|
18
|
+
*/
|
|
19
|
+
export var COSEKEYS;
|
|
20
|
+
(function (COSEKEYS) {
|
|
21
|
+
COSEKEYS[COSEKEYS["kty"] = 1] = "kty";
|
|
22
|
+
COSEKEYS[COSEKEYS["alg"] = 3] = "alg";
|
|
23
|
+
COSEKEYS[COSEKEYS["crv"] = -1] = "crv";
|
|
24
|
+
COSEKEYS[COSEKEYS["x"] = -2] = "x";
|
|
25
|
+
COSEKEYS[COSEKEYS["y"] = -3] = "y";
|
|
26
|
+
COSEKEYS[COSEKEYS["n"] = -1] = "n";
|
|
27
|
+
COSEKEYS[COSEKEYS["e"] = -2] = "e";
|
|
28
|
+
})(COSEKEYS || (COSEKEYS = {}));
|
|
29
|
+
/**
|
|
30
|
+
* COSE Key Types
|
|
31
|
+
*
|
|
32
|
+
* https://www.iana.org/assignments/cose/cose.xhtml#key-type
|
|
33
|
+
*/
|
|
34
|
+
export var COSEKTY;
|
|
35
|
+
(function (COSEKTY) {
|
|
36
|
+
COSEKTY[COSEKTY["OKP"] = 1] = "OKP";
|
|
37
|
+
COSEKTY[COSEKTY["EC2"] = 2] = "EC2";
|
|
38
|
+
COSEKTY[COSEKTY["RSA"] = 3] = "RSA";
|
|
39
|
+
})(COSEKTY || (COSEKTY = {}));
|
|
40
|
+
export function isCOSEKty(kty) {
|
|
41
|
+
return Object.values(COSEKTY).indexOf(kty) >= 0;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* COSE Curves
|
|
45
|
+
*
|
|
46
|
+
* https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
|
|
47
|
+
*/
|
|
48
|
+
export var COSECRV;
|
|
49
|
+
(function (COSECRV) {
|
|
50
|
+
COSECRV[COSECRV["P256"] = 1] = "P256";
|
|
51
|
+
COSECRV[COSECRV["P384"] = 2] = "P384";
|
|
52
|
+
COSECRV[COSECRV["P521"] = 3] = "P521";
|
|
53
|
+
COSECRV[COSECRV["ED25519"] = 6] = "ED25519";
|
|
54
|
+
COSECRV[COSECRV["SECP256K1"] = 8] = "SECP256K1";
|
|
55
|
+
})(COSECRV || (COSECRV = {}));
|
|
56
|
+
export function isCOSECrv(crv) {
|
|
57
|
+
return Object.values(COSECRV).indexOf(crv) >= 0;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* COSE Algorithms
|
|
61
|
+
*
|
|
62
|
+
* https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
63
|
+
*/
|
|
64
|
+
export var COSEALG;
|
|
65
|
+
(function (COSEALG) {
|
|
66
|
+
COSEALG[COSEALG["ES256"] = -7] = "ES256";
|
|
67
|
+
COSEALG[COSEALG["EdDSA"] = -8] = "EdDSA";
|
|
68
|
+
COSEALG[COSEALG["ES384"] = -35] = "ES384";
|
|
69
|
+
COSEALG[COSEALG["ES512"] = -36] = "ES512";
|
|
70
|
+
COSEALG[COSEALG["PS256"] = -37] = "PS256";
|
|
71
|
+
COSEALG[COSEALG["PS384"] = -38] = "PS384";
|
|
72
|
+
COSEALG[COSEALG["PS512"] = -39] = "PS512";
|
|
73
|
+
COSEALG[COSEALG["ES256K"] = -47] = "ES256K";
|
|
74
|
+
COSEALG[COSEALG["RS256"] = -257] = "RS256";
|
|
75
|
+
COSEALG[COSEALG["RS384"] = -258] = "RS384";
|
|
76
|
+
COSEALG[COSEALG["RS512"] = -259] = "RS512";
|
|
77
|
+
COSEALG[COSEALG["RS1"] = -65535] = "RS1";
|
|
78
|
+
})(COSEALG || (COSEALG = {}));
|
|
79
|
+
export function isCOSEAlg(alg) {
|
|
80
|
+
return Object.values(COSEALG).indexOf(alg) >= 0;
|
|
81
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isoCBOR } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert an AttestationObject buffer to a proper object
|
|
4
|
+
*
|
|
5
|
+
* @param base64AttestationObject Attestation Object buffer
|
|
6
|
+
*/
|
|
7
|
+
export function decodeAttestationObject(attestationObject) {
|
|
8
|
+
return _decodeAttestationObjectInternals.stubThis(isoCBOR.decodeFirst(attestationObject));
|
|
9
|
+
}
|
|
10
|
+
// Make it possible to stub the return value during testing
|
|
11
|
+
export const _decodeAttestationObjectInternals = {
|
|
12
|
+
stubThis: (value) => value,
|
|
13
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isoCBOR } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert authenticator extension data buffer to a proper object
|
|
4
|
+
*
|
|
5
|
+
* @param extensionData Authenticator Extension Data buffer
|
|
6
|
+
*/
|
|
7
|
+
export function decodeAuthenticatorExtensions(extensionData) {
|
|
8
|
+
let toCBOR;
|
|
9
|
+
try {
|
|
10
|
+
toCBOR = isoCBOR.decodeFirst(extensionData);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
const _err = err;
|
|
14
|
+
throw new Error(`Error decoding authenticator extensions: ${_err.message}`);
|
|
15
|
+
}
|
|
16
|
+
return convertMapToObjectDeep(toCBOR);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* CBOR-encoded extensions can be deeply-nested Maps, which are too deep for a simple
|
|
20
|
+
* `Object.entries()`. This method will recursively make sure that all Maps are converted into
|
|
21
|
+
* basic objects.
|
|
22
|
+
*/
|
|
23
|
+
function convertMapToObjectDeep(input) {
|
|
24
|
+
const mapped = {};
|
|
25
|
+
for (const [key, value] of input) {
|
|
26
|
+
if (value instanceof Map) {
|
|
27
|
+
mapped[key] = convertMapToObjectDeep(value);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
mapped[key] = value;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return mapped;
|
|
34
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isoBase64URL } from './iso/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decode an authenticator's base64url-encoded clientDataJSON to JSON
|
|
4
|
+
*/
|
|
5
|
+
export function decodeClientDataJSON(data) {
|
|
6
|
+
const toString = isoBase64URL.toString(data);
|
|
7
|
+
const clientData = JSON.parse(toString);
|
|
8
|
+
return _decodeClientDataJSONInternals.stubThis(clientData);
|
|
9
|
+
}
|
|
10
|
+
// Make it possible to stub the return value during testing
|
|
11
|
+
export const _decodeClientDataJSONInternals = {
|
|
12
|
+
stubThis: (value) => value,
|
|
13
|
+
};
|