-
Notifications
You must be signed in to change notification settings - Fork 595
Test internal cert generation & verification process #10350
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
base: master
Are you sure you want to change the base?
Conversation
79c98f8
to
0500a12
Compare
0f579b7
to
a8ac9e4
Compare
9355e47
to
53b65c2
Compare
6591932
to
9e2fe37
Compare
That was my last push :)! Now, all of the GHAs should be fine, so pls have a look! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9e2fe37
to
e1c8fba
Compare
e1c8fba
to
b15e692
Compare
As @julianbrost found out, OpenSSL has no problems with past 2038 timestamps, so the whole |
9e8b7ec
to
4c6b0b7
Compare
The previously used |
The certificate generated by `PkiUtility::NewCert()` is self-signed, and so the subsequent `PkiUtility::SignCsr()` call is required. However, `PkiUtility::SignCsr()` doesn't reuse existin cert, instead it'll generate a fresh one on its own. So, skip the first one entirely!
4c6b0b7
to
f7219f7
Compare
Just rebased to resolve the conflicts! |
f7219f7
to
0133fa1
Compare
Fixed a small comparison failure on docker builds as it seems to take over a second to sign the certificate and load it from disk, thus fails the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few comments, mostly things clang-tidy
suggested, one readability improvement. Otherwise this looks fine to me.
0133fa1
to
c48941f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆 assertIMMorDZSSC
isn't much better than before, but it's not that important either.
lib/base/tlsutility.cpp
Outdated
X509_set_version(cert, 2); | ||
X509_gmtime_adj(X509_get_notBefore(cert), 0); | ||
X509_gmtime_adj(X509_get_notAfter(cert), ca ? ROOT_VALID_FOR : LEAF_VALID_FOR); | ||
auto notBefore = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0
is an int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please stop splitting a single point across multiple comments. This makes it way harder to read, especially if individual conversations are marked as resolved and additionally, it clutters the diff view (see the screenshot below). If you want to refer to code in a different place, you can also just include it by referencing it like this:
icinga2/lib/base/tlsutility.cpp
Line 651 in 190dc86
notBefore = validFor - 365*24*60*60; |

lib/base/tlsutility.cpp
Outdated
if (validFor < 0) { | ||
// Set the validity start date to one year past the validFor date, | ||
// so that the generated cert doesn't expire before the validFor date. | ||
notBefore = validFor - 365*24*60*60; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But validFor is a long.
lib/base/tlsutility.cpp
Outdated
X509_set_version(cert, 2); | ||
X509_gmtime_adj(X509_get_notBefore(cert), 0); | ||
X509_gmtime_adj(X509_get_notAfter(cert), ca ? ROOT_VALID_FOR : LEAF_VALID_FOR); | ||
auto notBefore = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So:
auto notBefore = 0; | |
long notBefore = 0; |
lib/base/tlsutility.cpp
Outdated
if (validFor < 0) { | ||
// Set the validity start date to one year past the validFor date, | ||
// so that the generated cert doesn't expire before the validFor date. | ||
notBefore = validFor - 365*24*60*60; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 1 year and not LEAF_VALID_FOR?
// Set the CA certificate to expire in 100 days, i.e. less than the LEAF_VALID_FOR threshold of 397 days. | ||
auto now = time(nullptr); | ||
BOOST_CHECK(X509_time_adj_ex(X509_get_notAfter(cacert.get()), 100, 0, &now)); | ||
BOOST_CHECK(!IsCaUptodate(cacert.get())); // Is CA outdated now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (and other places in the new tests) still use the pattern where you update some certificate parameters, but don't actually create a new signature. So after just doing that X509_time_adj_ex()
, the X509
structure is in an inconsistent state where the parsed and changed information does not match the signature. IMHO this makes the whole test case questionable if you use inconsistent data structures. Thus, everywhere something needs to be changed in a certificate, a new certificate should be created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still using X509_time_adj_ex()
here because I don't verify any cert signature here but want to only test whether the IsCaUptodate
function behaves correctly or not and this has nothing to do with the actual cert signature. And for the other few cases that still use X509_time_adj_ex()
, they don't use it to adjust the notAfter
timestamp but the notBefore
one, since it's not user configurable (and I don't want to add yet another parameter for it), so creating a new certificate would be pointless as it's going to have a notBefore
ts of 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your newly added comment highlights the problem, because of that inconsistency within the test data, it's possible the test doesn't even test what it's supposed to test:
icinga2/test/base-tlsutility.cpp
Lines 197 to 203 in c3ee33c
// Set the certificate validity start date to 2016, all certificates created before 2017 are considered outdated. | |
BOOST_CHECK(X509_time_adj_ex(X509_get_notBefore(cert.get()), 0, -(now-l_2016), &now)); | |
BOOST_CHECK(!IsCertUptodate(cert)); | |
// ... but verification should still work, as the certificate is still valid. Though, on AL2 the notBefore | |
// time set above will be reset to its original value, as VerifyCertificate transforms the crt first to string | |
// and back to X509, which causes OpenSSL to reset the notBefore time to its original value. | |
BOOST_CHECK(VerifyCertificate(cacert, cert, String())); |
and I don't want to add yet another parameter for it
That would result in a better test case though. The actual use of these functions is to check a certificate that was either loaded from a file or sent by a peer, not a X509*
where some values were adjusted retroactively. So using a regular certificate as an input in the test cases would be more realistic.
Plus, it would additionally remove the need for this special case in the implementation if the caller could just specify the whole validity period:
icinga2/lib/base/tlsutility.cpp
Lines 648 to 652 in c3ee33c
if (validFor < 0) { | |
// Set the validity start date to ~1 year past the validFor date, | |
// so that the generated cert doesn't expire before the validFor date. | |
notBefore = validFor - LEAF_VALID_FOR; | |
} |
test/base-tlsutility.cpp
Outdated
char errBuf[256]; // Buffer for OpenSSL error messages. | ||
ERR_error_string_n(ERR_get_error(), errBuf, 256); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nicer if it didn't repeat that magic constant:
char errBuf[256]; // Buffer for OpenSSL error messages. | |
ERR_error_string_n(ERR_get_error(), errBuf, 256); | |
char errBuf[256]; // Buffer for OpenSSL error messages. | |
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On that note (and because clang-tidy complained about it), make the char array a std::array
and use .data()
and .size()
instead of decaying into a char *
and sizeof(char[])
.
c48941f
to
c3ee33c
Compare
c3ee33c
to
3ee0336
Compare
The |
This is basically kind of the same as #10329 but without using hard coded certificates!
closes #10329