1

I'm running an OpenSCEP Server and try to enrol a certificate on an JSCEP-Client.

When it comes to the PKIOperation I end up with a request like this

http://[my_openscep_server]/cgi-bin/pkiclient.exe?operation=PKIOperation&message=%5BB%406c4cbf96

where the message is obviously not correct, but I don't know why.

I took jscep-2.0.2-sources, bcpkix-jdk15on-1.50.jar and bcprov-jdk15on-1.50.jar. The JSCEP-documentation does not seem to fit the version so the current Test-code, created with input from various sources, looks like this:

    URL server = new URL("http://[my_openscep_server]/cgi-bin/pkiclient.exe");

    KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
    char[] keyPw = "somePW".toCharArray();
    SecretKeyFactory factory = SecretKeyFactory.getInstance(FACTORY_ALGORITHM, PROVIDER);
    KeySpec spec = new PBEKeySpec(keyPw, SecureRandom.getSeed(50), 65536, 128);
    SecretKey tmp = factory.generateSecret(spec);

    KeyStore ks = KeyStore.getInstance("JCEKS", "SunJCE");
    ks.load(null, keyPw);
    ks.setEntry("someAlias", new SecretKeyEntry(tmp), new KeyStore.PasswordProtection(keyPw));

    X500Name entityName = new X500Name("DN=someDN");

    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.HOUR, -1);
    Date notBefore = calendar.getTime();

    calendar.add(Calendar.HOUR, 4);
    Date notAfter = calendar.getTime();

    X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(entityName, BigInteger.valueOf(
            new Date().getTime()).abs(), notBefore, notAfter, entityName, SubjectPublicKeyInfo.getInstance(keyPair
            .getPublic().getEncoded()));

    ContentSigner cs = new JCESigner(keyPair.getPrivate(), "SHA256withRSA");
    byte[] certBytes = certBuilder.build(cs).getEncoded();
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(new ByteArrayInputStream(certBytes));

    PKCS10CertificationRequestBuilder crb = new JcaPKCS10CertificationRequestBuilder(
    certificate.getSubjectX500Principal(), keyPair.getPublic());
    PKCS10CertificationRequest csr = crb.build(cs);

    // Send the enrolment request
    CallbackHandler handler = new DefaultCallbackHandler(new ConsoleCertificateVerifier());

    Client client = new Client(server, handler);
    client.enrol(certificate, keyPair.getPrivate(), csr);

This is the JCESigner-class:

private static class JCESigner implements ContentSigner {

    private static final AlgorithmIdentifier PKCS1_SHA256_WITH_RSA_OID = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.1.1.11"));

    private Signature signature;
    private ByteArrayOutputStream outputStream;

    public JCESigner(PrivateKey privateKey, String signatureAlgorithm) {
        if (!"SHA256withRSA".equals(signatureAlgorithm)) {
            throw new IllegalArgumentException("Signature algorithm \"" + signatureAlgorithm + "\" not yet supported");
        }
        try {
            this.outputStream = new ByteArrayOutputStream();
            this.signature = Signature.getInstance(signatureAlgorithm);
            this.signature.initSign(privateKey);
        } catch (GeneralSecurityException gse) {
            throw new IllegalArgumentException(gse.getMessage());
        }
    }

    @Override
    public AlgorithmIdentifier getAlgorithmIdentifier() {
        if (signature.getAlgorithm().equals("SHA256withRSA")) {
            return PKCS1_SHA256_WITH_RSA_OID;
        } else {
            return null;
        }
    }

    @Override
    public OutputStream getOutputStream(){

        return this.outputStream;
    }

    @Override
    public byte[] getSignature(){

        byte[] result = null;
        try{
             result = this.signature.sign();
        }
        catch(SignatureException e){

            System.err.println(e.getMessage());
        }

        return result;
    }
}

This is the log after GetCACert:

8644 [main] DEBUG org.jscep.client.Client  - Certificate verification passed.
8644 [main] DEBUG org.jscep.client.Client  - Verifying signature of RA certificate
8644 [main] DEBUG org.jscep.client.Client  - RA and CA are identical
8644 [main] DEBUG org.jscep.client.Client  - Verifying signature of RA certificate
8644 [main] DEBUG org.jscep.client.Client  - RA and CA are identical
8675 [main] DEBUG org.jscep.client.Client  - Determining capabilities of SCEP server
8675 [main] DEBUG org.jscep.transport.UrlConnectionGetTransport  - Sending GetCACaps  to http://[my_openscep_server]/cgi-bin/pkiclient.exe?operation=GetCACaps&message=
8707 [main] DEBUG org.jscep.transport.UrlConnectionGetTransport  - Received '500 Internal Server Error' when sending GetCACaps to http://[my_openscep_server]/cgi-bin/pkiclient.exe?operation=GetCACaps&message=
8707 [main] WARN  org.jscep.client.Client  - AbstractTransport problem when determining capabilities.  Using empty capabilities.
8707 [main] INFO  org.jscep.client.Client  - MD5 PKCS#10 Fingerprint: [[e, c, 1, d, a, f, e, 0, c, 9, a, 6, 7, 6, 7, b, 2, e, a, 0, 7, e, b, 0, 5, 4, 8, e, a, d, 8, 2]]
8707 [main] DEBUG org.jscep.message.PkiMessageEncoder  - Encoding pkiMessage
8723 [main] DEBUG org.jscep.message.PkiMessageEncoder  - Encoding message: org.jscep.message.PkcsReq@539b2f32[transId=7f5b59f959ca41e337566ffff1d2bcb79033b377,messageType=PKCS_REQ,senderNonce=Nonce [[C@5a97618e],messageData=org.bouncycastle.pkcs.PKCS10CertificationRequest@405b4828]
8723 [main] DEBUG org.jscep.message.PkcsPkiEnvelopeEncoder  - Encoding pkcsPkiEnvelope
8739 [main] DEBUG org.jscep.message.PkcsPkiEnvelopeEncoder  - Encrypting pkcsPkiEnvelope using key belonging to [dn=[my_ca_dn], CN=[my_ca_cn], OU=[my_ca_ou], O=[my_ca_o], ST=[my_ca_st], C=[my_ca_c]; serial=[my_ca_serial]]
8941 [main] DEBUG org.jscep.message.PkcsPkiEnvelopeEncoder  - Finished encoding pkcsPkiEnvelope
8941 [main] DEBUG org.jscep.message.PkiMessageEncoder  - CMSEnvelopedData: org.bouncycastle.cms.CMSEnvelopedData@1683d070
8941 [main] DEBUG org.jscep.message.PkiMessageEncoder  - Signing pkiMessage using key belonging to [dn=CN=golan.ispin.ch; serial=1395903633577]
8957 [main] DEBUG org.jscep.message.PkiMessageEncoder  - Signing org.bouncycastle.cms.CMSProcessableByteArray@38a68a10 content
8973 [main] DEBUG org.jscep.message.PkiMessageEncoder  - Finished encoding pkiMessage
8973 [main] DEBUG org.jscep.message.PkiMessageEncoder  - pkiMessage: [B@33daf0bf
8973 [main] DEBUG org.jscep.transaction.EnrollmentTransaction  - Sending [B@6af3a631
8973 [main] DEBUG org.jscep.transport.UrlConnectionGetTransport  - Sending org.bouncycastle.cms.CMSSignedData@22b64866 to http://[my_openscep_server]/cgi-bin/pkiclient.exe?operation=PKIOperation&message=%5BB%406c4cbf96
9019 [main] DEBUG org.jscep.transport.UrlConnectionGetTransport  - Received '500 Internal Server Error' when sending org.bouncycastle.cms.CMSSignedData@22b64866 to http://[my_openscep_server]/cgi-bin/pkiclient.exe?operation=PKIOperation&message=%5BB%406c4cbf96

This is from the apache error-log, coming from the OpenSCEP-server:

scepd.c:93: cleared scep structure
init.c:70: crypto strings loaded
init.c:74: openscep strings loaded
init.c:81: algorithms added
init.c:87: random source seeded
init.c:95: stderr BIO initialized
init.c:103: added oid 2.16.840.1.113733.1.9.2 for name messageType
init.c:103: added oid 2.16.840.1.113733.1.9.3 for name pkiStatus
init.c:103: added oid 2.16.840.1.113733.1.9.4 for name failInfo
init.c:103: added oid 2.16.840.1.113733.1.9.5 for name senderNonce
init.c:103: added oid 2.16.840.1.113733.1.9.6 for name recipientNonce
init.c:103: added oid 2.16.840.1.113733.1.9.7 for name transId
init.c:103: added oid 2.16.840.1.113733.1.9.8 for name extensionReq
init.c:103: added oid 1.3.6.1.4.1.4263.5.5 for name proxyAuthenticator
scepd.c:99: initialized libraries
scepd.c:114: config file is /usr/local/lib/openscep/openscep.cnf
init.c:151: conf sets debug to 2
init.c:157: name: OpenSCEP
init.c:174: CA certificate from /usr/local/lib/openscep/cacert.pem read
init.c:189: CA private key from /usr/local/lib/openscep/cakey.pem read
init.c:204: CA CRL from /usr/local/lib/openscep/crl.pem read
init.c:214: LDAP parameters ldap://[my_ldap_server], base [my_ldap_base], bind as [my_ldap_user]
init.c:227: automatic mode enabled
init.c:250: proxy community is 'cvurg3nfnbvbt75'
scepldap.c:192: LDAP [my_ldap_server] initialized
scepldap.c:204: LDAP bind complete
scepd.c:136: writing chunk ofsize 11
scepd.c:139: no more data from inbio
decode.c:58: decoding request message
decode.c:65: prepending Base64 decoder
decode.c:82: decoded data at 0x0: 0 bytes
decode.c:106: cannot decode message
decode.c:463: error return from decode
140444998489768:error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data:a_d2i_fp.c:175:
scepd.c:151: decode failed
Premature end of script headers: pkiclient.exe

Any hints would be appreciated.

jww
  • 97,681
  • 90
  • 411
  • 885
pma
  • 860
  • 1
  • 9
  • 26
  • `decode.c:82: decoded data at 0x0: 0 bytes` - seems like the server receives empty value (empty base64 string?) instead of whatever it expects at that point. – Oleg Estekhin Mar 27 '14 at 08:25
  • "message=%5BB%406c4cbf96" - that looks like a password, and not a message. It URL decodes to `[B@6c4cbf96`. – jww Mar 27 '14 at 10:18
  • @OlegEstekhin yes, the request is supposed to have a bigger value for the message-parameter, that's the actual problem – pma Mar 27 '14 at 11:24
  • @noloader it is the result of `org.jscep.message.PkiMessageEncoder.encode(final PkiMessage> message)`. The provided message looks bigger to me, as can be seen in `8723 [main] DEBUG org.jscep.message.PkiMessageEncoder - Encoding message: org.jscep.message.PkcsReq@539b2f32[transId=7f5b59f959ca41e337566ffff1d2bcb79033b377,messageType=PKCS_REQ,senderNonce=Nonce [[C@5a97618e],messageData=org.bouncycastle.pkcs.PKCS10CertificationRequest@405b4828]` but I'm having difficulties to debug what exactly happens in the bouncycastle-classes that are involved (or if my input is not correct). – pma Mar 27 '14 at 11:31
  • 1
    %5BB%406c4cbf96 is the default string representation of byte array, meaning that you use something like `byteArray.toString()`. Instead you should Base64-encode the byte array on the sending side and Base64-decode on the receiving side, or may be even switch to POST method and send the binary data in the body of the POST request. – Oleg Estekhin Mar 27 '14 at 11:35
  • @OlegEstekhin you are right, there was `Base64.encodeBase64(msgData.getEncoded()).toString();` in the PkiOperationRequest-class of jscep. I have replaced it with `new String(Base64.encodeBase64(msgData.getEncoded()));` now the request looks much better. The server is still having problems with it though, and unfortunately my C knowledge is close to 0... Anyway, thanks a lot! – pma Mar 27 '14 at 12:01
  • @pma - You beat me to it :) +1. – jww Mar 27 '14 at 19:10

0 Answers0