diff options
author | Stefan Metzmacher <metze@samba.org> | 2004-09-01 07:29:02 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:58:28 -0500 |
commit | deb288d82e92644dcc2431806e214dfeac7b0e84 (patch) | |
tree | 619b4fa792e60f94488df93f60cccae87fd95048 /source4 | |
parent | 960c1d13c1595194a594e867693b5439a1a57afc (diff) | |
download | samba-deb288d82e92644dcc2431806e214dfeac7b0e84.tar.gz samba-deb288d82e92644dcc2431806e214dfeac7b0e84.tar.bz2 samba-deb288d82e92644dcc2431806e214dfeac7b0e84.zip |
r2166: sync the asn1 stuff with trunk
metze
(This used to be commit 46762c9ee011e5c37f3d94a1b80ed7d679c55434)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/util/asn1.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index 7025808a1e..7e313bcd4a 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -107,23 +107,59 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } -static void push_int_bigendian(ASN1_DATA *data, int i) +/* "i" is the one's complement representation, as is the normal result of an + * implicit signed->unsigned conversion */ + +static void push_int_bigendian(ASN1_DATA *data, unsigned int i, BOOL negative) { uint8_t lowest = i & 0xFF; i = i >> 8; if (i != 0) - push_int_bigendian(data, i); + push_int_bigendian(data, i, negative); + + if (data->nesting->start+1 == data->ofs) { + + /* We did not write anything yet, looking at the highest + * valued byte */ + + if (negative) { + /* Don't write leading 0xff's */ + if (lowest == 0xFF) + return; + + if ((lowest & 0x80) == 0) { + /* The only exception for a leading 0xff is if + * the highest bit is 0, which would indicate + * a positive value */ + asn1_write_uint8(data, 0xff); + } + } else { + if (lowest & 0x80) { + /* The highest bit of a positive integer is 1, + * this would indicate a negative number. Push + * a 0 to indicate a positive one */ + asn1_write_uint8(data, 0); + } + } + } asn1_write_uint8(data, lowest); } - /* write an integer */ BOOL asn1_write_Integer(ASN1_DATA *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; - push_int_bigendian(data, i); + if (i == -1) { + /* -1 is special as it consists of all-0xff bytes. In + push_int_bigendian this is the only case that is not + properly handled, as all 0xff bytes would be handled as + leading ones to be ignored. */ + asn1_write_uint8(data, 0xff); + } else { + push_int_bigendian(data, i, i<0); + } return asn1_pop_tag(data); } |