summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/generic
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2003-12-13 07:07:23 +0000
committerKen Raeburn <raeburn@mit.edu>2003-12-13 07:07:23 +0000
commit4034e2497a7c2d1f7bd25dcf4b1900fcfce0ff1f (patch)
tree9d1cfd73cb55cce404854a39583e5b9761b7576c /src/lib/gssapi/generic
parentfdf31b235367b03333258af5e524c36fbd1eee64 (diff)
downloadkrb5-4034e2497a7c2d1f7bd25dcf4b1900fcfce0ff1f.tar.gz
krb5-4034e2497a7c2d1f7bd25dcf4b1900fcfce0ff1f.tar.xz
krb5-4034e2497a7c2d1f7bd25dcf4b1900fcfce0ff1f.zip
Add 64-bit sequence number support. Do sequence number ordering tests relative
to the initial value rather than absolute. Support tokens without pseudo-ASN.1 wrappers. Don't restrict enctype lists. Implement CFX token support. With CFX_EXERCISE defined, use random padding, random rotates, and bogus initial tokens, to exercise the associated code paths. ticket: 2040 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15911 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi/generic')
-rw-r--r--src/lib/gssapi/generic/ChangeLog17
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h14
-rw-r--r--src/lib/gssapi/generic/util_ordering.c56
-rw-r--r--src/lib/gssapi/generic/util_token.c25
4 files changed, 86 insertions, 26 deletions
diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog
index 5444c99d6..a6e77399e 100644
--- a/src/lib/gssapi/generic/ChangeLog
+++ b/src/lib/gssapi/generic/ChangeLog
@@ -1,3 +1,20 @@
+2003-12-13 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_generic.h: Include k5-platform.h.
+ (gssint_uint64): New typedef.
+ (g_order_init, g_order_check): Update decls.
+ * util_ordering.c (struct _queue): Change sequence number fields
+ to gssint_uint64. Add mask field.
+ (queue_insert): Change sequence number to gssint_uint64.
+ (g_order_init): Change sequence numbers to gssint_uint64. Add
+ "wide_nums" argument; initialize the queue mask field based on
+ it; all callers changed. Store a -1 as the first element.
+ (g_order_check): Store and check elements as offsets from
+ firstnum. Mask to 32 bits if desired.
+ * util_token.c (g_verify_token_header): Add new argument
+ indicating whether the pseudo-ASN.1 wrapper is required; all
+ callers changed.
+
2003-07-17 Ken Raeburn <raeburn@mit.edu>
* Makefile.in (LIBNAME) [##WIN16##]: Don't define.
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index 102ba699e..24d51d0d5 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -40,6 +40,9 @@
#include "gssapi_err_generic.h"
#include <errno.h>
+#include "k5-platform.h"
+typedef UINT64_TYPE gssint_uint64;
+
/** helper macros **/
#define g_OID_equal(o1,o2) \
@@ -159,8 +162,9 @@ void g_make_token_header (gss_OID mech, unsigned int body_size,
unsigned char **buf, int tok_type);
gss_int32 g_verify_token_header (gss_OID mech, unsigned int *body_size,
- unsigned char **buf, int tok_type,
- unsigned int toksize_in);
+ unsigned char **buf, int tok_type,
+ unsigned int toksize_in,
+ int wrapper_required);
OM_uint32 g_display_major_status (OM_uint32 *minor_status,
OM_uint32 status_value,
@@ -171,10 +175,10 @@ OM_uint32 g_display_com_err_status (OM_uint32 *minor_status,
OM_uint32 status_value,
gss_buffer_t status_string);
-gss_int32 g_order_init (void **queue, OM_uint32 seqnum,
- int do_replay, int do_sequence);
+gss_int32 g_order_init (void **queue, gssint_uint64 seqnum,
+ int do_replay, int do_sequence, int wide);
-gss_int32 g_order_check (void **queue, OM_uint32 seqnum);
+gss_int32 g_order_check (void **queue, gssint_uint64 seqnum);
void g_order_free (void **queue);
diff --git a/src/lib/gssapi/generic/util_ordering.c b/src/lib/gssapi/generic/util_ordering.c
index 21a8b0641..fe2eaafc2 100644
--- a/src/lib/gssapi/generic/util_ordering.c
+++ b/src/lib/gssapi/generic/util_ordering.c
@@ -38,8 +38,14 @@ typedef struct _queue {
int do_sequence;
int start;
int length;
- unsigned int firstnum;
- unsigned int elem[QUEUE_LENGTH];
+ gssint_uint64 firstnum;
+ /* Stored as deltas from firstnum. This way, the high bit won't
+ overflow unless we've actually gone through 2**n messages, or
+ gotten something *way* out of sequence. */
+ gssint_uint64 elem[QUEUE_LENGTH];
+ /* All ones for 64-bit sequence numbers; 32 ones for 32-bit
+ sequence numbers. */
+ gssint_uint64 mask;
} queue;
/* rep invariant:
@@ -51,7 +57,7 @@ typedef struct _queue {
#define QELEM(q,i) ((q)->elem[(i)%QSIZE(q)])
static void
-queue_insert(queue *q, int after, unsigned int seqnum)
+queue_insert(queue *q, int after, gssint_uint64 seqnum)
{
/* insert. this is not the fastest way, but it's easy, and it's
optimized for insert at end, which is the common case */
@@ -80,10 +86,10 @@ queue_insert(queue *q, int after, unsigned int seqnum)
q->length++;
}
}
-
+
gss_int32
-g_order_init(void **vqueue, OM_uint32 seqnum,
- int do_replay, int do_sequence)
+g_order_init(void **vqueue, gssint_uint64 seqnum,
+ int do_replay, int do_sequence, int wide_nums)
{
queue *q;
@@ -92,38 +98,49 @@ g_order_init(void **vqueue, OM_uint32 seqnum,
q->do_replay = do_replay;
q->do_sequence = do_sequence;
+ q->mask = wide_nums ? ~(gssint_uint64)0 : 0xffffffffUL;
q->start = 0;
q->length = 1;
q->firstnum = seqnum;
- q->elem[q->start] = seqnum-1;
+ q->elem[q->start] = ((gssint_uint64)0 - 1) & q->mask;
*vqueue = (void *) q;
return(0);
}
gss_int32
-g_order_check(void **vqueue, OM_uint32 seqnum)
+g_order_check(void **vqueue, gssint_uint64 seqnum)
{
queue *q;
int i;
-
+ gssint_uint64 expected;
+
q = (queue *) (*vqueue);
if (!q->do_replay && !q->do_sequence)
return(GSS_S_COMPLETE);
+ /* All checks are done relative to the initial sequence number, to
+ avoid (or at least put off) the pain of wrapping. */
+ seqnum -= q->firstnum;
+ /* If we're only doing 32-bit values, adjust for that again.
+
+ Note that this will probably be the wrong thing to if we get
+ 2**32 messages sent with 32-bit sequence numbers. */
+ seqnum &= q->mask;
+
/* rule 1: expected sequence number */
- if (seqnum == QELEM(q,q->start+q->length-1)+1) {
+ expected = (QELEM(q,q->start+q->length-1)+1) & q->mask;
+ if (seqnum == expected) {
queue_insert(q, q->start+q->length-1, seqnum);
return(GSS_S_COMPLETE);
}
/* rule 2: > expected sequence number */
- if ((seqnum > QELEM(q,q->start+q->length-1)+1) ||
- (seqnum < q->firstnum)) {
+ if ((seqnum > expected)) {
queue_insert(q, q->start+q->length-1, seqnum);
if (q->do_replay && !q->do_sequence)
return(GSS_S_COMPLETE);
@@ -134,7 +151,20 @@ g_order_check(void **vqueue, OM_uint32 seqnum)
/* rule 3: seqnum < seqnum(first) */
if ((seqnum < QELEM(q,q->start)) &&
- (seqnum >= q->firstnum)) {
+ /* Is top bit of whatever width we're using set?
+
+ We used to check for greater than or equal to firstnum, but
+ (1) we've since switched to compute values relative to
+ firstnum, so the lowest we can have is 0, and (2) the effect
+ of the original scheme was highly dependent on whether
+ firstnum was close to either side of 0. (Consider
+ firstnum==0xFFFFFFFE and we miss three packets; the next
+ packet is *new* but would look old.)
+
+ This check should give us 2**31 or 2**63 messages "new", and
+ just as many "old". That's not quite right either. */
+ (seqnum & (1 + (q->mask >> 1)))
+ ) {
if (q->do_replay && !q->do_sequence)
return(GSS_S_OLD_TOKEN);
else
diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c
index 30ae0698c..97a788c09 100644
--- a/src/lib/gssapi/generic/util_token.c
+++ b/src/lib/gssapi/generic/util_token.c
@@ -168,12 +168,15 @@ void g_make_token_header(mech, body_size, buf, tok_type)
* mechanism in the token does not match the mech argument. buf and
* *body_size are left unmodified on error.
*/
-gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
+
+gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in,
+ wrapper_required)
gss_OID mech;
unsigned int *body_size;
unsigned char **buf_in;
int tok_type;
unsigned int toksize_in;
+ int wrapper_required;
{
unsigned char *buf = *buf_in;
int seqsize;
@@ -182,8 +185,13 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
if ((toksize-=1) < 0)
return(G_BAD_TOK_HEADER);
- if (*buf++ != 0x60)
- return(G_BAD_TOK_HEADER);
+ if (*buf++ != 0x60) {
+ if (wrapper_required)
+ return(G_BAD_TOK_HEADER);
+ buf--;
+ toksize++;
+ goto skip_wrapper;
+ }
if ((seqsize = der_read_length(&buf, &toksize)) < 0)
return(G_BAD_TOK_HEADER);
@@ -207,16 +215,17 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize_in)
if (! g_OID_equal(&toid, mech))
return G_WRONG_MECH;
+skip_wrapper:
if (tok_type != -1) {
if ((toksize-=2) < 0)
return(G_BAD_TOK_HEADER);
if ((*buf++ != ((tok_type>>8)&0xff)) ||
- (*buf++ != (tok_type&0xff)))
+ (*buf++ != (tok_type&0xff)))
return(G_WRONG_TOKID);
}
- *buf_in = buf;
- *body_size = toksize;
+ *buf_in = buf;
+ *body_size = toksize;
- return 0;
- }
+ return 0;
+}