Fixes to various ASN1_INTEGER routines for negative case.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 19 Jan 2001 14:21:48 +0000 (14:21 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 19 Jan 2001 14:21:48 +0000 (14:21 +0000)
Enhance s2i_ASN1_INTEGER().

CHANGES
apps/ocsp.c
crypto/asn1/a_int.c
crypto/asn1/f_int.c
crypto/x509v3/v3_utl.c

diff --git a/CHANGES b/CHANGES
index eeddf41840b5ba4db58a2645da50284ff6aac50c..f548204e313723837bc170aaf69cc7ed68ab7ef3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,14 @@
 
  Changes between 0.9.6 and 0.9.7  [xx XXX 2000]
 
+  *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
+     result in a zero length in the ASN1_INTEGER structure which was
+     not consistent with the structure when d2i_ASN1_INTEGER() was used
+     and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
+     to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
+     where it did not print out a minus for negative ASN1_INTEGER.
+     [Steve Henson]
+
   *) Fix 'openssl passwd -1'.
      [Bodo Moeller]
 
index f23aa4c52a856b397f794d79964cc83dd61c000c..eaba15f3099172ef5a21a1c5aa450466cc83c956 100644 (file)
@@ -585,7 +585,7 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
                if (status != V_OCSP_CERTSTATUS_REVOKED)
                        continue;
 
-               if (reason > 0)
+               if (reason != -1)
                        BIO_printf(out, "\tReason: %s\n",
                                OCSP_crl_reason_str(reason));
 
index b0fc97ea273a3e0debf1504f71a0524b87c676f1..496704b9a52636235f14ae1ddd15feb7af6b289c 100644 (file)
@@ -399,6 +399,12 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
        len=((j == 0)?0:((j/8)+1));
        ret->data=(unsigned char *)OPENSSL_malloc(len+4);
        ret->length=BN_bn2bin(bn,ret->data);
+       /* Correct zero case */
+       if(!ret->length)
+               {
+               ret->data[0] = 0;
+               ret->length = 1;
+               }
        return(ret);
 err:
        if (ret != ai) M_ASN1_INTEGER_free(ret);
index 6b090f6740c2c1f6a142773ae8787eee576651d9..48cc3bfb90d52bb66ca13f0b84d549f3be3f6130 100644 (file)
@@ -69,10 +69,16 @@ int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
 
        if (a == NULL) return(0);
 
+       if (a->type & V_ASN1_NEG)
+               {
+               if (BIO_write(bp, "-", 1) != 1) goto err;
+               n = 1;
+               }
+
        if (a->length == 0)
                {
                if (BIO_write(bp,"00",2) != 2) goto err;
-               n=2;
+               n += 2;
                }
        else
                {
index 727a93ff517b03c7d921917ec2efeb8328cbb837..434ddbbc3c15b7f95a9cf4d44c98f2f0ab899fdc 100644 (file)
@@ -154,21 +154,40 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
 {
        BIGNUM *bn = NULL;
        ASN1_INTEGER *aint;
+       int isneg, ishex;
+       int ret;
        bn = BN_new();
-       if(!value) {
+       if (!value) {
                X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
                return 0;
        }
-       if(!BN_dec2bn(&bn, value)) {
+       if (value[0] == '-') {
+               value++;
+               isneg = 1;
+       } else isneg = 0;
+
+       if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+               value += 2;
+               ishex = 1;
+       } else ishex = 0;
+
+       if (ishex) ret = BN_hex2bn(&bn, value);
+       else ret = BN_dec2bn(&bn, value);
+
+       if (!ret) {
                X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
                return 0;
        }
 
-       if(!(aint = BN_to_ASN1_INTEGER(bn, NULL))) {
+       if (isneg && BN_is_zero(bn)) isneg = 0;
+
+       aint = BN_to_ASN1_INTEGER(bn, NULL);
+       BN_free(bn);
+       if (!aint) {
                X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
                return 0;
        }
-       BN_free(bn);
+       if (isneg) aint->type |= V_ASN1_NEG;
        return aint;
 }