/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
memcpy(p, b, blen);
else {
/* Begin at the end of the encoding */
- n = b + blen - 1;
- p += blen - 1;
+ n = b + blen;
+ p += blen;
i = blen;
/* Copy zeros to destination as long as source is zero */
- while (!*n && i > 1) {
- *(p--) = 0;
+ while (!n[-1] && i > 1) {
+ *(--p) = 0;
n--;
i--;
}
/* Complement and increment next octet */
- *(p--) = ((*(n--)) ^ 0xff) + 1;
+ *(--p) = ((*(--n)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for (; i > 0; i--)
- *(p--) = *(n--) ^ 0xff;
+ *(--p) = *(--n) ^ 0xff;
}
*pp += ret;
/* Must be negative: calculate twos complement */
if (b) {
const unsigned char *from = p + plen - 1 + pad;
- unsigned char *to = b + plen - 1;
+ unsigned char *to = b + plen;
i = plen;
while (*from == 0 && i) {
- *to-- = 0;
+ *--to = 0;
i--;
from--;
}
- *to-- = (*from-- ^ 0xff) + 1;
+ *--to = (*from-- ^ 0xff) + 1;
OPENSSL_assert(i != 0);
i--;
for (; i > 0; i--)
- *to-- = *from-- ^ 0xff;
+ *--to = *from-- ^ 0xff;
}
return plen;
}
ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL);
return 0;
}
- *pr = -(int64_t)r;
+ *pr = 0 - (uint64_t)r;
} else {
if (r > INT64_MAX) {
ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE);
}
ret = BN_bin2bn(ai->data, ai->length, bn);
- if (ret == 0) {
+ if (ret == NULL) {
ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB);
return NULL;
}
return ASN1_ENUMERATED_set_int64(a, v);
}
-long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
{
int i;
int64_t r;
{
return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
}
+
+/* Internal functions used by x_int64.c */
+int c2i_uint64_int(uint64_t *ret, int *neg, const unsigned char **pp, long len)
+{
+ unsigned char buf[sizeof(uint64_t)];
+ size_t buflen;
+
+ buflen = c2i_ibuf(NULL, NULL, *pp, len);
+ if (buflen == 0)
+ return 0;
+ if (buflen > sizeof(uint64_t)) {
+ ASN1err(ASN1_F_C2I_UINT64_INT, ASN1_R_TOO_LARGE);
+ return 0;
+ }
+ (void)c2i_ibuf(buf, neg, *pp, len);
+ return asn1_get_uint64(ret, buf, buflen);
+}
+
+int i2c_uint64_int(unsigned char *p, uint64_t r, int neg)
+{
+ unsigned char buf[sizeof(uint64_t)];
+ size_t buflen;
+
+ buflen = asn1_put_uint64(buf, r);
+ if (p == NULL)
+ return i2c_ibuf(buf, buflen, neg, NULL);
+ return i2c_ibuf(buf, buflen, neg, &p);
+}
+