summaryrefslogtreecommitdiff
path: root/acme.hs
diff options
context:
space:
mode:
Diffstat (limited to 'acme.hs')
-rw-r--r--acme.hs23
1 files changed, 16 insertions, 7 deletions
diff --git a/acme.hs b/acme.hs
index d187f86..8b1a77e 100644
--- a/acme.hs
+++ b/acme.hs
@@ -44,6 +44,7 @@ import Options.Applicative hiding (header)
44import qualified Options.Applicative as Opt 44import qualified Options.Applicative as Opt
45import Pipes 45import Pipes
46import System.Directory 46import System.Directory
47import Text.Email.Validate
47 48
48stagingDirectoryUrl, liveDirectoryUrl :: String 49stagingDirectoryUrl, liveDirectoryUrl :: String
49liveDirectoryUrl = "https://acme-v01.api.letsencrypt.org/directory" 50liveDirectoryUrl = "https://acme-v01.api.letsencrypt.org/directory"
@@ -154,15 +155,21 @@ go CmdOpts { .. } = do
154 155
155 Just keys <- readKeyFile privKeyFile 156 Just keys <- readKeyFile privKeyFile
156 157
157 doesFileExist domainCSRFile `otherwiseM` genReq domainKeyFile requestDomains >>= LC.writeFile domainCSRFile
158
159 csrData <- B.readFile domainCSRFile
160
161 ensureWritable optChallengeDir "challenge directory" 158 ensureWritable optChallengeDir "challenge directory"
162 ensureWritable domainDir "domain directory" 159 ensureWritable domainDir "domain directory"
163 160
164 forM_ requestDomains $ canProvision optChallengeDir >=> (`unless` error "Error: cannot provision files to web server via challenge directory") 161 forM_ requestDomains $ canProvision optChallengeDir >=> (`unless` error "Error: cannot provision files to web server via challenge directory")
165 162
163 csrData <- CSR . toStrict <$> genReq domainKeyFile requestDomains
164 B.writeFile domainCSRFile (coerce csrData)
165
166 let email = either (error . ("Error: invalid email address: " ++)) id . validate . fromString <$> optEmail
167
168 certify directoryUrl keys email terms requestDomains optChallengeDir csrData domainCertFile
169
170certify :: String -> Keys -> Maybe EmailAddress -> String -> [String] -> String -> CSR -> FilePath -> IO ()
171certify directoryUrl keys optEmail terms requestDomains optChallengeDir csrData domainCertFile =
172
166 runACME directoryUrl keys $ do 173 runACME directoryUrl keys $ do
167 forM_ optEmail $ register terms >=> statusReport 174 forM_ optEmail $ register terms >=> statusReport
168 175
@@ -178,6 +185,8 @@ go CmdOpts { .. } = do
178 185
179 retrieveCert csrData >>= statusReport >>= saveCert domainCertFile 186 retrieveCert csrData >>= statusReport >>= saveCert domainCertFile
180 187
188newtype CSR = CSR ByteString
189
181(</>) :: String -> String -> String 190(</>) :: String -> String -> String
182a </> b = a ++ "/" ++ b 191a </> b = a ++ "/" ++ b
183infixr 5 </> 192infixr 5 </>
@@ -234,8 +243,8 @@ saveCert domainCertFile r =
234 where 243 where
235 isSuccess n = n >= 200 && n <= 300 244 isSuccess n = n >= 200 && n <= 300
236 245
237retrieveCert :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => ByteString -> m (Response LC.ByteString) 246retrieveCert :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => CSR -> m (Response LC.ByteString)
238retrieveCert input = sendPayload _newCert (csr input) 247retrieveCert input = sendPayload _newCert (csr $ coerce input)
239 248
240notifyChallenge :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => String -> ByteString -> m (Response LC.ByteString) 249notifyChallenge :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => String -> ByteString -> m (Response LC.ByteString)
241notifyChallenge crUri thumbtoken = sendPayload (const crUri) (challenge thumbtoken) 250notifyChallenge crUri thumbtoken = sendPayload (const crUri) (challenge thumbtoken)
@@ -263,7 +272,7 @@ getDirectory sess url = do
263 k x = r ^? responseBody . JSON.key x . _String . to T.unpack 272 k x = r ^? responseBody . JSON.key x . _String . to T.unpack
264 return $ (,) <$> (Directory <$> k "new-cert" <*> k "new-authz" <*> k "revoke-cert" <*> k "new-reg") <*> nonce 273 return $ (,) <$> (Directory <$> k "new-cert" <*> k "new-authz" <*> k "revoke-cert" <*> k "new-reg") <*> nonce
265 274
266register :: String -> String -> ACME (Response LC.ByteString) 275register :: String -> EmailAddress -> ACME (Response LC.ByteString)
267register terms email = sendPayload _newReg (registration email terms) 276register terms email = sendPayload _newReg (registration email terms)
268 277
269challengeRequest :: (MonadIO m, MonadState Nonce m, MonadReader Env m) => String -> m (Response LC.ByteString) 278challengeRequest :: (MonadIO m, MonadState Nonce m, MonadReader Env m) => String -> m (Response LC.ByteString)