summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-07-06 01:28:12 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:56:52 -0500
commitb359f5d89301882bbec657084b99c8d3e93dc3f2 (patch)
tree2a4e2edd394fe2462e682bc6a86348924528bc30 /source4/libcli
parent3b7872f69ffa0b1cde8d14ab9122a91ee8aab7a6 (diff)
downloadsamba-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.c59
-rw-r--r--source4/libcli/util/asn1.c22
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)
{