on master help sign in
use in-memory certificate for https
commitba44194ad68e7aff55746bcf5004f013af314c8f authorJoe Betz <joebetz91@gmail.com> dateFri 22 Nov 2019, 16:54 (7 years ago) parentc82c8c1
3 files changed+18−27
README.md+2−2 lib/run/obelisk-run.cabal+1−1 lib/run/src/Obelisk/Run.hs+15−24
README.md+2−2
@@ -152,9 +152,9 @@ For further information see [the Haskell section](https://nixos.org/nixpkgs/manu
152152
153153### Running over https
154154
155−To run your app locally over https, update the protocol in `config/common/route` to `https`, and then use `ob run` as normal. Obelisk will generate a self-signed certificate for running https which will be valid for one year, at which point a new certificate can be generated by removing `certificate.pem` from `~/.config/obelisk` and restarting the app.
155+To run your app locally over https, update the protocol in `config/common/route` to `https`, and then use `ob run` as normal.
156156
157−Note: The browser will issue a warning about using an invalid certificate on localhost. On Chrome, you can either go to `chrome://flags/#allow-insecure-localhost` to enable invalid certificates for localhost, or click through the warning to add an exception for Obelisk's self-signed certificate.
157+Note, since Obelisk generates a self-signed certificate for running https, the browser will issue a warning about using an invalid certificate on localhost. On Chrome, you can go to `chrome://flags/#allow-insecure-localhost` to enable invalid certificates for localhost.
158158
159159## Deploying
160160
lib/run/obelisk-run.cabal+1−1
@@ -14,7 +14,6 @@ library
1414 , cookie
1515 , dependent-sum
1616 , dependent-sum-template
17− , directory
1817 , ghcjs-dom
1918 , HsOpenSSL
2019 , http-client
@@ -40,6 +39,7 @@ library
4039 , text
4140 , time
4241 , universe
42+ , utf8-string
4343 , wai
4444 , wai-websockets
4545 , warp
lib/run/src/Obelisk/Run.hs+15−24
@@ -18,12 +18,12 @@ import Control.Category
1818import Control.Concurrent
1919import Control.Exception
2020import Control.Lens ((%~), (^?), _Just, _Right)
21−import Control.Monad (unless)
2221import qualified Data.Attoparsec.ByteString.Char8 as A
2322import Data.ByteString (ByteString)
2423import qualified Data.ByteString as BS
2524import qualified Data.ByteString.Char8 as BSC
2625import qualified Data.ByteString.Lazy.Char8 as BSLC
26+import qualified Data.ByteString.UTF8 as BSUTF8
2727import Data.Functor.Identity
2828import Data.List (uncons)
2929import Data.Map (Map)
@@ -59,7 +59,6 @@ import qualified OpenSSL.X509 as X509
5959import qualified OpenSSL.X509.Request as X509Request
6060import Reflex.Dom.Core
6161import Snap.Core (Snap)
62−import System.Directory (getXdgDirectory, XdgDirectory(..), doesFileExist, createDirectoryIfMissing)
6362import System.Environment
6463import System.IO
6564import System.Process
@@ -124,32 +123,24 @@ runWidget conf configs frontend validFullEncoder = do
124123 -- Providing TLS here will also incidentally provide it to proxied requests to the backend.
125124 prepareRunner = case (uri ^? uriScheme . _Just . unRText) of
126125 Just "https" -> do
127− userCfg <- getXdgDirectory XdgConfig "obelisk"
128− let (sslCertFile, sslKeyFile) = (userCfg <> "/certificate.pem", userCfg <> "/key.pem")
129− sslCertExists <- doesFileExist sslCertFile
130− sslKeyExists <- doesFileExist sslKeyFile
126+ -- Generate a private key and self-signed certificate for TLS
127+ privateKey <- RSA.generateRSAKey' 2048 3
131128
132− -- Generate private key and self-signed certificate if not already available
133− unless (sslCertExists && sslKeyExists) $ do
134− privateKey <- RSA.generateRSAKey' 2048 3
129+ certRequest <- X509Request.newX509Req
130+ _ <- X509Request.setPublicKey certRequest privateKey
131+ _ <- X509Request.signX509Req certRequest privateKey Nothing
135132
136− certRequest <- X509Request.newX509Req
137− _ <- X509Request.setPublicKey certRequest privateKey
138− _ <- X509Request.signX509Req certRequest privateKey Nothing
133+ cert <- X509.newX509 >>= X509Request.makeX509FromReq certRequest
134+ _ <- X509.setPublicKey cert privateKey
135+ now <- getCurrentTime
136+ _ <- X509.setNotBefore cert $ addUTCTime (-1) now
137+ _ <- X509.setNotAfter cert $ addUTCTime (365 * 24 * 60 * 60) now
138+ _ <- X509.signX509 cert privateKey Nothing
139139
140− cert <- X509.newX509 >>= X509Request.makeX509FromReq certRequest
141− _ <- X509.setPublicKey cert privateKey
142− now <- getCurrentTime
143− _ <- X509.setNotBefore cert $ addUTCTime (-1) now
144− let days = 365
145− _ <- X509.setNotAfter cert $ addUTCTime (days * 24 * 60 * 60) now
146− _ <- X509.signX509 cert privateKey Nothing
140+ certByteString <- BSUTF8.fromString <$> PEM.writeX509 cert
141+ privateKeyByteString <- BSUTF8.fromString <$> PEM.writePKCS8PrivateKey privateKey Nothing
147142
148− _ <- createDirectoryIfMissing True userCfg
149− PEM.writeX509 cert >>= writeFile sslCertFile
150− PEM.writePKCS8PrivateKey privateKey Nothing >>= writeFile sslKeyFile
151−
152− return $ runTLSSocket (tlsSettings sslCertFile sslKeyFile)
143+ return $ runTLSSocket (tlsSettingsMemory certByteString privateKeyByteString)
153144 _ -> return runSettingsSocket
154145 runner <- prepareRunner
155146 bracket