*/
#include "suricata-common.h"
-
#include "util-decode-der.h"
+#include "util-validate.h"
#define MAX_OID_LENGTH 256
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
uint32_t max_size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
uint32_t size, uint8_t depth,
- uint32_t *errcode);
+ uint32_t *errcode) __attribute__((nonnull));
+static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
+ uint32_t max_size, uint8_t depth,
+ int seq_index, uint32_t *errcode) __attribute__((nonnull));
static Asn1Generic * Asn1GenericNew(void)
{
numbytes = c & 0x7f;
if (numbytes > el_max_size) {
SCFree(child);
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
child->length = 0;
numbytes = d_ptr[1];
if (numbytes > size) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
uint32_t value = 0;
if (numbytes > 4) {
- if (errcode)
- *errcode = ERR_DER_INVALID_SIZE;
+ *errcode = ERR_DER_INVALID_SIZE;
/* too big won't fit: set it to 0xffffffff by convention */
value = 0xffffffff;
}
if (length == UINT32_MAX || length > max_size) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
}
if (length == UINT32_MAX || length > max_size) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
}
if (length == UINT32_MAX || length > max_size) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
}
node->length = d_length + (d_ptr - buffer);
if (node->length > max_size || node->length < d_length /* wrap */) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
SCFree(node);
return NULL;
}
Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth,
seq_index, errcode);
if (child == NULL) {
- if (errcode && *errcode != 0) {
+ if (*errcode != 0) {
DerFree(node);
return NULL;
}
node->length = d_length + (d_ptr - buffer);
if (node->length > max_size || node->length < d_length /* wrap */) {
- if (errcode)
- *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
+ *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
SCFree(node);
return NULL;
}
return a;
}
+/**
+ * \param errcode pointer to error code variable. May not be NULL.
+ */
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size,
uint32_t *errcode)
{
Asn1Generic *cert;
uint8_t c;
+ DEBUG_VALIDATE_BUG_ON(errcode == NULL);
+
if (size < 2)
return NULL;
if (d_length+(d_ptr-buffer) != size)
return NULL;
- if (errcode)
- *errcode = 0;
-
+ *errcode = 0;
cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
return cert;