From 0cd3563aa0df0f0d8a145a4c5247e378023f6c5c Mon Sep 17 00:00:00 2001 From: Jonathan Knowles Date: Wed, 22 May 2024 06:17:27 +0000 Subject: [PATCH 1/3] Add test that attempts to encrypt multiple tx metadata messages. --- .../Scenario/API/Shelley/TransactionsNew.hs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs index bc9ed3eada2..330c8bdfeed 100644 --- a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs +++ b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs @@ -599,6 +599,36 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do ] checkMetadataEncryption ctx toBeEncrypted metadataRaw + it "TRANS_NEW_CREATE_02d - \ + \Attempt to encrypt multiple metadata messages" $ + \ctx -> runResourceT $ do + wa <- fixtureWallet ctx + let toBeEncrypted1 = + TxMetaList [TxMetaText "Extremely secret message #1."] + let toBeEncrypted2 = + TxMetaList [TxMetaText "Extremely secret message #2."] + let metadataToBeEncrypted = + TxMetadataWithSchema TxMetadataDetailedSchema $ + TxMetadata $ + Map.fromList + [ (674, TxMetaMap + [ (TxMetaText "msg", toBeEncrypted1) + , (TxMetaText "msg", toBeEncrypted2) + ] + ) + ] + let pwdApiT = ApiT $ Passphrase "metadata-secret" + let encryptMetadata = ApiEncryptMetadata pwdApiT Nothing + let payload = Json [json|{ + "encrypt_metadata": #{toJSON encryptMetadata}, + "metadata": #{toJSON metadataToBeEncrypted} + }|] + rTx <- request @(ApiConstructTransaction n) ctx + (Link.createUnsignedTransaction @'Shelley wa) Default payload + verify rTx + [ expectResponseCode HTTP.status202 + ] + it "TRANS_NEW_CREATE_03a - Withdrawal from self, 0 rewards" $ \ctx -> runResourceT $ do wa <- fixtureWallet ctx let initialBalance = wa ^. #balance . #available . #toNatural From 5434f0b3fc217de8d630096d07b743350f9f0642 Mon Sep 17 00:00:00 2001 From: Pawel Jakubas Date: Fri, 28 Jun 2024 15:36:48 +0200 Subject: [PATCH 2/3] fix --- lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs | 7 +++---- .../Integration/Scenario/API/Shelley/TransactionsNew.hs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs b/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs index 292a81b12ee..392d10b8d4e 100644 --- a/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs +++ b/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs @@ -3195,14 +3195,13 @@ toMetadataEncrypted apiEncrypt payload saltM = secretKey, iv :: ByteString (secretKey, iv) = PBKDF2.generateKey metadataPBKDF2Config pwd saltM - -- `msg` is not embedded beyond the first level - parseMessage :: TxMetadataValue -> Maybe TxMetadataValue + -- `msg` is embedded at the first level + parseMessage :: TxMetadataValue -> Maybe [TxMetadataValue] parseMessage = \case TxMetaMap kvs -> case mapMaybe getValue kvs of [ ] -> Nothing - [v] -> Just v - _vs -> error "only one 'msg' field expected" + vs -> Just vs _ -> Nothing where diff --git a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs index 330c8bdfeed..ec0c069e8d8 100644 --- a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs +++ b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs @@ -600,7 +600,7 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do checkMetadataEncryption ctx toBeEncrypted metadataRaw it "TRANS_NEW_CREATE_02d - \ - \Attempt to encrypt multiple metadata messages" $ + \Encrypt multiple metadata messages" $ \ctx -> runResourceT $ do wa <- fixtureWallet ctx let toBeEncrypted1 = From 4afcd9e995d0e3ab84a4f918ac5a85bae04ebf51 Mon Sep 17 00:00:00 2001 From: Pawel Jakubas Date: Fri, 28 Jun 2024 17:29:17 +0200 Subject: [PATCH 3/3] enhance testing --- .../Cardano/Wallet/Api/Http/Shelley/Server.hs | 3 +- .../Scenario/API/Shelley/TransactionsNew.hs | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs b/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs index 392d10b8d4e..984e5a7224b 100644 --- a/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs +++ b/lib/api/src/Cardano/Wallet/Api/Http/Shelley/Server.hs @@ -3225,7 +3225,8 @@ toMetadataEncrypted apiEncrypt payload saltM = encryptMessage :: TxMetadataValue -> Either ErrConstructTx TxMetadataValue encryptMessage = \case TxMetaMap pairs -> - TxMetaMap . concat <$> mapM encryptPairIfQualifies pairs + TxMetaMap . reverse . L.nub . reverse . concat <$> + mapM encryptPairIfQualifies pairs _ -> error "encryptMessage should have TxMetaMap value" where diff --git a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs index ec0c069e8d8..315d3deffa1 100644 --- a/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs +++ b/lib/integration/scenarios/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs @@ -628,6 +628,50 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do verify rTx [ expectResponseCode HTTP.status202 ] + let ApiSerialisedTransaction apiTx _ = getFromResponse #transaction rTx + signedTx <- signTx ctx wa apiTx [ expectResponseCode HTTP.status202 ] + let era = ApiEra.toAnyCardanoEra $ _mainEra ctx + let tx = cardanoTxIdeallyNoLaterThan era $ + getApiT (signedTx ^. #serialisedTxSealed) + + let extractTxt (Cardano.TxMetaText txt) = txt + extractTxt _ = + error "extractTxt is expected" + let encryptedMsg = case getMetadataFromTx tx of + Nothing -> error "Tx doesn't include metadata" + Just m -> case Map.lookup 674 m of + Nothing -> error "Tx doesn't include metadata" + Just (Cardano.TxMetaMap + [ (TxMetaText "msg",TxMetaList chunks1) + , (TxMetaText "msg",TxMetaList chunks2) + , (TxMetaText "enc",TxMetaText "basic") + ]) -> ( foldl T.append T.empty $ extractTxt <$> chunks1 + , foldl T.append T.empty $ extractTxt <$> chunks2 ) + Just _ -> error "Tx metadata incorrect" + + -- we retriev salt from the encypted msg, then encrypt the value in + -- `msg` field and compare + let (Just salt1) = getSaltFromEncrypted $ unsafeFromBase64 $ fst encryptedMsg + let (Just salt2) = getSaltFromEncrypted $ unsafeFromBase64 $ snd encryptedMsg + + let pwd = BA.convert $ unPassphrase $ getApiT pwdApiT + let (key1, iv1) = generateKey metadataPBKDF2Config pwd (Just salt1) + let (key2, iv2) = generateKey metadataPBKDF2Config pwd (Just salt2) + + let (Right encryptedMsgRaw1) = encrypt WithPadding key1 iv1 (Just salt1) $ + BL.toStrict $ Aeson.encode $ Cardano.metadataValueToJsonNoSchema + toBeEncrypted1 + let (Right encryptedMsgRaw2) = encrypt WithPadding key2 iv2 (Just salt2) $ + BL.toStrict $ Aeson.encode $ Cardano.metadataValueToJsonNoSchema + toBeEncrypted2 + + encryptedMsg `shouldBe` (toBase64 encryptedMsgRaw1, toBase64 encryptedMsgRaw2) + + submittedTx <- submitTxWithWid ctx wa signedTx + verify submittedTx + [ expectSuccess + , expectResponseCode HTTP.status202 + ] it "TRANS_NEW_CREATE_03a - Withdrawal from self, 0 rewards" $ \ctx -> runResourceT $ do wa <- fixtureWallet ctx