]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
auth: CryptoKey, use dynamic usage keys
authorMarcus Watts <mwatts@redhat.com>
Sat, 15 Nov 2025 08:05:59 +0000 (03:05 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 5 Jan 2026 21:23:41 +0000 (16:23 -0500)
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 <mwatts@redhat.com>
src/auth/cephx/CephxClientHandler.cc
src/auth/cephx/CephxKeyServer.cc
src/auth/cephx/CephxProtocol.cc
src/auth/cephx/CephxProtocol.h
src/auth/cephx/CephxServiceHandler.cc

index 451fdb4fc28b4041903601db1f9834f5a956a450..fcfbcfc67122208ac667a5fc1ce89857274e881c 100644 (file)
@@ -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;
index 2d6aa8765ed7c59b2b86952f8c21b81d41e7210f..a9aeea5c0b78803074af4706bc792d7cf641723f 100644 (file)
@@ -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;
index 10eda69c1f49c9029100f4bccc372994e57bcd7a..57b50e1e327c0382af203d20a52694df3ef881ed 100644 (file)
@@ -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;
   }
index 02daace84b34f88a9e330848acd0e2abeb0d2251..fb431a84cbca2d4dd79a971c9e11fc1e1407700e 100644 (file)
@@ -630,6 +630,34 @@ void decode_decrypt_enc_bl(CephContext *cct, T& t, const CryptoKey& key,
   decode(t, iter2);
 }
 
+template <typename T>
+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 <typename T>
 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 <typename T>
+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 <typename T>
 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 <typename T>
+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 <typename T>
 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 <typename T>
+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 <typename T>
 int encode_hash(CephContext *cct, const T& t, const CryptoKey& key,
                 ceph::buffer::list& out, std::string &error)
index ca5b721bf63aa074d65c888b86920224615e7570..9366dd8963cc1ae95d6dae629204412c7b23f132 100644 (file)
@@ -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;