webauthn 0.2.0.0 → 0.3.0.0
raw patch · 11 files changed
+56/−93 lines, 11 filesdep ~aesondep ~basedep ~base16-bytestringPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, base, base16-bytestring, binary, bytestring, cborg, containers, cryptonite, file-embed, lens, serialise, singletons, unordered-containers, uuid, validation
API changes (from Hackage documentation)
- Crypto.WebAuthn.Metadata.Statement.Types: [CTAP2_0] :: ProtocolVersion 'Fido2
- Crypto.WebAuthn.Metadata.Statement.Types: [CTAP2_1] :: ProtocolVersion 'Fido2
- Crypto.WebAuthn.Metadata.Statement.Types: [U2F1_0] :: ProtocolVersion 'FidoU2F
- Crypto.WebAuthn.Metadata.Statement.Types: [U2F1_1] :: ProtocolVersion 'FidoU2F
- Crypto.WebAuthn.Metadata.Statement.Types: [U2F1_2] :: ProtocolVersion 'FidoU2F
- Crypto.WebAuthn.Metadata.Statement.Types: data ProtocolVersion (p :: ProtocolKind)
- Crypto.WebAuthn.Metadata.Statement.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Crypto.WebAuthn.Metadata.Statement.Types.ProtocolVersion p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Classes.Eq (Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Classes.Eq (Crypto.WebAuthn.Metadata.Statement.Types.ProtocolVersion p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Generics.Generic (Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Show.Show (Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement p)
- Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Show.Show (Crypto.WebAuthn.Metadata.Statement.Types.ProtocolVersion p)
+ Crypto.WebAuthn.Metadata.Service.Types: [meIdentifier] :: MetadataEntry (p :: ProtocolKind) -> AuthenticatorIdentifier p
+ Crypto.WebAuthn.Metadata.Statement.Types: instance Data.Aeson.Types.ToJSON.ToJSON Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement
+ Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Classes.Eq Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement
+ Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Generics.Generic Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement
+ Crypto.WebAuthn.Metadata.Statement.Types: instance GHC.Show.Show Crypto.WebAuthn.Metadata.Statement.Types.MetadataStatement
- Crypto.WebAuthn.Metadata.Service.Types: MetadataEntry :: Maybe (MetadataStatement p) -> NonEmpty StatusReport -> Date -> MetadataEntry (p :: ProtocolKind)
+ Crypto.WebAuthn.Metadata.Service.Types: MetadataEntry :: AuthenticatorIdentifier p -> Maybe MetadataStatement -> NonEmpty StatusReport -> Date -> MetadataEntry (p :: ProtocolKind)
- Crypto.WebAuthn.Metadata.Service.Types: SomeMetadataEntry :: AuthenticatorIdentifier p -> MetadataEntry p -> SomeMetadataEntry
+ Crypto.WebAuthn.Metadata.Service.Types: SomeMetadataEntry :: MetadataEntry p -> SomeMetadataEntry
- Crypto.WebAuthn.Metadata.Service.Types: [meMetadataStatement] :: MetadataEntry (p :: ProtocolKind) -> Maybe (MetadataStatement p)
+ Crypto.WebAuthn.Metadata.Service.Types: [meMetadataStatement] :: MetadataEntry (p :: ProtocolKind) -> Maybe MetadataStatement
- Crypto.WebAuthn.Metadata.Statement.Decode: decodeMetadataStatement :: forall p. SingI p => MetadataStatement -> Either (Maybe Text) (MetadataStatement p)
+ Crypto.WebAuthn.Metadata.Statement.Decode: decodeMetadataStatement :: MetadataStatement -> Either (Maybe Text) MetadataStatement
- Crypto.WebAuthn.Metadata.Statement.Types: MetadataStatement :: Text -> Text -> Maybe AlternativeDescriptions -> Word32 -> NonEmpty (ProtocolVersion p) -> NonEmpty AuthenticationAlgorithm -> NonEmpty PublicKeyRepresentationFormat -> NonEmpty WebauthnAttestationType -> NonEmpty VerificationMethodANDCombinations -> NonEmpty KeyProtectionType -> Maybe Bool -> Maybe Bool -> NonEmpty MatcherProtectionType -> Maybe Word16 -> NonEmpty AuthenticatorAttachmentHint -> [TransactionConfirmationDisplayType] -> Maybe Text -> Maybe (NonEmpty DisplayPNGCharacteristicsDescriptor) -> NonEmpty SignedCertificate -> Maybe ByteString -> Maybe (NonEmpty ExtensionDescriptor) -> Maybe AuthenticatorGetInfo -> MetadataStatement (p :: ProtocolKind)
+ Crypto.WebAuthn.Metadata.Statement.Types: MetadataStatement :: Text -> Text -> Maybe AlternativeDescriptions -> Word32 -> NonEmpty Version -> NonEmpty AuthenticationAlgorithm -> NonEmpty PublicKeyRepresentationFormat -> NonEmpty WebauthnAttestationType -> NonEmpty VerificationMethodANDCombinations -> NonEmpty KeyProtectionType -> Maybe Bool -> Maybe Bool -> NonEmpty MatcherProtectionType -> Maybe Word16 -> NonEmpty AuthenticatorAttachmentHint -> [TransactionConfirmationDisplayType] -> Maybe Text -> Maybe (NonEmpty DisplayPNGCharacteristicsDescriptor) -> NonEmpty SignedCertificate -> Maybe ByteString -> Maybe (NonEmpty ExtensionDescriptor) -> Maybe AuthenticatorGetInfo -> MetadataStatement
- Crypto.WebAuthn.Metadata.Statement.Types: [msAlternativeDescriptions] :: MetadataStatement (p :: ProtocolKind) -> Maybe AlternativeDescriptions
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAlternativeDescriptions] :: MetadataStatement -> Maybe AlternativeDescriptions
- Crypto.WebAuthn.Metadata.Statement.Types: [msAttachmentHint] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty AuthenticatorAttachmentHint
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAttachmentHint] :: MetadataStatement -> NonEmpty AuthenticatorAttachmentHint
- Crypto.WebAuthn.Metadata.Statement.Types: [msAttestationRootCertificates] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty SignedCertificate
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAttestationRootCertificates] :: MetadataStatement -> NonEmpty SignedCertificate
- Crypto.WebAuthn.Metadata.Statement.Types: [msAttestationTypes] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty WebauthnAttestationType
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAttestationTypes] :: MetadataStatement -> NonEmpty WebauthnAttestationType
- Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticationAlgorithms] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty AuthenticationAlgorithm
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticationAlgorithms] :: MetadataStatement -> NonEmpty AuthenticationAlgorithm
- Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticatorGetInfo] :: MetadataStatement (p :: ProtocolKind) -> Maybe AuthenticatorGetInfo
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticatorGetInfo] :: MetadataStatement -> Maybe AuthenticatorGetInfo
- Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticatorVersion] :: MetadataStatement (p :: ProtocolKind) -> Word32
+ Crypto.WebAuthn.Metadata.Statement.Types: [msAuthenticatorVersion] :: MetadataStatement -> Word32
- Crypto.WebAuthn.Metadata.Statement.Types: [msCryptoStrength] :: MetadataStatement (p :: ProtocolKind) -> Maybe Word16
+ Crypto.WebAuthn.Metadata.Statement.Types: [msCryptoStrength] :: MetadataStatement -> Maybe Word16
- Crypto.WebAuthn.Metadata.Statement.Types: [msDescription] :: MetadataStatement (p :: ProtocolKind) -> Text
+ Crypto.WebAuthn.Metadata.Statement.Types: [msDescription] :: MetadataStatement -> Text
- Crypto.WebAuthn.Metadata.Statement.Types: [msIcon] :: MetadataStatement (p :: ProtocolKind) -> Maybe ByteString
+ Crypto.WebAuthn.Metadata.Statement.Types: [msIcon] :: MetadataStatement -> Maybe ByteString
- Crypto.WebAuthn.Metadata.Statement.Types: [msIsFreshUserVerificationRequired] :: MetadataStatement (p :: ProtocolKind) -> Maybe Bool
+ Crypto.WebAuthn.Metadata.Statement.Types: [msIsFreshUserVerificationRequired] :: MetadataStatement -> Maybe Bool
- Crypto.WebAuthn.Metadata.Statement.Types: [msIsKeyRestricted] :: MetadataStatement (p :: ProtocolKind) -> Maybe Bool
+ Crypto.WebAuthn.Metadata.Statement.Types: [msIsKeyRestricted] :: MetadataStatement -> Maybe Bool
- Crypto.WebAuthn.Metadata.Statement.Types: [msKeyProtection] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty KeyProtectionType
+ Crypto.WebAuthn.Metadata.Statement.Types: [msKeyProtection] :: MetadataStatement -> NonEmpty KeyProtectionType
- Crypto.WebAuthn.Metadata.Statement.Types: [msLegalHeader] :: MetadataStatement (p :: ProtocolKind) -> Text
+ Crypto.WebAuthn.Metadata.Statement.Types: [msLegalHeader] :: MetadataStatement -> Text
- Crypto.WebAuthn.Metadata.Statement.Types: [msMatcherProtection] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty MatcherProtectionType
+ Crypto.WebAuthn.Metadata.Statement.Types: [msMatcherProtection] :: MetadataStatement -> NonEmpty MatcherProtectionType
- Crypto.WebAuthn.Metadata.Statement.Types: [msPublicKeyAlgAndEncodings] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty PublicKeyRepresentationFormat
+ Crypto.WebAuthn.Metadata.Statement.Types: [msPublicKeyAlgAndEncodings] :: MetadataStatement -> NonEmpty PublicKeyRepresentationFormat
- Crypto.WebAuthn.Metadata.Statement.Types: [msSupportedExtensions] :: MetadataStatement (p :: ProtocolKind) -> Maybe (NonEmpty ExtensionDescriptor)
+ Crypto.WebAuthn.Metadata.Statement.Types: [msSupportedExtensions] :: MetadataStatement -> Maybe (NonEmpty ExtensionDescriptor)
- Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplayContentType] :: MetadataStatement (p :: ProtocolKind) -> Maybe Text
+ Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplayContentType] :: MetadataStatement -> Maybe Text
- Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplayPNGCharacteristics] :: MetadataStatement (p :: ProtocolKind) -> Maybe (NonEmpty DisplayPNGCharacteristicsDescriptor)
+ Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplayPNGCharacteristics] :: MetadataStatement -> Maybe (NonEmpty DisplayPNGCharacteristicsDescriptor)
- Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplay] :: MetadataStatement (p :: ProtocolKind) -> [TransactionConfirmationDisplayType]
+ Crypto.WebAuthn.Metadata.Statement.Types: [msTcDisplay] :: MetadataStatement -> [TransactionConfirmationDisplayType]
- Crypto.WebAuthn.Metadata.Statement.Types: [msUpv] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty (ProtocolVersion p)
+ Crypto.WebAuthn.Metadata.Statement.Types: [msUpv] :: MetadataStatement -> NonEmpty Version
- Crypto.WebAuthn.Metadata.Statement.Types: [msUserVerificationDetails] :: MetadataStatement (p :: ProtocolKind) -> NonEmpty VerificationMethodANDCombinations
+ Crypto.WebAuthn.Metadata.Statement.Types: [msUserVerificationDetails] :: MetadataStatement -> NonEmpty VerificationMethodANDCombinations
- Crypto.WebAuthn.Metadata.Statement.Types: data MetadataStatement (p :: ProtocolKind)
+ Crypto.WebAuthn.Metadata.Statement.Types: data MetadataStatement
Files
- README.md +5/−1
- changelog.md +7/−0
- src/Crypto/WebAuthn.hs +8/−0
- src/Crypto/WebAuthn/Metadata/Service/Decode.hs +3/−4
- src/Crypto/WebAuthn/Metadata/Service/Processing.hs +4/−11
- src/Crypto/WebAuthn/Metadata/Service/Types.hs +5/−3
- src/Crypto/WebAuthn/Metadata/Statement/Decode.hs +3/−22
- src/Crypto/WebAuthn/Metadata/Statement/Types.hs +4/−34
- src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs +0/−1
- src/Crypto/WebAuthn/Operation/Registration.hs +1/−1
- webauthn.cabal +16/−16
README.md view
@@ -39,7 +39,11 @@ To get started with the library it is best to read the documentation of the `Crypto.WebAuthn` module. An example of how to use this library to implement a relying party can be found in the `server` directory, particularly the-`server/src/Main.hs` module.+`server/src/Main.hs` module. Additionally, we highly recommend reading the+[relying party section](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations-rp)+of the+[WebAuthn security considerations chapter](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations)+before implementing a relying party. ## Developing the Library The [Haskell Language Server (hls)][hls] and [Ormolu][ormolu] are highly
changelog.md view
@@ -1,3 +1,10 @@+### 0.3.0.0++* [#125](https://github.com/tweag/webauthn/pull/125) Some small metadata type+ simplifications involving `msUpv` and `SomeMetadataEntry`+* [#126](https://github.com/tweag/webauthn/pull/126) Decrease lower bounds of+ many dependencies including `base`, adding compatibility with GHC 8.8+ ### 0.2.0.0 * [#115](https://github.com/tweag/webauthn/pull/115) Increase the upper bound
src/Crypto/WebAuthn.hs view
@@ -79,6 +79,14 @@ -- [a potential implementation](https://github.com/tweag/webauthn/blob/master/server/www/unauthenticated.js). -- See also these [Sample API Usage Scenarios](https://www.w3.org/TR/webauthn-2/#sctn-sample-scenarios). --+-- == WebAuthn Security considerations+--+-- [Chapter 13](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations)+-- details the security considerations of WebAuthn. It is highly recommend to+-- read at least the+-- [relying party section](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations-rp)+-- of these considerations before implementing a relying party.+-- -- == Library -- -- The two ceremonies described above are very similar in many ways. Because of
src/Crypto/WebAuthn/Metadata/Service/Decode.hs view
@@ -55,19 +55,18 @@ Left Nothing (Nothing, Just aaguid, Nothing) -> do -- This is a FIDO 2 entry- identifier <- first Just $ decodeAAGUID aaguid+ meIdentifier <- first Just $ decodeAAGUID aaguid meMetadataStatement <- traverse decodeMetadataStatement metadataStatement meStatusReports <- first Just $ traverse decodeStatusReport statusReports meTimeOfLastStatusChange <- first Just $ decodeDate timeOfLastStatusChange- Right $ pure $ ServiceTypes.SomeMetadataEntry identifier ServiceTypes.MetadataEntry {..}+ Right $ pure $ ServiceTypes.SomeMetadataEntry ServiceTypes.MetadataEntry {..} (Nothing, Nothing, Just attestationCertificateKeyIdentifiers) -> do -- This is a FIDO U2F entry identifiers <- first Just $ traverse decodeSubjectKeyIdentifier attestationCertificateKeyIdentifiers meMetadataStatement <- traverse decodeMetadataStatement metadataStatement meStatusReports <- first Just $ traverse decodeStatusReport statusReports meTimeOfLastStatusChange <- first Just $ decodeDate timeOfLastStatusChange- let entry = ServiceTypes.MetadataEntry {..}- Right $ fmap (`ServiceTypes.SomeMetadataEntry` entry) identifiers+ Right $ fmap (\meIdentifier -> ServiceTypes.SomeMetadataEntry ServiceTypes.MetadataEntry {..}) identifiers (Nothing, Nothing, Nothing) -> Left $ Just "None of aaid, aaguid or attestationCertificateKeyIdentifiers are set for this entry" _ ->
src/Crypto/WebAuthn/Metadata/Service/Processing.hs view
@@ -4,7 +4,6 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} -- | Stability: experimental@@ -49,12 +48,7 @@ import qualified Crypto.WebAuthn.Model as M import Crypto.WebAuthn.Model.Identifier ( AAGUID,- AuthenticatorIdentifier- ( AuthenticatorIdentifierFido2,- AuthenticatorIdentifierFidoU2F,- idAaguid,- idSubjectKeyIdentifier- ),+ AuthenticatorIdentifier (AuthenticatorIdentifierFido2, AuthenticatorIdentifierFidoU2F), SubjectKeyIdentifier, ) import Data.Aeson (Value)@@ -67,7 +61,6 @@ import qualified Data.HashMap.Strict as HashMap import Data.Hourglass (DateTime) import qualified Data.List.NonEmpty as NE-import Data.Singletons (singByProxy) import Data.Text (Text) import qualified Data.Text as Text import qualified Data.X509 as X509@@ -222,9 +215,9 @@ (fido2Pairs, fidoU2FPairs) = partitionEithers $ map fromSomeMetadataEntry entries fromSomeMetadataEntry :: Service.SomeMetadataEntry -> Either (AAGUID, Service.MetadataEntry 'M.Fido2) (SubjectKeyIdentifier, Service.MetadataEntry 'M.FidoU2F)- fromSomeMetadataEntry (Service.SomeMetadataEntry ident entry) = case singByProxy ident of- M.SFido2 -> Left (idAaguid ident, entry)- M.SFidoU2F -> Right (idSubjectKeyIdentifier ident, entry)+ fromSomeMetadataEntry (Service.SomeMetadataEntry entry@Service.MetadataEntry {..}) = case meIdentifier of+ AuthenticatorIdentifierFido2 aaguid -> Left (aaguid, entry)+ AuthenticatorIdentifierFidoU2F subjectKeyIdentifier -> Right (subjectKeyIdentifier, entry) -- | Query a 'Service.MetadataEntry' for an 'M.AuthenticatorIdentifier' queryMetadata ::
src/Crypto/WebAuthn/Metadata/Service/Types.hs view
@@ -73,8 +73,10 @@ -- Same as 'StatementIDL.MetadataBLOBPayloadEntry', but fully decoded. This type -- is parametrized over the 'StatementIDL.ProtocolFamily' this metadata entry is for data MetadataEntry (p :: M.ProtocolKind) = MetadataEntry- { -- [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-metadatastatement)- meMetadataStatement :: Maybe (MetadataStatement p),+ { -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-aaguid) or [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-attestationcertificatekeyidentifiers)+ meIdentifier :: AuthenticatorIdentifier p,+ -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-metadatastatement)+ meMetadataStatement :: Maybe MetadataStatement, -- TODO: Implement this, currently not used in the blob however -- meBiometricStatusReports :: Maybe (NonEmpty BiometricStatusReport), @@ -88,7 +90,7 @@ deriving (Eq, Show, Generic, ToJSON) -- | Same as 'MetadataEntry', but with its type parameter erased-data SomeMetadataEntry = forall p. SingI p => SomeMetadataEntry (AuthenticatorIdentifier p) (MetadataEntry p)+data SomeMetadataEntry = forall p. SingI p => SomeMetadataEntry (MetadataEntry p) -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#statusreport-dictionary) -- Same as 'StatementIDL.StatusReport', but fully decoded.
src/Crypto/WebAuthn/Metadata/Statement/Decode.hs view
@@ -1,7 +1,5 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-} -- | Stability: experimental -- This module contains functions to further decode@@ -21,7 +19,6 @@ import Crypto.WebAuthn.Metadata.Statement.Types (WebauthnAttestationType (WebauthnAttestationAttCA, WebauthnAttestationBasic)) import qualified Crypto.WebAuthn.Metadata.Statement.Types as StatementTypes import qualified Crypto.WebAuthn.Metadata.Statement.WebIDL as StatementIDL-import qualified Crypto.WebAuthn.Metadata.UAF as UAF import qualified Crypto.WebAuthn.Model as M import Crypto.WebAuthn.Model.Identifier (AAGUID (AAGUID), AuthenticatorIdentifier (AuthenticatorIdentifierFido2, AuthenticatorIdentifierFidoU2F), SubjectKeyIdentifier (SubjectKeyIdentifier)) import qualified Crypto.WebAuthn.WebIDL as IDL@@ -32,7 +29,6 @@ import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NE import Data.Maybe (mapMaybe)-import Data.Singletons (SingI, sing) import Data.Text (Text) import qualified Data.Text as Text import Data.Text.Encoding (encodeUtf8)@@ -68,25 +64,21 @@ -- | Fully decodes a [MetadataStatement](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys). -- The @p@ type parameter is the 'StatementIDL.ProtocolFamily' that this metadata statement is for. decodeMetadataStatement ::- forall p.- SingI p => -- | The raw metadata statement, directly parsed from JSON StatementIDL.MetadataStatement -> -- | Either an early exit with 'Left', where @Left Nothing@ signals that -- this entry can be skipped because it's not relevant for Webauthn, and -- @Left . Just@ signals that an error happened during decoding -- Otherwise a successful result with 'Right'- Either (Maybe Text) (StatementTypes.MetadataStatement p)+ Either (Maybe Text) StatementTypes.MetadataStatement decodeMetadataStatement StatementIDL.MetadataStatement {..} = do let msLegalHeader = legalHeader msDescription = description msAlternativeDescriptions = alternativeDescriptions msAuthenticatorVersion = authenticatorVersion unless (schema == 3) $ Left $ Just $ "Schema version is not 3 but " <> Text.pack (show schema)- msUpv <- case sing @p of- M.SFidoU2F -> first Just $ traverse decodeUpvFidoU2F upv- M.SFido2 -> first Just $ traverse decodeUpvFido2 upv- let msAuthenticationAlgorithms = authenticationAlgorithms+ let msUpv = upv+ msAuthenticationAlgorithms = authenticationAlgorithms msPublicKeyAlgAndEncodings = publicKeyAlgAndEncodings msAttestationTypes <- decodeAttestationTypes attestationTypes let msUserVerificationDetails = userVerificationDetails@@ -109,17 +101,6 @@ msAuthenticatorGetInfo = authenticatorGetInfo pure $ StatementTypes.MetadataStatement {..} where- decodeUpvFidoU2F :: UAF.Version -> Either Text (StatementTypes.ProtocolVersion 'M.FidoU2F)- decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 0} = Right StatementTypes.U2F1_0- decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 1} = Right StatementTypes.U2F1_1- decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 2} = Right StatementTypes.U2F1_2- decodeUpvFidoU2F version = Left $ "Unknown FIDO U2F UPV version: " <> Text.pack (show version)-- decodeUpvFido2 :: UAF.Version -> Either Text (StatementTypes.ProtocolVersion 'M.Fido2)- decodeUpvFido2 UAF.Version {UAF.major = 1, UAF.minor = 0} = Right StatementTypes.CTAP2_0- decodeUpvFido2 UAF.Version {UAF.major = 1, UAF.minor = 1} = Right StatementTypes.CTAP2_1- decodeUpvFido2 version = Left $ "Unknown FIDO2 UPV version: " <> Text.pack (show version)- -- Turns a non-empty list of 'Registry.AuthenticatorAttestationType' into a non-empty list of 'WebauthnAttestationType'. -- If the authenticator doesn't support any webauthn attestation types, -- `Left Nothing` is returned, indicating that this authenticator should be ignored
src/Crypto/WebAuthn/Metadata/Statement/Types.hs view
@@ -1,23 +1,17 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE StandaloneDeriving #-}- -- | Stability: experimental -- This module contains additional Haskell-specific type definitions for the -- [FIDO Metadata Statement](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html) -- specification module Crypto.WebAuthn.Metadata.Statement.Types ( MetadataStatement (..),- ProtocolVersion (..), WebauthnAttestationType (..), ) where import qualified Crypto.WebAuthn.Metadata.FidoRegistry as Registry import qualified Crypto.WebAuthn.Metadata.Statement.WebIDL as StatementIDL-import qualified Crypto.WebAuthn.Model as M-import Data.Aeson (ToJSON, toJSON)+import qualified Crypto.WebAuthn.Metadata.UAF as UAF+import Data.Aeson (ToJSON) import qualified Data.ByteString as BS import Data.List.NonEmpty (NonEmpty) import Data.Text (Text)@@ -27,7 +21,7 @@ import GHC.Word (Word16) -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys)-data MetadataStatement (p :: M.ProtocolKind) = MetadataStatement+data MetadataStatement = MetadataStatement { -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-legalheader) msLegalHeader :: Text, -- msAaid, msAaguid, attestationCertificateKeyIdentifiers: These fields are the key of the hashmaps in MetadataServiceRegistry@@ -42,7 +36,7 @@ -- msSchema, this is always schema version 3 -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-upv)- msUpv :: NonEmpty (ProtocolVersion p),+ msUpv :: NonEmpty UAF.Version, -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-authenticationalgorithms) msAuthenticationAlgorithms :: NonEmpty Registry.AuthenticationAlgorithm, -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-publickeyalgandencodings)@@ -81,30 +75,6 @@ msAuthenticatorGetInfo :: Maybe StatementIDL.AuthenticatorGetInfo } deriving (Eq, Show, Generic, ToJSON)---- | FIDO protocol versions, parametrized by the protocol family-data ProtocolVersion (p :: M.ProtocolKind) where- -- | FIDO U2F 1.0- U2F1_0 :: ProtocolVersion 'M.FidoU2F- -- | FIDO U2F 1.1- U2F1_1 :: ProtocolVersion 'M.FidoU2F- -- | FIDO U2F 1.2- U2F1_2 :: ProtocolVersion 'M.FidoU2F- -- | FIDO 2, CTAP 2.0- CTAP2_0 :: ProtocolVersion 'M.Fido2- -- | FIDO 2, CTAP 2.1- CTAP2_1 :: ProtocolVersion 'M.Fido2--deriving instance Eq (ProtocolVersion p)--deriving instance Show (ProtocolVersion p)--instance ToJSON (ProtocolVersion p) where- toJSON U2F1_0 = "U2F 1.0"- toJSON U2F1_1 = "U2F 1.1"- toJSON U2F1_2 = "U2F 1.2"- toJSON CTAP2_0 = "CTAP 2.0"- toJSON CTAP2_1 = "CTAP 2.1" -- | Values of 'Registry.AuthenticatorAttestationType' but limited to the ones possible with Webauthn, see https://www.w3.org/TR/webauthn-2/#sctn-attestation-types data WebauthnAttestationType
src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE DataKinds #-} {-# LANGUAGE DuplicateRecordFields #-} -- | Stability: experimental
src/Crypto/WebAuthn/Operation/Registration.hs view
@@ -513,7 +513,7 @@ -- | Metadata statements can convey multiple attestation types. -- In such a case we choose to result in the Uncertain type. -- Otherwise, we results in the only one available.-fixupVerifiableAttestationType :: M.VerifiableAttestationType -> Meta.MetadataStatement p -> M.VerifiableAttestationType+fixupVerifiableAttestationType :: M.VerifiableAttestationType -> Meta.MetadataStatement -> M.VerifiableAttestationType fixupVerifiableAttestationType M.VerifiableAttestationTypeUncertain statement = case Meta.msAttestationTypes statement of -- If there are multiple types we can't know which one it is
webauthn.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: webauthn-version: 0.2.0.0+version: 0.3.0.0 license: Apache-2.0 license-file: LICENSE copyright:@@ -73,33 +73,33 @@ import: sanity hs-source-dirs: src build-depends:- base >= 4.14.3 && < 4.15,- aeson >= 1.4.7.1 && < 2.1,+ base >= 4.13.0 && < 4.15,+ aeson >= 1.4.7 && < 2.1, asn1-encoding >= 0.9.6 && < 0.10, asn1-parse >= 0.9.5 && < 0.10, asn1-types >= 0.3.4 && < 0.4,- base16-bytestring >= 1.0.2 && < 1.1,+ base16-bytestring >= 1.0.0 && < 1.1, base64-bytestring >= 1.2.1 && < 1.3,- binary >= 0.8.8 && < 0.9,- bytestring >= 0.10.12 && < 0.11,- cborg >= 0.2.6 && < 0.3,- containers >= 0.6.5 && < 0.7,- cryptonite >= 0.29 && < 0.30,- file-embed >= 0.0.15 && < 0.1,+ binary >= 0.8.7 && < 0.9,+ bytestring >= 0.10.10 && < 0.11,+ cborg >= 0.2.4 && < 0.3,+ containers >= 0.6.2 && < 0.7,+ cryptonite >= 0.27 && < 0.30,+ file-embed >= 0.0.11 && < 0.1, hashable >= 1.3.0 && < 1.5, hourglass >= 0.2.12 && < 0.3, jose >= 0.8.5 && < 0.10,- lens >= 4.19.2 && < 4.20,+ lens >= 4.18.1 && < 4.20, memory >= 0.15.0 && < 0.16, monad-time >= 0.3.1 && < 0.4, mtl >= 2.2.2 && < 2.3,- serialise >= 0.2.4 && < 0.3,- singletons >= 2.7 && < 2.8,+ serialise >= 0.2.3 && < 0.3,+ singletons >= 2.6 && < 2.8, text >= 1.2.4 && < 1.3, time >= 1.9.3 && < 1.10,- unordered-containers >= 0.2.11.0 && < 0.3,- uuid >= 1.3.15 && < 1.4,- validation >= 1.1.2 && < 1.2,+ unordered-containers >= 0.2.11 && < 0.3,+ uuid >= 1.3.13 && < 1.4,+ validation >= 1.1 && < 1.2, x509 >= 1.7.5 && < 1.8, x509-store >= 1.6.7 && < 1.7, x509-validation >= 1.6.12 && < 1.7