svn rev #23613: trunk/src/lib/krb5/ krb/ os/

tsitkova@MIT.EDU tsitkova at MIT.EDU
Fri Jan 8 14:35:40 EST 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=23613
Commit By: tsitkova
Log Message:
Move kdc related functionality from pac.c into pac_sign.c



Changed Files:
U   trunk/src/lib/krb5/krb/Makefile.in
U   trunk/src/lib/krb5/krb/authdata.h
U   trunk/src/lib/krb5/krb/pac.c
A   trunk/src/lib/krb5/krb/pac_sign.c
U   trunk/src/lib/krb5/os/locate_kdc.c
Modified: trunk/src/lib/krb5/krb/Makefile.in
===================================================================
--- trunk/src/lib/krb5/krb/Makefile.in	2010-01-08 14:54:04 UTC (rev 23612)
+++ trunk/src/lib/krb5/krb/Makefile.in	2010-01-08 19:35:40 UTC (rev 23613)
@@ -71,6 +71,7 @@
 	mk_req_ext.o	\
 	mk_safe.o	\
 	pac.o		\
+	pac_sign.o	\
 	parse.o		\
 	pr_to_salt.o	\
 	preauth.o	\
@@ -167,6 +168,7 @@
 	$(OUTPRE)mk_req_ext.$(OBJEXT)	\
 	$(OUTPRE)mk_safe.$(OBJEXT)	\
 	$(OUTPRE)pac.$(OBJEXT)		\
+	$(OUTPRE)pac_sign.$(OBJEXT)	\
 	$(OUTPRE)parse.$(OBJEXT)	\
 	$(OUTPRE)pr_to_salt.$(OBJEXT)	\
 	$(OUTPRE)preauth.$(OBJEXT)	\
@@ -264,6 +266,7 @@
 	$(srcdir)/mk_req_ext.c	\
 	$(srcdir)/mk_safe.c	\
 	$(srcdir)/pac.c		\
+	$(srcdir)/pac_sign.c	\
 	$(srcdir)/parse.c	\
 	$(srcdir)/pr_to_salt.c	\
 	$(srcdir)/preauth.c	\
@@ -331,12 +334,12 @@
 T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o set_realm.o str_conv.o
 
 T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \
-	ser_ctx.o ser_key.o ser_princ.o serialize.o authdata.o pac.o \
+	ser_ctx.o ser_key.o ser_princ.o serialize.o authdata.o pac.o pac_sign.o \
 	copy_data.o etype_list.o
 
 T_DELTAT_OBJS= t_deltat.o deltat.o
 
-T_PAC_OBJS= t_pac.o pac.o copy_data.o
+T_PAC_OBJS= t_pac.o pac.o pac_sign.o copy_data.o
 
 T_PRINC_OBJS= t_princ.o parse.o unparse.o
 

Modified: trunk/src/lib/krb5/krb/authdata.h
===================================================================
--- trunk/src/lib/krb5/krb/authdata.h	2010-01-08 14:54:04 UTC (rev 23612)
+++ trunk/src/lib/krb5/krb/authdata.h	2010-01-08 19:35:40 UTC (rev 23613)
@@ -32,7 +32,9 @@
 #define KRB_AUTHDATA_H
 
 #include <k5-int.h>
+#include "k5-utf8.h"
 
+
 /* authdata.c */
 krb5_error_code
 krb5int_authdata_verify(krb5_context context,
@@ -42,7 +44,74 @@
                         const krb5_keyblock *key,
                         const krb5_ap_req *ap_req);
 
-/* pac.c */
+/* PAC */
+/*
+ * A PAC consists of a sequence of PAC_INFO_BUFFERs, preceeded by
+ * a PACTYPE header. Decoding the contents of the buffers is left
+ * to the application (notwithstanding signature verification).
+ */
+
+typedef struct _PAC_INFO_BUFFER {
+    krb5_ui_4 ulType;
+    krb5_ui_4 cbBufferSize;
+    krb5_ui_8 Offset;
+} PAC_INFO_BUFFER;
+
+typedef struct _PACTYPE {
+    krb5_ui_4 cBuffers;
+    krb5_ui_4 Version;
+    PAC_INFO_BUFFER Buffers[1];
+} PACTYPE;
+
+struct krb5_pac_data {
+    PACTYPE *pac;       /* PAC header + info buffer array */
+    krb5_data data;     /* PAC data (including uninitialised header) */
+    krb5_boolean verified;
+};
+
+
+
+#define PAC_ALIGNMENT               8
+#define PACTYPE_LENGTH              8U
+#define PAC_SIGNATURE_DATA_LENGTH   4U
+#define PAC_CLIENT_INFO_LENGTH      10U
+#define PAC_INFO_BUFFER_LENGTH  16
+/* ulType */
+#define PAC_LOGON_INFO          1
+#define PAC_CREDENTIALS_INFO    2
+#define PAC_SERVER_CHECKSUM     6
+#define PAC_PRIVSVR_CHECKSUM    7
+#define PAC_CLIENT_INFO         10
+#define PAC_DELEGATION_INFO     11
+#define PAC_UPN_DNS_INFO        12
+
+#define NT_TIME_EPOCH               11644473600LL
+
 extern krb5plugin_authdata_client_ftable_v0 krb5int_mspac_authdata_client_ftable;
 
+krb5_error_code
+k5_pac_locate_buffer(krb5_context context,
+                     const krb5_pac pac,
+                     krb5_ui_4 type,
+                     krb5_data *data);
+
+krb5_error_code
+k5_pac_validate_client(krb5_context context,
+                       const krb5_pac pac,
+                       krb5_timestamp authtime,
+                       krb5_const_principal principal);
+
+krb5_error_code
+k5_pac_add_buffer(krb5_context context,
+                  krb5_pac pac,
+                  krb5_ui_4 type,
+                  const krb5_data *data,
+                  krb5_boolean zerofill,
+                  krb5_data *out_data);
+
+krb5_error_code
+k5_seconds_since_1970_to_time(krb5_timestamp elapsedSeconds,
+                              krb5_ui_8 *ntTime);
+
+
 #endif /* !KRB_AUTHDATA_H */

Modified: trunk/src/lib/krb5/krb/pac.c
===================================================================
--- trunk/src/lib/krb5/krb/pac.c	2010-01-08 14:54:04 UTC (rev 23612)
+++ trunk/src/lib/krb5/krb/pac.c	2010-01-08 19:35:40 UTC (rev 23613)
@@ -27,63 +27,14 @@
  */
 
 #include "k5-int.h"
-#include "k5-utf8.h"
 #include "authdata.h"
 
 /* draft-brezak-win2k-krb-authz-00 */
 
 /*
- * A PAC consists of a sequence of PAC_INFO_BUFFERs, preceeded by
- * a PACTYPE header. Decoding the contents of the buffers is left
- * to the application (notwithstanding signature verification).
- */
-
-typedef struct _PAC_INFO_BUFFER {
-    krb5_ui_4 ulType;
-    krb5_ui_4 cbBufferSize;
-    krb5_ui_8 Offset;
-} PAC_INFO_BUFFER;
-
-#define PAC_INFO_BUFFER_LENGTH  16
-
-/* ulType */
-#define PAC_LOGON_INFO          1
-#define PAC_CREDENTIALS_INFO    2
-#define PAC_SERVER_CHECKSUM     6
-#define PAC_PRIVSVR_CHECKSUM    7
-#define PAC_CLIENT_INFO         10
-#define PAC_DELEGATION_INFO     11
-#define PAC_UPN_DNS_INFO        12
-
-typedef struct _PACTYPE {
-    krb5_ui_4 cBuffers;
-    krb5_ui_4 Version;
-    PAC_INFO_BUFFER Buffers[1];
-} PACTYPE;
-
-#define PAC_ALIGNMENT               8
-#define PACTYPE_LENGTH              8U
-#define PAC_SIGNATURE_DATA_LENGTH   4U
-#define PAC_CLIENT_INFO_LENGTH      10U
-
-#define NT_TIME_EPOCH               11644473600LL
-
-struct krb5_pac_data {
-    PACTYPE *pac;       /* PAC header + info buffer array */
-    krb5_data data;     /* PAC data (including uninitialised header) */
-    krb5_boolean verified;
-};
-
-static krb5_error_code
-k5_pac_locate_buffer(krb5_context context,
-                     const krb5_pac pac,
-                     krb5_ui_4 type,
-                     krb5_data *data);
-
-/*
  * Add a buffer to the provided PAC and update header.
  */
-static krb5_error_code
+krb5_error_code
 k5_pac_add_buffer(krb5_context context,
                   krb5_pac pac,
                   krb5_ui_4 type,
@@ -187,7 +138,7 @@
     }
 }
 
-static krb5_error_code
+krb5_error_code
 k5_pac_locate_buffer(krb5_context context,
                      const krb5_pac pac,
                      krb5_ui_4 type,
@@ -447,7 +398,7 @@
     return 0;
 }
 
-static krb5_error_code
+krb5_error_code
 k5_seconds_since_1970_to_time(krb5_timestamp elapsedSeconds,
                               krb5_ui_8 *ntTime)
 {
@@ -461,7 +412,7 @@
     return 0;
 }
 
-static krb5_error_code
+krb5_error_code
 k5_pac_validate_client(krb5_context context,
                        const krb5_pac pac,
                        krb5_timestamp authtime,
@@ -702,251 +653,6 @@
     return 0;
 }
 
-static krb5_error_code
-k5_insert_client_info(krb5_context context,
-                      krb5_pac pac,
-                      krb5_timestamp authtime,
-                      krb5_const_principal principal)
-{
-    krb5_error_code ret;
-    krb5_data client_info;
-    char *princ_name_utf8 = NULL;
-    unsigned char *princ_name_ucs2 = NULL, *p;
-    size_t princ_name_ucs2_len = 0;
-    krb5_ui_8 nt_authtime;
-
-    /* If we already have a CLIENT_INFO buffer, then just validate it */
-    if (k5_pac_locate_buffer(context, pac,
-                             PAC_CLIENT_INFO, &client_info) == 0) {
-        return k5_pac_validate_client(context, pac, authtime, principal);
-    }
-
-    ret = krb5_unparse_name_flags(context, principal,
-                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
-                                  &princ_name_utf8);
-    if (ret != 0)
-        goto cleanup;
-
-    ret = krb5int_utf8s_to_ucs2les(princ_name_utf8,
-                                   &princ_name_ucs2,
-                                   &princ_name_ucs2_len);
-    if (ret != 0)
-        goto cleanup;
-
-    client_info.length = PAC_CLIENT_INFO_LENGTH + princ_name_ucs2_len;
-    client_info.data = NULL;
-
-    ret = k5_pac_add_buffer(context, pac, PAC_CLIENT_INFO,
-                            &client_info, TRUE, &client_info);
-    if (ret != 0)
-        goto cleanup;
-
-    p = (unsigned char *)client_info.data;
-
-    /* copy in authtime converted to a 64-bit NT time */
-    k5_seconds_since_1970_to_time(authtime, &nt_authtime);
-    store_64_le(nt_authtime, p);
-    p += 8;
-
-    /* copy in number of UCS-2 characters in principal name */
-    store_16_le(princ_name_ucs2_len, p);
-    p += 2;
-
-    /* copy in principal name */
-    memcpy(p, princ_name_ucs2, princ_name_ucs2_len);
-
-cleanup:
-    if (princ_name_ucs2 != NULL)
-        free(princ_name_ucs2);
-    krb5_free_unparsed_name(context, princ_name_utf8);
-
-    return ret;
-}
-
-static krb5_error_code
-k5_insert_checksum(krb5_context context,
-                   krb5_pac pac,
-                   krb5_ui_4 type,
-                   const krb5_keyblock *key,
-                   krb5_cksumtype *cksumtype)
-{
-    krb5_error_code ret;
-    size_t len;
-    krb5_data cksumdata;
-
-    ret = krb5int_c_mandatory_cksumtype(context, key->enctype, cksumtype);
-    if (ret != 0)
-        return ret;
-
-    ret = krb5_c_checksum_length(context, *cksumtype, &len);
-    if (ret != 0)
-        return ret;
-
-    ret = k5_pac_locate_buffer(context, pac, type, &cksumdata);
-    if (ret == 0) {
-        /*
-         * If we're resigning PAC, make sure we can fit checksum
-         * into existing buffer
-         */
-        if (cksumdata.length != PAC_SIGNATURE_DATA_LENGTH + len)
-            return ERANGE;
-
-        memset(cksumdata.data, 0, cksumdata.length);
-    } else {
-        /* Add a zero filled buffer */
-        cksumdata.length = PAC_SIGNATURE_DATA_LENGTH + len;
-        cksumdata.data = NULL;
-
-        ret = k5_pac_add_buffer(context, pac,
-                                type, &cksumdata,
-                                TRUE, &cksumdata);
-        if (ret != 0)
-            return ret;
-    }
-
-    /* Encode checksum type into buffer */
-    store_32_le((krb5_ui_4)*cksumtype, cksumdata.data);
-
-    return 0;
-}
-
-/* in-place encoding of PAC header */
-static krb5_error_code
-k5_pac_encode_header(krb5_context context, krb5_pac pac)
-{
-    size_t i;
-    unsigned char *p;
-    size_t header_len;
-
-    header_len = PACTYPE_LENGTH +
-        (pac->pac->cBuffers * PAC_INFO_BUFFER_LENGTH);
-    assert(pac->data.length >= header_len);
-
-    p = (unsigned char *)pac->data.data;
-
-    store_32_le(pac->pac->cBuffers, p);
-    p += 4;
-    store_32_le(pac->pac->Version, p);
-    p += 4;
-
-    for (i = 0; i < pac->pac->cBuffers; i++) {
-        PAC_INFO_BUFFER *buffer = &pac->pac->Buffers[i];
-
-        store_32_le(buffer->ulType, p);
-        p += 4;
-        store_32_le(buffer->cbBufferSize, p);
-        p += 4;
-        store_64_le(buffer->Offset, p);
-        p += 8;
-
-        assert((buffer->Offset % PAC_ALIGNMENT) == 0);
-        assert(buffer->Offset + buffer->cbBufferSize <= pac->data.length);
-        assert(buffer->Offset >= header_len);
-
-        if (buffer->Offset % PAC_ALIGNMENT ||
-            buffer->Offset + buffer->cbBufferSize > pac->data.length ||
-            buffer->Offset < header_len)
-            return ERANGE;
-    }
-
-    return 0;
-}
-
-krb5_error_code KRB5_CALLCONV
-krb5int_pac_sign(krb5_context context,
-                 krb5_pac pac,
-                 krb5_timestamp authtime,
-                 krb5_const_principal principal,
-                 const krb5_keyblock *server_key,
-                 const krb5_keyblock *privsvr_key,
-                 krb5_data *data)
-{
-    krb5_error_code ret;
-    krb5_data server_cksum, privsvr_cksum;
-    krb5_cksumtype server_cksumtype, privsvr_cksumtype;
-    krb5_crypto_iov iov[2];
-
-    data->length = 0;
-    data->data = NULL;
-
-    if (principal != NULL) {
-        ret = k5_insert_client_info(context, pac, authtime, principal);
-        if (ret != 0)
-            return ret;
-    }
-
-    /* Create zeroed buffers for both checksums */
-    ret = k5_insert_checksum(context, pac, PAC_SERVER_CHECKSUM,
-                             server_key, &server_cksumtype);
-    if (ret != 0)
-        return ret;
-
-    ret = k5_insert_checksum(context, pac, PAC_PRIVSVR_CHECKSUM,
-                             privsvr_key, &privsvr_cksumtype);
-    if (ret != 0)
-        return ret;
-
-    /* Now, encode the PAC header so that the checksums will include it */
-    ret = k5_pac_encode_header(context, pac);
-    if (ret != 0)
-        return ret;
-
-    /* Generate the server checksum over the entire PAC */
-    ret = k5_pac_locate_buffer(context, pac,
-                               PAC_SERVER_CHECKSUM, &server_cksum);
-    if (ret != 0)
-        return ret;
-
-    assert(server_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
-    iov[0].data = pac->data;
-
-    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
-    iov[1].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[1].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
-
-    ret = krb5_c_make_checksum_iov(context, server_cksumtype,
-                                   server_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
-                                   iov, sizeof(iov)/sizeof(iov[0]));
-    if (ret != 0)
-        return ret;
-
-    /* Generate the privsvr checksum over the server checksum buffer */
-    ret = k5_pac_locate_buffer(context, pac,
-                               PAC_PRIVSVR_CHECKSUM, &privsvr_cksum);
-    if (ret != 0)
-        return ret;
-
-    assert(privsvr_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
-
-    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
-    iov[0].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[0].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
-
-    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
-    iov[1].data.data = privsvr_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
-    iov[1].data.length = privsvr_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
-
-    ret = krb5_c_make_checksum_iov(context, privsvr_cksumtype,
-                                   privsvr_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
-                                   iov, sizeof(iov)/sizeof(iov[0]));
-    if (ret != 0)
-        return ret;
-
-    data->data = malloc(pac->data.length);
-    if (data->data == NULL)
-        return ENOMEM;
-
-    data->length = pac->data.length;
-
-    memcpy(data->data, pac->data.data, pac->data.length);
-    memset(pac->data.data, 0,
-           PACTYPE_LENGTH + (pac->pac->cBuffers * PAC_INFO_BUFFER_LENGTH));
-
-    return 0;
-}
-
 /*
  * PAC auth data attribute backend
  */

Added: trunk/src/lib/krb5/krb/pac_sign.c
===================================================================
--- trunk/src/lib/krb5/krb/pac_sign.c	                        (rev 0)
+++ trunk/src/lib/krb5/krb/pac_sign.c	2010-01-08 19:35:40 UTC (rev 23613)
@@ -0,0 +1,278 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * lib/krb5/krb/pac.c
+ *
+ * Copyright 2008 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.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * 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.
+ *
+ * krb5int_pac_sign()
+ */
+
+#include "k5-int.h"
+#include "authdata.h"
+
+/* draft-brezak-win2k-krb-authz-00 */
+
+static krb5_error_code
+k5_insert_client_info(krb5_context context,
+                      krb5_pac pac,
+                      krb5_timestamp authtime,
+                      krb5_const_principal principal)
+{
+    krb5_error_code ret;
+    krb5_data client_info;
+    char *princ_name_utf8 = NULL;
+    unsigned char *princ_name_ucs2 = NULL, *p;
+    size_t princ_name_ucs2_len = 0;
+    krb5_ui_8 nt_authtime;
+
+    /* If we already have a CLIENT_INFO buffer, then just validate it */
+    if (k5_pac_locate_buffer(context, pac,
+                             PAC_CLIENT_INFO, &client_info) == 0) {
+        return k5_pac_validate_client(context, pac, authtime, principal);
+    }
+
+    ret = krb5_unparse_name_flags(context, principal,
+                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+                                  &princ_name_utf8);
+    if (ret != 0)
+        goto cleanup;
+
+    ret = krb5int_utf8s_to_ucs2les(princ_name_utf8,
+                                   &princ_name_ucs2,
+                                   &princ_name_ucs2_len);
+    if (ret != 0)
+        goto cleanup;
+
+    client_info.length = PAC_CLIENT_INFO_LENGTH + princ_name_ucs2_len;
+    client_info.data = NULL;
+
+    ret = k5_pac_add_buffer(context, pac, PAC_CLIENT_INFO,
+                            &client_info, TRUE, &client_info);
+    if (ret != 0)
+        goto cleanup;
+
+    p = (unsigned char *)client_info.data;
+
+    /* copy in authtime converted to a 64-bit NT time */
+    k5_seconds_since_1970_to_time(authtime, &nt_authtime);
+    store_64_le(nt_authtime, p);
+    p += 8;
+
+    /* copy in number of UCS-2 characters in principal name */
+    store_16_le(princ_name_ucs2_len, p);
+    p += 2;
+
+    /* copy in principal name */
+    memcpy(p, princ_name_ucs2, princ_name_ucs2_len);
+
+cleanup:
+    if (princ_name_ucs2 != NULL)
+        free(princ_name_ucs2);
+    krb5_free_unparsed_name(context, princ_name_utf8);
+
+    return ret;
+}
+
+static krb5_error_code
+k5_insert_checksum(krb5_context context,
+                   krb5_pac pac,
+                   krb5_ui_4 type,
+                   const krb5_keyblock *key,
+                   krb5_cksumtype *cksumtype)
+{
+    krb5_error_code ret;
+    size_t len;
+    krb5_data cksumdata;
+
+    ret = krb5int_c_mandatory_cksumtype(context, key->enctype, cksumtype);
+    if (ret != 0)
+        return ret;
+
+    ret = krb5_c_checksum_length(context, *cksumtype, &len);
+    if (ret != 0)
+        return ret;
+
+    ret = k5_pac_locate_buffer(context, pac, type, &cksumdata);
+    if (ret == 0) {
+        /*
+         * If we're resigning PAC, make sure we can fit checksum
+         * into existing buffer
+         */
+        if (cksumdata.length != PAC_SIGNATURE_DATA_LENGTH + len)
+            return ERANGE;
+
+        memset(cksumdata.data, 0, cksumdata.length);
+    } else {
+        /* Add a zero filled buffer */
+        cksumdata.length = PAC_SIGNATURE_DATA_LENGTH + len;
+        cksumdata.data = NULL;
+
+        ret = k5_pac_add_buffer(context, pac,
+                                type, &cksumdata,
+                                TRUE, &cksumdata);
+        if (ret != 0)
+            return ret;
+    }
+
+    /* Encode checksum type into buffer */
+    store_32_le((krb5_ui_4)*cksumtype, cksumdata.data);
+
+    return 0;
+}
+
+/* in-place encoding of PAC header */
+static krb5_error_code
+k5_pac_encode_header(krb5_context context, krb5_pac pac)
+{
+    size_t i;
+    unsigned char *p;
+    size_t header_len;
+
+    header_len = PACTYPE_LENGTH +
+        (pac->pac->cBuffers * PAC_INFO_BUFFER_LENGTH);
+    assert(pac->data.length >= header_len);
+
+    p = (unsigned char *)pac->data.data;
+
+    store_32_le(pac->pac->cBuffers, p);
+    p += 4;
+    store_32_le(pac->pac->Version, p);
+    p += 4;
+
+    for (i = 0; i < pac->pac->cBuffers; i++) {
+        PAC_INFO_BUFFER *buffer = &pac->pac->Buffers[i];
+
+        store_32_le(buffer->ulType, p);
+        p += 4;
+        store_32_le(buffer->cbBufferSize, p);
+        p += 4;
+        store_64_le(buffer->Offset, p);
+        p += 8;
+
+        assert((buffer->Offset % PAC_ALIGNMENT) == 0);
+        assert(buffer->Offset + buffer->cbBufferSize <= pac->data.length);
+        assert(buffer->Offset >= header_len);
+
+        if (buffer->Offset % PAC_ALIGNMENT ||
+            buffer->Offset + buffer->cbBufferSize > pac->data.length ||
+            buffer->Offset < header_len)
+            return ERANGE;
+    }
+
+    return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5int_pac_sign(krb5_context context,
+                 krb5_pac pac,
+                 krb5_timestamp authtime,
+                 krb5_const_principal principal,
+                 const krb5_keyblock *server_key,
+                 const krb5_keyblock *privsvr_key,
+                 krb5_data *data)
+{
+    krb5_error_code ret;
+    krb5_data server_cksum, privsvr_cksum;
+    krb5_cksumtype server_cksumtype, privsvr_cksumtype;
+    krb5_crypto_iov iov[2];
+
+    data->length = 0;
+    data->data = NULL;
+
+    if (principal != NULL) {
+        ret = k5_insert_client_info(context, pac, authtime, principal);
+        if (ret != 0)
+            return ret;
+    }
+
+    /* Create zeroed buffers for both checksums */
+    ret = k5_insert_checksum(context, pac, PAC_SERVER_CHECKSUM,
+                             server_key, &server_cksumtype);
+    if (ret != 0)
+        return ret;
+
+    ret = k5_insert_checksum(context, pac, PAC_PRIVSVR_CHECKSUM,
+                             privsvr_key, &privsvr_cksumtype);
+    if (ret != 0)
+        return ret;
+
+    /* Now, encode the PAC header so that the checksums will include it */
+    ret = k5_pac_encode_header(context, pac);
+    if (ret != 0)
+        return ret;
+
+    /* Generate the server checksum over the entire PAC */
+    ret = k5_pac_locate_buffer(context, pac,
+                               PAC_SERVER_CHECKSUM, &server_cksum);
+    if (ret != 0)
+        return ret;
+
+    assert(server_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
+
+    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    iov[0].data = pac->data;
+
+    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+    iov[1].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
+    iov[1].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
+
+    ret = krb5_c_make_checksum_iov(context, server_cksumtype,
+                                   server_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
+                                   iov, sizeof(iov)/sizeof(iov[0]));
+    if (ret != 0)
+        return ret;
+
+    /* Generate the privsvr checksum over the server checksum buffer */
+    ret = k5_pac_locate_buffer(context, pac,
+                               PAC_PRIVSVR_CHECKSUM, &privsvr_cksum);
+    if (ret != 0)
+        return ret;
+
+    assert(privsvr_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
+
+    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+    iov[0].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
+    iov[0].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
+
+    iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+    iov[1].data.data = privsvr_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
+    iov[1].data.length = privsvr_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
+
+    ret = krb5_c_make_checksum_iov(context, privsvr_cksumtype,
+                                   privsvr_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
+                                   iov, sizeof(iov)/sizeof(iov[0]));
+    if (ret != 0)
+        return ret;
+
+    data->data = malloc(pac->data.length);
+    if (data->data == NULL)
+        return ENOMEM;
+
+    data->length = pac->data.length;
+
+    memcpy(data->data, pac->data.data, pac->data.length);
+    memset(pac->data.data, 0,
+           PACTYPE_LENGTH + (pac->pac->cBuffers * PAC_INFO_BUFFER_LENGTH));
+
+    return 0;
+}

Modified: trunk/src/lib/krb5/os/locate_kdc.c
===================================================================
--- trunk/src/lib/krb5/os/locate_kdc.c	2010-01-08 14:54:04 UTC (rev 23612)
+++ trunk/src/lib/krb5/os/locate_kdc.c	2010-01-08 19:35:40 UTC (rev 23613)
@@ -310,7 +310,7 @@
  */
 
 static krb5_error_code
-krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
+locate_srv_conf_1(krb5_context context, const krb5_data *realm,
                        const char * name, struct addrlist *addrlist,
                        int get_masters, int socktype,
                        int udpport, int sec_udpport, int family)
@@ -491,7 +491,7 @@
 {
     krb5_error_code ret;
 
-    ret = krb5_locate_srv_conf_1 (context, realm, name, al,
+    ret = locate_srv_conf_1 (context, realm, name, al,
                                   get_masters, 0, udpport, sec_udpport, 0);
     if (ret)
         return ret;
@@ -503,7 +503,7 @@
 
 #ifdef KRB5_DNS_LOOKUP
 static krb5_error_code
-krb5_locate_srv_dns_1 (const krb5_data *realm,
+locate_srv_dns_1 (const krb5_data *realm,
                        const char *service,
                        const char *protocol,
                        struct addrlist *addrlist,
@@ -750,7 +750,7 @@
         return EBUSY;           /* XXX */
     }
 
-    return krb5_locate_srv_conf_1 (context, realm, profname, addrlist,
+    return locate_srv_conf_1 (context, realm, profname, addrlist,
                                    0, socktype,
                                    dflport1, dflport2, family);
 }
@@ -789,12 +789,12 @@
 
     code = 0;
     if (socktype == SOCK_DGRAM || socktype == 0) {
-        code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", addrlist, family);
+        code = locate_srv_dns_1(realm, dnsname, "_udp", addrlist, family);
         if (code)
             Tprintf("dns udp lookup returned error %d\n", code);
     }
     if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
-        code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", addrlist, family);
+        code = locate_srv_dns_1(realm, dnsname, "_tcp", addrlist, family);
         if (code)
             Tprintf("dns tcp lookup returned error %d\n", code);
     }




More information about the cvs-krb5 mailing list