summaryrefslogtreecommitdiff
path: root/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pk/asn1/der/object_identifier/der_encode_object_identifier.c')
-rw-r--r--src/pk/asn1/der/object_identifier/der_encode_object_identifier.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
index 16eb112..b343aaa 100644
--- a/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
+++ b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
@@ -6,7 +6,7 @@
* The library is free for all purposes without any express
* guarantee it works.
*
- * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
+ * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
*/
#include "tomcrypt.h"
@@ -27,7 +27,7 @@
int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
unsigned char *out, unsigned long *outlen)
{
- unsigned long i, x, y, z, t, mask;
+ unsigned long i, x, y, z, t, mask, wordbuf;
int err;
LTC_ARGCHK(words != NULL);
@@ -39,50 +39,54 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
return err;
}
if (x > *outlen) {
+ *outlen = x;
return CRYPT_BUFFER_OVERFLOW;
}
/* compute length to store OID data */
- z = 1;
- for (y = 2; y < nwords; y++) {
- t = der_object_identifier_bits(words[y]);
- z += t/7 + ((t%7) ? 1 : 0);
+ z = 0;
+ wordbuf = words[0] * 40 + words[1];
+ for (y = 1; y < nwords; y++) {
+ t = der_object_identifier_bits(wordbuf);
+ z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
+ if (y < nwords - 1) {
+ wordbuf = words[y + 1];
+ }
}
/* store header + length */
x = 0;
out[x++] = 0x06;
if (z < 128) {
- out[x++] = z;
+ out[x++] = (unsigned char)z;
} else if (z < 256) {
out[x++] = 0x81;
- out[x++] = z;
+ out[x++] = (unsigned char)z;
} else if (z < 65536UL) {
out[x++] = 0x82;
- out[x++] = (z>>8)&255;
- out[x++] = z&255;
+ out[x++] = (unsigned char)((z>>8)&255);
+ out[x++] = (unsigned char)(z&255);
} else {
return CRYPT_INVALID_ARG;
}
/* store first byte */
- out[x++] = words[0] * 40 + words[1];
-
- for (i = 2; i < nwords; i++) {
+ wordbuf = words[0] * 40 + words[1];
+ for (i = 1; i < nwords; i++) {
/* store 7 bit words in little endian */
- t = words[i] & 0xFFFFFFFF;
+ t = wordbuf & 0xFFFFFFFF;
if (t) {
y = x;
mask = 0;
while (t) {
- out[x++] = (t & 0x7F) | mask;
+ out[x++] = (unsigned char)((t & 0x7F) | mask);
t >>= 7;
mask |= 0x80; /* upper bit is set on all but the last byte */
}
/* now swap bytes y...x-1 */
z = x - 1;
while (y < z) {
- t = out[y]; out[y] = out[z]; out[z] = t;
+ t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t;
++y;
--z;
}
@@ -90,6 +94,10 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
/* zero word */
out[x++] = 0x00;
}
+
+ if (i < nwords - 1) {
+ wordbuf = words[i + 1];
+ }
}
*outlen = x;
@@ -99,5 +107,5 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
#endif
/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */
-/* $Revision: 1.1 $ */
-/* $Date: 2005/05/16 15:08:11 $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/04 21:34:03 $ */