@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
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyAttestationAndroidSafetyNet = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
4
|
+
const toHash_js_1 = require("../../helpers/toHash.js");
|
|
5
|
+
const verifySignature_js_1 = require("../../helpers/verifySignature.js");
|
|
6
|
+
const getCertificateInfo_js_1 = require("../../helpers/getCertificateInfo.js");
|
|
7
|
+
const validateCertificatePath_js_1 = require("../../helpers/validateCertificatePath.js");
|
|
8
|
+
const convertCertBufferToPEM_js_1 = require("../../helpers/convertCertBufferToPEM.js");
|
|
9
|
+
const index_js_1 = require("../../helpers/iso/index.js");
|
|
10
|
+
const metadataService_js_1 = require("../../services/metadataService.js");
|
|
11
|
+
const verifyAttestationWithMetadata_js_1 = require("../../metadata/verifyAttestationWithMetadata.js");
|
|
12
12
|
/**
|
|
13
13
|
* Verify an attestation response with fmt 'android-safetynet'
|
|
14
14
|
*/
|
|
@@ -24,10 +24,10 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
24
24
|
throw new Error('No response was included in attStmt by authenticator (SafetyNet)');
|
|
25
25
|
}
|
|
26
26
|
// Prepare to verify a JWT
|
|
27
|
-
const jwt =
|
|
27
|
+
const jwt = index_js_1.isoUint8Array.toUTF8String(response);
|
|
28
28
|
const jwtParts = jwt.split('.');
|
|
29
|
-
const HEADER = JSON.parse(
|
|
30
|
-
const PAYLOAD = JSON.parse(
|
|
29
|
+
const HEADER = JSON.parse(index_js_1.isoBase64URL.toString(jwtParts[0]));
|
|
30
|
+
const PAYLOAD = JSON.parse(index_js_1.isoBase64URL.toString(jwtParts[1]));
|
|
31
31
|
const SIGNATURE = jwtParts[2];
|
|
32
32
|
/**
|
|
33
33
|
* START Verify PAYLOAD
|
|
@@ -46,9 +46,9 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
46
46
|
throw new Error(`Payload timestamp "${timestampPlusDelay}" has expired (SafetyNet)`);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
const nonceBase =
|
|
50
|
-
const nonceBuffer = await (0,
|
|
51
|
-
const expectedNonce =
|
|
49
|
+
const nonceBase = index_js_1.isoUint8Array.concat([authData, clientDataHash]);
|
|
50
|
+
const nonceBuffer = await (0, toHash_js_1.toHash)(nonceBase);
|
|
51
|
+
const expectedNonce = index_js_1.isoBase64URL.fromBuffer(nonceBuffer, 'base64');
|
|
52
52
|
if (nonce !== expectedNonce) {
|
|
53
53
|
throw new Error('Could not verify payload nonce (SafetyNet)');
|
|
54
54
|
}
|
|
@@ -62,18 +62,18 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
62
62
|
* START Verify Header
|
|
63
63
|
*/
|
|
64
64
|
// `HEADER.x5c[0]` is definitely a base64 string
|
|
65
|
-
const leafCertBuffer =
|
|
66
|
-
const leafCertInfo = (0,
|
|
65
|
+
const leafCertBuffer = index_js_1.isoBase64URL.toBuffer(HEADER.x5c[0], 'base64');
|
|
66
|
+
const leafCertInfo = (0, getCertificateInfo_js_1.getCertificateInfo)(leafCertBuffer);
|
|
67
67
|
const { subject } = leafCertInfo;
|
|
68
68
|
// Ensure the certificate was issued to this hostname
|
|
69
69
|
// See https://developer.android.com/training/safetynet/attestation#verify-attestation-response
|
|
70
70
|
if (subject.CN !== 'attest.android.com') {
|
|
71
71
|
throw new Error('Certificate common name was not "attest.android.com" (SafetyNet)');
|
|
72
72
|
}
|
|
73
|
-
const statement = await
|
|
73
|
+
const statement = await metadataService_js_1.MetadataService.getStatement(aaguid);
|
|
74
74
|
if (statement) {
|
|
75
75
|
try {
|
|
76
|
-
await (0,
|
|
76
|
+
await (0, verifyAttestationWithMetadata_js_1.verifyAttestationWithMetadata)({
|
|
77
77
|
statement,
|
|
78
78
|
credentialPublicKey,
|
|
79
79
|
x5c: HEADER.x5c,
|
|
@@ -88,7 +88,7 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
88
88
|
else {
|
|
89
89
|
try {
|
|
90
90
|
// Try validating the certificate path using the root certificates set via SettingsService
|
|
91
|
-
await (0,
|
|
91
|
+
await (0, validateCertificatePath_js_1.validateCertificatePath)(HEADER.x5c.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM), rootCertificates);
|
|
92
92
|
}
|
|
93
93
|
catch (err) {
|
|
94
94
|
const _err = err;
|
|
@@ -101,9 +101,9 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
101
101
|
/**
|
|
102
102
|
* START Verify Signature
|
|
103
103
|
*/
|
|
104
|
-
const signatureBaseBuffer =
|
|
105
|
-
const signatureBuffer =
|
|
106
|
-
const verified = await (0,
|
|
104
|
+
const signatureBaseBuffer = index_js_1.isoUint8Array.fromUTF8String(`${jwtParts[0]}.${jwtParts[1]}`);
|
|
105
|
+
const signatureBuffer = index_js_1.isoBase64URL.toBuffer(SIGNATURE);
|
|
106
|
+
const verified = await (0, verifySignature_js_1.verifySignature)({
|
|
107
107
|
signature: signatureBuffer,
|
|
108
108
|
data: signatureBaseBuffer,
|
|
109
109
|
x509Certificate: leafCertBuffer,
|
|
@@ -114,4 +114,3 @@ async function verifyAttestationAndroidSafetyNet(options) {
|
|
|
114
114
|
return verified;
|
|
115
115
|
}
|
|
116
116
|
exports.verifyAttestationAndroidSafetyNet = verifyAttestationAndroidSafetyNet;
|
|
117
|
-
//# sourceMappingURL=verifyAttestationAndroidSafetyNet.js.map
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyAttestationApple = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const iso_1 = require("../../helpers/iso");
|
|
4
|
+
const deps_js_1 = require("../../deps.js");
|
|
5
|
+
const validateCertificatePath_js_1 = require("../../helpers/validateCertificatePath.js");
|
|
6
|
+
const convertCertBufferToPEM_js_1 = require("../../helpers/convertCertBufferToPEM.js");
|
|
7
|
+
const toHash_js_1 = require("../../helpers/toHash.js");
|
|
8
|
+
const convertCOSEtoPKCS_js_1 = require("../../helpers/convertCOSEtoPKCS.js");
|
|
9
|
+
const index_js_1 = require("../../helpers/iso/index.js");
|
|
11
10
|
async function verifyAttestationApple(options) {
|
|
12
|
-
const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates } = options;
|
|
11
|
+
const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates, } = options;
|
|
13
12
|
const x5c = attStmt.get('x5c');
|
|
14
13
|
if (!x5c) {
|
|
15
14
|
throw new Error('No attestation certificate provided in attestation statement (Apple)');
|
|
@@ -18,7 +17,7 @@ async function verifyAttestationApple(options) {
|
|
|
18
17
|
* Verify certificate path
|
|
19
18
|
*/
|
|
20
19
|
try {
|
|
21
|
-
await (0,
|
|
20
|
+
await (0, validateCertificatePath_js_1.validateCertificatePath)(x5c.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM), rootCertificates);
|
|
22
21
|
}
|
|
23
22
|
catch (err) {
|
|
24
23
|
const _err = err;
|
|
@@ -27,17 +26,17 @@ async function verifyAttestationApple(options) {
|
|
|
27
26
|
/**
|
|
28
27
|
* Compare nonce in certificate extension to computed nonce
|
|
29
28
|
*/
|
|
30
|
-
const parsedCredCert =
|
|
29
|
+
const parsedCredCert = deps_js_1.AsnParser.parse(x5c[0], deps_js_1.Certificate);
|
|
31
30
|
const { extensions, subjectPublicKeyInfo } = parsedCredCert.tbsCertificate;
|
|
32
31
|
if (!extensions) {
|
|
33
32
|
throw new Error('credCert missing extensions (Apple)');
|
|
34
33
|
}
|
|
35
|
-
const extCertNonce = extensions.find(ext => ext.extnID === '1.2.840.113635.100.8.2');
|
|
34
|
+
const extCertNonce = extensions.find((ext) => ext.extnID === '1.2.840.113635.100.8.2');
|
|
36
35
|
if (!extCertNonce) {
|
|
37
36
|
throw new Error('credCert missing "1.2.840.113635.100.8.2" extension (Apple)');
|
|
38
37
|
}
|
|
39
|
-
const nonceToHash =
|
|
40
|
-
const nonce = await (0,
|
|
38
|
+
const nonceToHash = index_js_1.isoUint8Array.concat([authData, clientDataHash]);
|
|
39
|
+
const nonce = await (0, toHash_js_1.toHash)(nonceToHash);
|
|
41
40
|
/**
|
|
42
41
|
* Ignore the first six ASN.1 structure bytes that define the nonce as an OCTET STRING. Should
|
|
43
42
|
* trim off <Buffer 30 24 a1 22 04 20>
|
|
@@ -46,18 +45,17 @@ async function verifyAttestationApple(options) {
|
|
|
46
45
|
* find out where it's defined (doesn't seem to be publicly documented at the moment...)
|
|
47
46
|
*/
|
|
48
47
|
const extNonce = new Uint8Array(extCertNonce.extnValue.buffer).slice(6);
|
|
49
|
-
if (!
|
|
48
|
+
if (!index_js_1.isoUint8Array.areEqual(nonce, extNonce)) {
|
|
50
49
|
throw new Error(`credCert nonce was not expected value (Apple)`);
|
|
51
50
|
}
|
|
52
51
|
/**
|
|
53
52
|
* Verify credential public key matches the Subject Public Key of credCert
|
|
54
53
|
*/
|
|
55
|
-
const credPubKeyPKCS = (0,
|
|
54
|
+
const credPubKeyPKCS = (0, convertCOSEtoPKCS_js_1.convertCOSEtoPKCS)(credentialPublicKey);
|
|
56
55
|
const credCertSubjectPublicKey = new Uint8Array(subjectPublicKeyInfo.subjectPublicKey);
|
|
57
|
-
if (!
|
|
56
|
+
if (!index_js_1.isoUint8Array.areEqual(credPubKeyPKCS, credCertSubjectPublicKey)) {
|
|
58
57
|
throw new Error('Credential public key does not equal credCert public key (Apple)');
|
|
59
58
|
}
|
|
60
59
|
return true;
|
|
61
60
|
}
|
|
62
61
|
exports.verifyAttestationApple = verifyAttestationApple;
|
|
63
|
-
//# sourceMappingURL=verifyAttestationApple.js.map
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyAttestationFIDOU2F = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
4
|
+
const convertCOSEtoPKCS_js_1 = require("../../helpers/convertCOSEtoPKCS.js");
|
|
5
|
+
const convertCertBufferToPEM_js_1 = require("../../helpers/convertCertBufferToPEM.js");
|
|
6
|
+
const validateCertificatePath_js_1 = require("../../helpers/validateCertificatePath.js");
|
|
7
|
+
const verifySignature_js_1 = require("../../helpers/verifySignature.js");
|
|
8
|
+
const index_js_1 = require("../../helpers/iso/index.js");
|
|
9
|
+
const cose_js_1 = require("../../helpers/cose.js");
|
|
10
10
|
/**
|
|
11
11
|
* Verify an attestation response with fmt 'fido-u2f'
|
|
12
12
|
*/
|
|
13
13
|
async function verifyAttestationFIDOU2F(options) {
|
|
14
14
|
const { attStmt, clientDataHash, rpIdHash, credentialID, credentialPublicKey, aaguid, rootCertificates, } = options;
|
|
15
15
|
const reservedByte = Uint8Array.from([0x00]);
|
|
16
|
-
const publicKey = (0,
|
|
17
|
-
const signatureBase =
|
|
16
|
+
const publicKey = (0, convertCOSEtoPKCS_js_1.convertCOSEtoPKCS)(credentialPublicKey);
|
|
17
|
+
const signatureBase = index_js_1.isoUint8Array.concat([
|
|
18
18
|
reservedByte,
|
|
19
19
|
rpIdHash,
|
|
20
20
|
clientDataHash,
|
|
@@ -30,24 +30,23 @@ async function verifyAttestationFIDOU2F(options) {
|
|
|
30
30
|
throw new Error('No attestation signature provided in attestation statement (FIDOU2F)');
|
|
31
31
|
}
|
|
32
32
|
// FIDO spec says that aaguid _must_ equal 0x00 here to be legit
|
|
33
|
-
const aaguidToHex = Number.parseInt(
|
|
33
|
+
const aaguidToHex = Number.parseInt(index_js_1.isoUint8Array.toHex(aaguid), 16);
|
|
34
34
|
if (aaguidToHex !== 0x00) {
|
|
35
35
|
throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
|
|
36
36
|
}
|
|
37
37
|
try {
|
|
38
38
|
// Try validating the certificate path using the root certificates set via SettingsService
|
|
39
|
-
await (0,
|
|
39
|
+
await (0, validateCertificatePath_js_1.validateCertificatePath)(x5c.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM), rootCertificates);
|
|
40
40
|
}
|
|
41
41
|
catch (err) {
|
|
42
42
|
const _err = err;
|
|
43
43
|
throw new Error(`${_err.message} (FIDOU2F)`);
|
|
44
44
|
}
|
|
45
|
-
return (0,
|
|
45
|
+
return (0, verifySignature_js_1.verifySignature)({
|
|
46
46
|
signature: sig,
|
|
47
47
|
data: signatureBase,
|
|
48
48
|
x509Certificate: x5c[0],
|
|
49
|
-
hashAlgorithm:
|
|
49
|
+
hashAlgorithm: cose_js_1.COSEALG.ES256,
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
exports.verifyAttestationFIDOU2F = verifyAttestationFIDOU2F;
|
|
53
|
-
//# sourceMappingURL=verifyAttestationFIDOU2F.js.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyAttestationPacked = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
4
|
+
const cose_js_1 = require("../../helpers/cose.js");
|
|
5
|
+
const convertCertBufferToPEM_js_1 = require("../../helpers/convertCertBufferToPEM.js");
|
|
6
|
+
const validateCertificatePath_js_1 = require("../../helpers/validateCertificatePath.js");
|
|
7
|
+
const getCertificateInfo_js_1 = require("../../helpers/getCertificateInfo.js");
|
|
8
|
+
const verifySignature_js_1 = require("../../helpers/verifySignature.js");
|
|
9
|
+
const index_js_1 = require("../../helpers/iso/index.js");
|
|
10
|
+
const metadataService_js_1 = require("../../services/metadataService.js");
|
|
11
|
+
const verifyAttestationWithMetadata_js_1 = require("../../metadata/verifyAttestationWithMetadata.js");
|
|
12
12
|
/**
|
|
13
13
|
* Verify an attestation response with fmt 'packed'
|
|
14
14
|
*/
|
|
15
15
|
async function verifyAttestationPacked(options) {
|
|
16
|
-
const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid, rootCertificates } = options;
|
|
16
|
+
const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid, rootCertificates, } = options;
|
|
17
17
|
const sig = attStmt.get('sig');
|
|
18
18
|
const x5c = attStmt.get('x5c');
|
|
19
19
|
const alg = attStmt.get('alg');
|
|
@@ -23,13 +23,13 @@ async function verifyAttestationPacked(options) {
|
|
|
23
23
|
if (!alg) {
|
|
24
24
|
throw new Error('Attestation statement did not contain alg (Packed)');
|
|
25
25
|
}
|
|
26
|
-
if (!(0,
|
|
26
|
+
if (!(0, cose_js_1.isCOSEAlg)(alg)) {
|
|
27
27
|
throw new Error(`Attestation statement contained invalid alg ${alg} (Packed)`);
|
|
28
28
|
}
|
|
29
|
-
const signatureBase =
|
|
29
|
+
const signatureBase = index_js_1.isoUint8Array.concat([authData, clientDataHash]);
|
|
30
30
|
let verified = false;
|
|
31
31
|
if (x5c) {
|
|
32
|
-
const { subject, basicConstraintsCA, version, notBefore, notAfter } = (0,
|
|
32
|
+
const { subject, basicConstraintsCA, version, notBefore, notAfter } = (0, getCertificateInfo_js_1.getCertificateInfo)(x5c[0]);
|
|
33
33
|
const { OU, CN, O, C } = subject;
|
|
34
34
|
if (OU !== 'Authenticator Attestation') {
|
|
35
35
|
throw new Error('Certificate OU was not "Authenticator Attestation" (Packed|Full)');
|
|
@@ -60,7 +60,7 @@ async function verifyAttestationPacked(options) {
|
|
|
60
60
|
// TODO: If certificate contains id-fido-gen-ce-aaguid(1.3.6.1.4.1.45724.1.1.4) extension, check
|
|
61
61
|
// that it’s value is set to the same AAGUID as in authData.
|
|
62
62
|
// If available, validate attestation alg and x5c with info in the metadata statement
|
|
63
|
-
const statement = await
|
|
63
|
+
const statement = await metadataService_js_1.MetadataService.getStatement(aaguid);
|
|
64
64
|
if (statement) {
|
|
65
65
|
// The presence of x5c means this is a full attestation. Check to see if attestationTypes
|
|
66
66
|
// includes packed attestations.
|
|
@@ -68,7 +68,7 @@ async function verifyAttestationPacked(options) {
|
|
|
68
68
|
throw new Error('Metadata does not indicate support for full attestations (Packed|Full)');
|
|
69
69
|
}
|
|
70
70
|
try {
|
|
71
|
-
await (0,
|
|
71
|
+
await (0, verifyAttestationWithMetadata_js_1.verifyAttestationWithMetadata)({
|
|
72
72
|
statement,
|
|
73
73
|
credentialPublicKey,
|
|
74
74
|
x5c,
|
|
@@ -83,21 +83,21 @@ async function verifyAttestationPacked(options) {
|
|
|
83
83
|
else {
|
|
84
84
|
try {
|
|
85
85
|
// Try validating the certificate path using the root certificates set via SettingsService
|
|
86
|
-
await (0,
|
|
86
|
+
await (0, validateCertificatePath_js_1.validateCertificatePath)(x5c.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM), rootCertificates);
|
|
87
87
|
}
|
|
88
88
|
catch (err) {
|
|
89
89
|
const _err = err;
|
|
90
90
|
throw new Error(`${_err.message} (Packed|Full)`);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
verified = await (0,
|
|
93
|
+
verified = await (0, verifySignature_js_1.verifySignature)({
|
|
94
94
|
signature: sig,
|
|
95
95
|
data: signatureBase,
|
|
96
96
|
x509Certificate: x5c[0],
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
|
-
verified = await (0,
|
|
100
|
+
verified = await (0, verifySignature_js_1.verifySignature)({
|
|
101
101
|
signature: sig,
|
|
102
102
|
data: signatureBase,
|
|
103
103
|
credentialPublicKey,
|
|
@@ -107,4 +107,3 @@ async function verifyAttestationPacked(options) {
|
|
|
107
107
|
return verified;
|
|
108
108
|
}
|
|
109
109
|
exports.verifyAttestationPacked = verifyAttestationPacked;
|
|
110
|
-
//# sourceMappingURL=verifyAttestationPacked.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { COSEAlgorithmIdentifier, CredentialDeviceType, RegistrationResponseJSON } from '../deps.js';
|
|
2
|
+
import { AttestationFormat, AttestationStatement } from '../helpers/decodeAttestationObject.js';
|
|
3
|
+
import { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions.js';
|
|
4
|
+
export type VerifyRegistrationResponseOpts = {
|
|
5
|
+
response: RegistrationResponseJSON;
|
|
6
|
+
expectedChallenge: string | ((challenge: string) => boolean);
|
|
7
|
+
expectedOrigin: string | string[];
|
|
8
|
+
expectedRPID?: string | string[];
|
|
9
|
+
requireUserVerification?: boolean;
|
|
10
|
+
supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Verify that the user has legitimately completed the registration process
|
|
14
|
+
*
|
|
15
|
+
* **Options:**
|
|
16
|
+
*
|
|
17
|
+
* @param response Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
|
|
18
|
+
* @param expectedChallenge The base64url-encoded `options.challenge` returned by
|
|
19
|
+
* `generateRegistrationOptions()`
|
|
20
|
+
* @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
|
|
21
|
+
* @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
|
|
22
|
+
* @param requireUserVerification (Optional) Enforce user verification by the authenticator
|
|
23
|
+
* (via PIN, fingerprint, etc...)
|
|
24
|
+
* @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
|
|
25
|
+
* attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifyRegistrationResponse(options: VerifyRegistrationResponseOpts): Promise<VerifiedRegistrationResponse>;
|
|
28
|
+
/**
|
|
29
|
+
* Result of registration verification
|
|
30
|
+
*
|
|
31
|
+
* @param verified If the assertion response could be verified
|
|
32
|
+
* @param registrationInfo.fmt Type of attestation
|
|
33
|
+
* @param registrationInfo.counter The number of times the authenticator reported it has been used.
|
|
34
|
+
* **Should be kept in a DB for later reference to help prevent replay attacks!**
|
|
35
|
+
* @param registrationInfo.aaguid Authenticator's Attestation GUID indicating the type of the
|
|
36
|
+
* authenticator
|
|
37
|
+
* @param registrationInfo.credentialPublicKey The credential's public key
|
|
38
|
+
* @param registrationInfo.credentialID The credential's credential ID for the public key above
|
|
39
|
+
* @param registrationInfo.credentialType The type of the credential returned by the browser
|
|
40
|
+
* @param registrationInfo.userVerified Whether the user was uniquely identified during attestation
|
|
41
|
+
* @param registrationInfo.attestationObject The raw `response.attestationObject` Buffer returned by
|
|
42
|
+
* the authenticator
|
|
43
|
+
* @param registrationInfo.credentialDeviceType Whether this is a single-device or multi-device
|
|
44
|
+
* credential. **Should be kept in a DB for later reference!**
|
|
45
|
+
* @param registrationInfo.credentialBackedUp Whether or not the multi-device credential has been
|
|
46
|
+
* backed up. Always `false` for single-device credentials. **Should be kept in a DB for later
|
|
47
|
+
* reference!**
|
|
48
|
+
* @param registrationInfo.origin The origin of the website that the registration occurred on
|
|
49
|
+
* @param registrationInfo?.rpID The RP ID that the registration occurred on, if one or more were
|
|
50
|
+
* specified in the registration options
|
|
51
|
+
* @param registrationInfo?.authenticatorExtensionResults The authenticator extensions returned
|
|
52
|
+
* by the browser
|
|
53
|
+
*/
|
|
54
|
+
export type VerifiedRegistrationResponse = {
|
|
55
|
+
verified: boolean;
|
|
56
|
+
registrationInfo?: {
|
|
57
|
+
fmt: AttestationFormat;
|
|
58
|
+
counter: number;
|
|
59
|
+
aaguid: string;
|
|
60
|
+
credentialID: Uint8Array;
|
|
61
|
+
credentialPublicKey: Uint8Array;
|
|
62
|
+
credentialType: 'public-key';
|
|
63
|
+
attestationObject: Uint8Array;
|
|
64
|
+
userVerified: boolean;
|
|
65
|
+
credentialDeviceType: CredentialDeviceType;
|
|
66
|
+
credentialBackedUp: boolean;
|
|
67
|
+
origin: string;
|
|
68
|
+
rpID?: string;
|
|
69
|
+
authenticatorExtensionResults?: AuthenticationExtensionsAuthenticatorOutputs;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Values passed to all attestation format verifiers, from which they are free to use as they please
|
|
74
|
+
*/
|
|
75
|
+
export type AttestationFormatVerifierOpts = {
|
|
76
|
+
aaguid: Uint8Array;
|
|
77
|
+
attStmt: AttestationStatement;
|
|
78
|
+
authData: Uint8Array;
|
|
79
|
+
clientDataHash: Uint8Array;
|
|
80
|
+
credentialID: Uint8Array;
|
|
81
|
+
credentialPublicKey: Uint8Array;
|
|
82
|
+
rootCertificates: string[];
|
|
83
|
+
rpIdHash: Uint8Array;
|
|
84
|
+
verifyTimestampMS?: boolean;
|
|
85
|
+
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyRegistrationResponse = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
4
|
+
const decodeAttestationObject_js_1 = require("../helpers/decodeAttestationObject.js");
|
|
5
|
+
const decodeClientDataJSON_js_1 = require("../helpers/decodeClientDataJSON.js");
|
|
6
|
+
const parseAuthenticatorData_js_1 = require("../helpers/parseAuthenticatorData.js");
|
|
7
|
+
const toHash_js_1 = require("../helpers/toHash.js");
|
|
8
|
+
const decodeCredentialPublicKey_js_1 = require("../helpers/decodeCredentialPublicKey.js");
|
|
9
|
+
const cose_js_1 = require("../helpers/cose.js");
|
|
10
|
+
const convertAAGUIDToString_js_1 = require("../helpers/convertAAGUIDToString.js");
|
|
11
|
+
const parseBackupFlags_js_1 = require("../helpers/parseBackupFlags.js");
|
|
12
|
+
const matchExpectedRPID_js_1 = require("../helpers/matchExpectedRPID.js");
|
|
13
|
+
const index_js_1 = require("../helpers/iso/index.js");
|
|
14
|
+
const settingsService_js_1 = require("../services/settingsService.js");
|
|
15
|
+
const generateRegistrationOptions_js_1 = require("./generateRegistrationOptions.js");
|
|
16
|
+
const verifyAttestationFIDOU2F_js_1 = require("./verifications/verifyAttestationFIDOU2F.js");
|
|
17
|
+
const verifyAttestationPacked_js_1 = require("./verifications/verifyAttestationPacked.js");
|
|
18
|
+
const verifyAttestationAndroidSafetyNet_js_1 = require("./verifications/verifyAttestationAndroidSafetyNet.js");
|
|
19
|
+
const verifyAttestationTPM_js_1 = require("./verifications/tpm/verifyAttestationTPM.js");
|
|
20
|
+
const verifyAttestationAndroidKey_js_1 = require("./verifications/verifyAttestationAndroidKey.js");
|
|
21
|
+
const verifyAttestationApple_js_1 = require("./verifications/verifyAttestationApple.js");
|
|
22
22
|
/**
|
|
23
23
|
* Verify that the user has legitimately completed the registration process
|
|
24
24
|
*
|
|
@@ -35,7 +35,7 @@ const verifyAttestationApple_1 = require("./verifications/verifyAttestationApple
|
|
|
35
35
|
* attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
36
36
|
*/
|
|
37
37
|
async function verifyRegistrationResponse(options) {
|
|
38
|
-
const { response, expectedChallenge, expectedOrigin, expectedRPID, requireUserVerification = true, supportedAlgorithmIDs =
|
|
38
|
+
const { response, expectedChallenge, expectedOrigin, expectedRPID, requireUserVerification = true, supportedAlgorithmIDs = generateRegistrationOptions_js_1.supportedCOSEAlgorithmIdentifiers, } = options;
|
|
39
39
|
const { id, rawId, type: credentialType, response: attestationResponse } = response;
|
|
40
40
|
// Ensure credential specified an ID
|
|
41
41
|
if (!id) {
|
|
@@ -49,7 +49,7 @@ async function verifyRegistrationResponse(options) {
|
|
|
49
49
|
if (credentialType !== 'public-key') {
|
|
50
50
|
throw new Error(`Unexpected credential type ${credentialType}, expected "public-key"`);
|
|
51
51
|
}
|
|
52
|
-
const clientDataJSON = (0,
|
|
52
|
+
const clientDataJSON = (0, decodeClientDataJSON_js_1.decodeClientDataJSON)(attestationResponse.clientDataJSON);
|
|
53
53
|
const { type, origin, challenge, tokenBinding } = clientDataJSON;
|
|
54
54
|
// Make sure we're handling an registration
|
|
55
55
|
if (type !== 'webauthn.create') {
|
|
@@ -83,13 +83,13 @@ async function verifyRegistrationResponse(options) {
|
|
|
83
83
|
throw new Error(`Unexpected tokenBinding.status value of "${tokenBinding.status}"`);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
const attestationObject =
|
|
87
|
-
const decodedAttestationObject = (0,
|
|
86
|
+
const attestationObject = index_js_1.isoBase64URL.toBuffer(attestationResponse.attestationObject);
|
|
87
|
+
const decodedAttestationObject = (0, decodeAttestationObject_js_1.decodeAttestationObject)(attestationObject);
|
|
88
88
|
const fmt = decodedAttestationObject.get('fmt');
|
|
89
89
|
const authData = decodedAttestationObject.get('authData');
|
|
90
90
|
const attStmt = decodedAttestationObject.get('attStmt');
|
|
91
|
-
const parsedAuthData = (0,
|
|
92
|
-
const { aaguid, rpIdHash, flags, credentialID, counter, credentialPublicKey, extensionsData } = parsedAuthData;
|
|
91
|
+
const parsedAuthData = (0, parseAuthenticatorData_js_1.parseAuthenticatorData)(authData);
|
|
92
|
+
const { aaguid, rpIdHash, flags, credentialID, counter, credentialPublicKey, extensionsData, } = parsedAuthData;
|
|
93
93
|
// Make sure the response's RP ID is ours
|
|
94
94
|
let matchedRPID;
|
|
95
95
|
if (expectedRPID) {
|
|
@@ -100,7 +100,7 @@ async function verifyRegistrationResponse(options) {
|
|
|
100
100
|
else {
|
|
101
101
|
expectedRPIDs = expectedRPID;
|
|
102
102
|
}
|
|
103
|
-
matchedRPID = await (0,
|
|
103
|
+
matchedRPID = await (0, matchExpectedRPID_js_1.matchExpectedRPID)(rpIdHash, expectedRPIDs);
|
|
104
104
|
}
|
|
105
105
|
// Make sure someone was physically present
|
|
106
106
|
if (!flags.up) {
|
|
@@ -119,8 +119,8 @@ async function verifyRegistrationResponse(options) {
|
|
|
119
119
|
if (!aaguid) {
|
|
120
120
|
throw new Error('No AAGUID was present during registration');
|
|
121
121
|
}
|
|
122
|
-
const decodedPublicKey = (0,
|
|
123
|
-
const alg = decodedPublicKey.get(
|
|
122
|
+
const decodedPublicKey = (0, decodeCredentialPublicKey_js_1.decodeCredentialPublicKey)(credentialPublicKey);
|
|
123
|
+
const alg = decodedPublicKey.get(cose_js_1.COSEKEYS.alg);
|
|
124
124
|
if (typeof alg !== 'number') {
|
|
125
125
|
throw new Error('Credential public key was missing numeric alg');
|
|
126
126
|
}
|
|
@@ -129,8 +129,10 @@ async function verifyRegistrationResponse(options) {
|
|
|
129
129
|
const supported = supportedAlgorithmIDs.join(', ');
|
|
130
130
|
throw new Error(`Unexpected public key alg "${alg}", expected one of "${supported}"`);
|
|
131
131
|
}
|
|
132
|
-
const clientDataHash = await (0,
|
|
133
|
-
const rootCertificates =
|
|
132
|
+
const clientDataHash = await (0, toHash_js_1.toHash)(index_js_1.isoBase64URL.toBuffer(attestationResponse.clientDataJSON));
|
|
133
|
+
const rootCertificates = settingsService_js_1.SettingsService.getRootCertificates({
|
|
134
|
+
identifier: fmt,
|
|
135
|
+
});
|
|
134
136
|
// Prepare arguments to pass to the relevant verification method
|
|
135
137
|
const verifierOpts = {
|
|
136
138
|
aaguid,
|
|
@@ -147,22 +149,22 @@ async function verifyRegistrationResponse(options) {
|
|
|
147
149
|
*/
|
|
148
150
|
let verified = false;
|
|
149
151
|
if (fmt === 'fido-u2f') {
|
|
150
|
-
verified = await (0,
|
|
152
|
+
verified = await (0, verifyAttestationFIDOU2F_js_1.verifyAttestationFIDOU2F)(verifierOpts);
|
|
151
153
|
}
|
|
152
154
|
else if (fmt === 'packed') {
|
|
153
|
-
verified = await (0,
|
|
155
|
+
verified = await (0, verifyAttestationPacked_js_1.verifyAttestationPacked)(verifierOpts);
|
|
154
156
|
}
|
|
155
157
|
else if (fmt === 'android-safetynet') {
|
|
156
|
-
verified = await (0,
|
|
158
|
+
verified = await (0, verifyAttestationAndroidSafetyNet_js_1.verifyAttestationAndroidSafetyNet)(verifierOpts);
|
|
157
159
|
}
|
|
158
160
|
else if (fmt === 'android-key') {
|
|
159
|
-
verified = await (0,
|
|
161
|
+
verified = await (0, verifyAttestationAndroidKey_js_1.verifyAttestationAndroidKey)(verifierOpts);
|
|
160
162
|
}
|
|
161
163
|
else if (fmt === 'tpm') {
|
|
162
|
-
verified = await (0,
|
|
164
|
+
verified = await (0, verifyAttestationTPM_js_1.verifyAttestationTPM)(verifierOpts);
|
|
163
165
|
}
|
|
164
166
|
else if (fmt === 'apple') {
|
|
165
|
-
verified = await (0,
|
|
167
|
+
verified = await (0, verifyAttestationApple_js_1.verifyAttestationApple)(verifierOpts);
|
|
166
168
|
}
|
|
167
169
|
else if (fmt === 'none') {
|
|
168
170
|
if (attStmt.size > 0) {
|
|
@@ -178,11 +180,11 @@ async function verifyRegistrationResponse(options) {
|
|
|
178
180
|
verified,
|
|
179
181
|
};
|
|
180
182
|
if (toReturn.verified) {
|
|
181
|
-
const { credentialDeviceType, credentialBackedUp } = (0,
|
|
183
|
+
const { credentialDeviceType, credentialBackedUp } = (0, parseBackupFlags_js_1.parseBackupFlags)(flags);
|
|
182
184
|
toReturn.registrationInfo = {
|
|
183
185
|
fmt,
|
|
184
186
|
counter,
|
|
185
|
-
aaguid: (0,
|
|
187
|
+
aaguid: (0, convertAAGUIDToString_js_1.convertAAGUIDToString)(aaguid),
|
|
186
188
|
credentialID,
|
|
187
189
|
credentialPublicKey,
|
|
188
190
|
credentialType,
|
|
@@ -198,4 +200,3 @@ async function verifyRegistrationResponse(options) {
|
|
|
198
200
|
return toReturn;
|
|
199
201
|
}
|
|
200
202
|
exports.verifyRegistrationResponse = verifyRegistrationResponse;
|
|
201
|
-
//# sourceMappingURL=verifyRegistrationResponse.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Hardware Attestation Root 1
|
|
3
|
+
*
|
|
4
|
+
* Downloaded from https://developer.android.com/training/articles/security-key-attestation#root_certificate
|
|
5
|
+
* (first entry)
|
|
6
|
+
*
|
|
7
|
+
* Valid until 2026-05-24 @ 09:28 PST
|
|
8
|
+
*
|
|
9
|
+
* SHA256 Fingerprint
|
|
10
|
+
* C1:98:4A:3E:F4:5C:1E:2A:91:85:51:DE:10:60:3C:86:F7:05:1B:22:49:C4:89:1C:AE:32:30:EA:BD:0C:97:D5
|
|
11
|
+
*/
|
|
12
|
+
export declare const Google_Hardware_Attestation_Root_1 = "-----BEGIN CERTIFICATE-----\nMIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\nBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy\nODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS\nSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7\ntv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj\nnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq\nC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ\noVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O\nJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg\nsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi\nigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M\nRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E\naDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um\nAGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD\nVR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO\nBgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk\nLmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD\nggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB\nPb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m\nqC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY\nDBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm\nQUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u\nJU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD\nCdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy\nZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD\nqwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic\nMDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1\nwDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk\n-----END CERTIFICATE-----\n";
|
|
13
|
+
/**
|
|
14
|
+
* Google Hardware Attestation Root 2
|
|
15
|
+
*
|
|
16
|
+
* Downloaded from https://developer.android.com/training/articles/security-key-attestation#root_certificate
|
|
17
|
+
* (second entry)
|
|
18
|
+
*
|
|
19
|
+
* Valid until 2034-11-18 @ 12:37 PST
|
|
20
|
+
*
|
|
21
|
+
* SHA256 Fingerprint
|
|
22
|
+
* 1E:F1:A0:4B:8B:A5:8A:B9:45:89:AC:49:8C:89:82:A7:83:F2:4E:A7:30:7E:01:59:A0:C3:A7:3B:37:7D:87:CC
|
|
23
|
+
*/
|
|
24
|
+
export declare const Google_Hardware_Attestation_Root_2 = "-----BEGIN CERTIFICATE-----\nMIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\nBAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz\nNzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS\nSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7\ntv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj\nnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq\nC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ\noVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O\nJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg\nsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi\nigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M\nRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E\naDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um\nAGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud\nIwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD\nVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu\nXKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U\nh6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno\nL/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok\nQBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA\nD32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI\nmMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW\nFua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91\noeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o\njm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB\nZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH\nex0SdDrx+tWUDqG8At2JHA==\n-----END CERTIFICATE-----\n";
|