Giter VIP home page Giter VIP logo

Comments (5)

lalloni avatar lalloni commented on June 14, 2024 1

Well, after writing this feature request I went ahead and wrote the code I needed for my use case, so I can help working on the PR.

Regarding the proposed API, my specific use case was mTLS from the client side, with a server presenting certificates signed by well known CA, so I would have gotten away with only:

X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial("certificate.pem", "key.pem", "keyPassword");

SSLFactory sslFactory = SSLFactory.builder()
    .withIdentityMaterial(keyManager)
    .build()

SSLContext sslContext = sslFactory.getSslContext();

I checked your PR, and it won't work as is because it doesn't parse PEM-encoded encrypted private keys correctly. In my implementation I ended up using BouncyCastle PEM parser utilities to avoid reinventing the wheel in such an error-prone task.

Here's the gist of what I did:

var cf = CertificateFactory.getInstance("X.509");
var cert = cf.generateCertificate(new ByteArrayInputStream(config.getCert().getBytes()));
var pemParser = new PEMParser(new StringReader(config.getKey()));
var keyObject = (PEMEncryptedKeyPair) pemParser.readObject();
var keyPass = config.getKeyPass().toCharArray();
var keyBytes = keyObject.decryptKeyPair(new BcPEMDecryptorProvider(keyPass)).getPrivateKeyInfo().getEncoded();
var keySpec = new PKCS8EncodedKeySpec(keyBytes);
var key = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
var ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null);
ks.setKeyEntry(config.getClientId(), key, keyPass, new Certificate[]{cert});
return SSLContextBuilder.create().loadKeyMaterial(ks, keyPass).build();

Note that for my use case I do not read key/cert material from files but from configuration values because I prefer my users to use a single configuration file instead of having the configuration spread among several different files (which is other reason to support PEM because it is very nicely embedded in YAML configuration files as scalar blocks).

from sslcontext-kickstart.

lalloni avatar lalloni commented on June 14, 2024 1

For receiving key material in a generic way (values vs files) you'd probably simply consider accepting InputStream (or Reader) and leave the option of using files vs memory vs whatever to the caller.

from sslcontext-kickstart.

Hakky54 avatar Hakky54 commented on June 14, 2024

Hi @lalloni

Thank you for suggesting this feature to enrich the capabilities of the library! I really like the idea of supporting different formats such as PEM, DER or other formats. It would make it much easier for a-lot of developers to just pass some identity and trust material to the SSLFactory regardless of the format, in this case PEM format, to create the ssl objects for their http client or server.

Couple of months ago I did an attempt to support loading keypair and certificates in PEM format. Loading a certificate is quite easy. But loading the keypair is tough. So during my earlier attempts I couldn't achieve to load the keypair as a KeyManager and stopped working on it. Today, after you opened this issue, I did a new attempt and got some more progress. I will open a pull request, please let me know if the solution will work for you. See here for the details: Support for loading pem files

The usage could be:

X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial("identity.pem");
X509ExtendedTrustManager trustManager = PemUtils.loadTrustMaterial("github-certificate.pem", "stackexchange.pem");

SSLFactory sslFactory = SSLFactory.builder()
    .withIdentityMaterial(keyManager)
    .withTrustMaterial(trustManager)
    .build()

SSLContext sslContext = sslFactory.getSslContext();

from sslcontext-kickstart.

Hakky54 avatar Hakky54 commented on June 14, 2024

Thank you for your valuable input! I didn't thought about passing the key and certificate as a value instead of loading it from file. That would also be a good addition indeed, I need to think of a proper design and implementation for that use case.

Also your other remark is valid, the current implementation only supports an unencrypted private key and doesn't yet support an encrypted private key. That is still a quite difficult in my opinion but maybe I can get it working. Still investigating...

Thank you for sharing the BouncyCastle snippet for your use case. The library is great for handling complex stuff such as easily parsing pem files without introducing a-lot additional complexity to your code base, you did well for choosing for BC for your needs. I will have a look at their implementation how they handle it.

from sslcontext-kickstart.

Hakky54 avatar Hakky54 commented on June 14, 2024

Hey @lalloni I forgot to ping you, although you are already using your own solution I wanted to notify you regarding the current feature within this library. I don't think you would refactor your existing project, but it might be useful for other projects in the future.

It supports now unencrypted and encrypted private keys in PEM format. You can load these key materials from the classpath, anywhere from your files system or as an inputstream just how you suggested it so you can load it from your yaml file directly into the library.

from sslcontext-kickstart.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.