Skip to content

Comments

Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict option)#13832

Closed
DDvO wants to merge 3 commits intoopenssl:masterfrom
siemens:correct_strict_check_chain
Closed

Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict option)#13832
DDvO wants to merge 3 commits intoopenssl:masterfrom
siemens:correct_strict_check_chain

Conversation

@DDvO
Copy link
Contributor

@DDvO DDvO commented Jan 11, 2021

This has been extracted from #13658 as requested by #13658 (comment).
Once that PR is merged the three new tests marked there as TODO can be re-enabled.

  • x509_vfy.c: strict check_chain() should check also single root CA certs
  • x509_vfy.c: rejecting unknown extensions in certs used solely as trust anchors is now done only in strict mode because such certs have been explicitly exempted from RFC requirements.
  • x509_vfy.c: check_chain() must allow V1 self-signed cert also in strict mode
    the expectations on whether a cert is (likely) a CA or not are no more checked for directly trusted EE certs because such certs have been explicitly exempted from RFC requirements.
Checklist
  • documentation is added or updated
  • tests are added or updated

@DDvO DDvO changed the title WIP: Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict) WIP: Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict option) Jan 11, 2021
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.

LGTM, although maybe adding something to Changes.md would be a good idea.

@DDvO DDvO force-pushed the correct_strict_check_chain branch from 817b820 to d096527 Compare January 11, 2021 13:45
@DDvO
Copy link
Contributor Author

DDvO commented Jan 11, 2021

LGTM, although maybe adding something to Changes.md would be a good idea.

Done, and also extended openssl-verification-options.pod (and one reference to it).

@DDvO DDvO changed the title WIP: Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict option) Correct check_chain() on X509_V_FLAG_X509_STRICT (-x509_strict option) Jan 11, 2021
@DDvO
Copy link
Contributor Author

DDvO commented Jan 13, 2021

@t8m, your comments have been addressed;
can you approve this as well?

@t8m t8m added the branch: master Applies to master branch label Jan 13, 2021
Copy link
Contributor

@kaduk kaduk left a comment

Choose a reason for hiding this comment

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

Some "drive by" comments; I didn't get to really review in depth.

Copy link

@vdukhovni vdukhovni left a comment

Choose a reason for hiding this comment

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

Overall, the code reorg and some of the changes look like progress, but I think we still need to sort out a few details.

Comment on lines 512 to 516
Copy link

@vdukhovni vdukhovni Jan 14, 2021

Choose a reason for hiding this comment

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

This check was previously only applied to non-EE certificates, i.e. those actually used in chain-integrity signature verification. If the application (not SSL, where this is not allowed) wants to allow use of explicit EC parameters, this is not the place to override that policy.

The only quibble is perhaps whether the check should be applied if we're checking "SS" signatures (even of EE certs)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, the check was previously done for all certs in the chain if the chain had more than one element.
Note that this PR stops checking directly trusted EE certs already before reaching this point and on the other hand removes the num > 1 guard that preceded these checks because I believe this guard has become pretty redundant.
If you want to have that it only applies to non-EE certificates, (which has not really the case before this PR), this check needs to be guarded differently.

@DDvO DDvO force-pushed the correct_strict_check_chain branch from d096527 to a5c6227 Compare January 14, 2021 21:17
@DDvO
Copy link
Contributor Author

DDvO commented Jan 14, 2021

Only tangentially related, I wonder if we want to add named symbols for these various values instead of hardcoding magic numbers.

I fully agree - yet another form of unreadable code 😉
If you like, I can fix that as 2nd commit as part of this PR.

How about adding #defines to x509_local.h, or where else?
Which name prefix shall be used for them?

@vdukhovni
Copy link

Only tangentially related, I wonder if we want to add named symbols for these various values instead of hardcoding magic numbers.

I fully agree - yet another form of unreadable code 😉
If you like, I can fix that as 2nd commit as part of this PR.

How about adding #defines to x509_local.h, or where else?
Which name prefix shall be used for them?

I don't have strong view on which header, the prefix should indicate that that these are CA validity code points, so something like (your call):

X509_CA_STATUS_NON_CA
X509_CA_STATUS_VALID
...

But if you think of something better, go with that. Since these are internal code points, in some suitable non-public header.

@DDvO DDvO force-pushed the correct_strict_check_chain branch 2 times, most recently from e2de593 to 3f8bd34 Compare January 15, 2021 08:02
@DDvO
Copy link
Contributor Author

DDvO commented Jan 15, 2021

It turns out that those wonderful(ly) magic numbers returned by {X509_,}check_ca need to be defined publicly because they are returned by the public function X509_check_ca and have already been documented along with it.
So added the mnemonic names to x509v3.h.in where also X509_check_ca is declared.

@DDvO
Copy link
Contributor Author

DDvO commented Jan 15, 2021

I've just tentatively added a further check to check_chain():

        /*
         * Check the validity of the cert representation beforehand
         * because otherwise the return code of X509_check_ca(x)
         * and various other checks actually have no (useful) value
         */
        CHECK_CB((x->ex_flags & EXFLAG_INVALID) != 0,
                 ctx, x, i, X509_V_ERR_INVALID_CERTIFICATE_FORMAT);

but maybe this is redundant because it is guaranteed not to happen when reaching it?

@DDvO
Copy link
Contributor Author

DDvO commented Jan 23, 2021

Rebased to solve merge conflicts.
Is this okay now?

CHANGES.md Outdated

Choose a reason for hiding this comment

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

I don't recall seeing a rationale for allowing v1 certs in strict mode. Did I miss somewhere amidst all the comments? Also, I don't actually see a matching change in the code. Is this still a thing???

Copy link
Contributor Author

@DDvO DDvO Aug 27, 2022

Choose a reason for hiding this comment

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

Oh, I just found that I had neglected not only this PR in general
but also your (@vdukhovni 's) latest comments there for long - sorry for that!

Well, to me the rationale is simply that v1 certs are not forbidden by RFC 5280, which is aged but still in charge.
The only thing I found there in this direction is in https://datatracker.ietf.org/doc/html/rfc5280#section-6.1.4:

Conforming implementations may choose to reject all version 1 and version 2 intermediate certificates.)

As far as I understand, our strict mode enforces strict requirements on X.509 certs (mostly from RFC 5280),
part of which OpenSSL so far has not really checked (for whatever reasons).
In other words, strict mode should not be more strict than RFC 5280.

Copy link

@vdukhovni vdukhovni Jan 24, 2021

Choose a reason for hiding this comment

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

It seems to me that the original code here (added recently in 1.1.1, after I last took a deep dive into the X.509 verification code) may not have been doing what was intended. The test num > 1 [addition by DvO for clarity: which has been removed here] tests the chain to see whether it has any CAs, and if so restricts every certificate in the chain (including the leaf) to not use explicit curve parameters.

Is this really the correct criterion? If we're also testing the leaf cert when num > 1, why not test it when num == 1? Alternatively, if the idea is to make sure none of the CA certs have been "tweaked", shouldn't the test be i > 0 rather than num > 1 and test everything but the leaf cert?

Finally, OpenSSL does not IIRC share the Windows Curveball bug, so it is not entirely clear why this has been added to OpenSSL.

The reason I mention all this, is that the new code is subtly different. It no longer applies the num > 1 constraint, but it is only enforced after self-issued EE certificates are exempted from further checks. This means that with partial_chain and a non-self-issued, but trusted EE certificate will now also be restricted when it is the only one in the chain.

So there are many subtle edge conditions here, and I don't have a clear sense that anyone knows what the expected semantics are. So I'd like to see that resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point that the intention which certs should actually be checked here under which circumstances is somewhat unclear.
AFAIR, I thought that the guard num > 1 makes not much sense and thus simply removed it.
Yet to be on the conservative side, I just re-added it and added a TODO comment about it such that this PR is relieved from solving this pre-existing issue.

Choose a reason for hiding this comment

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

Suggested change
Non-CA certificate required but has CA markings.
A CA certificate was encountered in a context where only a non-CA certificates are expected.

Copy link
Contributor Author

@DDvO DDvO Aug 27, 2022

Choose a reason for hiding this comment

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

Changed to: CA certificate was encountered where only a non-CA certificate is expected.

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 30 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 61 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 92 days ago

@DDvO DDvO force-pushed the correct_strict_check_chain branch from 7a973a4 to 9855b47 Compare April 27, 2021 09:33
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Aug 27, 2022
DDvO added 2 commits August 27, 2022 12:51
Extend checking single root CA certs also to strict mode.
Unknown critical extensions in certs used only as trust anchors are now rejected
only in strict mode because they are explicitly exempted from RFC requirements.
The expectations on whether a cert is (likely) a CA or not are no more checked for directly
trusted EE certs because such certs have been explicitly exempted from RFC requirements.
@DDvO DDvO force-pushed the correct_strict_check_chain branch from 0f7c889 to 359968d Compare August 27, 2022 10:52
@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 30 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 61 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 92 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 123 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 154 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 185 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 216 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 247 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 278 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 309 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 340 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 371 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 402 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 433 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 464 days ago

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 495 days ago

@t8m
Copy link
Member

t8m commented Jan 5, 2024

We should revive this as it seems to make sense. Unfortunately it needs a rebase.

@t8m t8m added triaged: feature The issue/pr requests/adds a feature and removed triaged: bug The issue/pr is/fixes a bug approval: otc review pending labels Jan 5, 2024
@richsalz
Copy link
Contributor

richsalz commented Jan 5, 2024

We should revive this as it seems to make sense. Unfortunately it needs a rebase.

After languishing for two years without any action, that is not surprising.

@t8m
Copy link
Member

t8m commented Jul 3, 2024

Could you please rebase the PR to resolve conflicts?

@DDvO
Copy link
Contributor Author

DDvO commented Jan 30, 2026

@vdukhovni, @t8m, unfortunately, I won't have the time to continue working on this.
Can someone take over, or shall I close this PR, or how else to handle this?

@DDvO
Copy link
Contributor Author

DDvO commented Feb 18, 2026

Closing for the time being.

@DDvO DDvO closed this Feb 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

branch: master Applies to master branch help wanted severity: fips change The pull request changes FIPS provider sources triaged: feature The issue/pr requests/adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants