diff options
author | Andrew Cady <d@jerkface.net> | 2016-01-20 12:07:30 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2016-01-20 12:07:30 -0500 |
commit | 1d1190635c6de041eb9490d530cd32cad31c25e1 (patch) | |
tree | 56eb6ba648d9f3ce92c81e63bb66bb7df157c66d | |
parent | 507e230d6ce9304b359d6a2811d7b32760e3bc07 (diff) |
remove 'writeBody'; minor cleanups
-rw-r--r-- | acme.hs | 65 |
1 files changed, 31 insertions, 34 deletions
@@ -65,42 +65,43 @@ genKey privKeyFile = readProcess "openssl" (words "genrsa 4096 -out" ++ [privKey | |||
65 | 65 | ||
66 | go :: CmdOpts -> IO () | 66 | go :: CmdOpts -> IO () |
67 | go (CmdOpts privKeyFile domain email termOverride) = do | 67 | go (CmdOpts privKeyFile domain email termOverride) = do |
68 | let terms = fromMaybe defaultTerms termOverride | 68 | |
69 | doesFileExist privKeyFile >>= flip unless (genKey privKeyFile) | 69 | doesFileExist privKeyFile >>= flip unless (genKey privKeyFile) |
70 | |||
70 | priv <- readFile privKeyFile >>= flip readPrivateKey PwTTY | 71 | priv <- readFile privKeyFile >>= flip readPrivateKey PwTTY |
71 | pub <- maybe (return Nothing) (rsaCopyPublic >=> return . Just) (toKeyPair priv :: Maybe RSAKeyPair) | 72 | mbPub <- maybe (return Nothing) (rsaCopyPublic >=> return . Just) |
72 | case pub of | 73 | (toKeyPair priv :: Maybe RSAKeyPair) |
73 | Nothing -> error "Error: failed to parse RSA key." | ||
74 | Just (userKey :: RSAPubKey) -> do | ||
75 | 74 | ||
76 | Just nonce_ <- getNonce | 75 | let terms = fromMaybe defaultTerms termOverride |
76 | pub :: RSAPubKey | ||
77 | pub = fromMaybe (error "Error: failed to parse RSA key.") mbPub | ||
77 | 78 | ||
78 | let protected = b64 (header userKey nonce_) | 79 | Just nonce_ <- getNonce |
79 | 80 | ||
80 | -- Create user account | 81 | -- Create user account |
81 | forM_ email $ \m -> signPayload "registration" priv userKey protected (registration m terms) | 82 | forM_ email $ \m -> |
83 | LB.writeFile "registration.body" =<< signPayload priv pub nonce_ (registration m terms) | ||
82 | 84 | ||
83 | -- Obtain a challenge | 85 | -- Obtain a challenge |
84 | signPayload "challenge-request" priv userKey protected (authz domain) | 86 | LB.writeFile "challenge-request.body" =<< signPayload priv pub nonce_ (authz domain) |
85 | 87 | ||
86 | -- Answser the challenge | 88 | -- Answser the challenge |
87 | let thumb = thumbprint (JWK (rsaE userKey) "RSA" (rsaN userKey)) | 89 | let thumb = thumbprint (JWK (rsaE pub) "RSA" (rsaN pub)) |
88 | -- Extracted from POST response above. | 90 | -- Extracted from POST response above. |
89 | token = "DjyJpI3HVWAmsAwMT5ZFpW8dj19cel6ml6qaBUeGpCg" | 91 | token = "DjyJpI3HVWAmsAwMT5ZFpW8dj19cel6ml6qaBUeGpCg" |
90 | thumbtoken = toStrict (LB.fromChunks [token, ".", thumb]) | 92 | thumbtoken = toStrict (LB.fromChunks [token, ".", thumb]) |
91 | 93 | ||
92 | putStrLn ("Serve http://" ++ domain ++ "/.well-known/acme-challenge/" ++ | 94 | putStrLn ("Serve http://" ++ domain ++ "/.well-known/acme-challenge/" ++ BC.unpack token) |
93 | BC.unpack token) | 95 | putStrLn ("With content:\n" ++ BC.unpack thumbtoken) |
94 | putStrLn ("With content:\n" ++ BC.unpack thumbtoken) | ||
95 | 96 | ||
96 | -- Notify Let's Encrypt we answsered the challenge | 97 | -- Notify Let's Encrypt we answsered the challenge |
97 | signPayload "challenge-response" priv userKey protected (challenge thumbtoken) | 98 | LB.writeFile "challenge-response.body" =<< signPayload priv pub nonce_ (challenge thumbtoken) |
98 | 99 | ||
99 | -- Wait for challenge validation | 100 | -- Wait for challenge validation Send a CSR and get a certificate |
101 | csr_ <- B.readFile (domain ++ ".csr.der") | ||
102 | LB.writeFile "csr-request.body" =<< signPayload priv pub nonce_ (csr csr_) | ||
100 | 103 | ||
101 | -- Send a CSR and get a certificate | 104 | return () |
102 | csr_ <- B.readFile (domain ++ ".csr.der") | ||
103 | signPayload "csr-request" priv userKey protected (csr csr_) | ||
104 | 105 | ||
105 | data Directory = Directory { | 106 | data Directory = Directory { |
106 | _newCert :: String, | 107 | _newCert :: String, |
@@ -122,16 +123,12 @@ getNonce = fmap _nonce <$> getDirectory directoryUrl | |||
122 | 123 | ||
123 | -------------------------------------------------------------------------------- | 124 | -------------------------------------------------------------------------------- |
124 | -- | Sign and write a payload to a file with a nonce-protected header. | 125 | -- | Sign and write a payload to a file with a nonce-protected header. |
125 | signPayload :: (RSAKey k, KeyPair kp) => String -> kp -> k -> ByteString -> ByteString -> IO () | 126 | signPayload :: (RSAKey k, KeyPair kp) => kp -> k -> String -> ByteString -> IO LC.ByteString |
126 | signPayload name priv key protected payload = withOpenSSL $ do | 127 | signPayload priv pub nonce_ payload = withOpenSSL $ do |
128 | let protected = b64 (header pub nonce_) | ||
127 | Just dig <- getDigestByName "SHA256" | 129 | Just dig <- getDigestByName "SHA256" |
128 | sig <- signBS dig priv (B.concat [protected, ".", payload]) | 130 | sig <- b64 <$> signBS dig priv (B.concat [protected, ".", payload]) |
129 | writeBody name key protected payload sig | 131 | return $ buildBody pub protected payload sig |
130 | |||
131 | -- | Write a signed payload to a file. It can be used as the body of a POST | ||
132 | -- request. | ||
133 | writeBody :: RSAKey k => String -> k -> ByteString -> ByteString -> ByteString -> IO () | ||
134 | writeBody name key protected payload sig = LB.writeFile (name ++ ".body") $ buildBody key protected payload sig | ||
135 | 132 | ||
136 | buildBody :: RSAKey k => k -> ByteString -> ByteString -> ByteString -> LC.ByteString | 133 | buildBody :: RSAKey k => k -> ByteString -> ByteString -> ByteString -> LC.ByteString |
137 | buildBody key protected payload sig = encode (Request (header' key) protected payload sig) | 134 | buildBody key protected payload sig = encode (Request (header' key) protected payload sig) |