Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with EC keys #11

Open
kolomparrudi opened this issue May 20, 2022 · 2 comments
Open

Problem with EC keys #11

kolomparrudi opened this issue May 20, 2022 · 2 comments

Comments

@kolomparrudi
Copy link

kolomparrudi commented May 20, 2022

Hi,

I'm trying to use pem-keystore for LDAP SASL External authentication:

Created a custom SSLSocketFamily:

 public class PemSSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;

    public PemSSLSocketFactory() {
        super();
    }

    protected PemSSLSocketFactory(SSLSocketFactory factory) {
        this.factory = factory;
    }

    public static PemSSLSocketFactory getDefault() {
        SSLContext ctx = null;
        KeyStore keyStoreForSASL;
        KeyStore keyStoreForVerify;
        TrustManagerFactory tmf;
        KeyManagerFactory kmf;

        try (FileInputStream stream = new FileInputStream("/tmp/tls.properties")) {
            keyStoreForSASL = KeyStore.getInstance("PEMCFG", new PemKeyStoreProvider());
            keyStoreForSASL.load(stream, new char[0]);
            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStoreForSASL, new char[0]);
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException e) {
            throw new RuntimeException( e );
        }
        try (FileInputStream stream = new FileInputStream("/run/secrets/tls-int-ca-cert/cacertbundle.pem")) {
            keyStoreForVerify = KeyStore.getInstance("PEMCA", new PemKeyStoreProvider());
            keyStoreForVerify.load(stream, new char[0]);
            tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(keyStoreForVerify);
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException  e) {
            throw new RuntimeException( e );
        }
        KeyManager[] keyManagers = kmf.getKeyManagers();
        try {
            ctx = SSLContext.getInstance( "TLS" );
            ctx.init( keyManagers, tmf.getTrustManagers(), new SecureRandom() );
        } catch ( KeyManagementException e ) {
            throw new RuntimeException( e );
        } catch ( NoSuchAlgorithmException e ) {
            throw new RuntimeException( e );
        }
        return new PemSSLSocketFactory( ctx.getSocketFactory() );
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return factory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return factory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return factory.createSocket( s, host, port, autoClose );
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return factory.createSocket( host, port );
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return factory.createSocket( host, port, localHost, localPort );
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return factory.createSocket( host, port );
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return factory.createSocket( address, port, localAddress, localPort );
    }
}

Here is the LDAP connect part:

		Hashtable<String, Object> env = new Hashtable<String, Object>(11);
		env.put(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, "ldap://myserver:389");
		try {
			// Create initial context
			LdapContext ctx = new InitialLdapContext(env, null);
			// Start TLS
			StartTlsResponse tls = (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
			tls.negotiate(PemSSLSocketFactory.getDefault());

			// Perform client authentication using TLS credentials. This uses default client keystore configured, check client-tls.cli
			ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "EXTERNAL");

			System.out.println(ctx.lookup("ou=people,dc=myquery"));`

/tmp/tls.properties content:

alias=ldapclient1
source.key=/run/secrets/ldap-admin-certs/cliprivkey.pem
source.cert=/run/secrets/ldap-admin-certs/clicert.pem

If I execute it with -Djavax.net.debug=all I got these errors:


javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.310 UTC|SunX509KeyManagerImpl.java:401|matching alias: ldapclient1
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.310 UTC|X509Authentication.java:242|ldapclient1 private or public key is not of EC algorithm
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.310 UTC|CertificateRequest.java:813|Unavailable authentication scheme: ecdsa_secp256r1_sha256
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.310 UTC|SunX509KeyManagerImpl.java:401|matching alias: ldapclient1
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.320 UTC|X509Authentication.java:242|ldapclient1 private or public key is not of EC algorithm
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.320 UTC|CertificateRequest.java:813|Unavailable authentication scheme: ecdsa_secp384r1_sha384
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.320 UTC|SunX509KeyManagerImpl.java:401|matching alias: ldapclient1
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.320 UTC|X509Authentication.java:242|ldapclient1 private or public key is not of EC algorithm
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.320 UTC|CertificateRequest.java:813|Unavailable authentication scheme: ecdsa_secp521r1_sha512
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.320 UTC|CertificateRequest.java:773|Unable to produce CertificateVerify for signature scheme: ed25519
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.321 UTC|CertificateRequest.java:773|Unable to produce CertificateVerify for signature scheme: ed448
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.321 UTC|X509Authentication.java:215|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.321 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_pss_sha256
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.321 UTC|X509Authentication.java:215|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.321 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_pss_sha384
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.322 UTC|X509Authentication.java:215|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.322 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_pss_sha512
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.322 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.322 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_rsae_sha256
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.322 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.322 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_rsae_sha384
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.322 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.323 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pss_rsae_sha512
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.323 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.323 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pkcs1_sha256
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.323 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.323 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pkcs1_sha384
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.323 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.323 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pkcs1_sha512
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.324 UTC|SunX509KeyManagerImpl.java:401|matching alias: ldapclient1
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.324 UTC|X509Authentication.java:242|ldapclient1 private or public key is not of EC algorithm
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.324 UTC|CertificateRequest.java:813|Unavailable authentication scheme: ecdsa_sha224
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.324 UTC|SunX509KeyManagerImpl.java:401|matching alias: ldapclient1
javax.net.ssl|FINE|01|main|2022-05-20 11:13:31.324 UTC|X509Authentication.java:242|ldapclient1 private or public key is not of EC algorithm
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.324 UTC|CertificateRequest.java:813|Unavailable authentication scheme: ecdsa_sha1
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.324 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.324 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_sha224
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.325 UTC|X509Authentication.java:215|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.325 UTC|CertificateRequest.java:813|Unavailable authentication scheme: rsa_pkcs1_sha1
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.325 UTC|X509Authentication.java:215|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.325 UTC|CertificateRequest.java:813|Unavailable authentication scheme: dsa_sha224
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.325 UTC|X509Authentication.java:215|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.325 UTC|CertificateRequest.java:813|Unavailable authentication scheme: dsa_sha1
javax.net.ssl|ALL|01|main|2022-05-20 11:13:31.325 UTC|X509Authentication.java:215|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.325 UTC|CertificateRequest.java:813|Unavailable authentication scheme: dsa_sha256
javax.net.ssl|WARNING|01|main|2022-05-20 11:13:31.326 UTC|CertificateRequest.java:823|No available authentication scheme
...
javax.net.ssl|FINE|01|main|2022-05-20 12:07:27.344 UTC|CertificateMessage.java:328|Produced client Certificate handshake message (
"Certificates": <empty list>
)

If I convert the certificate and key to jks and using the default SSLContextFactory than it is working.

The certificate is signed with ecdsa-with-SHA256.

Do you have any idea, what could be the problem?

Thanks

@ctron
Copy link
Owner

ctron commented May 20, 2022

Hm, not really. It looks good, except for the fact that it doesn't work.

I am not sure though I ever tested this with ECs. So that might be an issue.

I would recommend (and really appreciate it) it you could create a test for EC to the existing tests. That would most likely fail, but give us a reproducer and a future test once this is fixed.

@kolomparrudi kolomparrudi changed the title KayManager problem Problem with EC keys May 23, 2022
@kolomparrudi
Copy link
Author

Hi,

You are right, the problem is with the EC keys. When I print the
keyStoreForSASL.getKey(...).getAlgorithm() I got ECDSA
If I load it from JKS keystore I got EC.

Found similar issue and they found the problem in Bouncy Castle:
https://stackoverflow.com/questions/27743045/ec-private-key-recovery-from-pem-format-with-bouncycastle

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants