diff options
author | Andrew Bartlett <abartlet@samba.org> | 2004-07-06 01:28:12 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:56:52 -0500 |
commit | b359f5d89301882bbec657084b99c8d3e93dc3f2 (patch) | |
tree | 2a4e2edd394fe2462e682bc6a86348924528bc30 /source4/libcli | |
parent | 3b7872f69ffa0b1cde8d14ab9122a91ee8aab7a6 (diff) | |
download | samba-b359f5d89301882bbec657084b99c8d3e93dc3f2.tar.gz samba-b359f5d89301882bbec657084b99c8d3e93dc3f2.tar.bz2 samba-b359f5d89301882bbec657084b99c8d3e93dc3f2.zip |
r1352: Add a 'peek' function to our ASN1 code, so we can safely perform the
various switches without looking one byte past te end of the buffer.
(This used to be commit 5bce188d429b4166f3d0314922ae40204de182a7)
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/auth/spnego_parse.c | 59 | ||||
-rw-r--r-- | source4/libcli/util/asn1.c | 22 |
2 files changed, 63 insertions, 18 deletions
diff --git a/source4/libcli/auth/spnego_parse.c b/source4/libcli/auth/spnego_parse.c index b38226c014..dfaf9cf320 100644 --- a/source4/libcli/auth/spnego_parse.c +++ b/source4/libcli/auth/spnego_parse.c @@ -35,8 +35,13 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { int i; + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + break; + } - switch (asn1->data[asn1->ofs]) { + switch (context) { /* Read mechTypes */ case ASN1_CONTEXT(0): asn1_start_tag(asn1, ASN1_CONTEXT(0)); @@ -70,8 +75,14 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token break; /* Read mecListMIC */ case ASN1_CONTEXT(3): + { + uint8_t type_peek; asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { + if (!asn1_peek_uint8(asn1, &type_peek)) { + asn1->has_error = True; + break; + } + if (type_peek == ASN1_OCTET_STRING) { asn1_read_OctetString(asn1, &token->mechListMIC); } else { @@ -90,6 +101,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, struct spnego_negTokenInit *token } asn1_end_tag(asn1); break; + } default: asn1->has_error = True; break; @@ -173,7 +185,13 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, struct spnego_negTokenTarg *token asn1_start_tag(asn1, ASN1_SEQUENCE(0)); while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - switch (asn1->data[asn1->ofs]) { + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + break; + } + + switch (context) { case ASN1_CONTEXT(0): asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_ENUMERATED); @@ -257,22 +275,27 @@ ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token) asn1_load(&asn1, data); - switch (asn1.data[asn1.ofs]) { - case ASN1_APPLICATION(0): - asn1_start_tag(&asn1, ASN1_APPLICATION(0)); - asn1_check_OID(&asn1, OID_SPNEGO); - if (read_negTokenInit(&asn1, &token->negTokenInit)) { - token->type = SPNEGO_NEG_TOKEN_INIT; - } - asn1_end_tag(&asn1); - break; - case ASN1_CONTEXT(1): - if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { - token->type = SPNEGO_NEG_TOKEN_TARG; + uint8_t context; + if (!asn1_peek_uint8(asn1, &context)) { + asn1->has_error = True; + } else { + switch (context) { + case ASN1_APPLICATION(0): + asn1_start_tag(&asn1, ASN1_APPLICATION(0)); + asn1_check_OID(&asn1, OID_SPNEGO); + if (read_negTokenInit(&asn1, &token->negTokenInit)) { + token->type = SPNEGO_NEG_TOKEN_INIT; + } + asn1_end_tag(&asn1); + break; + case ASN1_CONTEXT(1): + if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { + token->type = SPNEGO_NEG_TOKEN_TARG; + } + break; + default: + break; } - break; - default: - break; } if (!asn1.has_error) ret = asn1.ofs; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 943ce4d1c1..da51340774 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -239,6 +239,28 @@ BOOL asn1_read_uint8(ASN1_DATA *data, uint8_t *v) return asn1_read(data, v, 1); } +/* read from a ASN1 buffer, advancing the buffer pointer */ +BOOL asn1_peek(ASN1_DATA *data, void *p, int len) +{ + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + data->has_error = True; + return False; + } + + if (data->ofs + len > data->length) { + data->has_error = True; + return False; + } + memcpy(p, data->data + data->ofs, len); + return True; +} + +/* read a uint8_t from a ASN1 buffer */ +BOOL asn1_peek_uint8(ASN1_DATA *data, uint8_t *v) +{ + return asn1_peek(data, v, 1); +} + /* start reading a nested asn1 structure */ BOOL asn1_start_tag(ASN1_DATA *data, uint8_t tag) { |