diff --git a/.circleci/config.yml b/.circleci/config.yml index 691a231518ffe4c9e7aed7b3f75ee862d8de8170..8c947f76e0e2a30e4b4267eb26e903c8171644dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,46 +24,16 @@ jobs: resource_class: "xlarge" - environment: - # Specify a revision of NixOS/nixpkgs to run against. This essentially - # pins the majority of the software involved in the build. This - # revision is selected arbitrarily. It's somewhat current as of the - # time of this comment. We can bump it to a newer version when that - # makes sense. Meanwhile, the platform won't shift around beneath us - # unexpectedly. - NIXPKGS_REV: "92609f3d9bc3acffbdbe54fa1c591a885612aa73" - steps: - run: name: "Setup Environment Variables" command: | - # Get NIX_PATH set for the rest of the job so that the revision of - # nixpkgs we selected will be used everywhere Nix pulls in software. - # There is no way to set an environment variable containing the - # value of another environment variable on CircleCI except to use - # the `BASH_ENV` feature as we do here. - echo "export NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs/archive/$NIXPKGS_REV.tar.gz" >> $BASH_ENV # Set XDG_CONFIG_DIRS to point at the source directory, so that nix # will pickup nix/nix.conf as a configuration file from there. echo "export XDG_CONFIG_DIRS=$CIRCLE_WORKING_DIRECTORY" >> $BASH_ENV # Get *our* source code. - "checkout" - - - "run": - # CircleCI won't let us interpolate NIXPKGS_REV into a cache key. - # Only CircleCI's own environment variables or variables set via the - # web interface in a "context" can be interpolated into cache keys. - # However, we can interpolate the checksum of a file... Since we - # don't care about the exact revision, we just care that a new - # revision gives us a new string, we can write the revision to a - # file and then put the checksum of that file into the cache key. - # This way, we don't have to maintain the nixpkgs revision in two - # places and risk having them desynchronize. - name: "Prepare For Cache Key" - command: | - echo "${NIXPKGS_REV}" > nixpkgs.rev - - restore_cache: # Get all of Nix's state relating to the particular revision of # nixpkgs we're using. It will always be the same. CircleCI @@ -87,9 +57,8 @@ jobs: # If nixpkgs changes then potentially a lot of cached packages for # the base system will be invalidated so we may as well drop them # and make a new cache with the new packages. - - paymentserver-nix-store-v5-{{ checksum "nixpkgs.rev" }}-{{ checksum "nix/challenge-bypass-ristretto-repo.nix" }} - - paymentserver-nix-store-v5-{{ checksum "nixpkgs.rev" }}- - - paymentserver-nix-store-v5- + - paymentserver-nix-store-v6-{{ checksum "nix/sources.json" }} + - paymentserver-nix-store-v6- - run: name: "Building with Nix" @@ -114,7 +83,7 @@ jobs: - save_cache: name: "Cache Nix Store Paths" - key: paymentserver-nix-store-v5-{{ checksum "nixpkgs.rev" }}-{{ checksum "nix/challenge-bypass-ristretto-repo.nix" }} + key: paymentserver-nix-store-v6-{{ checksum "nix/sources.json" }} paths: - "/nix" diff --git a/PaymentServer.cabal b/PaymentServer.cabal index 1a96e000a5642345389b961adb1288a8b3d2df6e..1b29cf00f39ed99b0734f253d67636a6d43315e3 100644 --- a/PaymentServer.cabal +++ b/PaymentServer.cabal @@ -67,6 +67,15 @@ executable PaymentServer-generate-key , PaymentServer default-language: Haskell2010 +executable PaymentServer-get-public-key + hs-source-dirs: get-public-key + main-is: Main.hs + ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wmissing-import-lists -Wunused-imports + build-depends: base + , text + , PaymentServer + default-language: Haskell2010 + test-suite PaymentServer-tests type: exitcode-stdio-1.0 hs-source-dirs: test diff --git a/get-public-key/Main.hs b/get-public-key/Main.hs new file mode 100644 index 0000000000000000000000000000000000000000..952caef4c26f5eaa58d51ca3e222fe2d2a1c5409 --- /dev/null +++ b/get-public-key/Main.hs @@ -0,0 +1,21 @@ +-- | Extract a public key from Ristretto-flavored PrivacyPass signing key read from stdin. +module Main + ( main + ) where + +import Prelude hiding + ( putStrLn + , getLine + ) + +import Data.Text.IO + ( putStrLn + , getLine + ) + +import PaymentServer.Ristretto + ( getPublicKey + ) + +main :: IO () +main = getLine >>= getPublicKey >>= putStrLn diff --git a/nix/challenge-bypass-ristretto-repo.nix b/nix/challenge-bypass-ristretto-repo.nix deleted file mode 100644 index 1357efe3e9ab3c9480109c7a52864f751d9bfdc3..0000000000000000000000000000000000000000 --- a/nix/challenge-bypass-ristretto-repo.nix +++ /dev/null @@ -1,9 +0,0 @@ -let - pkgs = import <nixpkgs> {}; -in - pkgs.fetchFromGitHub { - owner = "LeastAuthority"; - repo = "python-challenge-bypass-ristretto"; - rev = "v2021.07.12"; - sha256 = "16af1qmx7srhvcc936x7hl2bz50hafm39311dbzqam9ms1i5q89j"; - } diff --git a/nix/challenge-bypass-ristretto.nix b/nix/challenge-bypass-ristretto.nix index dc08608de18a4fec80c90e75839b52c11817d59f..10bf5e88a11dff116c80776a91f53c8561d166aa 100644 --- a/nix/challenge-bypass-ristretto.nix +++ b/nix/challenge-bypass-ristretto.nix @@ -1,6 +1,8 @@ # Provide the ffi bindings to the Rust challenge-bypass-ristretto library. -{ fetchFromGitHub, callPackage }: let - src = import ./challenge-bypass-ristretto-repo.nix; + sources = import ./sources.nix; in - import "${src}/default-challenge-bypass-ristretto-ffi.nix" { } +{ callPackage +, libchallenge_bypass_ristretto_ffi_repo ? sources.libchallenge_bypass_ristretto_ffi +}: + callPackage "${libchallenge_bypass_ristretto_ffi_repo}/challenge-bypass-ristretto.nix" { } diff --git a/nix/materialized.paymentserver/PaymentServer.nix b/nix/materialized.paymentserver/PaymentServer.nix index e77024c3f3ce41bf84ff5a0390d25744852739ce..842157cc790e792b94c19bb6ca1ee4291bd5b749 100644 --- a/nix/materialized.paymentserver/PaymentServer.nix +++ b/nix/materialized.paymentserver/PaymentServer.nix @@ -93,6 +93,16 @@ hsSourceDirs = [ "generate-key" ]; mainPath = [ "Main.hs" ]; }; + "PaymentServer-get-public-key" = { + depends = [ + (hsPkgs."base" or (errorHandler.buildDepError "base")) + (hsPkgs."text" or (errorHandler.buildDepError "text")) + (hsPkgs."PaymentServer" or (errorHandler.buildDepError "PaymentServer")) + ]; + buildable = true; + hsSourceDirs = [ "get-public-key" ]; + mainPath = [ "Main.hs" ]; + }; }; tests = { "PaymentServer-tests" = { diff --git a/nix/sources.json b/nix/sources.json index a6a9c21c29e2a869d2a6b820fde41ee535314819..a4fb79ffaf80d6c31966860200d263ff20e7a362 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -11,6 +11,18 @@ "url": "https://github.com/input-output-hk/haskell.nix/archive/e95a1f0dacbc64603c31d11e36e4ba1af8f0eb43.tar.gz", "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" }, + "libchallenge_bypass_ristretto_ffi": { + "branch": "master", + "description": "Python bindings for Brave's challenge-bypass-ristretto library", + "homepage": null, + "owner": "leastauthority", + "repo": "python-challenge-bypass-ristretto", + "rev": "6e25af8a721a9d8507745efad3d15dae75b78909", + "sha256": "0w5vpq9kqhdbbynbbky1ibx1im5582yacqnb9y2y3h114diywdyq", + "type": "tarball", + "url": "https://github.com/leastauthority/python-challenge-bypass-ristretto/archive/6e25af8a721a9d8507745efad3d15dae75b78909.tar.gz", + "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" + }, "niv": { "branch": "master", "description": "Easy dependency management for Nix projects", diff --git a/src/PaymentServer/Ristretto.hs b/src/PaymentServer/Ristretto.hs index 7c065206f5d93963bd410fbd588c17c41e726942..1018eb5cdc6b17236ce0d6ce1ee76906ca2cc206 100644 --- a/src/PaymentServer/Ristretto.hs +++ b/src/PaymentServer/Ristretto.hs @@ -4,6 +4,7 @@ module PaymentServer.Ristretto ( Issuance(Issuance) , randomSigningKey + , getPublicKey , ristretto ) where @@ -159,3 +160,14 @@ randomSigningKey = do result <- peekCString cString free cString return $ pack result + +-- | getPublicKey returns the base64 encoded public key corresponding to the +-- base64 encoded signing key passed to it. +getPublicKey :: Text -> IO Text +getPublicKey enc_skey = do + enc_cstr_skey <- newCString . unpack $ enc_skey + skey <- signing_key_decode_base64 $ enc_cstr_skey + pkey <- signing_key_get_public_key skey + enc_cstr_pkey <- public_key_encode_base64 pkey + enc_pkey <- peekCString enc_cstr_pkey + return $ pack enc_pkey