diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp index 246bd5aee4..55d6bf1746 100644 --- a/lib/base/tlsutility.cpp +++ b/lib/base/tlsutility.cpp @@ -981,21 +981,27 @@ String BinaryToHex(const unsigned char* data, size_t length) { return output; } -bool VerifyCertificate(const std::shared_ptr &caCertificate, const std::shared_ptr &certificate, const String& crlFile) +bool VerifyCertificate( + const std::shared_ptr& caCertificate, const std::shared_ptr& certificate, const String& crlFile, + X509_STORE* (*mockX509_STORE_new)(), + int (*mockX509_STORE_add_cert)(X509_STORE*, X509*), + X509_STORE_CTX* (*mockX509_STORE_CTX_new)(), + int (*mockX509_STORE_CTX_init)(X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*) +) { - X509_STORE *store = X509_STORE_new(); + X509_STORE *store = mockX509_STORE_new(); if (!store) return false; - X509_STORE_add_cert(store, caCertificate.get()); + mockX509_STORE_add_cert(store, caCertificate.get()); if (!crlFile.IsEmpty()) { AddCRLToSSLContext(store, crlFile); } - X509_STORE_CTX *csc = X509_STORE_CTX_new(); - X509_STORE_CTX_init(csc, store, certificate.get(), nullptr); + X509_STORE_CTX *csc = mockX509_STORE_CTX_new(); + mockX509_STORE_CTX_init(csc, store, certificate.get(), nullptr); int rc = X509_verify_cert(csc); diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp index b064120201..cb4a15c9f1 100644 --- a/lib/base/tlsutility.hpp +++ b/lib/base/tlsutility.hpp @@ -78,7 +78,14 @@ String SHA256(const String& s); String RandomString(int length); String BinaryToHex(const unsigned char* data, size_t length); -bool VerifyCertificate(const std::shared_ptr& caCertificate, const std::shared_ptr& certificate, const String& crlFile); +bool VerifyCertificate( + const std::shared_ptr& caCertificate, const std::shared_ptr& certificate, const String& crlFile, + X509_STORE* (*mockX509_STORE_new)() = X509_STORE_new, + int (*mockX509_STORE_add_cert)(X509_STORE*, X509*) = X509_STORE_add_cert, + X509_STORE_CTX* (*mockX509_STORE_CTX_new)() = X509_STORE_CTX_new, + int (*mockX509_STORE_CTX_init)(X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*) = X509_STORE_CTX_init +); + bool IsCa(const std::shared_ptr& cacert); int GetCertificateVersion(const std::shared_ptr& cert); String GetSignatureAlgorithm(const std::shared_ptr& cert); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a255178da2..27c6b0223d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -175,6 +175,14 @@ add_boost_test(base base_tlsutility/iscertuptodate_ok base_tlsutility/iscertuptodate_expiring base_tlsutility/iscertuptodate_old + base_tlsutility/verifycertificate_ok + base_tlsutility/verifycertificate_leafexpired + base_tlsutility/verifycertificate_caexpired + base_tlsutility/verifycertificate_sigmismatch + base_tlsutility/verifycertificate_X509_STORE_new + base_tlsutility/verifycertificate_X509_STORE_add_cert + base_tlsutility/verifycertificate_X509_STORE_CTX_new + base_tlsutility/verifycertificate_X509_STORE_CTX_init base_utility/parse_version base_utility/compare_version base_utility/comparepasswords_works diff --git a/test/base-tlsutility-certs.hpp b/test/base-tlsutility-certs.hpp new file mode 100644 index 0000000000..2c145c3083 --- /dev/null +++ b/test/base-tlsutility-certs.hpp @@ -0,0 +1,199 @@ +/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */ + +// openssl req -x509 -subj /CN=IcingaCA -days 1000000 -newkey rsa:4096 -keyout IcingaCA.key -out IcingaCA.crt -nodes +static const auto l_IcingaCa = R"( +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUd/Uh17xKVnNfOADD5ST78J8hFOAwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMjAzMTQyNDU4WhgPNDc2MzAx +MDExNDI0NThaMBMxETAPBgNVBAMMCEljaW5nYUNBMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAx8Iau7S4bInBSzYLPcee/FFr5jBSGTiVXyRS0PUnA9ZV +zmoBc6CeXaG3WwnO+lR7z1i1KqOmIdBQxFIHnTX162enFmI89w9UK4SNo/IyorZc +XwOXFOqzo3dbn8CAk6Y6WTuY3bE7Aimxwoe74JN48uzAcfXBd97oAAaORFvL1JQa +odll9OFfshnSuRUQFuwZ5+06qGMuaKtYhmViQgCbNegzddLzpkcgtBhAx29RkQCx +6riqzbjFQdI96Tw3NDZvwsSz7d5Jc9QybfP3sMGgBJFbGsVWxamqGz0VF/c3jN6A +Vo4Zif06jvQFsiIc4Q7srriKfdAcD1OyrTtLswklip0DdgQO2/p/p/FDvoPnulQM +62bZ26ncuzLkB7Q0TF42ngfGEO6sGSLOeHbSVEnltgxhrwN45hv/wb/6JBuYoM0t +Z4467UDRSBjUwY8t1HoBcSFnZ5P6K8ZnULb+HNVxkNr3FqRuUoN4cCG8YYVcHXFK +H3DUEHj5QxMgW09ZrRz//LInELK1sPMY1ZZdzwd5kZUatFnI926FMZ80d7JhW88h +VNkTmh6trFlnJGESN3040DUzQ9LAIheHw3aevU9PDa6rqO7/bzRVz3Gm997eYHTc ++B30OubAQXZ/V8SkxuEVwWBhG969kKYHDcu8NxModlHX1yjJXGvOjc+srCaG6QUC +AwEAAaNTMFEwHQYDVR0OBBYEFGg4D67J0AQtvv9UtmSKKY6NjnrDMB8GA1UdIwQY +MBaAFGg4D67J0AQtvv9UtmSKKY6NjnrDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBABxK068gVwfguf0WnwClw9vNIf4jXJXU6Ka6rsMUzufkL0Qp +2ByAX6YNft1lPPJhsFLJTRQIdFGBPjVr/xkpBlYTRMi0KhxJYGDMfci88jNLT7jJ +GALZ3QqOZiQCsuh3x/qo15tyA53Uo2KQVxdJAz8y2jz9OV2tE6b1QuljmPLJ3y+V +5pmVQSnOtLE5aRgNONbNxojCHUIeSS9pQ24TGbciB2k8iparzX8KHpXWwBZfDXeW +HuooZZILbVQC8N1LJoDCM1g5alZCBqu8oXI06XsCQ2zO7cg7zg5IyrI+pI1nr+gz +SMANFdvMjCFcg2JjE5/SWSFtTRZ+AFPDT1BgEKg30JD00BxV6B14xwcsJvB12QMB +uBeAuQ3K/4a/2YFa5r/zw8ryzOiUNsayV8MGbFsEc9P5UGpHd5d5nFkbHmUfMUEC +3RpmzYA29qHgeXSjEdIYsafyiLvEP8cFHgwXmfuU46UEVd2N12GiWUstkNjjeClz +Hj350GhmvdVQzJHfuMohhfiPlEsShXlVimuqQtzABJ9Ofc5qfj1HJ4zy+ChuIOeq +8KCk8LnaScqbizFyQz4aJeqDrVoOUAWnIUfPI7j88MfeAFfAaUvvsafff65otjJW +GglKfwlBbg9ZxroKEU01NkzpNjbi4bx3R1bd3D5hbWznvuYAW5GB8VN2RuLA +-----END CERTIFICATE----- +)"; + +// openssl req -x509 -subj /CN=example.com -CA IcingaCA.crt -CAkey IcingaCA.key -days 1000000 -newkey rsa:4096 -keyout example.key -out example.crt -nodes +static const auto l_ExampleCrt = R"( +-----BEGIN CERTIFICATE----- +MIIFDDCCAvSgAwIBAgIUB4eZoCzckBBu/YurWoqZLhXsZB8wDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMjAzMTQyNTI0WhgPNDc2MzAx +MDExNDI1MjRaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAlo3dS6OuUeMX/eh6STENz/CnDVIEvF+j2PFvSjFg +V3HpKfeP1THQExpVbbCWuHXyPInZyur8WQuFxLI5EL4B/62d74g82r1u9VLVj90g +4z9K/ySStB5KE/rfvcqfdlgcRVvXilBd/Rw5bXQpkWARTHFokAA90fYOgAD2Yvyc +3P/6/UJEsV0/D4maPeb5ynaALKT5oxmM2kt4asOx1h/HkEzhhBUwrrBCohfP4+Yk +QpWfOqvyrkSlNwJ4G6Lcgmuda5u21Lo1HBNlM8sNmGfF0uijpXlDdaYOqdBsgaFQ +n4EVAH/JfqjwVQRhwBfreN29uN1HBH6+s3WgYWKnNszpqqDYLMLI3SIdoO/ewurG +nP1+oR1auQ79nn1O7GpAFNl7zXvsBnKhoz8zvKbnPrQyJ3+9LaG/5iXJap27cJEV +J8z7WOxA2VdJfzbfECz1DINlwtS03X7RCsaPCkrvStxQoT9V2SHJINj/wFytkc5O +JykncjIBfTw9+MyUV6FTMgOEQT7vkWnVzjCGNwxrU152kyFb5LaZO9mBDu+RmRbE +qEjNVL4wJY1oS1GX0ojmMsKbgaINMpy1OhAKSCtho0GpJ9BnjDMlks+2cKLcEcVX +TqBrtfPcMQQwgBeX5KCPo45Gn6sk+k22qn73VTYfffTGklp0QmhdwHSA8DBKMYXk +XLkCAwEAAaNTMFEwHQYDVR0OBBYEFE0rR95tiFIMBa3ia0ySM9UV/e0kMB8GA1Ud +IwQYMBaAFGg4D67J0AQtvv9UtmSKKY6NjnrDMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggIBALV8yFeD4SgO0YJzCE9e+2IeUiReebYtgqbuMeQhM0ag +Bokc1m/N+YrKB07LNUiSFswnSUVnCIYWmqnGbQ7MjhJZf779SWZmLVgc19o2zqEQ +Iz/mn9jWny9RIW1kwSsB+CAUNhVNO4IRPlBUzknaNhEntIwsta8yCimQFTGjELkA +BJlqPnbbbhPP/OjPWc1j6NvZVy30JZHytocPt+Fk6fsfQvGqVyuFWXB/0wR9sTIz +9ZuMEn9lUjkXIx/uOsI4QDy+jzQ2GLoTSGBnWsbmVfyCOXYSNzCtVTo6HQaz9dIx +FrgJqjK2b75XObDLxuMlC79OG4amqDFDpR73QRZnR4Wu1mLAcUIDorxPTVwyTtid +KxjdJx2Ve5R9BqJPyfRLlh/KWJ7xVo7GyGSSQ1KgnATDW+KbAuktC7F5QguSb4BD +NhZgRIShrflKPPx58W/whCZcx7yNml+JkrQ+DYsGe3ndR9V5XGmoU2zeeNRl8/ik +pYxVCR6rTu/c7q5Gf9dkVW0hf2sEcUA9s7x/aN7Imov7iWHVD10ArzOtWmSoyUqB +ugPfVjB3uPlM8GTIFcsSb1PX++f6dxyrswfzg/8iXbeFzfsySbmbBriDYKUDPaEs +WxjM3wPsBsMY0XloaYipqy6NE1vxvrKZlslg2V2/gOTw9NPAepUXvXi1DNDKrc0/ +-----END CERTIFICATE----- +)"; + +// faketime -f -101d openssl req -x509 -subj /CN=example.com -CA IcingaCA.crt -CAkey IcingaCA.key -days 100 -newkey rsa:4096 -keyout expired.key -out expired.crt -nodes +static const auto l_ExpiredCrt = R"( +-----BEGIN CERTIFICATE----- +MIIFCjCCAvKgAwIBAgIUXkad7cO9zwmneYEuephdmacq+rYwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwHhcNMjQxMDI1MTQyNjA2WhcNMjUwMjAy +MTQyNjA2WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANlz1XpNvJSuJuGLTMly6eiV9oT6uW540A1uMm9XqKom +974+10po+21qbl+5GCIxQTY3y7MwKtN/X4hEBHRLKkkp2ovvEzMk+Vcy0kcTD1/P +usS7w9RLUHXPOhUsFUJBBQ2+EoXgvQn9OeePrA0u04xTud3KyrLIIc70PfdL8sMP +99qciWp+gb1BAqEluQBn20ekTUt0JTMuqJapNgQV2VNKg72EV4BOuN9DqIdFfAbi +KYGDtouUIGsBnagBXZ6GcTgLAkxdpA1Ol9DzG1GfjTPMMSLMGAdG8GLOmhPXXBmP +ymB3O/3d/jg3asXs1rofco68fzifelqrnO2lFhMYDclCoW8QG0V781494cr3t32m +NeLNcpTj/DkFuR1gS85QhplWUDshy5hqessTcpDz3f7bAJZ8f5TCJKTvv7yAqf9I +38cIKzwHZqK1pK82XBHrTzHnk8BY4Wt8o9+9uW8/4+lr0AELf7F2oAhzaKto9H2e +6fntNSEgKbPOsxyxwAj8hNaNRTawMJEY9wYR1GaoIeWO2kI8Hnqli7WGHw3vo22S +mGvc/NPNPEm/EyFQX2wSeGZjBG26tumz3XAt1NGMjwjGjEZv4ijVEAnz0xvZT3iK +8E8njfRbxr54izfPsxfDgDT0FVupLR+yshI2CAZjrF0kn9D9skciPw6okvhBHpx1 +AgMBAAGjUzBRMB0GA1UdDgQWBBRpFK4LfAF6QhnLYO87MQnvwNL+4DAfBgNVHSME +GDAWgBRoOA+uydAELb7/VLZkiimOjY56wzAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBCwUAA4ICAQAgIwUrJb0XDdGHLUQwcd/rUGeqJk5ny5i1te+7c+cKOI2S +N795rxSBnQ7qqXbbU44un6VzvAVSHSvz9CJZJOPVZKgDIs1cpsokQUJQqYIlWdDM +MSXulVY2q6LqGA05ln9yUkQyVwTYl9PxbgknQ9+6ZY/sHixvp4zhZ+QNjJ6lHPlu +ZFfB/ioIriMDKDqmpbUhIhHTrm6eCYvLZ1VY9k3+ojgz6NNQnMHOS/awA+ttC9To +z4jrfLWWNfSFXGErMWpLtFyywpJEtZKVyPPPgy6TF7ui/DdtsNUzyL/u2SuPWHBK +QbwgS9eddJCG2f7+F69nabbZ7g2b5z/yvyuqnxzM8aYjtFNpH/ch2SWFtfVMYS9z +h47I40t09zf3Wv3fmJ74Cx/vaEkDLwcgtMQdyXuN+Js5tVdAj64jkihCrVK0kz33 +UAGoQyrIbQsbkWacvBIA7Ce9Qn6TLpO7KnySXfl0WVS+Vv/GzVrU0d6A6yeU2H34 +RncPTUFqy98NItat2Q92ShATYLHUyXK0u+Yhx4CdZStmfKt58ZXuJFy3MtCccxxh +2VWhsCEX2YbB8IbdemgbpkT+OXCWD33onAuoT4zLPhOLT6Rj7zzMDcuD8vZz4fY/ +8EyQq+WyExRNGp5UXFR7TDqDb6QjfqM86T5XmfHIIAt2K7LPjJg5vFcSiGMmsg== +-----END CERTIFICATE----- +)"; + +// faketime -f -1001d openssl req -x509 -subj /CN=IcingaCA -days 1000 -newkey rsa:4096 -keyout expiredCA.key -out expiredCA.crt -nodes +static const auto l_ExpiredCa = R"( +-----BEGIN CERTIFICATE----- +MIIFBzCCAu+gAwIBAgIUGBuVUho8Wt3JVXJU4zdeNEpjODQwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwHhcNMjIwNTA5MTQyNjM2WhcNMjUwMjAy +MTQyNjM2WjATMREwDwYDVQQDDAhJY2luZ2FDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJt0yGV1xh75rn006TJcArS9vnJMfByGHnob15u3RgL9zkmB +Hj4Ew/gBT9YH57R6b1LuRKFI267ohy64gYwLngVYd2vHrHxshH0Mr3z4Z/S61cYD +hnDltxAtGW0zzXkbXg591oskzt9XqgXPgPy/vr5GIrJcahl8MKI+04IDsc08qq9s +5ELtGcvk9FMruM9EBh9QnruUgvr+5tejy7UGi8rfUv+YJoJK/SgibHWV4sDGHFo9 +UaZJN1lkJHWhybhb0ZxVKUDGvD4/M2DKE4eVFsgZJ0A6HpduwUBqZy45KTLM86tx +3WH/PPu+i1J2LkJjbv9y692evJBUQtpb27Ucde5qajjXkw/amCbfXT6iX2cX3nd8 +XQQ02QuDXBI4dakYR68ObXRTUCgcxcQ8+78BQU8AIa3249LPzRtzO4lsUeDZGWD/ +rkQ3O0U5joILuNucM/Gew3WG1jj/S8qvTkPJl/9+iD+86C4l7c6+dS+FlBnpGlUc +CqyePbZyjjCdSrmfHIizzrzMFr1SO9YDUC6ffmU/IcSbOKUzWEM4OrDPKzrHPJU3 +ijuQRaOvvELw9707syLBqdYV9+I1n2rPzZDsH2Q3ZQ7pa+7rEhk+qAsFYYvlHQjJ +KINz/wzSq0Cg7b8Ownls5rEPgCCaurcFilkUFZzmkM6RqZPjgwMSHNQ+hj+RAgMB +AAGjUzBRMB0GA1UdDgQWBBRlaMot+o1GzNauD2h1vnxEzFVmIjAfBgNVHSMEGDAW +gBRlaMot+o1GzNauD2h1vnxEzFVmIjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQArO9Oufq1nY2fSrLhaJxfMcB4prtJ1SHMNUggYNPxAspIkUW8Y +zp1ddvqzmJbDzSN7+z5t2iqgFCeHe0GY4TLm+WhRdp/Ive2WmNErqDbY6VQYU/1q +ZIo/Zzk2MH6ddISxJQhoQXGrIrqmlW9MAzE9DV+vU8umBiR50FRt1qqlgMVgrYGo +crU4pUAeTy3mF34695NVePwYWBPWGRvqcg9mRcCWnMhEd8uuJhdboKv0L9H1Koh9 +bmuH01ScpIBFK9oA6JKI90jUWvp4OD6A8a9tTY1xQ2TLxnt4Wj+aiy997p2HR2o+ +e3c4Wl6s5Eu2utt6DgcVXmzRz6JIVG22KNzKtRA0GKtl75ZaaTL4SxCaFpkiiQST +g5j6Qc175HGbK0CWOkHNKN8Gg8IwGBZEt+VVpAUsfIv5QXTpBiqG06TM5T8KwH4G +D1Nc+i7tCcxq/e35gqAt3XyZuCXjfmAMhOThXqVrvxCZx4+htysSWRaLAVlDZ7+k +DkrzrI8eYACoJLotme1rTNSlJyCDzS2p1TYkMeNJybGHkLFXd5pJd4+9mU0SPnRx +X1omsrc6gS/MHEud4kNtRPrX5ZECT2yaJaQAQGXJL3M1GC1HRELa7qlmmQ1Vuh8H +qu+KkZsBUa+U9x2JSWHC+roU2nlS93ppxBypbokyTc4fU7XN2OI8oG7sYg== +-----END CERTIFICATE----- +)"; + +// faketime -f -1001d openssl req -x509 -subj /CN=example.com -CA expiredCA.crt -CAkey expiredCA.key -days 1000000 -newkey rsa:4096 -keyout expiredCAleaf.key -out expiredCAleaf.crt -nodes +static const auto l_ExpiredCaLeaf = R"( +-----BEGIN CERTIFICATE----- +MIIFDDCCAvSgAwIBAgIUefhInmZ2qIDMAUykWgk9PTiaulYwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjIwNTA5MTQyNzAyWhgPNDc2MDA0 +MDUxNDI3MDJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA0/TpxNemM6NaUr+/Fy5OtWlq1TVAJCaWEQJwPUs2 +398DNDhT8mkS5vp/+doO3N5XT/hr+EF/623N85ZlK+oukfUEWpYkCdBj+oZ8xsXW +5J+auwhbE+6haME5KDZIdOCWhhx1BueEHu4oZzUsEDSPB1rovlbxExE5ISvI7gCi +EbkcGdepNVv1zpfFpfeNHPYJwj9v3KnXgqwNrQv7NMPmDvoYepMzGUH91bj20HJ+ +n8lHsLw/NbfFNREh6G8/LR/eg2H387E57GSEzXQ2n6qCUdSdk3xTfU+ZaY2XjC6b +AH4w14MbjnAqYx7/ZjRXOAJhCC7qHz+iYobW8eCGuSzI9QI+IY4yM/P0WyaeYRPx +XPQY7lMqjXB3vwlR0Y/zYeUV3xUc5DxuQ8MRxreR+oo7M0T8JDJHtPaw/JU2JsuB +XWILzIX4+RcQS/VYUs2cH0E3PjVbjNDpV86KRsmjpZ4iNxFGnybzw5BkE45a5BwM +2iCjPs5Jdjt+QCws2mrBxGryKPaCF+g6dgGwCqp+Y3gtTNgnSLmAj2oev1AI1T0v +SE1Q7OoRliN1m/etPc7e1CVyP2/hhFxfTEp2ErnumkuPe15WHVYeM4G59rDxhPfJ +cdNr7geNg1+nZJHSFIR2a7/+/dZx97GQCl89FX9MoJNH7dvQAFXqvsfp//I199LT +9qkCAwEAAaNTMFEwHQYDVR0OBBYEFBOAppbz2huhTWQpwV3q6SqDYy0oMB8GA1Ud +IwQYMBaAFGVoyi36jUbM1q4PaHW+fETMVWYiMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggIBAIb1hCLM+A0I4mIZ+f6BnfqUpeAJ+yD+lZLyJ2NhQ11L +UoN4xTGrKk2ktRCPx6ln1Kpks7I3OirfiWrb+nM84ravA+b+3PR8/3QqeLHSj0nb +NGAQyd+fAuF6GdOs7VEzpCaRA0mmQOWln0DQt9I3SQvEyC2eGtpDQBN2tPtG+TUI +C7rIHltjdkTK0TJvgsr2vRgDS5AqzcqzemaX61vJOWTp2euHpWr2/TJl/xWK6xDq +6Quavq2zIVBiBqOeFseOLTicyqsGSIDxICcjecDFBvh5gdSxEcaeuyjSUED+w48Z +agCdgPHNcS1qWwxDEy6N6m8RM1LDr4nQfkP6XSe+aKHUSPPepRqkBUaSGo8Ycxdh +zOJChgpzTr/4LfOEJjmy/mkfh+rUQ/ir6ANEgUXkKRvco+uIw675xaa6oXycZQTl +VsMi7kuf/B0IFtTbwwMkVrzW6cVXQeWotjnP/Mlm+eGUczD4KQ5Q9yQrz0n6ykUk +d8SeMNkNPtYJWQ8uaMrKLNXrH4DR6Rk966dRWl0DOSxjhYLwD7utd2q0zM8g7LJs +zntfnnmvsRukhK9l104Y4mzerLDzAUM1kYMcD8kZsbJ3hC5Kfxq/Fh1cfwAAdEBb +RpCa0NXJNve/DQgA71q2fgJJJrA7H3M0k2lNlQ8sfbiZcFrXJT9rIWSxS8ItA7IP +-----END CERTIFICATE----- +)"; + +// openssl req -x509 -subj /CN=IcingaCA -days 1000000 -newkey rsa:4096 -keyout IcingaCA2.key -out IcingaCA2.crt -nodes +static const auto l_IcingaCa2 = R"( +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUcuGwkbZxyVfq9aJlsEPRsi23d/AwDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMjAzMTQyNzI0WhgPNDc2MzAx +MDExNDI3MjRaMBMxETAPBgNVBAMMCEljaW5nYUNBMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAqAcnR0//8D455vuoiaKxyevkaSEoF/VbWwS6ty9inNbO +V+c7Qi/PS3Raw9Vo1kj+SSYMdgLYiu/rAw/fkoAyHAdFt9KWWMbDJkAXH12VDvkI +YjJj4iNr5fXmntzYd5ZHmja11WhGlq64rlwEG+buC6fwWZc40KPHa8DnPEqXWg6+ +YUDD2IkQnDtzHE2jNydjxwKX2fYfKL80PwPYZxuKZdghX4EHkhLiIc5IDk3hkjhj +7bhV7zOPFDu4jLOMh7P99kVcgOBFTZ5RPfDgbHT1AJpvBq9zHAW2zoAqKiCdvIlJ +iCin2qu5ejVHc3vNhcaCAPgErgGyqnhpc8HDkyjhi0JV0d/Dxuoy1TRQisZZjeVX +d0G0iQlO/tYheALjtXwCzVBv3to9j/qHLaWs4AIHS/kIZ405xfO1V+17pZrSTH2z +tTNuF4Vm4KZ+51GKT6uMvWTEewxbz2sYBp/GfEgo/YQz3F+7ROyqWgONgGW3Bs/h +4qtonLNt8vEj7GcsaZ2G290gVF9M3a17edJ1ra/UMv8Xzx9Zo+57IdeH0fwatbdh +ZNz+KvEIihSHhntgTdiTPxSzxGezv8za6+GVUGtF6ZYTMQZnuor1Ep+Hc9pds9x2 +uRQU0U/DCQ8w9rVBUsNdSN0hC5hsFEsV0OLoBbq5EN77l1pv93VZ3WakVlFExSMC +AwEAAaNTMFEwHQYDVR0OBBYEFCgDpGYhxHIWlFXiHJbMcB3WkOI3MB8GA1UdIwQY +MBaAFCgDpGYhxHIWlFXiHJbMcB3WkOI3MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBAE3e5/u6/+aX+4Pbl45AY6dN3P3qtVoGWuyGnf/hOji63cA+ +UtYR9Ylk/ffa0ksyO4nl2ku4M0m0M0JpTO1m98CDRCq/RY6ABQYCZFoQmJbzu0JY +pKCD9f2EL0a92A0pOQ6M4uPJfk1rgGNe7By1EW7VQBpjbKXKLOngo613ckEB8qL/ +dUEeVoeWv019AJnsGPzJiMD97a8ZpRCGGBMWj97zEEPYooCdF3xRNkJQJkOD7y4x +BJDRNbBJQILxDQKwdRADWzjYlqfUwUkNpcqvxwFjfeQqSDom84doafM1v01/S+wi +ytcn4AxrVmJFlmeSfi5Eo+WwEMIARtm9ljTsiJ8QxHZiwTp3oPSIyHsQTdDlEvR+ +SqOFlYDXEUML1jqLcggx9zFnC5V4DZMg8m2dhY14IskBK7qtvcDINBdc/f/HFbg0 +yjcdkJmxUcigOGrZx6zLJNctbNNdVBfuzsKrETIc2NvDkWTBOu/xDjsOQyTuY/vn +xoCx6ECSoFXFzJXnz3bwAlWY34ckJv2Y2KsyCdeQMXFlxh2AdLjytGESYr0U5RAY +NnqwJNNFjEZ+agaOpSGeTpzr1Zv0gOxp9bupJpVM3Mke0+Ay9S4squ3WHFiGDH7K +Mu8SpqZ2/3wbAs/00Jh3nPGGmCjvFsf2BLSyUqP04+cfDv3fDY1fCntPLMEd +-----END CERTIFICATE----- +)"; diff --git a/test/base-tlsutility.cpp b/test/base-tlsutility.cpp index 2e611e49ae..f26c577fd2 100644 --- a/test/base-tlsutility.cpp +++ b/test/base-tlsutility.cpp @@ -1,6 +1,7 @@ /* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */ #include "base/tlsutility.hpp" +#include "base-tlsutility-certs.hpp" #include #include #include @@ -132,4 +133,72 @@ BOOST_AUTO_TEST_CASE(iscertuptodate_old) }))); } +BOOST_AUTO_TEST_CASE(verifycertificate_ok) +{ + BOOST_CHECK(VerifyCertificate( + StringToCertificate(l_IcingaCa), StringToCertificate(l_ExampleCrt), String() + )); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_leafexpired) +{ + BOOST_CHECK_THROW(VerifyCertificate( + StringToCertificate(l_IcingaCa), StringToCertificate(l_ExpiredCrt), String() + ), openssl_error); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_caexpired) +{ + BOOST_CHECK_THROW(VerifyCertificate( + StringToCertificate(l_ExpiredCa), StringToCertificate(l_ExpiredCaLeaf), String() + ), openssl_error); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_sigmismatch) +{ + BOOST_CHECK_THROW(VerifyCertificate( + StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String() + ), openssl_error); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_new) +{ + BOOST_CHECK(!VerifyCertificate( + StringToCertificate(l_IcingaCa), StringToCertificate(l_ExampleCrt), String(), + [] { return (X509_STORE*)nullptr; } + )); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_add_cert) +{ + BOOST_CHECK_THROW(VerifyCertificate( + StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(), + X509_STORE_new, + [](X509_STORE*, X509*) { return 0; } + ), openssl_error); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_CTX_new) +{ + if constexpr (OPENSSL_VERSION_NUMBER < 0x30000000) { + // These OpenSSL versions don't handle a nullptr X509_STORE_CTX* gracefully: they simply crash + return; + } + + BOOST_CHECK(!VerifyCertificate( + StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(), + X509_STORE_new, X509_STORE_add_cert, + [] { return (X509_STORE_CTX*)nullptr; } + )); +} + +BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_CTX_init) +{ + BOOST_CHECK(!VerifyCertificate( + StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(), + X509_STORE_new, X509_STORE_add_cert, X509_STORE_CTX_new, + [](X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*) { return 0; } + )); +} + BOOST_AUTO_TEST_SUITE_END()