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

Reply via email to