aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/asn.1
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/asn.1')
-rw-r--r--src/lib/krb5/asn.1/ChangeLog100
-rw-r--r--src/lib/krb5/asn.1/Makefile.in73
-rw-r--r--src/lib/krb5/asn.1/asn1_decode.c46
-rw-r--r--src/lib/krb5/asn.1/asn1_decode.h2
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.c101
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.h4
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c43
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.h7
-rw-r--r--src/lib/krb5/asn.1/krb5_decode.c62
-rw-r--r--src/lib/krb5/asn.1/krb5_encode.c73
10 files changed, 454 insertions, 57 deletions
diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog
index b1ff161..18e4c07 100644
--- a/src/lib/krb5/asn.1/ChangeLog
+++ b/src/lib/krb5/asn.1/ChangeLog
@@ -1,3 +1,103 @@
+2003-10-08 Tom Yu <tlyu@mit.edu>
+
+ * asn1_k_encode.c (asn1_encode_krb_saved_safe_body): New function;
+ kludge to insert a raw pre-encoded KRB-SAFE-BODY.
+
+ * asn1_k_encode.h (asn1_encode_krb_saved_safe_body): Add
+ prototype.
+
+ * krb5_decode.c (decode_krb5_safe_with_body): New function; saves
+ a copy of the encoding of the KRB-SAFE-BODY to avoid problems
+ caused by re-encoding it during verification.
+
+ * krb5_encode.c (encode_krb5_safe_with_body): New function;
+ re-encode a KRB-SAFE using a saved KRB-SAFE-BODY encoding, to
+ avoid trouble with re-encoding a KRB-SAFE-BODY.
+
+2003-07-22 Sam Hartman <hartmans@avalanche-breakdown.mit.edu>
+
+ * asn1_k_decode.c (asn1_decode_etype_info2_entry_1_3): Decoder for
+ the broken 1.3 ASN.1 behavior for etype_info2; see bug 1681.
+
+ * asn1_k_decode.h (asn1_decode_etype_info2): Add v1_3_behavior
+ flag for parsing the broken 1.3 behavior of using an octetString
+ instead of generalString
+
+ * asn1_k_decode.c (asn1_decode_etype_info2_entry): Expect etype_info2 as generalstring not octetstring
+
+2003-06-20 Sam Hartman <hartmans@mit.edu>
+
+ * asn1_k_decode.h (asn1_decode_etype_info2): Prototype. Also
+ deleted prototype for asn1_decode_etype_info_entry as that is not
+ used outside asn1_k_decode.c
+
+ * krb5_decode.c (decode_krb5_etype_info2): Call etype_info2 decoder
+
+ * asn1_k_decode.c (asn1_decode_etype_info_entry): Split out
+ etype_info2 and etype_info decoder so we ignore tag 2 in the
+ heimdal encoder
+ (asn1_decode_etype_info2): new function
+
+2003-05-23 Sam Hartman <hartmans@mit.edu>
+
+ * asn1_k_decode.c (asn1_decode_etype_info_entry): Fix logic error
+ that incorrectly set up s2kparams.data
+
+2003-05-20 Ezra Peisach <epeisach@bu.edu>
+
+ * asn1_k_encode.c (asn1_encode_krb_safe_body): Use
+ asn1_encode_unsigned_integer for sequence number.
+
+ * asn1_k_decode.c (asn1_decode_krb_safe_body): Use
+ asn1_decode_seqnum to decode sequence number.
+
+
+2003-05-18 Tom Yu <tlyu@mit.edu>
+
+ * asn1_decode.c (asn1_decode_maybe_unsigned): New function; decode
+ negative 32-bit numbers into positive unsigned numbers for the
+ sake of backwards compatibility with old code.
+
+ * asn1_decode.h: Add prototype for asn1_decode_maybe_unsigned.
+
+ * asn1_k_decode.c (asn1_decode_seqnum): New function; wrapper
+ around asn1_decode_maybe_unsigned.
+
+ * asn1_k_decode.h: Add prototype for asn1_decode_seqnum.
+
+ * krb5_decode.c (decode_krb5_authenticator)
+ (decode_krb5_ap_rep_enc_part, decode_krb5_enc_priv_part): Sequence
+ numbers are now unsigned. Use asn1_decode_seqnum to handle
+ backwards compat with negative sequence numbers.
+
+ * krb5_encode.c (encode_krb5_authenticator)
+ (encode_krb5_ap_rep_enc_part, encode_krb5_enc_priv_part): Sequence
+ numbers are now unsigned.
+
+2003-05-06 Sam Hartman <hartmans@mit.edu>
+
+ * krb5_decode.c (decode_krb5_etype_info2): New function; currently
+ the same code as decode_krb5_etype_info. This means that we can
+ manage to accept s2kparams in etype_info which is wrong but
+ probably harmless.
+
+ * asn1_k_decode.c (asn1_decode_etype_info_entry): Add etype_info2
+ support
+
+ * asn1_k_encode.c (asn1_encode_etype_info_entry): Add support for
+ etype-info2
+
+ * krb5_encode.c (encode_krb5_etype_info2): New function
+
+2003-04-15 Sam Hartman <hartmans@mit.edu>
+
+ * krb5_encode.c (encode_krb5_setpw_req): new function
+
+2003-04-13 Ezra Peisach <epeisach@mit.edu>
+
+ * asn1_k_decode.c (asn1_decode_kdc_req_body): Fix memory leak if
+ optional server field is lacking,
+
2003-03-11 Ken Raeburn <raeburn@mit.edu>
* asn1_get.c (asn1_get_tag): Deleted.
diff --git a/src/lib/krb5/asn.1/Makefile.in b/src/lib/krb5/asn.1/Makefile.in
index 6757046..8de97f0 100644
--- a/src/lib/krb5/asn.1/Makefile.in
+++ b/src/lib/krb5/asn.1/Makefile.in
@@ -61,61 +61,66 @@ clean-unix:: clean-libobjs
#
asn1_decode.so asn1_decode.po $(OUTPRE)asn1_decode.$(OBJEXT): asn1_decode.c asn1_decode.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h asn1buf.h asn1_get.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_get.h
asn1_k_decode.so asn1_k_decode.po $(OUTPRE)asn1_k_decode.$(OBJEXT): asn1_k_decode.c asn1_k_decode.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h asn1buf.h asn1_decode.h asn1_get.h asn1_misc.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_decode.h \
+ asn1_get.h asn1_misc.h
asn1_encode.so asn1_encode.po $(OUTPRE)asn1_encode.$(OBJEXT): asn1_encode.c asn1_encode.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h asn1buf.h asn1_make.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h asn1_make.h
asn1_get.so asn1_get.po $(OUTPRE)asn1_get.$(OBJEXT): asn1_get.c asn1_get.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h asn1buf.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h
asn1_make.so asn1_make.po $(OUTPRE)asn1_make.$(OBJEXT): asn1_make.c asn1_make.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h asn1buf.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h asn1buf.h
asn1buf.so asn1buf.po $(OUTPRE)asn1buf.$(OBJEXT): asn1buf.c asn1buf.h $(SRCTOP)/include/k5-int.h \
$(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
- $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+ $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5.h \
+ $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
- $(BUILDTOP)/include/profile.h krbasn1.h asn1_get.h
+ krbasn1.h asn1_get.h
krb5_decode.so krb5_decode.po $(OUTPRE)krb5_decode.$(OBJEXT): krb5_decode.c $(BUILDTOP)/include/krb5.h \
$(COM_ERR_DEPS) krbasn1.h $(SRCTOP)/include/k5-int.h \
$(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+ $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
$(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- asn1_k_decode.h asn1buf.h asn1_decode.h asn1_get.h
+ $(SRCTOP)/include/krb5/kdb.h asn1_k_decode.h asn1buf.h \
+ asn1_decode.h asn1_get.h
krb5_encode.so krb5_encode.po $(OUTPRE)krb5_encode.$(OBJEXT): krb5_encode.c $(BUILDTOP)/include/krb5.h \
$(COM_ERR_DEPS) asn1_k_encode.h $(SRCTOP)/include/k5-int.h \
$(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+ $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/profile.h \
$(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- asn1buf.h krbasn1.h asn1_encode.h asn1_make.h
+ $(SRCTOP)/include/krb5/kdb.h asn1buf.h krbasn1.h asn1_encode.h \
+ asn1_make.h
asn1_k_encode.so asn1_k_encode.po $(OUTPRE)asn1_k_encode.$(OBJEXT): asn1_k_encode.c asn1_k_encode.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- asn1buf.h krbasn1.h asn1_make.h asn1_encode.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h asn1buf.h krbasn1.h asn1_make.h \
+ asn1_encode.h
asn1_misc.so asn1_misc.po $(OUTPRE)asn1_misc.$(OBJEXT): asn1_misc.c asn1_misc.h \
$(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
- $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/profile.h \
- krbasn1.h
+ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
+ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/include/krb5/kdb.h krbasn1.h
diff --git a/src/lib/krb5/asn.1/asn1_decode.c b/src/lib/krb5/asn.1/asn1_decode.c
index 56904c5..6586320 100644
--- a/src/lib/krb5/asn.1/asn1_decode.c
+++ b/src/lib/krb5/asn.1/asn1_decode.c
@@ -1,7 +1,7 @@
/*
* src/lib/krb5/asn.1/asn1_decode.c
*
- * Copyright 1994 by the Massachusetts Institute of Technology.
+ * Copyright 1994, 2003 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -106,6 +106,50 @@ asn1_error_code asn1_decode_unsigned_integer(asn1buf *buf, long unsigned int *va
cleanup();
}
+/*
+ * asn1_decode_maybe_unsigned
+ *
+ * This is needed because older releases of MIT krb5 have signed
+ * sequence numbers. We want to accept both signed and unsigned
+ * sequence numbers, in the range -2^31..2^32-1, mapping negative
+ * numbers into their positive equivalents in the same way that C's
+ * normal integer conversions do, i.e., would preserve bits on a
+ * two's-complement architecture.
+ */
+asn1_error_code asn1_decode_maybe_unsigned(asn1buf *buf, unsigned long *val)
+{
+ setup();
+ asn1_octet o;
+ unsigned long n, bitsremain;
+ unsigned int i;
+
+ tag(ASN1_INTEGER);
+ o = 0;
+ n = 0;
+ bitsremain = ~0UL;
+ for (i = 0; i < length; i++) {
+ /* Accounts for u_long width not being a multiple of 8. */
+ if (bitsremain < 0xff) return ASN1_OVERFLOW;
+ retval = asn1buf_remove_octet(buf, &o);
+ if (retval) return retval;
+ if (bitsremain == ~0UL) {
+ if (i == 0)
+ n = (o & 0x80) ? ~0UL : 0UL; /* grab sign bit */
+ /*
+ * Skip leading zero or 0xFF octets to humor non-compliant encoders.
+ */
+ if (n == 0 && o == 0)
+ continue;
+ if (n == ~0UL && o == 0xff)
+ continue;
+ }
+ n = (n << 8) | o;
+ bitsremain >>= 8;
+ }
+ *val = n;
+ cleanup();
+}
+
asn1_error_code asn1_decode_oid(asn1buf *buf, unsigned int *retlen, asn1_octet **val)
{
setup();
diff --git a/src/lib/krb5/asn.1/asn1_decode.h b/src/lib/krb5/asn.1/asn1_decode.h
index 449a589..cafbf3f 100644
--- a/src/lib/krb5/asn.1/asn1_decode.h
+++ b/src/lib/krb5/asn.1/asn1_decode.h
@@ -62,6 +62,8 @@ asn1_error_code asn1_decode_integer
(asn1buf *buf, long *val);
asn1_error_code asn1_decode_unsigned_integer
(asn1buf *buf, unsigned long *val);
+asn1_error_code asn1_decode_maybe_unsigned
+ (asn1buf *buf, unsigned long *val);
asn1_error_code asn1_decode_null
(asn1buf *buf);
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c
index c64ebb8..3ffb701 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.c
+++ b/src/lib/krb5/asn.1/asn1_k_decode.c
@@ -320,6 +320,17 @@ integer_convert(asn1_decode_authdatatype,krb5_authdatatype)
unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2)
unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4)
+asn1_error_code asn1_decode_seqnum(asn1buf *buf, krb5_ui_4 *val)
+{
+ asn1_error_code retval;
+ unsigned long n;
+
+ retval = asn1_decode_maybe_unsigned(buf, &n);
+ if (retval) return retval;
+ *val = (krb5_ui_4)n & 0xffffffff;
+ return 0;
+}
+
asn1_error_code asn1_decode_msgtype(asn1buf *buf, krb5_msgtype *val)
{
asn1_error_code retval;
@@ -541,7 +552,9 @@ asn1_error_code asn1_decode_kdc_req(asn1buf *buf, krb5_kdc_req *val)
asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val)
{
setup();
- { begin_structure();
+ {
+ krb5_principal psave;
+ begin_structure();
get_field(val->kdc_options,0,asn1_decode_kdc_options);
if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); }
opt_field(val->client,1,asn1_decode_principal_name,NULL);
@@ -550,7 +563,19 @@ asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val)
if(val->client != NULL){
retval = asn1_krb5_realm_copy(val->client,val->server);
if(retval) return retval; }
+
+ /* If opt_field server is missing, memory reference to server is
+ lost and results in memory leak */
+ psave = val->server;
opt_field(val->server,3,asn1_decode_principal_name,NULL);
+ if(val->server == NULL){
+ if(psave->realm.data) {
+ free(psave->realm.data);
+ psave->realm.data = NULL;
+ psave->realm.length=0;
+ }
+ free(psave);
+ }
opt_field(val->from,4,asn1_decode_kerberos_time,0);
get_field(val->till,5,asn1_decode_kerberos_time);
opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
@@ -580,7 +605,7 @@ asn1_error_code asn1_decode_krb_safe_body(asn1buf *buf, krb5_safe *val)
get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
opt_field(val->usec,2,asn1_decode_int32,0);
- opt_field(val->seq_number,3,asn1_decode_int32,0);
+ opt_field(val->seq_number,3,asn1_decode_seqnum,0);
alloc_field(val->s_address,krb5_address);
get_field(*(val->s_address),4,asn1_decode_host_address);
if(tagnum == 5){
@@ -782,7 +807,33 @@ asn1_error_code asn1_decode_sequence_of_checksum(asn1buf *buf, krb5_checksum ***
decode_array_body(krb5_checksum, asn1_decode_checksum);
}
-asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val)
+static asn1_error_code asn1_decode_etype_info2_entry(asn1buf *buf, krb5_etype_info_entry *val )
+{
+ setup();
+ { begin_structure();
+ get_field(val->etype,0,asn1_decode_enctype);
+ if (tagnum == 1) {
+ get_lenfield(val->length,val->salt,1,asn1_decode_generalstring);
+ } else {
+ val->length = KRB5_ETYPE_NO_SALT;
+ val->salt = 0;
+ }
+ if ( tagnum ==2) {
+ krb5_octet *params ;
+ get_lenfield( val->s2kparams.length, params,
+ 2, asn1_decode_octetstring);
+ val->s2kparams.data = ( char *) params;
+ } else {
+ val->s2kparams.data = NULL;
+ val->s2kparams.length = 0;
+ }
+ end_structure();
+ val->magic = KV5M_ETYPE_INFO_ENTRY;
+ }
+ cleanup();
+}
+
+static asn1_error_code asn1_decode_etype_info2_entry_1_3(asn1buf *buf, krb5_etype_info_entry *val )
{
setup();
{ begin_structure();
@@ -793,17 +844,59 @@ asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry
val->length = KRB5_ETYPE_NO_SALT;
val->salt = 0;
}
+ if ( tagnum ==2) {
+ krb5_octet *params ;
+ get_lenfield( val->s2kparams.length, params,
+ 2, asn1_decode_octetstring);
+ val->s2kparams.data = ( char *) params;
+ } else {
+ val->s2kparams.data = NULL;
+ val->s2kparams.length = 0;
+ }
end_structure();
val->magic = KV5M_ETYPE_INFO_ENTRY;
}
cleanup();
}
-asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val)
+
+static asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val )
+{
+ setup();
+ { begin_structure();
+ get_field(val->etype,0,asn1_decode_enctype);
+ if (tagnum == 1) {
+ get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
+ } else {
+ val->length = KRB5_ETYPE_NO_SALT;
+ val->salt = 0;
+ }
+ val->s2kparams.data = NULL;
+ val->s2kparams.length = 0;
+
+ end_structure();
+ val->magic = KV5M_ETYPE_INFO_ENTRY;
+ }
+ cleanup();
+}
+
+asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val )
{
decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry);
}
+asn1_error_code asn1_decode_etype_info2(asn1buf *buf, krb5_etype_info_entry ***val ,
+ krb5_boolean v1_3_behavior)
+{
+ if (v1_3_behavior) {
+ decode_array_body(krb5_etype_info_entry,
+ asn1_decode_etype_info2_entry_1_3);
+ } else {
+ decode_array_body(krb5_etype_info_entry,
+ asn1_decode_etype_info2_entry);
+ }
+}
+
asn1_error_code asn1_decode_passwdsequence(asn1buf *buf, passwd_phrase_element *val)
{
setup();
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.h b/src/lib/krb5/asn.1/asn1_k_decode.h
index 8f8b0bc..1852e76 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.h
+++ b/src/lib/krb5/asn.1/asn1_k_decode.h
@@ -89,6 +89,8 @@ asn1_error_code asn1_decode_ui_2
(asn1buf *buf, krb5_ui_2 *val);
asn1_error_code asn1_decode_ui_4
(asn1buf *buf, krb5_ui_4 *val);
+asn1_error_code asn1_decode_seqnum
+ (asn1buf *buf, krb5_ui_4 *val);
asn1_error_code asn1_decode_kerberos_time
(asn1buf *buf, krb5_timestamp *val);
asn1_error_code asn1_decode_sam_flags
@@ -185,6 +187,8 @@ asn1_error_code asn1_decode_sequence_of_passwdsequence
asn1_error_code asn1_decode_etype_info
(asn1buf *buf, krb5_etype_info_entry ***val);
+asn1_error_code asn1_decode_etype_info2
+ (asn1buf *buf, krb5_etype_info_entry ***val, krb5_boolean v1_3_behavior);
#endif
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 9226f7c..00cfab0 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -27,6 +27,7 @@
#include "asn1_k_encode.h"
#include "asn1_make.h"
#include "asn1_encode.h"
+#include <assert.h>
/**** asn1 macros ****/
#if 0
@@ -643,7 +644,7 @@ asn1_error_code asn1_encode_krb_safe_body(asn1buf *buf, const krb5_safe *val, un
asn1_addfield(val->r_address,5,asn1_encode_host_address);
asn1_addfield(val->s_address,4,asn1_encode_host_address);
if(val->seq_number)
- asn1_addfield(val->seq_number,3,asn1_encode_integer);
+ asn1_addfield(val->seq_number,3,asn1_encode_unsigned_integer);
if(val->timestamp){
asn1_addfield(val->usec,2,asn1_encode_integer);
asn1_addfield(val->timestamp,1,asn1_encode_kerberos_time);
@@ -708,24 +709,33 @@ asn1_error_code asn1_encode_krb_cred_info(asn1buf *buf, const krb5_cred_info *va
asn1_cleanup();
}
-asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info_entry *val, unsigned int *retlen)
+asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info_entry *val,
+ unsigned int *retlen, int etype_info2)
{
asn1_setup();
+ assert(val->s2kparams.data == NULL || etype_info2);
if(val == NULL || (val->length > 0 && val->length != KRB5_ETYPE_NO_SALT &&
val->salt == NULL))
return ASN1_MISSING_FIELD;
-
- if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT)
+ if(val->s2kparams.data != NULL)
+ asn1_addlenfield(val->s2kparams.length, val->s2kparams.data, 2,
+ asn1_encode_octetstring);
+ if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT){
+ if (etype_info2)
asn1_addlenfield(val->length,val->salt,1,
- asn1_encode_octetstring);
- asn1_addfield(val->etype,0,asn1_encode_integer);
+ asn1_encode_generalstring)
+ else asn1_addlenfield(val->length,val->salt,1,
+ asn1_encode_octetstring);
+ }
+asn1_addfield(val->etype,0,asn1_encode_integer);
asn1_makeseq();
asn1_cleanup();
}
-asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry **val, unsigned int *retlen)
+asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry **val,
+ unsigned int *retlen, int etype_info2)
{
asn1_setup();
int i;
@@ -734,7 +744,7 @@ asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry
for(i=0; val[i] != NULL; i++); /* get to the end of the array */
for(i--; i>=0; i--){
- retval = asn1_encode_etype_info_entry(buf,val[i],&length);
+ retval = asn1_encode_etype_info_entry(buf,val[i],&length, etype_info2);
if(retval) return retval;
sum += length;
}
@@ -932,3 +942,20 @@ asn1_error_code asn1_encode_predicted_sam_response(asn1buf *buf, const krb5_pred
asn1_cleanup();
}
+
+/*
+ * Do some ugliness to insert a raw pre-encoded KRB-SAFE-BODY.
+ */
+asn1_error_code asn1_encode_krb_saved_safe_body(asn1buf *buf, const krb5_data *body, unsigned int *retlen)
+{
+ asn1_error_code retval;
+
+ retval = asn1buf_insert_octetstring(buf, body->length,
+ (krb5_octet *)body->data);
+ if (retval){
+ asn1buf_destroy(&buf);
+ return retval;
+ }
+ *retlen = body->length;
+ return 0;
+}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.h b/src/lib/krb5/asn.1/asn1_k_encode.h
index 5914e09..caa46c5 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.h
+++ b/src/lib/krb5/asn.1/asn1_k_encode.h
@@ -219,11 +219,11 @@ asn1_error_code asn1_encode_alt_method
asn1_error_code asn1_encode_etype_info_entry
(asn1buf *buf, const krb5_etype_info_entry *val,
- unsigned int *retlen);
+ unsigned int *retlen, int etype_info2);
asn1_error_code asn1_encode_etype_info
(asn1buf *buf, const krb5_etype_info_entry **val,
- unsigned int *retlen);
+ unsigned int *retlen, int etype_info2);
asn1_error_code asn1_encode_passwdsequence
(asn1buf *buf, const passwd_phrase_element *val, unsigned int *retlen);
@@ -266,4 +266,7 @@ asn1_error_code asn1_encode_predicted_sam_response
(asn1buf *buf, const krb5_predicted_sam_response *val,
unsigned int *retlen);
+asn1_error_code asn1_encode_krb_saved_safe_body
+ (asn1buf *buf, const krb5_data *body, unsigned int *retlen);
+
#endif
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index 03a3029..596997f 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -90,6 +90,7 @@ if((var) == NULL) clean_return(ENOMEM)
construction = t2.construction; \
tagnum = t2.tagnum; \
indef = t2.indef; \
+ taglen = t2.length; \
}
#define get_eoc() \
@@ -107,6 +108,7 @@ if((var) == NULL) clean_return(ENOMEM)
/* decode sequence header and initialize tagnum with the first field */
#define begin_structure()\
+unsigned int taglen;\
asn1buf subbuf;\
int seqindef;\
int indef;\
@@ -219,7 +221,7 @@ krb5_error_code decode_krb5_authenticator(const krb5_data *code, krb5_authentica
get_field((*rep)->ctime,5,asn1_decode_kerberos_time);
if(tagnum == 6){ alloc_field((*rep)->subkey,krb5_keyblock); }
opt_field(*((*rep)->subkey),6,asn1_decode_encryption_key);
- opt_field((*rep)->seq_number,7,asn1_decode_int32);
+ opt_field((*rep)->seq_number,7,asn1_decode_seqnum);
opt_field((*rep)->authorization_data,8,asn1_decode_authorization_data);
(*rep)->magic = KV5M_AUTHENTICATOR;
end_structure();
@@ -440,7 +442,7 @@ krb5_error_code decode_krb5_ap_rep_enc_part(const krb5_data *code, krb5_ap_rep_e
get_field((*rep)->cusec,1,asn1_decode_int32);
if(tagnum == 2){ alloc_field((*rep)->subkey,krb5_keyblock); }
opt_field(*((*rep)->subkey),2,asn1_decode_encryption_key);
- opt_field((*rep)->seq_number,3,asn1_decode_int32);
+ opt_field((*rep)->seq_number,3,asn1_decode_seqnum);
end_structure();
(*rep)->magic = KV5M_AP_REP_ENC_PART;
}
@@ -494,8 +496,26 @@ krb5_error_code decode_krb5_kdc_req_body(const krb5_data *code, krb5_kdc_req **r
cleanup(free);
}
-krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
+/*
+ * decode_krb5_safe_with_body
+ *
+ * Like decode_krb5_safe(), but grabs the encoding of the
+ * KRB-SAFE-BODY as well, in case re-encoding would produce a
+ * different encoding. (Yes, we're using DER, but there's this
+ * annoying problem with pre-1.3.x code using signed sequence numbers,
+ * which we permissively decode and cram into unsigned 32-bit numbers.
+ * When they're re-encoded, they're no longer negative if they started
+ * out negative, so checksum verification fails.)
+ *
+ * This does *not* perform any copying; the returned pointer to the
+ * encoded KRB-SAFE-BODY points into the input buffer.
+ */
+krb5_error_code decode_krb5_safe_with_body(
+ const krb5_data *code,
+ krb5_safe **rep,
+ krb5_data *body)
{
+ krb5_data tmpbody;
setup();
alloc_field(*rep,krb5_safe);
clear_field(rep,checksum);
@@ -511,12 +531,26 @@ krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
if(msg_type != KRB5_SAFE) clean_return(KRB5_BADMSGTYPE);
#endif
}
+ /*
+ * Gross kludge to extract pointer to encoded safe-body. Relies
+ * on tag prefetch done by next_tag(). Don't handle indefinite
+ * encoding, as it's too much work.
+ */
+ if (!indef) {
+ tmpbody.length = taglen;
+ tmpbody.data = subbuf.next;
+ } else {
+ tmpbody.length = 0;
+ tmpbody.data = NULL;
+ }
get_field(**rep,2,asn1_decode_krb_safe_body);
alloc_field((*rep)->checksum,krb5_checksum);
get_field(*((*rep)->checksum),3,asn1_decode_checksum);
(*rep)->magic = KV5M_SAFE;
end_structure();
}
+ if (body != NULL)
+ *body = tmpbody;
cleanup_manual();
error_out:
if (rep && *rep) {
@@ -526,6 +560,11 @@ error_out:
return retval;
}
+krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep)
+{
+ return decode_krb5_safe_with_body(code, rep, NULL);
+}
+
krb5_error_code decode_krb5_priv(const krb5_data *code, krb5_priv **rep)
{
setup();
@@ -561,7 +600,7 @@ krb5_error_code decode_krb5_enc_priv_part(const krb5_data *code, krb5_priv_enc_p
get_lenfield((*rep)->user_data.length,(*rep)->user_data.data,0,asn1_decode_charstring);
opt_field((*rep)->timestamp,1,asn1_decode_kerberos_time);
opt_field((*rep)->usec,2,asn1_decode_int32);
- opt_field((*rep)->seq_number,3,asn1_decode_int32);
+ opt_field((*rep)->seq_number,3,asn1_decode_seqnum);
alloc_field((*rep)->s_address,krb5_address);
get_field(*((*rep)->s_address),4,asn1_decode_host_address);
if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); }
@@ -744,6 +783,21 @@ krb5_error_code decode_krb5_etype_info(const krb5_data *code, krb5_etype_info_en
cleanup_none(); /* we're not allocating anything here */
}
+krb5_error_code decode_krb5_etype_info2(const krb5_data *code, krb5_etype_info_entry ***rep)
+{
+ setup_buf_only();
+ *rep = 0;
+ retval = asn1_decode_etype_info2(&buf,rep, 0);
+ if (retval == ASN1_BAD_ID) {
+ retval = asn1buf_wrap_data(&buf,code);
+ if(retval) clean_return(retval);
+ retval = asn1_decode_etype_info2(&buf, rep, 1);
+ }
+ if(retval) clean_return(retval);
+ cleanup_none(); /* we're not allocating anything here */
+}
+
+
krb5_error_code decode_krb5_enc_data(const krb5_data *code, krb5_enc_data **rep)
{
setup_buf_only();
diff --git a/src/lib/krb5/asn.1/krb5_encode.c b/src/lib/krb5/asn.1/krb5_encode.c
index 2a4f7bb..ecdfa18 100644
--- a/src/lib/krb5/asn.1/krb5_encode.c
+++ b/src/lib/krb5/asn.1/krb5_encode.c
@@ -166,7 +166,7 @@ krb5_error_code encode_krb5_authenticator(const krb5_authenticator *rep, krb5_da
/* seq-number[7] INTEGER OPTIONAL */
if(rep->seq_number != 0)
- krb5_addfield(rep->seq_number,7,asn1_encode_integer);
+ krb5_addfield(rep->seq_number,7,asn1_encode_unsigned_integer);
/* subkey[6] EncryptionKey OPTIONAL */
if(rep->subkey != NULL)
@@ -305,6 +305,7 @@ krb5_error_code encode_krb5_enc_kdc_rep_part(const krb5_enc_kdc_rep_part *rep, k
#ifdef KRB5_ENCKRB5KDCREPPART_COMPAT
krb5_apptag(26);
#else
+ /* XXX WRONG!!! Should use 25 || 26, not the outer KDC_REP tags! */
if (rep->msg_type == KRB5_AS_REP) { krb5_apptag(ASN1_KRB_AS_REP); }
else if (rep->msg_type == KRB5_TGS_REP) { krb5_apptag(ASN1_KRB_TGS_REP); }
else return KRB5_BADMSGTYPE;
@@ -395,7 +396,7 @@ krb5_error_code encode_krb5_ap_rep_enc_part(const krb5_ap_rep_enc_part *rep, krb
/* seq-number[3] INTEGER OPTIONAL */
if(rep->seq_number)
- krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+ krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
/* subkey[2] EncryptionKey OPTIONAL */
if(rep->subkey != NULL)
@@ -477,6 +478,43 @@ krb5_error_code encode_krb5_safe(const krb5_safe *rep, krb5_data **code)
krb5_cleanup();
}
+/*
+ * encode_krb5_safe_with_body
+ *
+ * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY
+ * encoding to avoid problems with re-encoding.
+ */
+krb5_error_code encode_krb5_safe_with_body(
+ const krb5_safe *rep,
+ const krb5_data *body,
+ krb5_data **code)
+{
+ krb5_setup();
+
+ if (body == NULL) {
+ asn1buf_destroy(&buf);
+ return ASN1_MISSING_FIELD;
+ }
+
+ /* cksum[3] Checksum */
+ krb5_addfield(rep->checksum,3,asn1_encode_checksum);
+
+ /* safe-body[2] KRB-SAFE-BODY */
+ krb5_addfield(body,2,asn1_encode_krb_saved_safe_body);
+
+ /* msg-type[1] INTEGER */
+ krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
+
+ /* pvno[0] INTEGER */
+ krb5_addfield(KVNO,0,asn1_encode_integer);
+
+ /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
+ krb5_makeseq();
+ krb5_apptag(20);
+
+ krb5_cleanup();
+}
+
krb5_error_code encode_krb5_priv(const krb5_priv *rep, krb5_data **code)
{
krb5_setup();
@@ -510,7 +548,7 @@ krb5_error_code encode_krb5_enc_priv_part(const krb5_priv_enc_part *rep, krb5_da
/* seq-number[3] INTEGER OPTIONAL */
if(rep->seq_number)
- krb5_addfield(rep->seq_number,3,asn1_encode_integer);
+ krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
/* usec[2] INTEGER OPTIONAL */
if(rep->timestamp){
@@ -678,11 +716,21 @@ krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **c
krb5_error_code encode_krb5_etype_info(const krb5_etype_info_entry **rep, krb5_data **code)
{
krb5_setup();
- retval = asn1_encode_etype_info(buf,rep,&length);
+ retval = asn1_encode_etype_info(buf,rep,&length, 0);
+ if(retval) return retval;
+ sum += length;
+ krb5_cleanup();
+}
+
+krb5_error_code encode_krb5_etype_info2(const krb5_etype_info_entry **rep, krb5_data **code)
+{
+ krb5_setup();
+ retval = asn1_encode_etype_info(buf,rep,&length, 1);
if(retval) return retval;
sum += length;
krb5_cleanup();
}
+
krb5_error_code encode_krb5_enc_data(const krb5_enc_data *rep, krb5_data **code)
{
@@ -822,3 +870,20 @@ krb5_error_code encode_krb5_predicted_sam_response(const krb5_predicted_sam_resp
sum += length;
krb5_cleanup();
}
+
+krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
+ char *password, krb5_data **code)
+{
+ /* Macros really want us to have a variable called rep which we do not need*/
+ const char *rep = "dummy string";
+
+ krb5_setup();
+
+ krb5_addfield(target,2,asn1_encode_realm);
+ krb5_addfield(target,1,asn1_encode_principal_name);
+ krb5_addlenfield(strlen(password), password,0,asn1_encode_octetstring);
+ krb5_makeseq();
+
+
+ krb5_cleanup();
+}