Skip to content

ASN.1: Refuse to encode to DER if non-optional items are missing [3.0]#16036

Closed
levitte wants to merge 6 commits intoopenssl:masterfrom
levitte:fix-16026
Closed

ASN.1: Refuse to encode to DER if non-optional items are missing [3.0]#16036
levitte wants to merge 6 commits intoopenssl:masterfrom
levitte:fix-16026

Conversation

@levitte
Copy link
Member

@levitte levitte commented Jul 9, 2021

Fixes #16026

@levitte levitte added branch: master Applies to master branch approval: review pending This pull request needs review by a committer labels Jul 9, 2021
@levitte levitte added this to the 3.0.0 milestone Jul 9, 2021
levitte added 4 commits July 9, 2021 09:08
…tent

The test case creates an RSA public key and tries to pass it through
i2d_PrivateKey().  This SHOULD fail, since the private bits are missing.
ASN1_FBOOLEAN is designed to use as a default for optional ASN1 items.
This test program used it for non-optional items, which doesn't encode
well.
Make it only report (and fail on) encoding/decoding failures when success
is expected.
@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

This is like #16027, but for 3.0

@t8m
Copy link
Member

t8m commented Jul 9, 2021

The CI failure is only CMP related - perhaps @DDvO can look at it? I suppose the test makes some incorrect expectations?

@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

I suppose the test makes some incorrect expectations?

I have no idea... test/cmp_ctx_test.c is too macroised for me to follow, not to mention debug.

@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

(irrelevant comment removed)

@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

So it appears that this particular test tries to set an incomplete certificate (signature algorithm is unset):

ADD_TEST(test_CTX_set1_get0_srvCert);

The result is that OSSL_CMP_CTX_set1_srvCert() tries to call ossl_x509v3_cache_extensions(), which fails because the certificate fingerprint couldn't be calculated (the calculation is done on the DER encoding of the certificate, but since it's incomplete, the DER encoding will fail with ASN1_R_ILLEGAL_ZERO_CONTENTS).

@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

I suppose that for that test, the following lines:

openssl/test/cmp_ctx_test.c

Lines 341 to 342 in 0007ff2

TYPE val1_to_free = NEW; \
TYPE val1 = val1_to_free; \

... translate to:

    X509 *val1_to_free = X509_new();
    X509 *val1 = val1_to_free;

and with set_fn == OSSL_CMP_CTX_set1_srvCert, it's clear why the following test fails:

openssl/test/cmp_ctx_test.c

Lines 371 to 374 in 0007ff2

if (!(*set_fn)(ctx, val1)) { \
TEST_error("setting first value failed"); \
res = 0; \
} \

@t8m
Copy link
Member

t8m commented Jul 9, 2021

I suppose replacing all the X509_new() calls in the test with calls to X509_dup() of a real certificate should fix it?

@DDvO
Copy link
Contributor

DDvO commented Jul 9, 2021

I suppose replacing all the X509_new() calls in the test with calls to X509_dup() of a real certificate should fix it?

The underlying issue is that X509_new() produces an invalid X.509 structure, not having the mandatory fields.
Indeed, copying a real cert would be a workaround.

@DDvO
Copy link
Contributor

DDvO commented Jul 9, 2021

(irrelevant comment removed)

The stack trace you originally provided here was of interest.

#9  0x0000555555667485 in X509_digest (cert=0x5555559b99b0, 
    md=0x55555596a4e0 <sha1_md>, data=0x5555559b9ae8 "", len=0x0)
    at ../master/crypto/x509/x_all.c:432
#10 0x000055555564f210 in ossl_x509v3_cache_extensions (x=0x5555559b99b0)
    at ../master/crypto/x509/v3_purp.c:421
#11 0x00005555555eb9b8 in OSSL_CMP_CTX_set1_srvCert (ctx=0x55555599b860, 
    val=0x5555559b99b0) at ../master/crypto/cmp/cmp_ctx.c:649
#12 0x00005555555bc370 in execute_CTX_set1_get0_srvCert (
    fixture=0x5555559e4430) at ../master/test/cmp_ctx_test.c:736
#13 0x00005555555bc59a in test_CTX_set1_get0_srvCert ()
    at ../master/test/cmp_ctx_test.c:736

It shows why part of the certificate get/set test failed, namely only those calling OSSL_CMP_CTX_set1_*():
They call ossl_x509v3_cache_extensions() for checking the validity of the cert, which among others has the side effect of hashing the cert contents, which now fails for a incomplete ASN.1 structures, as you wrote above.

Copy link
Member

@t8m t8m left a comment

Choose a reason for hiding this comment

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

Approving the base change done by Richard.

Copy link
Contributor

@DDvO DDvO left a comment

Choose a reason for hiding this comment

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

Approving the additional changes done by Tomáš.

@DDvO DDvO added the approval: done This pull request has the required number of approvals label Jul 9, 2021
@levitte
Copy link
Member Author

levitte commented Jul 9, 2021

@t8m, many thanks for fixing the test

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

openssl-machine pushed a commit that referenced this pull request Jul 10, 2021
…tent

The test case creates an RSA public key and tries to pass it through
i2d_PrivateKey().  This SHOULD fail, since the private bits are missing.

Reviewed-by: Tomas Mraz <[email protected]>
(Merged from #16036)
openssl-machine pushed a commit that referenced this pull request Jul 10, 2021
openssl-machine pushed a commit that referenced this pull request Jul 10, 2021
ASN1_FBOOLEAN is designed to use as a default for optional ASN1 items.
This test program used it for non-optional items, which doesn't encode
well.

Reviewed-by: Tomas Mraz <[email protected]>
(Merged from #16036)
openssl-machine pushed a commit that referenced this pull request Jul 10, 2021
Make it only report (and fail on) encoding/decoding failures when success
is expected.

Reviewed-by: Tomas Mraz <[email protected]>
(Merged from #16036)
openssl-machine pushed a commit that referenced this pull request Jul 10, 2021
Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: David von Oheimb <[email protected]>
(Merged from #16036)
@levitte
Copy link
Member Author

levitte commented Jul 10, 2021

Merged

2296cc3 TEST: Check that i2d refuses to encode non-optional items with no content
4cd4735 ASN.1: Refuse to encode to DER if non-optional items are missing
f0f4de4 Fix test/asn1_encode_test.c to not use ASN1_FBOOLEAN
50d0a51 Fix test/asn1_encode_test.c to handle encoding/decoding failure
6bfd3e5 test_cmp_ctx: Avoid using empty X509 with i2d

@DDvO
Copy link
Contributor

DDvO commented Jul 12, 2021

I suppose replacing all the X509_new() calls in the test with calls to X509_dup() of a real certificate should fix it?

The underlying issue is that X509_new() produces an invalid X.509 structure, not having the mandatory fields.
Indeed, copying a real cert would be a workaround.

As I wrote above, the quick solution taken here is just a workaround.
For the root cause and my proposal to solve it, see #16043.

i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
if (!i)
return 0;
if (i == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this block is unreachable because the line immediately after it would have returned zero first. It seems:

  1. They should be swapped.
  2. This call is missing a check for negative values.

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 approval: review pending This pull request needs review by a committer branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ASN.1 encoders produce zero content for non-optional items

5 participants