Fixes to various ASN1_INTEGER routines for negative case.
[openssl.git] / crypto / x509v3 / v3_utl.c
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;
 }