Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/6-federation/check-server-cert-usage
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Server certificates without the "serverAuth" extended usage flag are now rejected when connecting to a remote federator.
5 changes: 4 additions & 1 deletion services/federator/federator.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cabal-version: 1.12
--
-- see: https://github.com/sol/hpack
--
-- hash: 9a181e3a92130220d845ad959ca6e02a217b07a38602513bff4c9376a4ffe145
-- hash: 9cb4007a4aa28024c1ac5077eb0840c877b7fd3a7afee0b48a9c218a54afc40a

name: federator
version: 1.0.0
Expand All @@ -25,9 +25,12 @@ extra-source-files:
test/resources/unit/localhost-dot-key.pem
test/resources/unit/localhost-dot.pem
test/resources/unit/localhost-key.pem
test/resources/unit/localhost.client-only-key.pem
test/resources/unit/localhost.client-only.pem
test/resources/unit/localhost.example.com-key.pem
test/resources/unit/localhost.example.com.pem
test/resources/unit/localhost.pem
test/resources/unit/README.md
test/resources/unit/second-federator.example.com-key.pem
test/resources/unit/second-federator.example.com.pem
test/resources/unit/unit-ca-key.pem
Expand Down
4 changes: 2 additions & 2 deletions services/federator/src/Federator/Remote.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ mkGrpcClient target@(SrvTarget host port) = do
{ TLS.onServerCertificate =
X509.validate
X509.HashSHA256
(X509.defaultHooks {X509.hookValidateName = validateDomainName})
X509.defaultChecks,
X509.defaultHooks {X509.hookValidateName = validateDomainName}
X509.defaultChecks {X509.checkLeafKeyPurpose = [X509.KeyUsagePurpose_ServerAuth]},
TLS.onCertificateRequest = \_ -> pure (Just (settings ^. creds))
},
TLS.clientShared = def {TLS.sharedCAStore = settings ^. caStore}
Expand Down
5 changes: 5 additions & 0 deletions services/federator/test/resources/unit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
localhost.client-only.pem has been created with:

```
openssl x509 -req -in <(openssl req -nodes -newkey rsa:2048 -keyout localhost.client-only-key.pem -out /dev/stdout -subj "/") -CA unit-ca.pem -CAkey unit-ca-key.pem -out localhost.client-only.pem -set_serial 0 -extfile <(echo 'subjectAltName = DNS:*integration.example.com, DNS:localhost'; echo 'extendedKeyUsage = clientAuth')
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC6Zp5uNWp581WJ
BwrneDnQRAuecmAHjnUwF1c/EAe/GJ3vO7erBU9//vDvGutNwZRXYrrGV1Jy2WY3
dADk513M0vc2OcOBWxKo+8svsio2rCLhTwDpR91DIINP8SjPRYxX9qSY8C8hRdxI
cER1EcwIf20EM5qL/shYl2p0wIpXQuwV3FwQGMELmkSzrb5kyq8tCPa2vzPtT5Lq
G50PyhcvnmPj/D0IpxalfOjLDvkeAXyEb79yTyuY3zDOFY2QjqJcxQkWu9uQH94L
3aMKIX2D8VCiPGbZTAKcW6BQACHjd74Kq6eyHW66C6lXBr0P2BDVAn8/w/Nduw/h
lZuUvMTLAgMBAAECggEBAK6b2EcmtHI+Vl7BAR7pSUblpviq7XfGo9ID20+QpaEF
31Qt3ZRPqjQdTfa9gbRZ5KqjKpEHVY2ORqklenzymrR23uql25T+ChHPpHsua0rB
nv7t8c2U6xipiThGkNLwtFHmEjPNsmh5t6sHt6junfFL5IQuDtSbO3N5i1iI0E6C
IZPmnkCOqQI+FjesJXvRgEwqJPDFlHNWTRAV751K1dBQsvsYSEetrR/+JGV8fgF6
vmFsaYmbLzeuGMg2I3tgiD0s5MdgWu6OvasZUS2OyGv2IPX9fWId5YoIcneVDE6X
q1Yw0nuF6Tf+jwVJEvk6telRhEJACx7p0Nkw65kC9SkCgYEA4O60hkRwzrwPhxXq
ZskZ3jjsAN+pL7PCWzPFJ4UxhJAlAdPpB48DM9D1u76sJkK5y5FhA7glFmNfH5eM
HX2LVB/oQNzjKzJp4o2e0WEb3Asvzo3koCTNEbMCPhOlmx8T5s/+HTndFPS34BYB
epa9TJTWz5CPz8uBIuaQfH0SMt8CgYEA1CV9r7GOcdVqPOO8+VdqXAuIvMyYpzFQ
ETNlU5A3G2kbmlViJTEGLHC1tiJe5cv6Kt74uFdR7pl+0Hba67Q8vZLWuj0aRwc7
EzmpXYSkpSi2+q3ntuTjMGmWx9ZmOldNmBiarm850lAsGrx9TNahZfzk9fZVif6m
h6y6t5fw95UCgYAJsF6YVgRh81nb4MbLDKiPmPYZh4jbJCwgD5fTfvpGEot1i7JD
ABcMOVkMcEcsEr28FhQOu/TlBPzI+JcxggHpasJvYNRsPOywtJb9v+gaT2UMybHq
cAthUsuq7t+4Udtimt0AV0i9qVjuTyRbKnkW/mZOZJS9R6/VWAcrRZvuEwKBgQCb
HOZvBdXu6WoKJ0HO1dmQf2Z1FOswo9+1E+0sUi/YvNtP1soyA0xORgK2rx7PynqZ
yfn1XvMrD9QnPCAJYvleavTRq0eBU4ogHnL1S7zOfZx8YZcgpO5wQWPbramFUrwL
T0IZ9H1EhxYYXmUHP4828Ne/92LHyQed/+9tuYyYmQKBgQC2lzwQQAVRTM2sVHt2
r/szB4/QXZpBcXUiUJoVdI2NETuSwxf6XhxiXtI6NPYIWjNiA+dZyWA/AY+EeMJL
9OPV/OtZArHILYHP1lyABs5ZwSC/qorkqct601T5+rjJyd8RVLJe+iWIrDEvU2V1
inC3V5SG3R5wDEzBfQRuxnKfpA==
-----END PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC2zCCAcOgAwIBAgIBADANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5jYS5l
eGFtcGxlLmNvbTAeFw0yMTEwMTMwODAwMTRaFw0yMTExMTIwODAwMTRaMAAwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6Zp5uNWp581WJBwrneDnQRAue
cmAHjnUwF1c/EAe/GJ3vO7erBU9//vDvGutNwZRXYrrGV1Jy2WY3dADk513M0vc2
OcOBWxKo+8svsio2rCLhTwDpR91DIINP8SjPRYxX9qSY8C8hRdxIcER1EcwIf20E
M5qL/shYl2p0wIpXQuwV3FwQGMELmkSzrb5kyq8tCPa2vzPtT5LqG50PyhcvnmPj
/D0IpxalfOjLDvkeAXyEb79yTyuY3zDOFY2QjqJcxQkWu9uQH94L3aMKIX2D8VCi
PGbZTAKcW6BQACHjd74Kq6eyHW66C6lXBr0P2BDVAn8/w/Nduw/hlZuUvMTLAgMB
AAGjRzBFMC4GA1UdEQQnMCWCGCppbnRlZ3JhdGlvbi5leGFtcGxlLmNvbYIJbG9j
YWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBB
wCeqw5FGB8GuZG9nEbRinfPKcMKNidy9zh/ppS6HyqOLuls3mAOgvdNZugUFsZq9
RSOXofk8lAP8bwaZubp4VB2DSf/EsJoFXydPgT5TDqGVcBRGXJ0EKxqjonWbjOlR
69BwNsE8nZ/vmTY+5RdyUJNCy+CUtXSRmggYa8ix5WqZFOGZ0BmOM+vzw98OuhH2
eZa9+e27fHiL1UVhS70RaMNixVai0cx8U+k2ntMCSbEbPoE25QWzfJEu6D7teh4c
nFv+6I5vZ/0g2z28h6Or/N6Bp2svvuuo5iyRzrWMPldHrbyP+zDh0A7Qtf8Io1Fv
LadoTB43UaTNaYdrwq2K
-----END CERTIFICATE-----
18 changes: 18 additions & 0 deletions services/federator/test/unit/Test/Federator/Remote.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ testValidatesCertificateWrongHostname =
"refuses to connect with server"
[ testCase "when the server's certificate doesn't match the hostname" $
bracket (startMockServer certForWrongDomain) (Async.cancel . fst) $ \(_, port) -> do
tlsSettings <- mkTLSSettingsOrThrow settings
eitherClient <-
Polysemy.runM
. Polysemy.runError
. Polysemy.runInputConst tlsSettings
$ mkGrpcClient (SrvTarget "localhost." (fromIntegral port))
case eitherClient of
Left (RemoteErrorTLSException _ _) -> pure ()
Left x -> assertFailure $ "Expected TLS failure, got: " <> show x
Right _ -> assertFailure "Expected connection with the server to fail",
testCase "when the server's certificate does not have the server key usage flag" $
bracket (startMockServer certWithoutServerKeyUsage) (Async.cancel . fst) $ \(_, port) -> do
tlsSettings <- mkTLSSettingsOrThrow settings
eitherClient <-
Polysemy.runM
Expand All @@ -122,6 +134,12 @@ certForLocalhostDot = WarpTLS.tlsSettings "test/resources/unit/localhost-dot.pem
certForWrongDomain :: WarpTLS.TLSSettings
certForWrongDomain = WarpTLS.tlsSettings "test/resources/unit/localhost.example.com.pem" "test/resources/unit/localhost.example.com-key.pem"

certWithoutServerKeyUsage :: WarpTLS.TLSSettings
certWithoutServerKeyUsage =
WarpTLS.tlsSettings
"test/resources/unit/localhost.client-only.pem"
"test/resources/unit/localhost.client-only-key.pem"

startMockServer :: MonadIO m => WarpTLS.TLSSettings -> m (Async.Async (), Warp.Port)
startMockServer tlsSettings = liftIO $ do
(port, sock) <- bindRandomPortTCP "*6"
Expand Down