More code for X509_print_ex() support.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 6 Oct 2000 11:51:47 +0000 (11:51 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 6 Oct 2000 11:51:47 +0000 (11:51 +0000)
CHANGES
apps/apps.c
apps/apps.h
apps/x509.c
crypto/asn1/t_x509.c
crypto/x509v3/v3_prn.c
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index aeea390f77e825b05f1ffd66e66058e68a100b1b..929431cb02da6c2a4110e2d1a67866c544947439 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,8 +5,10 @@
  Changes between 0.9.6 and 0.9.7  [xx XXX 2000]
 
   *) Fix for bug in DirectoryString mask setting. Add support for
-     X509_NAME_print_ex() in 'req' and initial X509_print_ex() function
-     to allow certificate printing to more controllable.
+     X509_NAME_print_ex() in 'req' and X509_print_ex() function
+     to allow certificate printing to more controllable, additional
+     'certopt' option to 'x509' to allow new printing options to be
+     set.
      [Steve Henson]
 
   *) Clean old EAY MD5 hack from e_os.h.
index c22550b2945e4504386c57975527917642e52e50..03bd9e2d3fa2c77035f3e0d34eab3ceaedc0bb4c 100644 (file)
 #  include "bss_file.c"
 #endif
 
+typedef struct {
+       char *name;
+       unsigned long flag;
+       unsigned long mask;
+} NAME_EX_TBL;
+
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
+
 int app_init(long mesgwin);
 #ifdef undef /* never finished - probably never will be :-) */
 int args_from_file(char *file, int *argc, char **argv[])
@@ -694,16 +702,43 @@ end:
        return(othercerts);
        }
 
-typedef struct {
-       char *name;
-       unsigned long flag;
-       unsigned long mask;
-} NAME_EX_TBL;
+
+#define X509V3_EXT_UNKNOWN_MASK                (0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT             0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN       (1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN       (2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN                (3L << 16)
+
+int set_cert_ex(unsigned long *flags, const char *arg)
+{
+       static const NAME_EX_TBL cert_tbl[] = {
+               { "compatible", X509_FLAG_COMPAT, 0xffffffffl},
+               { "no_header", X509_FLAG_NO_HEADER, 0},
+               { "no_version", X509_FLAG_NO_VERSION, 0},
+               { "no_serial", X509_FLAG_NO_SERIAL, 0},
+               { "no_signame", X509_FLAG_NO_SIGNAME, 0},
+               { "no_validity", X509_FLAG_NO_VALIDITY, 0},
+               { "no_subject", X509_FLAG_NO_SUBJECT, 0},
+               { "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
+               { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
+               { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
+               { "no_aux", X509_FLAG_NO_AUX, 0},
+               { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
+               { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+               { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+               { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+               { NULL, 0, 0}
+       };
+       return set_table_opts(flags, arg, cert_tbl);
+}
 
 int set_name_ex(unsigned long *flags, const char *arg)
 {
-       char c;
-       const NAME_EX_TBL *ptbl, ex_tbl[] = {
+       static const NAME_EX_TBL ex_tbl[] = {
                { "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
                { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
                { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
@@ -731,7 +766,13 @@ int set_name_ex(unsigned long *flags, const char *arg)
                { "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
                { NULL, 0, 0}
        };
+       return set_table_opts(flags, arg, ex_tbl);
+}
 
+static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
+{
+       char c;
+       const NAME_EX_TBL *ptbl;
        c = arg[0];
 
        if(c == '-') {
@@ -742,7 +783,7 @@ int set_name_ex(unsigned long *flags, const char *arg)
                arg++;
        } else c = 1;
 
-       for(ptbl = ex_tbl; ptbl->name; ptbl++) {
+       for(ptbl = in_tbl; ptbl->name; ptbl++) {
                if(!strcmp(arg, ptbl->name)) {
                        *flags &= ~ptbl->mask;
                        if(c) *flags |= ptbl->flag;
index 82587b977056c9ef64918c0211ca0c64f9088350..0951299d5816fdbdf04b45dbdf3f31b7fe2267d9 100644 (file)
@@ -147,6 +147,7 @@ int chopup_args(ARGS *arg,char *buf, int *argc, char **argv[]);
 int dump_cert_text(BIO *out, X509 *x);
 void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags);
 #endif
+int set_cert_ex(unsigned long *flags, const char *arg);
 int set_name_ex(unsigned long *flags, const char *arg);
 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
 int add_oid_section(BIO *err, LHASH *conf);
index 76dd66db86250b039e8af0a51b1a286e86d0c5ca..3bef1fc590a62342c72314ff65e824eb47e4b0c5 100644 (file)
@@ -129,6 +129,7 @@ static char *x509_usage[]={
 " -extensions     - section from config file with X509V3 extensions to add\n",
 " -clrext         - delete extensions before signing and input certificate\n",
 " -nameopt arg    - various certificate name options\n",
+" -certopt arg    - various certificate text options\n",
 NULL
 };
 
@@ -174,7 +175,7 @@ int MAIN(int argc, char **argv)
        char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
        int need_rand = 0;
        int checkend=0,checkoffset=0;
-       unsigned long nmflag = 0;
+       unsigned long nmflag = 0, certflag = 0;
 
        reqfile=0;
 
@@ -326,6 +327,11 @@ int MAIN(int argc, char **argv)
                        alias= *(++argv);
                        trustout = 1;
                        }
+               else if (strcmp(*argv,"-certopt") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       if (!set_cert_ex(&certflag, *(++argv))) goto bad;
+                       }
                else if (strcmp(*argv,"-nameopt") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -774,7 +780,7 @@ bad:
                                }
                        else if (text == i)
                                {
-                               X509_print(out,x);
+                               X509_print_ex(out,x,nmflag, certflag);
                                }
                        else if (startdate == i)
                                {
index 189e5bdce8fd9e369044dd218688de3839a6f796..f2979bf5a75a8013a728fc01d53aadc9981e72cc 100644 (file)
@@ -103,6 +103,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
        long l;
        int ret=0,i,j,n;
        char *m=NULL,*s, mlch = ' ';
+       int nmindent = 0;
        X509_CINF *ci;
        ASN1_INTEGER *bs;
        EVP_PKEY *pkey=NULL;
@@ -110,8 +111,13 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
        X509_EXTENSION *ex;
        ASN1_STRING *str=NULL;
 
-       if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE)
+       if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
                        mlch = '\n';
+                       nmindent = 16;
+       }
+
+       if(nmflags == X509_FLAG_COMPAT)
+               nmindent = 16;
 
        ci=x->cert_info;
        if(!(cflag & X509_FLAG_NO_HEADER))
@@ -169,7 +175,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
        if(!(cflag & X509_FLAG_NO_ISSUER))
                {
                if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
-               if (!X509_NAME_print_ex(bp,X509_get_issuer_name(x),16, nmflags)) goto err;
+               if (!X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags)) goto err;
                }
        if(!(cflag & X509_FLAG_NO_VALIDITY))
                {
@@ -183,7 +189,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
        if(!(cflag & X509_FLAG_NO_SUBJECT))
                {
                if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
-               if (!X509_NAME_print(bp,X509_get_subject_name(x),16)) goto err;
+               if (!X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags)) goto err;
                }
        if(!(cflag & X509_FLAG_NO_PUBKEY))
                {
@@ -239,7 +245,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
                        j=X509_EXTENSION_get_critical(ex);
                        if (BIO_printf(bp,": %s\n",j?"critical":"","") <= 0)
                                goto err;
-                       if(!X509V3_EXT_print(bp, ex, 0, 16))
+                       if(!X509V3_EXT_print(bp, ex, cflag, 16))
                                {
                                BIO_printf(bp, "%16s", "");
                                M_ASN1_OCTET_STRING_print(bp,ex->value);
index dbc4fb1f160009d575d919c689a40f9afac25c0b..5416f662d3155cf0abbb362e4362b4d1d411e71d 100644 (file)
@@ -64,6 +64,8 @@
 
 /* Extension printing routines */
 
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported);
+
 /* Print out a name+value stack */
 
 void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
@@ -96,16 +98,18 @@ void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
 
 /* Main routine: print out a general extension */
 
-int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent)
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
 {
        char *ext_str = NULL, *value = NULL;
        unsigned char *p;
        X509V3_EXT_METHOD *method;      
        STACK_OF(CONF_VALUE) *nval = NULL;
        int ok = 1;
-       if(!(method = X509V3_EXT_get(ext))) return 0;
+       if(!(method = X509V3_EXT_get(ext)))
+               return unknown_ext_print(out, ext, flag, indent, 0);
        p = ext->value->data;
-       if(!(ext_str = method->d2i(NULL, &p, ext->value->length))) return 0;
+       if(!(ext_str = method->d2i(NULL, &p, ext->value->length)))
+               return unknown_ext_print(out, ext, flag, indent, 1);
        if(method->i2s) {
                if(!(value = method->i2s(method, ext_str))) {
                        ok = 0;
@@ -138,6 +142,32 @@ int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent)
                return ok;
 }
 
+static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent, int supported)
+{
+       switch(flag & X509V3_EXT_UNKNOWN_MASK) {
+
+               case X509V3_EXT_DEFAULT:
+               return 0;
+
+               case X509V3_EXT_ERROR_UNKNOWN:
+               if(supported)
+                       BIO_printf(out, "%*s<Parse Error>", indent, "");
+               else
+                       BIO_printf(out, "%*s<Not Supported>", indent, "");
+               return 1;
+
+               case X509V3_EXT_PARSE_UNKNOWN:
+                       return ASN1_parse_dump(out,
+                               ext->value->data, ext->value->length, indent, -1);
+               case X509V3_EXT_DUMP_UNKNOWN:
+                       return BIO_dump_indent(out, (char *)ext->value->data, ext->value->length, indent);
+
+               default:
+               return 1;
+       }
+}
+       
+
 #ifndef NO_FP_API
 int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
 {
index 0453b12d6335b619306b8486c3feeeb138838c6e..4c3edc3dafcde4f8f92b754ba0865972333574e7 100644 (file)
@@ -352,6 +352,18 @@ typedef struct x509_purpose_st {
 #define X509_PURPOSE_MIN               1
 #define X509_PURPOSE_MAX               7
 
+/* Flags for X509V3_EXT_print() */
+
+#define X509V3_EXT_UNKNOWN_MASK                (0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT             0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN       (1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN       (2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN                (3L << 16)
+
 DECLARE_STACK_OF(X509_PURPOSE)
 
 void ERR_load_X509V3_strings(void);
@@ -528,7 +540,7 @@ int name_cmp(const char *name, const char *cmp);
 
 void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
                                                                 int ml);
-int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
 int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
 
 int X509_check_purpose(X509 *x, int id, int ca);