mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-06-05 04:11:39 +00:00
add IP and FQDN to online certificate (#278)
This commit is contained in:
+76
-34
@@ -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
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
@@ -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 =
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
Vendored
+8
-6
@@ -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
|
||||
|
||||
Vendored
+10
-9
@@ -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-----
|
||||
|
||||
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MEcCAQAwBQYDK2VxBDsEOZvjURTKSor4A7+45hnY721WD06L3E4UMKh9zntEY83C
|
||||
CCv1Jju2fffDmtIFl6EXytF/nyEPGQfS5A==
|
||||
MEcCAQAwBQYDK2VxBDsEOW6vCN7H7or3VsiMaNrFUoCf4LsuhYchWJKataA1mXhN
|
||||
VIYFo7xWZWBnczDf5hkWQLIHNHm7DDr6+A==
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Vendored
+12
@@ -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
|
||||
@@ -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
|
||||
Vendored
+10
-9
@@ -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-----
|
||||
|
||||
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MEcCAQAwBQYDK2VxBDsEOQANqfrmSygKW1iiDCgf/G/y2AH1lp5NurM3Q73fp9Aw
|
||||
nznRFYq6BvM03cMOkqtFpQd15A+DZr248A==
|
||||
MEcCAQAwBQYDK2VxBDsEOY3wzMxEAnHIJ36bmp+0YfaGUUdHPfS4y+DD+KmSrslz
|
||||
PQPIY/SZc5orjPuF66RlEutpkqHBNE3WMg==
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Reference in New Issue
Block a user