diff --git a/apps/smp-server/Main.hs b/apps/smp-server/Main.hs index 1f3e6db8d..4f32f554c 100644 --- a/apps/smp-server/Main.hs +++ b/apps/smp-server/Main.hs @@ -11,12 +11,12 @@ module Main where import Control.Monad.Except import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as B -import Data.Composition ((.:)) import Data.Either (fromRight) import Data.Ini (Ini, lookupValue, readIniFile) +import Data.Maybe (fromMaybe) import qualified Data.Text as T import Data.X509.Validation (Fingerprint (..)) -import Network.Socket (ServiceName) +import Network.Socket (HostName, ServiceName) import Options.Applicative import Simplex.Messaging.Encoding.String import Simplex.Messaging.Server (runSMPServer) @@ -81,8 +81,11 @@ data CliCommand data InitOptions = InitOptions { enableStoreLog :: Bool, - signAlgorithm :: SignAlgorithm + signAlgorithm :: SignAlgorithm, + ip :: HostName, + fqdn :: Maybe HostName } + deriving (Show) data SignAlgorithm = ED448 | ED25519 deriving (Read, Show) @@ -108,24 +111,42 @@ cliCommandP = where initP :: Parser CliCommand initP = - Init .: InitOptions - <$> switch - ( long "store-log" - <> short 'l' - <> help "Enable store log for SMP queues persistence" - ) - <*> option - (maybeReader readMaybe) - ( long "sign-algorithm" - <> short 'a' - <> help "Signature algorithm used for TLS certificates: ED25519, ED448" - <> value ED448 - <> showDefault - <> metavar "ALG" - ) + Init + <$> ( InitOptions + <$> switch + ( long "store-log" + <> short 'l' + <> help "Enable store log for SMP queues persistence" + ) + <*> option + (maybeReader readMaybe) + ( long "sign-algorithm" + <> short 'a' + <> help "Signature algorithm used for TLS certificates: ED25519, ED448" + <> value ED448 + <> showDefault + <> metavar "ALG" + ) + <*> strOption + ( long "ip" + <> help + "Server IP address used as Subject Alternative Name for TLS online certificate, \ + \also used as Common Name if FQDN is not supplied" + <> value "127.0.0.1" + <> showDefault + <> metavar "IP" + ) + <*> (optional . strOption) + ( long "fqdn" + <> short 'n' + <> help "Server FQDN used as Common Name and Subject Alternative Name for TLS online certificate" + <> showDefault + <> metavar "FQDN" + ) + ) initializeServer :: InitOptions -> IO () -initializeServer InitOptions {enableStoreLog, signAlgorithm} = do +initializeServer InitOptions {enableStoreLog, signAlgorithm, ip, fqdn} = do cleanup createDirectoryIfMissing True cfgDir createDirectoryIfMissing True logDir @@ -137,35 +158,56 @@ initializeServer InitOptions {enableStoreLog, signAlgorithm} = do warnCAPrivateKeyFile where createX509 = do - createOpensslConf + createOpensslCaConf + createOpensslServerConf -- CA certificate (identity/offline) run $ "openssl genpkey -algorithm " <> show signAlgorithm <> " -out " <> caKeyFile - run $ "openssl req -new -x509 -days 999999 -config " <> opensslCnfFile <> " -extensions v3_ca -key " <> caKeyFile <> " -out " <> caCrtFile + run $ "openssl req -new -x509 -days 999999 -config " <> opensslCaConfFile <> " -extensions v3 -key " <> caKeyFile <> " -out " <> caCrtFile -- server certificate (online) run $ "openssl genpkey -algorithm " <> show signAlgorithm <> " -out " <> serverKeyFile - run $ "openssl req -new -config " <> opensslCnfFile <> " -reqexts v3_req -key " <> serverKeyFile <> " -out " <> serverCsrFile - run $ "openssl x509 -req -days 999999 -extfile " <> opensslCnfFile <> " -extensions v3_req -in " <> serverCsrFile <> " -CA " <> caCrtFile <> " -CAkey " <> caKeyFile <> " -CAcreateserial -out " <> serverCrtFile + run $ "openssl req -new -config " <> opensslServerConfFile <> " -reqexts v3 -key " <> serverKeyFile <> " -out " <> serverCsrFile + run $ "openssl x509 -req -days 999999 -extfile " <> opensslServerConfFile <> " -extensions v3 -in " <> serverCsrFile <> " -CA " <> caCrtFile <> " -CAkey " <> caKeyFile <> " -CAcreateserial -out " <> serverCrtFile where run cmd = void $ readCreateProcess (shell cmd) "" - opensslCnfFile = combine cfgDir "openssl.cnf" + opensslCaConfFile = combine cfgDir "openssl_ca.conf" + opensslServerConfFile = combine cfgDir "openssl_server.conf" serverCsrFile = combine cfgDir "server.csr" - createOpensslConf = - -- TODO revise https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3, https://www.rfc-editor.org/rfc/rfc3279#section-2.3.5 + createOpensslCaConf = writeFile - opensslCnfFile + opensslCaConfFile "[req]\n\ \distinguished_name = req_distinguished_name\n\ \prompt = no\n\n\ \[req_distinguished_name]\n\ - \CN = localhost\n\n\ - \[v3_ca]\n\ + \CN = SMP server CA\n\ + \O = SimpleX\n\n\ + \[v3]\n\ \subjectKeyIdentifier = hash\n\ \authorityKeyIdentifier = keyid:always\n\ - \basicConstraints = critical,CA:true\n\n\ - \[v3_req]\n\ - \basicConstraints = CA:FALSE\n\ - \keyUsage = digitalSignature, nonRepudiation, keyAgreement\n\ - \extendedKeyUsage = serverAuth\n" + \basicConstraints = critical,CA:true\n" + -- TODO revise https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3, https://www.rfc-editor.org/rfc/rfc3279#section-2.3.5 + createOpensslServerConf = + writeFile + opensslServerConfFile + ( "[req]\n\ + \distinguished_name = req_distinguished_name\n\ + \prompt = no\n\n\ + \[req_distinguished_name]\n" + <> ("CN = " <> cn <> "\n\n") + <> "[v3]\n\ + \basicConstraints = CA:FALSE\n\ + \keyUsage = digitalSignature, nonRepudiation, keyAgreement\n\ + \extendedKeyUsage = serverAuth\n\ + \subjectAltName = @alt_names\n\n\ + \[alt_names]\n" + <> optionalDns1 + <> ("IP.1 = " <> ip <> "\n") + ) + where + cn = fromMaybe ip fqdn + optionalDns1 = case fqdn of + Nothing -> "" + Just n -> "DNS.1 = " <> n <> "\n" saveFingerprint = do Fingerprint fp <- loadFingerprint caCrtFile diff --git a/tests/AgentTests.hs b/tests/AgentTests.hs index 2df31f302..2bdc2e2a4 100644 --- a/tests/AgentTests.hs +++ b/tests/AgentTests.hs @@ -428,7 +428,7 @@ syntaxTests t = do ( "311", "a", "JOIN https://simpex.chat/invitation#/?smp=smp%3A%2F%2F" - <> urlEncode True "9VjLsOY5ZvB4hoglNdBzJFAUi_vP4GkZnJFahQOXV20=" + <> urlEncode True "LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=" <> "%40localhost%3A5001%2F3456-w%3D%3D%23" <> urlEncode True sampleDhKey <> "&v=1" diff --git a/tests/SMPAgentClient.hs b/tests/SMPAgentClient.hs index f3d952738..e8b113b4d 100644 --- a/tests/SMPAgentClient.hs +++ b/tests/SMPAgentClient.hs @@ -156,7 +156,7 @@ cfg :: AgentConfig cfg = defaultAgentConfig { tcpPort = agentTestPort, - smpServers = L.fromList ["smp://9VjLsOY5ZvB4hoglNdBzJFAUi_vP4GkZnJFahQOXV20=@localhost:5001"], + smpServers = L.fromList ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=@localhost:5001"], tbqSize = 1, dbFile = testDB, smpCfg = diff --git a/tests/SMPClient.hs b/tests/SMPClient.hs index d25df0411..1dddd47cc 100644 --- a/tests/SMPClient.hs +++ b/tests/SMPClient.hs @@ -37,7 +37,7 @@ testPort2 :: ServiceName testPort2 = "5002" testKeyHash :: C.KeyHash -testKeyHash = "9VjLsOY5ZvB4hoglNdBzJFAUi_vP4GkZnJFahQOXV20=" +testKeyHash = "LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=" testStoreLogFile :: FilePath testStoreLogFile = "tests/tmp/smp-server-store.log" diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md index 9e12802a6..82cadc67e 100644 --- a/tests/fixtures/README.md +++ b/tests/fixtures/README.md @@ -1,16 +1,18 @@ To generate fixtures: -(keep these instructions and *openssl.cnf* consistent with certificate generation on server) +(keep these instructions and *openssl_ca.conf* and *openssl_server.conf* files consistent with certificate generation on server) ```sh # CA certificate (identity/offline) openssl genpkey -algorithm ED448 -out ca.key -openssl req -new -x509 -days 999999 -config openssl.cnf -extensions v3_ca -key ca.key -out ca.crt -# server certificate (online) +openssl req -new -x509 -days 999999 -config openssl_ca.conf -extensions v3 -key ca.key -out ca.crt + +# Server certificate (online) openssl genpkey -algorithm ED448 -out server.key -openssl req -new -config openssl.cnf -reqexts v3_req -key server.key -out server.csr -openssl x509 -req -days 999999 -extfile openssl.cnf -extensions v3_req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -# to pretty-print +openssl req -new -config openssl_server.conf -reqexts v3 -key server.key -out server.csr +openssl x509 -req -days 999999 -extfile openssl_server.conf -extensions v3 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt + +# To pretty-print openssl x509 -in ca.crt -text -noout openssl req -in server.csr -text -noout openssl x509 -in server.crt -text -noout diff --git a/tests/fixtures/ca.crt b/tests/fixtures/ca.crt index 290d8f32d..e9902529b 100644 --- a/tests/fixtures/ca.crt +++ b/tests/fixtures/ca.crt @@ -1,11 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIBijCCAQqgAwIBAgIUf/txCk9PXE4nY2gQ/B/HG2sNzmswBQYDK2VxMBQxEjAQ -BgNVBAMMCWxvY2FsaG9zdDAgFw0yMTEyMjMxNzEzMjNaGA80NzU5MTExOTE3MTMy -M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAXlJkn15EFUS21zLI -I+HSKlhvt88LSXK70KkN4JRRLrXPaTYfpSchFZWmSuLmx5m6rmSg5Ywj9d2Ao1Mw -UTAdBgNVHQ4EFgQUxJBTkCx02jIpcUKU4fJYcnce59QwHwYDVR0jBBgwFoAUxJBT -kCx02jIpcUKU4fJYcnce59QwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDlxmpY -U7j3CIVnMKAGA1rqML5lvKrDTS6DidTiq90dkMTyoXv8AE4omdiGobMnB3HZPl+B -CpdDUYCfQfkNdi8Hqj3V9viqcgahbn5mGnjUAK1+Ix6r7KLm2zeKcfGEG008ykGW -TMUFDvkQqRIlFDdOPAA= +MIIBtjCCATagAwIBAgIUe2PryrWo0xXX9vcA3WfbCzcdmgAwBQYDK2VxMCoxFjAU +BgNVBAMMDVNNUCBzZXJ2ZXIgQ0ExEDAOBgNVBAoMB1NpbXBsZVgwIBcNMjIwMTEx +MTExNjM5WhgPNDc1OTEyMDgxMTE2MzlaMCoxFjAUBgNVBAMMDVNNUCBzZXJ2ZXIg +Q0ExEDAOBgNVBAoMB1NpbXBsZVgwQzAFBgMrZXEDOgCAcvFwVicR+RLZpiEWPFNR +XYTbf+mFcX1NHIyPQDugFwOCgqJAW1fsjYgFhtQJSMH/lc1N7clfm4CjUzBRMB0G +A1UdDgQWBBQcUJvR7mm26yxMQfCsWgbnwMmJVDAfBgNVHSMEGDAWgBQcUJvR7mm2 +6yxMQfCsWgbnwMmJVDAPBgNVHRMBAf8EBTADAQH/MAUGAytlcQNzAAAP/hMPNxyW +fyJi+iJViodU+C/aklnvHtjh5P3AbiVCSUfY6+PEdvkC8Ov0pBAYpYi5ukSNNVXl +ABVRlipB+vOcLQStNyaZ7kXzQ2IO/0btmIidh+G6SP8I4aytYIYYcV5pEUZpG1L1 +57g8P29SDv81AA== -----END CERTIFICATE----- diff --git a/tests/fixtures/ca.key b/tests/fixtures/ca.key index ca14015e0..33f2e1f76 100644 --- a/tests/fixtures/ca.key +++ b/tests/fixtures/ca.key @@ -1,4 +1,4 @@ -----BEGIN PRIVATE KEY----- -MEcCAQAwBQYDK2VxBDsEOZvjURTKSor4A7+45hnY721WD06L3E4UMKh9zntEY83C -CCv1Jju2fffDmtIFl6EXytF/nyEPGQfS5A== +MEcCAQAwBQYDK2VxBDsEOW6vCN7H7or3VsiMaNrFUoCf4LsuhYchWJKataA1mXhN +VIYFo7xWZWBnczDf5hkWQLIHNHm7DDr6+A== -----END PRIVATE KEY----- diff --git a/tests/fixtures/openssl_ca.conf b/tests/fixtures/openssl_ca.conf new file mode 100644 index 000000000..6cebea61a --- /dev/null +++ b/tests/fixtures/openssl_ca.conf @@ -0,0 +1,12 @@ +[req] +distinguished_name = req_distinguished_name +prompt = no + +[req_distinguished_name] +CN = SMP server CA +O = SimpleX + +[v3] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always +basicConstraints = critical,CA:true diff --git a/tests/fixtures/openssl.cnf b/tests/fixtures/openssl_server.conf similarity index 65% rename from tests/fixtures/openssl.cnf rename to tests/fixtures/openssl_server.conf index ab5344606..4fa8886da 100644 --- a/tests/fixtures/openssl.cnf +++ b/tests/fixtures/openssl_server.conf @@ -5,12 +5,12 @@ prompt = no [req_distinguished_name] CN = localhost -[v3_ca] -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always -basicConstraints = critical,CA:true - -[v3_req] +[v3] basicConstraints = CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyAgreement extendedKeyUsage = serverAuth +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +IP.1 = 127.0.0.1 diff --git a/tests/fixtures/server.crt b/tests/fixtures/server.crt index 2c01c2183..d869c5a4f 100644 --- a/tests/fixtures/server.crt +++ b/tests/fixtures/server.crt @@ -1,11 +1,12 @@ -----BEGIN CERTIFICATE----- -MIIBpjCCASagAwIBAgIUZVFfBPmSQ+hPioDvatGcRuwcKhgwBQYDK2VxMBQxEjAQ -BgNVBAMMCWxvY2FsaG9zdDAgFw0yMjAxMDMxNjI1MDhaGA80NzU5MTEzMDE2MjUw -OFowFDESMBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoA/q7ngl2MOKDeHVgC -4aNgO4+pOQ7cfHJhgVTKz0W6CCK9Ce39B0N+cRy6/dPzGCSSOYNKyGE0rnWAo28w -bTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDyDATBgNVHSUEDDAKBggrBgEFBQcDATAd -BgNVHQ4EFgQUQP8dENbwDxWZNX2QwauT1Ple6aswHwYDVR0jBBgwFoAUxJBTkCx0 -2jIpcUKU4fJYcnce59QwBQYDK2VxA3MAyQKimFiGGPR+vHHo2PVh5hHG9QSJn+34 -b36oGP4ekP/JFA0P3ZS7Kt7mLx2Lm8WmB31Ah1xJu1SA79LpArfum4QLn9GvOIyt -K4Ox/bUdYRvnWqFF8msQAWetO2tt0ZUar7zI7ac3uHBdKAzLFDw1fjgA +MIIB2jCCAVqgAwIBAgIUOMoaJ+qlkiUwq5MW7LDi+sHu64IwBQYDK2VxMCoxFjAU +BgNVBAMMDVNNUCBzZXJ2ZXIgQ0ExEDAOBgNVBAoMB1NpbXBsZVgwIBcNMjIwMTEx +MTExODAyWhgPNDc1OTEyMDgxMTE4MDJaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDBD +MAUGAytlcQM6AJXsy+S9i3Qdftydn51/p/6a0Ml9vJsYonAwv6CzpIOVG5e3Ath1 +wUfrS0YETmZe0EA7Nk40UKRSgKOBjDCBiTAJBgNVHRMEAjAAMAsGA1UdDwQEAwID +yDATBgNVHSUEDDAKBggrBgEFBQcDATAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8A +AAEwHQYDVR0OBBYEFPuA/LW1tq1byaZ4Rrx4JON60JlEMB8GA1UdIwQYMBaAFBxQ +m9HuabbrLExB8KxaBufAyYlUMAUGAytlcQNzABfc1ODnEfcpAsRmOjYIuyhMvJFE +sGnjf0TRk4vNS5vs2+CfEGHjKOrbAUDwhUI0Al26WpSvxMcvAE2E0qQoCSRS5Pa8 ++FgzzN3WfFMcXnuYAiqOp8op2mtsp5aJ3UIkwncItp5w+kICiWV6LL3QJM4zAA== -----END CERTIFICATE----- diff --git a/tests/fixtures/server.key b/tests/fixtures/server.key index 579ac813c..66c77a892 100644 --- a/tests/fixtures/server.key +++ b/tests/fixtures/server.key @@ -1,4 +1,4 @@ -----BEGIN PRIVATE KEY----- -MEcCAQAwBQYDK2VxBDsEOQANqfrmSygKW1iiDCgf/G/y2AH1lp5NurM3Q73fp9Aw -nznRFYq6BvM03cMOkqtFpQd15A+DZr248A== +MEcCAQAwBQYDK2VxBDsEOY3wzMxEAnHIJ36bmp+0YfaGUUdHPfS4y+DD+KmSrslz +PQPIY/SZc5orjPuF66RlEutpkqHBNE3WMg== -----END PRIVATE KEY-----