Search code examples
javasslx509certificatebouncycastle

How to sign a certificate using BouncyCastle or Java 11


I've an existing certificate (C1), including private key, and not marked as a CA and trusted from an internal root-CA (C0) I want to use it to:

Client side:

  • Generate a new keypair (C2)
  • Sign the keypair using C1, so that it has validation path C2<C1<C0
  • Use C2 to perform SSL client auth

Server side:

  • Accept the SSL client cert
  • Validate the chain regardless of C1 not being a CA

So far I've found articles on how to use a generic key to sign a new key: Creating an X509 Certificate in Java without BouncyCastle?

However:

  • The resulting C2 is not trusted and thus not accepted when negotiating => We'll probably have to disable client cert validation on the apache side and perform it on the Java side
  • The above article hints at using private sun JDK methods: any hints on how to do that using standard jdk 11 classed or BouncyCastle?

Solution

  • As it is pointed out in comments by Boriss the Spider, certificate is not allowed to sign other certificates if any of the following conditions are not met:

    1. Certificate subject must be CA via Basic Constraints certificate extension. See my blog post on how basic constraints work in practice and how certificate chaining engine reacts to violation.
    2. Certificate must include certKeySign usage in Key Usage certificate extension

    Validate the chain regardless of C1 not being a CA

    it would be hard to disable basic constraints and key usage extension validation and retain other validation steps, this may require to disable client certificate validation at all. This is a simple PKI misuse that opens various vulnerabilities because you cannot implement proper certificate validation.