fix digest generation maybe?
This commit is contained in:
parent
f8a786e455
commit
a094f7a403
5 changed files with 16 additions and 30 deletions
|
@ -57,6 +57,7 @@ library
|
||||||
, req
|
, req
|
||||||
, modern-uri
|
, modern-uri
|
||||||
, base64
|
, base64
|
||||||
|
, memory
|
||||||
, crypton
|
, crypton
|
||||||
, crypton-x509
|
, crypton-x509
|
||||||
, cryptostore
|
, cryptostore
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
module Fedi.Crypto where
|
module Fedi.Crypto where
|
||||||
|
|
||||||
import Crypto.Hash qualified as Crypto
|
import Crypto.Hash qualified as Crypto
|
||||||
|
import Data.ByteArray qualified as BA
|
||||||
import Crypto.PubKey.RSA.PSS qualified as Crypto
|
import Crypto.PubKey.RSA.PSS qualified as Crypto
|
||||||
import Crypto.Store.X509 qualified as Crypto
|
import Crypto.Store.X509 qualified as Crypto
|
||||||
import Crypto.Store.PKCS8 qualified as Crypto
|
import Crypto.Store.PKCS8 qualified as Crypto
|
||||||
|
@ -21,16 +22,6 @@ verifyPub pubkeypem sig message = do
|
||||||
_ -> throw "failed to read pubkey pem"
|
_ -> throw "failed to read pubkey pem"
|
||||||
pure $ Crypto.verify (Crypto.defaultPSSParams Crypto.SHA256) pubkey message sig
|
pure $ Crypto.verify (Crypto.defaultPSSParams Crypto.SHA256) pubkey message sig
|
||||||
|
|
||||||
verifyDigest :: MonadThrow m => ByteString -> ByteString -> ByteString -> m Bool
|
|
||||||
verifyDigest pubkeypem sig digest' = do
|
|
||||||
pubkey <-
|
|
||||||
case Crypto.readPubKeyFileFromMemory pubkeypem of
|
|
||||||
[Crypto.PubKeyRSA pubkey'] -> pure pubkey'
|
|
||||||
_ -> throw "failed to read pubkey pem"
|
|
||||||
let
|
|
||||||
digest = Crypto.hash digest'
|
|
||||||
pure $ Crypto.verifyDigest (Crypto.defaultPSSParams Crypto.SHA256) pubkey digest sig
|
|
||||||
|
|
||||||
sign :: UserDetails -> ByteString -> IO Signed
|
sign :: UserDetails -> ByteString -> IO Signed
|
||||||
sign details message = do
|
sign details message = do
|
||||||
-- get private key
|
-- get private key
|
||||||
|
@ -43,21 +34,12 @@ sign details message = do
|
||||||
signedMessage <- either (throw . show) pure =<<
|
signedMessage <- either (throw . show) pure =<<
|
||||||
Crypto.sign Nothing (Crypto.defaultPSSParams Crypto.SHA256) privateKey message
|
Crypto.sign Nothing (Crypto.defaultPSSParams Crypto.SHA256) privateKey message
|
||||||
|
|
||||||
-- sign digest
|
|
||||||
let
|
|
||||||
digest :: Crypto.Digest Crypto.SHA256
|
|
||||||
digest = Crypto.hash message
|
|
||||||
|
|
||||||
signedDigest <- either (throw . show) pure =<<
|
|
||||||
Crypto.signDigest Nothing (Crypto.defaultPSSParams Crypto.SHA256) privateKey digest
|
|
||||||
|
|
||||||
-- return
|
-- return
|
||||||
pure Signed{..}
|
pure Signed{..}
|
||||||
|
|
||||||
data Signed
|
newtype Signed
|
||||||
= Signed
|
= Signed
|
||||||
{ signedMessage :: ByteString
|
{ signedMessage :: ByteString
|
||||||
, signedDigest :: ByteString
|
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
@ -66,7 +48,6 @@ ppSigned signed =
|
||||||
unlines
|
unlines
|
||||||
[ "Signature"
|
[ "Signature"
|
||||||
, "{ signedMessage = " <> encodeBase64String signed.signedMessage
|
, "{ signedMessage = " <> encodeBase64String signed.signedMessage
|
||||||
, ", signedDigest = " <> encodeBase64String signed.signedDigest
|
|
||||||
, "}"
|
, "}"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -79,6 +60,6 @@ encodeBase64String = T.unpack . Base64.extractBase64 . Base64.encodeBase64
|
||||||
decodeBase64 :: ByteString -> ByteString
|
decodeBase64 :: ByteString -> ByteString
|
||||||
decodeBase64 = Base64.decodeBase64Lenient
|
decodeBase64 = Base64.decodeBase64Lenient
|
||||||
|
|
||||||
makeDigest :: ByteString -> String
|
makeDigest :: ByteString -> ByteString
|
||||||
makeDigest message =
|
makeDigest message =
|
||||||
show (Crypto.hash message :: Crypto.Digest Crypto.SHA256)
|
BA.convert (Crypto.hash message :: Crypto.Digest Crypto.SHA256)
|
||||||
|
|
|
@ -48,7 +48,7 @@ checkSignatureAndParseBody = do
|
||||||
checkSignature
|
checkSignature
|
||||||
:: MonadThrow m
|
:: MonadThrow m
|
||||||
=> Url -> ByteString -> SignatureHeader -> ByteString -> ByteString -> m ()
|
=> Url -> ByteString -> SignatureHeader -> ByteString -> ByteString -> m ()
|
||||||
checkSignature personPkid personPublicKey sigheader digest body = do
|
checkSignature personPkid personPublicKey sigheader _digest body = do
|
||||||
-- check
|
-- check
|
||||||
unless (personPkid == sigheader.keyId) $
|
unless (personPkid == sigheader.keyId) $
|
||||||
throw "public key mismatch with signature."
|
throw "public key mismatch with signature."
|
||||||
|
@ -57,9 +57,10 @@ checkSignature personPkid personPublicKey sigheader digest body = do
|
||||||
unless pub $
|
unless pub $
|
||||||
throw "signature verification failed."
|
throw "signature verification failed."
|
||||||
|
|
||||||
dig <- verifyDigest personPublicKey digest body
|
-- dig <- verifyDigest personPublicKey digest body
|
||||||
unless dig $
|
-- unless dig $
|
||||||
throw "digest verification failed."
|
-- throw "digest verification failed."
|
||||||
|
|
||||||
-- todo: check date
|
-- todo: check date
|
||||||
|
|
||||||
parseSignature :: MonadThrow m => Maybe T.Text -> m SignatureHeader
|
parseSignature :: MonadThrow m => Maybe T.Text -> m SignatureHeader
|
||||||
|
|
|
@ -23,7 +23,7 @@ signSignature details host requestTarget body = do
|
||||||
<&> Time.formatTime Time.defaultTimeLocale Time.rfc822DateFormat
|
<&> Time.formatTime Time.defaultTimeLocale Time.rfc822DateFormat
|
||||||
|
|
||||||
let
|
let
|
||||||
digest = encodeBase64 $ fromString $ makeDigest body
|
digest = "SHA-256=" <> encodeBase64 (makeDigest body)
|
||||||
keyId = actorUrl details <> "#main-key"
|
keyId = actorUrl details <> "#main-key"
|
||||||
headers = ["(request-target)", "host", "date", "digest"]
|
headers = ["(request-target)", "host", "date", "digest"]
|
||||||
components = []
|
components = []
|
||||||
|
@ -44,5 +44,5 @@ makeSignatureString host requestTarget date digest =
|
||||||
[ "(request-target): " <> fromString requestTarget
|
[ "(request-target): " <> fromString requestTarget
|
||||||
, "host: " <> fromString host
|
, "host: " <> fromString host
|
||||||
, "date: " <> fromString date
|
, "date: " <> fromString date
|
||||||
, "digest: SHA-256=" <> digest
|
, "digest: " <> digest
|
||||||
]
|
]
|
||||||
|
|
|
@ -48,7 +48,10 @@ instance (ToObject a) => A.ToJSON (Object a) where
|
||||||
instance (ToObject a) => ToObject (Object a) where
|
instance (ToObject a) => ToObject (Object a) where
|
||||||
toObject object =
|
toObject object =
|
||||||
[ "@context"
|
[ "@context"
|
||||||
A..= ("https://www.w3.org/ns/activitystreams" :: String)
|
A..=
|
||||||
|
[ ("https://www.w3.org/ns/activitystreams" :: String)
|
||||||
|
, ("https://w3id.org/security/v1" :: String)
|
||||||
|
]
|
||||||
]
|
]
|
||||||
<> toObject object.otype
|
<> toObject object.otype
|
||||||
<> [ assignment
|
<> [ assignment
|
||||||
|
|
Loading…
Add table
Reference in a new issue