{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module Crypto.WebAuthn.Cose.Internal.Verify
(
PublicKey (..),
fromCose,
fromX509,
verify,
SomeHashAlgorithm (..),
toCryptHashECDSA,
SomeHashAlgorithmASN1 (..),
toCryptHashRSA,
toCryptCurveECDSA,
fromCryptCurveECDSA,
)
where
import Crypto.Error (CryptoFailable (CryptoFailed, CryptoPassed))
import qualified Crypto.Hash as Hash
import Crypto.Number.Serialize (i2osp, i2ospOf, os2ip)
import qualified Crypto.PubKey.ECC.ECDSA as ECDSA
import qualified Crypto.PubKey.ECC.Types as ECC
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Crypto.PubKey.RSA as RSA
import qualified Crypto.PubKey.RSA.PKCS15 as RSA
import qualified Crypto.WebAuthn.Cose.Algorithm as A
import qualified Crypto.WebAuthn.Cose.Key as Cose
import Crypto.WebAuthn.Internal.ToJSONOrphans ()
import qualified Data.ASN1.BinaryEncoding as ASN1
import qualified Data.ASN1.Encoding as ASN1
import qualified Data.ASN1.Types as ASN1
import Data.Aeson (ToJSON)
import Data.ByteArray (convert)
import qualified Data.ByteString as BS
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.X509 as X509
import qualified Data.X509.EC as X509
import GHC.Generics (Generic)
data PublicKey
=
PublicKeyEdDSA
{
PublicKey -> CoseCurveEdDSA
eddsaCurve :: Cose.CoseCurveEdDSA,
PublicKey -> ByteString
eddsaX :: BS.ByteString
}
|
PublicKeyECDSA
{
PublicKey -> CoseCurveECDSA
ecdsaCurve :: Cose.CoseCurveECDSA,
PublicKey -> ByteString
ecdsaX :: BS.ByteString,
PublicKey -> ByteString
ecdsaY :: BS.ByteString
}
|
PublicKeyRSA
{
PublicKey -> Integer
rsaN :: Integer,
PublicKey -> Integer
rsaE :: Integer
}
deriving (PublicKey -> PublicKey -> Bool
(PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicKey -> PublicKey -> Bool
$c/= :: PublicKey -> PublicKey -> Bool
== :: PublicKey -> PublicKey -> Bool
$c== :: PublicKey -> PublicKey -> Bool
Eq, Int -> PublicKey -> ShowS
[PublicKey] -> ShowS
PublicKey -> String
(Int -> PublicKey -> ShowS)
-> (PublicKey -> String)
-> ([PublicKey] -> ShowS)
-> Show PublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicKey] -> ShowS
$cshowList :: [PublicKey] -> ShowS
show :: PublicKey -> String
$cshow :: PublicKey -> String
showsPrec :: Int -> PublicKey -> ShowS
$cshowsPrec :: Int -> PublicKey -> ShowS
Show, (forall x. PublicKey -> Rep PublicKey x)
-> (forall x. Rep PublicKey x -> PublicKey) -> Generic PublicKey
forall x. Rep PublicKey x -> PublicKey
forall x. PublicKey -> Rep PublicKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PublicKey x -> PublicKey
$cfrom :: forall x. PublicKey -> Rep PublicKey x
Generic, [PublicKey] -> Encoding
[PublicKey] -> Value
PublicKey -> Encoding
PublicKey -> Value
(PublicKey -> Value)
-> (PublicKey -> Encoding)
-> ([PublicKey] -> Value)
-> ([PublicKey] -> Encoding)
-> ToJSON PublicKey
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [PublicKey] -> Encoding
$ctoEncodingList :: [PublicKey] -> Encoding
toJSONList :: [PublicKey] -> Value
$ctoJSONList :: [PublicKey] -> Value
toEncoding :: PublicKey -> Encoding
$ctoEncoding :: PublicKey -> Encoding
toJSON :: PublicKey -> Value
$ctoJSON :: PublicKey -> Value
ToJSON)
fromCose :: Cose.CosePublicKey -> PublicKey
fromCose :: CosePublicKey -> PublicKey
fromCose Cose.CosePublicKeyEdDSA {ByteString
CoseCurveEdDSA
eddsaX :: CosePublicKey -> ByteString
eddsaCurve :: CosePublicKey -> CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
..} = PublicKeyEdDSA :: CoseCurveEdDSA -> ByteString -> PublicKey
PublicKeyEdDSA {ByteString
CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
..}
fromCose Cose.CosePublicKeyECDSA {ByteString
CoseHashAlgECDSA
CoseCurveECDSA
ecdsaY :: CosePublicKey -> ByteString
ecdsaX :: CosePublicKey -> ByteString
ecdsaCurve :: CosePublicKey -> CoseCurveECDSA
ecdsaHash :: CosePublicKey -> CoseHashAlgECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaHash :: CoseHashAlgECDSA
..} = PublicKeyECDSA :: CoseCurveECDSA -> ByteString -> ByteString -> PublicKey
PublicKeyECDSA {ByteString
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
..}
fromCose Cose.CosePublicKeyRSA {Integer
CoseHashAlgRSA
rsaE :: CosePublicKey -> Integer
rsaN :: CosePublicKey -> Integer
rsaHash :: CosePublicKey -> CoseHashAlgRSA
rsaE :: Integer
rsaN :: Integer
rsaHash :: CoseHashAlgRSA
..} = PublicKeyRSA :: Integer -> Integer -> PublicKey
PublicKeyRSA {Integer
rsaE :: Integer
rsaN :: Integer
rsaE :: Integer
rsaN :: Integer
..}
fromX509 :: X509.PubKey -> Either Text PublicKey
fromX509 :: PubKey -> Either Text PublicKey
fromX509 (X509.PubKeyEd25519 PublicKey
key) =
PublicKey -> Either Text PublicKey
forall a b. b -> Either a b
Right (PublicKey -> Either Text PublicKey)
-> PublicKey -> Either Text PublicKey
forall a b. (a -> b) -> a -> b
$
PublicKeyEdDSA :: CoseCurveEdDSA -> ByteString -> PublicKey
PublicKeyEdDSA
{ eddsaCurve :: CoseCurveEdDSA
eddsaCurve = CoseCurveEdDSA
Cose.CoseCurveEd25519,
eddsaX :: ByteString
eddsaX = PublicKey -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert PublicKey
key
}
fromX509 (X509.PubKeyEC X509.PubKeyEC_Named {CurveName
SerializedPoint
pubkeyEC_pub :: PubKeyEC -> SerializedPoint
pubkeyEC_name :: PubKeyEC -> CurveName
pubkeyEC_pub :: SerializedPoint
pubkeyEC_name :: CurveName
..}) = do
let curve :: Curve
curve = CurveName -> Curve
ECC.getCurveByName CurveName
pubkeyEC_name
CoseCurveECDSA
ecdsaCurve <- CurveName -> Either Text CoseCurveECDSA
fromCryptCurveECDSA CurveName
pubkeyEC_name
Point
point <- case Curve -> SerializedPoint -> Maybe Point
X509.unserializePoint Curve
curve SerializedPoint
pubkeyEC_pub of
Maybe Point
Nothing -> Text -> Either Text Point
forall a b. a -> Either a b
Left Text
"Failed to unserialize ECDSA point in X509 certificate"
Just Point
res -> Point -> Either Text Point
forall (f :: * -> *) a. Applicative f => a -> f a
pure Point
res
let byteSize :: Int
byteSize = (Curve -> Int
ECC.curveSizeBits Curve
curve Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8
case Point
point of
ECC.Point Integer
x Integer
y -> do
ByteString
ecdsaX <- case Int -> Integer -> Maybe ByteString
forall ba. ByteArray ba => Int -> Integer -> Maybe ba
i2ospOf Int
byteSize Integer
x of
Maybe ByteString
Nothing -> Text -> Either Text ByteString
forall a b. a -> Either a b
Left (Text -> Either Text ByteString) -> Text -> Either Text ByteString
forall a b. (a -> b) -> a -> b
$ Text
"Failed to convert ECDSA x coordinate integer " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Integer -> String
forall a. Show a => a -> String
show Integer
x) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to bytes of size " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Int -> String
forall a. Show a => a -> String
show Int
byteSize)
Just ByteString
res -> ByteString -> Either Text ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
res
ByteString
ecdsaY <- case Int -> Integer -> Maybe ByteString
forall ba. ByteArray ba => Int -> Integer -> Maybe ba
i2ospOf Int
byteSize Integer
y of
Maybe ByteString
Nothing -> Text -> Either Text ByteString
forall a b. a -> Either a b
Left (Text -> Either Text ByteString) -> Text -> Either Text ByteString
forall a b. (a -> b) -> a -> b
$ Text
"Failed to convert ECDSA y coordinate integer " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Integer -> String
forall a. Show a => a -> String
show Integer
y) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to bytes of size " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Int -> String
forall a. Show a => a -> String
show Int
byteSize)
Just ByteString
res -> ByteString -> Either Text ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
res
PublicKey -> Either Text PublicKey
forall a b. b -> Either a b
Right (PublicKey -> Either Text PublicKey)
-> PublicKey -> Either Text PublicKey
forall a b. (a -> b) -> a -> b
$ PublicKeyECDSA :: CoseCurveECDSA -> ByteString -> ByteString -> PublicKey
PublicKeyECDSA {ByteString
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
..}
Point
ECC.PointO -> Text -> Either Text PublicKey
forall a b. a -> Either a b
Left Text
"The infinity point is not supported"
fromX509 (X509.PubKeyRSA RSA.PublicKey {Int
Integer
public_size :: PublicKey -> Int
public_n :: PublicKey -> Integer
public_e :: PublicKey -> Integer
public_e :: Integer
public_n :: Integer
public_size :: Int
..}) =
PublicKey -> Either Text PublicKey
forall a b. b -> Either a b
Right
PublicKeyRSA :: Integer -> Integer -> PublicKey
PublicKeyRSA
{ rsaN :: Integer
rsaN = Integer
public_n,
rsaE :: Integer
rsaE = Integer
public_e
}
fromX509 PubKey
key = Text -> Either Text PublicKey
forall a b. a -> Either a b
Left (Text -> Either Text PublicKey) -> Text -> Either Text PublicKey
forall a b. (a -> b) -> a -> b
$ Text
"X509 public key algorithm is not supported: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (PubKeyALG -> String
forall a. Show a => a -> String
show (PubKey -> PubKeyALG
X509.pubkeyToAlg PubKey
key))
verify :: A.CoseSignAlg -> PublicKey -> BS.ByteString -> BS.ByteString -> Either Text ()
verify :: CoseSignAlg
-> PublicKey -> ByteString -> ByteString -> Either Text ()
verify CoseSignAlg
A.CoseSignAlgEdDSA PublicKeyEdDSA {eddsaCurve :: PublicKey -> CoseCurveEdDSA
eddsaCurve = CoseCurveEdDSA
Cose.CoseCurveEd25519, ByteString
eddsaX :: ByteString
eddsaX :: PublicKey -> ByteString
..} ByteString
msg ByteString
sig = do
PublicKey
key <- case ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
Ed25519.publicKey ByteString
eddsaX of
CryptoFailed CryptoError
err -> Text -> Either Text PublicKey
forall a b. a -> Either a b
Left (Text -> Either Text PublicKey) -> Text -> Either Text PublicKey
forall a b. (a -> b) -> a -> b
$ Text
"Failed to create Ed25519 public key: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (CryptoError -> String
forall a. Show a => a -> String
show CryptoError
err)
CryptoPassed PublicKey
res -> PublicKey -> Either Text PublicKey
forall (f :: * -> *) a. Applicative f => a -> f a
pure PublicKey
res
Signature
sig <- case ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed25519.signature ByteString
sig of
CryptoFailed CryptoError
err -> Text -> Either Text Signature
forall a b. a -> Either a b
Left (Text -> Either Text Signature) -> Text -> Either Text Signature
forall a b. (a -> b) -> a -> b
$ Text
"Failed to create Ed25519 signature: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (CryptoError -> String
forall a. Show a => a -> String
show CryptoError
err)
CryptoPassed Signature
res -> Signature -> Either Text Signature
forall (f :: * -> *) a. Applicative f => a -> f a
pure Signature
res
if PublicKey -> ByteString -> Signature -> Bool
forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
Ed25519.verify PublicKey
key ByteString
msg Signature
sig
then () -> Either Text ()
forall a b. b -> Either a b
Right ()
else Text -> Either Text ()
forall a b. a -> Either a b
Left Text
"EdDSA Signature invalid"
verify (A.CoseSignAlgECDSA (CoseHashAlgECDSA -> SomeHashAlgorithm
toCryptHashECDSA -> SomeHashAlgorithm a
hash)) PublicKeyECDSA {ByteString
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaY :: PublicKey -> ByteString
ecdsaX :: PublicKey -> ByteString
ecdsaCurve :: PublicKey -> CoseCurveECDSA
..} ByteString
msg ByteString
sig = do
let key :: PublicKey
key =
PublicKey :: Curve -> Point -> PublicKey
ECDSA.PublicKey
{ public_curve :: Curve
public_curve = CurveName -> Curve
ECC.getCurveByName (CurveName -> Curve) -> CurveName -> Curve
forall a b. (a -> b) -> a -> b
$ CoseCurveECDSA -> CurveName
toCryptCurveECDSA CoseCurveECDSA
ecdsaCurve,
public_q :: Point
public_q = Integer -> Integer -> Point
ECC.Point (ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
ecdsaX) (ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
ecdsaY)
}
Signature
sig <- case DER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
ASN1.decodeASN1' DER
ASN1.DER ByteString
sig of
Left ASN1Error
err -> Text -> Either Text Signature
forall a b. a -> Either a b
Left (Text -> Either Text Signature) -> Text -> Either Text Signature
forall a b. (a -> b) -> a -> b
$ Text
"Failed to decode ECDSA DER value: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (ASN1Error -> String
forall a. Show a => a -> String
show ASN1Error
err)
Right [ASN1.Start ASN1ConstructionType
ASN1.Sequence, ASN1.IntVal Integer
r, ASN1.IntVal Integer
s, ASN1.End ASN1ConstructionType
ASN1.Sequence] ->
Signature -> Either Text Signature
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Signature -> Either Text Signature)
-> Signature -> Either Text Signature
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Signature
ECDSA.Signature Integer
r Integer
s
Right [ASN1]
asns -> Text -> Either Text Signature
forall a b. a -> Either a b
Left (Text -> Either Text Signature) -> Text -> Either Text Signature
forall a b. (a -> b) -> a -> b
$ Text
"Unexpected ECDSA ASN.1 structure: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack ([ASN1] -> String
forall a. Show a => a -> String
show [ASN1]
asns)
if a -> PublicKey -> Signature -> ByteString -> Bool
forall msg hash.
(ByteArrayAccess msg, HashAlgorithm hash) =>
hash -> PublicKey -> Signature -> msg -> Bool
ECDSA.verify a
hash PublicKey
key Signature
sig ByteString
msg
then () -> Either Text ()
forall a b. b -> Either a b
Right ()
else Text -> Either Text ()
forall a b. a -> Either a b
Left Text
"ECDSA Signature invalid"
verify (A.CoseSignAlgRSA (CoseHashAlgRSA -> SomeHashAlgorithmASN1
toCryptHashRSA -> SomeHashAlgorithmASN1 a
hash)) PublicKeyRSA {Integer
rsaE :: Integer
rsaN :: Integer
rsaE :: PublicKey -> Integer
rsaN :: PublicKey -> Integer
..} ByteString
msg ByteString
sig = do
let key :: PublicKey
key =
PublicKey :: Int -> Integer -> Integer -> PublicKey
RSA.PublicKey
{
public_size :: Int
public_size = ByteString -> Int
BS.length (Integer -> ByteString
forall ba. ByteArray ba => Integer -> ba
i2osp Integer
rsaN),
public_n :: Integer
public_n = Integer
rsaN,
public_e :: Integer
public_e = Integer
rsaE
}
if Maybe a -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (a -> Maybe a
forall a. a -> Maybe a
Just a
hash) PublicKey
key ByteString
msg ByteString
sig
then () -> Either Text ()
forall a b. b -> Either a b
Right ()
else Text -> Either Text ()
forall a b. a -> Either a b
Left Text
"RSA Signature invalid"
verify CoseSignAlg
sigAlg PublicKey
pubKey ByteString
_ ByteString
_ =
Text -> Either Text ()
forall a b. a -> Either a b
Left (Text -> Either Text ()) -> Text -> Either Text ()
forall a b. (a -> b) -> a -> b
$ Text
"Unsupported combination of signature algorithm " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (CoseSignAlg -> String
forall a. Show a => a -> String
show CoseSignAlg
sigAlg) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" and public key " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (PublicKey -> String
forall a. Show a => a -> String
show PublicKey
pubKey)
data SomeHashAlgorithm = forall a. Hash.HashAlgorithm a => SomeHashAlgorithm a
toCryptHashECDSA :: A.CoseHashAlgECDSA -> SomeHashAlgorithm
toCryptHashECDSA :: CoseHashAlgECDSA -> SomeHashAlgorithm
toCryptHashECDSA CoseHashAlgECDSA
A.CoseHashAlgECDSASHA256 = SHA256 -> SomeHashAlgorithm
forall a. HashAlgorithm a => a -> SomeHashAlgorithm
SomeHashAlgorithm SHA256
Hash.SHA256
toCryptHashECDSA CoseHashAlgECDSA
A.CoseHashAlgECDSASHA384 = SHA384 -> SomeHashAlgorithm
forall a. HashAlgorithm a => a -> SomeHashAlgorithm
SomeHashAlgorithm SHA384
Hash.SHA384
toCryptHashECDSA CoseHashAlgECDSA
A.CoseHashAlgECDSASHA512 = SHA512 -> SomeHashAlgorithm
forall a. HashAlgorithm a => a -> SomeHashAlgorithm
SomeHashAlgorithm SHA512
Hash.SHA512
data SomeHashAlgorithmASN1 = forall a. RSA.HashAlgorithmASN1 a => SomeHashAlgorithmASN1 a
toCryptHashRSA :: A.CoseHashAlgRSA -> SomeHashAlgorithmASN1
toCryptHashRSA :: CoseHashAlgRSA -> SomeHashAlgorithmASN1
toCryptHashRSA CoseHashAlgRSA
A.CoseHashAlgRSASHA1 = SHA1 -> SomeHashAlgorithmASN1
forall a. HashAlgorithmASN1 a => a -> SomeHashAlgorithmASN1
SomeHashAlgorithmASN1 SHA1
Hash.SHA1
toCryptHashRSA CoseHashAlgRSA
A.CoseHashAlgRSASHA256 = SHA256 -> SomeHashAlgorithmASN1
forall a. HashAlgorithmASN1 a => a -> SomeHashAlgorithmASN1
SomeHashAlgorithmASN1 SHA256
Hash.SHA256
toCryptHashRSA CoseHashAlgRSA
A.CoseHashAlgRSASHA384 = SHA384 -> SomeHashAlgorithmASN1
forall a. HashAlgorithmASN1 a => a -> SomeHashAlgorithmASN1
SomeHashAlgorithmASN1 SHA384
Hash.SHA384
toCryptHashRSA CoseHashAlgRSA
A.CoseHashAlgRSASHA512 = SHA512 -> SomeHashAlgorithmASN1
forall a. HashAlgorithmASN1 a => a -> SomeHashAlgorithmASN1
SomeHashAlgorithmASN1 SHA512
Hash.SHA512
toCryptCurveECDSA :: Cose.CoseCurveECDSA -> ECC.CurveName
toCryptCurveECDSA :: CoseCurveECDSA -> CurveName
toCryptCurveECDSA CoseCurveECDSA
Cose.CoseCurveP256 = CurveName
ECC.SEC_p256r1
toCryptCurveECDSA CoseCurveECDSA
Cose.CoseCurveP384 = CurveName
ECC.SEC_p384r1
toCryptCurveECDSA CoseCurveECDSA
Cose.CoseCurveP521 = CurveName
ECC.SEC_p521r1
fromCryptCurveECDSA :: ECC.CurveName -> Either Text Cose.CoseCurveECDSA
fromCryptCurveECDSA :: CurveName -> Either Text CoseCurveECDSA
fromCryptCurveECDSA CurveName
ECC.SEC_p256r1 = CoseCurveECDSA -> Either Text CoseCurveECDSA
forall a b. b -> Either a b
Right CoseCurveECDSA
Cose.CoseCurveP256
fromCryptCurveECDSA CurveName
ECC.SEC_p384r1 = CoseCurveECDSA -> Either Text CoseCurveECDSA
forall a b. b -> Either a b
Right CoseCurveECDSA
Cose.CoseCurveP384
fromCryptCurveECDSA CurveName
ECC.SEC_p521r1 = CoseCurveECDSA -> Either Text CoseCurveECDSA
forall a b. b -> Either a b
Right CoseCurveECDSA
Cose.CoseCurveP521
fromCryptCurveECDSA CurveName
curve = Text -> Either Text CoseCurveECDSA
forall a b. a -> Either a b
Left (Text -> Either Text CoseCurveECDSA)
-> Text -> Either Text CoseCurveECDSA
forall a b. (a -> b) -> a -> b
$ Text
"Curve " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (CurveName -> String
forall a. Show a => a -> String
show CurveName
curve) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" is not a supported COSE ECDSA public key curve"