FreeBSD/sys/kgssapi/krb5/krb5_mech.c
/*
 * Verify a token, checking the inner token length and mechanism oid.
 * pointer to the first byte of the TOK_ID. The length of the
 * encapsulated data is checked to be at least len bytes; the actual
 * length of the encapsulated data (including TOK_ID) is returned in
 * *encap_len.
 *
 * If can_pullup is TRUE and the token header is fragmented, we will
 * rearrange it.
 *
 * Format is as follows:
 *
 *	0x60			[APPLICATION 0] SEQUENCE
 *	DER encoded length	length of oid + type + inner token length
 *	0x06 NN <oid data>	OID of mechanism type
 *	TT TT			TOK_ID
 *	<inner token>		data for inner token
 *	
 * 1:		der encoded length
 */
Verify a token, checking the inner token length and mechanism oid.
pointer to the first byte of the TOK_ID. The length of the
encapsulated data is checked to be at least len bytes; the actual
length of the encapsulated data (including TOK_ID) is returned in
*encap_len.

If can_pullup is TRUE and the token header is fragmented, we will
rearrange it.

Format is as follows.

0x60                    [APPLICATION 0] SEQUENCE
DER encoded length      length of oid + type + inner token length
0x06 NN       OID of mechanism type
TT TT                   TOK_ID
           data for inner token

der encoded length
Verify a token checking the inner token length and mechanism oid . pointer to the first byte of the TOK_ID . The length of the encapsulated data is checked to be at least len bytes ; the actual length of the encapsulated data ( including TOK_ID ) is returned in * encap_len . If can_pullup is TRUE and the token header is fragmented we will rearrange it . Format is as follows . 0x60 [ APPLICATION 0 ] SEQUENCE DER encoded length length of oid + type + inner token length 0x06 NN OID of mechanism type TT TT TOK_ID data for inner token der encoded length
static void *
krb5_verify_token(char tok_id[2], size_t len, struct mbuf **mp,
    size_t *encap_len, bool_t can_pullup)
{
	struct mbuf *m;
	size_t tlen, hlen, len_len, inside_len;
	gss_OID oid = &krb5_mech_oid;
	uint8_t *p;
	m = *mp;
	tlen = m_length(m, NULL);
	if (tlen < 2)
		return (NULL);
	if (m->m_len < 2) {
		if (can_pullup)
			*mp = m = m_pullup(m, 2);
		else
			return (NULL);
	}
	p = m->m_data;
	if (*p++ != 0x60)
		return (NULL);
	if (*p < 0x80) {
		inside_len = *p++;
		len_len = 1;
	} else {
		len_len = (*p & 0x7f) + 1;
		if (tlen < len_len + 1)
			return (NULL);
		if (m->m_len < len_len + 1) {
			if (can_pullup)
				*mp = m = m_pullup(m, len_len + 1);
			else
				return (NULL);
			p = m->m_data + 1;
		}
		switch (*p++) {
		case 0x81:
			inside_len = *p++;
			break;
		case 0x82:
			inside_len = (p[0] << 8) | p[1];
			p += 2;
			break;
		case 0x83:
			inside_len = (p[0] << 16) | (p[1] << 8) | p[2];
			p += 3;
			break;
		case 0x84:
			inside_len = (p[0] << 24) | (p[1] << 16)
				| (p[2] << 8) | p[3];
			p += 4;
			break;
		default:
			return (NULL);
		}
	}
	if (tlen != inside_len + len_len + 1)
		return (NULL);
	if (inside_len < 2 + oid->length + len)
		return (NULL);
	hlen = 1 + len_len + 2 + oid->length + len;
	if (m->m_len < hlen) {
		if (can_pullup)
			*mp = m = m_pullup(m, hlen);
		else
			return (NULL);
		p = m->m_data + 1 + len_len;
	}
	if (*p++ != 0x06)
		return (NULL);
	if (*p++ != oid->length)
		return (NULL);
	if (bcmp(oid->elements, p, oid->length))
		return (NULL);
	p += oid->length;
	if (p[0] != tok_id[0])
		return (NULL);
	if (p[1] != tok_id[1])
		return (NULL);
	*encap_len = inside_len - 2 - oid->length;
	return (p);
}
static void * krb5_verify_token ( char tok_id [ 2 ] , size_t len , struct mbuf * * mp , size_t * encap_len , bool_t can_pullup ) { struct mbuf * m ; size_t tlen , hlen , len_len , inside_len ; gss_OID oid = & krb5_mech_oid ; uint8_t * p ; m = * mp ; tlen = m_length ( m , NULL ) ; if ( tlen < 2 ) return ( NULL ) ; if ( m -> m_len < 2 ) { if ( can_pullup ) * mp = m = m_pullup ( m , 2 ) ; else return ( NULL ) ; } p = m -> m_data ; if ( * p ++ != 0x60 ) return ( NULL ) ; if ( * p < 0x80 ) { inside_len = * p ++ ; len_len = 1 ; } else { len_len = ( * p & 0x7f ) + 1 ; if ( tlen < len_len + 1 ) return ( NULL ) ; if ( m -> m_len < len_len + 1 ) { if ( can_pullup ) * mp = m = m_pullup ( m , len_len + 1 ) ; else return ( NULL ) ; p = m -> m_data + 1 ; } switch ( * p ++ ) { case 0x81 : inside_len = * p ++ ; break ; case 0x82 : inside_len = ( p [ 0 ] << 8 ) | p [ 1 ] ; p += 2 ; break ; case 0x83 : inside_len = ( p [ 0 ] << 16 ) | ( p [ 1 ] << 8 ) | p [ 2 ] ; p += 3 ; break ; case 0x84 : inside_len = ( p [ 0 ] << 24 ) | ( p [ 1 ] << 16 ) | ( p [ 2 ] << 8 ) | p [ 3 ] ; p += 4 ; break ; default : return ( NULL ) ; } } if ( tlen != inside_len + len_len + 1 ) return ( NULL ) ; if ( inside_len < 2 + oid -> length + len ) return ( NULL ) ; hlen = 1 + len_len + 2 + oid -> length + len ; if ( m -> m_len < hlen ) { if ( can_pullup ) * mp = m = m_pullup ( m , hlen ) ; else return ( NULL ) ; p = m -> m_data + 1 + len_len ; } if ( * p ++ != 0x06 ) return ( NULL ) ; if ( * p ++ != oid -> length ) return ( NULL ) ; if ( bcmp ( oid -> elements , p , oid -> length ) ) return ( NULL ) ; p += oid -> length ; if ( p [ 0 ] != tok_id [ 0 ] ) return ( NULL ) ; if ( p [ 1 ] != tok_id [ 1 ] ) return ( NULL ) ; * encap_len = inside_len - 2 - oid -> length ; return ( p ) ; }
Verify a token, checking the inner token length and mechanism oid.
Verify a token checking the inner token length and mechanism oid .
/*
	 * Ensure that at least the framing part of the token is
	 * contigous.
	 */ /*
		 * Ensure there is enough space for the DER encoded length.
		 */ /*
	 * Now that we know the value of len_len, we can pullup the
	 * whole header. The header is 1 + len_len + 2 + oid->length +
	 * len bytes.
	 */