Hi,
please find attached a context diff patch applying to the following
openssl source code files:
apps/req.c
apps/x509.c
crypto/asn1/t_req.c
crypto/asn1/t_x509.c
Please review and apply to the openssl release. Of course this is
subject to your scrutiny, but I am sure you will find most of this
quite reasonable.
This patch accomplishes the following things:
- make x509 and req apps skip over the subject DN if subject DN is
empty. Previously, some binary garbage was printed, which is clearly
not appropriate.
[crypto/asn1/t_req.c, crypto/asn1/t_x509.c, apps/x509.c]
- allow user to generate a request (and subsequently a certificate)
with empty subject DN. PKIX clearly allows subject DNs to be empty,
and this is very useful if the certificate is for a non-person
subject.
[apps/req.c]
- add an option "-name" to the req application that allows the user to
select the DN section in the configuration file. This option
overrides the default distinguished_name option in the configuration
file.
[apps/req.c]
- add an option "-dns" to the x509 application that prints the a DNS
type subject alternate name to standard output.
[apps/x509.c]
I would have preferred to implement a more generally useful subject
alternate name, or v3 extension extraction option to x509. But I had to
constrain myself to DNS because that's all I need and doing more is so
hard. I always get scared whenever I dive into openssl's code. It's
extremely complex. A lot of undocumented stylish c-isms. Some of the
blame here should go to this terrible thing called ASN.1 and X509,
that is so overly complicated.
I know there are folks who would need to extract an IP address from
the cert. That's not too hard to do based on the template for DNS.
However, someone should add IPv6 address support here as well.
regards,
-Gunther
--
Gunther Schadow, M.D., Ph.D. [EMAIL PROTECTED]
Medical Information Scientist Regenstrief Institute for Health Care
Adjunct Assistant Professor Indiana University School of Medicine
tel:1(317)630-7960 http://aurora.regenstrief.org
*** apps/req.c.orig Tue Oct 16 14:17:27 2001
--- apps/req.c Tue Oct 16 18:08:03 2001
***************
*** 108,116 ****
* -x509 - output a self signed X509 structure instead.
* -asn1-kludge - output new certificate request in a format that some CA's
* require. This format is wrong
*/
! static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs);
static int prompt_info(X509_REQ *req,
STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs);
--- 108,117 ----
* -x509 - output a self signed X509 structure instead.
* -asn1-kludge - output new certificate request in a format that some CA's
* require. This format is wrong
+ * -name - specify the distinguished_name section to use
*/
! static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs, char *dn_sect);
static int prompt_info(X509_REQ *req,
STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs);
***************
*** 154,159 ****
--- 155,161 ----
char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
char *extensions = NULL;
char *req_exts = NULL;
+ char *dn_sect = NULL;
EVP_CIPHER *cipher=NULL;
int modulus=0;
char *inrand=NULL;
***************
*** 351,356 ****
--- 353,363 ----
if (--argc < 1) goto bad;
req_exts = *(++argv);
}
+ else if (strcmp(*argv,"-name") == 0)
+ {
+ if (--argc < 1) goto bad;
+ dn_sect = *(++argv);
+ }
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
***************
*** 394,399 ****
--- 401,407 ----
BIO_printf(bio_err," have been reported as
requiring\n");
BIO_printf(bio_err," -extensions .. specify certificate extension
section (override value in config file)\n");
BIO_printf(bio_err," -reqexts .. specify request extension section
(override value in config file)\n");
+ BIO_printf(bio_err," -name .. specify distinguished name section
+(override value in config file)\n");
goto end;
}
***************
*** 702,708 ****
goto end;
}
! i=make_REQ(req,pkey,!x509);
if (kludge >= 0)
req->req_info->req_kludge=kludge;
if (!i)
--- 710,716 ----
goto end;
}
! i=make_REQ(req,pkey,!x509,dn_sect);
if (kludge >= 0)
req->req_info->req_kludge=kludge;
if (!i)
***************
*** 916,944 ****
EXIT(ex);
}
! static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs)
{
int ret=0,i;
char no_prompt = 0;
! STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
! char *tmp, *dn_sect,*attr_sect;
tmp=CONF_get_string(req_conf,SECTION,PROMPT);
if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
! dn_sect=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
! if (dn_sect == NULL)
! {
! BIO_printf(bio_err,"unable to find '%s' in config\n",
! DISTINGUISHED_NAME);
! goto err;
! }
! dn_sk=CONF_get_section(req_conf,dn_sect);
! if (dn_sk == NULL)
! {
! BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
! goto err;
! }
attr_sect=CONF_get_string(req_conf,SECTION,ATTRIBUTES);
if (attr_sect == NULL)
--- 924,952 ----
EXIT(ex);
}
! static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs, char *dn_sect)
{
int ret=0,i;
char no_prompt = 0;
! STACK_OF(CONF_VALUE) *dn_sk = NULL, *attr_sk = NULL;
! char *tmp,*attr_sect;
tmp=CONF_get_string(req_conf,SECTION,PROMPT);
if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
! if(dn_sect == NULL)
! dn_sect=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
! if(dn_sect == NULL)
! dn_sk=NULL;
! else
! {
! dn_sk=CONF_get_section(req_conf,dn_sect);
! if (dn_sk == NULL)
! {
! BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
! goto err;
! }
! }
attr_sect=CONF_get_string(req_conf,SECTION,ATTRIBUTES);
if (attr_sect == NULL)
***************
*** 978,985 ****
int nid,min,max;
char *type,*def,*value;
CONF_VALUE *v;
- X509_NAME *subj;
- subj = X509_REQ_get_subject_name(req);
BIO_printf(bio_err,"You are about to be asked to enter information that will
be incorporated\n");
BIO_printf(bio_err,"into your certificate request.\n");
BIO_printf(bio_err,"What you are about to enter is what is called a
Distinguished Name or a DN.\n");
--- 986,991 ----
***************
*** 989,996 ****
BIO_printf(bio_err,"-----\n");
! if (sk_CONF_VALUE_num(dn_sk))
{
i= -1;
start: for (;;)
{
--- 995,1005 ----
BIO_printf(bio_err,"-----\n");
! if ((dn_sk != NULL) && (sk_CONF_VALUE_num(dn_sk) > 0))
{
+ X509_NAME *subj = NULL;
+ subj = X509_REQ_get_subject_name(req);
+
i= -1;
start: for (;;)
{
***************
*** 1033,1043 ****
min,max))
return 0;
}
! if (X509_NAME_entry_count(subj) == 0)
! {
! BIO_printf(bio_err,"error, no objects specified in config
file\n");
! return 0;
! }
if (attribs)
{
--- 1042,1048 ----
min,max))
return 0;
}
! }
if (attribs)
{
***************
*** 1081,1092 ****
return 0;
}
}
! }
! else
! {
! BIO_printf(bio_err,"No template, please set one up.\n");
! return 0;
! }
return 1;
--- 1086,1092 ----
return 0;
}
}
!
return 1;
***************
*** 1099,1138 ****
char *p,*q;
char *type;
CONF_VALUE *v;
- X509_NAME *subj;
-
- subj = X509_REQ_get_subject_name(req);
! for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
{
! v=sk_CONF_VALUE_value(dn_sk,i);
! p=q=NULL;
! type=v->name;
! /* Skip past any leading X. X: X, etc to allow for
! * multiple instances
! */
! for(p = v->name; *p ; p++)
! #ifndef CHARSET_EBCDIC
! if ((*p == ':') || (*p == ',') || (*p == '.')) {
! #else
! if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p
== os_toascii['.'])) {
! #endif
! p++;
! if(*p) type = p;
! break;
! }
! if (!X509_NAME_add_entry_by_txt(subj,type, MBSTRING_ASC,
! (unsigned char *) v->value,-1,-1,0)) return 0;
!
! }
! /* a subject name may be empty. Don't bark here
! if (!X509_NAME_entry_count(subj))
! {
! BIO_printf(bio_err,"error, no objects specified in config
file\n");
! return 0;
! }
! */
if (attribs)
{
--- 1099,1133 ----
char *p,*q;
char *type;
CONF_VALUE *v;
! if ((dn_sk != NULL) && (sk_CONF_VALUE_num(dn_sk) > 0))
{
! X509_NAME *subj;
! subj = X509_REQ_get_subject_name(req);
! for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
! {
! v=sk_CONF_VALUE_value(dn_sk,i);
! p=q=NULL;
! type=v->name;
! /* Skip past any leading X. X: X, etc to allow for
! * multiple instances
! */
! for(p = v->name; *p ; p++)
! #ifndef CHARSET_EBCDIC
! if ((*p == ':') || (*p == ',') || (*p == '.')) {
! #else
! if ((*p == os_toascii[':']) || (*p == os_toascii[','])
|| (*p == os_toascii['.'])) {
! #endif
! p++;
! if(*p) type = p;
! break;
! }
! if (!X509_NAME_add_entry_by_txt(subj,type, MBSTRING_ASC,
! (unsigned char *) v->value,-1,-1,0)) return 0;
!
! }
! }
if (attribs)
{
*** apps/x509.c.orig Wed Jul 4 18:19:10 2001
--- apps/x509.c Tue Oct 16 18:05:06 2001
***************
*** 96,101 ****
--- 96,102 ----
" -subject - print subject DN\n",
" -issuer - print issuer DN\n",
" -email - print email address(es)\n",
+ " -dns - print DNS domain name\n",
" -startdate - notBefore field\n",
" -enddate - notAfter field\n",
" -purpose - print out certificate purposes\n",
***************
*** 159,165 ****
char *CAkeyfile=NULL,*CAserial=NULL;
char *alias=NULL;
int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
! int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
int C=0;
int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
--- 160,166 ----
char *CAkeyfile=NULL,*CAserial=NULL;
char *alias=NULL;
int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
! int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0,dns=0;
int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
int C=0;
int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
***************
*** 341,346 ****
--- 342,349 ----
C= ++num;
else if (strcmp(*argv,"-email") == 0)
email= ++num;
+ else if (strcmp(*argv,"-dns") == 0)
+ dns = ++num;
else if (strcmp(*argv,"-serial") == 0)
serial= ++num;
else if (strcmp(*argv,"-modulus") == 0)
***************
*** 635,642 ****
}
else if (subject == i)
{
! print_name(STDout, "subject= ",
! X509_get_subject_name(x), nmflag);
}
else if (serial == i)
{
--- 638,648 ----
}
else if (subject == i)
{
! X509_NAME *subj = NULL;
! subj = X509_get_subject_name(x);
! if (subj && (X509_NAME_entry_count(subj) > 0))
! print_name(STDout, "subject= ",
! subj, nmflag);
}
else if (serial == i)
{
***************
*** 652,657 ****
--- 658,680 ----
for (j = 0; j < sk_num(emlst); j++)
BIO_printf(STDout, "%s\n", sk_value(emlst, j));
X509_email_free(emlst);
+ }
+ else if (dns == i)
+ {
+ STACK_OF(GENERAL_NAME) *gens;
+ int i;
+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL,
+NULL);
+ for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+ {
+ GENERAL_NAME *gen =
+sk_GENERAL_NAME_value(gens, i);
+ if(gen->type == GEN_DNS)
+ {
+ ASN1_STRING_print_ex(STDout,
+gen->d.ia5, 0);
+ BIO_printf(STDout, "\n");
+ break;
+ }
+ }
+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
}
else if (aliasout == i)
{
*** crypto/asn1/t_req.c.orig Sun Aug 20 03:46:06 2000
--- crypto/asn1/t_req.c Tue Oct 16 15:36:10 2001
***************
*** 109,115 ****
sprintf(str,"%8sSubject: ","");
if (BIO_puts(bp,str) <= 0) goto err;
! X509_NAME_print(bp,ri->subject,16);
sprintf(str,"\n%8sSubject Public Key Info:\n","");
if (BIO_puts(bp,str) <= 0) goto err;
i=OBJ_obj2nid(ri->pubkey->algor->algorithm);
--- 109,116 ----
sprintf(str,"%8sSubject: ","");
if (BIO_puts(bp,str) <= 0) goto err;
! if(X509_NAME_entry_count(ri->subject)>0)
! X509_NAME_print(bp,ri->subject,16);
sprintf(str,"\n%8sSubject Public Key Info:\n","");
if (BIO_puts(bp,str) <= 0) goto err;
i=OBJ_obj2nid(ri->pubkey->algor->algorithm);
*** crypto/asn1/t_x509.c.orig Sun Nov 26 06:33:01 2000
--- crypto/asn1/t_x509.c Tue Oct 16 16:16:32 2001
***************
*** 147,153 ****
if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
if (BIO_write(bp,"\n Subject: ",18) <= 0) goto err;
! if (!X509_NAME_print(bp,X509_get_subject_name(x),16)) goto err;
if (BIO_write(bp,"\n Subject Public Key Info:\n",34) <= 0)
goto err;
i=OBJ_obj2nid(ci->key->algor->algorithm);
--- 147,154 ----
if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
if (BIO_write(bp,"\n Subject: ",18) <= 0) goto err;
! if(X509_NAME_entry_count(X509_get_subject_name(x))>0)
! if (!X509_NAME_print(bp,X509_get_subject_name(x),16)) goto err;
if (BIO_write(bp,"\n Subject Public Key Info:\n",34) <= 0)
goto err;
i=OBJ_obj2nid(ci->key->algor->algorithm);