Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle SCEP PKI message in POST request body #542

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

borama
Copy link
Contributor

@borama borama commented Aug 30, 2020

This is a minimal implementation of parsing the SCEP PKI message from the body of the request. When a POST request is received in the servlet, the code expects binary data in the POST body and tries to parse it into the message, which is then handled the same way as the message from a GET parameter.

I am not sure whether Dogtag uses POST requests in the servlet internally but if it does, it might bring problems as reading the body clashes with current code for determining the parameters (AFAIK, the body of a servlet request may be read only once and both the new code as well as the current code in the toHashTable method try to read the request body). Ideally, we should only read POST body when the application/x-pki-message content_type is present in the request but in reality it seems that many SCEP clients don't do that.

If the SCEP request is a HTTP POST request, we try to read the message as a binary string from the request body as outlined in https://tools.ietf.org/html/draft-gutmann-scep-16#section-4.3.

Note that the content type is ignored here - all POST request are processed this way which may cause problems when parameters are sent as form values in the body.
@cipherboy
Copy link
Member

\o hey @borama -- sorry, we've been a bit busy. Hope to take a look at it by late next week. :)

@borama
Copy link
Contributor Author

borama commented Sep 8, 2020

Hi @cipherboy, sure, no worries, thanks!

Copy link
Contributor

@ladycfu ladycfu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution. I only have two comments, and I am soliciting @edewata 's and @cipherboy 's input and let them have the final call on whether changes are needed.
Otherwise, I have tested this patch with curl post and seems to work as expected.

String message = null;

try {
if (httpReq.getMethod().equalsIgnoreCase("POST")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a style thing. Personally, I'd put the the check on the method (POST or GET) outside of this method and branch on how each method retrieves its message. But I'll let our our refactor expert @edewata chip in on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too familiar with SCEP. Does it support both POST and GET? In general if POST and GET are handled differently I'd suggest putting them into separate doPost() and doGet() methods.

try {
if (httpReq.getMethod().equalsIgnoreCase("POST")) {
ServletInputStream is = httpReq.getInputStream();
ByteArrayOutputStream bstream = new ByteArrayOutputStream(10000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an attempt to limit the size of the input data? If so, I don't think it'd work as the buffer will grow as needed for ByteArrayOutputStream. Now the question is on whether we want to set a limit on the input data. Any suggestion, @cipherboy or @edewata ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this will limit the input data, but since the try-catch block surrounding this code will discard the exception, I'm not quite sure what would happen if the limit is exceeded, whether it will fall back to the old behavior or completely fail. IIUC the getParameter() cannot be called after getInputStream(), so it might completely fail.

Is there a defined limit on the size of a valid SCEP input?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we pull Commons IO, do we want to use IOUtil.Copylarge?

message = Utils.base64encode(bstream.toByteArray(), false);
}
} catch (IOException e) {
logger.warn("CSREnrollment: exception while reading POST body: " + e.getMessage(), e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general we don't want to catch and discard exceptions since it would make it harder to troubleshoot issues. I'd suggest to wrap and rethrow the exception like this:

throw new ServletException(e);

try {
if (httpReq.getMethod().equalsIgnoreCase("POST")) {
ServletInputStream is = httpReq.getInputStream();
ByteArrayOutputStream bstream = new ByteArrayOutputStream(10000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this will limit the input data, but since the try-catch block surrounding this code will discard the exception, I'm not quite sure what would happen if the limit is exceeded, whether it will fall back to the old behavior or completely fail. IIUC the getParameter() cannot be called after getInputStream(), so it might completely fail.

Is there a defined limit on the size of a valid SCEP input?

String message = null;

try {
if (httpReq.getMethod().equalsIgnoreCase("POST")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too familiar with SCEP. Does it support both POST and GET? In general if POST and GET are handled differently I'd suggest putting them into separate doPost() and doGet() methods.

@cipherboy cipherboy removed their request for review February 4, 2022 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants