static krb5_error_code decrypt_tkt_enc_part (krb5_context context, krb5_keyblock *key, EncryptedData *enc_part, EncTicketPart *decr_part) { krb5_error_code ret; krb5_data plain; size_t len; krb5_crypto crypto; ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) return ret; ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, enc_part, &plain); krb5_crypto_destroy(context, crypto); if (ret) return ret; ret = krb5_decode_EncTicketPart(context, plain.data, plain.length, decr_part, &len); krb5_data_free (&plain); return ret; }
static void print_and_decode_tkt (krb5_context context, krb5_data *ticket, krb5_principal server, krb5_enctype enctype) { krb5_error_code ret; krb5_crypto crypto; krb5_data dec_data; size_t len; EncTicketPart decr_part; krb5_keyblock key; Ticket tkt; ret = decode_Ticket (ticket->data, ticket->length, &tkt, &len); if (ret) krb5_err (context, 1, ret, "decode_Ticket"); ret = krb5_string_to_key (context, enctype, "foo", server, &key); if (ret) krb5_err (context, 1, ret, "krb5_string_to_key"); ret = krb5_crypto_init(context, &key, 0, &crypto); if (ret) krb5_err (context, 1, ret, "krb5_crypto_init"); ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, &tkt.enc_part, &dec_data); krb5_crypto_destroy (context, crypto); if (ret) krb5_err (context, 1, ret, "krb5_decrypt_EncryptedData"); ret = krb5_decode_EncTicketPart (context, dec_data.data, dec_data.length, &decr_part, &len); krb5_data_free (&dec_data); if (ret) krb5_err (context, 1, ret, "krb5_decode_EncTicketPart"); }
krb5_error_code _kdc_do_524(krb5_context context, krb5_kdc_configuration *config, const Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr) { krb5_error_code ret = 0; krb5_crypto crypto; hdb_entry_ex *server = NULL; Key *skey; krb5_data et_data; EncTicketPart et; EncryptedData ticket; krb5_storage *sp; char *spn = NULL; unsigned char buf[MAX_KTXT_LEN + 4 * 4]; size_t len; int kvno = 0; if(!config->enable_524) { ret = KRB5KDC_ERR_POLICY; kdc_log(context, config, 0, "Rejected ticket conversion request from %s", from); goto out; } ret = fetch_server (context, config, t, &spn, &server, from); if (ret) { goto out; } ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey); if(ret){ kdc_log(context, config, 0, "No suitable key found for server (%s) from %s", spn, from); goto out; } ret = krb5_crypto_init(context, &skey->key, 0, &crypto); if (ret) { kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); goto out; } ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, &t->enc_part, &et_data); krb5_crypto_destroy(context, crypto); if(ret){ kdc_log(context, config, 0, "Failed to decrypt ticket from %s for %s", from, spn); goto out; } ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length, &et, &len); krb5_data_free(&et_data); if(ret){ kdc_log(context, config, 0, "Failed to decode ticket from %s for %s", from, spn); goto out; } ret = log_524 (context, config, &et, from, spn); if (ret) { free_EncTicketPart(&et); goto out; } ret = verify_flags (context, config, &et, spn); if (ret) { free_EncTicketPart(&et); goto out; } ret = set_address (context, config, &et, addr, from); if (ret) { free_EncTicketPart(&et); goto out; } ret = encode_524_response(context, config, spn, et, t, server, &ticket, &kvno); free_EncTicketPart(&et); out: /* make reply */ memset(buf, 0, sizeof(buf)); sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp) { krb5_store_int32(sp, ret); if(ret == 0){ krb5_store_int32(sp, kvno); krb5_store_data(sp, ticket.cipher); /* Aargh! This is coded as a KTEXT_ST. */ krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR); krb5_store_int32(sp, 0); /* mbz */ free_EncryptedData(&ticket); } ret = krb5_storage_to_data(sp, reply); reply->length = krb5_storage_seek(sp, 0, SEEK_CUR); krb5_storage_free(sp); } else krb5_data_zero(reply); if(spn) free(spn); if(server) _kdc_free_ent (context, server); return ret; }