diff --git a/CHANGELOG.md b/CHANGELOG.md index 79fad8f3613b..23b2a961234e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - CheckQuorum now requires a quorum in every configuration (#7375) - `read_ledger.py` validates the offsets table in committed ledger files, reporting an error if this is truncated (#7501). +- Allow carriage returns in PEM certificatees (#7507) ### Changed diff --git a/include/ccf/crypto/openssl/openssl_wrappers.h b/include/ccf/crypto/openssl/openssl_wrappers.h index 8726ff816351..1d52f45288fd 100644 --- a/include/ccf/crypto/openssl/openssl_wrappers.h +++ b/include/ccf/crypto/openssl/openssl_wrappers.h @@ -251,7 +251,7 @@ namespace ccf::crypto {} }; - static const char pem_prefix[] = "-----BEGIN CERTIFICATE-----\n"; + static const char pem_prefix[] = "-----BEGIN CERTIFICATE-----"; // -1 for the null terminator static constexpr size_t pem_prefix_len = sizeof(pem_prefix) - 1; diff --git a/src/crypto/test/crypto.cpp b/src/crypto/test/crypto.cpp index 3e9921ccaa96..e4e5ed401a5c 100644 --- a/src/crypto/test/crypto.cpp +++ b/src/crypto/test/crypto.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the Apache 2.0 License. +#include "ccf/crypto/openssl/openssl_wrappers.h" #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "ccf/crypto/base64.h" #include "ccf/crypto/eddsa_key_pair.h" @@ -1349,4 +1350,49 @@ TEST_CASE("Decrypt should validate integrity") ~broken_ciphertext[ciphertext.size() / 2]; CHECK_THROWS(ccf::crypto::aes_gcm_decrypt(key, broken_ciphertext)); +} + +TEST_CASE("Carriage returns in PEM certificates") +{ + const std::string single_cert = + "-----BEGIN " + "CERTIFICATE-----" + "\nMIIByDCCAU6gAwIBAgIQOBe5SrcwReWmSzTjzj2HDjAKBggqhkjOPQQDAzATMREw\nDwYDVQ" + "QDDAhDQ0YgTm9kZTAeFw0yMzA1MTcxMzUwMzFaFw0yMzA1MTgxMzUwMzBa\nMBMxETAPBgNVBA" + "MMCENDRiBOb2RlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE74qL\nAc/" + "45tiriN5MuquYhHVdMGQRvYSm08HBfYcODtET88qC0A39o6Y2TmfbIn6BdjMG\nkD58o377ZMT" + "aApQu/oJcwt7qZ9/LE8j8WU2qHn0cPTlpwH/" + "2tiud2w+U3voSo2cw\nZTASBgNVHRMBAf8ECDAGAQH/" + "AgEAMB0GA1UdDgQWBBS9FJNwWSXtUpHaBV57EwTW\noM8vHjAfBgNVHSMEGDAWgBS9FJNwWSXt" + "UpHaBV57EwTWoM8vHjAPBgNVHREECDAG\nhwR/" + "xF96MAoGCCqGSM49BAMDA2gAMGUCMQDKxpjPToJ7VSqKqQSeMuW9tr4iL+" + "9I\n7gTGdGwiIYV1qTSS35Sk9XQZ0VpSa58c/" + "5UCMEgmH71k7XlTGVUypm4jAgjpC46H\ns+hJpGMvyD9dKzEpZgmZYtghbyakUkwBiqmFQA==" + "\n-----END CERTIFICATE-----"; + Pem cert_pem(single_cert); + auto cert_vec = cert_pem.raw(); + OpenSSL::Unique_BIO certbio(cert_vec); + OpenSSL::Unique_X509 cert(certbio, true); + REQUIRE_NE(cert, nullptr); + + const std::string single_cert_cr = + "-----BEGIN " + "CERTIFICATE-----" + "\r\nMIIByDCCAU6gAwIBAgIQOBe5SrcwReWmSzTjzj2HDjAKBggqhkjOPQQDAzATMREw\r\nDw" + "YDVQQDDAhDQ0YgTm9kZTAeFw0yMzA1MTcxMzUwMzFaFw0yMzA1MTgxMzUwMzBa\r\nMBMxETAP" + "BgNVBAMMCENDRiBOb2RlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE74qL\r\nAc/" + "45tiriN5MuquYhHVdMGQRvYSm08HBfYcODtET88qC0A39o6Y2TmfbIn6BdjMG\r\nkD58o377Z" + "MTaApQu/oJcwt7qZ9/LE8j8WU2qHn0cPTlpwH/" + "2tiud2w+U3voSo2cw\r\nZTASBgNVHRMBAf8ECDAGAQH/" + "AgEAMB0GA1UdDgQWBBS9FJNwWSXtUpHaBV57EwTW\r\noM8vHjAfBgNVHSMEGDAWgBS9FJNwWS" + "XtUpHaBV57EwTWoM8vHjAPBgNVHREECDAG\r\nhwR/" + "xF96MAoGCCqGSM49BAMDA2gAMGUCMQDKxpjPToJ7VSqKqQSeMuW9tr4iL+" + "9I\r\n7gTGdGwiIYV1qTSS35Sk9XQZ0VpSa58c/" + "5UCMEgmH71k7XlTGVUypm4jAgjpC46H\r\ns+hJpGMvyD9dKzEpZgmZYtghbyakUkwBiqmFQA=" + "=\r\n-----END CERTIFICATE-----"; + Pem cert_pem_cr(single_cert_cr); + auto cert_vec_cr = cert_pem_cr.raw(); + OpenSSL::Unique_BIO certbio_cr(cert_vec_cr); + OpenSSL::Unique_X509 cert_cr(certbio_cr, true); + REQUIRE_NE(cert_cr, nullptr); } \ No newline at end of file