https://bz.apache.org/bugzilla/show_bug.cgi?id=67818
Bug ID: 67818 Summary: SSLContext#setVerify() silently sets undocumented default verify paths Product: Tomcat Native Version: 2.0.6 Hardware: All OS: All Status: NEW Severity: normal Priority: P2 Component: Library Assignee: dev@tomcat.apache.org Reporter: micha...@apache.org Target Milestone: --- Note: This applies to 2.0.x and 1.2.x Consider the following Connector (any Tomcat version): > <Connector port="18444" connectionTimeout="20000" keepAliveTimeout="7200000" > maxParameterCount="1000" > maxHttpHeaderSize="24576" maxThreads="250" > SSLEnabled="true" scheme="https" secure="true" > defaultSSLHostConfigName="deblndw024v.ad001.siemens.net"> > <SSLHostConfig hostName="deblndw024v.ad001.siemens.net" > protocols="TLSv1.2+TLSv1.3" > honorCipherOrder="true" disableSessionTickets="true" > certificateVerification="optional" > certificateVerificationDepth="5" > > ciphers="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK:!DSS:!SHA1:!SHA256:!SHA384"> > <Certificate > certificateFile="/opt/openssl/deblndw024v.ad001.siemens.net/cert.crt" > > certificateKeyFile="/opt/openssl/deblndw024v.ad001.siemens.net/key.crt" > > certificateKeyPasswordFile="/opt/openssl/deblndw024v.ad001.siemens.net/password" > type="RSA" /> > <OpenSSLConf> > <OpenSSLConfCmd name="RequestCAFile" > value="/opt/openssl/siemens-medium+strong-clientcert-cacerts.crt" /> > <OpenSSLConfCmd name="NO_OCSP_CHECK" value="true" /> > </OpenSSLConf> > </SSLHostConfig> > </Connector> Conditions: * The certificate file does not contain a chain of the issuers * SSLCertificateChainFile (mod_ssl) or certificateChainFile (Tomcat) is not set * Neither SSLCACertificatePath/SSLCACertificateFile (mod_ssl) or caCertificateFile/caCertificatePath (Tomcat) is not set According then to my understanding Tomcat should construct any chain for the peer to verify the server certificate, nor when the server requests for for a client certificate would it be able to verify the client certificate chain. Now let's probe the server: > $ openssl s_client -connect deblndw024v:18444 -no-CApath -no-CAfile > CONNECTED(00000004) > Can't use SSL_get_servername > depth=2 C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = > ZZZZZZA1, OU = Siemens Trust Center, CN = Siemens Root CA V3.0 2016 > verify error:num=19:self signed certificate in certificate chain > verify return:1 > depth=2 C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = > ZZZZZZA1, OU = Siemens Trust Center, CN = Siemens Root CA V3.0 2016 > verify return:1 > depth=1 C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = > ZZZZZZE7, CN = Siemens Issuing CA Intranet Server 2022 > verify return:1 > depth=0 C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > verify return:1 > --- > Certificate chain > 0 s:C = DE, O = Siemens, OU = SMD HVM DW, CN = deblndw024v.ad001.siemens.net > i:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZE7, > CN = Siemens Issuing CA Intranet Server 2022 > 1 s:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZE7, > CN = Siemens Issuing CA Intranet Server 2022 > i:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZA1, > OU = Siemens Trust Center, CN = Siemens Root CA V3.0 2016 > 2 s:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZA1, > OU = Siemens Trust Center, CN = Siemens Root CA V3.0 2016 > i:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZA1, > OU = Siemens Trust Center, CN = Siemens Root CA V3.0 2016 > --- > Server certificate > -----BEGIN CERTIFICATE----- > MIIIvjCCBqagAwIBAgIUFZyE3zc5lFsDVaFS9w2zaDea4mYwDQYJKoZIhvcNAQEL > ... > tiR7NMIYlOYgW/cUNFfwJUJk8D0L92oKlmT6JAfDN+rahjtOTUXXw3MD7uZ58+6T > aYp+izk9yY90cqgrdGe82vv4kx2xkEozgvYlW2GyKg1Fhh9GYu64xn0ny4M5jE0N > eFdmSs7MqQZBF6HSlucSXbkVV3zvoltvILbWXrMVYldJGA== > -----END CERTIFICATE----- > subject=C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > > issuer=C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = > ZZZZZZE7, CN = Siemens Issuing CA Intranet Server 2022 > > --- > Acceptable client certificate CA names > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZD2, CN = Siemens > Issuing CA EE Auth 2021 > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZDD, CN = Siemens > Issuing CA EE Network Smartcard Auth 2021 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZB2, OU = > Siemens Trust Center, CN = Siemens Issuing CA EE Auth 2020 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZBD, OU = > Siemens Trust Center, CN = Siemens Issuing CA EE Network Smartcard Auth 2020 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZB6, OU = > Siemens Trust Center, CN = Siemens Issuing CA Medium Strength Authentication > 2020 > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZD6, CN = Siemens > Issuing CA Medium Strength Authentication 2021 > Requested Signature Algorithms: > ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1 > Shared Requested Signature Algorithms: > ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512 > Peer signing digest: SHA256 > Peer signature type: RSA-PSS > Server Temp Key: X25519, 253 bits > --- > SSL handshake has read 7914 bytes and written 403 bytes > Verification error: self signed certificate in certificate chain > --- Where does the chain come from when I have not set it? Reproducing the same in HTTPd gives only the leaf, not the chain. it turns out that the admin does not have real control over this because sslcontext.c sets the default verify paths without admin's consent and without any documentation. This is likely unwanted in many scenarios. > if (!c->store) { > if (SSL_CTX_set_default_verify_paths(c->ctx)) { > c->store = SSL_CTX_get_cert_store(c->ctx); > X509_STORE_set_flags(c->store, 0); > } Depending on how the default trust store is configured this might work silently or produce unwanted effects. The solution is simple: don't do it just like in mod_ssl, give the admin full control over this. Applied a patch and tried again: > $ openssl s_client -connect deblndw024v:18444 -no-CApath -no-CAfile > CONNECTED(00000004) > Can't use SSL_get_servername > depth=0 C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > verify error:num=20:unable to get local issuer certificate > verify return:1 > depth=0 C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > verify error:num=21:unable to verify the first certificate > verify return:1 > depth=0 C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > verify return:1 > --- > Certificate chain > 0 s:C = DE, O = Siemens, OU = SMD HVM DW, CN = deblndw024v.ad001.siemens.net > i:C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZE7, > CN = Siemens Issuing CA Intranet Server 2022 > --- > Server certificate > -----BEGIN CERTIFICATE----- > MIIIvjCCBqagAwIBAgIUFZyE3zc5lFsDVaFS9w2zaDea4mYwDQYJKoZIhvcNAQEL > ... > aYp+izk9yY90cqgrdGe82vv4kx2xkEozgvYlW2GyKg1Fhh9GYu64xn0ny4M5jE0N > eFdmSs7MqQZBF6HSlucSXbkVV3zvoltvILbWXrMVYldJGA== > -----END CERTIFICATE----- > subject=C = DE, O = Siemens, OU = SMD HVM DW, CN = > deblndw024v.ad001.siemens.net > > issuer=C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = > ZZZZZZE7, CN = Siemens Issuing CA Intranet Server 2022 > > --- > Acceptable client certificate CA names > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZD2, CN = Siemens > Issuing CA EE Auth 2021 > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZDD, CN = Siemens > Issuing CA EE Network Smartcard Auth 2021 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZB2, OU = > Siemens Trust Center, CN = Siemens Issuing CA EE Auth 2020 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZBD, OU = > Siemens Trust Center, CN = Siemens Issuing CA EE Network Smartcard Auth 2020 > C = DE, ST = Bayern, L = Muenchen, O = Siemens, serialNumber = ZZZZZZB6, OU = > Siemens Trust Center, CN = Siemens Issuing CA Medium Strength Authentication > 2020 > C = DE, ST = Bayern, O = Siemens, serialNumber = ZZZZZZD6, CN = Siemens > Issuing CA Medium Strength Authentication 2021 > Requested Signature Algorithms: > ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1 > Shared Requested Signature Algorithms: > ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512 > Peer signing digest: SHA256 > Peer signature type: RSA-PSS > Server Temp Key: X25519, 253 bits > --- > SSL handshake has read 4045 bytes and written 403 bytes > Verification error: unable to verify the first certificate > --- > New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 > Server public key is 4096 bit > Secure Renegotiation IS NOT supported > Compression: NONE > Expansion: NONE > No ALPN negotiated > Early data was not sent > Verify return code: 21 (unable to verify the first certificate) > --- As one can see, truly no chain transmitted. Now I can properly construct the chain for the server certificate AND the chain for client certificate validation myself. I will provide a PR. -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org