From 5342b71c084b619ba47bd93728ad56d4f4789064 Mon Sep 17 00:00:00 2001 From: Marcus Watts Date: Sat, 15 Nov 2025 03:05:59 -0500 Subject: [PATCH] auth: CryptoKey, use dynamic usage keys Use new extended api to implement non-zero usage constants. 3 std::string connection_secret 4 CephXServiceTicket 5 encode(CephXTicketBlob) 10 CephXServiceTicketInfo 11 CephXAuthorize 13 CephXAuthorizeChallenge 15 CephXAuthorizeReply 16 RotatingSecrets Generally speaking, these keys are constructed by "CryptoKey::decode" which does not know the context for how the key will be used, so usage can't be set here. In a brief experiment, these usages for keys were invoked by keys decoded under these routines: 3 4 5 CephxClientHandler::handle_response 11 13 15 CephXTicketHandler::verify_service_ticket_reply Signed-off-by: Marcus Watts --- src/auth/cephx/CephxClientHandler.cc | 4 +- src/auth/cephx/CephxKeyServer.cc | 2 +- src/auth/cephx/CephxProtocol.cc | 28 +++++----- src/auth/cephx/CephxProtocol.h | 77 +++++++++++++++++++++++++++ src/auth/cephx/CephxServiceHandler.cc | 2 +- 5 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/auth/cephx/CephxClientHandler.cc b/src/auth/cephx/CephxClientHandler.cc index 451fdb4fc28..fcfbcfc6712 100644 --- a/src/auth/cephx/CephxClientHandler.cc +++ b/src/auth/cephx/CephxClientHandler.cc @@ -228,7 +228,7 @@ int CephxClientHandler::handle_response( if (cbl.length() && connection_secret) { auto p = cbl.cbegin(); string err; - if (decode_decrypt(cct, *connection_secret, *session_key, p, + if (decode_decrypt(cct, *connection_secret, *session_key, 3, p, err)) { lderr(cct) << __func__ << " failed to decrypt connection_secret" << dendl; @@ -284,7 +284,7 @@ int CephxClientHandler::handle_response( return -ENOENT; } std::string error; - if (decode_decrypt(cct, secrets, secret_key, indata, error)) { + if (decode_decrypt(cct, secrets, secret_key, 16, indata, error)) { ldout(cct, 0) << "could not set rotating key: decode_decrypt failed. error:" << error << dendl; return -EINVAL; diff --git a/src/auth/cephx/CephxKeyServer.cc b/src/auth/cephx/CephxKeyServer.cc index 2d6aa8765ed..a9aeea5c0b7 100644 --- a/src/auth/cephx/CephxKeyServer.cc +++ b/src/auth/cephx/CephxKeyServer.cc @@ -450,7 +450,7 @@ bool KeyServer::get_rotating_encrypted(const EntityName& name, RotatingSecrets secrets = rotate_iter->second; std::string error; - if (encode_encrypt(cct, secrets, specific_key, enc_bl, error)) + if (encode_encrypt(cct, secrets, specific_key, 16, enc_bl, error)) return false; return true; diff --git a/src/auth/cephx/CephxProtocol.cc b/src/auth/cephx/CephxProtocol.cc index 10eda69c1f4..57b50e1e327 100644 --- a/src/auth/cephx/CephxProtocol.cc +++ b/src/auth/cephx/CephxProtocol.cc @@ -93,7 +93,7 @@ bool cephx_build_service_ticket_blob(CephContext *cct, const CephXSessionAuthInf if (info.service_secret.empty()) error = "invalid key"; // Bad key? else - encode_encrypt_enc_bl(cct, ticket_info, info.service_secret, blob.blob, error); + encode_encrypt_enc_bl(cct, ticket_info, info.service_secret, 10, blob.blob, error); if (!error.empty()) { ldout(cct, -1) << "cephx_build_service_ticket_blob failed with error " << error << dendl; @@ -139,7 +139,7 @@ bool cephx_build_service_ticket_reply(CephContext *cct, msg_a.session_key = info.session_key; msg_a.validity = info.validity; std::string error; - if (encode_encrypt(cct, msg_a, principal_secret, reply, error)) { + if (encode_encrypt(cct, msg_a, principal_secret, 4, reply, error)) { ldout(cct, -1) << "error encoding encrypted: " << error << dendl; return false; } @@ -157,7 +157,7 @@ bool cephx_build_service_ticket_reply(CephContext *cct, encode((__u8)should_encrypt_ticket, reply); if (should_encrypt_ticket) { - if (encode_encrypt(cct, service_ticket_bl, ticket_enc_key, reply, error)) { + if (encode_encrypt(cct, service_ticket_bl, ticket_enc_key, 5, reply, error)) { ldout(cct, -1) << "error encoding encrypted ticket: " << error << dendl; return false; } @@ -183,7 +183,7 @@ bool CephXTicketHandler::verify_service_ticket_reply( CephXServiceTicket msg_a; std::string error; - if (decode_decrypt(cct, msg_a, secret, indata, error)) { + if (decode_decrypt(cct, msg_a, secret, 4, indata, error)) { ldout(cct, 0) << __func__ << " failed decode_decrypt, error is: " << error << dendl; return false; @@ -196,7 +196,7 @@ bool CephXTicketHandler::verify_service_ticket_reply( if (ticket_enc) { ldout(cct, 10) << __func__ << " got encrypted ticket" << dendl; std::string error; - if (decode_decrypt(cct, service_ticket_bl, session_key, indata, error)) { + if (decode_decrypt(cct, service_ticket_bl, session_key, 5, indata, error)) { ldout(cct, 10) << __func__ << " decode_decrypt failed " << "with " << error << dendl; return false; @@ -367,7 +367,7 @@ CephXAuthorizer *CephXTicketHandler::build_authorizer(uint64_t global_id) const msg.nonce = a->nonce; std::string error; - if (encode_encrypt(cct, msg, session_key, a->bl, error)) { + if (encode_encrypt(cct, msg, session_key, 11, a->bl, error)) { ldout(cct, 0) << "failed to encrypt authorizer: " << error << dendl; delete a; return 0; @@ -433,7 +433,7 @@ bool cephx_decode_ticket(CephContext *cct, KeyStore *keys, } std::string error; - decode_decrypt_enc_bl(cct, ticket_info, service_secret, ticket_blob.blob, error); + decode_decrypt_enc_bl(cct, ticket_info, service_secret, 10, ticket_blob.blob, error); if (!error.empty()) { ldout(cct, 0) << "ceph_decode_ticket could not decrypt ticket info. error:" << error << dendl; @@ -502,7 +502,7 @@ bool cephx_verify_authorizer(CephContext *cct, const KeyStore& keys, if (service_secret.empty()) error = "invalid key"; // Bad key? else - decode_decrypt_enc_bl(cct, ticket_info, service_secret, ticket.blob, error); + decode_decrypt_enc_bl(cct, ticket_info, service_secret, 10, ticket.blob, error); if (!error.empty()) { ldout(cct, 0) << __func__ << ": could not decrypt ticket info: " << error << dendl; return false; @@ -521,7 +521,7 @@ bool cephx_verify_authorizer(CephContext *cct, const KeyStore& keys, CephXAuthorize auth_msg; if (ticket_info.session_key.empty()) { error = "session key is invalid"; - } else if (!decode_decrypt(cct, auth_msg, ticket_info.session_key, indata, error)) { + } else if (!decode_decrypt(cct, auth_msg, ticket_info.session_key, 11, indata, error)) { error = ""; } if (!error.empty()) { @@ -538,7 +538,7 @@ bool cephx_verify_authorizer(CephContext *cct, const KeyStore& keys, ldout(cct,10) << __func__ << ": adding server_challenge " << c->server_challenge << dendl; - encode_encrypt_enc_bl(cct, *c, ticket_info.session_key, *reply_bl, error); + encode_encrypt_enc_bl(cct, *c, ticket_info.session_key, 13, *reply_bl, error); if (!error.empty()) { ldout(cct, 0) << __func__ << ": encode_encrypt error: " << error << dendl; return false; @@ -576,7 +576,7 @@ bool cephx_verify_authorizer(CephContext *cct, const KeyStore& keys, } reply.connection_secret = *connection_secret; } - if (encode_encrypt(cct, reply, ticket_info.session_key, *reply_bl, error)) { + if (encode_encrypt(cct, reply, ticket_info.session_key, 15, *reply_bl, error)) { ldout(cct, 10) << "verify_authorizer: encode_encrypt error: " << error << dendl; return false; } @@ -592,7 +592,7 @@ bool CephXAuthorizer::verify_reply(bufferlist::const_iterator& indata, CephXAuthorizeReply reply; std::string error; - if (decode_decrypt(cct, reply, session_key, indata, error)) { + if (decode_decrypt(cct, reply, session_key, 15, indata, error)) { ldout(cct, 0) << "verify_reply couldn't decrypt with error: " << error << dendl; return false; } @@ -623,7 +623,7 @@ bool CephXAuthorizer::add_challenge(CephContext *cct, if (!p.end()) { std::string error; CephXAuthorizeChallenge ch{}; - decode_decrypt_enc_bl(cct, ch, session_key, challenge, error); + decode_decrypt_enc_bl(cct, ch, session_key, 13, challenge, error); if (!error.empty()) { ldout(cct, 0) << "failed to decrypt challenge (" << challenge.length() << " bytes): " << error << dendl; @@ -634,7 +634,7 @@ bool CephXAuthorizer::add_challenge(CephContext *cct, } std::string error; - if (encode_encrypt(cct, msg, session_key, bl, error)) { + if (encode_encrypt(cct, msg, session_key, 11, bl, error)) { ldout(cct, 0) << __func__ << " failed to encrypt authorizer: " << error << dendl; return false; } diff --git a/src/auth/cephx/CephxProtocol.h b/src/auth/cephx/CephxProtocol.h index 02daace84b3..fb431a84cbc 100644 --- a/src/auth/cephx/CephxProtocol.h +++ b/src/auth/cephx/CephxProtocol.h @@ -630,6 +630,34 @@ void decode_decrypt_enc_bl(CephContext *cct, T& t, const CryptoKey& key, decode(t, iter2); } +template +void decode_decrypt_enc_bl(CephContext *cct, T& t, const CryptoKey& key, + uint32_t usage, const ceph::buffer::list& bl_enc, + std::string &error) +{ + uint64_t magic; + ceph::buffer::list bl; + + if (key.decrypt_ext(cct, usage, bl_enc, bl, &error) < 0) { + error = "decryption failed"; + return; + } + + auto iter2 = bl.cbegin(); + __u8 struct_v; + using ceph::decode; + decode(struct_v, iter2); + decode(magic, iter2); + if (magic != AUTH_ENC_MAGIC) { + std::ostringstream oss; + oss << "bad magic in decode_decrypt, " << magic << " != " << AUTH_ENC_MAGIC; + error = oss.str(); + return; + } + + decode(t, iter2); +} + template void encode_encrypt_enc_bl(CephContext *cct, const T& t, const CryptoKey& key, ceph::buffer::list& out, std::string &error) @@ -645,6 +673,22 @@ void encode_encrypt_enc_bl(CephContext *cct, const T& t, const CryptoKey& key, key.encrypt(cct, bl, out, &error); } +template +void encode_encrypt_enc_bl(CephContext *cct, const T& t, const CryptoKey& key, + uint32_t usage, ceph::buffer::list& out, + std::string &error) +{ + ceph::buffer::list bl; + __u8 struct_v = 1; + using ceph::encode; + encode(struct_v, bl); + uint64_t magic = AUTH_ENC_MAGIC; + encode(magic, bl); + encode(t, bl); + + key.encrypt_ext(cct, usage, bl, out, &error); +} + template int decode_decrypt(CephContext *cct, T& t, const CryptoKey& key, ceph::buffer::list::const_iterator& iter, std::string &error) @@ -663,6 +707,25 @@ int decode_decrypt(CephContext *cct, T& t, const CryptoKey& key, return 0; } +template +int decode_decrypt(CephContext *cct, T& t, const CryptoKey& key, + uint32_t usage, ceph::buffer::list::const_iterator& iter, + std::string &error) +{ + ceph::buffer::list bl_enc; + using ceph::decode; + try { + decode(bl_enc, iter); + decode_decrypt_enc_bl(cct, t, key, usage, bl_enc, error); + } + catch (ceph::buffer::error &e) { + error = "error decoding block for decryption"; + } + if (!error.empty()) + return CEPHX_CRYPT_ERR; + return 0; +} + template int encode_encrypt(CephContext *cct, const T& t, const CryptoKey& key, ceph::buffer::list& out, std::string &error) @@ -677,6 +740,20 @@ int encode_encrypt(CephContext *cct, const T& t, const CryptoKey& key, return 0; } +template +int encode_encrypt(CephContext *cct, const T& t, const CryptoKey& key, + uint32_t usage, ceph::buffer::list& out, std::string &error) +{ + using ceph::encode; + ceph::buffer::list bl_enc; + encode_encrypt_enc_bl(cct, t, key, usage, bl_enc, error); + if (!error.empty()){ + return CEPHX_CRYPT_ERR; + } + encode(bl_enc, out); + return 0; +} + template int encode_hash(CephContext *cct, const T& t, const CryptoKey& key, ceph::buffer::list& out, std::string &error) diff --git a/src/auth/cephx/CephxServiceHandler.cc b/src/auth/cephx/CephxServiceHandler.cc index ca5b721bf63..9366dd8963c 100644 --- a/src/auth/cephx/CephxServiceHandler.cc +++ b/src/auth/cephx/CephxServiceHandler.cc @@ -318,7 +318,7 @@ int CephxServiceHandler::handle_request( connection_secret_required_len); } std::string err; - if (encode_encrypt(cct, *pconnection_secret, session_key, cbl, + if (encode_encrypt(cct, *pconnection_secret, session_key, 3, cbl, err)) { lderr(cct) << __func__ << " failed to encrypt connection secret, " << err << dendl; -- 2.47.3