Skip to content

Commit

Permalink
refactoring - part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
paweljakubas committed Nov 29, 2023
1 parent d9ce450 commit a212ebe
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 11 deletions.
5 changes: 5 additions & 0 deletions lib/wallet/api/http/Cardano/Wallet/Api/Http/Server/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,11 @@ instance IsServerError ErrConstructTx where
, "The exact error is: "
, T.pack (show cryptoError)
]
ErrConstructTxIncorrectRawMetadata ->
apiError err403 InvalidMetadataEncryption $ mconcat
[ "It looks like the metadata to be encrypted does not "
, "have `msg` field which value is to be encrypted."
]


instance IsServerError ErrGetPolicyId where
Expand Down
52 changes: 43 additions & 9 deletions lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,8 @@ import qualified Network.Ntp as Ntp
import qualified Network.Wai.Handler.Warp as Warp
import qualified Network.Wai.Handler.WarpTLS as Warp

import qualified Debug.Trace as TR

-- | Allow configuring which port the wallet server listen to in an integration
-- setup. Crashes if the variable is not a number.
walletListenFromEnv :: Show e
Expand Down Expand Up @@ -3087,24 +3089,56 @@ encryptionNonce :: ByteString
encryptionNonce = "encrypt-data"

-- When encryption is enabled we do the following:
-- (a) toJSON on metadata,
-- (b) encrypt it
-- (c) and create new tx metadata
-- (0, TxMetaBytes chunk1)
-- (1, TxMetaBytes chunk2)
-- ....
-- (N, TxMetaBytes chunkN)
-- until encrypted metadata is accommodated
-- (a) find field `msg`
-- (b) encrypt its value if present, otherwise emit error
-- (c) and update value of `msg` with the encrypted initial value encoded in base64
-- [TxMetaText base64_1, TxMetaText base64_2, ..., TxMetaText base64_n]
-- (d) add `enc` field with encryption method value ("base" or "chachapoly1305")
toMetadataEncrypted
:: ApiEncryptMetadata
-> TxMetadataWithSchema
-> Either ErrConstructTx Cardano.TxMetadata
toMetadataEncrypted apiEncrypt payload = do
msgValue <- findMsgValue
encrypted <- encrypt . toBytes $ payload
pure $ toMetadata encrypted
TR.trace ("msgValue: "<> show msgValue<>"\nfindMsgValue1: "<> show findMsgValue1) $ pure $ toMetadata encrypted
where
((secretKey,iv), encMethod) = unwrapApiMetadata apiEncrypt

getMsgValue (Cardano.TxMetaText metaField, metaValue) =
if metaField == "msg" then
Just metaValue
else Nothing
getMsgValue _ = Nothing
join Nothing (Just val) = Just val
join (Just val) Nothing = Just val
join Nothing Nothing = Nothing
join (Just val1) (Just val2) = error "only one 'msg' field expected"
-- assumption: `msg` is not embedded beyond first level
-- we could change that in the future
inspectMetaPair (Cardano.TxMetaMap pairs) =
foldl join Nothing (getMsgValue <$> pairs)
inspectMetaPair _ = Nothing
mapMetaPair val Nothing = val
mapMetaPair _ (Just val) =
Cardano.TxMetaBytes $
BL.toStrict $
Aeson.encode $
Cardano.metadataValueToJsonNoSchema val
adjustVals val =
let temp = inspectMetaPair val
in mapMetaPair val temp
findMsgValue =
let (Cardano.TxMetadata themap) = payload ^. #txMetadataWithSchema_metadata
filteredMap = Map.filter (isJust . inspectMetaPair) themap
in if Map.size filteredMap == 1 then
Right $ Map.toList filteredMap
else
Left ErrConstructTxIncorrectRawMetadata
findMsgValue1 =
let (Cardano.TxMetadata themap) = payload ^. #txMetadataWithSchema_metadata
in Map.map adjustVals themap

toBytes = BL.toStrict . Aeson.encode

encrypt = case encMethod of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ import Cardano.Wallet.Api.Types
, ApiWallet
, ApiWalletInput (..)
, ApiWalletOutput (..)
, EncryptMetadataMethod (..)
, ResourceContext (..)
, WalletStyle (..)
, fromApiEra
Expand Down Expand Up @@ -518,7 +519,12 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do

it "TRANS_NEW_CREATE_02c - Small metadata encrypted" $
\ctx -> runResourceT $ do
let metadataRaw = TxMetadata (Map.fromList [(1,TxMetaText "hello")])
let metadataRaw =
TxMetadata (Map.fromList
[ (0,TxMetaText "hello")
, (1,TxMetaMap [(TxMetaText "msg", TxMetaText "hello")])
, (50, TxMetaNumber 1245)
])
checkMetadataEncrytion ctx metadataRaw

it "TRANS_NEW_CREATE_02d - Big metadata encrypted" $
Expand Down Expand Up @@ -5248,7 +5254,7 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do
let metadataToBeEncrypted =
TxMetadataWithSchema TxMetadataNoSchema metadataRaw
let encryptMetadata =
ApiEncryptMetadata (ApiT $ Passphrase "metadata-secret") Nothing
ApiEncryptMetadata (ApiT $ Passphrase "metadata-secret") (Just ChaChaPoly1305)
let payload = Json [json|{
"encrypt_metadata": #{toJSON encryptMetadata},
"metadata": #{toJSON metadataToBeEncrypted}
Expand Down
1 change: 1 addition & 0 deletions lib/wallet/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3547,6 +3547,7 @@ data ErrConstructTx
| ErrConstructTxSharedWalletIncomplete
| ErrConstructTxDelegationInvalid
| ErrConstructTxEncryptMetadata CryptoError
| ErrConstructTxIncorrectRawMetadata
| ErrConstructTxNotImplemented
deriving (Show, Eq)

Expand Down

0 comments on commit a212ebe

Please sign in to comment.