'openssl x509 -text' sometimes shows serial numbers as negative numbers
even though positive integers are used on the certificate. The correct
numbers are show with 'openssl x509 -serial'.

This is reproducable with serial numbers between 2^31 and 2^32 on
32-bits systems. The offending code is found in crypto/asn1/t_x509.c

The attached patch seems to fix this behaviour. A side-effect is dat
larger (negative) serial numbers are now shown in the same format as
smaller numbers. I did not to extensive testing, somebody with better
knowledge of this code may want to devise a better solution.


Regards,
Johan

Index: t_x509.c
===================================================================
RCS file: /home/johans/cvs/rsync/openssl/crypto/asn1/t_x509.c,v
retrieving revision 1.44
diff -u -r1.44 t_x509.c
--- t_x509.c	10 Aug 2009 14:56:57 -0000	1.44
+++ t_x509.c	18 Sep 2009 12:56:00 -0000
@@ -104,13 +104,15 @@
 int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
 	{
 	long l;
-	int ret=0,i;
+	int ret=0;
 	char *m=NULL,mlch = ' ';
 	int nmindent = 0;
 	X509_CINF *ci;
 	ASN1_INTEGER *bs;
 	EVP_PKEY *pkey=NULL;
-	const char *neg;
+	BIGNUM *bn;
+	char *bnd, *bnh;
+
 
 	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
 			mlch = '\n';
@@ -133,36 +135,20 @@
 		}
 	if(!(cflag & X509_FLAG_NO_SERIAL))
 		{
-
 		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;
 
 		bs=X509_get_serialNumber(x);
-		if (bs->length <= 4)
-			{
-			l=ASN1_INTEGER_get(bs);
-			if (l < 0)
-				{
-				l= -l;
-				neg="-";
-				}
-			else
-				neg="";
-			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
-				goto err;
-			}
-		else
-			{
-			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
-			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
-
-			for (i=0; i<bs->length; i++)
-				{
-				if (BIO_printf(bp,"%02x%c",bs->data[i],
-					((i+1 == bs->length)?'\n':':')) <= 0)
-					goto err;
-				}
-			}
+		bn=ASN1_INTEGER_to_BN(bs,NULL);
+		bnh=BN_bn2hex(bn);
+		bnd=BN_bn2dec(bn);
+		if (BIO_printf(bp, " %s (%s0x%s)\n", bnd,
+				bnh && *bnh == '-' ? "-" : "",
+				bnh && *bnh == '-' ? bnh + 1 : bnh) <= 0)
+			goto err;
 
+		OPENSSL_free(bnh);
+		OPENSSL_free(bnd);
+		BN_free(bn);
 		}
 
 	if(!(cflag & X509_FLAG_NO_SIGNAME))

Attachment: pgpds73aK8V04.pgp
Description: PGP signature

Reply via email to