diff options
author | beck <> | 2000-03-19 11:13:58 +0000 |
---|---|---|
committer | beck <> | 2000-03-19 11:13:58 +0000 |
commit | 796d609550df3a33fc11468741c5d2f6d3df4c11 (patch) | |
tree | 6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libssl/src/apps/req.c | |
parent | 5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff) | |
download | openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2 openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip |
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2
if you are using the ssl26 packages for ssh and other things to work you will
need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libssl/src/apps/req.c')
-rw-r--r-- | src/lib/libssl/src/apps/req.c | 411 |
1 files changed, 247 insertions, 164 deletions
diff --git a/src/lib/libssl/src/apps/req.c b/src/lib/libssl/src/apps/req.c index 463ac156ea..97bb0d0ed8 100644 --- a/src/lib/libssl/src/apps/req.c +++ b/src/lib/libssl/src/apps/req.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include "apps.h" | 66 | #include "apps.h" |
67 | #include <openssl/bio.h> | 67 | #include <openssl/bio.h> |
68 | #include <openssl/evp.h> | 68 | #include <openssl/evp.h> |
69 | #include <openssl/rand.h> | ||
70 | #include <openssl/conf.h> | 69 | #include <openssl/conf.h> |
71 | #include <openssl/err.h> | 70 | #include <openssl/err.h> |
72 | #include <openssl/asn1.h> | 71 | #include <openssl/asn1.h> |
@@ -79,9 +78,12 @@ | |||
79 | 78 | ||
80 | #define BITS "default_bits" | 79 | #define BITS "default_bits" |
81 | #define KEYFILE "default_keyfile" | 80 | #define KEYFILE "default_keyfile" |
81 | #define PROMPT "prompt" | ||
82 | #define DISTINGUISHED_NAME "distinguished_name" | 82 | #define DISTINGUISHED_NAME "distinguished_name" |
83 | #define ATTRIBUTES "attributes" | 83 | #define ATTRIBUTES "attributes" |
84 | #define V3_EXTENSIONS "x509_extensions" | 84 | #define V3_EXTENSIONS "x509_extensions" |
85 | #define REQ_EXTENSIONS "req_extensions" | ||
86 | #define STRING_MASK "string_mask" | ||
85 | 87 | ||
86 | #define DEFAULT_KEY_LENGTH 512 | 88 | #define DEFAULT_KEY_LENGTH 512 |
87 | #define MIN_KEY_LENGTH 384 | 89 | #define MIN_KEY_LENGTH 384 |
@@ -89,7 +91,7 @@ | |||
89 | #undef PROG | 91 | #undef PROG |
90 | #define PROG req_main | 92 | #define PROG req_main |
91 | 93 | ||
92 | /* -inform arg - input format - default PEM (one of DER, TXT or PEM) | 94 | /* -inform arg - input format - default PEM (DER or PEM) |
93 | * -outform arg - output format - default PEM | 95 | * -outform arg - output format - default PEM |
94 | * -in arg - input file - default stdin | 96 | * -in arg - input file - default stdin |
95 | * -out arg - output file - default stdout | 97 | * -out arg - output file - default stdout |
@@ -108,13 +110,20 @@ | |||
108 | */ | 110 | */ |
109 | 111 | ||
110 | static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); | 112 | static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); |
111 | static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, | 113 | static int prompt_info(X509_REQ *req, |
114 | STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, | ||
115 | STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs); | ||
116 | static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, | ||
117 | STACK_OF(CONF_VALUE) *attr, int attribs); | ||
118 | static int add_attribute_object(X509_REQ *req, char *text, | ||
112 | char *def, char *value, int nid, int min, | 119 | char *def, char *value, int nid, int min, |
113 | int max); | 120 | int max); |
114 | static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, | 121 | static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, |
115 | int nid,int min,int max); | 122 | int nid,int min,int max); |
123 | #ifndef NO_RSA | ||
116 | static void MS_CALLBACK req_cb(int p,int n,void *arg); | 124 | static void MS_CALLBACK req_cb(int p,int n,void *arg); |
117 | static int req_fix_data(int nid,int *type,int len,int min,int max); | 125 | #endif |
126 | static int req_check_len(int len,int min,int max); | ||
118 | static int check_end(char *str, char *end); | 127 | static int check_end(char *str, char *end); |
119 | static int add_oid_section(LHASH *conf); | 128 | static int add_oid_section(LHASH *conf); |
120 | #ifndef MONOLITH | 129 | #ifndef MONOLITH |
@@ -127,6 +136,8 @@ static LHASH *req_conf=NULL; | |||
127 | #define TYPE_DSA 2 | 136 | #define TYPE_DSA 2 |
128 | #define TYPE_DH 3 | 137 | #define TYPE_DH 3 |
129 | 138 | ||
139 | int MAIN(int, char **); | ||
140 | |||
130 | int MAIN(int argc, char **argv) | 141 | int MAIN(int argc, char **argv) |
131 | { | 142 | { |
132 | #ifndef NO_DSA | 143 | #ifndef NO_DSA |
@@ -139,17 +150,21 @@ int MAIN(int argc, char **argv) | |||
139 | int i,badops=0,newreq=0,newkey= -1,pkey_type=0; | 150 | int i,badops=0,newreq=0,newkey= -1,pkey_type=0; |
140 | BIO *in=NULL,*out=NULL; | 151 | BIO *in=NULL,*out=NULL; |
141 | int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; | 152 | int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; |
142 | int nodes=0,kludge=0; | 153 | int nodes=0,kludge=0,newhdr=0; |
143 | char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL; | 154 | char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL; |
144 | char *extensions = NULL; | 155 | char *extensions = NULL; |
156 | char *req_exts = NULL; | ||
145 | EVP_CIPHER *cipher=NULL; | 157 | EVP_CIPHER *cipher=NULL; |
146 | int modulus=0; | 158 | int modulus=0; |
159 | char *passargin = NULL, *passargout = NULL; | ||
160 | char *passin = NULL, *passout = NULL; | ||
147 | char *p; | 161 | char *p; |
148 | const EVP_MD *md_alg=NULL,*digest=EVP_md5(); | 162 | const EVP_MD *md_alg=NULL,*digest=EVP_md5(); |
149 | #ifndef MONOLITH | 163 | #ifndef MONOLITH |
150 | MS_STATIC char config_name[256]; | 164 | MS_STATIC char config_name[256]; |
151 | #endif | 165 | #endif |
152 | 166 | ||
167 | req_conf = NULL; | ||
153 | #ifndef NO_DES | 168 | #ifndef NO_DES |
154 | cipher=EVP_des_ede3_cbc(); | 169 | cipher=EVP_des_ede3_cbc(); |
155 | #endif | 170 | #endif |
@@ -214,6 +229,16 @@ int MAIN(int argc, char **argv) | |||
214 | if (--argc < 1) goto bad; | 229 | if (--argc < 1) goto bad; |
215 | keyout= *(++argv); | 230 | keyout= *(++argv); |
216 | } | 231 | } |
232 | else if (strcmp(*argv,"-passin") == 0) | ||
233 | { | ||
234 | if (--argc < 1) goto bad; | ||
235 | passargin= *(++argv); | ||
236 | } | ||
237 | else if (strcmp(*argv,"-passout") == 0) | ||
238 | { | ||
239 | if (--argc < 1) goto bad; | ||
240 | passargout= *(++argv); | ||
241 | } | ||
217 | else if (strcmp(*argv,"-newkey") == 0) | 242 | else if (strcmp(*argv,"-newkey") == 0) |
218 | { | 243 | { |
219 | int is_numeric; | 244 | int is_numeric; |
@@ -281,6 +306,8 @@ int MAIN(int argc, char **argv) | |||
281 | 306 | ||
282 | newreq=1; | 307 | newreq=1; |
283 | } | 308 | } |
309 | else if (strcmp(*argv,"-newhdr") == 0) | ||
310 | newhdr=1; | ||
284 | else if (strcmp(*argv,"-modulus") == 0) | 311 | else if (strcmp(*argv,"-modulus") == 0) |
285 | modulus=1; | 312 | modulus=1; |
286 | else if (strcmp(*argv,"-verify") == 0) | 313 | else if (strcmp(*argv,"-verify") == 0) |
@@ -308,8 +335,17 @@ int MAIN(int argc, char **argv) | |||
308 | /* ok */ | 335 | /* ok */ |
309 | digest=md_alg; | 336 | digest=md_alg; |
310 | } | 337 | } |
338 | else if (strcmp(*argv,"-extensions") == 0) | ||
339 | { | ||
340 | if (--argc < 1) goto bad; | ||
341 | extensions = *(++argv); | ||
342 | } | ||
343 | else if (strcmp(*argv,"-reqexts") == 0) | ||
344 | { | ||
345 | if (--argc < 1) goto bad; | ||
346 | req_exts = *(++argv); | ||
347 | } | ||
311 | else | 348 | else |
312 | |||
313 | { | 349 | { |
314 | BIO_printf(bio_err,"unknown option %s\n",*argv); | 350 | BIO_printf(bio_err,"unknown option %s\n",*argv); |
315 | badops=1; | 351 | badops=1; |
@@ -324,8 +360,8 @@ int MAIN(int argc, char **argv) | |||
324 | bad: | 360 | bad: |
325 | BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); | 361 | BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); |
326 | BIO_printf(bio_err,"where options are\n"); | 362 | BIO_printf(bio_err,"where options are\n"); |
327 | BIO_printf(bio_err," -inform arg input format - one of DER TXT PEM\n"); | 363 | BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); |
328 | BIO_printf(bio_err," -outform arg output format - one of DER TXT PEM\n"); | 364 | BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); |
329 | BIO_printf(bio_err," -in arg input file\n"); | 365 | BIO_printf(bio_err," -in arg input file\n"); |
330 | BIO_printf(bio_err," -out arg output file\n"); | 366 | BIO_printf(bio_err," -out arg output file\n"); |
331 | BIO_printf(bio_err," -text text form of request\n"); | 367 | BIO_printf(bio_err," -text text form of request\n"); |
@@ -344,16 +380,21 @@ bad: | |||
344 | BIO_printf(bio_err," -new new request.\n"); | 380 | BIO_printf(bio_err," -new new request.\n"); |
345 | BIO_printf(bio_err," -x509 output a x509 structure instead of a cert. req.\n"); | 381 | BIO_printf(bio_err," -x509 output a x509 structure instead of a cert. req.\n"); |
346 | BIO_printf(bio_err," -days number of days a x509 generated by -x509 is valid for.\n"); | 382 | BIO_printf(bio_err," -days number of days a x509 generated by -x509 is valid for.\n"); |
383 | BIO_printf(bio_err," -newhdr output \"NEW\" in the header lines\n"); | ||
347 | BIO_printf(bio_err," -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); | 384 | BIO_printf(bio_err," -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); |
348 | BIO_printf(bio_err," have been reported as requiring\n"); | 385 | BIO_printf(bio_err," have been reported as requiring\n"); |
349 | BIO_printf(bio_err," [ It is now always turned on but can be turned off with -no-asn1-kludge ]\n"); | 386 | BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n"); |
387 | BIO_printf(bio_err," -reqexts .. specify request extension section (override value in config file)\n"); | ||
350 | goto end; | 388 | goto end; |
351 | } | 389 | } |
352 | 390 | ||
353 | ERR_load_crypto_strings(); | 391 | ERR_load_crypto_strings(); |
354 | X509V3_add_standard_extensions(); | 392 | if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { |
393 | BIO_printf(bio_err, "Error getting passwords\n"); | ||
394 | goto end; | ||
395 | } | ||
355 | 396 | ||
356 | #ifndef MONOLITH | 397 | #ifndef MONOLITH /* else this has happened in openssl.c (global `config') */ |
357 | /* Lets load up our environment a little */ | 398 | /* Lets load up our environment a little */ |
358 | p=getenv("OPENSSL_CONF"); | 399 | p=getenv("OPENSSL_CONF"); |
359 | if (p == NULL) | 400 | if (p == NULL) |
@@ -367,7 +408,7 @@ bad: | |||
367 | strcat(config_name,OPENSSL_CONF); | 408 | strcat(config_name,OPENSSL_CONF); |
368 | p=config_name; | 409 | p=config_name; |
369 | } | 410 | } |
370 | default_config_file=p; | 411 | default_config_file=p; |
371 | config=CONF_load(config,p,NULL); | 412 | config=CONF_load(config,p,NULL); |
372 | #endif | 413 | #endif |
373 | 414 | ||
@@ -425,7 +466,8 @@ bad: | |||
425 | digest=md_alg; | 466 | digest=md_alg; |
426 | } | 467 | } |
427 | 468 | ||
428 | extensions = CONF_get_string(req_conf, SECTION, V3_EXTENSIONS); | 469 | if(!extensions) |
470 | extensions = CONF_get_string(req_conf, SECTION, V3_EXTENSIONS); | ||
429 | if(extensions) { | 471 | if(extensions) { |
430 | /* Check syntax of file */ | 472 | /* Check syntax of file */ |
431 | X509V3_CTX ctx; | 473 | X509V3_CTX ctx; |
@@ -438,6 +480,34 @@ bad: | |||
438 | } | 480 | } |
439 | } | 481 | } |
440 | 482 | ||
483 | if(!passin) | ||
484 | passin = CONF_get_string(req_conf, SECTION, "input_password"); | ||
485 | |||
486 | if(!passout) | ||
487 | passout = CONF_get_string(req_conf, SECTION, "output_password"); | ||
488 | |||
489 | p = CONF_get_string(req_conf, SECTION, STRING_MASK); | ||
490 | |||
491 | if(p && !ASN1_STRING_set_default_mask_asc(p)) { | ||
492 | BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); | ||
493 | goto end; | ||
494 | } | ||
495 | |||
496 | if(!req_exts) | ||
497 | req_exts = CONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); | ||
498 | if(req_exts) { | ||
499 | /* Check syntax of file */ | ||
500 | X509V3_CTX ctx; | ||
501 | X509V3_set_ctx_test(&ctx); | ||
502 | X509V3_set_conf_lhash(&ctx, req_conf); | ||
503 | if(!X509V3_EXT_add_conf(req_conf, &ctx, req_exts, NULL)) { | ||
504 | BIO_printf(bio_err, | ||
505 | "Error Loading request extension section %s\n", | ||
506 | req_exts); | ||
507 | goto end; | ||
508 | } | ||
509 | } | ||
510 | |||
441 | in=BIO_new(BIO_s_file()); | 511 | in=BIO_new(BIO_s_file()); |
442 | out=BIO_new(BIO_s_file()); | 512 | out=BIO_new(BIO_s_file()); |
443 | if ((in == NULL) || (out == NULL)) | 513 | if ((in == NULL) || (out == NULL)) |
@@ -451,11 +521,12 @@ bad: | |||
451 | goto end; | 521 | goto end; |
452 | } | 522 | } |
453 | 523 | ||
454 | /* if (keyform == FORMAT_ASN1) | 524 | if (keyform == FORMAT_ASN1) |
455 | rsa=d2i_RSAPrivateKey_bio(in,NULL); | 525 | pkey=d2i_PrivateKey_bio(in,NULL); |
456 | else */ | 526 | else if (keyform == FORMAT_PEM) |
457 | if (keyform == FORMAT_PEM) | 527 | { |
458 | pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL); | 528 | pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,passin); |
529 | } | ||
459 | else | 530 | else |
460 | { | 531 | { |
461 | BIO_printf(bio_err,"bad input format specified for X509 request\n"); | 532 | BIO_printf(bio_err,"bad input format specified for X509 request\n"); |
@@ -471,25 +542,9 @@ bad: | |||
471 | 542 | ||
472 | if (newreq && (pkey == NULL)) | 543 | if (newreq && (pkey == NULL)) |
473 | { | 544 | { |
474 | char *randfile; | 545 | char *randfile = CONF_get_string(req_conf,SECTION,"RANDFILE"); |
475 | char buffer[200]; | 546 | app_RAND_load_file(randfile, bio_err, 0); |
476 | 547 | ||
477 | if ((randfile=CONF_get_string(req_conf,SECTION,"RANDFILE")) == NULL) | ||
478 | randfile=RAND_file_name(buffer,200); | ||
479 | #ifdef WINDOWS | ||
480 | BIO_printf(bio_err,"Loading 'screen' into random state -"); | ||
481 | BIO_flush(bio_err); | ||
482 | RAND_screen(); | ||
483 | BIO_printf(bio_err," done\n"); | ||
484 | #endif | ||
485 | if ((randfile == NULL) || !RAND_load_file(randfile,1024L*1024L)) | ||
486 | { | ||
487 | BIO_printf(bio_err,"unable to load 'random state'\n"); | ||
488 | BIO_printf(bio_err,"What this means is that the random number generator has not been seeded\n"); | ||
489 | BIO_printf(bio_err,"with much random data.\n"); | ||
490 | BIO_printf(bio_err,"Consider setting the RANDFILE environment variable to point at a file that\n"); | ||
491 | BIO_printf(bio_err,"'random' data can be kept in.\n"); | ||
492 | } | ||
493 | if (newkey <= 0) | 548 | if (newkey <= 0) |
494 | { | 549 | { |
495 | newkey=(int)CONF_get_number(req_conf,SECTION,BITS); | 550 | newkey=(int)CONF_get_number(req_conf,SECTION,BITS); |
@@ -527,8 +582,7 @@ bad: | |||
527 | } | 582 | } |
528 | #endif | 583 | #endif |
529 | 584 | ||
530 | if ((randfile == NULL) || (RAND_write_file(randfile) == 0)) | 585 | app_RAND_write_file(randfile, bio_err); |
531 | BIO_printf(bio_err,"unable to write 'random state'\n"); | ||
532 | 586 | ||
533 | if (pkey == NULL) goto end; | 587 | if (pkey == NULL) goto end; |
534 | 588 | ||
@@ -560,7 +614,7 @@ bad: | |||
560 | i=0; | 614 | i=0; |
561 | loop: | 615 | loop: |
562 | if (!PEM_write_bio_PrivateKey(out,pkey,cipher, | 616 | if (!PEM_write_bio_PrivateKey(out,pkey,cipher, |
563 | NULL,0,NULL,NULL)) | 617 | NULL,0,NULL,passout)) |
564 | { | 618 | { |
565 | if ((ERR_GET_REASON(ERR_peek_error()) == | 619 | if ((ERR_GET_REASON(ERR_peek_error()) == |
566 | PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) | 620 | PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) |
@@ -677,6 +731,22 @@ loop: | |||
677 | } | 731 | } |
678 | else | 732 | else |
679 | { | 733 | { |
734 | X509V3_CTX ext_ctx; | ||
735 | |||
736 | /* Set up V3 context struct */ | ||
737 | |||
738 | X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); | ||
739 | X509V3_set_conf_lhash(&ext_ctx, req_conf); | ||
740 | |||
741 | /* Add extensions */ | ||
742 | if(req_exts && !X509V3_EXT_REQ_add_conf(req_conf, | ||
743 | &ext_ctx, req_exts, req)) | ||
744 | { | ||
745 | BIO_printf(bio_err, | ||
746 | "Error Loading extension section %s\n", | ||
747 | req_exts); | ||
748 | goto end; | ||
749 | } | ||
680 | if (!(i=X509_REQ_sign(req,pkey,digest))) | 750 | if (!(i=X509_REQ_sign(req,pkey,digest))) |
681 | goto end; | 751 | goto end; |
682 | } | 752 | } |
@@ -767,9 +837,10 @@ loop: | |||
767 | { | 837 | { |
768 | if (outformat == FORMAT_ASN1) | 838 | if (outformat == FORMAT_ASN1) |
769 | i=i2d_X509_REQ_bio(out,req); | 839 | i=i2d_X509_REQ_bio(out,req); |
770 | else if (outformat == FORMAT_PEM) | 840 | else if (outformat == FORMAT_PEM) { |
771 | i=PEM_write_bio_X509_REQ(out,req); | 841 | if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req); |
772 | else { | 842 | else i=PEM_write_bio_X509_REQ(out,req); |
843 | } else { | ||
773 | BIO_printf(bio_err,"bad output format specified for outfile\n"); | 844 | BIO_printf(bio_err,"bad output format specified for outfile\n"); |
774 | goto end; | 845 | goto end; |
775 | } | 846 | } |
@@ -807,7 +878,8 @@ end: | |||
807 | EVP_PKEY_free(pkey); | 878 | EVP_PKEY_free(pkey); |
808 | X509_REQ_free(req); | 879 | X509_REQ_free(req); |
809 | X509_free(x509ss); | 880 | X509_free(x509ss); |
810 | X509V3_EXT_cleanup(); | 881 | if(passin) Free(passin); |
882 | if(passout) Free(passout); | ||
811 | OBJ_cleanup(); | 883 | OBJ_cleanup(); |
812 | #ifndef NO_DSA | 884 | #ifndef NO_DSA |
813 | if (dsa_params != NULL) DSA_free(dsa_params); | 885 | if (dsa_params != NULL) DSA_free(dsa_params); |
@@ -818,43 +890,67 @@ end: | |||
818 | static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) | 890 | static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) |
819 | { | 891 | { |
820 | int ret=0,i; | 892 | int ret=0,i; |
821 | char *p,*q; | 893 | char no_prompt = 0; |
822 | X509_REQ_INFO *ri; | 894 | STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; |
823 | char buf[100]; | 895 | char *tmp, *dn_sect,*attr_sect; |
824 | int nid,min,max; | 896 | |
825 | char *type,*def,*tmp,*value,*tmp_attr; | 897 | tmp=CONF_get_string(req_conf,SECTION,PROMPT); |
826 | STACK_OF(CONF_VALUE) *sk, *attr=NULL; | 898 | if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1; |
827 | CONF_VALUE *v; | 899 | |
828 | 900 | dn_sect=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); | |
829 | tmp=CONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); | 901 | if (dn_sect == NULL) |
830 | if (tmp == NULL) | ||
831 | { | 902 | { |
832 | BIO_printf(bio_err,"unable to find '%s' in config\n", | 903 | BIO_printf(bio_err,"unable to find '%s' in config\n", |
833 | DISTINGUISHED_NAME); | 904 | DISTINGUISHED_NAME); |
834 | goto err; | 905 | goto err; |
835 | } | 906 | } |
836 | sk=CONF_get_section(req_conf,tmp); | 907 | dn_sk=CONF_get_section(req_conf,dn_sect); |
837 | if (sk == NULL) | 908 | if (dn_sk == NULL) |
838 | { | 909 | { |
839 | BIO_printf(bio_err,"unable to get '%s' section\n",tmp); | 910 | BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect); |
840 | goto err; | 911 | goto err; |
841 | } | 912 | } |
842 | 913 | ||
843 | tmp_attr=CONF_get_string(req_conf,SECTION,ATTRIBUTES); | 914 | attr_sect=CONF_get_string(req_conf,SECTION,ATTRIBUTES); |
844 | if (tmp_attr == NULL) | 915 | if (attr_sect == NULL) |
845 | attr=NULL; | 916 | attr_sk=NULL; |
846 | else | 917 | else |
847 | { | 918 | { |
848 | attr=CONF_get_section(req_conf,tmp_attr); | 919 | attr_sk=CONF_get_section(req_conf,attr_sect); |
849 | if (attr == NULL) | 920 | if (attr_sk == NULL) |
850 | { | 921 | { |
851 | BIO_printf(bio_err,"unable to get '%s' section\n",tmp_attr); | 922 | BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect); |
852 | goto err; | 923 | goto err; |
853 | } | 924 | } |
854 | } | 925 | } |
855 | 926 | ||
856 | ri=req->req_info; | 927 | /* setup version number */ |
928 | if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ | ||
929 | |||
930 | if(no_prompt) i = auto_info(req, dn_sk, attr_sk, attribs); | ||
931 | else i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs); | ||
932 | if(!i) goto err; | ||
933 | |||
934 | X509_REQ_set_pubkey(req,pkey); | ||
857 | 935 | ||
936 | ret=1; | ||
937 | err: | ||
938 | return(ret); | ||
939 | } | ||
940 | |||
941 | |||
942 | static int prompt_info(X509_REQ *req, | ||
943 | STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, | ||
944 | STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs) | ||
945 | { | ||
946 | int i; | ||
947 | char *p,*q; | ||
948 | char buf[100]; | ||
949 | int nid,min,max; | ||
950 | char *type,*def,*value; | ||
951 | CONF_VALUE *v; | ||
952 | X509_NAME *subj; | ||
953 | subj = X509_REQ_get_subject_name(req); | ||
858 | BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); | 954 | BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); |
859 | BIO_printf(bio_err,"into your certificate request.\n"); | 955 | BIO_printf(bio_err,"into your certificate request.\n"); |
860 | BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); | 956 | BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); |
@@ -863,18 +959,16 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) | |||
863 | BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); | 959 | BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); |
864 | BIO_printf(bio_err,"-----\n"); | 960 | BIO_printf(bio_err,"-----\n"); |
865 | 961 | ||
866 | /* setup version number */ | ||
867 | if (!ASN1_INTEGER_set(ri->version,0L)) goto err; /* version 1 */ | ||
868 | 962 | ||
869 | if (sk_CONF_VALUE_num(sk)) | 963 | if (sk_CONF_VALUE_num(dn_sk)) |
870 | { | 964 | { |
871 | i= -1; | 965 | i= -1; |
872 | start: for (;;) | 966 | start: for (;;) |
873 | { | 967 | { |
874 | i++; | 968 | i++; |
875 | if (sk_CONF_VALUE_num(sk) <= i) break; | 969 | if (sk_CONF_VALUE_num(dn_sk) <= i) break; |
876 | 970 | ||
877 | v=sk_CONF_VALUE_value(sk,i); | 971 | v=sk_CONF_VALUE_value(dn_sk,i); |
878 | p=q=NULL; | 972 | p=q=NULL; |
879 | type=v->name; | 973 | type=v->name; |
880 | if(!check_end(type,"_min") || !check_end(type,"_max") || | 974 | if(!check_end(type,"_min") || !check_end(type,"_max") || |
@@ -893,32 +987,32 @@ start: for (;;) | |||
893 | /* If OBJ not recognised ignore it */ | 987 | /* If OBJ not recognised ignore it */ |
894 | if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; | 988 | if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; |
895 | sprintf(buf,"%s_default",v->name); | 989 | sprintf(buf,"%s_default",v->name); |
896 | if ((def=CONF_get_string(req_conf,tmp,buf)) == NULL) | 990 | if ((def=CONF_get_string(req_conf,dn_sect,buf)) == NULL) |
897 | def=""; | 991 | def=""; |
898 | 992 | ||
899 | sprintf(buf,"%s_value",v->name); | 993 | sprintf(buf,"%s_value",v->name); |
900 | if ((value=CONF_get_string(req_conf,tmp,buf)) == NULL) | 994 | if ((value=CONF_get_string(req_conf,dn_sect,buf)) == NULL) |
901 | value=NULL; | 995 | value=NULL; |
902 | 996 | ||
903 | sprintf(buf,"%s_min",v->name); | 997 | sprintf(buf,"%s_min",v->name); |
904 | min=(int)CONF_get_number(req_conf,tmp,buf); | 998 | min=(int)CONF_get_number(req_conf,dn_sect,buf); |
905 | 999 | ||
906 | sprintf(buf,"%s_max",v->name); | 1000 | sprintf(buf,"%s_max",v->name); |
907 | max=(int)CONF_get_number(req_conf,tmp,buf); | 1001 | max=(int)CONF_get_number(req_conf,dn_sect,buf); |
908 | 1002 | ||
909 | if (!add_DN_object(ri->subject,v->value,def,value,nid, | 1003 | if (!add_DN_object(subj,v->value,def,value,nid, |
910 | min,max)) | 1004 | min,max)) |
911 | goto err; | 1005 | return 0; |
912 | } | 1006 | } |
913 | if (sk_X509_NAME_ENTRY_num(ri->subject->entries) == 0) | 1007 | if (X509_NAME_entry_count(subj) == 0) |
914 | { | 1008 | { |
915 | BIO_printf(bio_err,"error, no objects specified in config file\n"); | 1009 | BIO_printf(bio_err,"error, no objects specified in config file\n"); |
916 | goto err; | 1010 | return 0; |
917 | } | 1011 | } |
918 | 1012 | ||
919 | if (attribs) | 1013 | if (attribs) |
920 | { | 1014 | { |
921 | if ((attr != NULL) && (sk_CONF_VALUE_num(attr) > 0)) | 1015 | if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)) |
922 | { | 1016 | { |
923 | BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); | 1017 | BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); |
924 | BIO_printf(bio_err,"to be sent with your certificate request\n"); | 1018 | BIO_printf(bio_err,"to be sent with your certificate request\n"); |
@@ -928,57 +1022,101 @@ start: for (;;) | |||
928 | start2: for (;;) | 1022 | start2: for (;;) |
929 | { | 1023 | { |
930 | i++; | 1024 | i++; |
931 | if ((attr == NULL) || | 1025 | if ((attr_sk == NULL) || |
932 | (sk_CONF_VALUE_num(attr) <= i)) | 1026 | (sk_CONF_VALUE_num(attr_sk) <= i)) |
933 | break; | 1027 | break; |
934 | 1028 | ||
935 | v=sk_CONF_VALUE_value(attr,i); | 1029 | v=sk_CONF_VALUE_value(attr_sk,i); |
936 | type=v->name; | 1030 | type=v->name; |
937 | if ((nid=OBJ_txt2nid(type)) == NID_undef) | 1031 | if ((nid=OBJ_txt2nid(type)) == NID_undef) |
938 | goto start2; | 1032 | goto start2; |
939 | 1033 | ||
940 | sprintf(buf,"%s_default",type); | 1034 | sprintf(buf,"%s_default",type); |
941 | if ((def=CONF_get_string(req_conf,tmp_attr,buf)) | 1035 | if ((def=CONF_get_string(req_conf,attr_sect,buf)) |
942 | == NULL) | 1036 | == NULL) |
943 | def=""; | 1037 | def=""; |
944 | 1038 | ||
945 | sprintf(buf,"%s_value",type); | 1039 | sprintf(buf,"%s_value",type); |
946 | if ((value=CONF_get_string(req_conf,tmp_attr,buf)) | 1040 | if ((value=CONF_get_string(req_conf,attr_sect,buf)) |
947 | == NULL) | 1041 | == NULL) |
948 | value=NULL; | 1042 | value=NULL; |
949 | 1043 | ||
950 | sprintf(buf,"%s_min",type); | 1044 | sprintf(buf,"%s_min",type); |
951 | min=(int)CONF_get_number(req_conf,tmp_attr,buf); | 1045 | min=(int)CONF_get_number(req_conf,attr_sect,buf); |
952 | 1046 | ||
953 | sprintf(buf,"%s_max",type); | 1047 | sprintf(buf,"%s_max",type); |
954 | max=(int)CONF_get_number(req_conf,tmp_attr,buf); | 1048 | max=(int)CONF_get_number(req_conf,attr_sect,buf); |
955 | 1049 | ||
956 | if (!add_attribute_object(ri->attributes, | 1050 | if (!add_attribute_object(req, |
957 | v->value,def,value,nid,min,max)) | 1051 | v->value,def,value,nid,min,max)) |
958 | goto err; | 1052 | return 0; |
959 | } | 1053 | } |
960 | } | 1054 | } |
961 | } | 1055 | } |
962 | else | 1056 | else |
963 | { | 1057 | { |
964 | BIO_printf(bio_err,"No template, please set one up.\n"); | 1058 | BIO_printf(bio_err,"No template, please set one up.\n"); |
965 | goto err; | 1059 | return 0; |
966 | } | 1060 | } |
967 | 1061 | ||
968 | X509_REQ_set_pubkey(req,pkey); | 1062 | return 1; |
969 | 1063 | ||
970 | ret=1; | ||
971 | err: | ||
972 | return(ret); | ||
973 | } | 1064 | } |
974 | 1065 | ||
1066 | static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, | ||
1067 | STACK_OF(CONF_VALUE) *attr_sk, int attribs) | ||
1068 | { | ||
1069 | int i; | ||
1070 | char *p,*q; | ||
1071 | char *type; | ||
1072 | CONF_VALUE *v; | ||
1073 | X509_NAME *subj; | ||
1074 | |||
1075 | subj = X509_REQ_get_subject_name(req); | ||
1076 | |||
1077 | for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) | ||
1078 | { | ||
1079 | v=sk_CONF_VALUE_value(dn_sk,i); | ||
1080 | p=q=NULL; | ||
1081 | type=v->name; | ||
1082 | /* Skip past any leading X. X: X, etc to allow for | ||
1083 | * multiple instances | ||
1084 | */ | ||
1085 | for(p = v->name; *p ; p++) | ||
1086 | if ((*p == ':') || (*p == ',') || (*p == '.')) { | ||
1087 | p++; | ||
1088 | if(*p) type = p; | ||
1089 | break; | ||
1090 | } | ||
1091 | if (!X509_NAME_add_entry_by_txt(subj,type, MBSTRING_ASC, | ||
1092 | (unsigned char *) v->value,-1,-1,0)) return 0; | ||
1093 | |||
1094 | } | ||
1095 | |||
1096 | if (!X509_NAME_entry_count(subj)) | ||
1097 | { | ||
1098 | BIO_printf(bio_err,"error, no objects specified in config file\n"); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | if (attribs) | ||
1102 | { | ||
1103 | for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) | ||
1104 | { | ||
1105 | v=sk_CONF_VALUE_value(attr_sk,i); | ||
1106 | if(!X509_REQ_add1_attr_by_txt(req, v->name, MBSTRING_ASC, | ||
1107 | (unsigned char *)v->value, -1)) return 0; | ||
1108 | } | ||
1109 | } | ||
1110 | return 1; | ||
1111 | } | ||
1112 | |||
1113 | |||
975 | static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, | 1114 | static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, |
976 | int nid, int min, int max) | 1115 | int nid, int min, int max) |
977 | { | 1116 | { |
978 | int i,j,ret=0; | 1117 | int i,ret=0; |
979 | X509_NAME_ENTRY *ne=NULL; | ||
980 | MS_STATIC char buf[1024]; | 1118 | MS_STATIC char buf[1024]; |
981 | 1119 | start: | |
982 | BIO_printf(bio_err,"%s [%s]:",text,def); | 1120 | BIO_printf(bio_err,"%s [%s]:",text,def); |
983 | (void)BIO_flush(bio_err); | 1121 | (void)BIO_flush(bio_err); |
984 | if (value != NULL) | 1122 | if (value != NULL) |
@@ -1011,33 +1149,23 @@ static int add_DN_object(X509_NAME *n, char *text, char *def, char *value, | |||
1011 | } | 1149 | } |
1012 | buf[--i]='\0'; | 1150 | buf[--i]='\0'; |
1013 | 1151 | ||
1014 | j=ASN1_PRINTABLE_type((unsigned char *)buf,-1); | ||
1015 | if (req_fix_data(nid,&j,i,min,max) == 0) | ||
1016 | goto err; | ||
1017 | #ifdef CHARSET_EBCDIC | 1152 | #ifdef CHARSET_EBCDIC |
1018 | ebcdic2ascii(buf, buf, i); | 1153 | ebcdic2ascii(buf, buf, i); |
1019 | #endif | 1154 | #endif |
1020 | if ((ne=X509_NAME_ENTRY_create_by_NID(NULL,nid,j,(unsigned char *)buf, | 1155 | if(!req_check_len(i, min, max)) goto start; |
1021 | strlen(buf))) | 1156 | if (!X509_NAME_add_entry_by_NID(n,nid, MBSTRING_ASC, |
1022 | == NULL) goto err; | 1157 | (unsigned char *) buf, -1,-1,0)) goto err; |
1023 | if (!X509_NAME_add_entry(n,ne,X509_NAME_entry_count(n),0)) | ||
1024 | goto err; | ||
1025 | |||
1026 | ret=1; | 1158 | ret=1; |
1027 | err: | 1159 | err: |
1028 | if (ne != NULL) X509_NAME_ENTRY_free(ne); | ||
1029 | return(ret); | 1160 | return(ret); |
1030 | } | 1161 | } |
1031 | 1162 | ||
1032 | static int add_attribute_object(STACK_OF(X509_ATTRIBUTE) *n, char *text, | 1163 | static int add_attribute_object(X509_REQ *req, char *text, |
1033 | char *def, char *value, int nid, int min, | 1164 | char *def, char *value, int nid, int min, |
1034 | int max) | 1165 | int max) |
1035 | { | 1166 | { |
1036 | int i,z; | 1167 | int i; |
1037 | X509_ATTRIBUTE *xa=NULL; | ||
1038 | static char buf[1024]; | 1168 | static char buf[1024]; |
1039 | ASN1_BIT_STRING *bs=NULL; | ||
1040 | ASN1_TYPE *at=NULL; | ||
1041 | 1169 | ||
1042 | start: | 1170 | start: |
1043 | BIO_printf(bio_err,"%s [%s]:",text,def); | 1171 | BIO_printf(bio_err,"%s [%s]:",text,def); |
@@ -1071,50 +1199,21 @@ start: | |||
1071 | return(0); | 1199 | return(0); |
1072 | } | 1200 | } |
1073 | buf[--i]='\0'; | 1201 | buf[--i]='\0'; |
1202 | if(!req_check_len(i, min, max)) goto start; | ||
1074 | 1203 | ||
1075 | /* add object plus value */ | 1204 | if(!X509_REQ_add1_attr_by_NID(req, nid, MBSTRING_ASC, |
1076 | if ((xa=X509_ATTRIBUTE_new()) == NULL) | 1205 | (unsigned char *)buf, -1)) { |
1077 | goto err; | 1206 | BIO_printf(bio_err, "Error adding attribute\n"); |
1078 | if ((xa->value.set=sk_ASN1_TYPE_new_null()) == NULL) | 1207 | ERR_print_errors(bio_err); |
1079 | goto err; | 1208 | goto err; |
1080 | xa->set=1; | 1209 | } |
1081 | |||
1082 | if (xa->object != NULL) ASN1_OBJECT_free(xa->object); | ||
1083 | xa->object=OBJ_nid2obj(nid); | ||
1084 | |||
1085 | if ((bs=ASN1_BIT_STRING_new()) == NULL) goto err; | ||
1086 | |||
1087 | bs->type=ASN1_PRINTABLE_type((unsigned char *)buf,-1); | ||
1088 | |||
1089 | z=req_fix_data(nid,&bs->type,i,min,max); | ||
1090 | if (z == 0) | ||
1091 | { | ||
1092 | if (value == NULL) | ||
1093 | goto start; | ||
1094 | else goto err; | ||
1095 | } | ||
1096 | |||
1097 | if (!ASN1_STRING_set(bs,(unsigned char *)buf,i+1)) | ||
1098 | { BIO_printf(bio_err,"Malloc failure\n"); goto err; } | ||
1099 | |||
1100 | if ((at=ASN1_TYPE_new()) == NULL) | ||
1101 | { BIO_printf(bio_err,"Malloc failure\n"); goto err; } | ||
1102 | |||
1103 | ASN1_TYPE_set(at,bs->type,(char *)bs); | ||
1104 | sk_ASN1_TYPE_push(xa->value.set,at); | ||
1105 | bs=NULL; | ||
1106 | at=NULL; | ||
1107 | /* only one item per attribute */ | ||
1108 | 1210 | ||
1109 | if (!sk_X509_ATTRIBUTE_push(n,xa)) goto err; | ||
1110 | return(1); | 1211 | return(1); |
1111 | err: | 1212 | err: |
1112 | if (xa != NULL) X509_ATTRIBUTE_free(xa); | ||
1113 | if (at != NULL) ASN1_TYPE_free(at); | ||
1114 | if (bs != NULL) ASN1_BIT_STRING_free(bs); | ||
1115 | return(0); | 1213 | return(0); |
1116 | } | 1214 | } |
1117 | 1215 | ||
1216 | #ifndef NO_RSA | ||
1118 | static void MS_CALLBACK req_cb(int p, int n, void *arg) | 1217 | static void MS_CALLBACK req_cb(int p, int n, void *arg) |
1119 | { | 1218 | { |
1120 | char c='*'; | 1219 | char c='*'; |
@@ -1129,26 +1228,10 @@ static void MS_CALLBACK req_cb(int p, int n, void *arg) | |||
1129 | p=n; | 1228 | p=n; |
1130 | #endif | 1229 | #endif |
1131 | } | 1230 | } |
1231 | #endif | ||
1132 | 1232 | ||
1133 | static int req_fix_data(int nid, int *type, int len, int min, int max) | 1233 | static int req_check_len(int len, int min, int max) |
1134 | { | 1234 | { |
1135 | if (nid == NID_pkcs9_emailAddress) | ||
1136 | *type=V_ASN1_IA5STRING; | ||
1137 | if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING)) | ||
1138 | *type=V_ASN1_T61STRING; | ||
1139 | if ((nid == NID_pkcs9_challengePassword) && | ||
1140 | (*type == V_ASN1_IA5STRING)) | ||
1141 | *type=V_ASN1_T61STRING; | ||
1142 | |||
1143 | if ((nid == NID_pkcs9_unstructuredName) && | ||
1144 | (*type == V_ASN1_T61STRING)) | ||
1145 | { | ||
1146 | BIO_printf(bio_err,"invalid characters in string, please re-enter the string\n"); | ||
1147 | return(0); | ||
1148 | } | ||
1149 | if (nid == NID_pkcs9_unstructuredName) | ||
1150 | *type=V_ASN1_IA5STRING; | ||
1151 | |||
1152 | if (len < min) | 1235 | if (len < min) |
1153 | { | 1236 | { |
1154 | BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",min); | 1237 | BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",min); |