From 608c51a1348675eb952de0d4a157a4e41d634c5c Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Sat, 11 May 2013 10:33:56 +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 0dbabd9..f72f7e9 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -832,6 +832,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 6c27baa..d0472da 100644 --- a/src/pluto/id.c +++ b/src/pluto/id.c @@ -165,7 +165,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 3c6d85f..83f28d4 100644 --- a/src/pluto/x509.c +++ b/src/pluto/x509.c @@ -669,13 +669,14 @@ 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 @@ -746,6 +747,16 @@ 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); @@ -761,7 +772,7 @@ 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 = empty_chunk; @@ -771,7 +782,7 @@ 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); @@ -780,6 +791,7 @@ 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