el_type = el.tag;
- if (el.tag == 0x1f)
+ if (el.tag == 0x1f) {
+ *errcode = ERR_DER_INVALID_TAG;
return NULL;
+ }
switch (el.cls) {
case ASN1_CLASS_CONTEXTSPEC:
child->length += (d_ptr - save_d_ptr);
if (child->length > max_size - (d_ptr - buffer)) {
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
SCFree(child);
return NULL;
}
break;
};
- if (child == NULL)
+ if (child == NULL) {
+ *errcode = ERR_DER_INVALID_OBJECT;
return NULL;
+ }
/* child length should never be zero */
if (child->length == 0) {
+ *errcode = ERR_DER_INVALID_OBJECT;
SCFree(child);
return NULL;
}
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_INTEGER;
a->length = (d_ptr - buffer) + numbytes;
a->str = SCMalloc(2*numbytes + 1);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
numbytes = d_ptr[1];
if ((uint32_t)(numbytes + 2) > size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
d_ptr += 2;
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_BOOLEAN;
a->length = (d_ptr - buffer);
numbytes = d_ptr[1];
if ((uint32_t)(numbytes + 2) > size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
d_ptr += 2;
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_NULL;
a->length = (d_ptr - buffer);
} else {
numbytes = c & 0x7f;
if ((uint32_t)(numbytes + 2) > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
d_ptr++;
}
}
- if ((d_ptr-buffer) + length > max_size)
+ if ((d_ptr-buffer) + length > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
+ }
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_BITSTRING;
a->strlen = length;
a->str = SCMalloc(length);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
} else {
numbytes = c & 0x7f;
if ((uint32_t)(numbytes + 2) > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
d_ptr++;
}
}
- if (oid_length == 0 || (d_ptr-buffer) + oid_length > max_size)
+ if (oid_length == 0 || (d_ptr-buffer) + oid_length > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
+ }
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_OID;
a->str = SCMalloc(MAX_OID_LENGTH);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
d_ptr++;
if (oid_length + (d_ptr-buffer) > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
SCFree(a->str);
SCFree(a);
return NULL;
} else {
numbytes = c & 0x7f;
if (max_size < 1 + numbytes) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
max_size -= 1 + numbytes;
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_IA5STRING;
a->strlen = length;
a->str = SCMalloc(length+1);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
} else {
numbytes = c & 0x7f;
if (max_size < 1 + numbytes) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
max_size -= 1 + numbytes;
return NULL;
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_OCTETSTRING;
a->strlen = length;
use the string in printf */
a->str = SCMalloc(length + 1);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
numbytes = c & 0x7f;
d_ptr++;
if (2 + numbytes > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
}
a = Asn1GenericNew();
- if (a == NULL)
+ if (a == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
a->type = ASN1_PRINTSTRING;
a->strlen = length;
a->str = SCMalloc(length+1);
if (a->str == NULL) {
+ *errcode = ERR_DER_GENERIC;
SCFree(a);
return NULL;
}
d_ptr++;
node = Asn1GenericNew();
- if (node == NULL)
+ if (node == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
node->type = ASN1_SEQUENCE;
numbytes = c & 0x7f;
d_ptr++;
if ( 2 + numbytes > max_size ) {
+ *errcode = ERR_DER_INVALID_SIZE;
SCFree(node);
return NULL;
}
d_ptr++;
node = Asn1GenericNew();
- if (node == NULL)
+ if (node == NULL) {
+ *errcode = ERR_DER_GENERIC;
return NULL;
+ }
node->type = ASN1_SET;
node->data = NULL;
} else {
numbytes = c & 0x7f;
if (2 + numbytes > max_size) {
+ *errcode = ERR_DER_INVALID_SIZE;
SCFree(node);
return NULL;
}
uint8_t c;
DEBUG_VALIDATE_BUG_ON(errcode == NULL);
+ *errcode = 0;
- if (size < 2)
+ if (size < 2) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
+ }
/* check that buffer is an ASN.1 structure (basic checks) */
- if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) /* Sequence */
+ if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) { /* Sequence */
+ *errcode = ERR_DER_UNKNOWN_ELEMENT;
return NULL;
+ }
c = d_ptr[1];
- if ((c & (1<<7))>>7 != 1)
+ if ((c & (1<<7))>>7 != 1) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
+ }
numbytes = c & 0x7f;
d_ptr += 2;
if (size < numbytes + 2) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
}
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
return NULL;
}
- if (d_length+(d_ptr-buffer) != size)
+ if (d_length+(d_ptr-buffer) != size) {
+ *errcode = ERR_DER_INVALID_SIZE;
return NULL;
+ }
- *errcode = 0;
cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
return cert;
struct Asn1Generic_ *next; /* only if type is sequence */
} Asn1Generic;
-/* Generic error */
+/* Generic error (failed allocation, etc.) */
#define ERR_DER_GENERIC 0x01
/* Unknown ASN.1 element type */
#define ERR_DER_UNKNOWN_ELEMENT 0x02
/* One element requires to read more bytes than available */
#define ERR_DER_ELEMENT_SIZE_TOO_BIG 0x03
-/* One element size is invalid (more than 4 bytes long) */
+/* One element size is invalid (e.g more than 4 bytes long) */
#define ERR_DER_INVALID_SIZE 0x04
/* Unsupported string type */
#define ERR_DER_UNSUPPORTED_STRING 0x05
#define ERR_DER_MISSING_ELEMENT 0x06
/* Generic error */
#define ERR_DER_RECURSION_LIMIT 0x07
+/* Unexpected or unknown tag */
+#define ERR_DER_INVALID_TAG 0x08
+/* Invalid element: empty object, etc. */
+#define ERR_DER_INVALID_OBJECT 0x09
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode) __attribute__((nonnull));
void DerFree(Asn1Generic *a);