Skip to content

Commit

Permalink
[release/5.x] Cherry pick: Handle multiple certificates in JWT CA bun…
Browse files Browse the repository at this point in the history
…dle correctly (#6818) (#6819)
  • Loading branch information
achamayou authored Feb 7, 2025
1 parent fa0ab62 commit 57839ca
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ 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.11]
## [5.0.0-12]

[5.0.0-12]: https://github.com/microsoft/CCF/releases/tag/5.0.0-12

### Fixed

- CA certificate bundles used for JWT refresh and containing more than one certificate are now handled correctly (#6817).

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

Expand Down
4 changes: 3 additions & 1 deletion src/node/jwt_key_auto_refresh.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ namespace ccf
auto metadata_url_port =
!metadata_url.port.empty() ? metadata_url.port : "443";

auto ca = std::make_shared<::tls::CA>(ca_cert_bundle_pem.value());
auto ca_pems =
crypto::split_x509_cert_bundle(ca_cert_bundle_pem.value());
auto ca = std::make_shared<::tls::CA>(ca_pems);
auto ca_cert = std::make_shared<::tls::Cert>(
ca, std::nullopt, std::nullopt, metadata_url.host);

Expand Down
9 changes: 9 additions & 0 deletions src/tls/ca.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ namespace tls
}
}

CA(const std::vector<ccf::crypto::Pem>& ca_pems, bool partial_ok_ = false) :
partial_ok(partial_ok_)
{
for (const auto& ca_pem : ca_pems)
{
append_cert(ca_pem.str());
}
}

~CA() = default;

void use(SSL_CTX* ssl_ctx)
Expand Down
39 changes: 35 additions & 4 deletions tests/jwt_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,13 +746,43 @@ def test_jwt_key_initial_refresh(network, args):
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----"""

DIGICERT_GLOBAL_ROOT_G2_CA = """-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----"""

def test_jwt_key_refresh_aad(network, args):

def test_jwt_key_refresh_aad(network, args, ascending=True):
primary, _ = network.find_nodes()

LOG.info("Add CA cert for Entra JWT issuer")
with tempfile.NamedTemporaryFile(prefix="ccf", mode="w+") as ca_cert_bundle_fp:
ca_cert_bundle_fp.write(DIGICERT_GLOBAL_ROOT_CA)
if ascending:
ca_cert_bundle_fp.write(DIGICERT_GLOBAL_ROOT_CA)
ca_cert_bundle_fp.write("\n")
ca_cert_bundle_fp.write(DIGICERT_GLOBAL_ROOT_G2_CA)
else:
ca_cert_bundle_fp.write(DIGICERT_GLOBAL_ROOT_G2_CA)
ca_cert_bundle_fp.write("\n")
ca_cert_bundle_fp.write(DIGICERT_GLOBAL_ROOT_CA)
ca_cert_bundle_fp.flush()
network.consortium.set_ca_cert_bundle(primary, "aad", ca_cert_bundle_fp.name)

Expand Down Expand Up @@ -806,8 +836,9 @@ def run_auto(args):
primary.stop()
network.wait_for_new_primary(primary)
test_jwt_key_auto_refresh(network, args)
# Check that we can refresh keys for AAD endpoint
test_jwt_key_refresh_aad(network, args)
# Check that we can refresh keys for Entra endpoint
test_jwt_key_refresh_aad(network, args, ascending=True)
test_jwt_key_refresh_aad(network, args, ascending=False)
test_jwt_key_auto_refresh_entries(network, args)


Expand Down

0 comments on commit 57839ca

Please sign in to comment.