I’m trying to contact a maven repo which requires a custom client certificate.
The documentation -connection-settings | bnd is not mentioning anything on it.
In a pure Java example I can configure the system props and provide a default Authenticator and it works.
System.getProperties().put("javax.net.ssl.keyStoreType", "pkcs12");
System.getProperties().put("javax.net.ssl.keyStore","keystore.pfx");
System.getProperties().put("javax.net.ssl.keyPassword", "pw");
System.getProperties().put("javax.net.ssl.keyStorePassword", "pw");
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USER, PW.toCharArray());
}
});
Is this feasible available for bnd?
Unfortunately not … yet. It has been on my list for a long time. You could try to provide the information with the -D when bnd is invoked. You can do this at Eclipse startup and Gradle.
Thx for the info Peter.
I patched the /biz.aQute.bndlib/src/aQute/bnd/http/HttpClient.java/getProxiedAndConfiguredConnection()
with this code.
...
matching.handle(urlc);
if (Boolean.valueOf(System.getProperty("bnd.basicAuth")) == true) {
logger.debug("using basic auth");
String user = System.getProperty("bnd.basicAuthUser");
String pw = System.getProperty("bnd.basicAuthPassword");
String userpass = user + ":" + pw;
String basicAuth = "Basic " + new String(Base64.getEncoder()
.encode(userpass.getBytes()));
urlc.setRequestProperty("Authorization", basicAuth);
}
return urlc;
giving me the option to add a basic auth feature via sys props.
Together with the javax.net.ssl.* sys props it works then.
What would be your approach to add this feature permanently?
This is just basic authentication, which is already supported by the connection settings ?
I am not sure I understand the relation to certificates?
It looks as there is a combination of connection settings (e.g. suspect is the verify
) and javax.net.ssl
properties which are not working. I will try to investigate it more and hopefully provide a testcase for /biz.aQute.bndlib.comm.tests/test/aQute/bnd/comm/tests/HttpClientTest.java
You might want to look at aQute.bnd.url.HttpsVerification
. It already does some certificate handling to verify the host and it creates its own SSL socket factory.
I’ve found a solution: in your connection-settings.xml
you need to specify <verify>true</verify>
and no <trust>
like this:
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<servers>
<server>
<id>https://nexus3.huwig.de</id>
<username>kurthuwig</username>
<password>XXX</password>
<verify>true</verify>
</server>
</servers>
</settings>
This is the only combination - besides no settings at all - that uses the default Http handler and thus allows client certificates to be sent.
Actually it is sufficient to have neither <verify>
nor <trust>
in your connection-settings.xml
.
opened 08:28AM - 07 Jan 22 UTC
If you need to use both a TLS client certificate and basic auth to authenticate … to your maven repository (e.g. Nexus 3), then you need to be extra cautious:
In `src/aQute/bnd/connection/settings/ConnectionSettings.java` this code decides what to do:
// verify=false, trust.isEmpty -> void default check
// verify=false, !trust.isEmpty -> ignore
// verify=true, trust.isEmpty -> use default check
// verify=true, !trust.isEmpty -> verify against given certs
boolean hasCerts = serverDTO.trust != null && !serverDTO.trust.isEmpty();
if (serverDTO.verify == false || hasCerts)
https = new HttpsVerification(serverDTO.trust, serverDTO.verify, processor);
else
https = null; // verify & no certs ==> default
So if either there is a `<verify>false</verify>` or there is a `<trust>...</trust>` then the own `HttpsVerification` is used which does not support TLS client authentication.
To reproduce:
1. Configure gradle to use TLS client certificates:
systemProp.javax.net.ssl.keyStoreType=pkcs12
systemProp.javax.net.ssl.keyStore=/home/kurt/SSL/keystore.p12
systemProp.javax.net.ssl.keyStorePassword=XXX
2. Configure `connection-settings.xml` to either have a `<verify>false</verify>` entry or have a `<trust>` entry.
3. try to download dependencies with a gradle build
Expected result:
Dependencies are downloaded
Actual result:
TLS client certificates are not sent => server denies access.
Workaround:
Don't have `<verify>` or `<trust>` entries in your `connection-settings.xml`.
Thanks, I’ve updated the document connection-settings.md to explain this.