TLS: add variable to store the error code in the decoder

Use a variable to store the decoding error code if required, and remove
the calls to SCLogInfo and SCLogDebug.
remotes/origin/HEAD
Pierre Chifflier 15 years ago committed by Victor Julien
parent 218b5d3ba0
commit d866f38982

@ -55,14 +55,17 @@
SCEnumCharMap tls_decoder_event_table[ ] = {
/* TLS protocol messages */
{ "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER },
{ "INVALID_TLS_HEADER", TLS_DECODER_EVENT_INVALID_TLS_HEADER },
{ "INVALID_RECORD_TYPE", TLS_DECODER_EVENT_INVALID_RECORD_TYPE },
{ "INVALID_HANDSHAKE_MESSAGE", TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE },
{ "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER },
{ "INVALID_TLS_HEADER", TLS_DECODER_EVENT_INVALID_TLS_HEADER },
{ "INVALID_RECORD_TYPE", TLS_DECODER_EVENT_INVALID_RECORD_TYPE },
{ "INVALID_HANDSHAKE_MESSAGE", TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE },
/* Certificates decoding messages */
{ "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE },
{ "CERTIFICATE_MISSING_FIELD", TLS_DECODER_EVENT_CERTIFICATE_MISSING_FIELD },
{ NULL, -1 },
{ "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE },
{ "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT },
{ "CERTIFICATE_UNKNOWN_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT },
{ "CERTIFICATE_INVALID_LENGTH", TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH },
{ "CERTIFICATE_INVALID_STRING", TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING },
{ NULL, -1 },
};
typedef struct SslConfig_ {

@ -36,7 +36,10 @@ enum {
TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE,
/* Certificates decoding messages */
TLS_DECODER_EVENT_INVALID_CERTIFICATE,
TLS_DECODER_EVENT_CERTIFICATE_MISSING_FIELD,
TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT,
TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT,
TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH,
TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING,
};
/* Flag to indicate that server will now on send encrypted msgs */

@ -52,6 +52,32 @@
#define SSLV3_RECORD_LEN 5
static void TLSCertificateErrCodeToWarning(SSLState *ssl_state, uint32_t errcode)
{
if (errcode == 0)
return;
switch (errcode) {
case ERR_DER_ELEMENT_SIZE_TOO_BIG:
case ERR_DER_INVALID_SIZE:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH);
break;
case ERR_DER_UNSUPPORTED_STRING:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING);
break;
case ERR_DER_UNKNOWN_ELEMENT:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT);
break;
case ERR_DER_MISSING_ELEMENT:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT);
break;
case ERR_DER_GENERIC:
default:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
break;
};
}
int DecodeTLSHandshakeServerHello(SSLState *ssl_state, uint8_t *input, uint32_t input_len)
{
uint32_t version, length, ciphersuite;
@ -99,6 +125,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin
int rc;
int parsed;
uint8_t *start_data;
uint32_t errcode;
if (input_len < 3)
return 1;
@ -119,20 +146,17 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin
parsed += 3;
if (input - start_data + cur_cert_length > input_len) {
SCLogWarning(SC_ERR_ALPARSER, "ASN.1 structure contains invalid length\n");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
return -1;
}
cert = DecodeDer(input, cur_cert_length);
cert = DecodeDer(input, cur_cert_length, &errcode);
if (cert == NULL) {
SCLogWarning(SC_ERR_ALPARSER, "decoding ASN.1 structure for X509 certificate failed\n");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
TLSCertificateErrCodeToWarning(ssl_state, errcode);
}
if (cert != NULL) {
rc = Asn1DerGetSubjectDN(cert, buffer, sizeof(buffer));
rc = Asn1DerGetSubjectDN(cert, buffer, sizeof(buffer), &errcode);
if (rc != 0) {
SCLogWarning(SC_ERR_ALPARSER, "X509: could not get subject\n");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_MISSING_FIELD);
TLSCertificateErrCodeToWarning(ssl_state, errcode);
} else {
//SCLogInfo("TLS Cert %d: %s\n", i, buffer);
if (i==0) {
@ -143,10 +167,9 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin
}
}
}
rc = Asn1DerGetIssuerDN(cert, buffer, sizeof(buffer));
rc = Asn1DerGetIssuerDN(cert, buffer, sizeof(buffer), &errcode);
if (rc != 0) {
SCLogWarning(SC_ERR_ALPARSER, "X509: could not get issuerdn\n");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_CERTIFICATE_MISSING_FIELD);
TLSCertificateErrCodeToWarning(ssl_state, errcode);
} else {
//SCLogInfo("TLS IssuerDN %d: %s\n", i, buffer);
if (i==0) {

@ -86,12 +86,15 @@ static const char *Oid2ShortStr(const char *oid)
*
* \retval The matching node, or NULL
*/
const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz)
const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz, uint32_t *errcode)
{
const Asn1Generic * node;
uint8_t idx, i;
uint8_t offset = 0;
if (errcode)
*errcode = ERR_DER_MISSING_ELEMENT;
node = top;
if (node == NULL || seq_index == NULL)
return NULL;
@ -127,10 +130,13 @@ const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index,
node = node->data;
}
if (errcode)
*errcode = 0;
return node;
}
int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length)
int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode)
{
const Asn1Generic *node_oid;
const Asn1Generic *node, *it;
@ -140,11 +146,14 @@ int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length)
int rc = -1;
const char *separator = ", ";
if (errcode)
*errcode = ERR_DER_MISSING_ELEMENT;
if (length < 10)
goto issuer_dn_error;
buffer[0] = '\0';
node = Asn1DerGet(cert, SEQ_IDX_ISSUER, sizeof(SEQ_IDX_ISSUER));
node = Asn1DerGet(cert, SEQ_IDX_ISSUER, sizeof(SEQ_IDX_ISSUER), errcode);
if ((node == NULL) || node->type != ASN1_SEQUENCE)
goto issuer_dn_error;
@ -180,7 +189,8 @@ int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length)
strlcat(buffer, node_str->str, length);
break;
default:
SCLogInfo("Unsupported 'string' type:'%d'", node_str->type);
if (errcode)
*errcode = ERR_DER_UNSUPPORTED_STRING;
goto issuer_dn_error;
}
@ -191,12 +201,15 @@ int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length)
it = it->next;
}
if (errcode)
*errcode = 0;
rc = 0;
issuer_dn_error:
return rc;
}
int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length)
int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode)
{
const Asn1Generic *node_oid;
const Asn1Generic *node, *it;
@ -206,11 +219,14 @@ int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length)
int rc = -1;
const char *separator = ", ";
if (errcode)
*errcode = ERR_DER_MISSING_ELEMENT;
if (length < 10)
goto subject_dn_error;
buffer[0] = '\0';
node = Asn1DerGet(cert, SEQ_IDX_SUBJECT, sizeof(SEQ_IDX_SUBJECT));
node = Asn1DerGet(cert, SEQ_IDX_SUBJECT, sizeof(SEQ_IDX_SUBJECT), errcode);
if ((node == NULL) || node->type != ASN1_SEQUENCE)
goto subject_dn_error;
@ -247,7 +263,8 @@ int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length)
strlcat(buffer, node_str->str, length);
break;
default:
SCLogInfo("Unsupported 'string' type:'%d'", node_str->type);
if (errcode)
*errcode = ERR_DER_UNSUPPORTED_STRING;
goto subject_dn_error;
}
@ -257,7 +274,9 @@ int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length)
strlcat(buffer, separator, length);
it = it->next;
}
SCLogDebug("read subject:'%s'", buffer);
if (errcode)
*errcode = 0;
rc = 0;
subject_dn_error:

@ -35,9 +35,9 @@
#ifndef __UTIL_DECODE_DER_GET_H__
#define __UTIL_DECODE_DER_GET_H__
const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz);
const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz, uint32_t *errcode);
int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length);
int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length);
int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode);
int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode);
#endif /* __UTIL_DECODE_DER_GET_H__ */

@ -60,19 +60,19 @@
#define MAX_OID_LENGTH 256
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t size, uint8_t depth);
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
static Asn1Generic * Asn1GenericNew(void)
{
@ -105,7 +105,7 @@ static void Asn1SequenceAppend(Asn1Generic *seq, Asn1Generic *node)
it->next = new_container;
}
static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t max_size, uint8_t depth, int seq_index)
static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t max_size, uint8_t depth, int seq_index, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t numbytes, el_max_size;
@ -152,43 +152,43 @@ static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t
el_max_size = max_size - (d_ptr-buffer);
switch (el_type) {
case ASN1_INTEGER:
child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_BOOLEAN:
child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_NULL:
child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_BITSTRING:
child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_OID:
child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_IA5STRING:
child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_OCTETSTRING:
child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_UTF8STRING:
child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_PRINTSTRING:
child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_SEQUENCE:
child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_SET:
child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_T61STRING:
child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1, errcode);
break;
case ASN1_UTCTIME:
child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1);
child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode);
break;
default:
/* unknown ASN.1 type */
@ -208,8 +208,8 @@ static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t
numbytes = c & 0x7f;
if (numbytes > el_max_size) {
SCFree(child);
SCLogWarning(SC_ERR_INVALID_VALUE,
"DER message requires to read over message");
if (errcode)
*errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
child->length = 0;
@ -232,7 +232,7 @@ static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t
return child;
}
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint8_t numbytes;
@ -243,8 +243,8 @@ static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t
numbytes = d_ptr[1];
if (numbytes > size) {
SCLogWarning(SC_ERR_INVALID_VALUE,
"DER message requires to read over available data");
if (errcode)
*errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
return NULL;
}
@ -283,12 +283,13 @@ static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t
return a;
}
static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val, uint8_t numbytes)
static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val, uint8_t numbytes, uint32_t *errcode)
{
int i;
uint32_t value = 0;
if (numbytes > 4) {
SCLogDebug("Invalid ASN.1 num bytes: %d", numbytes);
if (errcode)
*errcode = ERR_DER_INVALID_SIZE;
/* too big won't fit: set it to 0xffffffff by convention */
value = 0xffffffff;
*val = value;
@ -303,7 +304,7 @@ static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val, uint
return 0;
}
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint8_t numbytes;
@ -313,7 +314,7 @@ static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t
numbytes = d_ptr[1];
d_ptr += 2;
if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
return NULL;
}
a = Asn1GenericNew();
@ -326,7 +327,7 @@ static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t
return a;
}
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint8_t numbytes;
@ -335,7 +336,7 @@ static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t siz
numbytes = d_ptr[1];
d_ptr += 2;
if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
return NULL;
}
a = Asn1GenericNew();
@ -348,7 +349,7 @@ static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t siz
return a;
}
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t length;
@ -365,7 +366,7 @@ static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
return NULL;
}
}
@ -390,7 +391,7 @@ static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_
return a;
}
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t oid_length, oid_value;
@ -408,7 +409,7 @@ static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) {
return NULL;
}
}
@ -451,7 +452,7 @@ static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_
return a;
}
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t length, numbytes;
@ -468,7 +469,7 @@ static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
return NULL;
}
}
@ -493,7 +494,7 @@ static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_
return a;
}
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t length, numbytes;
@ -510,7 +511,7 @@ static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint3
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
return NULL;
}
}
@ -538,15 +539,15 @@ static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint3
return a;
}
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth);
Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode);
if (a != NULL)
a->type = ASN1_UTF8STRING;
return a;
}
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t length, numbytes;
@ -563,7 +564,7 @@ static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, u
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
return NULL;
}
}
@ -589,7 +590,7 @@ static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, u
return a;
}
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t d_length, parsed_bytes, numbytes, el_max_size;
@ -613,7 +614,7 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
free(node);
return NULL;
}
@ -630,7 +631,7 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t
/* decode child elements */
while (parsed_bytes < d_length) {
el_max_size = max_size - (d_ptr-buffer);
child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index);
child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
if (child == NULL) {
break;
@ -644,7 +645,7 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t
return (Asn1Generic *)node;
}
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t d_length, numbytes, el_max_size;
@ -669,7 +670,7 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_
} else { /* long form 8.1.3.5 */
numbytes = c & 0x7f;
d_ptr++;
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
free(node);
return NULL;
}
@ -677,9 +678,8 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_
node->length = d_length + (d_ptr - buffer);
if (node->length > max_size) {
SCLogInfo("Announced message length too big: %" PRIu32 " vs %" PRIu32,
node->length,
max_size);
if (errcode)
*errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
free(node);
return NULL;
}
@ -687,36 +687,36 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_
seq_index = 0;
el_max_size = max_size - (d_ptr-buffer);
child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index);
child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
node->data = child;
return (Asn1Generic *)node;
}
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
Asn1Generic *a;
a = DecodeAsn1DerIA5String(buffer, max_size, depth);
a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
if (a != NULL)
a->type = ASN1_T61STRING;
return a;
}
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t max_size, uint8_t depth)
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
{
Asn1Generic *a;
a = DecodeAsn1DerIA5String(buffer, max_size, depth);
a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
if (a != NULL)
a->type = ASN1_UTCTIME;
return a;
}
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size)
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode)
{
const unsigned char *d_ptr = buffer;
uint32_t d_length, numbytes;
@ -733,13 +733,16 @@ Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size)
numbytes = c & 0x7f;
d_ptr += 2;
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes) == -1) {
if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
return NULL;
}
if (d_length+(d_ptr-buffer) != size)
return NULL;
cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0);
if (errcode)
*errcode = 0;
cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
return cert;
}

@ -77,7 +77,20 @@ typedef struct Asn1Generic_ {
struct Asn1Generic_ *next; /* only if type is sequence */
} Asn1Generic;
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size);
/* Generic error */
#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) */
#define ERR_DER_INVALID_SIZE 0x04
/* Unsupported string type */
#define ERR_DER_UNSUPPORTED_STRING 0x05
/* Missing field or element */
#define ERR_DER_MISSING_ELEMENT 0x06
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode);
void DerFree(Asn1Generic *a);
#endif /* __UTIL_DECODE_DER_H__ */

Loading…
Cancel
Save