20 if (!jwk.
e || jwk.
e->empty() || !jwk.
n || jwk.
n->empty())
25 std::vector<uint8_t> der;
28 data.
kid = jwk.
kid.value();
29 data.
n = jwk.
n.value();
30 data.
e = jwk.
e.value();
34 return pubkey->public_key_der();
36 catch (
const std::invalid_argument& exc)
38 throw std::logic_error(
39 fmt::format(
"Failed to construct RSA public key: {}", exc.what()));
45 if (!jwk.
x || jwk.
x->empty() || !jwk.
y || jwk.
y->empty() || !jwk.
crv)
52 data.
kid = jwk.
kid.value();
53 data.
crv = jwk.
crv.value();
54 data.
x = jwk.
x.value();
55 data.
y = jwk.
y.value();
59 return pubkey->public_key_der();
61 catch (
const std::invalid_argument& exc)
63 throw std::logic_error(
64 fmt::format(
"Failed to construct EC public key: {}", exc.what()));
70 if (!jwk.
x5c || jwk.
x5c->empty())
75 const auto& kid = jwk.
kid.value();
76 auto& der_base64 = jwk.
x5c.value()[0];
82 catch (
const std::invalid_argument& e)
84 throw std::logic_error(
85 fmt::format(
"Could not parse x5c of key id {}: {}", kid, e.what()));
90 return verifier->public_key_der();
92 catch (std::invalid_argument& exc)
94 throw std::logic_error(fmt::format(
95 "JWKS kid {} has an invalid X.509 certificate: {}", kid, exc.what()));
101 const auto& kid = jwk.
kid.value();
102 auto key = try_parse_raw_rsa(jwk);
107 key = try_parse_raw_ec(jwk);
112 key = try_parse_x5c(jwk);
118 throw std::logic_error(
119 fmt::format(
"JWKS kid {} has neither RSA/EC public key or x5c", kid));
125 static void legacy_remove_jwt_public_signing_keys(
129 Tables::Legacy::JWT_PUBLIC_SIGNING_KEYS);
131 Tables::Legacy::JWT_PUBLIC_SIGNING_KEY_ISSUER);
134 [&issuer, &keys, &key_issuer](
const auto& k,
const auto& v) {
138 key_issuer->remove(k);
144 Tables::Legacy::JWT_PUBLIC_SIGNING_KEYS_METADATA);
145 metadata->foreach([&issuer, &metadata](
const auto& k,
const auto& v) {
146 std::vector<OpenIDJWKMetadataLegacy> updated;
147 for (
const auto& key : v)
149 if (
key.issuer != issuer)
151 updated.push_back(key);
159 else if (updated.size() < v.size())
161 metadata->put(k, updated);
168 static bool check_issuer_constraint(
169 const std::string& issuer,
const std::string& constraint)
178 if (constraint_domain.empty())
190 if (issuer_domain != constraint_domain)
192 const auto pattern =
"." + constraint_domain;
193 return issuer_domain.ends_with(pattern);
199 static void remove_jwt_public_signing_keys(
205 legacy_remove_jwt_public_signing_keys(tx, issuer);
208 Tables::JWT_PUBLIC_SIGNING_KEYS_METADATA);
210 keys->foreach([&issuer, &keys](
const auto& k,
const auto& v) {
211 auto it = find_if(v.begin(), v.end(), [&](
const auto& metadata) {
212 return metadata.issuer == issuer;
217 std::vector<OpenIDJWKMetadata> updated(v.begin(), it);
218 updated.insert(updated.end(), ++it, v.end());
220 if (!updated.empty())
222 keys->put(k, updated);
233 static bool set_jwt_public_signing_keys(
235 const std::string& log_prefix,
237 const JwtIssuerMetadata& issuer_metadata,
238 const JsonWebKeySet& jwks)
241 Tables::JWT_PUBLIC_SIGNING_KEYS_METADATA);
243 if (jwks.keys.empty())
248 std::map<std::string, PublicKey> new_keys;
249 std::map<std::string, JwtIssuer> issuer_constraints;
253 for (
auto& jwk : jwks.keys)
255 if (!jwk.
kid.has_value())
257 throw std::logic_error(
"Missing kid for JWT signing key");
260 const auto& kid = jwk.
kid.value();
261 auto key_der = try_parse_jwk(jwk);
265 if (!check_issuer_constraint(issuer, *jwk.
issuer))
267 throw std::logic_error(fmt::format(
268 "JWKS kid {} with issuer constraint {} fails validation "
276 issuer_constraints.emplace(kid, *jwk.
issuer);
279 new_keys.emplace(kid, key_der);
282 catch (
const std::exception& exc)
288 if (new_keys.empty())
290 LOG_FAIL_FMT(
"{}: no keys left after applying filter", log_prefix);
294 std::set<std::string> existing_kids;
295 keys->foreach([&existing_kids, &issuer_constraints, &issuer](
296 const auto& k,
const auto& v) {
297 if (find_if(v.begin(), v.end(), [&](
const auto& metadata) {
298 return metadata.issuer == issuer;
301 existing_kids.insert(k);
307 for (
auto& [kid, der] : new_keys)
309 OpenIDJWKMetadata value{
310 .public_key = der, .issuer = issuer, .constraint = std::nullopt};
311 value.public_key = der;
313 const auto it = issuer_constraints.find(kid);
314 if (it != issuer_constraints.end())
316 value.constraint = it->second;
319 if (existing_kids.count(kid))
321 const auto& keys_for_kid = keys->get(kid);
324 keys_for_kid->begin(),
326 [&value](
const auto& metadata) {
327 return metadata.public_key == value.public_key &&
328 metadata.issuer == value.issuer &&
329 metadata.constraint == value.constraint;
330 }) != keys_for_kid->end())
338 "Save JWT key kid={} issuer={}, constraint={}",
343 auto existing_keys = keys->get(kid);
346 const auto prev = find_if(
347 existing_keys->begin(),
348 existing_keys->end(),
349 [&](
const auto& issuer_with_constraint) {
350 return issuer_with_constraint.issuer == issuer;
353 if (prev != existing_keys->end())
359 existing_keys->push_back(std::move(value));
361 keys->put(kid, *existing_keys);
365 keys->put(kid, std::vector<OpenIDJWKMetadata>{value});
369 for (
auto& kid : existing_kids)
371 if (!new_keys.contains(kid))
373 auto updated = keys->get(kid);
378 [&](
const auto& metadata) { return metadata.issuer == issuer; }),
381 if (updated->empty())
387 keys->put(kid, *updated);
M::Handle * rw(M &m)
Definition tx.h:212
#define LOG_DEBUG_FMT
Definition logger.h:357
#define LOG_FAIL_FMT
Definition logger.h:363
ccf::kv::RawCopySerialisedMap< JwtKeyId, JwtIssuer > JwtPublicSigningKeyIssuer
Definition jwt.h:87
ccf::kv::RawCopySerialisedMap< JwtKeyId, Cert > JwtPublicSigningKeys
Definition jwt.h:85
VerifierUniquePtr make_unique_verifier(const std::vector< uint8_t > &cert)
Definition verifier.cpp:13
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
PublicKeyPtr make_public_key(const Pem &pem)
Definition key_pair.cpp:20
RSAPublicKeyPtr make_rsa_public_key(const Pem &pem)
Definition rsa_key_pair.cpp:13
uint8_t * key
Definition kv_helpers.h:78
Definition app_interface.h:14
std::vector< uint8_t > Cert
Definition jwt.h:37
ServiceMap< JwtKeyId, std::vector< OpenIDJWKMetadata > > JwtPublicSigningKeysMetadata
Definition jwt.h:51
ServiceMap< JwtKeyId, std::vector< OpenIDJWKMetadataLegacy > > JwtPublicSigningKeysMetadataLegacy
Definition jwt.h:64
URL parse_url_full(const std::string &url)
Definition http_parser.h:145
std::optional< std::string > n
Definition jwk.h:54
std::optional< std::string > x
Definition jwk.h:56
std::optional< std::vector< std::string > > x5c
Definition jwk.h:53
std::optional< JsonWebKeyECCurve > crv
Definition jwk.h:58
std::optional< std::string > kid
Definition jwk.h:52
std::optional< std::string > issuer
Definition jwk.h:59
std::optional< std::string > e
Definition jwk.h:55
std::optional< std::string > y
Definition jwk.h:57
std::string x
Definition jwk.h:120
JsonWebKeyECCurve crv
Definition jwk.h:119
std::string y
Definition jwk.h:121
std::string e
Definition jwk.h:140
std::string n
Definition jwk.h:139
std::optional< std::string > kid
Definition jwk.h:28
JsonWebKeyType kty
Definition jwk.h:27
std::string host
Definition http_parser.h:138