module Test.MLS.Keys where import API.Galley import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Base64.URL as B64U import qualified Data.ByteString.Char8 as B8 import SetupHelpers import Testlib.Prelude testRawPublicKeys :: (HasCallStack) => App () testRawPublicKeys :: HasCallStack => App () testRawPublicKeys = do Value u <- Domain -> App Value forall domain. (HasCallStack, MakesValue domain) => domain -> App Value randomUserId Domain OwnDomain Value keys <- Value -> App Response forall user. (HasCallStack, MakesValue user) => user -> App Response getMLSPublicKeys Value u App Response -> (Response -> App Value) -> App Value forall a b. App a -> (a -> App b) -> App b forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= HasCallStack => Int -> Response -> App Value Int -> Response -> App Value getJSON Int 200 do String pubkeyS <- Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ed25519" App Value -> (App Value -> App String) -> App String forall a b. a -> (a -> b) -> b & App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString ByteString pubkey <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64.decode (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyS ByteString -> Int B8.length ByteString pubkey Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 32 do String pubkeyS <- Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp256r1_sha256" App Value -> (App Value -> App String) -> App String forall a b. a -> (a -> b) -> b & App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString ByteString pubkey <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64.decode (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyS ByteString -> Int B8.length ByteString pubkey Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 65 do String pubkeyS <- Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp384r1_sha384" App Value -> (App Value -> App String) -> App String forall a b. a -> (a -> b) -> b & App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString ByteString pubkey <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64.decode (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyS ByteString -> Int B8.length ByteString pubkey Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 97 do String pubkeyS <- Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp521r1_sha512" App Value -> (App Value -> App String) -> App String forall a b. a -> (a -> b) -> b & App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString ByteString pubkey <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64.decode (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyS ByteString -> Int B8.length ByteString pubkey Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 133 testJWKPublicKeys :: (HasCallStack) => App () testJWKPublicKeys :: HasCallStack => App () testJWKPublicKeys = do Value u <- Domain -> App Value forall domain. (HasCallStack, MakesValue domain) => domain -> App Value randomUserId Domain OwnDomain Value keys <- Value -> App Response forall user. (HasCallStack, MakesValue user) => user -> App Response getMLSPublicKeysJWK Value u App Response -> (Response -> App Value) -> App Value forall a b. App a -> (a -> App b) -> App b forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= HasCallStack => Int -> Response -> App Value Int -> Response -> App Value getJSON Int 200 do Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ed25519.crv" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "Ed25519" Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ed25519.kty" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "OKP" String pubkeyS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ed25519.x" ByteString pubkey <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyS ByteString -> Int B8.length ByteString pubkey Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 32 do Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp256r1_sha256.crv" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "P-256" Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp256r1_sha256.kty" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "EC" String pubkeyXS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp256r1_sha256.x" ByteString pubkeyX <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyXS ByteString -> Int B8.length ByteString pubkeyX Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 32 String pubkeyYS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp256r1_sha256.y" ByteString pubkeyY <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyYS ByteString -> Int B8.length ByteString pubkeyY Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 32 do Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp384r1_sha384.crv" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "P-384" Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp384r1_sha384.kty" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "EC" String pubkeyXS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp384r1_sha384.x" ByteString pubkeyX <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyXS ByteString -> Int B8.length ByteString pubkeyX Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 48 String pubkeyYS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp384r1_sha384.y" ByteString pubkeyY <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyYS ByteString -> Int B8.length ByteString pubkeyY Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 48 do Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp521r1_sha512.crv" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "P-521" Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp521r1_sha512.kty" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "EC" String pubkeyXS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp521r1_sha512.x" ByteString pubkeyX <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyXS ByteString -> Int B8.length ByteString pubkeyX Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 66 String pubkeyYS <- App Value -> App String forall a. (HasCallStack, MakesValue a) => a -> App String asString (App Value -> App String) -> App Value -> App String forall a b. (a -> b) -> a -> b $ Value keys Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "removal.ecdsa_secp521r1_sha512.y" ByteString pubkeyY <- [ByteString] -> App ByteString forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a assertOne ([ByteString] -> App ByteString) -> (ByteString -> [ByteString]) -> ByteString -> App ByteString forall b c a. (b -> c) -> (a -> b) -> a -> c . Either String ByteString -> [ByteString] forall a. Either String a -> [a] forall (t :: * -> *) a. Foldable t => t a -> [a] toList (Either String ByteString -> [ByteString]) -> (ByteString -> Either String ByteString) -> ByteString -> [ByteString] forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String ByteString B64U.decodeUnpadded (ByteString -> App ByteString) -> ByteString -> App ByteString forall a b. (a -> b) -> a -> b $ String -> ByteString B8.pack String pubkeyYS ByteString -> Int B8.length ByteString pubkeyY Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 66 testPublicKeysMLSNotEnabled :: (HasCallStack) => App () testPublicKeysMLSNotEnabled :: HasCallStack => App () testPublicKeysMLSNotEnabled = ServiceOverrides -> (HasCallStack => String -> App ()) -> App () forall a. HasCallStack => ServiceOverrides -> (HasCallStack => String -> App a) -> App a withModifiedBackend ServiceOverrides forall a. Default a => a def { galleyCfg = removeField "settings.mlsPrivateKeyPaths" } ((HasCallStack => String -> App ()) -> App ()) -> (HasCallStack => String -> App ()) -> App () forall a b. (a -> b) -> a -> b $ \String domain -> do Value alice <- String -> App Value forall domain. (HasCallStack, MakesValue domain) => domain -> App Value randomUserId String domain App Response -> (Response -> App ()) -> App () forall a. HasCallStack => App Response -> (Response -> App a) -> App a bindResponse (Value -> App Response forall user. (HasCallStack, MakesValue user) => user -> App Response getMLSPublicKeys Value alice) ((Response -> App ()) -> App ()) -> (Response -> App ()) -> App () forall a b. (a -> b) -> a -> b $ \Response resp -> do Response resp.status Int -> Int -> App () forall a. (MakesValue a, HasCallStack) => a -> Int -> App () `shouldMatchInt` Int 400 Response resp.json App Value -> String -> App Value forall a. (HasCallStack, MakesValue a) => a -> String -> App Value %. String "label" App Value -> String -> App () forall a b. (MakesValue a, MakesValue b, HasCallStack) => a -> b -> App () `shouldMatch` String "mls-not-enabled"