diff options
Diffstat (limited to 'src/lib/gssapi/mechglue/g_imp_name.c')
-rw-r--r-- | src/lib/gssapi/mechglue/g_imp_name.c | 112 |
1 files changed, 29 insertions, 83 deletions
diff --git a/src/lib/gssapi/mechglue/g_imp_name.c b/src/lib/gssapi/mechglue/g_imp_name.c index c3e809c..a805078 100644 --- a/src/lib/gssapi/mechglue/g_imp_name.c +++ b/src/lib/gssapi/mechglue/g_imp_name.c @@ -28,6 +28,7 @@ */ #include "mglueP.h" +#include "k5-der.h" #include <stdio.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> @@ -181,13 +182,6 @@ allocation_failure: return (major_status); } -/* - * GSS export name constants - */ -static const unsigned int expNameTokIdLen = 2; -static const unsigned int mechOidLenLen = 2; -static const unsigned int nameTypeLenLen = 2; - static OM_uint32 importExportName(minor, unionName, inputNameType) OM_uint32 *minor; @@ -196,59 +190,31 @@ importExportName(minor, unionName, inputNameType) { gss_OID_desc mechOid; gss_buffer_desc expName; - unsigned char *buf; gss_mechanism mech; - OM_uint32 major, mechOidLen, nameLen, curLength; - unsigned int bytes; + OM_uint32 major, mechOidLen, nameLen; + uint8_t b2; + const uint8_t *name; + struct k5input in, oid, old_format; expName.value = unionName->external_name->value; expName.length = unionName->external_name->length; + k5_input_init(&in, expName.value, expName.length); - curLength = expNameTokIdLen + mechOidLenLen; - if (expName.length < curLength) + if (k5_input_get_byte(&in) != 0x04) return (GSS_S_DEFECTIVE_TOKEN); - - buf = (unsigned char *)expName.value; - if (buf[0] != 0x04) - return (GSS_S_DEFECTIVE_TOKEN); - if (buf[1] != 0x01 && buf[1] != 0x02) /* allow composite names */ + b2 = k5_input_get_byte(&in); + if (b2 != 0x01 && b2 != 0x02) /* allow composite names */ return (GSS_S_DEFECTIVE_TOKEN); - buf += expNameTokIdLen; + mechOidLen = k5_input_get_uint16_be(&in); - /* extract the mechanism oid length */ - mechOidLen = (*buf++ << 8); - mechOidLen |= (*buf++); - curLength += mechOidLen; - if (expName.length < curLength) + if (!k5_der_get_value(&in, 0x06, &oid)) return (GSS_S_DEFECTIVE_TOKEN); - /* - * The mechOid itself is encoded in DER format, OID Tag (0x06) - * length and the value of mech_OID - */ - if (*buf++ != 0x06) - return (GSS_S_DEFECTIVE_TOKEN); - - /* - * mechoid Length is encoded twice; once in 2 bytes as - * explained in RFC2743 (under mechanism independent exported - * name object format) and once using DER encoding - * - * We verify both lengths. - */ - - mechOid.length = gssint_get_der_length(&buf, - (expName.length - curLength), &bytes); - mechOid.elements = (void *)buf; - - /* - * 'bytes' is the length of the DER length, '1' is for the DER - * tag for OID - */ - if ((bytes + mechOid.length + 1) != mechOidLen) + /* Verify that mechOidLen is consistent with the DER OID length. */ + if (mechOidLen != k5_der_value_len(oid.len)) return (GSS_S_DEFECTIVE_TOKEN); - - buf += mechOid.length; + mechOid.length = oid.len; + mechOid.elements = (uint8_t *)oid.ptr; if ((mech = gssint_get_mechanism(&mechOid)) == NULL) return (GSS_S_BAD_MECH); @@ -297,21 +263,11 @@ importExportName(minor, unionName, inputNameType) * that included a null terminator which was counted in the * display name gss_buffer_desc. */ - curLength += 4; /* 4 bytes for name len */ - if (expName.length < curLength) - return (GSS_S_DEFECTIVE_TOKEN); /* next 4 bytes in the name are the name length */ - nameLen = load_32_be(buf); - buf += 4; - - /* - * we use < here because bad code in rpcsec_gss rounds up exported - * name token lengths and pads with nulls, otherwise != would be - * appropriate - */ - curLength += nameLen; /* this is the total length */ - if (expName.length < curLength) + nameLen = k5_input_get_uint32_be(&in); + name = k5_input_get_bytes(&in, nameLen); + if (name == NULL) return (GSS_S_DEFECTIVE_TOKEN); /* @@ -324,29 +280,19 @@ importExportName(minor, unionName, inputNameType) * and length) there's the name itself, though null-terminated; * this null terminator should also not be there, but it is. */ - if (nameLen > 0 && *buf == '\0') { + if (nameLen > 0 && *name == '\0') { OM_uint32 nameTypeLen; - /* next two bytes are the name oid */ - if (nameLen < nameTypeLenLen) - return (GSS_S_DEFECTIVE_TOKEN); - - nameLen -= nameTypeLenLen; - nameTypeLen = (*buf++) << 8; - nameTypeLen |= (*buf++); - - if (nameLen < nameTypeLen) + /* Skip the name type. */ + k5_input_init(&old_format, name, nameLen); + nameTypeLen = k5_input_get_uint16_be(&old_format); + if (k5_input_get_bytes(&old_format, nameTypeLen) == NULL) return (GSS_S_DEFECTIVE_TOKEN); - - buf += nameTypeLen; - nameLen -= nameTypeLen; - - /* - * adjust for expected null terminator that should - * really not be there - */ - if (nameLen > 0 && *(buf + nameLen - 1) == '\0') - nameLen--; + /* Remove a null terminator if one is present. */ + if (old_format.len > 0 && old_format.ptr[old_format.len - 1] == 0) + old_format.len--; + name = old_format.ptr; + nameLen = old_format.len; } /* @@ -365,7 +311,7 @@ importExportName(minor, unionName, inputNameType) * IDN is thrown in with Kerberos V extensions). */ expName.length = nameLen; - expName.value = nameLen ? (void *)buf : NULL; + expName.value = nameLen ? (uint8_t *)name : NULL; if (mech->gssspi_import_name_by_mech) { major = mech->gssspi_import_name_by_mech(minor, &mechOid, &expName, GSS_C_NULL_OID, |