Two TODO comments taken care of. Nils pointed out that one of them had already
been done, and took care of the other one (which hadn't).

Submitted by: Nils Larsch
Reviewed by: Geoff Thorpe
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
index 12d8a8c..5bd742a 100644
--- a/crypto/bn/bn_ctx.c
+++ b/crypto/bn/bn_ctx.c
@@ -70,10 +70,7 @@
  *
  * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
  * check they can be safely removed.
- *  - BN_bin2bn() looks pretty nasty with the miscellaneous +1 and +2 adjustments.
- *    Needs a full rubber-gloving, me thinks.
  *  - Check +1 and other ugliness in BN_from_montgomery()
- *  - Aspects of BN_bn2dec() also look a bit arbitrary
  *
  * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
  * appropriate 'block' size that will be honoured by bn_expand_internal() to
diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c
index 092322d..5fb8473 100644
--- a/crypto/bn/bn_print.c
+++ b/crypto/bn/bn_print.c
@@ -102,14 +102,19 @@
 /* Must 'OPENSSL_free' the returned data */
 char *BN_bn2dec(const BIGNUM *a)
 	{
-	int i=0,num;
+	int i=0,num, ok = 0;
 	char *buf=NULL;
 	char *p;
 	BIGNUM *t=NULL;
 	BN_ULONG *bn_data=NULL,*lp;
 
+	/* get an upper bound for the length of the decimal integer
+	 * num <= (BN_num_bits(a) + 1) * log(2)
+	 *     <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1     (rounding error)
+	 *     <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 
+	 */
 	i=BN_num_bits(a)*3;
-	num=(i/10+i/1000+3)+1;
+	num=(i/10+i/1000+1)+1;
 	bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
 	buf=(char *)OPENSSL_malloc(num+3);
 	if ((buf == NULL) || (bn_data == NULL))
@@ -122,7 +127,6 @@
 #define BUF_REMAIN (num+3 - (size_t)(p - buf))
 	p=buf;
 	lp=bn_data;
-	if (t->neg) *(p++)='-';
 	if (BN_is_zero(t))
 		{
 		*(p++)='0';
@@ -130,6 +134,9 @@
 		}
 	else
 		{
+		if (BN_get_sign(t))
+			*p++ = '-';
+
 		i=0;
 		while (!BN_is_zero(t))
 			{
@@ -149,9 +156,16 @@
 			while (*p) p++;
 			}
 		}
+	ok = 1;
 err:
 	if (bn_data != NULL) OPENSSL_free(bn_data);
 	if (t != NULL) BN_free(t);
+	if (!ok && buf)
+		{
+		OPENSSL_free(buf);
+		buf = NULL;
+		}
+
 	return(buf);
 	}