From: Isaac Boukris Date: Mon, 24 Jun 2019 10:06:38 +0000 (+0300) Subject: Fix authdata signatures for non-TGT AS-REQs X-Git-Tag: krb5-1.18-beta1~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15349afaaedcf1113382a92bd3a34b7cedd0129f;p=thirdparty%2Fkrb5.git Fix authdata signatures for non-TGT AS-REQs PACs (as well as anything wrapped in CAMMAC) should be signed using the local TGT key. Cross-realm TGS requests, ticket renewal and validation requests, and non-TGT AS requests currently do not pass the local TGT DB entry or its key to sign_authdata(), forcing the KDB module to do a redundant lookup in order to properly sign PACs. Rename the existing krbtgt and krbtgt_key parameters to header_server and header_key, to better indicate that they are for the header ticket server. For AS requests, pass NULL for these parameters instead of passing a duplicate of server/server_key. Add local_tgt and local_tgt_key parameters for the realm's local TGT and its first key. [ghudson@mit.edu: rewrote commit message] ticket: 8829 (new) --- diff --git a/src/include/kdb.h b/src/include/kdb.h index e3536cb492..a632de9ad1 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -664,10 +664,12 @@ krb5_error_code krb5_db_sign_authdata(krb5_context kcontext, krb5_const_principal server_princ, krb5_db_entry *client, krb5_db_entry *server, - krb5_db_entry *krbtgt, + krb5_db_entry *header_server, + krb5_db_entry *local_tgt, krb5_keyblock *client_key, krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, + krb5_keyblock *header_key, + krb5_keyblock *local_tgt_key, krb5_keyblock *session_key, krb5_timestamp authtime, krb5_authdata **tgt_auth_data, @@ -1303,10 +1305,11 @@ typedef struct _kdb_vftabl { * server: The DB entry of the service principal, or of a cross-realm * krbtgt principal in case of referral. * - * krbtgt: For S4U2Proxy requests, the DB entry of the second ticket - * server. For other TGS requests, the DB entry of the header ticket - * server. For AS requests, the DB entry of the service principal; - * this is usually a local krbtgt principal. + * header_server: For S4U2Proxy requests, the DB entry of the second + * ticket server. For other TGS requests, the DB entry of the header + * ticket server. For AS requests, NULL. + * + * local_tgt: the DB entry of the local krbtgt principal. * * client_key: The reply key for the KDC request, before any FAST armor * is applied. For AS requests, this may be the client's long-term key @@ -1315,10 +1318,11 @@ typedef struct _kdb_vftabl { * * server_key: The server key used to encrypt the returned ticket. * - * krbtgt_key: For S4U2Proxy requests, the key used to decrypt the second - * ticket. For other TGS requests, the key used to decrypt the header - * ticket. For AS requests, the server key used to encrypt the - * returned ticket. + * header_key: For S4U2Proxy requests, the key used to decrypt the second + * ticket. For TGS requests, the key used to decrypt the header + * ticket. For AS requests, NULL. + * + * local_tgt_key: The decrypted first key of local_tgt. * * session_key: The session key of the ticket being granted to the * requestor. @@ -1347,10 +1351,12 @@ typedef struct _kdb_vftabl { krb5_const_principal server_princ, krb5_db_entry *client, krb5_db_entry *server, - krb5_db_entry *krbtgt, + krb5_db_entry *header_server, + krb5_db_entry *local_tgt, krb5_keyblock *client_key, krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, + krb5_keyblock *header_key, + krb5_keyblock *local_tgt_key, krb5_keyblock *session_key, krb5_timestamp authtime, krb5_authdata **tgt_auth_data, diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c index 6fa15b8e0e..9c434f3cf0 100644 --- a/src/kdc/kdc_authdata.c +++ b/src/kdc/kdc_authdata.c @@ -316,8 +316,9 @@ copy_tgt_authdata(krb5_context context, krb5_kdc_req *request, static krb5_error_code fetch_kdb_authdata(krb5_context context, unsigned int flags, krb5_db_entry *client, krb5_db_entry *server, - krb5_db_entry *header_server, krb5_keyblock *client_key, - krb5_keyblock *server_key, krb5_keyblock *header_key, + krb5_db_entry *header_server, krb5_db_entry *local_tgt, + krb5_keyblock *client_key, krb5_keyblock *server_key, + krb5_keyblock *header_key, krb5_keyblock *local_tgt_key, krb5_kdc_req *req, krb5_const_principal altcprinc, void *ad_info, krb5_enc_tkt_part *enc_tkt_req, krb5_enc_tkt_part *enc_tkt_reply, @@ -327,8 +328,6 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags, krb5_authdata **tgt_authdata, **db_authdata = NULL; krb5_boolean tgs_req = (req->msg_type == KRB5_TGS_REQ); krb5_const_principal actual_client; - krb5_db_entry *krbtgt; - krb5_keyblock *krbtgt_key; /* * Check whether KDC issued authorization data should be included. @@ -363,19 +362,11 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags, else actual_client = enc_tkt_reply->client; - /* - * For DAL major version 5, always pass "krbtgt" and "krbtgt_key" - * parameters which are usually, but not always, for local or cross-realm - * TGT principals. In the future we might rename the parameters and pass - * NULL for AS requests. - */ - krbtgt = (header_server != NULL) ? header_server : server; - krbtgt_key = (header_key != NULL) ? header_key : server_key; - tgt_authdata = tgs_req ? enc_tkt_req->authorization_data : NULL; ret = krb5_db_sign_authdata(context, flags, actual_client, req->server, - client, server, krbtgt, client_key, server_key, - krbtgt_key, enc_tkt_reply->session, + client, server, header_server, local_tgt, + client_key, server_key, header_key, + local_tgt_key, enc_tkt_reply->session, enc_tkt_reply->times.authtime, tgt_authdata, ad_info, auth_indicators, &db_authdata); if (ret) @@ -863,9 +854,9 @@ handle_authdata(krb5_context context, unsigned int flags, if (!isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS)) { /* Fetch authdata from the KDB if appropriate. */ ret = fetch_kdb_authdata(context, flags, client, server, header_server, - client_key, server_key, header_key, req, - altcprinc, ad_info, enc_tkt_req, - enc_tkt_reply, auth_indicators); + local_tgt, client_key, server_key, header_key, + local_tgt_key, req, altcprinc, ad_info, + enc_tkt_req, enc_tkt_reply, auth_indicators); if (ret) return ret; } diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index 6526812c7f..9001fb797c 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -2594,9 +2594,10 @@ krb5_error_code krb5_db_sign_authdata(krb5_context kcontext, unsigned int flags, krb5_const_principal client_princ, krb5_const_principal server_princ, krb5_db_entry *client, - krb5_db_entry *server, krb5_db_entry *krbtgt, - krb5_keyblock *client_key, krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, krb5_keyblock *session_key, + krb5_db_entry *server, krb5_db_entry *header_server, + krb5_db_entry *local_tgt, krb5_keyblock *client_key, + krb5_keyblock *server_key, krb5_keyblock *header_key, + krb5_keyblock *local_tgt_key, krb5_keyblock *session_key, krb5_timestamp authtime, krb5_authdata **tgt_auth_data, void *ad_info, krb5_data ***auth_indicators, krb5_authdata ***signed_auth_data) @@ -2611,9 +2612,10 @@ krb5_db_sign_authdata(krb5_context kcontext, unsigned int flags, if (v->sign_authdata == NULL) return KRB5_PLUGIN_OP_NOTSUPP; return v->sign_authdata(kcontext, flags, client_princ, server_princ, - client, server, krbtgt, client_key, server_key, - krbtgt_key, session_key, authtime, tgt_auth_data, - ad_info, auth_indicators, signed_auth_data); + client, server, header_server, local_tgt, + client_key, server_key, header_key, local_tgt_key, + session_key, authtime, tgt_auth_data, ad_info, + auth_indicators, signed_auth_data); } krb5_error_code diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c index fe83fd010c..a4408e65d4 100644 --- a/src/plugins/kdb/test/kdb_test.c +++ b/src/plugins/kdb/test/kdb_test.c @@ -541,9 +541,10 @@ static krb5_error_code test_sign_authdata(krb5_context context, unsigned int flags, krb5_const_principal client_princ, krb5_const_principal server_princ, krb5_db_entry *client, - krb5_db_entry *server, krb5_db_entry *krbtgt, - krb5_keyblock *client_key, krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, krb5_keyblock *session_key, + krb5_db_entry *server, krb5_db_entry *header_server, + krb5_db_entry *local_tgt, krb5_keyblock *client_key, + krb5_keyblock *server_key, krb5_keyblock *header_key, + krb5_keyblock *local_tgt_key, krb5_keyblock *session_key, krb5_timestamp authtime, krb5_authdata **tgt_auth_data, void *ad_info, krb5_data ***auth_indicators, krb5_authdata ***signed_auth_data)