Beispiel #1
0
static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
				       unsigned char *eoc,
				       unsigned long *integer)
{
	unsigned char ch;
	unsigned int  len;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*integer = ch;
	if (ch == 0) len = 0;
	else len = 1;

	while (ctx->pointer < eoc) {
		if (++len > sizeof (unsigned long)) {
			ctx->error = ASN1_ERR_DEC_BADVALUE;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*integer <<= 8;
		*integer |= ch;
	}
	return 1;
}
static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
                                        unsigned int *def,
                                        unsigned int *len)
{
	unsigned char ch, cnt;
	
	if (!asn1_octet_decode(ctx, &ch))
		return 0;
		
	if (ch == 0x80)
		*def = 0;
	else {
		*def = 1;
		
		if (ch < 0x80)
			*len = ch;
		else {
			cnt = (unsigned char) (ch & 0x7F);
			*len = 0;
			
			while (cnt > 0) {
				if (!asn1_octet_decode(ctx, &ch))
					return 0;
				*len <<= 8;
				*len |= ch;
				cnt--;
			}
		}
	}
	return 1;
}
Beispiel #3
0
static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
{
	unsigned char ch;

	if (eoc == NULL) {
		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		if (ch != 0x00) {
			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		if (ch != 0x00) {
			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
			return 0;
		}
		return 1;
	} else {
		if (ctx->pointer != eoc) {
			ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
			return 0;
		}
		return 1;
	}
}
Beispiel #4
0
static unsigned char
asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
{
	unsigned char ch, cnt;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	if (ch == 0x80)
		*def = 0;
	else {
		*def = 1;

		if (ch < 0x80)
			*len = ch;
		else {
			cnt = (unsigned char) (ch & 0x7F);
			*len = 0;

			while (cnt > 0) {
				if (!asn1_octet_decode(ctx, &ch))
					return 0;
				*len <<= 8;
				*len |= ch;
				cnt--;
			}
		}
	}

	/* don't trust len bigger than ctx buffer */
	if (*len > ctx->end - ctx->pointer)
		return 0;

	return 1;
}
static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
					unsigned char *eoc,
					unsigned char **octets,
					unsigned int *len)
{
	unsigned char *ptr;

	*len = 0;

	*octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC);
	if (*octets == NULL) {
		if (net_ratelimit())
			pr_notice("OOM in bsalg (%d)\n", __LINE__);
		return 0;
	}

	ptr = *octets;
	while (ctx->pointer < eoc) {
		if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) {
			kfree(*octets);
			*octets = NULL;
			return 0;
		}
		(*len)++;
	}
	return 1;
}
Beispiel #6
0
static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
{
	unsigned char ch;

	*tag = 0;

	do
	{
		if (!asn1_octet_decode(ctx, &ch))
			return 0;
		*tag <<= 7;
		*tag |= ch & 0x7F;
	} while ((ch & 0x80) == 0x80);
	return 1;
}
Beispiel #7
0
/*
 * NAME:        asn1_tag_get
 * SYNOPSIS:    int asn1_tag_get
 *                  (
 *                      ASN1_SCK *asn1,
 *                      guint    *tag
 *                  )
 * DESCRIPTION: Decodes a tag number, combining it with existing tag bits.
 * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
 */
static int
asn1_tag_get(ASN1_SCK *asn1, guint *tag)
{
    int    ret;
    guchar ch;

    do {
	ret = asn1_octet_decode (asn1, &ch);
	if (ret != ASN1_ERR_NOERROR)
	    return ret;
        *tag <<= 7;
        *tag |= ch & 0x7F;
    } while ((ch & 0x80) == 0x80);
    return ASN1_ERR_NOERROR;
}
Beispiel #8
0
static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,
				       unsigned long *subid)
{
	unsigned char ch;

	*subid = 0;

	do {
		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*subid <<= 7;
		*subid |= ch & 0x7F;
	} while ((ch & 0x80) == 0x80);
	return 1;
}
Beispiel #9
0
/*
 * NAME:        asn1_id_decode1
 * SYNOPSIS:    int asn1_id_decode1
 *                  (
 *                      ASN1_SCK *asn1,
 *                      guint    *tag
 *                  )
 * DESCRIPTION: Decodes an identifier.
 *		Like asn1_id_decode() except that the Class and Constructor
 *		bits are returned in the tag.
 * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
 */
int
asn1_id_decode1(ASN1_SCK *asn1, guint *tag)
{
    int    ret;
    guchar ch;

    *tag = 0;
    ret = asn1_octet_decode (asn1, &ch);
    if (ret != ASN1_ERR_NOERROR)
        return ret;

    *tag = ch;
    if ((*tag & 0x1F) == 0x1F) { /* high-tag-number format */
	*tag = ch >> 5;	/* leave just the Class and Constructor bits */
        ret = asn1_tag_get (asn1, tag);
        if (ret != ASN1_ERR_NOERROR)
            return ret;
    }
Beispiel #10
0
static unsigned char
asn1_id_decode(struct asn1_ctx *ctx,
	       unsigned int *cls, unsigned int *con, unsigned int *tag)
{
	unsigned char ch;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*cls = (ch & 0xC0) >> 6;
	*con = (ch & 0x20) >> 5;
	*tag = (ch & 0x1F);

	if (*tag == 0x1F) {
		if (!asn1_tag_decode(ctx, tag))
			return 0;
	}
	return 1;
}
Beispiel #11
0
/*
 * NAME:        asn1_id_decode
 * SYNOPSIS:    int asn1_id_decode
 *                  (
 *                      ASN1_SCK *asn1,
 *                      guint    *cls,
 *                      guint    *con,
 *                      guint    *tag
 *                  )
 * DESCRIPTION: Decodes an identifier.
 * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
 */
int
asn1_id_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag)
{
    int    ret;
    guchar ch;

    *tag = 0;
    ret = asn1_octet_decode (asn1, &ch);
    if (ret != ASN1_ERR_NOERROR)
        return ret;
    *cls = (ch & 0xC0) >> 6;
    *con = (ch & 0x20) >> 5;
    *tag = (ch & 0x1F);
    if (*tag == 0x1F) {
        ret = asn1_tag_decode (asn1, tag);
        if (ret != ASN1_ERR_NOERROR)
            return ret;
    }
    return ASN1_ERR_NOERROR;
}
Beispiel #12
0
static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
					unsigned char *eoc,
					unsigned char **octets,
					unsigned int *len)
{
	unsigned char *ptr;

	*len = 0;

	*octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
	if (*octets == NULL)
		return 0;

	ptr = *octets;
	while (ctx->pointer < eoc) {
		if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) {
			kfree(*octets);
			*octets = NULL;
			return 0;
		}
		(*len)++;
	}
	return 1;
}