# Using client certificate for server authentication

**URL:** <https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85>\
**Category:** GENERAL\
**Created:** [January 27, 2021, 12:10pm UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85 "2021-01-27T12:10:30Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![peterkir](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/peterkir/32/28_2.png) [@peterkir](https://bnd.discourse.group/u/peterkir)\
**Post date:** [January 27, 2021, 12:10pm UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/1 "2021-01-27T12:10:30Z")

</div>

I’m trying to contact a maven repo which requires a custom client certificate.  
The documentation [-connection-settings | bnd](https://bnd.bndtools.org/instructions/connection-settings) 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.

```auto
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?

---

<div class="post-metadata">

**Author:** ![pkriens](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/pkriens/32/3_2.png) [@pkriens](https://bnd.discourse.group/u/pkriens)\
**Post date:** [January 27, 2021, 1:40pm UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/2 "2021-01-27T13:40:42Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![peterkir](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/peterkir/32/28_2.png) [@peterkir](https://bnd.discourse.group/u/peterkir)\
**Post date:** [February 8, 2021, 4:56am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/3 "2021-02-08T04:56:19Z")

</div>

Thx for the info Peter.  
I patched the `/biz.aQute.bndlib/src/aQute/bnd/http/HttpClient.java/getProxiedAndConfiguredConnection()`  
with this code.

```auto
...
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?

---

<div class="post-metadata">

**Author:** ![pkriens](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/pkriens/32/3_2.png) [@pkriens](https://bnd.discourse.group/u/pkriens)\
**Post date:** [February 8, 2021, 7:52am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/4 "2021-02-08T07:52:37Z")

</div>

This is just basic authentication, which is already supported by the [connection settings](https://bnd.bndtools.org/instructions/connection-settings.html)?

I am not sure I understand the relation to certificates?

---

<div class="post-metadata">

**Author:** ![peterkir](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/peterkir/32/28_2.png) [@peterkir](https://bnd.discourse.group/u/peterkir)\
**Post date:** [February 8, 2021, 8:00am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/5 "2021-02-08T08:00:32Z")

</div>

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`

---

<div class="post-metadata">

**Author:** ![pkriens](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/pkriens/32/3_2.png) [@pkriens](https://bnd.discourse.group/u/pkriens)\
**Post date:** [February 8, 2021, 8:25am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/6 "2021-02-08T08:25:06Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![peterkir](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/peterkir/32/28_2.png) [@peterkir](https://bnd.discourse.group/u/peterkir)\
**Post date:** [February 8, 2021, 9:56am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/7 "2021-02-08T09:56:21Z")

</div>

Thx, I will have a look.

---

<div class="post-metadata">

**Author:** ![kurthuwig](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/kurthuwig/32/120_2.png) [@kurthuwig](https://bnd.discourse.group/u/kurthuwig)\
**Post date:** [January 7, 2022, 8:27am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/8 "2022-01-07T08:27:38Z")

</div>

I’ve found a solution: in your `connection-settings.xml` you need to specify `<verify>true</verify>` and no `<trust>` like this:

```auto
<?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.

---

<div class="post-metadata">

**Author:** ![kurthuwig](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/kurthuwig/32/120_2.png) [@kurthuwig](https://bnd.discourse.group/u/kurthuwig)\
**Post date:** [January 7, 2022, 8:45am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/9 "2022-01-07T08:45:04Z")

</div>

Actually it is sufficient to have neither `<verify>` nor `<trust>` in your `connection-settings.xml`.

> <https://github.com/bndtools/bnd/issues/5034>
>
> 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\`.

---

<div class="post-metadata">

**Author:** ![pkriens](https://yyz2.discourse-cdn.com/free1/user_avatar/bnd.discourse.group/pkriens/32/3_2.png) [@pkriens](https://bnd.discourse.group/u/pkriens)\
**Post date:** [January 7, 2022, 9:21am UTC](https://bnd.discourse.group/t/using-client-certificate-for-server-authentication/85/10 "2022-01-07T09:21:04Z")

</div>

Thanks, I’ve updated the document connection-settings.md to explain this.
