I discovered an interoperability problem between the JSCEP Client and the JDK.
The HttpURLConnection implementation contains some code like this:
if (!method.equals("PUT") && (poster != null || streaming()))
requests.setIfNotSet ("Content-type", "application/x-www-form-urlencoded");
The JSCEP Client does not set Content-Type on the POSTs it makes to the SCEP server.
Because the Content-Type is force-set by the implementation code, Tomcat and other servlet containers will attempt to decode and process the data as if it were URL encoded. But because it's actually binary SCEP data this is going to fail, and when it does, Tomcat deletes the POST body from its own Request objects, which makes it impossible to handle the request in the server side.
Unfortunately the SCEP RFC draft does not specify what Content-Type to use when performing the POST upstream.
I did report the JDK's bug to Oracle here:
But that will probably take a long time to get addressed. So I am hoping it would be possible to request a new version of JSCEP, which allows some way to set the Content-Type to be set from outside, so I could try different values, to find one which is interoperable across both sides, or, at least, try setting it to application/x-pki-message .
RFC 2616 appears to recommend "application/octet-stream":
Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource. If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream".
Sets the content type to application/octet-stream for POST requests.