swagger-api / swagger-api/swagger-codegen

[JAVA]sslCaCert InputStream is getting exhausted when loading SSLCerts in ApiClient.java/apiclient.mustache

Open
#7,719 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

in ApiClient.java/apiclient.mustache applySslSettings() is called when ever we set sslCerts||verifySSL||keyManagers.
if we form ApiClient object like following

 ApiClient client=  new ApiClient()
		 .setBasePath("https://192.168.42.250:8443")
		 .setSslCaCert(new ByteArrayInputStream(caSSLcert))
		 .setKeyManagers(SSLUtils.keyManagers(clientcert, clientKey, "RSA", "", null, null))
		 .setVerifyingSsl(true);

applySslSettings() will be called multiple times, but will fail(at setkeyManagers()) saying

Exception in thread "main" java.lang.IllegalArgumentException: expected non-empty set of trusted certificates
	at io.kubernetes.client.ApiClient.applySslSettings(ApiClient.java:1130)
	at io.kubernetes.client.ApiClient.setKeyManagers(ApiClient.java:219)
	at io.kubernetes.client.examples.Example.main(Example.java:57)

sslCaCert will get exhausted after setSslCert() call and when setKeyManagers() is called it fails.

we have observed this issue in kubernetes java client:
we have ClientBuilder class which Builds APiClient.

Swagger-codegen version

i believe its 2.3.0 ( https://github.com/kubernetes-client/java/blob/master/kubernetes/.swagger-codegen/VERSION)

Swagger declaration file content or url

https://raw.githubusercontent.com/kubernetes-client/java/master/kubernetes/swagger.json

Related issues/PRs

This has been observed in https://github.com/kubernetes-client/java/issues/199 by @brendandburns

Suggest a fix/enhancement

In apiclient.mustache
either make a clone of sslCaCert and pass the clone to generateCertificates(sslCaCert);

 private void applySslSettings() {
.
.
.
else if (sslCaCert != null) {
byte[] targetArray = null ;
        try {
          targetArray = new byte[sslCaCert.available()];
          sslCaCert.read(targetArray);
        }
        catch(Exception e) {
        }
        sslCaCert = new ByteArrayInputStream(targetArray);
        char[] password = null; // Any password will work.
        InputStream sslCaCertCopy =  new ByteArrayInputStream(targetArray);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(sslCaCertCopy);
.
.
.

or instead of using InputStream, can use byte[] in setters for sslcaCerts and just convert to InputStream before passing it to certificateFactory.generateCertificates()

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apiclient.mustache and the generated ApiClient.java, focusing on applySslSettings() and the setSslCaCert(), setKeyManagers(), and setVerifyingSsl() calls. Reproduce the chained setter example with the Java client and trace how sslCaCert is consumed. Done means applying SSL settings repeatedly no longer exhausts the certificate stream or raises the empty trusted-certificates error.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.