1

I am trying to sign a pkcs10 request using bouncy castle in Java. The resulting cert will be used in a two-way ssl scenario. I've looked through and tried many of the examples on this and other sites, but I always end up get the following when trying to connect my client to the server:

--java--

org.springframework.web.client.ResourceAccessException: 
I/O error on GET request for "https://localhost:8443/resources/1":
Received fatal alert: certificate_unknown;
nested exception is javax.net.ssl.SSLHandshakeException:
Received fatal alert: certificate_unknown

--openssl--

$ openssl s_client -connect localhost:8443 -CAfile ca.crt -cert client.crt -key client.key -pass pass:password -showcerts
CONNECTED(00000003)
depth=1 /C=xx/ST=xx/L=xx/O=xxxx/OU=xxxx/CN=xxxx/emailAddress=xxxx@xxxx.com
verify return:1
depth=0 /C=xx/ST=xx/L=xx/O=xxxx/OU=xxxx/CN=localhost/emailAddress=xxxx@xxxx.com
verify return:1
76234:error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown:
/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098
-59.40.2/src/ssl/s3_pkt.c:1145:SSL alert number 46
76234:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:
/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.40.2/src/ssl/s23_lib.c:185:

I've made many attempts with bouncy castle, but here is one attempt just as an example:

public Certificate signCertificateSigningRequest(PKCS10CertificationRequest certificationRequest,
        Certificate caCertificate, PrivateKey caPrivateKey) throws Exception {
    X500Name issuer = getX500Name("xxxx");
    Calendar notBefore = Calendar.getInstance();
    notBefore.add(Calendar.DATE, -1);
    Calendar notAfter = Calendar.getInstance();
    notAfter.add(Calendar.YEAR, 3);
    X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(
        issuer,
        BigInteger.valueOf(3),
        notBefore.getTime(),
        notAfter.getTime(),
        certificationRequest.getSubject(),
        certificationRequest.getSubjectPublicKeyInfo()
    );
    X509CertificateHolder certHolder = certGen
        .build(new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(caPrivateKey));
    X509Certificate certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
    return certificate;
}

What I would like is the bouncy castle equivalent of the following openssl command which I know works:

$ openssl \
x509 \
-req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-passin pass:password \
-CAcreateserial \
-sha256 \
-out client.crt \
-days 3650

This has been driving me nuts. Any help would be much appreciated. Thanks.

leetstap
  • 41
  • 2

1 Answers1

2

I found the answer here: X509 certificate signed with bouncy castle is not valid

The answer had to do with the issuer given to the X509v3CertificateBuilder. The issuer return by getX500Name("xxxx") should be identical to the one that generated the cert, but I guess it isn't. I had to change:

X500Name issuer = getX500Name("xxxx");

to:

X500Name issuer = X500Name.getInstance(((X509Certificate)caCertificate).getSubjectX500Principal().getEncoded());

and now it works fine.

Community
  • 1
  • 1
leetstap
  • 41
  • 2