Skip to content

Commit 265d252

Browse files
committed
core: split signature/narSignature parser/builder
1 parent 8b1db17 commit 265d252

File tree

4 files changed

+46
-27
lines changed

4 files changed

+46
-27
lines changed

hnix-store-core/src/System/Nix/Signature.hs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ Description : Nix-relevant interfaces to NaCl signatures.
66

77
module System.Nix.Signature
88
( Signature(..)
9-
, NarSignature(..)
109
, signatureParser
1110
, parseSignature
1211
, signatureToText
12+
, NarSignature(..)
13+
, narSignatureParser
14+
, parseNarSignature
15+
, narSignatureToText
1316
) where
1417

1518
import Crypto.Error (CryptoFailable(..))
19+
import Data.Attoparsec.Text (Parser)
1620
import Data.ByteString (ByteString)
1721
import Data.Text (Text)
1822
import GHC.Generics (Generic)
@@ -28,6 +32,26 @@ import qualified Data.Text
2832
newtype Signature = Signature Ed25519.Signature
2933
deriving (Eq, Generic, Show)
3034

35+
signatureParser :: Parser Signature
36+
signatureParser = do
37+
encodedSig <-
38+
Data.Attoparsec.Text.takeWhile1
39+
(\c -> Data.Char.isAlphaNum c || c == '+' || c == '/' || c == '=')
40+
decodedSig <- case decodeWith Base64 encodedSig of
41+
Left e -> fail e
42+
Right decodedSig -> pure decodedSig
43+
sig <- case Ed25519.signature decodedSig of
44+
CryptoFailed e -> (fail . show) e
45+
CryptoPassed sig -> pure sig
46+
pure $ Signature sig
47+
48+
parseSignature :: Text -> Either String Signature
49+
parseSignature = Data.Attoparsec.Text.parseOnly signatureParser
50+
51+
signatureToText :: Signature -> Text
52+
signatureToText (Signature sig) =
53+
encodeWith Base64 (Data.ByteArray.convert sig :: ByteString)
54+
3155
-- | A detached signature attesting to a nix archive's validity.
3256
data NarSignature = NarSignature
3357
{ -- | The name of the public key used to sign the archive.
@@ -43,26 +67,19 @@ instance Ord Signature where
4367
yBS = Data.ByteArray.convert y :: ByteString
4468
in compare xBS yBS
4569

46-
signatureParser :: Data.Attoparsec.Text.Parser NarSignature
47-
signatureParser = do
70+
narSignatureParser :: Parser NarSignature
71+
narSignatureParser = do
4872
publicKey <- Data.Attoparsec.Text.takeWhile1 (/= ':')
4973
_ <- Data.Attoparsec.Text.string ":"
50-
encodedSig <- Data.Attoparsec.Text.takeWhile1 (\c -> Data.Char.isAlphaNum c || c == '+' || c == '/' || c == '=')
51-
decodedSig <- case decodeWith Base64 encodedSig of
52-
Left e -> fail e
53-
Right decodedSig -> pure decodedSig
54-
sig <- case Ed25519.signature decodedSig of
55-
CryptoFailed e -> (fail . show) e
56-
CryptoPassed sig -> pure sig
57-
pure $ NarSignature publicKey (Signature sig)
74+
sig <- signatureParser
75+
pure $ NarSignature {..}
5876

59-
parseSignature :: Text -> Either String NarSignature
60-
parseSignature = Data.Attoparsec.Text.parseOnly signatureParser
77+
parseNarSignature :: Text -> Either String NarSignature
78+
parseNarSignature = Data.Attoparsec.Text.parseOnly narSignatureParser
6179

62-
signatureToText :: NarSignature -> Text
63-
signatureToText NarSignature {publicKey, sig=Signature sig'} = let
64-
b64Encoded = encodeWith Base64 (Data.ByteArray.convert sig' :: ByteString)
65-
in mconcat [ publicKey, ":", b64Encoded ]
80+
narSignatureToText :: NarSignature -> Text
81+
narSignatureToText NarSignature {..} =
82+
mconcat [ publicKey, ":", signatureToText sig ]
6683

6784
instance Show NarSignature where
68-
show narSig = Data.Text.unpack (signatureToText narSig)
85+
show narSig = Data.Text.unpack (narSignatureToText narSig)

hnix-store-core/tests/Fingerprint.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ exampleMetadata = Metadata
4848
, registrationTime = UTCTime (fromOrdinalDate 0 0) 0
4949
, narBytes = Just 196040
5050
, trust = BuiltElsewhere
51-
, sigs = Set.fromList $ forceRight . parseSignature <$> ["cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", "test1:519iiVLx/c4Rdt5DNt6Y2Jm6hcWE9+XY69ygiWSZCNGVcmOcyL64uVAJ3cV8vaTusIZdbTnYo9Y7vDNeTmmMBQ=="]
51+
, sigs = Set.fromList $ forceRight . parseNarSignature <$> ["cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", "test1:519iiVLx/c4Rdt5DNt6Y2Jm6hcWE9+XY69ygiWSZCNGVcmOcyL64uVAJ3cV8vaTusIZdbTnYo9Y7vDNeTmmMBQ=="]
5252
, contentAddress = Nothing
5353
}
5454

5555
pubkey :: Ed25519.PublicKey
5656
pubkey = forceDecodeB64Pubkey "6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
57-
57+
5858
forceDecodeB64Pubkey :: Text -> Ed25519.PublicKey
5959
forceDecodeB64Pubkey b64EncodedPubkey = let
6060
decoded = forceRight $ decodeWith Base64 b64EncodedPubkey
61-
in case Ed25519.publicKey decoded of
61+
in case Ed25519.publicKey decoded of
6262
CryptoFailed err -> (error . show) err
63-
CryptoPassed x -> x
63+
CryptoPassed x -> x
6464

6565
forceRight :: Either a b -> b
6666
forceRight = \case

hnix-store-core/tests/Signature.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,24 @@ pubkeyNixosOrg :: Crypto.PubKey.Ed25519.PublicKey
5454
pubkeyNixosOrg = forceDecodeB64Pubkey "6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
5555

5656
shouldNotParse :: Text -> Expectation
57-
shouldNotParse encoded = case parseSignature encoded of
57+
shouldNotParse encoded = case parseNarSignature encoded of
5858
Left _ -> pure ()
5959
Right _ -> expectationFailure "should not have parsed"
6060

6161
shouldParseName :: Text -> Text -> Expectation
62-
shouldParseName encoded name = case parseSignature encoded of
62+
shouldParseName encoded name = case parseNarSignature encoded of
6363
Left err -> expectationFailure err
6464
Right narSig -> shouldBe name (publicKey narSig)
6565

6666
shouldVerify :: Text -> Crypto.PubKey.Ed25519.PublicKey -> BS.ByteString -> Expectation
67-
shouldVerify encoded pubkey msg = case parseSignature encoded of
67+
shouldVerify encoded pubkey msg = case parseNarSignature encoded of
6868
Left err -> expectationFailure err
6969
Right narSig -> let
7070
(Signature sig') = sig narSig
7171
in sig' `shouldSatisfy` Crypto.PubKey.Ed25519.verify pubkey msg
7272

7373
shouldNotVerify :: Text -> Crypto.PubKey.Ed25519.PublicKey -> BS.ByteString -> Expectation
74-
shouldNotVerify encoded pubkey msg = case parseSignature encoded of
74+
shouldNotVerify encoded pubkey msg = case parseNarSignature encoded of
7575
Left err -> expectationFailure err
7676
Right narSig -> let
7777
(Signature sig') = sig narSig

hnix-store-tests/tests/SignatureSpec.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import Test.Hspec (Spec, describe)
44
import Test.Hspec.Nix (roundtrips)
55
import Test.Hspec.QuickCheck (prop)
66

7-
import System.Nix.Signature (signatureToText, parseSignature)
7+
import System.Nix.Signature (signatureToText, parseSignature, narSignatureToText, parseNarSignature)
88
import System.Nix.Arbitrary ()
99

1010
spec :: Spec
1111
spec = do
1212
describe "Signature" $ do
1313
prop "roundtrips" $ roundtrips signatureToText parseSignature
14+
describe "NarSignature" $ do
15+
prop "roundtrips" $ roundtrips narSignatureToText parseNarSignature

0 commit comments

Comments
 (0)