diff --git a/CHANGES b/CHANGES index aeea390f77e825b05f1ffd66e66058e68a100b1b..929431cb02da6c2a4110e2d1a67866c544947439 100644 --- 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. diff --git a/apps/apps.c b/apps/apps.c index c22550b2945e4504386c57975527917642e52e50..03bd9e2d3fa2c77035f3e0d34eab3ceaedc0bb4c 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -74,6 +74,14 @@ # 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; diff --git a/apps/apps.h b/apps/apps.h index 82587b977056c9ef64918c0211ca0c64f9088350..0951299d5816fdbdf04b45dbdf3f31b7fe2267d9 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -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); diff --git a/apps/x509.c b/apps/x509.c index 76dd66db86250b039e8af0a51b1a286e86d0c5ca..3bef1fc590a62342c72314ff65e824eb47e4b0c5 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -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) { diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c index 189e5bdce8fd9e369044dd218688de3839a6f796..f2979bf5a75a8013a728fc01d53aadc9981e72cc 100644 --- a/crypto/asn1/t_x509.c +++ b/crypto/asn1/t_x509.c @@ -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); diff --git a/crypto/x509v3/v3_prn.c b/crypto/x509v3/v3_prn.c index dbc4fb1f160009d575d919c689a40f9afac25c0b..5416f662d3155cf0abbb362e4362b4d1d411e71d 100644 --- a/crypto/x509v3/v3_prn.c +++ b/crypto/x509v3/v3_prn.c @@ -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", indent, ""); + else + BIO_printf(out, "%*s", 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) { diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index 0453b12d6335b619306b8486c3feeeb138838c6e..4c3edc3dafcde4f8f92b754ba0865972333574e7 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -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);