chain of two certificates - offline (identity) and online; switch certificates to v3 (#238)

This commit is contained in:
Efim Poberezkin authored and GitHub committed 2021-12-23 21:20:41 +04:00
1 parent 96cf4d288c
commit 0c866105d2
17 files changed
+179 -57

No files matched your search

+80 -23
View File
@@ -22,7 +22,7 @@ import Simplex.Messaging.Server.Env.STM
import Simplex.Messaging.Server.StoreLog (StoreLog, openReadStoreLog, storeLogFilePath)
import Simplex.Messaging.Transport (ATransport (..), TLS, Transport (..), encodeFingerprint, loadFingerprint)
import Simplex.Messaging.Transport.WebSockets (WS)
import System.Directory (createDirectoryIfMissing, doesFileExist, removeFile)
import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist, removeDirectoryRecursive, removeFile)
import System.Exit (exitFailure)
import System.FilePath (combine)
import System.IO (IOMode (..), hFlush, stdout)
@@ -43,6 +43,7 @@ serverConfig =
-- below parameters are set based on ini file /etc/opt/simplex/smp-server.ini
transports = undefined,
storeLog = undefined,
caCertificateFile = undefined,
serverPrivateKeyFile = undefined,
serverCertificateFile = undefined
}
@@ -56,12 +57,19 @@ cfgDir = "/etc/opt/simplex"
logDir :: FilePath
logDir = "/var/opt/simplex"
-- TODO remove file paths from ini
defaultStoreLogFile :: FilePath
defaultStoreLogFile = combine logDir "smp-server-store.log"
iniFile :: FilePath
iniFile = combine cfgDir "smp-server.ini"
caPrivateKeyFile :: FilePath
caPrivateKeyFile = combine cfgDir "ca.key"
defaultCACertificateFile :: FilePath
defaultCACertificateFile = combine cfgDir "ca.crt"
defaultPrivateKeyFile :: FilePath
defaultPrivateKeyFile = combine cfgDir "server.key"
@@ -82,12 +90,14 @@ main = do
putStrLn "Error: server is already initialized. Start it with `smp-server start` command"
fingerprint <- loadSavedFingerprint
printConfig cfg fingerprint
checkCAPrivateKeyFile
exitFailure
Left _ -> do
cfg <- initializeServer opts
putStrLn "Server was initialized. Start it with `smp-server start` command"
fingerprint <- loadSavedFingerprint
printConfig cfg fingerprint
warnCAPrivateKeyFile
ServerStart ->
runExceptT (getConfig opts) >>= \case
Right cfg -> runServer cfg
@@ -111,9 +121,9 @@ getConfig opts = do
pure $ makeConfig ini storeLog
makeConfig :: IniOpts -> Maybe (StoreLog 'ReadMode) -> ServerConfig
makeConfig IniOpts {serverPort, enableWebsockets, serverPrivateKeyFile, serverCertificateFile} storeLog =
makeConfig IniOpts {serverPort, enableWebsockets, caCertificateFile, serverPrivateKeyFile, serverCertificateFile} storeLog =
let transports = (serverPort, transport @TLS) : [("80", transport @WS) | enableWebsockets]
in serverConfig {transports, storeLog, serverPrivateKeyFile, serverCertificateFile}
in serverConfig {transports, storeLog, caCertificateFile, serverPrivateKeyFile, serverCertificateFile}
printConfig :: ServerConfig -> String -> IO ()
printConfig ServerConfig {storeLog} fingerprint = do
@@ -126,8 +136,8 @@ initializeServer :: ServerOpts -> IO ServerConfig
initializeServer opts = do
createDirectoryIfMissing True cfgDir
ini <- createIni opts
createKeyAndCertificate ini opts
saveFingerprint $ serverCertificateFile (ini :: IniOpts)
createX509 ini opts
saveFingerprint $ caCertificateFile (ini :: IniOpts)
storeLog <- openStoreLog opts ini
pure $ makeConfig ini storeLog
@@ -136,38 +146,59 @@ runServer cfg = do
savedFingerprint <- loadSavedFingerprint
checkSavedFingerprint savedFingerprint
printConfig cfg savedFingerprint
checkCAPrivateKeyFile
forM_ (transports cfg) $ \(port, ATransport t) ->
putStrLn $ "listening on port " <> port <> " (" <> transportName t <> ")"
runSMPServer cfg
where
checkSavedFingerprint :: String -> IO ()
checkSavedFingerprint savedFingerprint = do
fingerprint <- loadFingerprint $ serverCertificateFile (cfg :: ServerConfig)
fingerprint <- loadFingerprint $ caCertificateFile (cfg :: ServerConfig)
if savedFingerprint == (B.unpack . encodeFingerprint) fingerprint
then putStrLn "stored fingerprint is valid"
else putStrLn "stored fingerprint is invalid" >> exitFailure
checkCAPrivateKeyFile :: IO ()
checkCAPrivateKeyFile =
doesFileExist caPrivateKeyFile >>= (`when` (alert >> warnCAPrivateKeyFile))
where
alert = putStrLn $ "WARNING: " <> caPrivateKeyFile <> " is present on the server!"
warnCAPrivateKeyFile :: IO ()
warnCAPrivateKeyFile =
putStrLn $
"----------\n\
\We highly recommend to remove CA private key file from the server and keep it securely in place of your choosing.\n\
\In case server's TLS credential is compromised you will be able to regenerate it using this key,\n\
\thus keeping server's identity and allowing clients to keep established connections. Key location:\n"
<> caPrivateKeyFile
<> "\n----------"
deleteServer :: IO ()
deleteServer = do
ini <- runExceptT readIni
deleteIfExists iniFile
case ini of
Right IniOpts {storeLogFile, serverPrivateKeyFile, serverCertificateFile} -> do
-- TODO delete only cfgDir and logDir once file paths are removed from ini
Right IniOpts {storeLogFile, caCertificateFile, serverPrivateKeyFile, serverCertificateFile} -> do
deleteDirIfExists cfgDir
deleteIfExists storeLogFile
deleteIfExists caCertificateFile
deleteIfExists serverPrivateKeyFile
deleteIfExists serverCertificateFile
deleteIfExists fingerprintFile
Left _ -> do
deleteDirIfExists cfgDir
deleteIfExists defaultStoreLogFile
deleteIfExists defaultCACertificateFile
deleteIfExists defaultPrivateKeyFile
deleteIfExists defaultCertificateFile
deleteIfExists fingerprintFile
data IniOpts = IniOpts
{ enableStoreLog :: Bool,
storeLogFile :: FilePath,
serverPort :: ServiceName,
enableWebsockets :: Bool,
caCertificateFile :: FilePath,
serverPrivateKeyFile :: FilePath,
serverCertificateFile :: FilePath
}
@@ -180,9 +211,10 @@ readIni = do
storeLogFile = opt defaultStoreLogFile "STORE_LOG" "file" ini
serverPort = opt defaultServerPort "TRANSPORT" "port" ini
enableWebsockets = (== Right "on") $ lookupValue "TRANSPORT" "websockets" ini
caCertificateFile = opt defaultCACertificateFile "TRANSPORT" "ca_certificate_file" ini
serverPrivateKeyFile = opt defaultPrivateKeyFile "TRANSPORT" "private_key_file" ini
serverCertificateFile = opt defaultCertificateFile "TRANSPORT" "certificate_file" ini
pure IniOpts {enableStoreLog, storeLogFile, serverPort, enableWebsockets, serverPrivateKeyFile, serverCertificateFile}
pure IniOpts {enableStoreLog, storeLogFile, serverPort, enableWebsockets, caCertificateFile, serverPrivateKeyFile, serverCertificateFile}
where
opt :: String -> Text -> Text -> Ini -> String
opt def section key ini = either (const def) T.unpack $ lookupValue section key ini
@@ -203,6 +235,9 @@ createIni ServerOpts {enableStoreLog} = do
<> defaultStoreLogFile
<> "\n\n\
\[TRANSPORT]\n\n\
\# ca_certificate_file: "
<> defaultCACertificateFile
<> "\n\
\# private_key_file: "
<> defaultPrivateKeyFile
<> "\n\
@@ -219,28 +254,47 @@ createIni ServerOpts {enableStoreLog} = do
storeLogFile = defaultStoreLogFile,
serverPort = defaultServerPort,
enableWebsockets = True,
caCertificateFile = defaultCACertificateFile,
serverPrivateKeyFile = defaultPrivateKeyFile,
serverCertificateFile = defaultCertificateFile
}
-- To generate self-signed certificate:
-- https://blog.pinterjann.is/ed25519-certificates.html
createKeyAndCertificate :: IniOpts -> ServerOpts -> IO ()
createKeyAndCertificate IniOpts {serverPrivateKeyFile, serverCertificateFile} ServerOpts {pubkeyAlgorihtm} = do
createX509 :: IniOpts -> ServerOpts -> IO ()
createX509 IniOpts {caCertificateFile, serverPrivateKeyFile, serverCertificateFile} ServerOpts {pubkeyAlgorihtm} = do
createOpensslConf
-- CA certificate (identity/offline)
run $ "openssl genpkey -algorithm " <> pubkeyAlgorihtm <> " -out " <> caPrivateKeyFile
run $ "openssl req -new -x509 -days 999999 -config " <> opensslConfFile <> " -extensions v3_ca -key " <> caPrivateKeyFile <> " -out " <> caCertificateFile
-- server certificate (online)
run $ "openssl genpkey -algorithm " <> pubkeyAlgorihtm <> " -out " <> serverPrivateKeyFile
run $ "openssl req -new -key " <> serverPrivateKeyFile <> " -subj \"/CN=localhost\" -out " <> csrPath
run $ "openssl x509 -req -days 999999 -in " <> csrPath <> " -signkey " <> serverPrivateKeyFile <> " -out " <> serverCertificateFile
run $ "rm " <> csrPath
run $ "openssl req -new -config " <> opensslConfFile <> " -reqexts v3_req -key " <> serverPrivateKeyFile <> " -out " <> serverCsrFile
run $ "openssl x509 -req -days 999999 -copy_extensions copy -in " <> serverCsrFile <> " -CA " <> caCertificateFile <> " -CAkey " <> caPrivateKeyFile <> " -out " <> serverCertificateFile
where
run :: String -> IO ()
run cmd = void $ readCreateProcess (shell cmd) ""
csrPath :: String
csrPath = combine cfgDir "localhost.csr"
opensslConfFile = combine cfgDir "openssl.cnf"
serverCsrFile = combine cfgDir "server.csr"
createOpensslConf :: IO ()
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
writeFile
opensslConfFile
"[req]\n\
\distinguished_name = req_distinguished_name\n\
\prompt = no\n\n\
\[req_distinguished_name]\n\
\CN = localhost\n\n\
\[v3_ca]\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"
saveFingerprint :: FilePath -> IO ()
saveFingerprint serverCertificateFile = do
fingerprint <- loadFingerprint serverCertificateFile
saveFingerprint caCertificateFile = do
fingerprint <- loadFingerprint caCertificateFile
writeFile fingerprintFile $ (B.unpack . encodeFingerprint) fingerprint <> "\n"
loadSavedFingerprint :: IO String
@@ -256,6 +310,9 @@ fileExists path = do
deleteIfExists :: FilePath -> IO ()
deleteIfExists path = doesFileExist path >>= (`when` removeFile path)
deleteDirIfExists :: FilePath -> IO ()
deleteDirIfExists path = doesDirectoryExist path >>= (`when` removeDirectoryRecursive path)
confirm :: String -> IO ()
confirm msg = do
putStr $ msg <> " (y/N): "
+2 -2
View File
@@ -105,13 +105,13 @@ runSMPAgent t cfg = do
-- This function uses passed TMVar to signal when the server is ready to accept TCP requests (True)
-- and when it is disconnected from the TCP socket once the server thread is killed (False).
runSMPAgentBlocking :: (MonadRandom m, MonadUnliftIO m) => ATransport -> TMVar Bool -> AgentConfig -> m ()
runSMPAgentBlocking (ATransport t) started cfg@AgentConfig {tcpPort, agentCertificateFile, agentPrivateKeyFile} = do
runSMPAgentBlocking (ATransport t) started cfg@AgentConfig {tcpPort, caCertificateFile, agentCertificateFile, agentPrivateKeyFile} = do
runReaderT (smpAgent t) =<< newSMPAgentEnv cfg
where
smpAgent :: forall c m'. (Transport c, MonadUnliftIO m', MonadReader Env m') => TProxy c -> m' ()
smpAgent _ = do
-- tlsServerParams not in env to avoid breaking functional api w/t key and certificate generation
tlsServerParams <- liftIO $ loadTLSServerParams agentCertificateFile agentPrivateKeyFile
tlsServerParams <- liftIO $ loadTLSServerParams caCertificateFile agentCertificateFile agentPrivateKeyFile
runTransportServer started tcpPort tlsServerParams $ \(h :: c) -> do
liftIO . putLn h $ "Welcome to SMP agent v" <> currentSMPVersionStr
c <- getAgentClient
+3 -1
View File
@@ -32,6 +32,7 @@ data AgentConfig = AgentConfig
smpCfg :: SMPClientConfig,
retryInterval :: RetryInterval,
reconnectInterval :: RetryInterval,
caCertificateFile :: FilePath,
agentPrivateKeyFile :: FilePath,
agentCertificateFile :: FilePath
}
@@ -63,7 +64,8 @@ defaultAgentConfig =
increaseAfter = 10_000_000,
maxInterval = 10_000_000
},
-- ! we do not generate these key and certificate
-- ! we do not generate these
caCertificateFile = "/etc/opt/simplex-agent/ca.crt",
agentPrivateKeyFile = "/etc/opt/simplex-agent/agent.key",
agentCertificateFile = "/etc/opt/simplex-agent/agent.crt"
}
+3 -2
View File
@@ -32,6 +32,7 @@ data ServerConfig = ServerConfig
msgIdBytes :: Int,
storeLog :: Maybe (StoreLog 'ReadMode),
blockSize :: Int,
caCertificateFile :: FilePath,
serverPrivateKeyFile :: FilePath,
serverCertificateFile :: FilePath
}
@@ -92,13 +93,13 @@ newSubscription = do
return Sub {subThread = NoSub, delivered}
newEnv :: forall m. (MonadUnliftIO m, MonadRandom m) => ServerConfig -> m Env
newEnv config = do
newEnv config@ServerConfig {caCertificateFile, serverCertificateFile, serverPrivateKeyFile} = do
server <- atomically $ newServer (serverTbqSize config)
queueStore <- atomically newQueueStore
msgStore <- atomically newMsgStore
idsDrg <- drgNew >>= newTVarIO
s' <- restoreQueues queueStore `mapM` storeLog (config :: ServerConfig)
tlsServerParams <- liftIO $ loadTLSServerParams (serverCertificateFile config) (serverPrivateKeyFile config)
tlsServerParams <- liftIO $ loadTLSServerParams caCertificateFile serverCertificateFile serverPrivateKeyFile
return Env {config, server, queueStore, msgStore, idsDrg, storeLog = s', tlsServerParams}
where
restoreQueues :: QueueStore -> StoreLog 'ReadMode -> m (StoreLog 'WriteMode)
+9 -8
View File
@@ -213,13 +213,13 @@ startTCPClient host port clientParams = withSocketsDo $ resolve >>= tryOpen err
ctx <- connectTLS clientParams sock
getClientConnection ctx
loadTLSServerParams :: FilePath -> FilePath -> IO T.ServerParams
loadTLSServerParams certificateFile privateKeyFile =
loadTLSServerParams :: FilePath -> FilePath -> FilePath -> IO T.ServerParams
loadTLSServerParams caCertificateFile certificateFile privateKeyFile =
fromCredential <$> loadServerCredential
where
loadServerCredential :: IO T.Credential
loadServerCredential =
T.credentialLoadX509 certificateFile privateKeyFile >>= \case
T.credentialLoadX509Chain certificateFile [caCertificateFile] privateKeyFile >>= \case
Right credential -> pure credential
Left _ -> putStrLn "invalid credential" >> exitFailure
fromCredential :: T.Credential -> T.ServerParams
@@ -288,8 +288,9 @@ mkTLSClientParams host port keyHash = do
validateCertificateChain :: Maybe C.KeyHash -> HostName -> ByteString -> X.CertificateChain -> IO [XV.FailedReason]
validateCertificateChain _ _ _ (X.CertificateChain []) = pure [XV.EmptyChain]
validateCertificateChain keyHash host port cc@(X.CertificateChain sc@[cert]) =
let fp = XV.getFingerprint cert X.HashSHA256
validateCertificateChain _ _ _ (X.CertificateChain [_]) = pure [XV.EmptyChain]
validateCertificateChain keyHash host port cc@(X.CertificateChain sc@[_, caCert]) =
let fp = XV.getFingerprint caCert X.HashSHA256
in if maybe True (sameFingerprint fp) keyHash
then x509validate
else pure [XV.UnknownCA]
@@ -299,11 +300,11 @@ validateCertificateChain keyHash host port cc@(X.CertificateChain sc@[cert]) =
x509validate = XV.validate X.HashSHA256 hooks checks certStore cache serviceID cc
where
hooks = XV.defaultHooks
checks = XV.defaultChecks {XV.checkLeafV3 = False} -- TODO create v3 certificates? https://stackoverflow.com/a/18242720
checks = XV.defaultChecks
certStore = XS.makeCertificateStore sc
cache = XV.exceptionValidationCache [] -- we manually check fingerprint only of the offline certificate (TODO 2 certificates)
cache = XV.exceptionValidationCache [] -- we manually check fingerprint only of the identity certificate (ca.crt)
serviceID = (host, port)
validateCertificateChain _ _ _ (X.CertificateChain (_ : _)) = pure [XV.AuthorityTooDeep]
validateCertificateChain _ _ _ _ = pure [XV.AuthorityTooDeep]
supportedParameters :: T.Supported
supportedParameters =
+1 -1
View File
@@ -368,7 +368,7 @@ syntaxTests t = do
-- TODO: ERROR no connection alias in the response (it does not generate it yet if not provided)
-- TODO: add tests with defined connection alias
it "using same server as in invitation" $
("311", "a", "JOIN https://simpex.chat/invitation#/?smp=smp%3A%2F%2F" <> (U.encode . decodeLenient) "f80NoyPgNXR5n/fRVfmRTtkRps6/xDrQLmiuz9qFUJU=" <> "%40localhost%3A5001%2F3456-w%3D%3D%23&e2e=" <> urlEncode True samplePublicKey <> " 14\nbob's connInfo")
("311", "a", "JOIN https://simpex.chat/invitation#/?smp=smp%3A%2F%2F" <> (U.encode . decodeLenient) "9VjLsOY5ZvB4hoglNdBzJFAUi/vP4GkZnJFahQOXV20=" <> "%40localhost%3A5001%2F3456-w%3D%3D%23&e2e=" <> urlEncode True samplePublicKey <> " 14\nbob's connInfo")
>#> ("311", "a", "ERR SMP AUTH")
describe "invalid" $ do
-- TODO: JOIN is not merged yet - to be added
+4 -3
View File
@@ -156,7 +156,7 @@ cfg :: AgentConfig
cfg =
defaultAgentConfig
{ tcpPort = agentTestPort,
smpServers = L.fromList ["localhost:5001#f80NoyPgNXR5n/fRVfmRTtkRps6/xDrQLmiuz9qFUJU="],
smpServers = L.fromList ["localhost:5001#9VjLsOY5ZvB4hoglNdBzJFAUi/vP4GkZnJFahQOXV20="],
tbqSize = 1,
dbFile = testDB,
smpCfg =
@@ -166,8 +166,9 @@ cfg =
tcpTimeout = 500_000
},
retryInterval = (retryInterval defaultAgentConfig) {initialInterval = 50_000},
agentPrivateKeyFile = "tests/fixtures/example.key",
agentCertificateFile = "tests/fixtures/example.crt"
caCertificateFile = "tests/fixtures/ca.crt",
agentPrivateKeyFile = "tests/fixtures/server.key",
agentCertificateFile = "tests/fixtures/server.crt"
}
withSmpAgentThreadOn_ :: (MonadUnliftIO m, MonadRandom m) => ATransport -> (ServiceName, ServiceName, String) -> m () -> (ThreadId -> m a) -> m a
+5 -4
View File
@@ -38,13 +38,13 @@ testPort2 :: ServiceName
testPort2 = "5002"
testKeyHashStr :: ByteString
testKeyHashStr = "f80NoyPgNXR5n/fRVfmRTtkRps6/xDrQLmiuz9qFUJU="
testKeyHashStr = "9VjLsOY5ZvB4hoglNdBzJFAUi/vP4GkZnJFahQOXV20="
testBlockSize :: Int
testBlockSize = 16 * 1024 -- TODO move to Protocol
testKeyHash :: Maybe C.KeyHash
testKeyHash = Just "f80NoyPgNXR5n/fRVfmRTtkRps6/xDrQLmiuz9qFUJU="
testKeyHash = Just "9VjLsOY5ZvB4hoglNdBzJFAUi/vP4GkZnJFahQOXV20="
testStoreLogFile :: FilePath
testStoreLogFile = "tests/tmp/smp-server-store.log"
@@ -67,8 +67,9 @@ cfg =
msgIdBytes = 24,
storeLog = Nothing,
blockSize = testBlockSize,
serverPrivateKeyFile = "tests/fixtures/example.key",
serverCertificateFile = "tests/fixtures/example.crt"
caCertificateFile = "tests/fixtures/ca.crt",
serverPrivateKeyFile = "tests/fixtures/server.key",
serverCertificateFile = "tests/fixtures/server.crt"
}
withSmpServerStoreLogOn :: (MonadUnliftIO m, MonadRandom m) => ATransport -> ServiceName -> (ThreadId -> m a) -> m a
+1
View File
@@ -0,0 +1 @@
server.csr
+25
View File
@@ -0,0 +1,25 @@
To generate fixtures:
(keep these instructions and *openssl.cnf* 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 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 -copy_extensions copy -in server.csr -CA ca.crt -CAkey ca.key -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
```
To compute fingerprint for tests:
```sh
stack ghci --ghci-options src/Simplex/Messaging/Transport.hs
> fingerprint <- loadFingerprint "tests/fixtures/ca.crt"
> encodeFingerprint fingerprint
```
+11
View File
@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBijCCAQqgAwIBAgIUf/txCk9PXE4nY2gQ/B/HG2sNzmswBQYDK2VxMBQxEjAQ
BgNVBAMMCWxvY2FsaG9zdDAgFw0yMTEyMjMxNzEzMjNaGA80NzU5MTExOTE3MTMy
M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAXlJkn15EFUS21zLI
I+HSKlhvt88LSXK70KkN4JRRLrXPaTYfpSchFZWmSuLmx5m6rmSg5Ywj9d2Ao1Mw
UTAdBgNVHQ4EFgQUxJBTkCx02jIpcUKU4fJYcnce59QwHwYDVR0jBBgwFoAUxJBT
kCx02jIpcUKU4fJYcnce59QwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDlxmpY
U7j3CIVnMKAGA1rqML5lvKrDTS6DidTiq90dkMTyoXv8AE4omdiGobMnB3HZPl+B
CpdDUYCfQfkNdi8Hqj3V9viqcgahbn5mGnjUAK1+Ix6r7KLm2zeKcfGEG008ykGW
TMUFDvkQqRIlFDdOPAA=
-----END CERTIFICATE-----
+4
View File
@@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOZvjURTKSor4A7+45hnY721WD06L3E4UMKh9zntEY83C
CCv1Jju2fffDmtIFl6EXytF/nyEPGQfS5A==
-----END PRIVATE KEY-----
-9
View File
@@ -1,9 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBLzCBsAIUDS2s4hUHeT9gYpGcf7SJNnyReDUwBQYDK2VxMBQxEjAQBgNVBAMM
CWxvY2FsaG9zdDAgFw0yMTEyMTQxMDM3NTFaGA80NzU5MTExMDEwMzc1MVowFDES
MBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAMb/HUcgN/sU2rm1YHoTMFVTu
ptY7hKjDm8mRxUWXzvHS0S6vqZRfJuCBQms4MSlTv+z1LjzDevUAMAUGAytlcQNz
AA2eyrpA0O2TzNCeVEs0Dp/uXTzQPWJHD8fN0DCwSJf7xIY01jNmcvx/IFYnGCd+
uQ/7vm6kcUFNgKhVWY9e7xLjYqeBirHTQiTRrh+9mKDOwmsSOhnz3acYPgrJ2QUO
zDtZa16ppKRA5ucLJ4AXaacOAA==
-----END CERTIFICATE-----
-4
View File
@@ -1,4 +0,0 @@
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOcj0BvnNHWg2dsOnww++p/PHxnl+KGWFXre57wXEredA
j0xo78ZgadAeY0Y5mO4nfb8lk3CBz+ojGA==
-----END PRIVATE KEY-----
+16
View File
@@ -0,0 +1,16 @@
[req]
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
CN = localhost
[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyAgreement
extendedKeyUsage = serverAuth
+11
View File
@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBpjCCASagAwIBAgIUaZBiYKJjueUsvwoaeK9mh+F2mn0wBQYDK2VxMBQxEjAQ
BgNVBAMMCWxvY2FsaG9zdDAgFw0yMTEyMjMxNzEzMzNaGA80NzU5MTExOTE3MTMz
M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoA/q7ngl2MOKDeHVgC
4aNgO4+pOQ7cfHJhgVTKz0W6CCK9Ce39B0N+cRy6/dPzGCSSOYNKyGE0rnWAo28w
bTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDyDATBgNVHSUEDDAKBggrBgEFBQcDATAd
BgNVHQ4EFgQUQP8dENbwDxWZNX2QwauT1Ple6aswHwYDVR0jBBgwFoAUxJBTkCx0
2jIpcUKU4fJYcnce59QwBQYDK2VxA3MATscvAiT11CqXODKwx/0uLan3mKRLfJrP
gqshoOmIG4HUXoSPZwjgARaCKTwFwMlLmMJt6wd7c8iAnKdfghvDvE+fgSKDe1d4
tVKQt+RWUzMb5w4WyqivxmKQyIBHNHzkj3Qh54P6JLpfMz29j84/pxIA
-----END CERTIFICATE-----
+4
View File
@@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOQANqfrmSygKW1iiDCgf/G/y2AH1lp5NurM3Q73fp9Aw
nznRFYq6BvM03cMOkqtFpQd15A+DZr248A==
-----END PRIVATE KEY-----