@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.
Files changed (343) hide show
  1. package/LICENSE.md +11 -14
  2. package/README.md +20 -7
  3. package/{dist → esm}/authentication/generateAuthenticationOptions.d.ts +2 -2
  4. package/esm/authentication/generateAuthenticationOptions.js +36 -0
  5. package/{dist → esm}/authentication/verifyAuthenticationResponse.d.ts +2 -2
  6. package/esm/authentication/verifyAuthenticationResponse.js +164 -0
  7. package/esm/deps.d.ts +11 -0
  8. package/esm/deps.js +14 -0
  9. package/esm/helpers/convertAAGUIDToString.js +17 -0
  10. package/esm/helpers/convertCOSEtoPKCS.js +21 -0
  11. package/{dist → esm}/helpers/convertCertBufferToPEM.d.ts +1 -1
  12. package/esm/helpers/convertCertBufferToPEM.js +31 -0
  13. package/esm/helpers/convertPEMToBytes.js +11 -0
  14. package/{dist → esm}/helpers/convertX509PublicKeyToCOSE.d.ts +1 -1
  15. package/esm/helpers/convertX509PublicKeyToCOSE.js +70 -0
  16. package/{dist → esm}/helpers/cose.d.ts +2 -1
  17. package/esm/helpers/cose.js +81 -0
  18. package/{dist → esm}/helpers/decodeAttestationObject.d.ts +3 -0
  19. package/esm/helpers/decodeAttestationObject.js +13 -0
  20. package/esm/helpers/decodeAuthenticatorExtensions.js +34 -0
  21. package/{dist → esm}/helpers/decodeClientDataJSON.d.ts +3 -0
  22. package/esm/helpers/decodeClientDataJSON.js +13 -0
  23. package/esm/helpers/decodeCredentialPublicKey.d.ts +5 -0
  24. package/esm/helpers/decodeCredentialPublicKey.js +8 -0
  25. package/esm/helpers/fetch.d.ts +8 -0
  26. package/esm/helpers/fetch.js +12 -0
  27. package/esm/helpers/generateChallenge.d.ts +7 -0
  28. package/esm/helpers/generateChallenge.js +21 -0
  29. package/{dist → esm}/helpers/getCertificateInfo.d.ts +1 -1
  30. package/esm/helpers/getCertificateInfo.js +76 -0
  31. package/esm/helpers/index.d.ts +22 -0
  32. package/esm/helpers/index.js +16 -0
  33. package/{dist → esm}/helpers/isCertRevoked.d.ts +1 -1
  34. package/esm/helpers/isCertRevoked.js +98 -0
  35. package/{dist → esm}/helpers/iso/index.d.ts +4 -4
  36. package/esm/helpers/iso/index.js +11 -0
  37. package/esm/helpers/iso/isoBase64URL.js +57 -0
  38. package/{dist → esm}/helpers/iso/isoCBOR.d.ts +1 -1
  39. package/esm/helpers/iso/isoCBOR.js +44 -0
  40. package/{dist → esm}/helpers/iso/isoCrypto/digest.d.ts +1 -1
  41. package/esm/helpers/iso/isoCrypto/digest.js +14 -0
  42. package/{dist → esm}/helpers/iso/isoCrypto/getRandomValues.d.ts +1 -1
  43. package/esm/helpers/iso/isoCrypto/getRandomValues.js +11 -0
  44. package/esm/helpers/iso/isoCrypto/getWebCrypto.d.ts +6 -0
  45. package/esm/helpers/iso/isoCrypto/getWebCrypto.js +40 -0
  46. package/esm/helpers/iso/isoCrypto/importKey.js +8 -0
  47. package/esm/helpers/iso/isoCrypto/index.d.ts +3 -0
  48. package/esm/helpers/iso/isoCrypto/index.js +3 -0
  49. package/{dist → esm}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.d.ts +2 -2
  50. package/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js +20 -0
  51. package/{dist → esm}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.d.ts +2 -2
  52. package/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js +19 -0
  53. package/esm/helpers/iso/isoCrypto/structs.js +1 -0
  54. package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js +30 -0
  55. package/{dist → esm}/helpers/iso/isoCrypto/verify.d.ts +1 -1
  56. package/esm/helpers/iso/isoCrypto/verify.js +28 -0
  57. package/{dist → esm}/helpers/iso/isoCrypto/verifyEC2.d.ts +1 -1
  58. package/esm/helpers/iso/isoCrypto/verifyEC2.js +73 -0
  59. package/{dist → esm}/helpers/iso/isoCrypto/verifyOKP.d.ts +1 -1
  60. package/esm/helpers/iso/isoCrypto/verifyOKP.js +51 -0
  61. package/{dist → esm}/helpers/iso/isoCrypto/verifyRSA.d.ts +1 -1
  62. package/esm/helpers/iso/isoCrypto/verifyRSA.js +91 -0
  63. package/esm/helpers/iso/isoUint8Array.js +75 -0
  64. package/{dist → esm}/helpers/logging.d.ts +1 -1
  65. package/esm/helpers/logging.js +19 -0
  66. package/{dist → esm}/helpers/mapX509SignatureAlgToCOSEAlg.d.ts +1 -1
  67. package/esm/helpers/mapX509SignatureAlgToCOSEAlg.js +35 -0
  68. package/esm/helpers/matchExpectedRPID.js +41 -0
  69. package/{dist → esm}/helpers/parseAuthenticatorData.d.ts +4 -1
  70. package/esm/helpers/parseAuthenticatorData.js +71 -0
  71. package/{dist → esm}/helpers/parseBackupFlags.d.ts +4 -1
  72. package/esm/helpers/parseBackupFlags.js +25 -0
  73. package/{dist → esm}/helpers/toHash.d.ts +1 -1
  74. package/esm/helpers/toHash.js +12 -0
  75. package/esm/helpers/validateCertificatePath.js +122 -0
  76. package/{dist → esm}/helpers/verifySignature.d.ts +4 -1
  77. package/esm/helpers/verifySignature.js +32 -0
  78. package/esm/index.d.ts +17 -0
  79. package/esm/index.js +11 -0
  80. package/{dist → esm}/metadata/mdsTypes.d.ts +1 -1
  81. package/esm/metadata/mdsTypes.js +17 -0
  82. package/esm/metadata/parseJWT.js +12 -0
  83. package/{dist → esm}/metadata/verifyAttestationWithMetadata.d.ts +3 -3
  84. package/esm/metadata/verifyAttestationWithMetadata.js +159 -0
  85. package/esm/metadata/verifyJWT.js +37 -0
  86. package/esm/package.json +3 -0
  87. package/{dist → esm}/registration/generateRegistrationOptions.d.ts +2 -2
  88. package/esm/registration/generateRegistrationOptions.js +142 -0
  89. package/esm/registration/verifications/tpm/constants.js +182 -0
  90. package/esm/registration/verifications/tpm/parseCertInfo.js +58 -0
  91. package/esm/registration/verifications/tpm/parsePubArea.js +94 -0
  92. package/{dist → esm}/registration/verifications/tpm/verifyAttestationTPM.d.ts +1 -1
  93. package/esm/registration/verifications/tpm/verifyAttestationTPM.js +323 -0
  94. package/{dist → esm}/registration/verifications/verifyAttestationAndroidKey.d.ts +1 -1
  95. package/esm/registration/verifications/verifyAttestationAndroidKey.js +90 -0
  96. package/{dist → esm}/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts +1 -1
  97. package/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js +112 -0
  98. package/{dist → esm}/registration/verifications/verifyAttestationApple.d.ts +1 -1
  99. package/esm/registration/verifications/verifyAttestationApple.js +57 -0
  100. package/{dist → esm}/registration/verifications/verifyAttestationFIDOU2F.d.ts +1 -1
  101. package/esm/registration/verifications/verifyAttestationFIDOU2F.js +48 -0
  102. package/{dist → esm}/registration/verifications/verifyAttestationPacked.d.ts +1 -1
  103. package/esm/registration/verifications/verifyAttestationPacked.js +105 -0
  104. package/{dist → esm}/registration/verifyRegistrationResponse.d.ts +3 -3
  105. package/esm/registration/verifyRegistrationResponse.js +198 -0
  106. package/esm/services/defaultRootCerts/android-key.js +85 -0
  107. package/esm/services/defaultRootCerts/android-safetynet.js +32 -0
  108. package/esm/services/defaultRootCerts/apple.js +25 -0
  109. package/esm/services/defaultRootCerts/mds.js +32 -0
  110. package/{dist → esm}/services/metadataService.d.ts +1 -1
  111. package/{dist → esm}/services/metadataService.js +52 -36
  112. package/{dist → esm}/services/settingsService.d.ts +1 -1
  113. package/esm/services/settingsService.js +65 -0
  114. package/package.json +40 -42
  115. package/script/authentication/generateAuthenticationOptions.d.ts +23 -0
  116. package/{dist → script}/authentication/generateAuthenticationOptions.js +8 -9
  117. package/script/authentication/verifyAuthenticationResponse.d.ts +66 -0
  118. package/{dist → script}/authentication/verifyAuthenticationResponse.js +25 -23
  119. package/script/deps.d.ts +11 -0
  120. package/script/deps.js +71 -0
  121. package/script/helpers/convertAAGUIDToString.d.ts +4 -0
  122. package/{dist → script}/helpers/convertAAGUIDToString.js +2 -3
  123. package/script/helpers/convertCOSEtoPKCS.d.ts +4 -0
  124. package/{dist → script}/helpers/convertCOSEtoPKCS.js +7 -8
  125. package/script/helpers/convertCertBufferToPEM.d.ts +5 -0
  126. package/{dist → script}/helpers/convertCertBufferToPEM.js +5 -6
  127. package/script/helpers/convertPEMToBytes.d.ts +4 -0
  128. package/{dist → script}/helpers/convertPEMToBytes.js +2 -3
  129. package/script/helpers/convertX509PublicKeyToCOSE.d.ts +2 -0
  130. package/{dist → script}/helpers/convertX509PublicKeyToCOSE.js +21 -25
  131. package/script/helpers/cose.d.ts +98 -0
  132. package/{dist → script}/helpers/cose.js +1 -1
  133. package/script/helpers/decodeAttestationObject.d.ts +29 -0
  134. package/script/helpers/decodeAttestationObject.js +17 -0
  135. package/script/helpers/decodeAuthenticatorExtensions.d.ts +20 -0
  136. package/{dist → script}/helpers/decodeAuthenticatorExtensions.js +2 -3
  137. package/script/helpers/decodeClientDataJSON.d.ts +17 -0
  138. package/script/helpers/decodeClientDataJSON.js +17 -0
  139. package/script/helpers/decodeCredentialPublicKey.d.ts +5 -0
  140. package/script/helpers/decodeCredentialPublicKey.js +12 -0
  141. package/script/helpers/fetch.d.ts +8 -0
  142. package/script/helpers/fetch.js +16 -0
  143. package/script/helpers/generateChallenge.d.ts +7 -0
  144. package/{dist → script}/helpers/generateChallenge.js +9 -6
  145. package/script/helpers/getCertificateInfo.d.ts +31 -0
  146. package/{dist → script}/helpers/getCertificateInfo.js +4 -6
  147. package/script/helpers/index.d.ts +22 -0
  148. package/script/helpers/index.js +59 -0
  149. package/script/helpers/isCertRevoked.d.ts +8 -0
  150. package/{dist → script}/helpers/isCertRevoked.js +20 -25
  151. package/script/helpers/iso/index.d.ts +11 -0
  152. package/{dist → script}/helpers/iso/index.js +4 -5
  153. package/script/helpers/iso/isoBase64URL.d.ts +37 -0
  154. package/{dist → script}/helpers/iso/isoBase64URL.js +9 -13
  155. package/script/helpers/iso/isoCBOR.d.ts +12 -0
  156. package/{dist → script}/helpers/iso/isoCBOR.js +8 -28
  157. package/script/helpers/iso/isoCrypto/digest.d.ts +8 -0
  158. package/script/helpers/iso/isoCrypto/digest.js +18 -0
  159. package/script/helpers/iso/isoCrypto/getRandomValues.d.ts +6 -0
  160. package/script/helpers/iso/isoCrypto/getRandomValues.js +15 -0
  161. package/script/helpers/iso/isoCrypto/getWebCrypto.d.ts +6 -0
  162. package/script/helpers/iso/isoCrypto/getWebCrypto.js +44 -0
  163. package/script/helpers/iso/isoCrypto/importKey.d.ts +4 -0
  164. package/script/helpers/iso/isoCrypto/importKey.js +12 -0
  165. package/script/helpers/iso/isoCrypto/index.d.ts +3 -0
  166. package/{dist → script}/helpers/iso/isoCrypto/index.js +6 -7
  167. package/script/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.d.ts +6 -0
  168. package/{dist → script}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js +6 -6
  169. package/script/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.d.ts +6 -0
  170. package/{dist → script}/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js +5 -6
  171. package/script/helpers/iso/isoCrypto/structs.d.ts +3 -0
  172. package/{dist → script}/helpers/iso/isoCrypto/structs.js +0 -1
  173. package/script/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +6 -0
  174. package/{dist → script}/helpers/iso/isoCrypto/unwrapEC2Signature.js +4 -6
  175. package/script/helpers/iso/isoCrypto/verify.d.ts +10 -0
  176. package/script/helpers/iso/isoCrypto/verify.js +32 -0
  177. package/script/helpers/iso/isoCrypto/verifyEC2.d.ts +10 -0
  178. package/{dist → script}/helpers/iso/isoCrypto/verifyEC2.js +19 -22
  179. package/script/helpers/iso/isoCrypto/verifyOKP.d.ts +6 -0
  180. package/{dist → script}/helpers/iso/isoCrypto/verifyOKP.js +13 -16
  181. package/script/helpers/iso/isoCrypto/verifyRSA.d.ts +10 -0
  182. package/{dist → script}/helpers/iso/isoCrypto/verifyRSA.js +19 -22
  183. package/script/helpers/iso/isoUint8Array.d.ts +36 -0
  184. package/{dist → script}/helpers/iso/isoUint8Array.js +7 -8
  185. package/script/helpers/logging.d.ts +17 -0
  186. package/{dist → script}/helpers/logging.js +2 -6
  187. package/script/helpers/mapX509SignatureAlgToCOSEAlg.d.ts +8 -0
  188. package/{dist → script}/helpers/mapX509SignatureAlgToCOSEAlg.js +8 -9
  189. package/script/helpers/matchExpectedRPID.d.ts +7 -0
  190. package/{dist → script}/helpers/matchExpectedRPID.js +5 -6
  191. package/script/helpers/parseAuthenticatorData.d.ts +28 -0
  192. package/{dist → script}/helpers/parseAuthenticatorData.js +19 -16
  193. package/script/helpers/parseBackupFlags.d.ts +19 -0
  194. package/{dist → script}/helpers/parseBackupFlags.js +2 -2
  195. package/script/helpers/toHash.d.ts +6 -0
  196. package/{dist → script}/helpers/toHash.js +4 -5
  197. package/script/helpers/validateCertificatePath.d.ts +6 -0
  198. package/{dist → script}/helpers/validateCertificatePath.js +13 -15
  199. package/script/helpers/verifySignature.d.ts +14 -0
  200. package/script/helpers/verifySignature.js +36 -0
  201. package/script/index.d.ts +17 -0
  202. package/script/index.js +19 -0
  203. package/script/metadata/mdsTypes.d.ts +216 -0
  204. package/{dist → script}/metadata/mdsTypes.js +0 -1
  205. package/script/metadata/parseJWT.d.ts +4 -0
  206. package/{dist → script}/metadata/parseJWT.js +3 -4
  207. package/script/metadata/verifyAttestationWithMetadata.d.ts +29 -0
  208. package/{dist → script}/metadata/verifyAttestationWithMetadata.js +24 -22
  209. package/script/metadata/verifyJWT.d.ts +10 -0
  210. package/script/metadata/verifyJWT.js +41 -0
  211. package/script/package.json +3 -0
  212. package/script/registration/generateRegistrationOptions.d.ts +43 -0
  213. package/{dist → script}/registration/generateRegistrationOptions.js +9 -10
  214. package/script/registration/verifications/tpm/constants.d.ts +47 -0
  215. package/{dist → script}/registration/verifications/tpm/constants.js +1 -2
  216. package/script/registration/verifications/tpm/parseCertInfo.d.ts +24 -0
  217. package/{dist → script}/registration/verifications/tpm/parseCertInfo.js +13 -14
  218. package/script/registration/verifications/tpm/parsePubArea.d.ts +43 -0
  219. package/{dist → script}/registration/verifications/tpm/parsePubArea.js +16 -17
  220. package/script/registration/verifications/tpm/verifyAttestationTPM.d.ts +2 -0
  221. package/{dist → script}/registration/verifications/tpm/verifyAttestationTPM.js +58 -58
  222. package/script/registration/verifications/verifyAttestationAndroidKey.d.ts +5 -0
  223. package/{dist → script}/registration/verifications/verifyAttestationAndroidKey.js +22 -26
  224. package/script/registration/verifications/verifyAttestationAndroidSafetyNet.d.ts +5 -0
  225. package/{dist → script}/registration/verifications/verifyAttestationAndroidSafetyNet.js +22 -23
  226. package/script/registration/verifications/verifyAttestationApple.d.ts +2 -0
  227. package/{dist → script}/registration/verifications/verifyAttestationApple.js +15 -17
  228. package/script/registration/verifications/verifyAttestationFIDOU2F.d.ts +5 -0
  229. package/{dist → script}/registration/verifications/verifyAttestationFIDOU2F.js +12 -13
  230. package/script/registration/verifications/verifyAttestationPacked.d.ts +5 -0
  231. package/{dist → script}/registration/verifications/verifyAttestationPacked.js +17 -18
  232. package/script/registration/verifyRegistrationResponse.d.ts +85 -0
  233. package/{dist → script}/registration/verifyRegistrationResponse.js +39 -38
  234. package/script/services/defaultRootCerts/android-key.d.ts +24 -0
  235. package/{dist → script}/services/defaultRootCerts/android-key.js +0 -1
  236. package/script/services/defaultRootCerts/android-safetynet.d.ts +11 -0
  237. package/{dist → script}/services/defaultRootCerts/android-safetynet.js +0 -1
  238. package/script/services/defaultRootCerts/apple.d.ts +11 -0
  239. package/{dist → script}/services/defaultRootCerts/apple.js +0 -1
  240. package/script/services/defaultRootCerts/mds.d.ts +11 -0
  241. package/{dist → script}/services/defaultRootCerts/mds.js +0 -1
  242. package/script/services/metadataService.d.ts +53 -0
  243. package/script/services/metadataService.js +277 -0
  244. package/script/services/settingsService.d.ts +25 -0
  245. package/{dist → script}/services/settingsService.js +21 -13
  246. package/dist/authentication/generateAuthenticationOptions.js.map +0 -1
  247. package/dist/authentication/verifyAuthenticationResponse.js.map +0 -1
  248. package/dist/helpers/convertAAGUIDToString.js.map +0 -1
  249. package/dist/helpers/convertCOSEtoPKCS.js.map +0 -1
  250. package/dist/helpers/convertCertBufferToPEM.js.map +0 -1
  251. package/dist/helpers/convertPEMToBytes.js.map +0 -1
  252. package/dist/helpers/convertX509PublicKeyToCOSE.js.map +0 -1
  253. package/dist/helpers/cose.js.map +0 -1
  254. package/dist/helpers/decodeAttestationObject.js +0 -14
  255. package/dist/helpers/decodeAttestationObject.js.map +0 -1
  256. package/dist/helpers/decodeAuthenticatorExtensions.js.map +0 -1
  257. package/dist/helpers/decodeClientDataJSON.js +0 -14
  258. package/dist/helpers/decodeClientDataJSON.js.map +0 -1
  259. package/dist/helpers/decodeCredentialPublicKey.d.ts +0 -2
  260. package/dist/helpers/decodeCredentialPublicKey.js +0 -9
  261. package/dist/helpers/decodeCredentialPublicKey.js.map +0 -1
  262. package/dist/helpers/generateChallenge.d.ts +0 -4
  263. package/dist/helpers/generateChallenge.js.map +0 -1
  264. package/dist/helpers/getCertificateInfo.js.map +0 -1
  265. package/dist/helpers/index.d.ts +0 -22
  266. package/dist/helpers/index.js +0 -60
  267. package/dist/helpers/index.js.map +0 -1
  268. package/dist/helpers/isCertRevoked.js.map +0 -1
  269. package/dist/helpers/iso/index.js.map +0 -1
  270. package/dist/helpers/iso/isoBase64URL.js.map +0 -1
  271. package/dist/helpers/iso/isoCBOR.js.map +0 -1
  272. package/dist/helpers/iso/isoCrypto/digest.js +0 -21
  273. package/dist/helpers/iso/isoCrypto/digest.js.map +0 -1
  274. package/dist/helpers/iso/isoCrypto/getRandomValues.js +0 -18
  275. package/dist/helpers/iso/isoCrypto/getRandomValues.js.map +0 -1
  276. package/dist/helpers/iso/isoCrypto/importKey.js +0 -13
  277. package/dist/helpers/iso/isoCrypto/importKey.js.map +0 -1
  278. package/dist/helpers/iso/isoCrypto/index.d.ts +0 -3
  279. package/dist/helpers/iso/isoCrypto/index.js.map +0 -1
  280. package/dist/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.js.map +0 -1
  281. package/dist/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js.map +0 -1
  282. package/dist/helpers/iso/isoCrypto/structs.js.map +0 -1
  283. package/dist/helpers/iso/isoCrypto/unwrapEC2Signature.js.map +0 -1
  284. package/dist/helpers/iso/isoCrypto/verify.js +0 -28
  285. package/dist/helpers/iso/isoCrypto/verify.js.map +0 -1
  286. package/dist/helpers/iso/isoCrypto/verifyEC2.js.map +0 -1
  287. package/dist/helpers/iso/isoCrypto/verifyOKP.js.map +0 -1
  288. package/dist/helpers/iso/isoCrypto/verifyRSA.js.map +0 -1
  289. package/dist/helpers/iso/isoUint8Array.js.map +0 -1
  290. package/dist/helpers/logging.js.map +0 -1
  291. package/dist/helpers/mapX509SignatureAlgToCOSEAlg.js.map +0 -1
  292. package/dist/helpers/matchExpectedRPID.js.map +0 -1
  293. package/dist/helpers/parseAuthenticatorData.js.map +0 -1
  294. package/dist/helpers/parseBackupFlags.js.map +0 -1
  295. package/dist/helpers/toHash.js.map +0 -1
  296. package/dist/helpers/validateCertificatePath.js.map +0 -1
  297. package/dist/helpers/verifySignature.js +0 -33
  298. package/dist/helpers/verifySignature.js.map +0 -1
  299. package/dist/index.d.ts +0 -17
  300. package/dist/index.js +0 -20
  301. package/dist/index.js.map +0 -1
  302. package/dist/metadata/mdsTypes.js.map +0 -1
  303. package/dist/metadata/parseJWT.js.map +0 -1
  304. package/dist/metadata/verifyAttestationWithMetadata.js.map +0 -1
  305. package/dist/metadata/verifyJWT.js +0 -42
  306. package/dist/metadata/verifyJWT.js.map +0 -1
  307. package/dist/registration/generateRegistrationOptions.js.map +0 -1
  308. package/dist/registration/verifications/tpm/constants.js.map +0 -1
  309. package/dist/registration/verifications/tpm/parseCertInfo.js.map +0 -1
  310. package/dist/registration/verifications/tpm/parsePubArea.js.map +0 -1
  311. package/dist/registration/verifications/tpm/verifyAttestationTPM.js.map +0 -1
  312. package/dist/registration/verifications/verifyAttestationAndroidKey.js.map +0 -1
  313. package/dist/registration/verifications/verifyAttestationAndroidSafetyNet.js.map +0 -1
  314. package/dist/registration/verifications/verifyAttestationApple.js.map +0 -1
  315. package/dist/registration/verifications/verifyAttestationFIDOU2F.js.map +0 -1
  316. package/dist/registration/verifications/verifyAttestationPacked.js.map +0 -1
  317. package/dist/registration/verifyRegistrationResponse.js.map +0 -1
  318. package/dist/services/defaultRootCerts/android-key.js.map +0 -1
  319. package/dist/services/defaultRootCerts/android-safetynet.js.map +0 -1
  320. package/dist/services/defaultRootCerts/apple.js.map +0 -1
  321. package/dist/services/defaultRootCerts/mds.js.map +0 -1
  322. package/dist/services/metadataService.js.map +0 -1
  323. package/dist/services/settingsService.js.map +0 -1
  324. /package/{dist → esm}/helpers/convertAAGUIDToString.d.ts +0 -0
  325. /package/{dist → esm}/helpers/convertCOSEtoPKCS.d.ts +0 -0
  326. /package/{dist → esm}/helpers/convertPEMToBytes.d.ts +0 -0
  327. /package/{dist → esm}/helpers/decodeAuthenticatorExtensions.d.ts +0 -0
  328. /package/{dist → esm}/helpers/iso/isoBase64URL.d.ts +0 -0
  329. /package/{dist → esm}/helpers/iso/isoCrypto/importKey.d.ts +0 -0
  330. /package/{dist → esm}/helpers/iso/isoCrypto/structs.d.ts +0 -0
  331. /package/{dist → esm}/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +0 -0
  332. /package/{dist → esm}/helpers/iso/isoUint8Array.d.ts +0 -0
  333. /package/{dist → esm}/helpers/matchExpectedRPID.d.ts +0 -0
  334. /package/{dist → esm}/helpers/validateCertificatePath.d.ts +0 -0
  335. /package/{dist → esm}/metadata/parseJWT.d.ts +0 -0
  336. /package/{dist → esm}/metadata/verifyJWT.d.ts +0 -0
  337. /package/{dist → esm}/registration/verifications/tpm/constants.d.ts +0 -0
  338. /package/{dist → esm}/registration/verifications/tpm/parseCertInfo.d.ts +0 -0
  339. /package/{dist → esm}/registration/verifications/tpm/parsePubArea.d.ts +0 -0
  340. /package/{dist → esm}/services/defaultRootCerts/android-key.d.ts +0 -0
  341. /package/{dist → esm}/services/defaultRootCerts/android-safetynet.d.ts +0 -0
  342. /package/{dist → esm}/services/defaultRootCerts/apple.d.ts +0 -0
  343. /package/{dist → esm}/services/defaultRootCerts/mds.d.ts +0 -0
@@ -0,0 +1,90 @@
1
+ import { AsnParser, Certificate, id_ce_keyDescription, KeyDescription } from '../../deps.js';
2
+ import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM.js';
3
+ import { validateCertificatePath } from '../../helpers/validateCertificatePath.js';
4
+ import { verifySignature } from '../../helpers/verifySignature.js';
5
+ import { convertCOSEtoPKCS } from '../../helpers/convertCOSEtoPKCS.js';
6
+ import { isCOSEAlg } from '../../helpers/cose.js';
7
+ import { isoUint8Array } from '../../helpers/iso/index.js';
8
+ import { MetadataService } from '../../services/metadataService.js';
9
+ import { verifyAttestationWithMetadata } from '../../metadata/verifyAttestationWithMetadata.js';
10
+ /**
11
+ * Verify an attestation response with fmt 'android-key'
12
+ */
13
+ export async function verifyAttestationAndroidKey(options) {
14
+ const { authData, clientDataHash, attStmt, credentialPublicKey, aaguid, rootCertificates, } = options;
15
+ const x5c = attStmt.get('x5c');
16
+ const sig = attStmt.get('sig');
17
+ const alg = attStmt.get('alg');
18
+ if (!x5c) {
19
+ throw new Error('No attestation certificate provided in attestation statement (AndroidKey)');
20
+ }
21
+ if (!sig) {
22
+ throw new Error('No attestation signature provided in attestation statement (AndroidKey)');
23
+ }
24
+ if (!alg) {
25
+ throw new Error(`Attestation statement did not contain alg (AndroidKey)`);
26
+ }
27
+ if (!isCOSEAlg(alg)) {
28
+ throw new Error(`Attestation statement contained invalid alg ${alg} (AndroidKey)`);
29
+ }
30
+ // Check that credentialPublicKey matches the public key in the attestation certificate
31
+ // Find the public cert in the certificate as PKCS
32
+ const parsedCert = AsnParser.parse(x5c[0], Certificate);
33
+ const parsedCertPubKey = new Uint8Array(parsedCert.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey);
34
+ // Convert the credentialPublicKey to PKCS
35
+ const credPubKeyPKCS = convertCOSEtoPKCS(credentialPublicKey);
36
+ if (!isoUint8Array.areEqual(credPubKeyPKCS, parsedCertPubKey)) {
37
+ throw new Error('Credential public key does not equal leaf cert public key (AndroidKey)');
38
+ }
39
+ // Find Android KeyStore Extension in certificate extensions
40
+ const extKeyStore = parsedCert.tbsCertificate.extensions?.find((ext) => ext.extnID === id_ce_keyDescription);
41
+ if (!extKeyStore) {
42
+ throw new Error('Certificate did not contain extKeyStore (AndroidKey)');
43
+ }
44
+ const parsedExtKeyStore = AsnParser.parse(extKeyStore.extnValue, KeyDescription);
45
+ // Verify extKeyStore values
46
+ const { attestationChallenge, teeEnforced, softwareEnforced } = parsedExtKeyStore;
47
+ if (!isoUint8Array.areEqual(new Uint8Array(attestationChallenge.buffer), clientDataHash)) {
48
+ throw new Error('Attestation challenge was not equal to client data hash (AndroidKey)');
49
+ }
50
+ // Ensure that the key is strictly bound to the caller app identifier (shouldn't contain the
51
+ // [600] tag)
52
+ if (teeEnforced.allApplications !== undefined) {
53
+ throw new Error('teeEnforced contained "allApplications [600]" tag (AndroidKey)');
54
+ }
55
+ if (softwareEnforced.allApplications !== undefined) {
56
+ throw new Error('teeEnforced contained "allApplications [600]" tag (AndroidKey)');
57
+ }
58
+ const statement = await MetadataService.getStatement(aaguid);
59
+ if (statement) {
60
+ try {
61
+ await verifyAttestationWithMetadata({
62
+ statement,
63
+ credentialPublicKey,
64
+ x5c,
65
+ attestationStatementAlg: alg,
66
+ });
67
+ }
68
+ catch (err) {
69
+ const _err = err;
70
+ throw new Error(`${_err.message} (AndroidKey)`);
71
+ }
72
+ }
73
+ else {
74
+ try {
75
+ // Try validating the certificate path using the root certificates set via SettingsService
76
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
77
+ }
78
+ catch (err) {
79
+ const _err = err;
80
+ throw new Error(`${_err.message} (AndroidKey)`);
81
+ }
82
+ }
83
+ const signatureBase = isoUint8Array.concat([authData, clientDataHash]);
84
+ return verifySignature({
85
+ signature: sig,
86
+ data: signatureBase,
87
+ x509Certificate: x5c[0],
88
+ hashAlgorithm: alg,
89
+ });
90
+ }
@@ -1,4 +1,4 @@
1
- import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse';
1
+ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse.js';
2
2
  /**
3
3
  * Verify an attestation response with fmt 'android-safetynet'
4
4
  */
@@ -0,0 +1,112 @@
1
+ import { toHash } from '../../helpers/toHash.js';
2
+ import { verifySignature } from '../../helpers/verifySignature.js';
3
+ import { getCertificateInfo } from '../../helpers/getCertificateInfo.js';
4
+ import { validateCertificatePath } from '../../helpers/validateCertificatePath.js';
5
+ import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM.js';
6
+ import { isoBase64URL, isoUint8Array } from '../../helpers/iso/index.js';
7
+ import { MetadataService } from '../../services/metadataService.js';
8
+ import { verifyAttestationWithMetadata } from '../../metadata/verifyAttestationWithMetadata.js';
9
+ /**
10
+ * Verify an attestation response with fmt 'android-safetynet'
11
+ */
12
+ export async function verifyAttestationAndroidSafetyNet(options) {
13
+ const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, credentialPublicKey, } = options;
14
+ const alg = attStmt.get('alg');
15
+ const response = attStmt.get('response');
16
+ const ver = attStmt.get('ver');
17
+ if (!ver) {
18
+ throw new Error('No ver value in attestation (SafetyNet)');
19
+ }
20
+ if (!response) {
21
+ throw new Error('No response was included in attStmt by authenticator (SafetyNet)');
22
+ }
23
+ // Prepare to verify a JWT
24
+ const jwt = isoUint8Array.toUTF8String(response);
25
+ const jwtParts = jwt.split('.');
26
+ const HEADER = JSON.parse(isoBase64URL.toString(jwtParts[0]));
27
+ const PAYLOAD = JSON.parse(isoBase64URL.toString(jwtParts[1]));
28
+ const SIGNATURE = jwtParts[2];
29
+ /**
30
+ * START Verify PAYLOAD
31
+ */
32
+ const { nonce, ctsProfileMatch, timestampMs } = PAYLOAD;
33
+ if (verifyTimestampMS) {
34
+ // Make sure timestamp is in the past
35
+ let now = Date.now();
36
+ if (timestampMs > Date.now()) {
37
+ throw new Error(`Payload timestamp "${timestampMs}" was later than "${now}" (SafetyNet)`);
38
+ }
39
+ // Consider a SafetyNet attestation valid within a minute of it being performed
40
+ const timestampPlusDelay = timestampMs + 60 * 1000;
41
+ now = Date.now();
42
+ if (timestampPlusDelay < now) {
43
+ throw new Error(`Payload timestamp "${timestampPlusDelay}" has expired (SafetyNet)`);
44
+ }
45
+ }
46
+ const nonceBase = isoUint8Array.concat([authData, clientDataHash]);
47
+ const nonceBuffer = await toHash(nonceBase);
48
+ const expectedNonce = isoBase64URL.fromBuffer(nonceBuffer, 'base64');
49
+ if (nonce !== expectedNonce) {
50
+ throw new Error('Could not verify payload nonce (SafetyNet)');
51
+ }
52
+ if (!ctsProfileMatch) {
53
+ throw new Error('Could not verify device integrity (SafetyNet)');
54
+ }
55
+ /**
56
+ * END Verify PAYLOAD
57
+ */
58
+ /**
59
+ * START Verify Header
60
+ */
61
+ // `HEADER.x5c[0]` is definitely a base64 string
62
+ const leafCertBuffer = isoBase64URL.toBuffer(HEADER.x5c[0], 'base64');
63
+ const leafCertInfo = getCertificateInfo(leafCertBuffer);
64
+ const { subject } = leafCertInfo;
65
+ // Ensure the certificate was issued to this hostname
66
+ // See https://developer.android.com/training/safetynet/attestation#verify-attestation-response
67
+ if (subject.CN !== 'attest.android.com') {
68
+ throw new Error('Certificate common name was not "attest.android.com" (SafetyNet)');
69
+ }
70
+ const statement = await MetadataService.getStatement(aaguid);
71
+ if (statement) {
72
+ try {
73
+ await verifyAttestationWithMetadata({
74
+ statement,
75
+ credentialPublicKey,
76
+ x5c: HEADER.x5c,
77
+ attestationStatementAlg: alg,
78
+ });
79
+ }
80
+ catch (err) {
81
+ const _err = err;
82
+ throw new Error(`${_err.message} (SafetyNet)`);
83
+ }
84
+ }
85
+ else {
86
+ try {
87
+ // Try validating the certificate path using the root certificates set via SettingsService
88
+ await validateCertificatePath(HEADER.x5c.map(convertCertBufferToPEM), rootCertificates);
89
+ }
90
+ catch (err) {
91
+ const _err = err;
92
+ throw new Error(`${_err.message} (SafetyNet)`);
93
+ }
94
+ }
95
+ /**
96
+ * END Verify Header
97
+ */
98
+ /**
99
+ * START Verify Signature
100
+ */
101
+ const signatureBaseBuffer = isoUint8Array.fromUTF8String(`${jwtParts[0]}.${jwtParts[1]}`);
102
+ const signatureBuffer = isoBase64URL.toBuffer(SIGNATURE);
103
+ const verified = await verifySignature({
104
+ signature: signatureBuffer,
105
+ data: signatureBaseBuffer,
106
+ x509Certificate: leafCertBuffer,
107
+ });
108
+ /**
109
+ * END Verify Signature
110
+ */
111
+ return verified;
112
+ }
@@ -1,2 +1,2 @@
1
- import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse';
1
+ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse.js';
2
2
  export declare function verifyAttestationApple(options: AttestationFormatVerifierOpts): Promise<boolean>;
@@ -0,0 +1,57 @@
1
+ import { AsnParser, Certificate } from '../../deps.js';
2
+ import { validateCertificatePath } from '../../helpers/validateCertificatePath.js';
3
+ import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM.js';
4
+ import { toHash } from '../../helpers/toHash.js';
5
+ import { convertCOSEtoPKCS } from '../../helpers/convertCOSEtoPKCS.js';
6
+ import { isoUint8Array } from '../../helpers/iso/index.js';
7
+ export async function verifyAttestationApple(options) {
8
+ const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates, } = options;
9
+ const x5c = attStmt.get('x5c');
10
+ if (!x5c) {
11
+ throw new Error('No attestation certificate provided in attestation statement (Apple)');
12
+ }
13
+ /**
14
+ * Verify certificate path
15
+ */
16
+ try {
17
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
18
+ }
19
+ catch (err) {
20
+ const _err = err;
21
+ throw new Error(`${_err.message} (Apple)`);
22
+ }
23
+ /**
24
+ * Compare nonce in certificate extension to computed nonce
25
+ */
26
+ const parsedCredCert = AsnParser.parse(x5c[0], Certificate);
27
+ const { extensions, subjectPublicKeyInfo } = parsedCredCert.tbsCertificate;
28
+ if (!extensions) {
29
+ throw new Error('credCert missing extensions (Apple)');
30
+ }
31
+ const extCertNonce = extensions.find((ext) => ext.extnID === '1.2.840.113635.100.8.2');
32
+ if (!extCertNonce) {
33
+ throw new Error('credCert missing "1.2.840.113635.100.8.2" extension (Apple)');
34
+ }
35
+ const nonceToHash = isoUint8Array.concat([authData, clientDataHash]);
36
+ const nonce = await toHash(nonceToHash);
37
+ /**
38
+ * Ignore the first six ASN.1 structure bytes that define the nonce as an OCTET STRING. Should
39
+ * trim off <Buffer 30 24 a1 22 04 20>
40
+ *
41
+ * TODO: Try and get @peculiar (GitHub) to add a schema for "1.2.840.113635.100.8.2" when we
42
+ * find out where it's defined (doesn't seem to be publicly documented at the moment...)
43
+ */
44
+ const extNonce = new Uint8Array(extCertNonce.extnValue.buffer).slice(6);
45
+ if (!isoUint8Array.areEqual(nonce, extNonce)) {
46
+ throw new Error(`credCert nonce was not expected value (Apple)`);
47
+ }
48
+ /**
49
+ * Verify credential public key matches the Subject Public Key of credCert
50
+ */
51
+ const credPubKeyPKCS = convertCOSEtoPKCS(credentialPublicKey);
52
+ const credCertSubjectPublicKey = new Uint8Array(subjectPublicKeyInfo.subjectPublicKey);
53
+ if (!isoUint8Array.areEqual(credPubKeyPKCS, credCertSubjectPublicKey)) {
54
+ throw new Error('Credential public key does not equal credCert public key (Apple)');
55
+ }
56
+ return true;
57
+ }
@@ -1,4 +1,4 @@
1
- import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse';
1
+ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse.js';
2
2
  /**
3
3
  * Verify an attestation response with fmt 'fido-u2f'
4
4
  */
@@ -0,0 +1,48 @@
1
+ import { convertCOSEtoPKCS } from '../../helpers/convertCOSEtoPKCS.js';
2
+ import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM.js';
3
+ import { validateCertificatePath } from '../../helpers/validateCertificatePath.js';
4
+ import { verifySignature } from '../../helpers/verifySignature.js';
5
+ import { isoUint8Array } from '../../helpers/iso/index.js';
6
+ import { COSEALG } from '../../helpers/cose.js';
7
+ /**
8
+ * Verify an attestation response with fmt 'fido-u2f'
9
+ */
10
+ export async function verifyAttestationFIDOU2F(options) {
11
+ const { attStmt, clientDataHash, rpIdHash, credentialID, credentialPublicKey, aaguid, rootCertificates, } = options;
12
+ const reservedByte = Uint8Array.from([0x00]);
13
+ const publicKey = convertCOSEtoPKCS(credentialPublicKey);
14
+ const signatureBase = isoUint8Array.concat([
15
+ reservedByte,
16
+ rpIdHash,
17
+ clientDataHash,
18
+ credentialID,
19
+ publicKey,
20
+ ]);
21
+ const sig = attStmt.get('sig');
22
+ const x5c = attStmt.get('x5c');
23
+ if (!x5c) {
24
+ throw new Error('No attestation certificate provided in attestation statement (FIDOU2F)');
25
+ }
26
+ if (!sig) {
27
+ throw new Error('No attestation signature provided in attestation statement (FIDOU2F)');
28
+ }
29
+ // FIDO spec says that aaguid _must_ equal 0x00 here to be legit
30
+ const aaguidToHex = Number.parseInt(isoUint8Array.toHex(aaguid), 16);
31
+ if (aaguidToHex !== 0x00) {
32
+ throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
33
+ }
34
+ try {
35
+ // Try validating the certificate path using the root certificates set via SettingsService
36
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
37
+ }
38
+ catch (err) {
39
+ const _err = err;
40
+ throw new Error(`${_err.message} (FIDOU2F)`);
41
+ }
42
+ return verifySignature({
43
+ signature: sig,
44
+ data: signatureBase,
45
+ x509Certificate: x5c[0],
46
+ hashAlgorithm: COSEALG.ES256,
47
+ });
48
+ }
@@ -1,4 +1,4 @@
1
- import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse';
1
+ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse.js';
2
2
  /**
3
3
  * Verify an attestation response with fmt 'packed'
4
4
  */
@@ -0,0 +1,105 @@
1
+ import { isCOSEAlg } from '../../helpers/cose.js';
2
+ import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM.js';
3
+ import { validateCertificatePath } from '../../helpers/validateCertificatePath.js';
4
+ import { getCertificateInfo } from '../../helpers/getCertificateInfo.js';
5
+ import { verifySignature } from '../../helpers/verifySignature.js';
6
+ import { isoUint8Array } from '../../helpers/iso/index.js';
7
+ import { MetadataService } from '../../services/metadataService.js';
8
+ import { verifyAttestationWithMetadata } from '../../metadata/verifyAttestationWithMetadata.js';
9
+ /**
10
+ * Verify an attestation response with fmt 'packed'
11
+ */
12
+ export async function verifyAttestationPacked(options) {
13
+ const { attStmt, clientDataHash, authData, credentialPublicKey, aaguid, rootCertificates, } = options;
14
+ const sig = attStmt.get('sig');
15
+ const x5c = attStmt.get('x5c');
16
+ const alg = attStmt.get('alg');
17
+ if (!sig) {
18
+ throw new Error('No attestation signature provided in attestation statement (Packed)');
19
+ }
20
+ if (!alg) {
21
+ throw new Error('Attestation statement did not contain alg (Packed)');
22
+ }
23
+ if (!isCOSEAlg(alg)) {
24
+ throw new Error(`Attestation statement contained invalid alg ${alg} (Packed)`);
25
+ }
26
+ const signatureBase = isoUint8Array.concat([authData, clientDataHash]);
27
+ let verified = false;
28
+ if (x5c) {
29
+ const { subject, basicConstraintsCA, version, notBefore, notAfter } = getCertificateInfo(x5c[0]);
30
+ const { OU, CN, O, C } = subject;
31
+ if (OU !== 'Authenticator Attestation') {
32
+ throw new Error('Certificate OU was not "Authenticator Attestation" (Packed|Full)');
33
+ }
34
+ if (!CN) {
35
+ throw new Error('Certificate CN was empty (Packed|Full)');
36
+ }
37
+ if (!O) {
38
+ throw new Error('Certificate O was empty (Packed|Full)');
39
+ }
40
+ if (!C || C.length !== 2) {
41
+ throw new Error('Certificate C was not two-character ISO 3166 code (Packed|Full)');
42
+ }
43
+ if (basicConstraintsCA) {
44
+ throw new Error('Certificate basic constraints CA was not `false` (Packed|Full)');
45
+ }
46
+ if (version !== 2) {
47
+ throw new Error('Certificate version was not `3` (ASN.1 value of 2) (Packed|Full)');
48
+ }
49
+ let now = new Date();
50
+ if (notBefore > now) {
51
+ throw new Error(`Certificate not good before "${notBefore.toString()}" (Packed|Full)`);
52
+ }
53
+ now = new Date();
54
+ if (notAfter < now) {
55
+ throw new Error(`Certificate not good after "${notAfter.toString()}" (Packed|Full)`);
56
+ }
57
+ // TODO: If certificate contains id-fido-gen-ce-aaguid(1.3.6.1.4.1.45724.1.1.4) extension, check
58
+ // that it’s value is set to the same AAGUID as in authData.
59
+ // If available, validate attestation alg and x5c with info in the metadata statement
60
+ const statement = await MetadataService.getStatement(aaguid);
61
+ if (statement) {
62
+ // The presence of x5c means this is a full attestation. Check to see if attestationTypes
63
+ // includes packed attestations.
64
+ if (statement.attestationTypes.indexOf('basic_full') < 0) {
65
+ throw new Error('Metadata does not indicate support for full attestations (Packed|Full)');
66
+ }
67
+ try {
68
+ await verifyAttestationWithMetadata({
69
+ statement,
70
+ credentialPublicKey,
71
+ x5c,
72
+ attestationStatementAlg: alg,
73
+ });
74
+ }
75
+ catch (err) {
76
+ const _err = err;
77
+ throw new Error(`${_err.message} (Packed|Full)`);
78
+ }
79
+ }
80
+ else {
81
+ try {
82
+ // Try validating the certificate path using the root certificates set via SettingsService
83
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
84
+ }
85
+ catch (err) {
86
+ const _err = err;
87
+ throw new Error(`${_err.message} (Packed|Full)`);
88
+ }
89
+ }
90
+ verified = await verifySignature({
91
+ signature: sig,
92
+ data: signatureBase,
93
+ x509Certificate: x5c[0],
94
+ });
95
+ }
96
+ else {
97
+ verified = await verifySignature({
98
+ signature: sig,
99
+ data: signatureBase,
100
+ credentialPublicKey,
101
+ hashAlgorithm: alg,
102
+ });
103
+ }
104
+ return verified;
105
+ }
@@ -1,6 +1,6 @@
1
- import { RegistrationResponseJSON, COSEAlgorithmIdentifier, CredentialDeviceType } from '@simplewebauthn/typescript-types';
2
- import { AttestationFormat, AttestationStatement } from '../helpers/decodeAttestationObject';
3
- import { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions';
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
4
  export type VerifyRegistrationResponseOpts = {
5
5
  response: RegistrationResponseJSON;
6
6
  expectedChallenge: string | ((challenge: string) => boolean);
@@ -0,0 +1,198 @@
1
+ import { decodeAttestationObject, } from '../helpers/decodeAttestationObject.js';
2
+ import { decodeClientDataJSON } from '../helpers/decodeClientDataJSON.js';
3
+ import { parseAuthenticatorData } from '../helpers/parseAuthenticatorData.js';
4
+ import { toHash } from '../helpers/toHash.js';
5
+ import { decodeCredentialPublicKey } from '../helpers/decodeCredentialPublicKey.js';
6
+ import { COSEKEYS } from '../helpers/cose.js';
7
+ import { convertAAGUIDToString } from '../helpers/convertAAGUIDToString.js';
8
+ import { parseBackupFlags } from '../helpers/parseBackupFlags.js';
9
+ import { matchExpectedRPID } from '../helpers/matchExpectedRPID.js';
10
+ import { isoBase64URL } from '../helpers/iso/index.js';
11
+ import { SettingsService } from '../services/settingsService.js';
12
+ import { supportedCOSEAlgorithmIdentifiers } from './generateRegistrationOptions.js';
13
+ import { verifyAttestationFIDOU2F } from './verifications/verifyAttestationFIDOU2F.js';
14
+ import { verifyAttestationPacked } from './verifications/verifyAttestationPacked.js';
15
+ import { verifyAttestationAndroidSafetyNet } from './verifications/verifyAttestationAndroidSafetyNet.js';
16
+ import { verifyAttestationTPM } from './verifications/tpm/verifyAttestationTPM.js';
17
+ import { verifyAttestationAndroidKey } from './verifications/verifyAttestationAndroidKey.js';
18
+ import { verifyAttestationApple } from './verifications/verifyAttestationApple.js';
19
+ /**
20
+ * Verify that the user has legitimately completed the registration process
21
+ *
22
+ * **Options:**
23
+ *
24
+ * @param response Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
25
+ * @param expectedChallenge The base64url-encoded `options.challenge` returned by
26
+ * `generateRegistrationOptions()`
27
+ * @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
28
+ * @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
29
+ * @param requireUserVerification (Optional) Enforce user verification by the authenticator
30
+ * (via PIN, fingerprint, etc...)
31
+ * @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
32
+ * attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
33
+ */
34
+ export async function verifyRegistrationResponse(options) {
35
+ const { response, expectedChallenge, expectedOrigin, expectedRPID, requireUserVerification = true, supportedAlgorithmIDs = supportedCOSEAlgorithmIdentifiers, } = options;
36
+ const { id, rawId, type: credentialType, response: attestationResponse } = response;
37
+ // Ensure credential specified an ID
38
+ if (!id) {
39
+ throw new Error('Missing credential ID');
40
+ }
41
+ // Ensure ID is base64url-encoded
42
+ if (id !== rawId) {
43
+ throw new Error('Credential ID was not base64url-encoded');
44
+ }
45
+ // Make sure credential type is public-key
46
+ if (credentialType !== 'public-key') {
47
+ throw new Error(`Unexpected credential type ${credentialType}, expected "public-key"`);
48
+ }
49
+ const clientDataJSON = decodeClientDataJSON(attestationResponse.clientDataJSON);
50
+ const { type, origin, challenge, tokenBinding } = clientDataJSON;
51
+ // Make sure we're handling an registration
52
+ if (type !== 'webauthn.create') {
53
+ throw new Error(`Unexpected registration response type: ${type}`);
54
+ }
55
+ // Ensure the device provided the challenge we gave it
56
+ if (typeof expectedChallenge === 'function') {
57
+ if (!expectedChallenge(challenge)) {
58
+ throw new Error(`Custom challenge verifier returned false for registration response challenge "${challenge}"`);
59
+ }
60
+ }
61
+ else if (challenge !== expectedChallenge) {
62
+ throw new Error(`Unexpected registration response challenge "${challenge}", expected "${expectedChallenge}"`);
63
+ }
64
+ // Check that the origin is our site
65
+ if (Array.isArray(expectedOrigin)) {
66
+ if (!expectedOrigin.includes(origin)) {
67
+ throw new Error(`Unexpected registration response origin "${origin}", expected one of: ${expectedOrigin.join(', ')}`);
68
+ }
69
+ }
70
+ else {
71
+ if (origin !== expectedOrigin) {
72
+ throw new Error(`Unexpected registration response origin "${origin}", expected "${expectedOrigin}"`);
73
+ }
74
+ }
75
+ if (tokenBinding) {
76
+ if (typeof tokenBinding !== 'object') {
77
+ throw new Error(`Unexpected value for TokenBinding "${tokenBinding}"`);
78
+ }
79
+ if (['present', 'supported', 'not-supported'].indexOf(tokenBinding.status) < 0) {
80
+ throw new Error(`Unexpected tokenBinding.status value of "${tokenBinding.status}"`);
81
+ }
82
+ }
83
+ const attestationObject = isoBase64URL.toBuffer(attestationResponse.attestationObject);
84
+ const decodedAttestationObject = decodeAttestationObject(attestationObject);
85
+ const fmt = decodedAttestationObject.get('fmt');
86
+ const authData = decodedAttestationObject.get('authData');
87
+ const attStmt = decodedAttestationObject.get('attStmt');
88
+ const parsedAuthData = parseAuthenticatorData(authData);
89
+ const { aaguid, rpIdHash, flags, credentialID, counter, credentialPublicKey, extensionsData, } = parsedAuthData;
90
+ // Make sure the response's RP ID is ours
91
+ let matchedRPID;
92
+ if (expectedRPID) {
93
+ let expectedRPIDs = [];
94
+ if (typeof expectedRPID === 'string') {
95
+ expectedRPIDs = [expectedRPID];
96
+ }
97
+ else {
98
+ expectedRPIDs = expectedRPID;
99
+ }
100
+ matchedRPID = await matchExpectedRPID(rpIdHash, expectedRPIDs);
101
+ }
102
+ // Make sure someone was physically present
103
+ if (!flags.up) {
104
+ throw new Error('User not present during registration');
105
+ }
106
+ // Enforce user verification if specified
107
+ if (requireUserVerification && !flags.uv) {
108
+ throw new Error('User verification required, but user could not be verified');
109
+ }
110
+ if (!credentialID) {
111
+ throw new Error('No credential ID was provided by authenticator');
112
+ }
113
+ if (!credentialPublicKey) {
114
+ throw new Error('No public key was provided by authenticator');
115
+ }
116
+ if (!aaguid) {
117
+ throw new Error('No AAGUID was present during registration');
118
+ }
119
+ const decodedPublicKey = decodeCredentialPublicKey(credentialPublicKey);
120
+ const alg = decodedPublicKey.get(COSEKEYS.alg);
121
+ if (typeof alg !== 'number') {
122
+ throw new Error('Credential public key was missing numeric alg');
123
+ }
124
+ // Make sure the key algorithm is one we specified within the registration options
125
+ if (!supportedAlgorithmIDs.includes(alg)) {
126
+ const supported = supportedAlgorithmIDs.join(', ');
127
+ throw new Error(`Unexpected public key alg "${alg}", expected one of "${supported}"`);
128
+ }
129
+ const clientDataHash = await toHash(isoBase64URL.toBuffer(attestationResponse.clientDataJSON));
130
+ const rootCertificates = SettingsService.getRootCertificates({
131
+ identifier: fmt,
132
+ });
133
+ // Prepare arguments to pass to the relevant verification method
134
+ const verifierOpts = {
135
+ aaguid,
136
+ attStmt,
137
+ authData,
138
+ clientDataHash,
139
+ credentialID,
140
+ credentialPublicKey,
141
+ rootCertificates,
142
+ rpIdHash,
143
+ };
144
+ /**
145
+ * Verification can only be performed when attestation = 'direct'
146
+ */
147
+ let verified = false;
148
+ if (fmt === 'fido-u2f') {
149
+ verified = await verifyAttestationFIDOU2F(verifierOpts);
150
+ }
151
+ else if (fmt === 'packed') {
152
+ verified = await verifyAttestationPacked(verifierOpts);
153
+ }
154
+ else if (fmt === 'android-safetynet') {
155
+ verified = await verifyAttestationAndroidSafetyNet(verifierOpts);
156
+ }
157
+ else if (fmt === 'android-key') {
158
+ verified = await verifyAttestationAndroidKey(verifierOpts);
159
+ }
160
+ else if (fmt === 'tpm') {
161
+ verified = await verifyAttestationTPM(verifierOpts);
162
+ }
163
+ else if (fmt === 'apple') {
164
+ verified = await verifyAttestationApple(verifierOpts);
165
+ }
166
+ else if (fmt === 'none') {
167
+ if (attStmt.size > 0) {
168
+ throw new Error('None attestation had unexpected attestation statement');
169
+ }
170
+ // This is the weaker of the attestations, so there's nothing else to really check
171
+ verified = true;
172
+ }
173
+ else {
174
+ throw new Error(`Unsupported Attestation Format: ${fmt}`);
175
+ }
176
+ const toReturn = {
177
+ verified,
178
+ };
179
+ if (toReturn.verified) {
180
+ const { credentialDeviceType, credentialBackedUp } = parseBackupFlags(flags);
181
+ toReturn.registrationInfo = {
182
+ fmt,
183
+ counter,
184
+ aaguid: convertAAGUIDToString(aaguid),
185
+ credentialID,
186
+ credentialPublicKey,
187
+ credentialType,
188
+ attestationObject,
189
+ userVerified: flags.uv,
190
+ credentialDeviceType,
191
+ credentialBackedUp,
192
+ origin: clientDataJSON.origin,
193
+ rpID: matchedRPID,
194
+ authenticatorExtensionResults: extensionsData,
195
+ };
196
+ }
197
+ return toReturn;
198
+ }