From ac20c46a8f51bb784c55d26650393b4b4a99f739 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Fri, 10 May 2013 20:25:05 +0200 Subject: [PATCH] Check buffer size in atodn --- src/pluto/connections.c | 1 + src/pluto/id.c | 2 +- src/pluto/x509.c | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pluto/connections.c b/src/pluto/connections.c index b800b16..2a2b3cd 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -829,6 +829,7 @@ extract_end(struct end *dst, const whack_end_t *src, const char *which) err_t ugh; dst->ca.ptr = temporary_cyclic_buffer(); + dst->ca.len = BUF_LEN; ugh = atodn(src->ca, &dst->ca); if (ugh != NULL) { diff --git a/src/pluto/id.c b/src/pluto/id.c index f34775e..3da2e14 100644 --- a/src/pluto/id.c +++ b/src/pluto/id.c @@ -179,7 +179,7 @@ atoid(char *src, struct id *id, bool myid_ok) /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */ id->kind = ID_DER_ASN1_DN; id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */ - id->name.len = 0; + id->name.len = BUF_LEN; /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN * discard optional @ character in front of DN */ diff --git a/src/pluto/x509.c b/src/pluto/x509.c index 0953f18..a23738e 100644 --- a/src/pluto/x509.c +++ b/src/pluto/x509.c @@ -670,13 +670,14 @@ err_t atodn(char *src, chunk_t *dn) int whitespace = 0; int rdn_seq_len = 0; int rdn_set_len = 0; + int rdn_len = 0; int dn_seq_len = 0; int pos = 0; err_t ugh = NULL; u_char *dn_ptr = dn->ptr + 4; - + size_t max_len = dn->len - 4; state_t state = SEARCH_OID; do @@ -755,6 +756,16 @@ err_t atodn(char *src, chunk_t *dn) rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len; code_asn1_length(rdn_set_len, &asn1_rdn_set_len); + /* compute the length of the relative distinguished name */ + rdn_len = 1 + asn1_rdn_set_len.len + rdn_set_len; + + /* do we have sufficient buffer_space */ + if (dn_seq_len + rdn_len > max_len) + { + ugh = "insufficient buffer space for atodn()"; + break; + } + /* encode the relative distinguished name */ *dn_ptr++ = ASN1_SET; chunkcpy(dn_ptr, asn1_rdn_set_len); @@ -770,7 +781,7 @@ err_t atodn(char *src, chunk_t *dn) chunkcpy(dn_ptr, name); /* accumulate the length of the distinguished name sequence */ - dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len; + dn_seq_len += rdn_len; /* reset name and change state */ name = chunk_empty; @@ -780,7 +791,7 @@ err_t atodn(char *src, chunk_t *dn) case UNKNOWN_OID: break; } - } while (*src++ != '\0'); + } while (*src++ != '\0' && ugh == NULL); /* complete the distinguished name sequence*/ code_asn1_length(dn_seq_len, &asn1_dn_seq_len); @@ -789,6 +800,7 @@ err_t atodn(char *src, chunk_t *dn) dn_ptr = dn->ptr; *dn_ptr++ = ASN1_SEQUENCE; chunkcpy(dn_ptr, asn1_dn_seq_len); + return ugh; } -- 1.8.1.2