From 0207e260a0113af832c8dc421683d41c6bdaf386 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Mon, 8 May 2023 16:48:06 -0400 Subject: [PATCH] Add a representation of the share data Take tahoe-chk as a dependency because it can already represent some of the fields of an SDMF share. Also, a crypto library for key representations. Fix a typo in the cabal file that passed with only a warning before. --- cabal.project | 12 +++ flake.lock | 179 ++++++++++++++++++++++++++++++- flake.nix | 8 ++ src/Tahoe/SDMF.hs | 5 +- src/Tahoe/SDMF/Internal/Share.hs | 34 ++++++ tahoe-ssk.cabal | 20 +++- 6 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 cabal.project create mode 100644 src/Tahoe/SDMF/Internal/Share.hs diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..473de17 --- /dev/null +++ b/cabal.project @@ -0,0 +1,12 @@ +packages: . + -- These aren't released on hackage yet so we have to grab them + -- straight from the vcs host. Probably should do some releases + -- soon. + https://whetstone.private.storage/privatestorage/tahoe-chk/-/archive/0.1.0.1/tahoe-chk-0.1.0.1.tar.gz + +package zlib + -- Turn on discovery of the underlying zlib using pkg-config. This + -- fixes build failures when the underlying zlib is not in the + -- traditional location but is discoverable with pkg-config. It might + -- break non-pkg-config platforms. + flags: +pkg-config diff --git a/flake.lock b/flake.lock index 16274dd..ecb5512 100644 --- a/flake.lock +++ b/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -49,6 +65,36 @@ "type": "github" } }, + "flake-utils_3": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "locked": { + "lastModified": 1676283394, + "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -71,6 +117,29 @@ "type": "github" } }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "tahoe-chk", + "hs-flake-utils", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "hs-flake-utils": { "inputs": { "flake-utils": "flake-utils_2", @@ -92,6 +161,27 @@ "url": "https://whetstone.private.storage/jcalderone/hs-flake-utils.git" } }, + "hs-flake-utils_2": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks_2" + }, + "locked": { + "lastModified": 1677773826, + "narHash": "sha256-xJmOtHugr4k2zNhP/AF6JdIUnIEyM+TEspLn2n5kloc=", + "ref": "main", + "rev": "d3a83fdd9563546ca41771186427638e685a2e2b", + "revCount": 9, + "type": "git", + "url": "https://whetstone.private.storage/jcalderone/hs-flake-utils.git" + }, + "original": { + "ref": "main", + "type": "git", + "url": "https://whetstone.private.storage/jcalderone/hs-flake-utils.git" + } + }, "nixpkgs": { "locked": { "lastModified": 1677624842, @@ -124,6 +214,38 @@ "type": "github" } }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1673800717, + "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1677624842, + "narHash": "sha256-4DF9DbDuK4/+KYx0L6XcPBeDHUFVCtzok2fWtwXtb5w=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d70f5cd5c3bef45f7f52698f39e7cc7a89daa7f0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", @@ -152,6 +274,36 @@ "type": "github" } }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": [ + "tahoe-chk", + "hs-flake-utils", + "flake-utils" + ], + "gitignore": "gitignore_2", + "nixpkgs": [ + "tahoe-chk", + "hs-flake-utils", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1677722096, + "narHash": "sha256-7mjVMvCs9InnrRybBfr5ohqcOz+pyEX8m22C1XsDilg=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "61a3511668891c68ebd19d40122150b98dc2fe3b", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "flake-utils": "flake-utils", @@ -159,7 +311,8 @@ "nixpkgs": [ "hs-flake-utils", "nixpkgs" - ] + ], + "tahoe-chk": "tahoe-chk" } }, "systems": { @@ -176,6 +329,30 @@ "repo": "default", "type": "github" } + }, + "tahoe-chk": { + "inputs": { + "flake-utils": "flake-utils_3", + "hs-flake-utils": "hs-flake-utils_2", + "nixpkgs": [ + "hs-flake-utils", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1683552888, + "narHash": "sha256-h9pgP/LYPtUr5CeCAhqt1XJyAqKTnkQxuIygiTulU/U=", + "ref": "refs/tags/0.1.0.1", + "rev": "05aeb5a433b85406ca3c0c313c46299a1026ade0", + "revCount": 344, + "type": "git", + "url": "https://whetstone.private.storage/PrivateStorage/tahoe-chk" + }, + "original": { + "ref": "refs/tags/0.1.0.1", + "type": "git", + "url": "https://whetstone.private.storage/PrivateStorage/tahoe-chk" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 83f3d7f..7b393e1 100644 --- a/flake.nix +++ b/flake.nix @@ -6,6 +6,10 @@ flake-utils.url = github:numtide/flake-utils; hs-flake-utils.url = "git+https://whetstone.private.storage/jcalderone/hs-flake-utils.git?ref=main"; nixpkgs.follows = "hs-flake-utils/nixpkgs"; + tahoe-chk = { + url = "git+https://whetstone.private.storage/PrivateStorage/tahoe-chk?ref=refs/tags/0.1.0.1"; + inputs.nixpkgs.follows = "hs-flake-utils/nixpkgs"; + }; }; outputs = { @@ -13,6 +17,7 @@ nixpkgs, flake-utils, hs-flake-utils, + tahoe-chk, }: let ulib = flake-utils.lib; ghcVersion = "ghc8107"; @@ -27,6 +32,9 @@ src = ./.; compilerVersion = ghcVersion; packageName = "tahoe-ssk"; + hsPkgsOverrides = hprev: hfinal: { + tahoe-chk = tahoe-chk.outputs.packages.${system}.default; + }; }; in { checks = hslib.checks {}; diff --git a/src/Tahoe/SDMF.hs b/src/Tahoe/SDMF.hs index 718741f..0aaf41a 100644 --- a/src/Tahoe/SDMF.hs +++ b/src/Tahoe/SDMF.hs @@ -1 +1,4 @@ -module Tahoe.SDMF where +-- | Expose the library's public interface. +module Tahoe.SDMF (Share (..)) where + +import Tahoe.SDMF.Internal.Share diff --git a/src/Tahoe/SDMF/Internal/Share.hs b/src/Tahoe/SDMF/Internal/Share.hs new file mode 100644 index 0000000..c31124d --- /dev/null +++ b/src/Tahoe/SDMF/Internal/Share.hs @@ -0,0 +1,34 @@ +-- | Deal with details related to the structural layout of an SDMF share. +module Tahoe.SDMF.Internal.Share where + +import qualified Crypto.Types.PubKey.RSA as RSA +import qualified Data.ByteString as B +import qualified Data.ByteString.Lazy as LB +import Data.Word (Word32, Word64, Word8) +import Tahoe.CHK.Merkle (MerkleTree) + +{- | Structured representation of a single version 0 SDMF share. + + See Tahoe-LAFS "mutable" specification document, section title "SDMF Slot + Format". +-} +data Share = Share + { shareSequenceNumber :: Word64 + , shareRootHash :: B.ByteString + , shareIV :: B.ByteString + , shareTotalShares :: Word8 + , shareRequiredShares :: Word8 + , shareSegmentSize :: Word64 + , shareDataLength :: Word8 + , shareOffsetSignature :: Word32 + , shareOffsetShareHashChain :: Word32 + , shareOffsetData :: Word32 + , shareOffsetEncryptedPrivateKey :: Word64 + , shareOffsetEOF :: Word64 + , shareVerificationKey :: RSA.PublicKey + , shareSignature :: B.ByteString + , shareHashChain :: [(Word8, B.ByteString)] + , shareBlockHashTree :: MerkleTree + , shareData :: LB.ByteString + , sharePrivateKey :: RSA.PrivateKey + } diff --git a/tahoe-ssk.cabal b/tahoe-ssk.cabal index 51ddf32..de3a3f9 100644 --- a/tahoe-ssk.cabal +++ b/tahoe-ssk.cabal @@ -61,11 +61,21 @@ common warnings library hs-source-dirs: src - exposed-modules: Tahoe.SDMF - build-depends: base + exposed-modules: + Tahoe.SDMF + Tahoe.SDMF.Internal.Share + + build-depends: + , base + , bytestring + , crypto-pubkey-types + + -- This dependency isn't ideal. Move common bits out to + -- another library. + build-depends: tahoe-chk ghc-options: -Wall default-extensions: OverloadedStrings - defaut-language: Haskell2010 + default-language: Haskell2010 test-suite tahoe-ssk-test -- Import common warning flags. @@ -90,4 +100,6 @@ test-suite tahoe-ssk-test main-is: Main.hs -- Test dependencies. - build-depends: base ^>=4.14.3.0 + build-depends: + , base ^>=4.14.3.0 + , tahoe-ssk -- GitLab