packages feed

hnix-store-core-0.9.0.0: tests/Fingerprint.hs

{-# LANGUAGE OverloadedStrings #-}
-- Test case from https://code.tvl.fyi/commit/tvix/nix-compat/src/narinfo/fingerprint.rs?id=a834966efd64c1b2306241c3ef20f4258f6b9c4e

module Fingerprint where

import Crypto.Error (CryptoFailable(..))
import Data.Default.Class
import System.Nix.Base (decodeWith, BaseEncoding(Base64))
import System.Nix.Fingerprint
import System.Nix.Signature
import System.Nix.StorePath
import System.Nix.StorePath.Metadata
import System.Nix.Hash (mkNamedDigest)
import Data.Text (Text)
import Data.Time.Clock (UTCTime(..))
import Data.Time.Calendar.OrdinalDate (fromOrdinalDate)
import Test.Hspec

import Crypto.PubKey.Ed25519 qualified as Ed25519
import Data.HashSet qualified as HashSet
import Data.Set qualified as Set
import Data.Text.Encoding qualified as Text

spec_fingerprint :: Spec
spec_fingerprint = do

  describe "fingerprint" $ do

    it "is valid for example metadata" $
      metadataFingerprint def exampleStorePath exampleMetadata `shouldBe` exampleFingerprint

    it "allows a successful signature verification" $ do
      let msg = Text.encodeUtf8 $ metadataFingerprint def exampleStorePath exampleMetadata
          Signature sig' =
            case
              sig
              <$> filter (\(NamedSignature publicKey _) -> publicKey == "cache.nixos.org-1")
              (Set.toList (metadataSigs exampleMetadata))
            of
              (x:_) -> x
              _ -> error "impossible"
      sig' `shouldSatisfy` Ed25519.verify pubkey msg

exampleFingerprint :: Text
exampleFingerprint = "1;/nix/store/syd87l2rxw8cbsxmxl853h0r6pdwhwjr-curl-7.82.0-bin;sha256:1b4sb93wp679q4zx9k1ignby1yna3z7c4c2ri3wphylbc2dwsys0;196040;/nix/store/0jqd0rlxzra1rs38rdxl43yh6rxchgc6-curl-7.82.0,/nix/store/6w8g7njm4mck5dmjxws0z1xnrxvl81xa-glibc-2.34-115,/nix/store/j5jxw3iy7bbz4a57fh9g2xm2gxmyal8h-zlib-1.2.12,/nix/store/yxvjs9drzsphm9pcf42a4byzj1kb9m7k-openssl-1.1.1n";

exampleStorePath :: StorePath
exampleStorePath = forceRight $ parsePath def "/nix/store/syd87l2rxw8cbsxmxl853h0r6pdwhwjr-curl-7.82.0-bin"

exampleMetadata :: Metadata StorePath
exampleMetadata = Metadata
  { metadataDeriverPath = Just $ forceRight $ parsePath def "/nix/store/5rwxzi7pal3qhpsyfc16gzkh939q1np6-curl-7.82.0.drv"
  , metadataNarHash = forceRight $ mkNamedDigest "sha256" "1b4sb93wp679q4zx9k1ignby1yna3z7c4c2ri3wphylbc2dwsys0"
  , metadataReferences = HashSet.fromList $ forceRight . parsePath def <$> ["/nix/store/0jqd0rlxzra1rs38rdxl43yh6rxchgc6-curl-7.82.0","/nix/store/6w8g7njm4mck5dmjxws0z1xnrxvl81xa-glibc-2.34-115","/nix/store/j5jxw3iy7bbz4a57fh9g2xm2gxmyal8h-zlib-1.2.12","/nix/store/yxvjs9drzsphm9pcf42a4byzj1kb9m7k-openssl-1.1.1n"]
  , metadataRegistrationTime = UTCTime (fromOrdinalDate 0 0) 0
  , metadataNarBytes = Just 196040
  , metadataTrust = BuiltElsewhere
  , metadataSigs = Set.fromList $ forceRight . parseNamedSignature <$> ["cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==", "test1:519iiVLx/c4Rdt5DNt6Y2Jm6hcWE9+XY69ygiWSZCNGVcmOcyL64uVAJ3cV8vaTusIZdbTnYo9Y7vDNeTmmMBQ=="]
  , metadataContentAddress = Nothing
  }

pubkey :: Ed25519.PublicKey
pubkey = forceDecodeB64Pubkey "6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="

forceDecodeB64Pubkey :: Text -> Ed25519.PublicKey
forceDecodeB64Pubkey b64EncodedPubkey = let
  decoded = forceRight $ decodeWith Base64 b64EncodedPubkey
  in case Ed25519.publicKey decoded of
    CryptoFailed err -> (error . show) err
    CryptoPassed x -> x

forceRight :: Either a b -> b
forceRight = \case
  Right x -> x
  _ -> error "forceRight failed"