From fee08cc580e5147d11f3f12a37452f8a86cee3b8 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Fri, 25 Mar 2022 16:52:07 +0100 Subject: [PATCH 1/4] webhooks: gencerts.sh: add intermediate and server certs with sha-1 signatures --- .../apiserver/pkg/util/webhook/gencerts.sh | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/gencerts.sh b/staging/src/k8s.io/apiserver/pkg/util/webhook/gencerts.sh index f99895e298a..a6426a95919 100755 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/gencerts.sh +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/gencerts.sh @@ -23,6 +23,14 @@ set -e CN_BASE="webhook_tests" +cat > intermediate_ca.conf << EOF +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = critical,CA:true +keyUsage = cRLSign, keyCertSign +EOF + cat > server.conf << EOF [req] req_extensions = v3_req @@ -71,6 +79,15 @@ openssl req -x509 -new -nodes -key caKey.pem -days 100000 -out caCert.pem -subj openssl genrsa -out badCAKey.pem 2048 openssl req -x509 -new -nodes -key badCAKey.pem -days 100000 -out badCACert.pem -subj "/CN=${CN_BASE}_ca" +# Create an intermediate certificate authority +openssl genrsa -out caKeyInter.pem 2048 +openssl req -new -nodes -key caKeyInter.pem -days 100000 -out caCertInter.csr -subj "/CN=${CN_BASE}_intermediate_ca" +openssl x509 -req -in caCertInter.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out caCertInter.pem -days 100000 -extensions v3_ca -extfile intermediate_ca.conf + +# Create an intermediate certificate authority with sha1 signature +openssl req -new -nodes -key caKeyInter.pem -days 100000 -out caCertInterSHA1.csr -subj "/CN=${CN_BASE}_intermediate_ca" +openssl x509 -sha1 -req -in caCertInterSHA1.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out caCertInterSHA1.pem -days 100000 -extensions v3_ca -extfile intermediate_ca.conf + # Create a server certiticate openssl genrsa -out serverKey.pem 2048 openssl req -new -key serverKey.pem -out server.csr -subj "/CN=${CN_BASE}_server" -config server.conf @@ -80,6 +97,14 @@ openssl x509 -req -in server.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial openssl req -new -key serverKey.pem -out serverNoSAN.csr -subj "/CN=localhost" -config server_no_san.conf openssl x509 -req -in serverNoSAN.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCertNoSAN.pem -days 100000 -extensions v3_req -extfile server_no_san.conf +# Create a server certiticate with SHA1 signature signed by OK intermediate CA +openssl req -new -key serverKey.pem -out serverSHA1.csr -subj "/CN=localhost" -config server.conf +openssl x509 -sha1 -req -in serverSHA1.csr -CA caCertInter.pem -CAkey caKeyInter.pem -CAcreateserial -out sha1ServerCertInter.pem -days 100000 -extensions v3_req -extfile server.conf + +# Create a server certiticate signed by SHA1-signed intermediate CA +openssl req -new -key serverKey.pem -out serverInterSHA1.csr -subj "/CN=localhost" -config server.conf +openssl x509 -req -in serverInterSHA1.csr -CA caCertInterSHA1.pem -CAkey caKeyInter.pem -CAcreateserial -out serverCertInterSHA1.pem -days 100000 -extensions v3_req -extfile server.conf + # Create a client certiticate openssl genrsa -out clientKey.pem 2048 openssl req -new -key clientKey.pem -out client.csr -subj "/CN=${CN_BASE}_client" -config client.conf @@ -110,7 +135,7 @@ limitations under the License. package webhook EOF -for file in caKey caCert badCAKey badCACert serverKey serverCert serverCertNoSAN clientKey clientCert; do +for file in caKey caCert badCAKey badCACert caCertInter caCertInterSHA1 serverKey serverCert serverCertNoSAN clientKey clientCert sha1ServerCertInter serverCertInterSHA1; do data=$(cat ${file}.pem) echo "" >> $outfile echo "var $file = []byte(\`$data\`)" >> $outfile From b2c6de170b0b880ccca0ae783bae09559f8dff04 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Fri, 25 Mar 2022 16:52:40 +0100 Subject: [PATCH 2/4] webhooks: regenerate certificates for additional sha-1 signatures --- .../apiserver/pkg/util/webhook/certs_test.go | 422 +++++++++++------- 1 file changed, 266 insertions(+), 156 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go index 8b6d0ad8724..0caf02512cc 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go @@ -20,184 +20,294 @@ limitations under the License. package webhook var caKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY-----`) var caCert = []byte(`-----BEGIN CERTIFICATE----- -MIIDGTCCAgGgAwIBAgIUOS2MkobR2t4rguefcC78gLuXkc0wDQYJKoZIhvcNAQEL -BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa -GA8yMjk0MDcyMzEyMzE0MVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy8o1sRSe8viuSxh8a7Ou8n -vyDJxeJA9son+clZdSwa1YpbhSsYPr2svTGLT4ZxX3JkvHZGDaB+G6QrZNIWOssJ -4+fjvEsVSnk9q7Yr8wX8QdShksnSP0qdB1xFKlqwTFcZyQHqjlyctV93/LEosM9D -RZzgPpXJuC6wD7qdLRSPxQwuegZYcMGT2Y4/8CfBgiEUkZNrGYJiDFrblI0N9jX2 -jUeP/g8xWJIKLTBedVbAzj02Y66WdNecYcyTMROdclPB1IbF4ABbCGynnP0fbiaf -0+4v0pLedqwCYSWD/ujajyDtYuhI8U+OkENwkZ/h5jw/6aWq7esMZDbEAT6UPgEC -AwEAAaNTMFEwHQYDVR0OBBYEFBgvyZWkRJCRjxclYA0mMlnzc/GmMB8GA1UdIwQY -MBaAFBgvyZWkRJCRjxclYA0mMlnzc/GmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBAHigaFJ8DqYFMGXNUT5lYM8oLLWYcbivGxR7ofDm8rXWGLdQ -tKsWeusSlgpzeO1PKCzwSrYQhlFIZI6AH+ch7EAWt84MfAaMz/1DiXF6Q8fAcR0h -QoyFIAKTiVkcgOQjSQOIM2SS5cyGeDRaHGVWfaJOwdIYo6ctFzI2asPJ4yU0QsA7 -0WTD2+sBG6AXGhfafGUHEmou8sGQ+QT8rgi4hs1bfyHuT5dPgC4TbwknD1G8pMqm -ID3CIiCF8hhF5C2hjrW0LTJ6zTlg1c1K0NmmUL1ucsfzEk//c7GsU8dk+FYmtW9A -VzryJj1NmnSqA3zd3jBMuK37Ei3pRvVbO7Uxf14= +MIIDGTCCAgGgAwIBAgIUealQGELTHLUVcpsNNwz8XexiWvswDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeW0Jkq6ViZkyhaLCUgbqsN +7+6HLwfZK/ljy/KnZ7W7QlJ65Q2tkptL0fY4DPumT7JgVTGnXyTXJ35Ss5A4yhm9 +yyMH8pNVR19udK1fU74YVmbXJkc0nP7n+AXX9lD2Yy9pDvtaq1E+erN2nR1XaCS9 +n0ph4C/fB1Rh7mIv/u7WW7/aRz/rJjBBZIbg7hgZPwFsukEifGi0U4uitVYR6MWp +jHj++e1G38+4JrZR9vhBoHtBJ1DBpmjAQaAtkSZAxXJnma4awE0Bv0Q4lxkUeY+D +th8OxPXxgTbwTKDaguHlWLTapppygA8FnKqmcUkwHZO5OVldi/ZKOUm2YCuJlfEC +AwEAAaNTMFEwHQYDVR0OBBYEFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMB8GA1UdIwQY +MBaAFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJaRryxp0iYWGfLiZ0uIdOiYRVZUtmpqUSqT9/y29ffDAnCS +5labJS8FjaiQdlyaH+E9gzo0+nkO9NyfemJRLTEsU4Mz9AAvxs/NuWucqiyF0Y6d +JSYt7+2liGK5WvJMbHfW3jloWlv3oX+qL4iGFkJN+L9G+vf0GnKZCxgNIOqM4otv +cviCA9ouPwnSfnCeTsBoaUJqhLMizvUx7avvUyZTuV+t9+aN/qH4V//hTBqz9CNq +koodzngbUuyaGFI8QISUAhU+pbt6npb69LlhJHC0icDXCc4uTsd+SDsBOorZDuUL +HsNKnE0CSPZ65ENVNfJjB1fVEYbbpjr8kizOCDE= -----END CERTIFICATE-----`) +var badCAKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzOC/5s1eAjTsIGOodGJ7/ZHcS2m7t5UL38u4Gh74qlS6ezev +YjHRsqDVUiMMt2J1wWYCrH+pKLRJZ0S0B89apagsjoZViYFRnNwkcDEywkksilUI +hmxC36TgPPQQIbAH9DnTUSz2ESJMdlJec83xdI7R/2basg1PfJYJr5TIyXGiUgkC +RiVqNT8FTzEg5xIoAJoTaI0q/euz7qog7t2k/6O1RYj9W2N23k9Jjv5ZSXnKHhap +MyQwp8CidLK8LHPIxvUch7dMA3R1O6U3890B73HuosnHTzCO7a/l4GHDBCfRk70U +880T/jjSfBqdSYm1AGHjqG2AiY+bPePZVC9EtwIDAQABAoIBACapNq1IDbhe4jwO +ckhcGUe1UZvNfQXck1wM5lXPiF8kE/iSfn8KJacOoJKaWJj2dIAlTtXcVUCAHOXm +2g4rO9DM1nOit9t10r/F7v5Y2lo9UrFb8HrlTQ1E4Ke/6pdgz29vxgeoc1qyXTlq +u7Ygo7K6DLikYRp+VoSND5DZg7Y3a3/W7xecdrV1gH3XOn1fyw4IZ3u1GaufA6Jx +iJqA2RRIhHWbL9nXeRQJyACf2kYnQK8nyRhtHGiqWdLdE/T7StyqtELA41zwBip4 +vUK8l71FUD121AC7MXBGJGxmPHSat7CMmn0rtm7gksKCHjdJA3f631CVEj1OmMqT +zgULsckCgYEA+qfZpJZAg+g/dtGb26oNAxiY+Q2DGF3qZQQGk8sK8ZiIEIDL4Zul ++F9N3IK0RFqojjL2p8ktvOnspPTqoSqBjRDr2YzDsCbXR0P1Q9N/9mAvJDSrtywF +V6Ru4XkcGLOOCU5/8eXrd6e/40I0Q25amAcVAW42cL5xAkc59O5dWmMCgYEA0T8I +FAuFy8kM7hPE6mSnvFpXzj0NpWVDqwCjxy7DnnOOo4ttUfZciSq3kQ7b9WK1BeHi +C2MWALGz5Qw21bj+TgLNO39+Ah/nCTGRMtaciy3yq5IX0pV+A3Frz5X6m/PBqmT8 +p6TdYBZ84AKCKuEEShm7BgzVB2w2VrLLvtRysp0CgYEA8oBj631GS5ftlpnybVIX +JrCshv/Qnkl2VWbQqjodi2Hj+ftxxQLeTu59mOKHXz5KptCdm/TiIEw9G9asDWLf +VchSNfae+JSLYLJZ3tYHjii+Uwv2OdAIFyPJ9rBCQ4+r0ks1M6Ya6nfMCSVrBPYG +BeGMLAch+m/1S5v3cYUPojsCgYArTPnk/AVyCGbulZS4VKAJcECfYy8BvRTlvDoo +K9s7XPp1iZLT1UGM+RQHpqWKACUp1HasmJKjDiMGESL/00p85kOGPnnbArMSyfkc +JiE7BAUl0BOx9lGfcMc4q/aycxzun/tQzeMp0T2CNcKuEOaMVwrG07z5zkDobBOR +p/EcWQKBgCV2nO7Z/oyqaD00VBBm118/ZqbZG0Znxm/oxI4bG+OGRWtJc0nCVYDT +bZP4QR5baZ7KOtKAP+ksyZpyKftAgNH+TrbTTg1gJcv3gfeTivbmXyoMjwbFlu8H +iQRXj801qb2ME3+HlT0Ti8Qf3BEPrDnGf8qVSkQPjHkIbKr/3/Zv +-----END RSA PRIVATE KEY-----`) + var badCACert = []byte(`-----BEGIN CERTIFICATE----- -MIIDGTCCAgGgAwIBAgIUINBaI0NGgSo4UqKHuPd/HSBO38EwDQYJKoZIhvcNAQEL -BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa -GA8yMjk0MDcyMzEyMzE0MVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJhgUJ5gSvPA3R3s0V3ndKV -9L7W8TD+lhMGsVtXese4zmn59h238bsQvwdXaXsKSrMAZUE4uP9C6o1Itv2CSMlS -WVxnRUWkec6mFSuC2DR0gb2PMvcMrqVDihoj+n8fWzAFzs2n3StC0ewvD+avfs8U -XI1PBubCvZp3fqDSyjGSdYGjFNyjGIt4J8YuXmzccT9CwGj6mPsn6Y0ptjmZEv63 -DFjF7KuNhET723JX9K2OaPrmrl12jYpZIyYVFKBJNGzpan5bIdqJfllcIUt1yDvT -DkcLKT+fHa5+e+CXMITBZTO2lJE+P4VaKp0mjpknS0dzqdzpkEqvp/ifXGyYlX0C -AwEAAaNTMFEwHQYDVR0OBBYEFLD1yOtonJPAufGLqZ3QSRZDAeoiMB8GA1UdIwQY -MBaAFLD1yOtonJPAufGLqZ3QSRZDAeoiMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBACpuDaS4SPpiA3cU6/tadt8F1vqDs0T4sHbPfiCLdb4P+3N/ -2R8q3SvGzpxJzPflkR8QFwjK0fQuIb0FLyXbBCAXz1KyDb7m5OAs50Cn8OVqsjci -LWUGR/QPhAlcNba5jLhbbq7P4qh28aNx8u6XT/l/PSxgcfWm5vOc/2dN4I948R3P -U1iyLSqHTDFzsawHgXIyTUq9TOZXlBjWyWHBFsDI1AnQdeT3ELdeDzGyD6paGSB5 -IJ4LFyvJkslvKFGWgOc6EhB9zvxrKWBEMTDUTOfRe7gNQ1esr6XcsAqtJ7/QRTUF -36VxjlPiERA2m5tmNNy4hZ4zUXKlsJgeY+bAdVM= +MIIDGTCCAgGgAwIBAgIUDr7CjUg6evYtl4uqdgyu94ACVOAwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzgv+bNXgI07CBjqHRie/2R +3Etpu7eVC9/LuBoe+KpUuns3r2Ix0bKg1VIjDLdidcFmAqx/qSi0SWdEtAfPWqWo +LI6GVYmBUZzcJHAxMsJJLIpVCIZsQt+k4Dz0ECGwB/Q501Es9hEiTHZSXnPN8XSO +0f9m2rINT3yWCa+UyMlxolIJAkYlajU/BU8xIOcSKACaE2iNKv3rs+6qIO7dpP+j +tUWI/Vtjdt5PSY7+WUl5yh4WqTMkMKfAonSyvCxzyMb1HIe3TAN0dTulN/PdAe9x +7qLJx08wju2v5eBhwwQn0ZO9FPPNE/440nwanUmJtQBh46htgImPmz3j2VQvRLcC +AwEAAaNTMFEwHQYDVR0OBBYEFKp7SXYko8r9qgYDbOaDOEt2aNUhMB8GA1UdIwQY +MBaAFKp7SXYko8r9qgYDbOaDOEt2aNUhMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAADzhaAVNIIWykvV4+RZ6FtSS3oJwerFUY2/PECLTcEyjtuu +eTu9uiZMu4R/hmvcGXxa40uS96SOwseIo8FJFSVEiTLqPJB+ZhiFE/wAaChRlc78 +4/Q9Hj46IS67aZoOT+nCIv3PcOrxFMZqtLyBLIrtFxkv2WfoaqxTm7GbBdvwIvQO +DvOHHudXGeC+RL8sz8YIv1ghd8LxLdWZmyZhvCWHB0YHnoVryN6oqhKY0zv9YUGJ +r97Qb+RQu9ijmNHWkwuTy5Zxj/GMIqC/vYu7x5DH/m0oCnSGqASLh1gAsjC0Aa+D +YqXbFLxSCtUNhKuW5ejbvHAYp/QgtjAtu81HOkQ= +-----END CERTIFICATE-----`) + +var caCertInter = []byte(`-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEIwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl +cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt +uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq +EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4 +M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT +al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK +SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z +ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD +bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARYbIpIidgAVb +5ra9zd7F902+xC13/nmlrKL/dRMrRdZxk1kVVww3FbXSp7k7oHsih42KUCVDBevw +0ZZiolZlLneU57dEKKiTMkuPdVbNbIBPXIQpHLrXpVIR5BRRdRZ5OJZY24hYCvce +50XV8ITIU0R/U4sQ6NFHv8NJ5BB+2u1M3HF2LSKZFLnfP5FBcTCg84Jd6gEmTU2j +wZELnHy1AVdQnKMP9VrdAr9Wn6omWxAfO/PSb9YeKhGH5vtX+Bpb9bSPQIpXeBdB +LLCkme0M+1UsF7xua0KVi4DSuJc+RBl4aOH0ZvKmrIWzLzZhRS0vaO/fPArVCvvI +VrUba0E3WQ== +-----END CERTIFICATE-----`) + +var caCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEMwDQYJKoZIhvcNAQEF +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl +cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt +uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq +EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4 +M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT +al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK +SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z +ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD +bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAAhMQTwrpAeIQ +nShHfTERiwg/tx3dL971d3pFS5wi4kEIbbYCUGpzkmK/FTw4hfUnLpwcjjAbOWkk +45glOmrLJXM4RvH5PQF3GZmZvxv8Dl4zuhH1QvWbJHUiC+gyrBWI0moyLSmNiutZ +d3TZGEehZGwivMdHHuhgiyFM4i33EQTW1vdMdOvdu8yNpAeXM2h1PcJwbEML9PO3 +LONzVKhz/RsyEwv7PkX1gdmi6eyAE61BWJGwzxE4K0xIYmcr6iOjsJhEf/5Qc93P +IGSHsG/HjWwZ47gbobtv7L+8uKP/0ky+k1cE4nIB1gKYey+SYwvkQTsj24oG9xcL +XhgnIl+qDw== -----END CERTIFICATE-----`) var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY-----`) var serverCert = []byte(`-----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE-----`) var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE-----`) var clientKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY-----`) var clientCert = []byte(`-----BEGIN CERTIFICATE----- -MIIDFDCCAfygAwIBAgIUZIt+6zrmR41Be/CrcPHLsj3pCAYwDQYJKoZIhvcNAQEL -BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa -GA8yMjk0MDcyMzEyMzE0MVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19jbGll -bnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgmmhC2CHBZZRBYyuM -B1vCjG9eThZVUFH9Ik95HG8MOHJDNSHc8kOZqtJyTVltZ2FprzWnaF7O3tuhbI57 -1jxf7IBJg48n574lgSKgO21XUNbkrPV/hWNFeAaAQ9kzOOblW21cYZ13AhFXuYfs -zaCPJV+cpZi1+vCp/nl69mb69i/J1n5vPTni8W6xaIBRZFThbdwdyuYrDhML9/8j -QGlZsLTYTTIV/NWQXmoM21fU0FVUbpKxGih6CRTosiiTT5dxnuDK4d9vQNPUCFQX -PdrB4yolExxeL3NCgHaT3P4YGKWIlT9DpQUagOmLvTyiZjpkk5UOhJLW7buT+usk -u2MHAgMBAAGjSjBIMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG +MIIDFDCCAfygAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEYwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19jbGll +bnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDH0HrVqiQ/6Cqv59gd +/drQnyKUpHYZ5Cd2mD0yfswf6dd3kMaxirFDyUhImVjqkaPAc/KTv+K9EOJfX2Pv +EPZhDS+ropDzkPd+yogv/S0m2/RIFrhP/vdvZliIb9I45j5+EIrlG4W2TGLb/OMT +W2q6hEPRCVPQXm47pz7uZAAfV5gR6IIABkDJ/joBpCsrJbV2UVmLfwvJVAVe1kPS +4GJBvzUDv2VjspKHy7vRuQpo7goYEQPNSgZFLgC9qPlLMl5d1crPsk4ZAtoyuWQC +WAlaEPTrBzTbQwz0qKW8COx4itp5X7ZQZQlDHDyXfJTRZ+ljVDNfy3qEGlXKrtGL +RawZAgMBAAGjSjBIMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG CCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEB -CwUAA4IBAQBUockuDBViT8F/1plpUT5fccMkePO8h/wsk/K8IxpXAv8XerBL0H/j -k235/cGvksiYH1nKSS8VOZfEYY+b0lUDRJFf6kppU7TFiEaH3idGAcmlQ1dSBu1f -iVP63tF0KOfdPlCzdXY4jzyXSnUsxZejALmecCZt1LCOMai2w5zzqy0isjWnDPFF -+Ssmf5HxtfrPvsKDJGD+79HGtTJ3dXmifuvRuuXsYSv2uQPtJsbtXhQWaQHs/6Bg -OtuFbTvFOyxYFJmAl/YM6hRbvKB8Itq38aayi47TA/b11QdAXCB9DMvivI6a89F7 -uL8+zNieoQkyj84eXfkyiSs03TrqOsj9 +CwUAA4IBAQA67Zgf2H84cDOlEbBFznivpp9jRQzwv21e4O0o0HtUJ/rgwbfry1D7 +LkYjtqMKQcxMREfp4d5rmkC0f7W3Skf3eoaCXTyW7Zh8ghHuqMllReSrOTAjS60m +1kzOAE07/Br1O8JtpPKFX7CTSBvLZYNNTRa/dPyQT8ZAMWSyHLc3kW9peIkQ5SZZ +kZ4EJ0/ztNuTLBbjcaxtFDYJpKuv14NJNy/ddjWvKSyBOtqae3HdEvmnfE9Ar9wt +J20OuNSKUAOZEbk9n8UrTV/C/oQ4yDpw0iHSNWhti+KvARQSTj115NkEg+7HrM4d +vhrAcrxy49UrY03GqZwmaf79vF+c2oKk +-----END CERTIFICATE-----`) + +var sha1ServerCertInter = []byte(`-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUaVjtC++/JGFoZRtkpo/j5q1nQ/4wDQYJKoZIhvcNAQEF +BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN +MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs +aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq +ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6 +jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1 +hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn +RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ +a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5 +U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z +dDANBgkqhkiG9w0BAQUFAAOCAQEATpiJFBwcRFIfZ9ffvS1WDzHqNElEnvocv/ul +3KVtoX4gmKRoOy344s3oJ5APPHYWUFuZVc3uofjW265r2uOW1Cb4P9yAtNc4htBS ++hYsdS3MQlzZCS9rItaT25R6Ieq5TbHGRCof387jzvo1NNhcAQ5akQlQKI87km77 +VzoEBdAw68Q0ZE+X34Q9eAA44oCcLAgCpGvs6hQuUSInribSR3vtsjuaLjdJ5F1f +GCu2QGM4cVLaezmoa1J54ETZggT2xFw2IyWJ2g/kXFpo+HnoyaDrPthud3Pe5xEt +JMzX0s3jPSjfeAv34Pr37s0Or18r1bS1hrgxE0SV2vk31fsImg== +-----END CERTIFICATE-----`) + +var serverCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUfSzzygvth1xlpa9DtyGpHuY2V+swDQYJKoZIhvcNAQEL +BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN +MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs +aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq +ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6 +jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1 +hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn +RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ +a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5 +U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z +dDANBgkqhkiG9w0BAQsFAAOCAQEAwe/JUeIiJ5ugiO4tM0ZtvgHuFC3hK+ZWndRE +z4JfVXTW9soxpa/cOU9QdJhZzouIu9yqZasY4zSEerC1e6grBYP95vMbN6xUAown +wNzrQzyJ6yP526txiIdOkKf+yVNdz0OWNHMPtwTWIr8kKGK23ABF94aUa0VlkErp +Qrd8NQ3guIPI+/upuxirJCFdhE+U3U0pLHpGaGvhkOytfnLYiINwR9norVCDGbQG +ITH0tOz8gVWWWwxa9s5CmbqTnasgUMDh1jHa5xOo+riX8H5lwQUaItKU1JM+QMIR +6Z+M0Isdw647A6tmX7DqNcmHlBKxPN1GDcVXalwYJUoXwTb9Hw== -----END CERTIFICATE-----`) From 499ee65a9b0cd45d41716b513fae0d537f7f9c88 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Thu, 24 Mar 2022 01:08:02 -0400 Subject: [PATCH 3/4] webhooks, aggregation: add metrics to count certs with SHA1 signatures Extends the certificate attribute deprecation RoundTrippers wrapper with a checker that counts certificates with sha-1 signatures in server responses. Non-root non-self-signed SHA-1 certificate signatures were deprecated in Golang 1.18. --- .../apiserver/pkg/util/webhook/certs_test.go | 28 - .../apiserver/pkg/util/webhook/client.go | 7 +- .../apiserver/pkg/util/webhook/metrics.go | 13 + .../apiserver/pkg/util/webhook/webhook.go | 5 +- .../pkg/util/webhook/webhook_test.go | 40 +- .../pkg/util/x509metrics/missing_san.go | 172 +++++- .../pkg/util/x509metrics/missing_san_test.go | 530 +++++++++++++++--- .../pkg/apiserver/handler_proxy.go | 5 +- .../kube-aggregator/pkg/apiserver/metrics.go | 13 + 9 files changed, 674 insertions(+), 139 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go index 0caf02512cc..4d21e252ee5 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/certs_test.go @@ -67,34 +67,6 @@ koodzngbUuyaGFI8QISUAhU+pbt6npb69LlhJHC0icDXCc4uTsd+SDsBOorZDuUL HsNKnE0CSPZ65ENVNfJjB1fVEYbbpjr8kizOCDE= -----END CERTIFICATE-----`) -var badCAKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAzOC/5s1eAjTsIGOodGJ7/ZHcS2m7t5UL38u4Gh74qlS6ezev -YjHRsqDVUiMMt2J1wWYCrH+pKLRJZ0S0B89apagsjoZViYFRnNwkcDEywkksilUI -hmxC36TgPPQQIbAH9DnTUSz2ESJMdlJec83xdI7R/2basg1PfJYJr5TIyXGiUgkC -RiVqNT8FTzEg5xIoAJoTaI0q/euz7qog7t2k/6O1RYj9W2N23k9Jjv5ZSXnKHhap -MyQwp8CidLK8LHPIxvUch7dMA3R1O6U3890B73HuosnHTzCO7a/l4GHDBCfRk70U -880T/jjSfBqdSYm1AGHjqG2AiY+bPePZVC9EtwIDAQABAoIBACapNq1IDbhe4jwO -ckhcGUe1UZvNfQXck1wM5lXPiF8kE/iSfn8KJacOoJKaWJj2dIAlTtXcVUCAHOXm -2g4rO9DM1nOit9t10r/F7v5Y2lo9UrFb8HrlTQ1E4Ke/6pdgz29vxgeoc1qyXTlq -u7Ygo7K6DLikYRp+VoSND5DZg7Y3a3/W7xecdrV1gH3XOn1fyw4IZ3u1GaufA6Jx -iJqA2RRIhHWbL9nXeRQJyACf2kYnQK8nyRhtHGiqWdLdE/T7StyqtELA41zwBip4 -vUK8l71FUD121AC7MXBGJGxmPHSat7CMmn0rtm7gksKCHjdJA3f631CVEj1OmMqT -zgULsckCgYEA+qfZpJZAg+g/dtGb26oNAxiY+Q2DGF3qZQQGk8sK8ZiIEIDL4Zul -+F9N3IK0RFqojjL2p8ktvOnspPTqoSqBjRDr2YzDsCbXR0P1Q9N/9mAvJDSrtywF -V6Ru4XkcGLOOCU5/8eXrd6e/40I0Q25amAcVAW42cL5xAkc59O5dWmMCgYEA0T8I -FAuFy8kM7hPE6mSnvFpXzj0NpWVDqwCjxy7DnnOOo4ttUfZciSq3kQ7b9WK1BeHi -C2MWALGz5Qw21bj+TgLNO39+Ah/nCTGRMtaciy3yq5IX0pV+A3Frz5X6m/PBqmT8 -p6TdYBZ84AKCKuEEShm7BgzVB2w2VrLLvtRysp0CgYEA8oBj631GS5ftlpnybVIX -JrCshv/Qnkl2VWbQqjodi2Hj+ftxxQLeTu59mOKHXz5KptCdm/TiIEw9G9asDWLf -VchSNfae+JSLYLJZ3tYHjii+Uwv2OdAIFyPJ9rBCQ4+r0ks1M6Ya6nfMCSVrBPYG -BeGMLAch+m/1S5v3cYUPojsCgYArTPnk/AVyCGbulZS4VKAJcECfYy8BvRTlvDoo -K9s7XPp1iZLT1UGM+RQHpqWKACUp1HasmJKjDiMGESL/00p85kOGPnnbArMSyfkc -JiE7BAUl0BOx9lGfcMc4q/aycxzun/tQzeMp0T2CNcKuEOaMVwrG07z5zkDobBOR -p/EcWQKBgCV2nO7Z/oyqaD00VBBm118/ZqbZG0Znxm/oxI4bG+OGRWtJc0nCVYDT -bZP4QR5baZ7KOtKAP+ksyZpyKftAgNH+TrbTTg1gJcv3gfeTivbmXyoMjwbFlu8H -iQRXj801qb2ME3+HlT0Ti8Qf3BEPrDnGf8qVSkQPjHkIbKr/3/Zv ------END RSA PRIVATE KEY-----`) - var badCACert = []byte(`-----BEGIN CERTIFICATE----- MIIDGTCCAgGgAwIBAgIUDr7CjUg6evYtl4uqdgyu94ACVOAwDQYJKoZIhvcNAQEL BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/client.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/client.go index 3ad774ef84d..514fd9551cc 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/client.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/client.go @@ -148,8 +148,11 @@ func (cm *ClientManager) HookClient(cc ClientConfig) (*rest.RESTClient, error) { cfg.ContentConfig.ContentType = runtime.ContentTypeJSON // Add a transport wrapper that allows detection of TLS connections to - // servers without SAN extension in their serving certificates - cfg.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter)) + // servers with serving certificates with deprecated characteristics + cfg.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor( + x509MissingSANCounter, + x509InsecureSHA1Counter, + )) client, err := rest.UnversionedRESTClientFor(cfg) if err == nil { diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/metrics.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/metrics.go index c3085226cfe..67fc8fabe05 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/metrics.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/metrics.go @@ -34,6 +34,19 @@ var x509MissingSANCounter = metrics.NewCounter( }, ) +var x509InsecureSHA1Counter = metrics.NewCounter( + &metrics.CounterOpts{ + Subsystem: "webhooks", + Namespace: "apiserver", + Name: "x509_insecure_sha1_total", + Help: "Counts the number of requests to servers with insecure SHA1 signatures " + + "in their serving certificate OR the number of connection failures " + + "due to the insecure SHA1 signatures (either/or, based on the runtime environment)", + StabilityLevel: metrics.ALPHA, + }, +) + func init() { legacyregistry.MustRegister(x509MissingSANCounter) + legacyregistry.MustRegister(x509InsecureSHA1Counter) } diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go index 80de7d8b066..06a74c1cd31 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go @@ -85,7 +85,10 @@ func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFact codec := codecFactory.LegacyCodec(groupVersions...) clientConfig.ContentConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}) - clientConfig.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter)) + clientConfig.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor( + x509MissingSANCounter, + x509InsecureSHA1Counter, + )) restClient, err := rest.UnversionedRESTClientFor(clientConfig) if err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go index 016f9744b21..b74aba044e5 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook_test.go @@ -334,11 +334,12 @@ func TestMissingKubeConfigFile(t *testing.T) { func TestTLSConfig(t *testing.T) { invalidCert := []byte("invalid") tests := []struct { - test string - clientCert, clientKey, clientCA []byte - serverCert, serverKey, serverCA []byte - errRegex string - increaseSANWarnCounter bool + test string + clientCert, clientKey, clientCA []byte + serverCert, serverKey, serverCA []byte + errRegex string + increaseSANWarnCounter bool + increaseSHA1SignatureWarnCounter bool }{ { test: "invalid server CA", @@ -402,8 +403,23 @@ func TestTLSConfig(t *testing.T) { errRegex: "x509: certificate relies on legacy Common Name field", increaseSANWarnCounter: true, }, + { + test: "server cert with SHA1 signature", + clientCA: caCert, + serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...), serverKey: serverKey, + errRegex: "x509: cannot verify signature: insecure algorithm SHA1-RSA \\(temporarily override with GODEBUG=x509sha1=1\\)", + increaseSHA1SignatureWarnCounter: true, + }, + { + test: "server cert signed by an intermediate CA with SHA1 signature", + clientCA: caCert, + serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...), serverKey: serverKey, + errRegex: "x509: cannot verify signature: insecure algorithm SHA1-RSA \\(temporarily override with GODEBUG=x509sha1=1\\)", + increaseSHA1SignatureWarnCounter: true, + }, } + lastSHA1SigCounter := 0 for _, tt := range tests { // Use a closure so defer statements trigger between loop iterations. func() { @@ -483,6 +499,20 @@ func TestTLSConfig(t *testing.T) { t.Errorf("expected the x509_common_name_error_count to be 1, but it's %d", errorCounter) } } + + if tt.increaseSHA1SignatureWarnCounter { + errorCounter := getSingleCounterValueFromRegistry(t, legacyregistry.DefaultGatherer, "apiserver_webhooks_x509_insecure_sha1_total") + + if errorCounter == -1 { + t.Errorf("failed to get the apiserver_webhooks_x509_insecure_sha1_total metrics: %v", err) + } + + if int(errorCounter) != lastSHA1SigCounter+1 { + t.Errorf("expected the apiserver_webhooks_x509_insecure_sha1_total counter to be 1, but it's %d", errorCounter) + } + + lastSHA1SigCounter++ + } }() } } diff --git a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go index d16daec2511..6dbac3b7468 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go +++ b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go @@ -20,64 +20,139 @@ import ( "crypto/x509" "errors" "net/http" + "reflect" "strings" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/component-base/metrics" + "k8s.io/klog/v2" ) -var _ utilnet.RoundTripperWrapper = &x509MissingSANErrorMetricsRTWrapper{} +var _ utilnet.RoundTripperWrapper = &x509DeprecatedCertificateMetricsRTWrapper{} -type x509MissingSANErrorMetricsRTWrapper struct { +type x509DeprecatedCertificateMetricsRTWrapper struct { rt http.RoundTripper - counter *metrics.Counter + checkers []deprecatedCertificateAttributeChecker } -// NewMissingSANRoundTripperWrapperConstructor returns a RoundTripper wrapper that's usable -// within ClientConfig.Wrap that increases the `metricCounter` whenever: +type deprecatedCertificateAttributeChecker interface { + // CheckRoundTripError returns true if the err is an error specific + // to this deprecated certificate attribute + CheckRoundTripError(err error) bool + // CheckPeerCertificates returns true if the deprecated attribute/value pair + // was found in a given certificate in the http.Response.TLS.PeerCertificates bundle + CheckPeerCertificates(certs []*x509.Certificate) bool + // IncreaseCounter increases the counter internal to this interface + // Use the req to derive and log information useful for troubleshooting the certificate issue + IncreaseMetricsCounter(req *http.Request) +} + +// counterRaiser is a helper structure to include in certificate deprecation checkers. +// It implements the IncreaseMetricsCounter() method so that, when included in the checker, +// it does not have to be reimplemented. +type counterRaiser struct { + counter *metrics.Counter + reason string +} + +func (c *counterRaiser) IncreaseMetricsCounter(req *http.Request) { + if req != nil && req.URL != nil { + if hostname := req.URL.Hostname(); len(hostname) > 0 { + klog.Infof("invalid certificate detected while connecting to %q: %s", req.URL.Hostname(), c.reason) + } + } + c.counter.Inc() +} + +// NewDeprecatedCertificateRoundTripperWrapperConstructor returns a RoundTripper wrapper that's usable within ClientConfig.Wrap. +// +// It increases the `missingSAN` counter whenever: // 1. we get a x509.HostnameError with string `x509: certificate relies on legacy Common Name field` // which indicates an error caused by the deprecation of Common Name field when veryfing remote // hostname // 2. the server certificate in response contains no SAN. This indicates that this binary run // with the GODEBUG=x509ignoreCN=0 in env -func NewMissingSANRoundTripperWrapperConstructor(metricCounter *metrics.Counter) func(rt http.RoundTripper) http.RoundTripper { +// +// It increases the `sha1` counter whenever: +// 1. we get a x509.InsecureAlgorithmError with string `SHA1` +// which indicates an error caused by an insecure SHA1 signature +// 2. the server certificate in response contains a SHA1WithRSA or ECDSAWithSHA1 signature. +// This indicates that this binary run with the GODEBUG=x509sha1=1 in env +func NewDeprecatedCertificateRoundTripperWrapperConstructor(missingSAN, sha1 *metrics.Counter) func(rt http.RoundTripper) http.RoundTripper { return func(rt http.RoundTripper) http.RoundTripper { - return &x509MissingSANErrorMetricsRTWrapper{ - rt: rt, - counter: metricCounter, + return &x509DeprecatedCertificateMetricsRTWrapper{ + rt: rt, + checkers: []deprecatedCertificateAttributeChecker{ + NewSANDeprecatedChecker(missingSAN), + NewSHA1SignatureDeprecatedChecker(sha1), + }, } } } -func (w *x509MissingSANErrorMetricsRTWrapper) RoundTrip(req *http.Request) (*http.Response, error) { +func (w *x509DeprecatedCertificateMetricsRTWrapper) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := w.rt.RoundTrip(req) - checkForHostnameError(err, w.counter) - checkRespForNoSAN(resp, w.counter) + + if err != nil { + for _, checker := range w.checkers { + if checker.CheckRoundTripError(err) { + checker.IncreaseMetricsCounter(req) + } + } + } else if resp != nil { + if resp.TLS != nil && len(resp.TLS.PeerCertificates) > 0 { + for _, checker := range w.checkers { + if checker.CheckPeerCertificates(resp.TLS.PeerCertificates) { + checker.IncreaseMetricsCounter(req) + } + } + } + } + return resp, err } -func (w *x509MissingSANErrorMetricsRTWrapper) WrappedRoundTripper() http.RoundTripper { +func (w *x509DeprecatedCertificateMetricsRTWrapper) WrappedRoundTripper() http.RoundTripper { return w.rt } -// checkForHostnameError increases the metricCounter when we're running w/o GODEBUG=x509ignoreCN=0 -// and the client reports a HostnameError about the legacy CN fields -func checkForHostnameError(err error, metricCounter *metrics.Counter) { - if err != nil && errors.As(err, &x509.HostnameError{}) && strings.Contains(err.Error(), "x509: certificate relies on legacy Common Name field") { - // increase the count of registered failures due to Go 1.15 x509 cert Common Name deprecation - metricCounter.Inc() +var _ deprecatedCertificateAttributeChecker = &missingSANChecker{} + +type missingSANChecker struct { + counterRaiser +} + +func NewSANDeprecatedChecker(counter *metrics.Counter) *missingSANChecker { + return &missingSANChecker{ + counterRaiser: counterRaiser{ + counter: counter, + reason: "relies on a legacy Common Name field instead of the SAN extension for subject validation", + }, } } -// checkRespForNoSAN increases the metricCounter when the server response contains +// CheckRoundTripError returns true when we're running w/o GODEBUG=x509ignoreCN=0 +// and the client reports a HostnameError about the legacy CN fields +func (c *missingSANChecker) CheckRoundTripError(err error) bool { + if err != nil && errors.As(err, &x509.HostnameError{}) && strings.Contains(err.Error(), "x509: certificate relies on legacy Common Name field") { + // increase the count of registered failures due to Go 1.15 x509 cert Common Name deprecation + return true + } + + return false +} + +// CheckPeerCertificates returns true when the server response contains // a leaf certificate w/o the SAN extension -func checkRespForNoSAN(resp *http.Response, metricCounter *metrics.Counter) { - if resp != nil && resp.TLS != nil && len(resp.TLS.PeerCertificates) > 0 { - if serverCert := resp.TLS.PeerCertificates[0]; !hasSAN(serverCert) { - metricCounter.Inc() +func (c *missingSANChecker) CheckPeerCertificates(peerCertificates []*x509.Certificate) bool { + if len(peerCertificates) > 0 { + if serverCert := peerCertificates[0]; !hasSAN(serverCert) { + return true } } + + return false } func hasSAN(c *x509.Certificate) bool { @@ -90,3 +165,52 @@ func hasSAN(c *x509.Certificate) bool { } return false } + +type sha1SignatureChecker struct { + *counterRaiser +} + +func NewSHA1SignatureDeprecatedChecker(counter *metrics.Counter) *sha1SignatureChecker { + return &sha1SignatureChecker{ + counterRaiser: &counterRaiser{ + counter: counter, + reason: "uses an insecure SHA-1 signature", + }, + } +} + +// CheckRoundTripError returns true when we're running w/o GODEBUG=x509sha1=1 +// and the client reports an InsecureAlgorithmError about a SHA1 signature +func (c *sha1SignatureChecker) CheckRoundTripError(err error) bool { + var unknownAuthorityError x509.UnknownAuthorityError + if err == nil { + return false + } + if !errors.As(err, &unknownAuthorityError) { + return false + } + + errMsg := err.Error() + if strIdx := strings.Index(errMsg, "x509: cannot verify signature: insecure algorithm"); strIdx != -1 && strings.Contains(errMsg[strIdx:], "SHA1") { + // increase the count of registered failures due to Go 1.18 x509 sha1 signature deprecation + return true + } + + return false +} + +// CheckPeerCertificates returns true when the server response contains +// a non-root non-self-signed certificate with a deprecated SHA1 signature +func (c *sha1SignatureChecker) CheckPeerCertificates(peerCertificates []*x509.Certificate) bool { + // check all received non-self-signed certificates for deprecated signing algorithms + for _, cert := range peerCertificates { + if cert.SignatureAlgorithm == x509.SHA1WithRSA || cert.SignatureAlgorithm == x509.ECDSAWithSHA1 { + // the SHA-1 deprecation does not involve self-signed root certificates + if !reflect.DeepEqual(cert.Issuer, cert.Subject) { + return true + } + } + } + + return false +} diff --git a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go index 227cc1924b4..36403b509ae 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go +++ b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go @@ -19,103 +19,189 @@ package x509metrics import ( "crypto/tls" "crypto/x509" + "crypto/x509/pkix" "encoding/pem" + "fmt" "net" "net/http" "net/http/httptest" "net/url" + "reflect" "testing" + "github.com/stretchr/testify/require" "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/testutil" ) // taken from pkg/util/webhook/certs_test.go var caCert = []byte(`-----BEGIN CERTIFICATE----- -MIIDGTCCAgGgAwIBAgIUOS2MkobR2t4rguefcC78gLuXkc0wDQYJKoZIhvcNAQEL -BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa -GA8yMjk0MDcyMzEyMzE0MVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy8o1sRSe8viuSxh8a7Ou8n -vyDJxeJA9son+clZdSwa1YpbhSsYPr2svTGLT4ZxX3JkvHZGDaB+G6QrZNIWOssJ -4+fjvEsVSnk9q7Yr8wX8QdShksnSP0qdB1xFKlqwTFcZyQHqjlyctV93/LEosM9D -RZzgPpXJuC6wD7qdLRSPxQwuegZYcMGT2Y4/8CfBgiEUkZNrGYJiDFrblI0N9jX2 -jUeP/g8xWJIKLTBedVbAzj02Y66WdNecYcyTMROdclPB1IbF4ABbCGynnP0fbiaf -0+4v0pLedqwCYSWD/ujajyDtYuhI8U+OkENwkZ/h5jw/6aWq7esMZDbEAT6UPgEC -AwEAAaNTMFEwHQYDVR0OBBYEFBgvyZWkRJCRjxclYA0mMlnzc/GmMB8GA1UdIwQY -MBaAFBgvyZWkRJCRjxclYA0mMlnzc/GmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBAHigaFJ8DqYFMGXNUT5lYM8oLLWYcbivGxR7ofDm8rXWGLdQ -tKsWeusSlgpzeO1PKCzwSrYQhlFIZI6AH+ch7EAWt84MfAaMz/1DiXF6Q8fAcR0h -QoyFIAKTiVkcgOQjSQOIM2SS5cyGeDRaHGVWfaJOwdIYo6ctFzI2asPJ4yU0QsA7 -0WTD2+sBG6AXGhfafGUHEmou8sGQ+QT8rgi4hs1bfyHuT5dPgC4TbwknD1G8pMqm -ID3CIiCF8hhF5C2hjrW0LTJ6zTlg1c1K0NmmUL1ucsfzEk//c7GsU8dk+FYmtW9A -VzryJj1NmnSqA3zd3jBMuK37Ei3pRvVbO7Uxf14= +MIIDGTCCAgGgAwIBAgIUealQGELTHLUVcpsNNwz8XexiWvswDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeW0Jkq6ViZkyhaLCUgbqsN +7+6HLwfZK/ljy/KnZ7W7QlJ65Q2tkptL0fY4DPumT7JgVTGnXyTXJ35Ss5A4yhm9 +yyMH8pNVR19udK1fU74YVmbXJkc0nP7n+AXX9lD2Yy9pDvtaq1E+erN2nR1XaCS9 +n0ph4C/fB1Rh7mIv/u7WW7/aRz/rJjBBZIbg7hgZPwFsukEifGi0U4uitVYR6MWp +jHj++e1G38+4JrZR9vhBoHtBJ1DBpmjAQaAtkSZAxXJnma4awE0Bv0Q4lxkUeY+D +th8OxPXxgTbwTKDaguHlWLTapppygA8FnKqmcUkwHZO5OVldi/ZKOUm2YCuJlfEC +AwEAAaNTMFEwHQYDVR0OBBYEFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMB8GA1UdIwQY +MBaAFJGX6zVDm0Ur4gJJR+PKlgGdwhPfMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJaRryxp0iYWGfLiZ0uIdOiYRVZUtmpqUSqT9/y29ffDAnCS +5labJS8FjaiQdlyaH+E9gzo0+nkO9NyfemJRLTEsU4Mz9AAvxs/NuWucqiyF0Y6d +JSYt7+2liGK5WvJMbHfW3jloWlv3oX+qL4iGFkJN+L9G+vf0GnKZCxgNIOqM4otv +cviCA9ouPwnSfnCeTsBoaUJqhLMizvUx7avvUyZTuV+t9+aN/qH4V//hTBqz9CNq +koodzngbUuyaGFI8QISUAhU+pbt6npb69LlhJHC0icDXCc4uTsd+SDsBOorZDuUL +HsNKnE0CSPZ65ENVNfJjB1fVEYbbpjr8kizOCDE= +-----END CERTIFICATE-----`) + +var caCertInter = []byte(`-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEIwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl +cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt +uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq +EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4 +M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT +al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK +SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z +ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD +bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARYbIpIidgAVb +5ra9zd7F902+xC13/nmlrKL/dRMrRdZxk1kVVww3FbXSp7k7oHsih42KUCVDBevw +0ZZiolZlLneU57dEKKiTMkuPdVbNbIBPXIQpHLrXpVIR5BRRdRZ5OJZY24hYCvce +50XV8ITIU0R/U4sQ6NFHv8NJ5BB+2u1M3HF2LSKZFLnfP5FBcTCg84Jd6gEmTU2j +wZELnHy1AVdQnKMP9VrdAr9Wn6omWxAfO/PSb9YeKhGH5vtX+Bpb9bSPQIpXeBdB +LLCkme0M+1UsF7xua0KVi4DSuJc+RBl4aOH0ZvKmrIWzLzZhRS0vaO/fPArVCvvI +VrUba0E3WQ== +-----END CERTIFICATE-----`) + +var caCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEMwDQYJKoZIhvcNAQEF +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRl +cm1lZGlhdGVfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT9DIt +uNXhesrh8XtPXK4pR7xGReEsIlgLpMYf11PtFln9eV0HXvUO2CG/YvMxwgyd6Yoq +EfzD4rjmXvl5bQPMygmxf5GN1PM7ef7gVYuHfDgsQ4a82u1JFhKvuOrXn3QRfRg4 +M4uYND7J4+Bg6J8oaA0yXIiMCpBi+XwEufo0RvgxM6mT+CeJ82hmlTKVhQJZZ9ZT +al1C4dTR2XeH5TLiIAvm+egBmSZhtCVn14rGk/PcHOWV7hdCxaFhSm7dSC+dR4zK +SxNleJ4Y+tZgoMfvgP/xHZEjbBzxnxyasES/Nc4nTgylcr6aqEX/fbcF0QzHpL9Z +ibkt1cBExU9zHuFJAgMBAAGjYDBeMB0GA1UdDgQWBBTfgUwjHsTOey7WqL4f3oFD +bmY77TAfBgNVHSMEGDAWgBSRl+s1Q5tFK+ICSUfjypYBncIT3zAPBgNVHRMBAf8E +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAAhMQTwrpAeIQ +nShHfTERiwg/tx3dL971d3pFS5wi4kEIbbYCUGpzkmK/FTw4hfUnLpwcjjAbOWkk +45glOmrLJXM4RvH5PQF3GZmZvxv8Dl4zuhH1QvWbJHUiC+gyrBWI0moyLSmNiutZ +d3TZGEehZGwivMdHHuhgiyFM4i33EQTW1vdMdOvdu8yNpAeXM2h1PcJwbEML9PO3 +LONzVKhz/RsyEwv7PkX1gdmi6eyAE61BWJGwzxE4K0xIYmcr6iOjsJhEf/5Qc93P +IGSHsG/HjWwZ47gbobtv7L+8uKP/0ky+k1cE4nIB1gKYey+SYwvkQTsj24oG9xcL +XhgnIl+qDw== -----END CERTIFICATE-----`) var serverKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY-----`) var serverCert = []byte(`-----BEGIN CERTIFICATE----- -MIIDHzCCAgegAwIBAgIUZIt+6zrmR41Be/CrcPHLsj3pCAQwDQYJKoZIhvcNAQEL -BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMDEwMDcxMjMxNDFa -GA8yMjk0MDcyMzEyMzE0MVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19zZXJ2 -ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQaL/ehc9TShE/fzE0 -BDWOzg/LV9WrLk5b7etxpk411SKIcnjorWYgwq4QfaesUCrZwWJcib2mutI3yHIt -j2VSC7ICV5x0d7qF7/v88Chfs0zw1fUvM59Si1w76Jm2ucxUK63a+WqOwayfGmks -qcWenXvJw7LvIoK5AejA+WfnGnomSFEXRvENcgUWa97i4ceVGxZwSg1BEllNo4yt -+sVh+ptzmIGK0jv/nGAw9k2rbzZNANwZ4mZsUcS78vWo7q5ODUuRs1tko19d4BTj -or555wYLA/JMyUNi5ER2hWkf0ZhbsLE4hFNiAItZWiT3rKTaN5UKrbUFvFnz40En -auGpAgMBAAGjVTBTMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG +MIIDHzCCAgegAwIBAgIUTJoqwFusJcupNCs/u39LBFrkZEQwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQd2ViaG9va190ZXN0c19jYTAgFw0yMjAzMjUxNTMzMjla +GA8yMjk2MDEwODE1MzMyOVowHzEdMBsGA1UEAwwUd2ViaG9va190ZXN0c19zZXJ2 +ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnZvhvIgmlQPJMqjkW +IJrkSSLLsIJ3xSiV5KiZCOHnNkawhuDP1GqNpMwsXSOpvOH2LHYNBKdj7DfYuo8z +aw4rX79q2Z4Jryblu9mtGgPE/ZPelAdPJ7QL1YjuOqiyYyq5EVqRpjU4PENE9YX0 +JGCEUXrY1wd+fO1basyIRi24NGRkaykkv8Hk4DMSAuviI/xMoyWpK6FpCGLnZ0Rm +jSknUh7i6nzHFcp6ip87dZJUN5GmP+fS1hIAuE4J0afRExq/nB9mbF19mkpSEGtz +EV96IMHlzvF2WfOIetjmWpJA8IfEBBtLWMxpXhp2HEPMXnq3lFTr/l5Y9ngi+VNG +1iY3AgMBAAGjVTBTMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQG CCsGAQUFBwMCBggrBgEFBQcDATAaBgNVHREEEzARhwR/AAABgglsb2NhbGhvc3Qw -DQYJKoZIhvcNAQELBQADggEBAFXNoW48IHJAcO84Smb+/k8DvJBwOorOPspJ/6DY -pYITCANq9kQ54bv3LgPuel5s2PytVL1dVQmAya1cT9kG3nIjNaulR2j5Sgt0Ilyd -Dk/HOE/zBi6KyifV3dgQSbzua8AI9VboR3o3FhmA9C9jDDxAS+q9+NQjB40/aG8m -TBx+oKgeYHee5llKNTsY1Jqh6TT47om70+sjvmgZ4blAV7ft+WG/h3ZVtAZJuFee -tchgUEpGR8ZGyK0r/vWBIKHNSqtG5gdOS9swQLdUFG90OivhddKUU8Zt52uUXbc/ -/ggEd4dM4X6B21xKJQY6vCnTvHFXcVJezV3g1xaNN0yR0DA= +DQYJKoZIhvcNAQELBQADggEBAAeUHlNJiGfvhi8ts96javP8tO5gPkN7uErIMpzA +N1rf5Kdy7/LsxM6Uvwn0ns+p1vxANAjR/c0nfu0eIO1t5fKVDD0s9+ohKA/6phrm +xChTyl21mDZlFKjq0sjSwzBcUHPJjzUW9+AMDvS7pOjR5h4nD21LlMIkBzinl5KT +uo2Pm/OZqepPdM5XH9DaW0T0tjXKvRFe4FklJSKGD7f+T1whtmyziyA84YjYVa/6 +gF+gpIOmPruJI9UoFqEncNpLfh5vKu2Vxv+maztFRhb+9gOg+nVBq1pxmMZV0PuM +L+tz0avIZEO2+KhgVGF3AF8HSZQHYcaskGFSGc8FxDKcDjM= -----END CERTIFICATE-----`) var serverCertNoSAN = []byte(`-----BEGIN CERTIFICATE----- -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 +-----END CERTIFICATE-----`) + +var sha1ServerCertInter = []byte(`-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUaVjtC++/JGFoZRtkpo/j5q1nQ/4wDQYJKoZIhvcNAQEF +BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN +MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs +aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq +ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6 +jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1 +hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn +RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ +a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5 +U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z +dDANBgkqhkiG9w0BAQUFAAOCAQEATpiJFBwcRFIfZ9ffvS1WDzHqNElEnvocv/ul +3KVtoX4gmKRoOy344s3oJ5APPHYWUFuZVc3uofjW265r2uOW1Cb4P9yAtNc4htBS ++hYsdS3MQlzZCS9rItaT25R6Ieq5TbHGRCof387jzvo1NNhcAQ5akQlQKI87km77 +VzoEBdAw68Q0ZE+X34Q9eAA44oCcLAgCpGvs6hQuUSInribSR3vtsjuaLjdJ5F1f +GCu2QGM4cVLaezmoa1J54ETZggT2xFw2IyWJ2g/kXFpo+HnoyaDrPthud3Pe5xEt +JMzX0s3jPSjfeAv34Pr37s0Or18r1bS1hrgxE0SV2vk31fsImg== +-----END CERTIFICATE-----`) + +var serverCertInterSHA1 = []byte(`-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUfSzzygvth1xlpa9DtyGpHuY2V+swDQYJKoZIhvcNAQEL +BQAwKDEmMCQGA1UEAwwdd2ViaG9va190ZXN0c19pbnRlcm1lZGlhdGVfY2EwIBcN +MjIwMzI1MTUzMzI5WhgPMjI5NjAxMDgxNTMzMjlaMBQxEjAQBgNVBAMMCWxvY2Fs +aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOdm+G8iCaVA8kyq +ORYgmuRJIsuwgnfFKJXkqJkI4ec2RrCG4M/Uao2kzCxdI6m84fYsdg0Ep2PsN9i6 +jzNrDitfv2rZngmvJuW72a0aA8T9k96UB08ntAvViO46qLJjKrkRWpGmNTg8Q0T1 +hfQkYIRRetjXB3587VtqzIhGLbg0ZGRrKSS/weTgMxIC6+Ij/EyjJakroWkIYudn +RGaNKSdSHuLqfMcVynqKnzt1klQ3kaY/59LWEgC4TgnRp9ETGr+cH2ZsXX2aSlIQ +a3MRX3ogweXO8XZZ84h62OZakkDwh8QEG0tYzGleGnYcQ8xeereUVOv+Xlj2eCL5 +U0bWJjcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMBMBoGA1UdEQQTMBGHBH8AAAGCCWxvY2FsaG9z +dDANBgkqhkiG9w0BAQsFAAOCAQEAwe/JUeIiJ5ugiO4tM0ZtvgHuFC3hK+ZWndRE +z4JfVXTW9soxpa/cOU9QdJhZzouIu9yqZasY4zSEerC1e6grBYP95vMbN6xUAown +wNzrQzyJ6yP526txiIdOkKf+yVNdz0OWNHMPtwTWIr8kKGK23ABF94aUa0VlkErp +Qrd8NQ3guIPI+/upuxirJCFdhE+U3U0pLHpGaGvhkOytfnLYiINwR9norVCDGbQG +ITH0tOz8gVWWWwxa9s5CmbqTnasgUMDh1jHa5xOo+riX8H5lwQUaItKU1JM+QMIR +6Z+M0Isdw647A6tmX7DqNcmHlBKxPN1GDcVXalwYJUoXwTb9Hw== -----END CERTIFICATE-----`) // Test_checkForHostnameError tests that the upstream message for remote server @@ -144,6 +230,7 @@ func TestCheckForHostnameError(t *testing.T) { x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkForHostnameError"}) registry := testutil.NewFakeKubeRegistry("0.0.0") registry.MustRegister(x509MissingSANCounter) + sanChecker := NewSANDeprecatedChecker(x509MissingSANCounter) var lastCounterVal int for _, tt := range tests { @@ -159,7 +246,9 @@ func TestCheckForHostnameError(t *testing.T) { _, err = client.Transport.RoundTrip(req) - checkForHostnameError(err, x509MissingSANCounter) + if sanChecker.CheckRoundTripError(err) { + sanChecker.IncreaseMetricsCounter(req) + } errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkForHostnameError") if errorCounterVal == -1 { @@ -185,9 +274,6 @@ func TestCheckRespForNoSAN(t *testing.T) { serverCert []byte counterIncrease bool }{ - { - name: "no certs", - }, { name: "no SAN", serverCert: serverCertNoSAN, @@ -203,6 +289,7 @@ func TestCheckRespForNoSAN(t *testing.T) { x509MissingSANCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkRespForNoSAN"}) registry := testutil.NewFakeKubeRegistry("0.0.0") registry.MustRegister(x509MissingSANCounter) + sanChecker := NewSANDeprecatedChecker(x509MissingSANCounter) var lastCounterVal int for _, tt := range tests { @@ -228,7 +315,9 @@ func TestCheckRespForNoSAN(t *testing.T) { TLS: tlsConnectionState, } - checkRespForNoSAN(resp, x509MissingSANCounter) + if sanChecker.CheckPeerCertificates(resp.TLS.PeerCertificates) { + sanChecker.IncreaseMetricsCounter(nil) + } errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkRespForNoSAN") if errorCounterVal == -1 { @@ -248,6 +337,291 @@ func TestCheckRespForNoSAN(t *testing.T) { } } +func TestCheckForInsecureAlgorithmError(t *testing.T) { + tests := []struct { + name string + serverCert []byte + counterIncrease bool + }{ + { + name: "server cert sha1-signed", + serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...), + counterIncrease: true, + }, + { + name: "intermediate CA cert sha1-signed", + serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...), + counterIncrease: true, + }, + { + name: "different error - cert untrusted, intermediate not in returned chain", + serverCert: serverCertInterSHA1, + }, + { + name: "properly signed", + serverCert: serverCert, + }, + } + + // register the test metrics + x509SHA1SignatureCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkForInsecureAlgorithmError"}) + registry := testutil.NewFakeKubeRegistry("0.0.0") + registry.MustRegister(x509SHA1SignatureCounter) + sha1checker := NewSHA1SignatureDeprecatedChecker(x509SHA1SignatureCounter) + + var lastCounterVal int + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tlsServer, serverURL := testServer(t, tt.serverCert) + defer tlsServer.Close() + + req, err := http.NewRequest(http.MethodGet, serverURL.String(), nil) + if err != nil { + t.Fatalf("failed to create an http request: %v", err) + } + + // can't use tlsServer.Client() as it contains the server certificate + // in tls.Config.Certificates. The signatures are, however, only checked + // during building a candidate verification certificate chain and + // if the content of tls.Config.Certificates matches the certificate + // returned by the server, this short-circuits and the signature verification is + // never performed. + caPool := x509.NewCertPool() + require.True(t, caPool.AppendCertsFromPEM(caCert)) + + client := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + RootCAs: caPool, + }, + }, + } + + _, err = client.Transport.RoundTrip(req) + + if sha1checker.CheckRoundTripError(err) { + sha1checker.IncreaseMetricsCounter(req) + } + + errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkForInsecureAlgorithmError") + if errorCounterVal == -1 { + t.Fatalf("failed to get the error counter from the registry") + } + + if tt.counterIncrease && errorCounterVal != lastCounterVal+1 { + t.Errorf("expected the Test_checkForInsecureAlgorithmError metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal) + } + + if !tt.counterIncrease && errorCounterVal != lastCounterVal { + t.Errorf("expected the Test_checkForInsecureAlgorithmError metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal) + } + + lastCounterVal = errorCounterVal + }) + } +} + +func TestCheckRespSHA1SignedCert(t *testing.T) { + tests := []struct { + name string + serverCert []byte + counterIncrease bool + }{ + { + name: "server cert sha1-signed", + serverCert: append(append(sha1ServerCertInter, byte('\n')), caCertInter...), + counterIncrease: true, + }, + { + name: "intermediate CA cert sha1-signed", + serverCert: append(append(serverCertInterSHA1, byte('\n')), caCertInterSHA1...), + counterIncrease: true, + }, + { + name: "properly signed", + serverCert: serverCert, + }, + } + + // register the test metrics + x509SHA1SignatureCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "Test_checkRespSHA1SignedCert"}) + registry := testutil.NewFakeKubeRegistry("0.0.0") + registry.MustRegister(x509SHA1SignatureCounter) + sha1checker := NewSHA1SignatureDeprecatedChecker(x509SHA1SignatureCounter) + + var lastCounterVal int + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var tlsConnectionState *tls.ConnectionState + if tt.serverCert != nil { + peerCerts := []*x509.Certificate{} + for block, rest := pem.Decode([]byte(tt.serverCert)); block != nil; block, rest = pem.Decode(rest) { + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + t.Fatalf("failed to parse certificate: %v", err) + } + + peerCerts = append(peerCerts, cert) + } + + tlsConnectionState = &tls.ConnectionState{ + PeerCertificates: peerCerts, + } + } + + resp := &http.Response{ + TLS: tlsConnectionState, + } + + if sha1checker.CheckPeerCertificates(resp.TLS.PeerCertificates) { + sha1checker.IncreaseMetricsCounter(nil) + } + + errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "Test_checkRespSHA1SignedCert") + if errorCounterVal == -1 { + t.Fatalf("failed to get the error counter from the registry") + } + + if tt.counterIncrease && errorCounterVal != lastCounterVal+1 { + t.Errorf("expected the Test_checkRespSHA1SignedCert metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal) + } + + if !tt.counterIncrease && errorCounterVal != lastCounterVal { + t.Errorf("expected the Test_checkRespSHA1SignedCert metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal) + } + + lastCounterVal = errorCounterVal + }) + } +} + +func Test_x509DeprecatedCertificateMetricsRTWrapper_RoundTrip(t *testing.T) { + // register the test metrics + testCounter := metrics.NewCounter(&metrics.CounterOpts{Name: "testCounter"}) + registry := testutil.NewFakeKubeRegistry("0.0.0") + registry.MustRegister(testCounter) + + tests := []struct { + name string + checkers []deprecatedCertificateAttributeChecker + resp *http.Response + err error + counterIncrease bool + }{ + { + name: "no error, resp w/ cert, no counter increase", + checkers: []deprecatedCertificateAttributeChecker{&testNegativeChecker{counterRaiser{testCounter, ""}}}, + resp: httpResponseWithCert(), + }, + { + name: "no error, resp w/o cert, no counter increase", + checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}}, + resp: httpResponseNoCert(), + }, + { + name: "no error, resp w/ cert, counter increase", + checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}}, + resp: httpResponseWithCert(), + counterIncrease: true, + }, + { + name: "unrelated error, no resp, no counter increase", + checkers: []deprecatedCertificateAttributeChecker{&testNegativeChecker{counterRaiser{testCounter, ""}}}, + err: fmt.Errorf("error"), + }, + { + name: "related error, no resp, counter increase", + checkers: []deprecatedCertificateAttributeChecker{&testPositiveChecker{counterRaiser{testCounter, ""}}}, + err: fmt.Errorf("error"), + counterIncrease: true, + }, + } + + var lastCounterVal int + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := &x509DeprecatedCertificateMetricsRTWrapper{ + rt: newTestRoundTripper(tt.resp, tt.err), + checkers: tt.checkers, + } + got, err := w.RoundTrip(&http.Request{}) + if err != tt.err { + t.Errorf("x509DeprecatedCertificateMetricsRTWrapper.RoundTrip() should not mutate the error. Got %v, want %v", err, tt.err) + return + } + if !reflect.DeepEqual(got, tt.resp) { + t.Errorf("x509DeprecatedCertificateMetricsRTWrapper.RoundTrip() = should not mutate the response. Got %v, want %v", got, tt.resp) + } + + errorCounterVal := getSingleCounterValueFromRegistry(t, registry, "testCounter") + if errorCounterVal == -1 { + t.Fatalf("failed to get the error counter from the registry") + } + + if tt.counterIncrease && errorCounterVal != lastCounterVal+1 { + t.Errorf("expected the testCounter metrics to increase by 1 from %d, but it is %d", lastCounterVal, errorCounterVal) + } + + if !tt.counterIncrease && errorCounterVal != lastCounterVal { + t.Errorf("expected the testCounter metrics to stay the same (%d), but it is %d", lastCounterVal, errorCounterVal) + } + + lastCounterVal = errorCounterVal + }) + } +} + +type testRoundTripper func(req *http.Request) (*http.Response, error) + +func (rt testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return rt(req) +} + +func newTestRoundTripper(resp *http.Response, err error) testRoundTripper { + return func(_ *http.Request) (*http.Response, error) { + return resp, err + } +} + +type testPositiveChecker struct { + counterRaiser +} + +func (c *testPositiveChecker) CheckRoundTripError(_ error) bool { + return true +} + +func (c *testPositiveChecker) CheckPeerCertificates(_ []*x509.Certificate) bool { + return true +} + +type testNegativeChecker struct { + counterRaiser +} + +func (c *testNegativeChecker) CheckRoundTripError(_ error) bool { + return false +} + +func (c *testNegativeChecker) CheckPeerCertificates(_ []*x509.Certificate) bool { + return false +} + +func httpResponseWithCert() *http.Response { + return &http.Response{ + TLS: &tls.ConnectionState{ + PeerCertificates: []*x509.Certificate{ + {Issuer: pkix.Name{CommonName: "a name"}}, + }, + }, + } +} + +func httpResponseNoCert() *http.Response { + return &http.Response{} +} + func testServer(t *testing.T, serverCert []byte) (*httptest.Server, *url.URL) { rootCAs := x509.NewCertPool() rootCAs.AppendCertsFromPEM(caCert) diff --git a/staging/src/k8s.io/kube-aggregator/pkg/apiserver/handler_proxy.go b/staging/src/k8s.io/kube-aggregator/pkg/apiserver/handler_proxy.go index f6255ea56f5..3a880b6b2cf 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/apiserver/handler_proxy.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/apiserver/handler_proxy.go @@ -241,7 +241,10 @@ func (r *proxyHandler) updateAPIService(apiService *apiregistrationv1api.APIServ CAData: apiService.Spec.CABundle, }, } - clientConfig.Wrap(x509metrics.NewMissingSANRoundTripperWrapperConstructor(x509MissingSANCounter)) + clientConfig.Wrap(x509metrics.NewDeprecatedCertificateRoundTripperWrapperConstructor( + x509MissingSANCounter, + x509InsecureSHA1Counter, + )) newInfo := proxyHandlingInfo{ name: apiService.Name, diff --git a/staging/src/k8s.io/kube-aggregator/pkg/apiserver/metrics.go b/staging/src/k8s.io/kube-aggregator/pkg/apiserver/metrics.go index ba25750ec9a..03315e984ff 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/apiserver/metrics.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/apiserver/metrics.go @@ -34,6 +34,19 @@ var x509MissingSANCounter = metrics.NewCounter( }, ) +var x509InsecureSHA1Counter = metrics.NewCounter( + &metrics.CounterOpts{ + Subsystem: "kube_aggregator", + Namespace: "apiserver", + Name: "x509_insecure_sha1_total", + Help: "Counts the number of requests to servers with insecure SHA1 signatures " + + "in their serving certificate OR the number of connection failures " + + "due to the insecure SHA1 signatures (either/or, based on the runtime environment)", + StabilityLevel: metrics.ALPHA, + }, +) + func init() { legacyregistry.MustRegister(x509MissingSANCounter) + legacyregistry.MustRegister(x509InsecureSHA1Counter) } From 5479306b1326bcbf29ae2ca0694a36555ed1ce35 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Fri, 25 Mar 2022 17:03:13 +0100 Subject: [PATCH 4/4] x509metrics: rename 'missing_san*.go' files to match their new purpose better --- .../x509metrics/{missing_san.go => server_cert_deprecations.go} | 0 .../{missing_san_test.go => server_cert_deprecations_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename staging/src/k8s.io/apiserver/pkg/util/x509metrics/{missing_san.go => server_cert_deprecations.go} (100%) rename staging/src/k8s.io/apiserver/pkg/util/x509metrics/{missing_san_test.go => server_cert_deprecations_test.go} (100%) diff --git a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go similarity index 100% rename from staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san.go rename to staging/src/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations.go diff --git a/staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go b/staging/src/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations_test.go similarity index 100% rename from staging/src/k8s.io/apiserver/pkg/util/x509metrics/missing_san_test.go rename to staging/src/k8s.io/apiserver/pkg/util/x509metrics/server_cert_deprecations_test.go