asn1_unwrap() function to parse ASN.1 objects with length/type

This commit is contained in:
Martin Willi
2009-07-06 13:15:28 +02:00
parent eebecebead
commit 596e0540a5
2 changed files with 59 additions and 1 deletions
+47
View File
@@ -311,6 +311,53 @@ size_t asn1_length(chunk_t *blob)
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
static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+12 -1
View File
@@ -74,7 +74,9 @@ typedef enum {
ASN1_CONTEXT_C_2 = 0xA2,
ASN1_CONTEXT_C_3 = 0xA3,
ASN1_CONTEXT_C_4 = 0xA4,
ASN1_CONTEXT_C_5 = 0xA5
ASN1_CONTEXT_C_5 = 0xA5,
ASN1_INVALID = 0x100,
} asn1_t;
#define ASN1_INVALID_LENGTH 0xffffffff
@@ -122,6 +124,15 @@ chunk_t asn1_build_known_oid(int n);
*/
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
*