From 4fca14fbf826d5713b977b98c260ebe7810141b3 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Thu, 12 Sep 2019 10:59:40 -0400
Subject: [PATCH] Add a helper for signing key generation

---
 PaymentServer.cabal            |  8 ++++++++
 generate-key/Main.hs           | 10 ++++++++++
 src/PaymentServer/Ristretto.hs | 19 ++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 generate-key/Main.hs

diff --git a/PaymentServer.cabal b/PaymentServer.cabal
index 723a1ba..6926cee 100644
--- a/PaymentServer.cabal
+++ b/PaymentServer.cabal
@@ -47,6 +47,14 @@ executable PaymentServer-exe
                      , PaymentServer
   default-language:    Haskell2010
 
+executable PaymentServer-generate-key
+  hs-source-dirs:      generate-key
+  main-is:             Main.hs
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wmissing-import-lists -Wunused-imports
+  build-depends:       base
+                     , PaymentServer
+  default-language:    Haskell2010
+
 source-repository head
   type:     git
   location: https://github.com/privatestorageio/PaymentServer
diff --git a/generate-key/Main.hs b/generate-key/Main.hs
new file mode 100644
index 0000000..3eb7b0e
--- /dev/null
+++ b/generate-key/Main.hs
@@ -0,0 +1,10 @@
+module Main
+  ( main
+  ) where
+
+import PaymentServer.Ristretto
+  ( randomSigningKey
+  )
+
+main :: IO ()
+main = randomSigningKey >>= putStrLn
diff --git a/src/PaymentServer/Ristretto.hs b/src/PaymentServer/Ristretto.hs
index a5d55d6..d56faf8 100644
--- a/src/PaymentServer/Ristretto.hs
+++ b/src/PaymentServer/Ristretto.hs
@@ -2,7 +2,8 @@
 {-# LANGUAGE EmptyDataDecls #-}
 
 module PaymentServer.Ristretto
-  ( ristretto
+  ( randomSigningKey
+  , ristretto
   ) where
 
 import Data.Text
@@ -17,6 +18,10 @@ import Foreign.C.String
   ( CString
   , withCString
   , newCString
+  , peekCString
+  )
+import Foreign.Marshal.Alloc
+  ( free
   )
 
 data C_BlindedToken
@@ -32,6 +37,7 @@ foreign import ccall "public_key_encode_base64" public_key_encode_base64 :: Ptr
 
 foreign import ccall "signing_key_random" signing_key_random :: IO (Ptr C_SigningKey)
 foreign import ccall "signing_key_decode_base64" signing_key_decode_base64 :: CString -> IO (Ptr C_SigningKey)
+foreign import ccall "signing_key_encode_base64" signing_key_encode_base64 :: Ptr C_SigningKey -> IO CString
 foreign import ccall "signing_key_destroy" signing_key_destroy :: Ptr C_SigningKey -> IO ()
 foreign import ccall "signing_key_get_public_key" signing_key_get_public_key :: Ptr C_SigningKey -> IO (Ptr C_PublicKey)
 foreign import ccall "signing_key_sign" signing_key_sign :: Ptr C_SigningKey -> Ptr C_BlindedToken -> IO (Ptr C_SignedToken)
@@ -64,3 +70,14 @@ ristretto textSigningKey textTokens = do
     --   encodedTokens
     --   encodedProof
   return (mempty, [], mempty)
+
+-- | randomSigningKey generates a new signing key at random and returns it
+-- encoded as a base64 string.
+randomSigningKey :: IO String
+randomSigningKey = do
+  cSigningKey <- signing_key_random
+  cString <- signing_key_encode_base64 cSigningKey
+  signing_key_destroy cSigningKey
+  result <- peekCString cString
+  free cString
+  return result
-- 
GitLab