diff options
| author | Ken Raeburn <raeburn@mit.edu> | 2003-12-13 07:07:23 +0000 |
|---|---|---|
| committer | Ken Raeburn <raeburn@mit.edu> | 2003-12-13 07:07:23 +0000 |
| commit | 4034e2497a7c2d1f7bd25dcf4b1900fcfce0ff1f (patch) | |
| tree | 9d1cfd73cb55cce404854a39583e5b9761b7576c /src/lib/gssapi/generic | |
| parent | fdf31b235367b03333258af5e524c36fbd1eee64 (diff) | |
| download | krb5-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/ChangeLog | 17 | ||||
| -rw-r--r-- | src/lib/gssapi/generic/gssapiP_generic.h | 14 | ||||
| -rw-r--r-- | src/lib/gssapi/generic/util_ordering.c | 56 | ||||
| -rw-r--r-- | src/lib/gssapi/generic/util_token.c | 25 |
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; +} |
