Skip to content

improve EVP cipher param diagnostics on unsupported cipher modes and malloc failure#6217

Closed
DDvO wants to merge 4 commits intoopenssl:masterfrom
siemens:EVP_cipher_param_diagnostics
Closed

improve EVP cipher param diagnostics on unsupported cipher modes and malloc failure#6217
DDvO wants to merge 4 commits intoopenssl:masterfrom
siemens:EVP_cipher_param_diagnostics

Conversation

@DDvO
Copy link
Contributor

@DDvO DDvO commented May 10, 2018

When trying to use PKCS12_create() with NID_aes_256_gcm I got rather inaccurate and even misleading diagnostics:

2147483656:error:0D0A7072:asn1 encoding routines:PKCS5_pbe2_set_iv:error setting cipher params:crypto/asn1/p5_pbev2.c:82:
2147483656:error:2307D00D:PKCS12 routines:PKCS8_encrypt:ASN1 lib:crypto/pkcs12/p12_p8e.c:32:
2147483656:error:23085041:PKCS12 routines:PKCS12_SAFEBAG_create_pkcs8_encrypt:malloc failure:crypto/pkcs12/p12_sbag.c:157:

It took me a little while to find out that the actual problem is that GCM (and also some other block cipher modes) are simply not supported here, which is a long-standing issue reported and discussed for instance at https://security.stackexchange.com/questions/83384/creating-a-private-key-with-openssl-and-encrypting-it-with-aes-gcm and https://groups.google.com/forum/#!topic/mailing.openssl.users/hGggWxfrZbA

This PR adds a distinction between unsupported cipher modes and other errors when converting between EVP cipher params and ASN.1, updating and slightly extending the documentation. It also replaces in the genpkey app these low-level error(s) by a more telling high-level error message and fixes the comparisons for error detection in a couple of calls to EVP_CIPHER_asn1_to_param() and EVP_CIPHER_param_to_asn1().

I also removed two needless and misleading malloc failure error messages of PKCS12_SAFEBAG_create_pkcs8_encrypt().
BTW, I wonder why malloc failures are not simply reported once and for all by CRYPTO_malloc() itself and instead the burden is put on the callers. There are presumably many instances like the ones I fixed here where a NULL pointer result is misinterpreted to be due to an out-of-memory condition, and very likely there are even much more cases where malloc failures are caught but not reported.

I also added a type cast in setup_tests() of test/x509aux.c preventing a compiler warning for the VC-WIN64A architecture (which is an unrelated very minor issue for which I thought it is not worth providing a separate PR).

Checklist
  • documentation is added or updated

Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

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

Approved assuming CIs pass

@mattcaswell mattcaswell added branch: master Applies to master branch approval: review pending This pull request needs review by a committer branch: 1.1.1 Applies to OpenSSL_1_1_1-stable branch (EOL) labels May 11, 2018
Copy link
Contributor

@richsalz richsalz left a comment

Choose a reason for hiding this comment

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

that if/test is indented wrong :) but okay.

@richsalz richsalz added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels May 11, 2018
@DDvO
Copy link
Contributor Author

DDvO commented May 11, 2018

A related general question also here:

I wonder why malloc failures are not simply reported once and for all by CRYPTO_malloc() itself and instead the burden is put on the callers. There are presumably many instances like the ones fixed in this PR where a NULL pointer result is misinterpreted to be due to an out-of-memory condition, and very likely there are even much more cases where malloc failures are caught but not reported.

@mattcaswell
Copy link
Member

I wonder why malloc failures are not simply reported once and for all by CRYPTO_malloc() itself and instead the burden is put on the callers. There are presumably many instances like the ones fixed in this PR where a NULL pointer result is misinterpreted to be due to an out-of-memory condition, and very likely there are even much more cases where malloc failures are caught but not reported.

I suppose, in theory, a malloc failure could either be because the system is running low on memory, or the call to CRYPTO_malloc() was erroneous (e.g. because it incorrectly attempts to allocate a vast amount of memory). In the second case this kind of problem would be difficult to find if all you have is the error code in CRYPTO_malloc itself.

@DDvO
Copy link
Contributor Author

DDvO commented May 11, 2018

Thanks Matt for your response.

In my question I should have consistently written 'malloc failure' (and not partly written 'out-of-memory') because I was not after a distinction between specific failure reasons.
My aim was/is to understand why CRYTPO_malloc does not report the failure (no matter for what reason) in the OpenSSL error queue itself but relies on all callers to do so.
If CRYTPO_malloc did the reporting itself, this would relieve the callers from reporting the failure and eliminate the risk of callers doing wrong here (like not reporting or wrongly reporting the malloc failure). Moreover, CRYPTO_malloc could be more specific on the failure reason (simply because it should know better than its callers what exactly went wrong and why).

@richsalz
Copy link
Contributor

If we had an error API that let you specify the file and line number we could use that in malloc, since it gets those line/file as parameters.

But there's also the issue in that the ERR code uses malloc, and we need to avoid the loop.

@mattcaswell
Copy link
Member

If we had an error API that let you specify the file and line number we could use that in malloc, since it gets those line/file as parameters.

ERR_PUT_error()?

@DDvO
Copy link
Contributor Author

DDvO commented May 11, 2018

But there's also the issue in that the ERR code uses malloc, and we need to avoid the loop.

That's a point, Yet one could implement the ERR queue such that there is always an element pre-allocated&reserved for use by CRYPTO_malloc, such that in case this function adds an entry (possibly by using a specific function) there is no need to (recursively) allocate it.

@DDvO
Copy link
Contributor Author

DDvO commented May 11, 2018

With the approach I just sketched, of course the queue cell should be reserved for actual out-of-memory situations only (and not any other potential failures of CRYPTO_malloc). When this reserved cell has been filled, any further requests to add elements to the ERR queue should be ignored in case the queue is full and would need re-allocation - I think this would be acceptable because at least from the lib's point of view an out-of-memory condition would be fatal anyway.

@richsalz
Copy link
Contributor

Too late for 1.1.1 to change the ERR queue stuff. Can you copy the relevant comments about that into a new issue?

@DDvO
Copy link
Contributor Author

DDvO commented May 11, 2018

Sure, will do soon.
I see no urgent need here anyway; this was just a general thought for a useful improvement.
I just checked: currently there are 900 (!) ERR calls for the ERR_R_MALLOC_FAILURE reason.

@mspncp
Copy link
Contributor

mspncp commented May 11, 2018

I just checked: currently there are 900 (!) ERR calls for the ERR_R_MALLOC_FAILURE reason.

FYI: Many of them were added only recently:

fe1128d Fix last(?) batch of malloc-NULL places
f06080c Add missing error code when alloc-return-null
f90bc6c Add missing malloc-return-null instance
7fcdbd8 X509: add more error codes on malloc or sk_TYP_push failure
7de2b9c Set error code if alloc returns NULL
6b49b30 Prevent a possible recursion in ERR_get_state and fix the problem that was pointed out in commit aef84bb differently.
cdb10ba Set error code on alloc failures

@mspncp
Copy link
Contributor

mspncp commented May 11, 2018

My aim was/is to understand why CRYTPO_malloc does not report the failure (no matter for what reason) in the OpenSSL error queue itself but relies on all callers to do so.

IIRC, the entire discussion about the malloc error codes started way back in #5781, which triggered a sequence of pull requests. There was even a discussion in that thread about doing the reporting in CRYPTO_malloc() itself, using file and line information provided by the caller. I don't really remember, why that thought was discarded at that time.

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2018

Thanks a lot @mspncp for pointing out this related discussion and the number of recent commits.
A pity that all this work has been invested going IMHO in a non-optimal direction.
Yet the two misplaced ERR_R_MALLOC_FAILURE removed in this PR apparently were introduced earlier, by

425f3300072 (Dr. Stephen Henson 2015-09-27 13:42:04 +0100 157)

who should have known better that ...

  • if there is actually a malloc failure in the functions called by PKCS12_SAFEBAG_create_pkcs8_encrypt(), the intermediate (ASN.1) functions already flag this failure with reason ERR_R_MALLOC_FAILURE, and thus it is is superfluous to do that again in PKCS12_SAFEBAG_create_pkcs8_encrypt()
  • there are also other reasons for p8 and bag to get NULL assigned, and in these cases the reason ERR_R_MALLOC_FAILURE is simply wrong.

@DDvO
Copy link
Contributor Author

DDvO commented May 14, 2018

Further, more general discussion on this topic has been started in issue #6251.

@kroeckx
Copy link
Member

kroeckx commented Jun 16, 2018

What is the status of this PR? Can it be merged?

@DDvO
Copy link
Contributor Author

DDvO commented Jun 16, 2018

Good reminder. Looks like the actual PR got buried under the more general discussion that it brought up, which has then been moved to a new thread.
Yes, at least in my view this could be merged; there are also two reviews with positive outcome.

@mattcaswell
Copy link
Member

Pushed. Thanks.

levitte pushed a commit that referenced this pull request Jun 18, 2018
…2_SAFEBAG_create_pkcs8_encrypt

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #6217)
levitte pushed a commit that referenced this pull request Jun 18, 2018
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #6217)
levitte pushed a commit that referenced this pull request Jun 18, 2018
…architecture

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #6217)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: done This pull request has the required number of approvals branch: master Applies to master branch branch: 1.1.1 Applies to OpenSSL_1_1_1-stable branch (EOL)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants