asn1_unwrap() function to parse ASN.1 objects with length/type
This commit is contained in:
@@ -311,6 +311,53 @@ size_t asn1_length(chunk_t *blob)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
int asn1_unwrap(chunk_t *blob, chunk_t *inner)
|
||||||
|
{
|
||||||
|
chunk_t res;
|
||||||
|
u_char len;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
if (blob->len < 2)
|
||||||
|
{
|
||||||
|
return ASN1_INVALID;
|
||||||
|
}
|
||||||
|
type = blob->ptr[0];
|
||||||
|
len = blob->ptr[1];
|
||||||
|
*blob = chunk_skip(*blob, 2);
|
||||||
|
|
||||||
|
if ((len & 0x80) == 0)
|
||||||
|
{ /* single length octet */
|
||||||
|
res.len = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* composite length, determine number of length octets */
|
||||||
|
len &= 0x7f;
|
||||||
|
if (len == 0 || len > sizeof(res.len))
|
||||||
|
{
|
||||||
|
return ASN1_INVALID;
|
||||||
|
}
|
||||||
|
res.len = 0;
|
||||||
|
while (len-- > 0)
|
||||||
|
{
|
||||||
|
res.len = 256 * res.len + blob->ptr[0];
|
||||||
|
*blob = chunk_skip(*blob, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res.len > blob->len)
|
||||||
|
{
|
||||||
|
return ASN1_INVALID;
|
||||||
|
}
|
||||||
|
res.ptr = blob->ptr;
|
||||||
|
*blob = chunk_skip(*blob, res.len);
|
||||||
|
/* updating inner not before we are finished allows a caller to pass
|
||||||
|
* blob = inner */
|
||||||
|
*inner = res;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
#define TIME_MAX 0x7fffffff
|
#define TIME_MAX 0x7fffffff
|
||||||
|
|
||||||
static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ typedef enum {
|
|||||||
ASN1_CONTEXT_C_2 = 0xA2,
|
ASN1_CONTEXT_C_2 = 0xA2,
|
||||||
ASN1_CONTEXT_C_3 = 0xA3,
|
ASN1_CONTEXT_C_3 = 0xA3,
|
||||||
ASN1_CONTEXT_C_4 = 0xA4,
|
ASN1_CONTEXT_C_4 = 0xA4,
|
||||||
ASN1_CONTEXT_C_5 = 0xA5
|
ASN1_CONTEXT_C_5 = 0xA5,
|
||||||
|
|
||||||
|
ASN1_INVALID = 0x100,
|
||||||
} asn1_t;
|
} asn1_t;
|
||||||
|
|
||||||
#define ASN1_INVALID_LENGTH 0xffffffff
|
#define ASN1_INVALID_LENGTH 0xffffffff
|
||||||
@@ -122,6 +124,15 @@ chunk_t asn1_build_known_oid(int n);
|
|||||||
*/
|
*/
|
||||||
size_t asn1_length(chunk_t *blob);
|
size_t asn1_length(chunk_t *blob);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unwrap the inner content of an ASN.1 type/length wrapped object.
|
||||||
|
*
|
||||||
|
* @param blob blob to parse header from, moved behind parsed content
|
||||||
|
* @param content inner content
|
||||||
|
* @return parsed type, ASN1_INVALID if length parsing failed
|
||||||
|
*/
|
||||||
|
int asn1_unwrap(chunk_t *blob, chunk_t *content);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an ASN.1 algorithmIdentifier object
|
* Parses an ASN.1 algorithmIdentifier object
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user