mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-27 18:14:52 +09:00
Define HMAC based access token and switch CapSignKey from Ed25519 to HMAC
This commit is contained in:
parent
fdbe46741b
commit
61d1aa6720
3 changed files with 92 additions and 1 deletions
|
@ -64,6 +64,7 @@ import Yesod.Mail.Send
|
|||
import qualified Network.HTTP.Signature as S (Algorithm (..))
|
||||
|
||||
import Network.FedURI
|
||||
import Web.ActivityAccess
|
||||
import Web.ActivityPub hiding (PublicKey)
|
||||
|
||||
import Text.Email.Local
|
||||
|
@ -92,7 +93,7 @@ data App = App
|
|||
, appSvgFont :: PreparedFont Double
|
||||
, appActorKeys :: TVar (ActorKey, ActorKey, Bool)
|
||||
, appInstanceMutex :: InstanceMutex
|
||||
, appCapSignKey :: ActorKey
|
||||
, appCapSignKey :: AccessTokenSecretKey
|
||||
, appHashidEncode :: Int64 -> Text
|
||||
, appHashidDecode :: Text -> Maybe Int64
|
||||
|
||||
|
|
89
src/Web/ActivityAccess.hs
Normal file
89
src/Web/ActivityAccess.hs
Normal file
|
@ -0,0 +1,89 @@
|
|||
{- This file is part of Vervis.
|
||||
-
|
||||
- Written in 2019 by fr33domlover <fr33domlover@riseup.net>.
|
||||
-
|
||||
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||
-
|
||||
- The author(s) have dedicated all copyright and related and neighboring
|
||||
- rights to this software to the public domain worldwide. This software is
|
||||
- distributed without any warranty.
|
||||
-
|
||||
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||
- with this software. If not, see
|
||||
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
-}
|
||||
|
||||
module Web.ActivityAccess
|
||||
( SignedAccessToken ()
|
||||
, AccessTokenSecretKey ()
|
||||
, encodeSignedAccessToken
|
||||
, decodeSignedAccessToken
|
||||
, signAccessToken
|
||||
, verifyAccessToken
|
||||
)
|
||||
where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Crypto.Hash
|
||||
import Crypto.MAC.HMAC
|
||||
import Crypto.Random
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.KeyFile
|
||||
|
||||
import qualified Data.ByteArray as BA
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Base64 as B64
|
||||
import qualified Data.ByteString.Char8 as BC
|
||||
|
||||
data SignedAccessToken = SignedAccessToken
|
||||
{ _accessTokenMsg :: ByteString
|
||||
, _accessTokenHMAC :: HMAC SHA256
|
||||
}
|
||||
|
||||
newtype AccessTokenSecretKey = AccessTokenSecretKey ByteString
|
||||
|
||||
instance KeyFile AccessTokenSecretKey where
|
||||
generateKey = AccessTokenSecretKey <$> getRandomBytes 32
|
||||
parseKey b =
|
||||
if B.length b == 32
|
||||
then return $ AccessTokenSecretKey b
|
||||
else fail "AccessTokenSigningKey parseKey invalid length"
|
||||
renderKey (AccessTokenSecretKey b) = b
|
||||
|
||||
encodeSignedAccessToken :: SignedAccessToken -> ByteString
|
||||
encodeSignedAccessToken (SignedAccessToken msg sig) = B.concat
|
||||
[ msg
|
||||
, "-"
|
||||
, B64.encode $ BA.convert sig
|
||||
]
|
||||
|
||||
decodeSignedAccessToken :: ByteString -> Either String SignedAccessToken
|
||||
decodeSignedAccessToken token = do
|
||||
let (msg, rest) = BC.break (== '-') token
|
||||
sigB64 <-
|
||||
case B.stripPrefix "-" rest of
|
||||
Nothing -> err "Invalid format, separator not found"
|
||||
Just rest' -> return rest'
|
||||
sigBin <-
|
||||
case B64.decode sigB64 of
|
||||
Left s -> err $ "Base64 decoding sig failed: " ++ s
|
||||
Right b -> return b
|
||||
digest <-
|
||||
case digestFromByteString sigBin of
|
||||
Nothing -> err "Decoding sig hash failed, invalid length"
|
||||
Just d -> return d
|
||||
return $ SignedAccessToken msg $ HMAC digest
|
||||
where
|
||||
err s = Left $ "decodeSignedAccessToken: " ++ s
|
||||
|
||||
signAccessToken :: AccessTokenSecretKey -> ByteString -> SignedAccessToken
|
||||
signAccessToken (AccessTokenSecretKey key) msg =
|
||||
SignedAccessToken msg $ hmac key msg
|
||||
|
||||
verifyAccessToken
|
||||
:: AccessTokenSecretKey -> SignedAccessToken -> Maybe ByteString
|
||||
verifyAccessToken (AccessTokenSecretKey key) (SignedAccessToken msg sig) =
|
||||
if hmac key msg == sig
|
||||
then Just msg
|
||||
else Nothing
|
|
@ -86,6 +86,7 @@ library
|
|||
Text.Email.Local
|
||||
Text.FilePath.Local
|
||||
Text.Jasmine.Local
|
||||
Web.ActivityAccess
|
||||
Web.ActivityPub
|
||||
Web.Hashids.Local
|
||||
Web.PathPieces.Local
|
||||
|
|
Loading…
Reference in a new issue