Tls check client certs [VAULT-2117] (#11860)

* add expiration warning to certificate checking for diagnose

* Adding TLS Client CA checks to diagnose
Adding checks for tls_disable_client_certs and tls_require_and_verify_client_cert flags

* Check validity of TLSClientCAFile
Adding related tests

* Addressing comments

* Fixing some tls tests

* Addressing comments

Co-authored-by: HridoyRoy <roy@hashicorp.com>
This commit is contained in:
hghaf099
2021-06-18 19:35:38 -04:00
committed by GitHub
parent 0d491c621f
commit 72c18c60fb
7 changed files with 668 additions and 127 deletions

View File

@@ -535,6 +535,11 @@ SEALFAIL:
} }
if ln.Config.TLSDisableClientCerts { if ln.Config.TLSDisableClientCerts {
diagnose.Warn(listenerTLSContext, "TLS for a listener is turned on without requiring client certs.") diagnose.Warn(listenerTLSContext, "TLS for a listener is turned on without requiring client certs.")
}
err = diagnose.TLSMutualExclusionCertCheck(ln.Config)
if err != nil {
diagnose.Warn(listenerTLSContext, fmt.Sprintf("TLSDisableClientCerts and TLSRequireAndVerifyClientCert should not both be set. %s", err))
} }
sanitizedListeners = append(sanitizedListeners, listenerutil.Listener{ sanitizedListeners = append(sanitizedListeners, listenerutil.Listener{

View File

@@ -0,0 +1,64 @@
-----BEGIN CERTIFICATE-----
MIIFkjCCA3qgAwIBAgICEAAwDQYJKoZIhvcNAQENBQAwWDELMAkGA1UEBhMCQ0Ex
CzAJBgNVBAgMAk9OMRAwDgYDVQQHDAdUb3JvbnRvMRQwEgYDVQQKDAtleGFtcGxl
LmNvbTEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjEwNjE3MTUyOTA4WhcNMzEw
NjE1MTUyOTA4WjBYMQswCQYDVQQGEwJDQTELMAkGA1UECAwCT04xFDASBgNVBAoM
C2V4YW1wbGUuY29tMQwwCgYDVQQLDANpbnQxGDAWBgNVBAMMD2ludC5leGFtcGxl
LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPcI9yYyT4jxvo7g
23mrjdAJC4tNeg2+eyujaVpxNWkwqecFiyCeN1qVNSzjY95wKk95Pd51oUsup3Ja
zQ/Prdt6eabPr3g/7eZOw87AW1g/fe2soh46+IIZA0JJxKDjJNY4JasRNvusHjYX
7hSZR+PnHcMuTx1h2arVnJX+ln6DmRRMNvPs0In+TG1z4wJbIRFq3m/uLgnEd7fv
/fvX4jphz7dk/I/I1b7NedHyl/wO52mBRQ6IdT8/hR7uT90CDxd66to2r5nnttLu
oVFjZkHrG4BJh9QO5Fp55QOy8wmAhlaDewbRUui0OpvFnxamarNd2vql4Kt645cc
R4+fpYHWTzJPM/8HqocrnI63NVaa7wSfGgCHBhNo1GYF2QL+5zAEHdKkSDPLszoc
dXAOZBDVZssgRZt5nWIAp7Kkm4gmsqPdUrO0OB+0v9+q2UjOT5/dhCDKdRsZ4K30
gU5BEJyfO31oM2QRRKlqjM4yN7/TRm5RlbFcVXobuVKWYsfkfhANa/hbWII3bB+v
G/V+HOqd0zwfhaTYNSRiUKfAcZBUxDW2XCWfxIV2bygu1Ev9POjrWteWqYTga3le
y+rnIq6mcAkjNKPIiRmM3guyl0XPqzfqHf2TMGRNf/Y6GlxkBDLcEF7cB420/FWz
zXM2DqpMKTvPnBm+I4nvO2lkZuNxAgMBAAGjZjBkMB0GA1UdDgQWBBSqAVbbvHD5
V/Cc0NjmmFyHBmX08zAfBgNVHSMEGDAWgBQDJwHpS6RzHvUmYhKXj3u++kF/sjAS
BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQ0F
AAOCAgEAl7BViBti9cGf/bEvOv1DmMDPQRy9GBwnzyBGeF8zYw79yGhOezruicg8
UzjgKL2zzNEdCQfetz+iEiuFAu/cpy2gpOkjuYa3KSNQJzmKwRlTAPNo3yHisSxM
YSvCD1csthZJVxBbM4XwiLg3zD1dOfVByasCPZ41PA2Ott5Xs0xwIYbYytypJ5WL
2bwMrt8vVkBz+SicoiUIbfNXAYP2NoW0JTg6gbVY7RbBi4suJDzjT4w75UbYMKzA
GudSvWi/8jC3AtXMu1usMVRc3Mpjo8NTnpTRcigHbRIHOO+s3UyXaDxyXXu1ML+u
8+DMq7PL+2EKWGIy8edj2VG2niRIV3WO15w5/LeGiAIfBEMbxDq3Y4m2VsObTEjh
3R4AHnyvfLjxk1wlFUfApcl/TQ3d/KI8e4FS3cB6XVO6oJSTfrm4QcWxHgZ9xJ6i
iVX3RahohR/5QcRsCPFJ19Iik9WvwZBQ/vh1BwDgGGOIUy/chzPIbJDg/OcBMfFk
xXA5Db8ykpMhpLD0FGdzTCIzCMitv46mRLSff3+4PyqEiZ7GOrKnduiBF6tkI34i
etQ4LvFmwloKfwPgAbRXtwp0XCnk+C/adT8fT16JGviHc4Q8fglUKZLVYJiqgb+x
CQZJrtWk7AgmiaeWQkfPcPbRGJjwXaJ7OvoFhXmZyDRWwOcCunQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFjjCCA3agAwIBAgIBADANBgkqhkiG9w0BAQ0FADBYMQswCQYDVQQGEwJDQTEL
MAkGA1UECAwCT04xEDAOBgNVBAcMB1Rvcm9udG8xFDASBgNVBAoMC2V4YW1wbGUu
Y29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0yMTA2MTcxNTEyMDZaFw0zMTA2
MTUxNTEyMDZaMFgxCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJPTjEQMA4GA1UEBwwH
VG9yb250bzEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUu
Y29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqhfgT3MSg+QfWFCp
RQ/z9GdrV3AGH/NMnlzpWFo39pUul8bGTSLiSNJZnfn4ZR6nL01gBVC14lD2W4a/
az6tkAR1s0Rfn9EfZFW8dWesYs0t98ENvsW7kZnJTtZX822XquE65hYOxI7ul87L
XsbMQBoAuQk44kla2gJ0VIJosvA+LyZIHZXcA4UYL70mcqWn72D3hLkIzUpapG8f
czoGhLW51anScQnJ3MStnOsvTpk1QVsrHLACNala7Pe+OIXHrg9D4eZorX3TZRIo
EVOcHyJVx40BkTnGhjgTAFuhTvc1NqHW7IpcAQawNV583JIZ8RvTXmCQGsJEgiDO
1HP1wVc8uUyCsZ0J/qbUohdWdFpgAwM5OkOV+0QOkvhD4ZOvwK2NxBlIwOxDdhTl
BmiKoLutvTXIc1dT+bU3g5T4024ulfsG3ZISJAGWB8b0KKPFl8oT3DGruMAA7dLn
pa9a35FF4zyERm5PTYVNRg59+bbpYOeZbUS3SoJdenjcL/pV8z9bmeSsWTZf4GtD
5sfvlnamUcqVveBSGNJQ/4TkTrWqpyEbQTpiAndqetJEDb8Ta7K2IaFzWwvYYFkB
o2G1jvr7qB19yChedu3DREtsDz4jaBEVSw+oyLHdN37iaDksP7cgmnjsmTnO5SdR
zjHt24CuwdpdPPf3m3XxZfWgb9MCAwEAAaNjMGEwHQYDVR0OBBYEFAMnAelLpHMe
9SZiEpePe776QX+yMB8GA1UdIwQYMBaAFAMnAelLpHMe9SZiEpePe776QX+yMA8G
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBDQUAA4IC
AQAkyoX6Wzl7xWPa6rqSj3gxTDs8rKMCw6mmjLIRsKU+vRQ/a8uDYunJXQrDQ21e
AKJfCPRt+d/gTllJ/OOuDW55zRvJX486aIQzQnU4TGgj58HUYaA9z8pQEpCN36Dp
X0UWarGKDGBJ/fb3GJf71TXQgCLgd9IWgtN0Y59MMOQyiUYjulBcSD9eTTsSezcQ
OYTSybma8mZxERMmuEMWZUJl91PLBogAwelwoFoOoCDFyZXcnXD5yDL4uhzMG+px
0A2zWM8dYYq+Hn1zfzu5cyxeiyGSLYtaKxQCxZJ9FunSLwgLfYRH9YZx92ZcVuMG
FylUhQVEkH3d+Pjgys8q/avWGkj0LBzK8/KkZGzO/SMlIJRHtqQgzKi4hbc57vRQ
F32H8/zGTfwDwdjZSy4UvvATNLGbYa/nXYgGzqzQiQd5SIIBMzyG89ZeEsYb3EKD
rZPqDfhSzXs0gZj+JDgFCkro7203k1mRjXa/txfmjjGKEggPk80J2joeHHbsQOj2
vLl/GE8XiLpT0rZQY1VvlrM0NdG/Ncfs9K3BZWh4yisspJgq6blURRhGV8rWHUMH
bnXMYXDb9bhmsbho0e+KYdN8EzdzZP0kX0Ro5uj6JlR+DtTX0MGQwawwdtrAbjGV
EDFilaw7tcZUQFXRmn5YTs8k7kowY8v5acOaeTJBoOSqBg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFkjCCA3qgAwIBAgICEAAwDQYJKoZIhvcNAQENBQAwWDELMAkGA1UEBhMCQ0Ex
CzAJBgNVBAgMAk9OMRAwDgYDVQQHDAdUb3JvbnRvMRQwEgYDVQQKDAtleGFtcGxl
LmNvbTEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjEwNjE3MTUyOTA4WhcNMzEw
NjE1MTUyOTA4WjBYMQswCQYDVQQGEwJDQTELMAkGA1UECAwCT04xFDASBgNVBAoM
C2V4YW1wbGUuY29tMQwwCgYDVQQLDANpbnQxGDAWBgNVBAMMD2ludC5leGFtcGxl
LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPcI9yYyT4jxvo7g
23mrjdAJC4tNeg2+eyujaVpxNWkwqecFiyCeN1qVNSzjY95wKk95Pd51oUsup3Ja
zQ/Prdt6eabPr3g/7eZOw87AW1g/fe2soh46+IIZA0JJxKDjJNY4JasRNvusHjYX
7hSZR+PnHcMuTx1h2arVnJX+ln6DmRRMNvPs0In+TG1z4wJbIRFq3m/uLgnEd7fv
/fvX4jphz7dk/I/I1b7NedHyl/wO52mBRQ6IdT8/hR7uT90CDxd66to2r5nnttLu
oVFjZkHrG4BJh9QO5Fp55QOy8wmAhlaDewbRUui0OpvFnxamarNd2vql4Kt645cc
R4+fpYHWTzJPM/8HqocrnI63NVaa7wSfGgCHBhNo1GYF2QL+5zAEHdKkSDPLszoc
dXAOZBDVZssgRZt5nWIAp7Kkm4gmsqPdUrO0OB+0v9+q2UjOT5/dhCDKdRsZ4K30
gU5BEJyfO31oM2QRRKlqjM4yN7/TRm5RlbFcVXobuVKWYsfkfhANa/hbWII3bB+v
G/V+HOqd0zwfhaTYNSRiUKfAcZBUxDW2XCWfxIV2bygu1Ev9POjrWteWqYTga3le
y+rnIq6mcAkjNKPIiRmM3guyl0XPqzfqHf2TMGRNf/Y6GlxkBDLcEF7cB420/FWz
zXM2DqpMKTvPnBm+I4nvO2lkZuNxAgMBAAGjZjBkMB0GA1UdDgQWBBSqAVbbvHD5
V/Cc0NjmmFyHBmX08zAfBgNVHSMEGDAWgBQDJwHpS6RzHvUmYhKXj3u++kF/sjAS
BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQ0F
AAOCAgEAl7BViBti9cGf/bEvOv1DmMDPQRy9GBwnzyBGeF8zYw79yGhOezruicg8
UzjgKL2zzNEdCQfetz+iEiuFAu/cpy2gpOkjuYa3KSNQJzmKwRlTAPNo3yHisSxM
YSvCD1csthZJVxBbM4XwiLg3zD1dOfVByasCPZ41PA2Ott5Xs0xwIYbYytypJ5WL
2bwMrt8vVkBz+SicoiUIbfNXAYP2NoW0JTg6gbVY7RbBi4suJDzjT4w75UbYMKzA
GudSvWi/8jC3AtXMu1usMVRc3Mpjo8NTnpTRcigHbRIHOO+s3UyXaDxyXXu1ML+u
8+DMq7PL+2EKWGIy8edj2VG2niRIV3WO15w5/LeGiAIfBEMbxDq3Y4m2VsObTEjh
3R4AHnyvfLjxk1wlFUfApcl/TQ3d/KI8e4FS3cB6XVO6oJSTfrm4QcWxHgZ9xJ6i
iVX3RahohR/5QcRsCPFJ19Iik9WvwZBQ/vh1BwDgGGOIUy/chzPIbJDg/OcBMfFk
xXA5Db8ykpMhpLD0FGdzTCIzCMitv46mRLSff3+4PyqEiZ7GOrKnduiBF6tkI34i
etQ4LvFmwloKfwPgAbRXtwp0XCnk+C/adT8fT16JGviHc4Q8fglUKZLVYJiqgb+x
CQZJrtWk7AgmiaeWQkfPcPbRGJjwXaJ7OvoFhXmZyDRWwOcCunQ=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEujCCAqICCQC/sjLTDP0XszANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRn
aXRodWIuaGFzaGljb3JwLmNvbTAeFw0yMTA2MTYyMDUwNDRaFw0yMjA2MTYyMDUw
NDRaMB8xHTAbBgNVBAMMFGdpdGh1Yi5oYXNoaWNvcnAuY29tMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEA7a2YsR6fPZPYGpUDQVsSFJSaX7ZqOecQiuTa
gIbbiPNVWgznMwPtHVdmZjjZQspMM49ox6wXiT2WqBGIgraFB+VW00I8XMwM64ge
Pcr7NK8INgwphvlI9cbrHQYce6wWexLO/S7EJ0UFSns6LGRn8FctXIalu1HgkeT3
jLpo3Fnr2UnwQAxljb8vW+5otpBDCRRXfgSq5dvZrPh+hxrfBNFZsd0gJGSJEzd1
9485+e5cvSKs7kyaeQBlxEEBP/ai7zroPhzEyBTm7/2qnr8sWmpFUHIgC0zO8qf3
TnJ6HDCGGwKXLEjHB+vrRBB4iAgDmUsYlW6G8A+U2hAAjTi3k2JHna5QBL7CEeza
U4GzyS2Kf3MQLLMyqntRIlotXzKBaoIQl8PSZZddyxWnd3qrwawYC4lDEFo1KnE5
m+jUojXx84ioKwqj2vZ7+LT6kCErrT/Di47ii89Y7KibF26ZA3IcpUtYNeypHmt1
A4eCxLIddf6rKtBwVb8cH/dvde/CErSQKsmA9LVvvm5V91y+oAyf6czpknU70F3h
YuCjFN347ipYSUYvDqvuIMnFo/gAqkonqDdYc7W7l1GMfvxr9c9oymqMml5W0FNM
77wnL6kUNJhlgaddVFHVWiUjeuX+G4uv2EemdzPmwB8BtC1X6ePEKUlWXVVg+OLf
hFdvor0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAjtrZzh9qx5RJ2vBLKugaLK80
aFIxIOqIZ/oJOMeTvqK1NLUCrRHP7mjhvkB0sYs0OS1ypOjhDOM9ccfkh2q9hwzz
m/gCqeUUOL+tpvA3VQyxxX5OnFCLdXVMPGd74BBWrYyFoZj28yNqEOAIUU5seJL5
A7bY/1rUG8YH1p82lPr8DOLg5OfPCIoaoOZE7i7/rL5j97RkFukYQX1pJiiPLfJi
s0cUOySSnnkqvo0u3UZIOexOlCLxfO32/UA1VW6/LBVitTVgzOSiORbkkXv+vxOZ
C/qr2XpEENj9vjP/1phPhyYDpVnrzXWPgJ30gl81IU+qTafONUzGftF7ELX0rNvK
5bFnEFJY7GeBdLLdUOxKlZ9L9Qd1d2Q+iQV25kwzf714dh/t4Oz4K0ZJ5mxpujcA
bbrEKMvqq7vIAfigHpI8W79BDEC7AP+QPSD1G3QzcxJRG2ctyfODXqTvw5zL/Fy7
ZYLVWhJuNnHE1pHNmUDRiT8sYl1xGdrUofvSQrnhju9g3FYX/OARRDzFYRq4Dwq/
ktZEcBcC6QN3fhVaefpsA+QdpMOdDwA+5NA7r7W3qqgAa9qoBdGtzKAzA9J1I67b
dGgdRrEjr6eP7enrOR+iymTWxun53H2Y4dseqrn18LmyrVV82dgLWH9xkWch5W0/
kQXne4cSrE727hmkw4k=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,52 @@
-----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUb5id+GcaMeMnYBv3MvdTGWigyJ0wDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzI5WhcNMjYw
MjI2MDIyNzU5WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAOxTMvhTuIRc2YhxZpmPwegP86cgnqfT1mXxi1A7
Q7qax24Nqbf00I3oDMQtAJlj2RB3hvRSCb0/lkF7i1Bub+TGxuM7NtZqp2F8FgG0
z2md+W6adwW26rlxbQKjmRvMn66G9YPTkoJmPmxt2Tccb9+apmwW7lslL5j8H48x
AHJTMb+PMP9kbOHV5Abr3PT4jXUPUr/mWBvBiKiHG0Xd/HEmlyOEPeAThxK+I5tb
6m+eB+7cL9BsvQpy135+2bRAxUphvFi5NhryJ2vlAvoJ8UqigsNK3E28ut60FAoH
SWRfFUFFYtfPgTDS1yOKU/z/XMU2giQv2HrleWt0mp4jqBUCAwEAAaOBgTB/MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdxLNP/ocx
7HK6JT3/sSAe76iTmzAfBgNVHSMEGDAWgBSdxLNP/ocx7HK6JT3/sSAe76iTmzAc
BgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEA
wHThDRsXJunKbAapxmQ6bDxSvTvkLA6m97TXlsFgL+Q3Jrg9HoJCNowJ0pUTwhP2
U946dCnSCkZck0fqkwVi4vJ5EQnkvyEbfN4W5qVsQKOFaFVzep6Qid4rZT6owWPa
cNNzNcXAee3/j6hgr6OQ/i3J6fYR4YouYxYkjojYyg+CMdn6q8BoV0BTsHdnw1/N
ScbnBHQIvIZMBDAmQueQZolgJcdOuBLYHe/kRy167z8nGg+PUFKIYOL8NaOU1+CJ
t2YaEibVq5MRqCbRgnd9a2vG0jr5a3Mn4CUUYv+5qIjP3hUusYenW1/EWtn1s/gk
zehNe5dFTjFpylg1o6b8Ow==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFjjCCA3agAwIBAgIBADANBgkqhkiG9w0BAQ0FADBYMQswCQYDVQQGEwJDQTEL
MAkGA1UECAwCT04xEDAOBgNVBAcMB1Rvcm9udG8xFDASBgNVBAoMC2V4YW1wbGUu
Y29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0yMTA2MTcxNTEyMDZaFw0zMTA2
MTUxNTEyMDZaMFgxCzAJBgNVBAYTAkNBMQswCQYDVQQIDAJPTjEQMA4GA1UEBwwH
VG9yb250bzEUMBIGA1UECgwLZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUu
Y29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqhfgT3MSg+QfWFCp
RQ/z9GdrV3AGH/NMnlzpWFo39pUul8bGTSLiSNJZnfn4ZR6nL01gBVC14lD2W4a/
az6tkAR1s0Rfn9EfZFW8dWesYs0t98ENvsW7kZnJTtZX822XquE65hYOxI7ul87L
XsbMQBoAuQk44kla2gJ0VIJosvA+LyZIHZXcA4UYL70mcqWn72D3hLkIzUpapG8f
czoGhLW51anScQnJ3MStnOsvTpk1QVsrHLACNala7Pe+OIXHrg9D4eZorX3TZRIo
EVOcHyJVx40BkTnGhjgTAFuhTvc1NqHW7IpcAQawNV583JIZ8RvTXmCQGsJEgiDO
1HP1wVc8uUyCsZ0J/qbUohdWdFpgAwM5OkOV+0QOkvhD4ZOvwK2NxBlIwOxDdhTl
BmiKoLutvTXIc1dT+bU3g5T4024ulfsG3ZISJAGWB8b0KKPFl8oT3DGruMAA7dLn
pa9a35FF4zyERm5PTYVNRg59+bbpYOeZbUS3SoJdenjcL/pV8z9bmeSsWTZf4GtD
5sfvlnamUcqVveBSGNJQ/4TkTrWqpyEbQTpiAndqetJEDb8Ta7K2IaFzWwvYYFkB
o2G1jvr7qB19yChedu3DREtsDz4jaBEVSw+oyLHdN37iaDksP7cgmnjsmTnO5SdR
zjHt24CuwdpdPPf3m3XxZfWgb9MCAwEAAaNjMGEwHQYDVR0OBBYEFAMnAelLpHMe
9SZiEpePe776QX+yMB8GA1UdIwQYMBaAFAMnAelLpHMe9SZiEpePe776QX+yMA8G
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBDQUAA4IC
AQAkyoX6Wzl7xWPa6rqSj3gxTDs8rKMCw6mmjLIRsKU+vRQ/a8uDYunJXQrDQ21e
AKJfCPRt+d/gTllJ/OOuDW55zRvJX486aIQzQnU4TGgj58HUYaA9z8pQEpCN36Dp
X0UWarGKDGBJ/fb3GJf71TXQgCLgd9IWgtN0Y59MMOQyiUYjulBcSD9eTTsSezcQ
OYTSybma8mZxERMmuEMWZUJl91PLBogAwelwoFoOoCDFyZXcnXD5yDL4uhzMG+px
0A2zWM8dYYq+Hn1zfzu5cyxeiyGSLYtaKxQCxZJ9FunSLwgLfYRH9YZx92ZcVuMG
FylUhQVEkH3d+Pjgys8q/avWGkj0LBzK8/KkZGzO/SMlIJRHtqQgzKi4hbc57vRQ
F32H8/zGTfwDwdjZSy4UvvATNLGbYa/nXYgGzqzQiQd5SIIBMzyG89ZeEsYb3EKD
rZPqDfhSzXs0gZj+JDgFCkro7203k1mRjXa/txfmjjGKEggPk80J2joeHHbsQOj2
vLl/GE8XiLpT0rZQY1VvlrM0NdG/Ncfs9K3BZWh4yisspJgq6blURRhGV8rWHUMH
bnXMYXDb9bhmsbho0e+KYdN8EzdzZP0kX0Ro5uj6JlR+DtTX0MGQwawwdtrAbjGV
EDFilaw7tcZUQFXRmn5YTs8k7kowY8v5acOaeTJBoOSqBg==
-----END CERTIFICATE-----

View File

@@ -8,8 +8,10 @@ import (
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"strings"
"time" "time"
"github.com/hashicorp/vault/internalshared/configutil"
"github.com/hashicorp/vault/internalshared/listenerutil" "github.com/hashicorp/vault/internalshared/listenerutil"
"github.com/hashicorp/vault/sdk/helper/tlsutil" "github.com/hashicorp/vault/sdk/helper/tlsutil"
) )
@@ -52,16 +54,11 @@ func ListenerChecks(ctx context.Context, listeners []listenerutil.Listener) ([]s
// Perform checks on the TLS Cryptographic Information. // Perform checks on the TLS Cryptographic Information.
warnings, err := TLSFileChecks(l.TLSCertFile, l.TLSKeyFile) warnings, err := TLSFileChecks(l.TLSCertFile, l.TLSKeyFile)
for _, warning := range warnings { listenerWarnings, listenerErrors = outputError(ctx, warnings, listenerWarnings, err, listenerErrors, listenerID)
warning = listenerID + ": " + warning
listenerWarnings = append(listenerWarnings, warning) // Perform checks on the Client CA Cert
Warn(ctx, warning) warnings, err = TLSClientCAFileCheck(l)
} listenerWarnings, listenerErrors = outputError(ctx, warnings, listenerWarnings, err, listenerErrors, listenerID)
if err != nil {
errMsg := listenerID + ": " + err.Error()
listenerErrors = append(listenerErrors, fmt.Errorf(errMsg))
Error(ctx, fmt.Errorf(errMsg))
}
// TODO: Use listenerutil.TLSConfig to warn on incorrect protocol specified // TODO: Use listenerutil.TLSConfig to warn on incorrect protocol specified
// Alternatively, use tlsutil.SetupTLSConfig. // Alternatively, use tlsutil.SetupTLSConfig.
@@ -69,6 +66,21 @@ func ListenerChecks(ctx context.Context, listeners []listenerutil.Listener) ([]s
return listenerWarnings, listenerErrors return listenerWarnings, listenerErrors
} }
func outputError(ctx context.Context, newWarnings, listenerWarnings []string, newErr error, listenerErrors []error, listenerID string) ([]string, []error) {
for _, warning := range newWarnings {
warning = listenerID + ": " + warning
listenerWarnings = append(listenerWarnings, warning)
Warn(ctx, warning)
}
if newErr != nil {
errMsg := listenerID + ": " + newErr.Error()
listenerErrors = append(listenerErrors, fmt.Errorf(errMsg))
Error(ctx, fmt.Errorf(errMsg))
}
return listenerWarnings, listenerErrors
}
// TLSFileChecks returns an error and warnings after checking TLS information // TLSFileChecks returns an error and warnings after checking TLS information
func TLSFileChecks(certpath, keypath string) ([]string, error) { func TLSFileChecks(certpath, keypath string) ([]string, error) {
// Parse TLS Certs from the certpath // Parse TLS Certs from the certpath
@@ -136,13 +148,18 @@ func ParseTLSInformation(certFilePath string) ([]*x509.Certificate, []*x509.Cert
leafCerts = append(leafCerts, cert) leafCerts = append(leafCerts, cert)
} }
} }
return leafCerts, interCerts, rootCerts, nil return leafCerts, interCerts, rootCerts, nil
} }
// TLSErrorChecks contains manual error checks against the TLS configuration // TLSErrorChecks contains manual error checks against the TLS configuration
func TLSErrorChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) error { func TLSErrorChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) error {
// First, create root pools and interPools from the root and inter certs lists // Make sure there's the proper number of leafCerts. If there are multiple, it's a bad pem file.
if len(leafCerts) == 0 {
return fmt.Errorf("No leaf certificates detected.")
}
// First, create root pools and interPools from the root and inter certs lists
rootPool := x509.NewCertPool() rootPool := x509.NewCertPool()
interPool := x509.NewCertPool() interPool := x509.NewCertPool()
@@ -153,29 +170,48 @@ func TLSErrorChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) error
interPool.AddCert(inter) interPool.AddCert(inter)
} }
// Make sure there's only one leaf. If there are multiple, it's a bad pem file. var err error
if len(leafCerts) != 1 { // Verify checks that certificate isn't expired, is of correct usage type, and has an appropriate
return fmt.Errorf("Number of leaf certificates detected is not one. Instead, it is: %d", len(leafCerts)) // chain. We start with Root
for _, root := range rootCerts {
_, err = root.Verify(x509.VerifyOptions{
Roots: rootPool,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
})
if err != nil {
return fmt.Errorf("failed to verify root certificate: %w", err)
}
}
// Verifying intermediate certs
for _, inter := range interCerts {
_, err = inter.Verify(x509.VerifyOptions{
Roots: rootPool,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
})
if err != nil {
return fmt.Errorf("failed to verify intermediate certificate: %w", err)
}
} }
rootSubjs := rootPool.Subjects() rootSubjs := rootPool.Subjects()
if len(rootSubjs) == 0 { if len(rootSubjs) == 0 && len(leafCerts) > 0 {
// this is a self signed server certificate, or the root is just not provided. In any // this is a self signed server certificate, or the root is just not provided. In any
// case, we need to bypass the root verification step by adding the leaf itself to the // case, we need to bypass the root verification step by adding the leaf itself to the
// root pool. // root pool.
rootPool.AddCert(leafCerts[0]) rootPool.AddCert(leafCerts[0])
} }
// Verify checks that certificate isn't expired, is of correct usage type, and has an appropriate // Verifying leaf cert
// chain. for _, leaf := range leafCerts {
_, err := leafCerts[0].Verify(x509.VerifyOptions{ _, err = leaf.Verify(x509.VerifyOptions{
Roots: rootPool, Roots: rootPool,
Intermediates: interPool, Intermediates: interPool,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
}) })
if err != nil {
if err != nil { return fmt.Errorf("failed to verify primary provided leaf certificate: %w", err)
return fmt.Errorf("failed to verify primary provided leaf certificate: %w", err) }
} }
return nil return nil
@@ -185,6 +221,12 @@ func TLSErrorChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) error
// and root certificates provided. // and root certificates provided.
func TLSFileWarningChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) ([]string, error) { func TLSFileWarningChecks(leafCerts, interCerts, rootCerts []*x509.Certificate) ([]string, error) {
var warnings []string var warnings []string
// add a warning for when there are more than one leaf certs
if len(leafCerts) > 1 {
warnings = append(warnings, "leafCerts contains more than one cert.")
}
for _, c := range leafCerts { for _, c := range leafCerts {
if willExpire, timeToExpiry := NearExpiration(c); willExpire { if willExpire, timeToExpiry := NearExpiration(c); willExpire {
warnings = append(warnings, fmt.Sprintf("leaf certificate %d is expired or near expiry. Time to expire is: %s", c.SerialNumber, timeToExpiry)) warnings = append(warnings, fmt.Sprintf("leaf certificate %d is expired or near expiry. Time to expire is: %s", c.SerialNumber, timeToExpiry))
@@ -214,3 +256,76 @@ func NearExpiration(c *x509.Certificate) (bool, time.Duration) {
} }
return false, timeToExpiry return false, timeToExpiry
} }
// TLSMutualExclusionCertCheck returns error if both TLSDisableClientCerts and TLSRequireAndVerifyClientCert are set
func TLSMutualExclusionCertCheck(l *configutil.Listener) error {
if l.TLSDisableClientCerts {
if l.TLSRequireAndVerifyClientCert {
return fmt.Errorf("the tls_disable_client_certs and tls_require_and_verify_client_cert fields in the " +
"listener stanza of the vault server config are mutually exclusive fields. Please ensure they are not both set to true.")
}
}
return nil
}
// TLSClientCAFileCheck Checks the validity of a client CA file
func TLSClientCAFileCheck(l *configutil.Listener) ([]string, error) {
if l.TLSDisableClientCerts {
return nil, nil
} else if !l.TLSRequireAndVerifyClientCert {
return nil, nil
}
var warningsSlc []string
// Parse TLS Certs from the tls config
leafCerts, interCerts, rootCerts, err := ParseTLSInformation(l.TLSClientCAFile)
if err != nil {
return nil, err
}
if len(rootCerts) == 0 {
return nil, fmt.Errorf("No root cert found!")
}
if len(rootCerts) > 1 {
warningsSlc = append(warningsSlc, fmt.Sprintf("Found Multiple rootCerts instead of just one!"))
}
// Checking for Self-Signed cert and return an explicit error about it.
// Self-Signed certs are placed in the leafCerts slice when parsed.
if len(leafCerts) > 0 && !leafCerts[0].IsCA && bytes.Equal(leafCerts[0].RawIssuer, leafCerts[0].RawSubject) {
return warningsSlc, fmt.Errorf("Found a Self-Signed certificate!")
}
if len(interCerts) > 0 {
return warningsSlc, fmt.Errorf("Found at least one intermediate cert in a root CA cert.")
}
if len(leafCerts) > 0 {
return warningsSlc, fmt.Errorf("Found at least one leafCert in a root CA cert.")
}
var warnings []string
// Check for TLS Warnings
warnings, err = TLSFileWarningChecks(leafCerts, interCerts, rootCerts)
warningsSlc = append(warningsSlc, warnings...)
for i, warning := range warningsSlc {
warningsSlc[i] = strings.Replace(warning, "leaf", "root", -1)
}
if err != nil {
return warningsSlc, err
}
// Adding rootCerts to leafCert to perform verification in TLSErrorChecks
leafCerts = append(leafCerts, rootCerts[0])
// Check for TLS Errors
if err = TLSErrorChecks(leafCerts, interCerts, rootCerts); err != nil {
return warningsSlc, fmt.Errorf(strings.Replace(err.Error(), "leaf", "root", -1))
}
return warningsSlc, err
}

View File

@@ -16,14 +16,13 @@ func TestTLSValidCert(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/goodcertwithroot.pem", TLSCertFile: "./test-fixtures/goodcertwithroot.pem",
TLSKeyFile: "./test-fixtures/goodkey.pem", TLSKeyFile: "./test-fixtures/goodkey.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -42,14 +41,13 @@ func TestTLSFakeCert(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/fakecert.pem", TLSCertFile: "./test-fixtures/fakecert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -73,14 +71,13 @@ func TestTLSTrailingData(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/trailingdatacert.pem", TLSCertFile: "./test-fixtures/trailingdatacert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -99,14 +96,13 @@ func TestTLSExpiredCert(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/expiredcert.pem", TLSCertFile: "./test-fixtures/expiredcert.pem",
TLSKeyFile: "./test-fixtures/expiredprivatekey.pem", TLSKeyFile: "./test-fixtures/expiredprivatekey.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -121,7 +117,7 @@ func TestTLSExpiredCert(t *testing.T) {
t.Fatalf("TLS Config check on fake certificate should warn") t.Fatalf("TLS Config check on fake certificate should warn")
} }
if !strings.Contains(warnings[0], "expired or near expiry") { if !strings.Contains(warnings[0], "expired or near expiry") {
t.Fatalf("Bad warning: %s", errs[0]) t.Fatalf("Bad warning: %s", warnings[0])
} }
} }
@@ -131,14 +127,13 @@ func TestTLSMismatchedCryptographicInfo(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./test-fixtures/ecdsa.key", TLSKeyFile: "./test-fixtures/ecdsa.key",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -153,15 +148,14 @@ func TestTLSMismatchedCryptographicInfo(t *testing.T) {
listeners = []listenerutil.Listener{ listeners = []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/ecdsa.crt", TLSCertFile: "./test-fixtures/ecdsa.crt",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem", TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -179,15 +173,14 @@ func TestTLSMultiKeys(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/key.pem", TLSCertFile: "./../../api/test-fixtures/keys/key.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem", TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -201,18 +194,17 @@ func TestTLSMultiKeys(t *testing.T) {
} }
// TestTLSMultiCerts verifies that a unique error message is thrown when a cert is specified twice. // TestTLSMultiCerts verifies that a unique error message is thrown when a cert is specified twice.
func TestTLSMultiCerts(t *testing.T) { func TestTLSCertAsKey(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/cert.pem", TLSKeyFile: "./../../api/test-fixtures/keys/cert.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -232,14 +224,13 @@ func TestTLSInvalidRoot(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/goodcertbadroot.pem", TLSCertFile: "./test-fixtures/goodcertbadroot.pem",
TLSKeyFile: "./test-fixtures/goodkey.pem", TLSKeyFile: "./test-fixtures/goodkey.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -259,14 +250,13 @@ func TestTLSNoRoot(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./test-fixtures/goodkey.pem", TLSKeyFile: "./test-fixtures/goodkey.pem",
TLSMinVersion: "tls10", TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -282,15 +272,14 @@ func TestTLSInvalidMinVersion(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem", TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "0", TLSMinVersion: "0",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -309,15 +298,14 @@ func TestTLSInvalidMaxVersion(t *testing.T) {
listeners := []listenerutil.Listener{ listeners := []listenerutil.Listener{
{ {
Config: &configutil.Listener{ Config: &configutil.Listener{
Type: "tcp", Type: "tcp",
Address: "127.0.0.1:443", Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201", ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem", TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem", TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem", TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "0", TLSMaxVersion: "0",
TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true,
TLSDisableClientCerts: false,
}, },
}, },
} }
@@ -329,3 +317,260 @@ func TestTLSInvalidMaxVersion(t *testing.T) {
t.Fatalf("Bad error message: %s", errs[0]) t.Fatalf("Bad error message: %s", errs[0])
} }
} }
// TestDisabledClientCertsAndDisabledTLSClientCAVerfiy checks that a listener works properly when both
// TLSRequireAndVerifyClientCert and TLSDisableClientCerts are false
func TestDisabledClientCertsAndDisabledTLSClientCAVerfiy(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: false,
TLSDisableClientCerts: false,
},
},
}
err := TLSMutualExclusionCertCheck(listeners[0].Config)
if err != nil {
t.Fatalf("TLS config failed when both TLSRequireAndVerifyClientCert and TLSDisableClientCerts are false")
}
}
// TestTLSClientCAVerfiy checks that a listener which has TLS client certs checks enabled works as expected
func TestTLSClientCAVerfiy(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
err := TLSMutualExclusionCertCheck(listeners[0].Config)
if err != nil {
t.Fatalf("TLS config check failed with %s", err)
}
}
// TestTLSClientCAVerfiySkip checks that TLS client cert checks are skipped if TLSDisableClientCerts is true
// regardless of the value for TLSRequireAndVerifyClientCert
func TestTLSClientCAVerfiySkip(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: false,
TLSDisableClientCerts: true,
},
},
}
err := TLSMutualExclusionCertCheck(listeners[0].Config)
if err != nil {
t.Fatalf("TLS config check did not skip verification and failed with %s", err)
}
}
// TestTLSClientCAVerfiyMutualExclusion checks that TLS client cert checks are skipped if TLSDisableClientCerts is true
// regardless of the value for TLSRequireAndVerifyClientCert
func TestTLSClientCAVerfiyMutualExclusion(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: true,
},
},
}
err := TLSMutualExclusionCertCheck(listeners[0].Config)
if err == nil {
t.Fatalf("TLS config check should have failed when both 'tls_disable_client_certs' and 'tls_require_and_verify_client_cert' are true")
}
if !strings.Contains(err.Error(), "the tls_disable_client_certs and tls_require_and_verify_client_cert fields in the "+
"listener stanza of the vault server config are mutually exclusive fields") {
t.Fatalf("Bad error message: %s", err)
}
}
// TestTLSClientCAVerfiy checks that a listener which has TLS client certs checks enabled works as expected
func TestTLSClientCAFileCheck(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
warnings, errs := ListenerChecks(context.Background(), listeners)
if errs != nil {
t.Fatalf("TLS config check failed while a good ClientCAFile was used")
}
if warnings != nil {
t.Fatalf("TLS config check return warning while a good ClientCAFile was used")
}
}
// TestTLSLeafCertInClientCAFile checks if a leafCert exist in TLSClientCAFile
func TestTLSLeafCertInClientCAFile(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./test-fixtures/goodcertbadroot.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
_, errs := ListenerChecks(context.Background(), listeners)
if errs == nil || len(errs) != 1 {
t.Fatalf("TLS Config check on bad ClientCAFile certificate should fail")
}
if !strings.Contains(errs[0].Error(), "Found at least one leafCert in a root CA cert.") {
t.Fatalf("Bad error message: %s", errs[0])
}
}
// TestTLSNoRootInClientCAFile checks if no Root cert exist in TLSClientCAFile
func TestTLSNoRootInClientCAFile(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./test-fixtures/intermediateCert.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
_, errs := ListenerChecks(context.Background(), listeners)
if errs == nil {
t.Fatalf("TLS Config check on bad ClientCAFile certificate should fail")
}
if !strings.Contains(errs[0].Error(), "No root cert found!") {
t.Fatalf("Bad error message: %s", errs[0])
}
}
// TestTLSIntermediateCertInClientCAFile checks if an intermediate cert is included in TLSClientCAFile
func TestTLSIntermediateCertInClientCAFile(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./test-fixtures/chain.crt.pem",
TLSMaxVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
_, errs := ListenerChecks(context.Background(), listeners)
if errs == nil || len(errs) != 1 {
t.Fatalf("TLS Config check on bad ClientCAFile certificate should fail")
}
if !strings.Contains(errs[0].Error(), "Found at least one intermediate cert in a root CA cert.") {
t.Fatalf("Bad error message: %s", errs[0])
}
}
// TestTLSMultipleRootInClietCACert checks if multiple roots included in TLSClientCAFile
func TestTLSMultipleRootInClietCACert(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./test-fixtures/twoRootCA.pem",
TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
warnings, errs := ListenerChecks(context.Background(), listeners)
if errs != nil {
t.Fatalf("TLS Config check on valid certificate should not fail")
}
if warnings == nil {
t.Fatalf("TLS Config check on valid but bad certificate should warn")
}
if !strings.Contains(warnings[0], "Found Multiple rootCerts instead of just one!") {
t.Fatalf("Bad warning: %s", warnings[0])
}
}
func TestTLSSelfSignedCert(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "test-fixtures/selfSignedCert.pem",
TLSMinVersion: "tls10",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
_, errs := ListenerChecks(context.Background(), listeners)
if errs == nil {
t.Fatalf("Self-signed certificate is insecure")
}
if !strings.Contains(errs[0].Error(), "No root cert found!") {
t.Fatalf("Bad error message: %s", errs[0])
}
}