Skip to content

Commit

Permalink
[release/5.x] Cherry pick: Address issue with embedded certificates i…
Browse files Browse the repository at this point in the history
…n JWT x5c (#6440) (#6442)
  • Loading branch information
ccf-bot authored Aug 15, 2024
1 parent 423f918 commit bb25588
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 13 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [5.0.4]

[5.0.4]: https://github.com/microsoft/CCF/releases/tag/ccf-5.0.4

### Bug fix

- JWT authentication correctly parses certificates that contain other certificates (#6440)

## [5.0.3]

[5.0.3]: https://github.com/microsoft/CCF/releases/tag/ccf-5.0.3
Expand Down
27 changes: 23 additions & 4 deletions src/crypto/openssl/openssl_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,35 @@ namespace ccf::crypto
{}
};

static const char pem_prefix[] = "-----BEGIN CERTIFICATE-----\n";
// -1 for the null terminator
static constexpr size_t pem_prefix_len = sizeof(pem_prefix) - 1;

// Check BIO starts with PEM prefix before attempting to read it as PEM
// because PEM_read_bio_X509 is permissive and will skip over non-PEM data,
// which may for example result in a DER containing nested PEM being read
// as the nested certificate.
inline X509* read_pem(BIO* mem)
{
std::vector<char> buf(pem_prefix_len);
auto read = BIO_read(mem, buf.data(), pem_prefix_len);
BIO_reset(mem);
if (
read != pem_prefix_len ||
std::memcmp(buf.data(), pem_prefix, read) != 0)
{
return nullptr;
}
return PEM_read_bio_X509(mem, NULL, NULL, NULL);
};

struct Unique_X509 : public Unique_SSL_OBJECT<X509, X509_new, X509_free>
{
using Unique_SSL_OBJECT::Unique_SSL_OBJECT;
// p == nullptr is OK (e.g. wrong format)
Unique_X509(BIO* mem, bool pem, bool check_null = false) :
Unique_SSL_OBJECT(
pem ? PEM_read_bio_X509(mem, NULL, NULL, NULL) :
d2i_X509_bio(mem, NULL),
X509_free,
check_null)
pem ? read_pem(mem) : d2i_X509_bio(mem, NULL), X509_free, check_null)
{}
Unique_X509(X509* cert, bool check_null) :
Unique_SSL_OBJECT(cert, X509_free, check_null)
Expand Down
11 changes: 11 additions & 0 deletions src/crypto/openssl/verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ namespace ccf::crypto
{
Unique_BIO tcbio(*pem);
Unique_X509 tc(tcbio, true);
if (tc == nullptr)
{
LOG_DEBUG_FMT("Failed to load certificate from PEM: {}", pem->str());
return false;
}

CHECK1(X509_STORE_add_cert(store, tc));
}

Expand All @@ -124,6 +130,11 @@ namespace ccf::crypto
{
Unique_BIO certbio(*pem);
Unique_X509 cert(certbio, true);
if (cert == nullptr)
{
LOG_DEBUG_FMT("Failed to load certificate from PEM: {}", pem->str());
return false;
}

CHECK1(sk_X509_push(chain_stack, cert));
CHECK1(X509_up_ref(cert));
Expand Down
11 changes: 9 additions & 2 deletions src/crypto/pem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,15 @@ namespace ccf::crypto
auto next_separator_start = pem.find(separator);
while (next_separator_start != std::string_view::npos)
{
pems.emplace_back(std::string(
pem.substr(separator_end, next_separator_start + separator.size())));
// Trim whitespace between certificates
while (separator_end < next_separator_start &&
std::isspace(pem[separator_end]))
{
++separator_end;
}
pems.emplace_back(std::string(pem.substr(
separator_end,
(next_separator_start - separator_end) + separator.size())));
separator_end = next_separator_start + separator.size();
next_separator_start = pem.find(separator, separator_end);
}
Expand Down
134 changes: 134 additions & 0 deletions src/crypto/test/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,127 @@ static const string contents_ =

vector<uint8_t> contents(contents_.begin(), contents_.end());

static const string nested_cert =
"MIIV1zCCFL+"
"gAwIBAgIBATANBgkqhkiG9w0BAQsFADAzMTEwLwYDVQQDDChodHRwczovL3NoYXJlZGV1czIuZXV"
"zMi5hdHRlc3QuYXp1cmUubmV0MCIYDzIwMTkwNTAxMDAwMDAwWhgPMjA1MDEyMzEyMzU5NTlaMDM"
"xMTAvBgNVBAMMKGh0dHBzOi8vc2hhcmVkZXVzMi5ldXMyLmF0dGVzdC5henVyZS5uZXQwggEiMA0"
"GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY0GsRB3BdTNXLan5JnuwGPFtV3iJMY0RAm78638L"
"Q0LNcgNPoMwQB5VktKhZZxbqhdDzWH7JBa3D6MVb9I+"
"AbgUZIvVSdU7xlqTzS2Gi9CTR1tkOj72Wyg6c59d89QvRP0CAe2omlSve0J/"
"JFEt0LQyAXW0DKNlsyPxsd7ZmYn0YtMlPm/0TSLmXdLhZljna8zNlpWl/"
"HD7T+zm1HNyg8aoisw6df/uS/mPuyKypko2rp8/7gwe8tv+1fIcKRboXNfyZSXDJE3ME/"
"dHjFpcG/KTMkxoCIJb9iv9PHJx2ebCxNHuF7VDvyrXYqdiou9RWOD+/f39FYZJsWdo/"
"VhfkfAgMBAAGjghLwMIIS7DAJBgNVHRMEAjAAMB0GA1UdDgQWBBRLSJIoQYE9YTEPZ30bgjdlv/"
"RNDzAfBgNVHSMEGDAWgBRLSJIoQYE9YTEPZ30bgjdlv/"
"RNDzCCEp0GCSsGAQQBgjdpAQSCEo4BAAAAAgAAAH4SAAAAAAAAAwACAAAAAAAKAA8Ak5pyM/"
"ecTKmUCg2zlX8GBz6f+cAQUwPfmJD+H0OHgqMAAAAADg4QD///"
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAHAAAAAAAA"
"AMG+d2W08VnHBjXWJzQgwpztMaXmeuK7Kha4P/"
"IN14L3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0ul+"
"6IIVxz5nh9xWOZTagW7ts54B+749ql/"
"ZKevZLgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnSkA919"
"dcepZaKaCsfznfAwh2Hn98t7XPq5Jdg9cJrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAyhAAABbJ695qIni/27w8wj0BRxIueJMn4SZTntdR7/"
"e+s5ajJc+jMXwish9akKmwKqeRdyX3cDnkAjPvY0AjYi/"
"39FZtwI3hoTxkyWE3Vpk8IdKJU+oomqS8snlNp+oT+"
"ClCyILcP78X1k0xk5vi2OO44ktNBTyHIVWAKSSdxNj39TBxDg4QD///"
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQAAAAAAAADnAAAAAAAA"
"AB7AKOTzYYZbiudS8D7kBDlbIscxEdPw8/"
"tDnGuibpX2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMT1d115ZQPpYTf3fGioKaAF"
"asje1wFAsIGwlEkMV7/"
"wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEACgAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvByKZT5Gm6A9i+"
"eXoH22RqqvB4tf80tEosVAMAK0h0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWdf+"
"dceUZCkBvD8ZTZQDgzklLWu5NJKI+"
"QZb3tC4f7ORUBfklfihcUZXLT3Uc4L8jaXnpDYbMplAIsUMueifCAAAAECAwQFBgcICQoLDA0ODx"
"AREhMUFRYXGBkaGxwdHh8FAGIOAAAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRTlEQ0"
"NCSm1nQXdJQkFnSVZBTkxaR05BSUVTOVN3QVA4ZGFocnlTN0daamVqTUFvR0NDcUdTTTQ5QkFNQw"
"pNSEF4SWpBZ0JnTlZCQU1NR1VsdWRHVnNJRk5IV0NCUVEwc2dVR3hoZEdadmNtMGdRMEV4R2pBWU"
"JnTlZCQW9NCkVVbHVkR1ZzSUVOdmNuQnZjbUYwYVc5dU1SUXdFZ1lEVlFRSERBdFRZVzUwWVNCRG"
"JHRnlZVEVMTUFrR0ExVUUKQ0F3Q1EwRXhDekFKQmdOVkJBWVRBbFZUTUI0WERUSTBNRFF3TmpFMU"
"5EZzFNVm9YRFRNeE1EUXdOakUxTkRnMQpNVm93Y0RFaU1DQUdBMVVFQXd3WlNXNTBaV3dnVTBkWU"
"lGQkRTeUJEWlhKMGFXWnBZMkYwWlRFYU1CZ0dBMVVFCkNnd1JTVzUwWld3Z1EyOXljRzl5WVhScG"
"IyNHhGREFTQmdOVkJBY01DMU5oYm5SaElFTnNZWEpoTVFzd0NRWUQKVlFRSURBSkRRVEVMTUFrR0"
"ExVUVCaE1DVlZNd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFRQQpjR2ZYVWpWME"
"RJUDJMajNUY0pXaHJCMmhTbmlVYkRoWVVOSWozL1pLelRMcGcwUXBzS1NHbkd5amlYRFo5cEg1Cm"
"IzbE1yMndJMFpBbFBRcCsyVVV0bzRJRERqQ0NBd293SHdZRFZSMGpCQmd3Rm9BVWxXOWR6YjBiNG"
"VsQVNjblUKOURQT0FWY0wzbFF3YXdZRFZSMGZCR1F3WWpCZ29GNmdYSVphYUhSMGNITTZMeTloY0"
"drdWRISjFjM1JsWkhObApjblpwWTJWekxtbHVkR1ZzTG1OdmJTOXpaM2d2WTJWeWRHbG1hV05oZE"
"dsdmJpOTJNeTl3WTJ0amNtdy9ZMkU5CmNHeGhkR1p2Y20wbVpXNWpiMlJwYm1jOVpHVnlNQjBHQT"
"FVZERnUVdCQlRlWjU1cXR4OEpVMmI4WkFkaTh4aysKQkhReXlUQU9CZ05WSFE4QkFmOEVCQU1DQn"
"NBd0RBWURWUjBUQVFIL0JBSXdBRENDQWpzR0NTcUdTSWI0VFFFTgpBUVNDQWl3d2dnSW9NQjRHQ2"
"lxR1NJYjRUUUVOQVFFRUVQVndZZHdoWU1HbHB4Z2dOK0xnaDBFd2dnRmxCZ29xCmhraUcrRTBCRF"
"FFQ01JSUJWVEFRQmdzcWhraUcrRTBCRFFFQ0FRSUJEakFRQmdzcWhraUcrRTBCRFFFQ0FnSUIKRG"
"pBUUJnc3Foa2lHK0UwQkRRRUNBd0lCQXpBUUJnc3Foa2lHK0UwQkRRRUNCQUlCQXpBUkJnc3Foa2"
"lHK0UwQgpEUUVDQlFJQ0FQOHdFUVlMS29aSWh2aE5BUTBCQWdZQ0FnRC9NQkFHQ3lxR1NJYjRUUU"
"VOQVFJSEFnRUJNQkFHCkN5cUdTSWI0VFFFTkFRSUlBZ0VBTUJBR0N5cUdTSWI0VFFFTkFRSUpBZ0"
"VBTUJBR0N5cUdTSWI0VFFFTkFRSUsKQWdFQU1CQUdDeXFHU0liNFRRRU5BUUlMQWdFQU1CQUdDeX"
"FHU0liNFRRRU5BUUlNQWdFQU1CQUdDeXFHU0liNApUUUVOQVFJTkFnRUFNQkFHQ3lxR1NJYjRUUU"
"VOQVFJT0FnRUFNQkFHQ3lxR1NJYjRUUUVOQVFJUEFnRUFNQkFHCkN5cUdTSWI0VFFFTkFRSVFBZ0"
"VBTUJBR0N5cUdTSWI0VFFFTkFRSVJBZ0VOTUI4R0N5cUdTSWI0VFFFTkFRSVMKQkJBT0RnTUQvLz"
"hCQUFBQUFBQUFBQUFBTUJBR0NpcUdTSWI0VFFFTkFRTUVBZ0FBTUJRR0NpcUdTSWI0VFFFTgpBUV"
"FFQmdCZ2FnQUFBREFQQmdvcWhraUcrRTBCRFFFRkNnRUJNQjRHQ2lxR1NJYjRUUUVOQVFZRUVDVU"
"JVNGp5CmZ0cnVoMmNvdGVnQXlOSXdSQVlLS29aSWh2aE5BUTBCQnpBMk1CQUdDeXFHU0liNFRRRU"
"5BUWNCQVFIL01CQUcKQ3lxR1NJYjRUUUVOQVFjQ0FRRUFNQkFHQ3lxR1NJYjRUUUVOQVFjREFRRU"
"FNQW9HQ0NxR1NNNDlCQU1DQTBrQQpNRVlDSVFDeW9USFpyR3BoSVBnMHczNWJucjJTR3kyMk16T1"
"ZGODRONUhTR3JPL3B2d0loQVA4WmxOYW9aV2hBCmhibVIyUzNVSHg1SjFSS216bzIwKzZJWmpuM3"
"lScjhaCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS"
"0tCk1JSUNsakNDQWoyZ0F3SUJBZ0lWQUpWdlhjMjlHK0hwUUVuSjFQUXp6Z0ZYQzk1VU1Bb0dDQ3"
"FHU000OUJBTUMKTUdneEdqQVlCZ05WQkFNTUVVbHVkR1ZzSUZOSFdDQlNiMjkwSUVOQk1Sb3dHQV"
"lEVlFRS0RCRkpiblJsYkNCRApiM0p3YjNKaGRHbHZiakVVTUJJR0ExVUVCd3dMVTJGdWRHRWdRMn"
"hoY21FeEN6QUpCZ05WQkFnTUFrTkJNUXN3CkNRWURWUVFHRXdKVlV6QWVGdzB4T0RBMU1qRXhNRF"
"V3TVRCYUZ3MHpNekExTWpFeE1EVXdNVEJhTUhBeElqQWcKQmdOVkJBTU1HVWx1ZEdWc0lGTkhXQ0"
"JRUTBzZ1VHeGhkR1p2Y20wZ1EwRXhHakFZQmdOVkJBb01FVWx1ZEdWcwpJRU52Y25CdmNtRjBhVz"
"l1TVJRd0VnWURWUVFIREF0VFlXNTBZU0JEYkdGeVlURUxNQWtHQTFVRUNBd0NRMEV4CkN6QUpCZ0"
"5WQkFZVEFsVlRNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVOU0IvN3QyMWxYU0"
"8KMkN1enB4dzc0ZUpCNzJFeURHZ1c1clhDdHgydFZUTHE2aEtrNnorVWlSWkNucVI3cHNPdmdxRm"
"VTeGxtVGxKbAplVG1pMldZejNxT0J1ekNCdURBZkJnTlZIU01FR0RBV2dCUWlaUXpXV3AwMGlmT0"
"R0SlZTdjFBYk9TY0dyREJTCkJnTlZIUjhFU3pCSk1FZWdSYUJEaGtGb2RIUndjem92TDJObGNuUn"
"BabWxqWVhSbGN5NTBjblZ6ZEdWa2MyVnkKZG1salpYTXVhVzUwWld3dVkyOXRMMGx1ZEdWc1UwZF"
"lVbTl2ZEVOQkxtUmxjakFkQmdOVkhRNEVGZ1FVbFc5ZAp6YjBiNGVsQVNjblU5RFBPQVZjTDNsUX"
"dEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCCkFmOENBUUF3Q2dZSUtvWk"
"l6ajBFQXdJRFJ3QXdSQUlnWHNWa2kwdytpNlZZR1czVUYvMjJ1YVhlMFlKRGoxVWUKbkErVGpEMW"
"FpNWNDSUNZYjFTQW1ENXhrZlRWcHZvNFVveWlTWXhyRFdMbVVSNENJOU5LeWZQTisKLS0tLS1FTk"
"QgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ2p6Q0NBal"
"NnQXdJQkFnSVVJbVVNMWxxZE5JbnpnN1NWVXI5UUd6a25CcXd3Q2dZSUtvWkl6ajBFQXdJdwphRE"
"VhTUJnR0ExVUVBd3dSU1c1MFpXd2dVMGRZSUZKdmIzUWdRMEV4R2pBWUJnTlZCQW9NRVVsdWRHVn"
"NJRU52CmNuQnZjbUYwYVc5dU1SUXdFZ1lEVlFRSERBdFRZVzUwWVNCRGJHRnlZVEVMTUFrR0ExVU"
"VDQXdDUTBFeEN6QUoKQmdOVkJBWVRBbFZUTUI0WERURTRNRFV5TVRFd05EVXhNRm9YRFRRNU1USX"
"pNVEl6TlRrMU9Wb3dhREVhTUJnRwpBMVVFQXd3UlNXNTBaV3dnVTBkWUlGSnZiM1FnUTBFeEdqQV"
"lCZ05WQkFvTUVVbHVkR1ZzSUVOdmNuQnZjbUYwCmFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQk"
"RiR0Z5WVRFTE1Ba0dBMVVFQ0F3Q1EwRXhDekFKQmdOVkJBWVQKQWxWVE1Ga3dFd1lIS29aSXpqME"
"NBUVlJS29aSXpqMERBUWNEUWdBRUM2bkV3TURJWVpPai9pUFdzQ3phRUtpNwoxT2lPU0xSRmhXR2"
"pibkJWSmZWbmtZNHUzSWprRFlZTDBNeE80bXFzeVlqbEJhbFRWWXhGUDJzSkJLNXpsS09CCnV6Q0"
"J1REFmQmdOVkhTTUVHREFXZ0JRaVpReldXcDAwaWZPRHRKVlN2MUFiT1NjR3JEQlNCZ05WSFI4RV"
"N6QkoKTUVlZ1JhQkRoa0ZvZEhSd2N6b3ZMMk5sY25ScFptbGpZWFJsY3k1MGNuVnpkR1ZrYzJWeW"
"RtbGpaWE11YVc1MApaV3d1WTI5dEwwbHVkR1ZzVTBkWVVtOXZkRU5CTG1SbGNqQWRCZ05WSFE0RU"
"ZnUVVJbVVNMWxxZE5JbnpnN1NWClVyOVFHemtuQnF3d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJJR0"
"ExVWRFd0VCL3dRSU1BWUJBZjhDQVFFd0NnWUkKS29aSXpqMEVBd0lEU1FBd1JnSWhBT1cvNVFrUi"
"tTOUNpU0RjTm9vd0x1UFJMc1dHZi9ZaTdHU1g5NEJnd1R3ZwpBaUVBNEowbHJIb01zK1hvNW8vc1"
"g2TzlRV3hIUkF2WlVHT2RSUTdjdnFSWGFxST0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoAMA"
"0GCSqGSIb3DQEBCwUAA4IBAQAWPfe1yj4TfaxWipdcjCX+"
"NBJQtQOvhu6TbkzwWczIkvcCQ8O6dzsnMDFkxVkZ2ZlcsufSaB74VS//3BzOh/PLWpSX/"
"TaQHxFKhcK5RxlEq0O/oINnJ7fMhKlrd/hyoD/"
"P2bSLej5zdh63JciGxNGXkanchgQ8qNxXhs9oRUJINYYinFfRsD3OzX6dsHLPVshkdOZFpM9DgP2"
"QozqQJ1GC4tAKwbktxU0Ai3BecoPFzYVIygGLY1BAGd112C6cktj7YZTWE/"
"tCSD+uXWyQieBu5zUN7H/PcxY9VBT/fOkBfaaL+JcpG4/tGrbTTbZUUclzKVQ/5XP6bOa1t6r/"
"zN/W";

static const string pem_key_for_nested_cert =
"-----BEGIN PUBLIC "
"KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2NBrEQdwXUzVy2p+"
"SZ7s\nBjxbVd4iTGNEQJu/Ot/C0NCzXIDT6DMEAeVZLSoWWcW6oXQ81h+yQWtw+jFW/"
"SPg\nG4FGSL1UnVO8Zak80thovQk0dbZDo+"
"9lsoOnOfXfPUL0T9AgHtqJpUr3tCfyRRLd\nC0MgF1tAyjZbMj8bHe2ZmJ9GLTJT5v9E0i5l3S4W"
"ZY52vMzZaVpfxw+0/s5tRzco\nPGqIrMOnX/7kv5j7sisqZKNq6fP+4MHvLb/"
"tXyHCkW6FzX8mUlwyRNzBP3R4xaXB\nvykzJMaAiCW/Yr/"
"TxycdnmwsTR7he1Q78q12KnYqLvUVjg/v39/RWGSbFnaP1YX5\nHwIDAQAB\n-----END "
"PUBLIC KEY-----\n";

template <typename T>
void corrupt(T& buf)
{
Expand All @@ -69,6 +190,19 @@ ccf::crypto::Pem generate_self_signed_cert(
kp, name, {}, valid_from, certificate_validity_period_days);
}

TEST_CASE("Check verifier handles nested certs for both PEM and DER inputs")
{
auto cert_der = ccf::crypto::raw_from_b64(nested_cert);
auto cert_pem = fmt::format(
"-----BEGIN CERTIFICATE-----\n{}\n-----END CERTIFICATE-----", nested_cert);
auto der_verifier = make_verifier(cert_der);
auto pem_verifier = make_verifier(cert_pem);
auto pem_key_from_der = der_verifier->public_key_pem();
auto pem_key_from_pem = pem_verifier->public_key_pem();
CHECK(pem_key_from_der.str() == pem_key_from_pem.str());
CHECK(pem_key_from_der.str() == pem_key_for_nested_cert);
}

TEST_CASE("Sign, verify, with KeyPair")
{
for (const auto curve : supported_curves)
Expand Down
41 changes: 34 additions & 7 deletions src/crypto/test/pem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@
using namespace std;
using namespace ccf::crypto;

void check_bundles(
const std::string& single_cert,
const Pem& cert_pem,
bool lr_before = false,
bool lr_after = false)
{
for (size_t count : {1, 2, 3, 10})
{
std::string certs;
for (size_t i = 0; i < count; ++i)
{
if (lr_before)
{
certs += "\n";
}
certs += single_cert;
if (lr_after)
{
certs += "\n";
}
}
auto bundle = split_x509_cert_bundle(certs);
REQUIRE(bundle.size() == count);
for (const auto& pem : bundle)
{
REQUIRE(pem == cert_pem);
}
}
}

TEST_CASE("Split x509 cert bundle")
{
REQUIRE(split_x509_cert_bundle("") == std::vector<Pem>{});
Expand All @@ -31,14 +61,11 @@ TEST_CASE("Split x509 cert bundle")
"\n-----END CERTIFICATE-----";
auto bundle = split_x509_cert_bundle(single_cert);
const auto cert_pem = Pem(single_cert);
REQUIRE(bundle.size() == 1);
REQUIRE(bundle[0] == cert_pem);

const std::string two_certs = single_cert + single_cert;
bundle = split_x509_cert_bundle(two_certs);
REQUIRE(bundle.size() == 2);
REQUIRE(bundle[0] == cert_pem);
REQUIRE(bundle[1] == cert_pem);
check_bundles(single_cert, cert_pem);
check_bundles(single_cert, cert_pem, true);
check_bundles(single_cert, cert_pem, false, true);
check_bundles(single_cert, cert_pem, true, true);

std::string bundle_with_invalid_suffix = single_cert + "ignored suffix";
bundle = split_x509_cert_bundle(bundle_with_invalid_suffix);
Expand Down

0 comments on commit bb25588

Please sign in to comment.