/*
- * Copyright (c) 2010, JANET(UK)
+ * Copyright (c) 2011, JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ * Utility routines for GSS tokens.
+ */
+
#include "gssapiP_eap.h"
/*
der_length_size(size_t length)
{
if (length < (1<<7))
- return(1);
+ return 1;
else if (length < (1<<8))
- return(2);
+ return 2;
#if INT_MAX == 0x7fff
else
- return(3);
+ return 3;
#else
else if (length < (1<<16))
- return(3);
+ return 3;
else if (length < (1<<24))
- return(4);
+ return 4;
else
- return(5);
+ return 5;
#endif
}
(*bufsize)--;
if (sf & 0x80) {
if ((sf &= 0x7f) > ((*bufsize)-1))
- return(-1);
+ return -1;
if (sf > sizeof(int))
- return (-1);
+ return -1;
ret = 0;
for (; sf; sf--) {
ret = (ret<<8) + (*(*buf)++);
{
/* set body_size to sequence contents size */
body_size += 4 + (size_t) mech->length; /* NEED overflow check */
- return (1 + der_length_size(body_size) + body_size);
+ return 1 + der_length_size(body_size) + body_size;
}
/* fills in a buffer with the token header. The buffer is assumed to
*(*buf)++ = (unsigned char)mech->length;
memcpy(*buf, mech->elements, mech->length);
*buf += mech->length;
- if (tok_type != TOK_TYPE_NONE) {
- *(*buf)++ = (unsigned char)((tok_type>>8) & 0xff);
- *(*buf)++ = (unsigned char)(tok_type & 0xff);
- }
+ assert(tok_type != TOK_TYPE_NONE);
+ *(*buf)++ = (unsigned char)((tok_type>>8) & 0xff);
+ *(*buf)++ = (unsigned char)(tok_type & 0xff);
}
/*
* *body_size are left unmodified on error.
*/
-int
-verifyTokenHeader(
- const gss_OID_desc * mech,
- size_t *body_size,
- unsigned char **buf_in,
- size_t toksize_in,
- enum gss_eap_token_type tok_type)
+OM_uint32
+verifyTokenHeader(OM_uint32 *minor,
+ gss_OID mech,
+ size_t *body_size,
+ unsigned char **buf_in,
+ size_t toksize_in,
+ enum gss_eap_token_type *ret_tok_type)
{
unsigned char *buf = *buf_in;
ssize_t seqsize;
gss_OID_desc toid;
ssize_t toksize = (ssize_t)toksize_in;
- if (toksize -= 1 < 0)
- return ERANGE;
+ *minor = GSSEAP_BAD_TOK_HEADER;
+
+ if (ret_tok_type != NULL)
+ *ret_tok_type = TOK_TYPE_NONE;
+
+ if ((toksize -= 1) < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
if (*buf++ != 0x60)
- return EINVAL;
+ return GSS_S_DEFECTIVE_TOKEN;
seqsize = der_read_length(&buf, &toksize);
if (seqsize < 0)
- return ERANGE;
+ return GSS_S_DEFECTIVE_TOKEN;
if (seqsize != toksize)
- return ERANGE;
+ return GSS_S_DEFECTIVE_TOKEN;
- if (toksize -= 1 < 0)
- return ERANGE;
+ if ((toksize -= 1) < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
if (*buf++ != 0x06)
- return EINVAL;
+ return GSS_S_DEFECTIVE_TOKEN;
- if (toksize -= 1 < 0)
- return ERANGE;
+ if ((toksize -= 1) < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
toid.length = *buf++;
- if (toksize -= toid.length < 0)
- return ERANGE;
+ if ((toksize -= toid.length) < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
toid.elements = buf;
buf += toid.length;
- if (!oidEqual(&toid, mech))
- return EINVAL;
+ if (mech->elements == NULL) {
+ *mech = toid;
+ if (toid.length == 0)
+ return GSS_S_BAD_MECH;
+ } else if (!oidEqual(&toid, mech)) {
+ *minor = GSSEAP_WRONG_MECH;
+ return GSS_S_BAD_MECH;
+ }
- if (tok_type != TOK_TYPE_NONE) {
- if (toksize -= 2 < 0)
- return EINVAL;
+ if (ret_tok_type != NULL) {
+ if ((toksize -= 2) < 0)
+ return GSS_S_DEFECTIVE_TOKEN;
- if ((*buf++ != ((tok_type>>8) & 0xff)) ||
- (*buf++ != (tok_type & 0xff)))
- return EINVAL;
+ *ret_tok_type = load_uint16_be(buf);
+ buf += 2;
}
+
*buf_in = buf;
*body_size = toksize;
- return 0;
+ *minor = 0;
+ return GSS_S_COMPLETE;
}