aboutsummaryrefslogtreecommitdiff
path: root/lib/asn1/der_put.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1/der_put.c')
-rw-r--r--lib/asn1/der_put.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/asn1/der_put.c b/lib/asn1/der_put.c
index 843d09f5cdc1..98c2c8a2cebb 100644
--- a/lib/asn1/der_put.c
+++ b/lib/asn1/der_put.c
@@ -313,7 +313,8 @@ der_put_octet_string (unsigned char *p, size_t len,
if (len < data->length)
return ASN1_OVERFLOW;
p -= data->length;
- memcpy (p+1, data->data, data->length);
+ if (data->length)
+ memcpy(p+1, data->data, data->length);
*size = data->length;
return 0;
}
@@ -341,19 +342,30 @@ der_put_heim_integer (unsigned char *p, size_t len,
if (data->negative) {
ssize_t i;
int carry;
- for (i = data->length - 1, carry = 1; i >= 0; i--) {
- *p = buf[i] ^ 0xff;
- if (carry)
- carry = !++*p;
- p--;
- }
- if (p[1] < 128) {
- if (len < 1)
- return ASN1_OVERFLOW;
- *p-- = 0xff;
- len--;
- hibitset = 1;
- }
+
+ /*
+ * We represent the parsed integer as a positive value with a
+ * negativity flag. But we need to put it on the wire as the shortest
+ * twos-complement byte sequence possible. So we're going to negate
+ * the number as go.
+ */
+ if (data->length == 1 && *(unsigned char *)data->data == 1) {
+ *(p--) = 0xff;
+ } else {
+ for (i = data->length - 1, carry = 1; i >= 0; i--) {
+ *p = buf[i] ^ 0xff;
+ if (carry)
+ carry = !++*p;
+ p--;
+ }
+ if (p[1] < 128) {
+ if (len < 1)
+ return ASN1_OVERFLOW;
+ *p-- = 0xff;
+ len--;
+ hibitset = 1;
+ }
+ }
} else {
p -= data->length;
memcpy(p + 1, buf, data->length);