Skip Menu |
 

Subject: asn.1 encoding of nonce differs from rfc4120 (signedness)
rfc4120 indicates that nonce should be an unsigned integer. ASN.1
encoding of a signed vs. unsigned int will differ if the high-bit is
set... Then, an additional octect of 0 needs to be included.

Currently, our nonce is based on time(0) - and the high bit is not
set... Nor will it be until 2038... But we should get this fixed sooner
rather than later.

Heimdal 0.7.1 is still using a signed int. The nonce is a randomly
assigned - so for interoperability - we would need to be careful in how
to handle this... If we encode as an unsigned int - would heimdals
decoder handle properly? Looking at heimdals code - der_get_integer will
only decode encodings of four bytes or less - sending a proper
representation
would bomb... So - if a heimdal client talks to a v5 kdc sending a nonce
with the high bit set - we will respond with a five byte encoding -
which heimdal will reject...

A patch for the basics - without interoperability issues is attached...
Download NONCEPATCH.txt
text/plain 4.6KiB
Index: src/include/krb5.hin
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = chemical/x-hin
Index: src/lib/krb5/asn.1/krb5_decode.c
===================================================================
--- src/lib/krb5/asn.1/krb5_decode.c (revision 17399)
+++ src/lib/krb5/asn.1/krb5_decode.c (working copy)
@@ -661,7 +661,7 @@
check_apptag(29);
{ begin_structure();
get_field((*rep)->ticket_info,0,asn1_decode_sequence_of_krb_cred_info);
- opt_field((*rep)->nonce,1,asn1_decode_int32);
+ opt_field((*rep)->nonce,1,asn1_decode_ui_4);
opt_field((*rep)->timestamp,2,asn1_decode_kerberos_time);
opt_field((*rep)->usec,3,asn1_decode_int32);
if(tagnum == 4){ alloc_field((*rep)->s_address,krb5_address); }
Index: src/lib/krb5/asn.1/asn1_k_decode.c
===================================================================
--- src/lib/krb5/asn.1/asn1_k_decode.c (revision 17399)
+++ src/lib/krb5/asn.1/asn1_k_decode.c (working copy)
@@ -491,7 +491,7 @@
alloc_field(val->session,krb5_keyblock);
get_field(*(val->session),0,asn1_decode_encryption_key);
get_field(val->last_req,1,asn1_decode_last_req);
- get_field(val->nonce,2,asn1_decode_int32);
+ get_field(val->nonce,2,asn1_decode_ui_4);
opt_field(val->key_exp,3,asn1_decode_kerberos_time,0);
get_field(val->flags,4,asn1_decode_ticket_flags);
get_field(val->times.authtime,5,asn1_decode_kerberos_time);
@@ -579,7 +579,7 @@
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);
- get_field(val->nonce,7,asn1_decode_int32);
+ get_field(val->nonce,7,asn1_decode_ui_4);
get_lenfield(val->nktypes,val->ktype,8,asn1_decode_sequence_of_enctype);
opt_field(val->addresses,9,asn1_decode_host_addresses,0);
if(tagnum == 10){
Index: src/lib/krb5/asn.1/krb5_encode.c
===================================================================
--- src/lib/krb5/asn.1/krb5_encode.c (revision 17399)
+++ src/lib/krb5/asn.1/krb5_encode.c (working copy)
@@ -609,9 +609,9 @@
krb5_addfield(rep->timestamp,2,asn1_encode_kerberos_time);
}

- /* nonce[1] INTEGER OPTIONAL */
+ /* nonce[1] UNSIGNED INTEGER OPTIONAL */
if(rep->nonce)
- krb5_addfield(rep->nonce,1,asn1_encode_integer);
+ krb5_addfield(rep->nonce,1,asn1_encode_unsigned_integer);

/* ticket-info[0] SEQUENCE OF KrbCredInfo */
krb5_addfield((const krb5_cred_info**)rep->ticket_info,
Index: src/lib/krb5/asn.1/asn1_k_encode.c
===================================================================
--- src/lib/krb5/asn.1/asn1_k_encode.c (revision 17399)
+++ src/lib/krb5/asn.1/asn1_k_encode.c (working copy)
@@ -357,8 +357,8 @@
if(val->key_exp)
asn1_addfield(val->key_exp,3,asn1_encode_kerberos_time);

- /* nonce[2] INTEGER */
- asn1_addfield(val->nonce,2,asn1_encode_integer);
+ /* nonce[2] UNSIGNED INTEGER */
+ asn1_addfield(val->nonce,2,asn1_encode_unsigned_integer);

/* last-req[1] LastReq */
asn1_addfield((const krb5_last_req_entry**)val->last_req,1,asn1_encode_last_req);
@@ -414,8 +414,8 @@
/* -- in preference order */
asn1_addlenfield(rep->nktypes,rep->ktype,8,asn1_encode_sequence_of_enctype);

- /* nonce[7] INTEGER, */
- asn1_addfield(rep->nonce,7,asn1_encode_integer);
+ /* nonce[7] UNSIGNED INTEGER, */
+ asn1_addfield(rep->nonce,7,asn1_encode_unsigned_integer);

/* rtime[6] KerberosTime OPTIONAL, */
if(rep->rtime)
Index: src/lib/krb5/krb/send_tgs.c
===================================================================
--- src/lib/krb5/krb/send_tgs.c (revision 17399)
+++ src/lib/krb5/krb/send_tgs.c (working copy)
@@ -159,7 +159,7 @@
if ((retval = krb5_timeofday(context, &time_now)))
return(retval);
/* XXX we know they are the same size... */
- rep->expected_nonce = tgsreq.nonce = (krb5_int32) time_now;
+ rep->expected_nonce = tgsreq.nonce = (krb5_ui_4) time_now;
rep->request_time = time_now;

tgsreq.addresses = (krb5_address **) addrs;
Index: src/lib/krb5/krb/get_in_tkt.c
===================================================================
--- src/lib/krb5/krb/get_in_tkt.c (revision 17399)
+++ src/lib/krb5/krb/get_in_tkt.c (working copy)
@@ -126,7 +126,7 @@
* XXX we know they are the same size... and we should do
* something better than just the current time
*/
- request->nonce = (krb5_int32) *time_now;
+ request->nonce = (krb5_ui_4) *time_now;

/* encode & send to KDC */
if ((retval = encode_krb5_as_req(request, &packet)) != 0)