get_in_tkt (krb5_get_in_tkt): Set the encryption type of the session
authorTheodore Tso <tytso@mit.edu>
Mon, 14 Nov 1994 21:35:28 +0000 (21:35 +0000)
committerTheodore Tso <tytso@mit.edu>
Mon, 14 Nov 1994 21:35:28 +0000 (21:35 +0000)
keyblock to be the type used to encrypt the ticket.

mk_cred.c, rd_cred.c: New routines for forwarding credentials --- note that
the API is still subject to change!  (Moved from telnet and bsd
directories)

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4659 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/mk_cred.c [new file with mode: 0644]
src/lib/krb5/krb/rd_cred.c [new file with mode: 0644]

index e7276c98a2aaec10b07d77c629aab923201fbd3e..e8cf4de6e3a299b6fb4044ff85fdb6191f020886 100644 (file)
@@ -1,3 +1,9 @@
+Fri Nov 11 01:20:22 1994  Theodore Y. Ts'o  (tytso@dcl)
+
+       * get_in_tkt (krb5_get_in_tkt): Set the encryption type of the
+               session keyblock to be the type used to encrypt the
+               ticket. 
+
 Thu Nov 10 23:56:43 1994  Theodore Y. Ts'o  (tytso@dcl)
 
        * rd_rep.c (krb5_rd_rep): Set the encryption type in
index d647f1e128594ff65c58274d0735176fcd2bf26e..2a278bc62a607adecfc14d49428dd4b224019a47 100644 (file)
@@ -40,6 +40,7 @@ OBJS= addr_comp.o     \
        in_tkt_sky.o    \
        kdc_rep_dc.o    \
        krbconfig.o     \
+       mk_cred.o       \
        mk_error.o      \
        mk_priv.o       \
        mk_rep.o        \
@@ -50,6 +51,7 @@ OBJS= addr_comp.o     \
        pr_to_salt.o    \
        preauth.o       \
        princ_comp.o    \
+       rd_cred.o       \
        rd_error.o      \
        rd_priv.o       \
        rd_rep.o        \
@@ -100,6 +102,7 @@ SRCS=       $(srcdir)/addr_comp.c   \
        $(srcdir)/in_tkt_sky.c  \
        $(srcdir)/kdc_rep_dc.c  \
        $(srcdir)/krbconfig.c   \
+       $(srcdir)/mk_cred.c     \
        $(srcdir)/mk_error.c    \
        $(srcdir)/mk_priv.c     \
        $(srcdir)/mk_rep.c      \
@@ -110,6 +113,7 @@ SRCS=       $(srcdir)/addr_comp.c   \
        $(srcdir)/pr_to_salt.c  \
        $(srcdir)/preauth.c     \
        $(srcdir)/princ_comp.c  \
+       $(srcdir)/rd_cred.c     \
        $(srcdir)/rd_error.c    \
        $(srcdir)/rd_priv.c     \
        $(srcdir)/rd_rep.c      \
index f9366a6ab21683eb61e8941de4a23ce687c791e1..90e200c76491599149bac0f7370e2924a062eca0 100644 (file)
@@ -279,6 +279,7 @@ OLDDECLARG(krb5_kdc_rep **, ret_as_reply)
     if (retval = krb5_copy_keyblock_contents(as_reply->enc_part2->session,
                                             &creds->keyblock))
        goto cleanup;
+    creds->keyblock.etype = as_reply->ticket->enc_part.etype;
 
     creds->times = as_reply->enc_part2->times;
     creds->is_skey = FALSE;            /* this is an AS_REQ, so cannot
diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c
new file mode 100644 (file)
index 0000000..4422bcd
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * lib/krb5/krb/mk_cred.c
+ *
+ * Copyright 1994 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ * krb5_mk_cred()
+ */
+
+
+/* XXX This API is going to change; what's here isn't general enough! */
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <krb5/los-proto.h>
+#include <krb5/asn1.h>
+
+/* Create asn.1 encoded KRB-CRED message from the kdc reply. */
+krb5_error_code
+mk_cred(dec_rep, etype, key, sender_addr, recv_addr, outbuf)
+krb5_kdc_rep *dec_rep;
+krb5_enctype etype;
+krb5_keyblock *key;
+krb5_address *sender_addr;
+krb5_address *recv_addr;
+krb5_data *outbuf;
+{
+    krb5_error_code retval;
+    krb5_encrypt_block eblock;
+    krb5_cred ret_cred;
+    krb5_cred_enc_part cred_enc_part;
+    krb5_data *scratch;
+
+    if (!valid_etype(etype))
+      return KRB5_PROG_ETYPE_NOSUPP;
+
+    ret_cred.tickets = (krb5_ticket **) calloc(2, sizeof(*ret_cred.tickets));
+    if (!ret_cred.tickets)
+      return ENOMEM;
+    ret_cred.tickets[0] = dec_rep->ticket;
+    ret_cred.tickets[1] = 0;
+
+    ret_cred.enc_part.etype = etype; 
+    ret_cred.enc_part.kvno = 0;
+
+    cred_enc_part.ticket_info = (krb5_cred_info **) 
+      calloc(2, sizeof(*cred_enc_part.ticket_info));
+    if (!cred_enc_part.ticket_info) {
+       krb5_free_tickets(ret_cred.tickets);
+       return ENOMEM;
+    }
+    cred_enc_part.ticket_info[0] = (krb5_cred_info *) 
+      malloc(sizeof(*cred_enc_part.ticket_info[0]));
+    if (!cred_enc_part.ticket_info[0]) {
+       krb5_free_tickets(ret_cred.tickets);
+       krb5_free_cred_enc_part(cred_enc_part);
+       return ENOMEM;
+    }
+    cred_enc_part.nonce = 0;
+
+    if (retval = krb5_us_timeofday(&cred_enc_part.timestamp,
+                                  &cred_enc_part.usec))
+      return retval;
+
+    cred_enc_part.s_address = (krb5_address *)sender_addr;
+    cred_enc_part.r_address = (krb5_address *)recv_addr;
+
+    cred_enc_part.ticket_info[0]->session = dec_rep->enc_part2->session;
+    cred_enc_part.ticket_info[0]->client = dec_rep->client;
+    cred_enc_part.ticket_info[0]->server = dec_rep->enc_part2->server;
+    cred_enc_part.ticket_info[0]->flags  = dec_rep->enc_part2->flags;
+    cred_enc_part.ticket_info[0]->times  = dec_rep->enc_part2->times;
+    cred_enc_part.ticket_info[0]->caddrs = dec_rep->enc_part2->caddrs;
+
+    cred_enc_part.ticket_info[1] = 0;
+
+    /* start by encoding to-be-encrypted part of the message */
+
+    if (retval = encode_krb5_enc_cred_part(&cred_enc_part, &scratch))
+      return retval;
+
+#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); krb5_free_data(scratch); }
+
+    /* put together an eblock for this encryption */
+
+    krb5_use_cstype(&eblock, etype);
+    ret_cred.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length,
+                                               eblock.crypto_entry);
+    /* add padding area, and zero it */
+    if (!(scratch->data = realloc(scratch->data,
+                                 ret_cred.enc_part.ciphertext.length))) {
+       /* may destroy scratch->data */
+       krb5_xfree(scratch);
+       return ENOMEM;
+    }
+    memset(scratch->data + scratch->length, 0,
+         ret_cred.enc_part.ciphertext.length - scratch->length);
+    if (!(ret_cred.enc_part.ciphertext.data =
+         malloc(ret_cred.enc_part.ciphertext.length))) {
+        retval = ENOMEM;
+        goto clean_scratch;
+    }
+
+#define cleanup_encpart() {\
+       (void) memset(ret_cred.enc_part.ciphertext.data, 0, \
+            ret_cred.enc_part.ciphertext.length); \
+       free(ret_cred.enc_part.ciphertext.data); \
+       ret_cred.enc_part.ciphertext.length = 0; \
+       ret_cred.enc_part.ciphertext.data = 0;}
+
+    /* do any necessary key pre-processing */
+    if (retval = krb5_process_key(&eblock, key)) {
+        goto clean_encpart;
+    }
+
+#define cleanup_prockey() {(void) krb5_finish_key(&eblock);}
+
+    /* call the encryption routine */
+    if (retval = krb5_encrypt((krb5_pointer) scratch->data,
+                             (krb5_pointer)
+                             ret_cred.enc_part.ciphertext.data, 
+                             scratch->length, &eblock,
+                             0)) {
+        goto clean_prockey;
+    }
+    
+    /* private message is now assembled-- do some cleanup */
+    cleanup_scratch();
+
+    if (retval = krb5_finish_key(&eblock)) {
+        cleanup_encpart();
+        return retval;
+    }
+    /* encode private message */
+    if (retval = encode_krb5_cred(&ret_cred, &scratch))  {
+        cleanup_encpart();
+       return retval;
+    }
+
+    cleanup_encpart();
+
+    *outbuf = *scratch;
+    krb5_xfree(scratch);
+    return 0;
+
+ clean_prockey:
+    cleanup_prockey();
+ clean_encpart:
+    cleanup_encpart();
+ clean_scratch:
+    cleanup_scratch();
+
+    return retval;
+#undef cleanup_prockey
+#undef cleanup_encpart
+#undef cleanup_scratch
+}
+
diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c
new file mode 100644 (file)
index 0000000..f9d7e43
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * lib/krb5/krb/rd_cred.c
+ *
+ * Copyright 1994 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ * krb5_rd_cred()
+ */
+
+/* XXX This API is going to change; what's here isn't general enough! */
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <krb5/los-proto.h>
+#include <krb5/asn1.h>
+
+extern krb5_deltat krb5_clockskew;
+#define in_clock_skew(date) (abs((date)-currenttime) < krb5_clockskew)
+
+/* Decode the KRB-CRED message, and return creds */
+krb5_error_code
+rd_cred(inbuf, key, creds, sender_addr, recv_addr)
+const krb5_data *inbuf;
+const krb5_keyblock *key;
+krb5_creds *creds;                /* Filled in */
+const krb5_address *sender_addr;  /* optional */
+const krb5_address *recv_addr;    /* optional */
+{
+    krb5_error_code retval;
+    krb5_encrypt_block eblock;
+    krb5_cred *credmsg;
+    krb5_cred_enc_part *credmsg_enc_part;
+    krb5_data *scratch;
+    krb5_timestamp currenttime;
+
+    if (!krb5_is_krb_cred(inbuf))
+       return KRB5KRB_AP_ERR_MSG_TYPE;
+    
+    /* decode private message */
+    if (retval = decode_krb5_cred(inbuf, &credmsg))  {
+       return retval;
+    }
+    
+#define cleanup_credmsg() {(void)krb5_xfree(credmsg->enc_part.ciphertext.data); (void)krb5_xfree(credmsg);}
+
+    if (!(scratch = (krb5_data *) malloc(sizeof(*scratch)))) {
+       cleanup_credmsg();
+       return ENOMEM;
+    }
+
+#define cleanup_scratch() {(void)memset(scratch->data, 0, scratch->length); (void)krb5_xfree(scratch->data);}
+
+    if (retval = encode_krb5_ticket(credmsg->tickets[0], &scratch)) {
+       cleanup_credmsg();
+       cleanup_scratch();
+       return(retval);
+    }
+
+    creds->ticket = *scratch;
+    if (!(creds->ticket.data = malloc(scratch->length))) {
+       krb5_xfree(creds->ticket.data);
+       return ENOMEM;
+    }
+    memcpy((char *)creds->ticket.data, (char *) scratch->data, scratch->length);
+
+    cleanup_scratch();
+
+    if (!valid_etype(credmsg->enc_part.etype)) {
+       cleanup_credmsg();
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+
+    /* put together an eblock for this decryption */
+
+    krb5_use_cstype(&eblock, credmsg->enc_part.etype);
+    scratch->length = credmsg->enc_part.ciphertext.length;
+    
+    if (!(scratch->data = malloc(scratch->length))) {
+       cleanup_credmsg();
+        return ENOMEM;
+    }
+
+    /* do any necessary key pre-processing */
+    if (retval = krb5_process_key(&eblock, key)) {
+        cleanup_credmsg();
+       cleanup_scratch();
+       return retval;
+    }
+    
+#define cleanup_prockey() {(void) krb5_finish_key(&eblock);}
+    
+    /* call the decryption routine */
+    if (retval = krb5_decrypt((krb5_pointer) credmsg->enc_part.ciphertext.data,
+                             (krb5_pointer) scratch->data,
+                             scratch->length, &eblock,
+                             0)) {
+       cleanup_credmsg();
+       cleanup_scratch();
+        cleanup_prockey();
+       return retval;
+    }
+
+    /* cred message is now decrypted -- do some cleanup */
+
+    cleanup_credmsg();
+
+    if (retval = krb5_finish_key(&eblock)) {
+        cleanup_scratch();
+        return retval;
+    }
+
+    /*  now decode the decrypted stuff */
+    if (retval = decode_krb5_enc_cred_part(scratch, &credmsg_enc_part)) {
+       cleanup_scratch();
+       return retval;
+    }
+    cleanup_scratch();
+
+#define cleanup_mesg() {(void)krb5_xfree(credmsg_enc_part);}
+
+    if (retval = krb5_timeofday(&currenttime)) {
+       cleanup_mesg();
+       return retval;
+    }
+    if (!in_clock_skew(credmsg_enc_part->timestamp)) {
+       cleanup_mesg();  
+       return KRB5KRB_AP_ERR_SKEW;
+    }
+
+    if (sender_addr && credmsg_enc_part->s_address &&
+       !krb5_address_compare(sender_addr, 
+                             credmsg_enc_part->s_address)) {
+       cleanup_mesg();
+       return KRB5KRB_AP_ERR_BADADDR;
+    }
+    if (recv_addr && credmsg_enc_part->r_address &&
+       !krb5_address_compare(recv_addr, 
+                             credmsg_enc_part->r_address)) {
+       cleanup_mesg();
+       return KRB5KRB_AP_ERR_BADADDR;
+    }      
+
+    if (credmsg_enc_part->r_address) {
+       krb5_address **our_addrs;
+       
+       if (retval = krb5_os_localaddr(&our_addrs)) {
+           cleanup_mesg();
+           return retval;
+       }
+       if (!krb5_address_search(credmsg_enc_part->r_address, 
+                                our_addrs)) {
+           krb5_free_addresses(our_addrs);
+           cleanup_mesg();
+           return KRB5KRB_AP_ERR_BADADDR;
+       }
+       krb5_free_addresses(our_addrs);
+    }
+
+    if (retval = krb5_copy_principal(credmsg_enc_part->ticket_info[0]->client,
+                                    &creds->client)) {
+       return(retval);
+    }
+
+    if (retval = krb5_copy_principal(credmsg_enc_part->ticket_info[0]->server,
+                                    &creds->server)) {
+       return(retval);
+    }  
+
+    if (retval =
+       krb5_copy_keyblock_contents(credmsg_enc_part->ticket_info[0]->session, 
+                                   &creds->keyblock)) {
+       return(retval);
+    }
+    creds->keyblock.magic = KV5M_KEYBLOCK;
+    creds->keyblock.etype = credmsg->tickets[0]->enc_part.etype;
+
+#undef clean
+#define clean() {\
+       memset((char *)creds->keyblock.contents, 0, creds->keyblock.length);}
+
+    creds->times = credmsg_enc_part->ticket_info[0]->times;
+    creds->is_skey = FALSE;
+    creds->ticket_flags = credmsg_enc_part->ticket_info[0]->flags;
+
+    if (retval = krb5_copy_addresses(credmsg_enc_part->ticket_info[0]->caddrs,
+                                    &creds->addresses)) {
+       clean();
+       return(retval);
+    }
+
+    creds->second_ticket.length = 0;
+
+    creds->authdata = 0;
+
+    cleanup_mesg();
+    return 0;
+#undef clean
+#undef cleanup_credmsg
+#undef cleanup_scratch
+#undef cleanup_prockey
+#undef cleanup_mesg
+}
+