Use des_set_key_unchecked, not des_set_key.
[oweals/openssl.git] / crypto / x509v3 / v3_utl.c
index a9068a2f0d5b622d5c38c6265d904ff2590743af..40f71c71b4fd070445db2db45102aa25ce3f9d7b 100644 (file)
  */
 /* X509 v3 extension utilities */
 
-#include <stdlib.h>
+
+#include <stdio.h>
 #include <ctype.h>
-#include <pem.h>
-#include <conf.h>
-#include <err.h>
-#include "x509v3.h"
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
 
-static char * str_dup(char *str);
 static char *strip_spaces(char *name);
 
-static char *str_dup(str)
-char *str;
-{
-       char *tmp;
-       if(!(tmp = Malloc(strlen(str) + 1))) return NULL;
-       strcpy(tmp, str);
-       return tmp;
-}
-
 /* Add a CONF_VALUE name value pair to stack */
 
-int X509V3_add_value(name, value, extlist)
-char *name;
-char *value;
-STACK **extlist;
+int X509V3_add_value(const char *name, const char *value,
+                                               STACK_OF(CONF_VALUE) **extlist)
 {
        CONF_VALUE *vtmp = NULL;
        char *tname = NULL, *tvalue = NULL;
-       if(name && !(tname = str_dup(name))) goto err;
-       if(value && !(tvalue = str_dup(value))) goto err;;
+       if(name && !(tname = BUF_strdup(name))) goto err;
+       if(value && !(tvalue = BUF_strdup(value))) goto err;;
        if(!(vtmp = (CONF_VALUE *)Malloc(sizeof(CONF_VALUE)))) goto err;
-       if(!*extlist && !(*extlist = sk_new(NULL))) goto err;
+       if(!*extlist && !(*extlist = sk_CONF_VALUE_new(NULL))) goto err;
        vtmp->section = NULL;
        vtmp->name = tname;
        vtmp->value = tvalue;
-       if(!sk_push(*extlist, (char *)vtmp)) goto err;
+       if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
        return 1;
        err:
        X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
@@ -102,10 +90,15 @@ STACK **extlist;
        return 0;
 }
 
-/* Free function for STACK of CONF_VALUE */
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                          STACK_OF(CONF_VALUE) **extlist)
+    {
+    return X509V3_add_value(name,(const char *)value,extlist);
+    }
 
-void X509V3_conf_free(conf)
-CONF_VALUE *conf;
+/* Free function for STACK_OF(CONF_VALUE) */
+
+void X509V3_conf_free(CONF_VALUE *conf)
 {
        if(!conf) return;
        if(conf->name) Free(conf->name);
@@ -114,44 +107,80 @@ CONF_VALUE *conf;
        Free((char *)conf);
 }
 
-int X509V3_add_value_bool(name, asn1_bool, extlist)
-char *name;
-int asn1_bool;
-STACK **extlist;
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+                                               STACK_OF(CONF_VALUE) **extlist)
 {
        if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
        return X509V3_add_value(name, "FALSE", extlist);
 }
 
-int X509V3_add_value_bool_nf(name, asn1_bool, extlist)
-char *name;
-int asn1_bool;
-STACK **extlist;
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+                                               STACK_OF(CONF_VALUE) **extlist)
 {
        if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
        return 1;
 }
 
-int X509V3_add_value_int(name, aint, extlist)
-char *name;
-ASN1_INTEGER *aint;
-STACK **extlist;
+
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
+{
+       BIGNUM *bntmp = NULL;
+       char *strtmp = NULL;
+       if(!a) return NULL;
+       if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
+           !(strtmp = BN_bn2dec(bntmp)) )
+               X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
+       BN_free(bntmp);
+       return strtmp;
+}
+
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
+{
+       BIGNUM *bntmp = NULL;
+       char *strtmp = NULL;
+       if(!a) return NULL;
+       if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
+           !(strtmp = BN_bn2dec(bntmp)) )
+               X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
+       BN_free(bntmp);
+       return strtmp;
+}
+
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
+{
+       BIGNUM *bn = NULL;
+       ASN1_INTEGER *aint;
+       bn = BN_new();
+       if(!value) {
+               X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
+               return 0;
+       }
+       if(!BN_dec2bn(&bn, value)) {
+               X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
+               return 0;
+       }
+
+       if(!(aint = BN_to_ASN1_INTEGER(bn, NULL))) {
+               X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+               return 0;
+       }
+       BN_free(bn);
+       return aint;
+}
+
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+            STACK_OF(CONF_VALUE) **extlist)
 {
-       BIGNUM *bntmp;
        char *strtmp;
        int ret;
        if(!aint) return 1;
-       bntmp = ASN1_INTEGER_to_BN(aint, NULL);
-       strtmp = BN_bn2dec(bntmp);
+       if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
        ret = X509V3_add_value(name, strtmp, extlist);
-       BN_free(bntmp);
        Free(strtmp);
        return ret;
 }
 
-int X509V3_get_value_bool(value, asn1_bool)
-CONF_VALUE *value;
-int *asn1_bool;
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
 {
        char *btmp;
        if(!(btmp = value->value)) goto err;
@@ -167,34 +196,19 @@ int *asn1_bool;
                return 1;
        }
        err:
-       X509V3err(X509V3_F_X509V3_VALUE_GET_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
+       X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
        X509V3_conf_err(value);
        return 0;
 }
 
-int X509V3_get_value_int(value, aint)
-CONF_VALUE *value;
-ASN1_INTEGER **aint;
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
 {
-       BIGNUM *bn = NULL;
-       bn = BN_new();
-       if(!value->value) {
-               X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_INVALID_NULL_VALUE);
+       ASN1_INTEGER *itmp;
+       if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
                X509V3_conf_err(value);
                return 0;
        }
-       if(!BN_dec2bn(&bn, value->value)) {
-               X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_DEC2BN_ERROR);
-               X509V3_conf_err(value);
-               return 0;
-       }
-
-       if(!(*aint = BN_to_ASN1_INTEGER(bn, NULL))) {
-               X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
-               X509V3_conf_err(value);
-               return 0;
-       }
-       BN_free(bn);
+       *aint = itmp;
        return 1;
 }
 
@@ -203,16 +217,15 @@ ASN1_INTEGER **aint;
 
 /*#define DEBUG*/
 
-STACK *X509V3_parse_list(line)
-char *line;
+STACK_OF(CONF_VALUE) *X509V3_parse_list(char *line)
 {
        char *p, *q, c;
        char *ntmp, *vtmp;
-       STACK *values = NULL;
+       STACK_OF(CONF_VALUE) *values = NULL;
        char *linebuf;
        int state;
        /* We are going to modify the line so copy it first */
-       linebuf = str_dup(line);
+       linebuf = BUF_strdup(line);
        state = HDR_NAME;
        ntmp = NULL;
        /* Go through all characters */
@@ -290,23 +303,116 @@ return values;
 
 err:
 Free(linebuf);
-sk_pop_free(values, X509V3_conf_free);
+sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
 return NULL;
 
 }
 
 /* Delete leading and trailing spaces from a string */
-static char *strip_spaces(name)
-char *name;
+static char *strip_spaces(char *name)
 {
        char *p, *q;
        /* Skip over leading spaces */
        p = name;
-       while(*p && isspace(*p)) p++;
+       while(*p && isspace((unsigned char)*p)) p++;
        if(!*p) return NULL;
        q = p + strlen(p) - 1;
-       while((q != p) && isspace(*q)) q--;
+       while((q != p) && isspace((unsigned char)*q)) q--;
        if(p != q) q[1] = 0;
        if(!*p) return NULL;
        return p;
 }
+
+/* hex string utilities */
+
+/* Given a buffer of length 'len' return a Malloc'ed string with its
+ * hex representation
+ */
+
+char *hex_to_string(unsigned char *buffer, long len)
+{
+       char *tmp, *q;
+       unsigned char *p;
+       int i;
+       static char hexdig[] = "0123456789ABCDEF";
+       if(!buffer || !len) return NULL;
+       if(!(tmp = Malloc(len * 3 + 1))) {
+               X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
+               return NULL;
+       }
+       q = tmp;
+       for(i = 0, p = buffer; i < len; i++,p++) {
+               *q++ = hexdig[(*p >> 4) & 0xf];
+               *q++ = hexdig[*p & 0xf];
+               *q++ = ':';
+       }
+       q[-1] = 0;
+       return tmp;
+}
+
+/* Give a string of hex digits convert to
+ * a buffer
+ */
+
+unsigned char *string_to_hex(char *str, long *len)
+{
+       unsigned char *hexbuf, *q;
+       unsigned char ch, cl, *p;
+       if(!str) {
+               X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
+               return NULL;
+       }
+       if(!(hexbuf = Malloc(strlen(str) >> 1))) goto err;
+       for(p = (unsigned char *)str, q = hexbuf; *p;) {
+               ch = *p++;
+               if(ch == ':') continue;
+               cl = *p++;
+               if(!cl) {
+                       X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
+                       Free(hexbuf);
+                       return NULL;
+               }
+               if(isupper(ch)) ch = tolower(ch);
+               if(isupper(cl)) cl = tolower(cl);
+
+               if((ch >= '0') && (ch <= '9')) ch -= '0';
+               else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
+               else goto badhex;
+
+               if((cl >= '0') && (cl <= '9')) cl -= '0';
+               else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
+               else goto badhex;
+
+               *q++ = (ch << 4) | cl;
+       }
+
+       if(len) *len = q - hexbuf;
+
+       return hexbuf;
+
+       err:
+       if(hexbuf) Free(hexbuf);
+       X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
+       return NULL;
+
+       badhex:
+       Free(hexbuf);
+       X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
+       return NULL;
+
+}
+
+/* V2I name comparison function: returns zero if 'name' matches
+ * cmp or cmp.*
+ */
+
+int name_cmp(const char *name, const char *cmp)
+{
+       int len, ret;
+       char c;
+       len = strlen(cmp);
+       if((ret = strncmp(name, cmp, len))) return ret;
+       c = name[len];
+       if(!c || (c=='.')) return 0;
+       return 1;
+}