New function X509V3_add_i2d() this is used for
authorDr. Stephen Henson <steve@openssl.org>
Sun, 24 Dec 2000 18:02:33 +0000 (18:02 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 24 Dec 2000 18:02:33 +0000 (18:02 +0000)
encoding, replacing and deleting extensions.

Fix X509V3_get_d2i() so it uses takes note of
new critical behaviour.

CHANGES
crypto/x509/x509.h
crypto/x509/x509_ext.c
crypto/x509v3/v3_lib.c
crypto/x509v3/v3err.c
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index e088fad..167048f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,12 @@
 
  Changes between 0.9.6 and 0.9.7  [xx XXX 2000]
 
+  *) New function X509V3_add1_i2d(). This automatically encodes and
+     adds an extension. Its behaviour can be customised with various
+     flags to append, replace or delete. Various wrappers added for
+     certifcates and CRLs.
+     [Steve Henson]
+
   *) Fix to avoid calling the underlying ASN1 print routine when
      an extension cannot be parsed. Correct a typo in the
      OCSP_SERVICELOC extension. Tidy up print OCSP format.
index 6ef1b48..24ba861 100644 (file)
@@ -1047,6 +1047,8 @@ X509_EXTENSION *X509_get_ext(X509 *x, int loc);
 X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
 int            X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
 void   *       X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int            X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                                                       unsigned long flags);
 
 int            X509_CRL_get_ext_count(X509_CRL *x);
 int            X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
@@ -1056,6 +1058,8 @@ X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
 X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
 int            X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
 void   *       X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int            X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                                                       unsigned long flags);
 
 int            X509_REVOKED_get_ext_count(X509_REVOKED *x);
 int            X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
@@ -1065,6 +1069,8 @@ X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
 X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
 int            X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
 void   *       X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int            X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                                                       unsigned long flags);
 
 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
                        int nid, int crit, ASN1_OCTET_STRING *data);
index 2955989..9b60258 100644 (file)
@@ -101,6 +101,12 @@ void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
        return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
 }
 
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                                                       unsigned long flags)
+{
+       return X509V3_add1_i2d(x->crl->extensions, nid, value, crit, flags);
+}
+
 int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
        {
        return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL);
@@ -146,6 +152,13 @@ void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
        return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
 }
 
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                                                       unsigned long flags)
+{
+       return X509V3_add1_i2d(x->cert_info->extensions, nid, value, crit,
+                                                       flags);
+}
+
 int X509_REVOKED_get_ext_count(X509_REVOKED *x)
        {
        return(X509v3_get_ext_count(x->extensions));
@@ -187,5 +200,11 @@ void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
        return X509V3_get_d2i(x->extensions, nid, crit, idx);
 }
 
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                                                       unsigned long flags)
+{
+       return X509V3_add1_i2d(x->extensions, nid, value, crit, flags);
+}
+
 IMPLEMENT_STACK_OF(X509_EXTENSION)
 IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
index 3376511..844cee1 100644 (file)
@@ -213,7 +213,7 @@ void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
        }
        if(found_ex) {
                /* Found it */
-               if(crit) *crit = found_ex->critical;
+               if(crit) *crit = X509_EXTENSION_get_critical(found_ex);
                return X509V3_EXT_d2i(found_ex);
        }
 
@@ -223,4 +223,78 @@ void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
        return NULL;
 }
 
+/* This function is a general extension append, replace and delete utility.
+ * The precise operation is governed by the 'flags' value. The 'crit' and
+ * 'value' arguments (if relevant) are the extensions internal structure.
+ */
+
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) *x, int nid, void *value,
+                                       int crit, unsigned long flags)
+{
+       int extidx = -1;
+       int errcode;
+       X509_EXTENSION *ext, *extmp;
+       unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+
+       /* If appending we don't care if it exists, otherwise
+        * look for existing extension.
+        */
+       if(ext_op != X509V3_ADD_APPEND)
+               extidx = X509v3_get_ext_by_NID(x, nid, -1);
+
+       /* See if extension exists */
+       if(extidx >= 0) {
+               /* If keep existing, nothing to do */
+               if(ext_op == X509V3_ADD_KEEP_EXISTING)
+                       return 1;
+               /* If default then its an error */
+               if(ext_op == X509V3_ADD_DEFAULT) {
+                       errcode = X509V3_R_EXTENSION_EXISTS;
+                       goto err;
+               }
+               /* If delete, just delete it */
+               if(ext_op == X509V3_ADD_DELETE) {
+                       if(!sk_X509_EXTENSION_delete(x, extidx)) return -1;
+                       return 1;
+               }
+       } else {
+               /* If replace existing or delete, error since 
+                * extension must exist
+                */
+               if((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+                  (ext_op == X509V3_ADD_DELETE)) {
+                       errcode = X509V3_R_EXTENSION_NOT_FOUND;
+                       goto err;
+               }
+       }
+
+       /* If we get this far then we have to create an extension:
+        * could have some flags for alternative encoding schemes...
+        */
+
+       ext = X509V3_EXT_i2d(nid, crit, value);
+
+       if(!ext) {
+               X509V3err(X509V3_F_X509V3_ADD_I2D, X509V3_R_ERROR_CREATING_EXTENSION);
+               return -1;
+       }
+
+       /* If extension exists replace it.. */
+       if(extidx >= 0) {
+               extmp = sk_X509_EXTENSION_value(x, extidx);
+               X509_EXTENSION_free(extmp);
+               if(!sk_X509_EXTENSION_set(x, extidx, ext)) return -1;
+               return 1;
+       }
+
+       if(!sk_X509_EXTENSION_push(x, ext)) return -1;
+
+       return 1;
+
+       err:
+       if(!(flags & X509V3_ADD_SILENT))
+               X509V3err(X509V3_F_X509V3_ADD_I2D, errcode);
+       return 0;
+}
+
 IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)
index aa4a605..1a8b7d5 100644 (file)
@@ -98,6 +98,7 @@ static ERR_STRING_DATA X509V3_str_functs[]=
 {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAME,0),      "v2i_GENERAL_NAME"},
 {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAMES,0),     "v2i_GENERAL_NAMES"},
 {ERR_PACK(0,X509V3_F_V3_GENERIC_EXTENSION,0),  "V3_GENERIC_EXTENSION"},
+{ERR_PACK(0,X509V3_F_X509V3_ADD_I2D,0),        "X509V3_ADD_I2D"},
 {ERR_PACK(0,X509V3_F_X509V3_ADD_VALUE,0),      "X509V3_add_value"},
 {ERR_PACK(0,X509V3_F_X509V3_EXT_ADD,0),        "X509V3_EXT_add"},
 {ERR_PACK(0,X509V3_F_X509V3_EXT_ADD_ALIAS,0),  "X509V3_EXT_add_alias"},
@@ -117,8 +118,10 @@ static ERR_STRING_DATA X509V3_str_reasons[]=
 {X509V3_R_BN_TO_ASN1_INTEGER_ERROR       ,"bn to asn1 integer error"},
 {X509V3_R_DUPLICATE_ZONE_ID              ,"duplicate zone id"},
 {X509V3_R_ERROR_CONVERTING_ZONE          ,"error converting zone"},
+{X509V3_R_ERROR_CREATING_EXTENSION       ,"error creating extension"},
 {X509V3_R_ERROR_IN_EXTENSION             ,"error in extension"},
 {X509V3_R_EXPECTED_A_SECTION_NAME        ,"expected a section name"},
+{X509V3_R_EXTENSION_EXISTS               ,"extension exists"},
 {X509V3_R_EXTENSION_NAME_ERROR           ,"extension name error"},
 {X509V3_R_EXTENSION_NOT_FOUND            ,"extension not found"},
 {X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"},
index 487d156..6678db3 100644 (file)
@@ -386,6 +386,17 @@ typedef struct x509_purpose_st {
 /* BIO_dump unknown extensions */
 #define X509V3_EXT_DUMP_UNKNOWN                (3L << 16)
 
+/* Flags for X509V3_add1_i2d */
+
+#define X509V3_ADD_OP_MASK             0xfL
+#define X509V3_ADD_DEFAULT             0L
+#define X509V3_ADD_APPEND              1L
+#define X509V3_ADD_REPLACE             2L
+#define X509V3_ADD_REPLACE_EXISTING    3L
+#define X509V3_ADD_KEEP_EXISTING       4L
+#define X509V3_ADD_DELETE              5L
+#define X509V3_ADD_SILENT              0x10
+
 DECLARE_STACK_OF(X509_PURPOSE)
 
 void ERR_load_X509V3_strings(void);
@@ -487,7 +498,9 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(char *line);
 void *X509V3_EXT_d2i(X509_EXTENSION *ext);
 void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
 
+
 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) *x, int nid, void *value, int crit, unsigned long flags);
 
 char *hex_to_string(unsigned char *buffer, long len);
 unsigned char *string_to_hex(char *str, long *len);
@@ -560,6 +573,7 @@ void X509_email_free(STACK *sk);
 #define X509V3_F_V2I_GENERAL_NAME                       117
 #define X509V3_F_V2I_GENERAL_NAMES                      118
 #define X509V3_F_V3_GENERIC_EXTENSION                   116
+#define X509V3_F_X509V3_ADD_I2D                                 140
 #define X509V3_F_X509V3_ADD_VALUE                       105
 #define X509V3_F_X509V3_EXT_ADD                                 104
 #define X509V3_F_X509V3_EXT_ADD_ALIAS                   106
@@ -576,8 +590,10 @@ void X509_email_free(STACK *sk);
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR               101
 #define X509V3_R_DUPLICATE_ZONE_ID                      133
 #define X509V3_R_ERROR_CONVERTING_ZONE                  131
+#define X509V3_R_ERROR_CREATING_EXTENSION               144
 #define X509V3_R_ERROR_IN_EXTENSION                     128
 #define X509V3_R_EXPECTED_A_SECTION_NAME                137
+#define X509V3_R_EXTENSION_EXISTS                       145
 #define X509V3_R_EXTENSION_NAME_ERROR                   115
 #define X509V3_R_EXTENSION_NOT_FOUND                    102
 #define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED        103