2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
67 #include <openssl/bio.h>
68 #include <openssl/evp.h>
69 #include <openssl/rand.h>
70 #include <openssl/conf.h>
71 #include <openssl/err.h>
72 #include <openssl/asn1.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 #include <openssl/objects.h>
76 #include <openssl/pem.h>
80 #define BITS "default_bits"
81 #define KEYFILE "default_keyfile"
82 #define DISTINGUISHED_NAME "distinguished_name"
83 #define ATTRIBUTES "attributes"
84 #define V3_EXTENSIONS "x509_extensions"
86 #define DEFAULT_KEY_LENGTH 512
87 #define MIN_KEY_LENGTH 384
92 /* -inform arg - input format - default PEM (one of DER, TXT or PEM)
93 * -outform arg - output format - default PEM
94 * -in arg - input file - default stdin
95 * -out arg - output file - default stdout
96 * -verify - check request signature
97 * -noout - don't print stuff out.
98 * -text - print out human readable text.
99 * -nodes - no des encryption
100 * -config file - Load configuration file.
101 * -key file - make a request using key in file (or use it for verification).
102 * -keyform - key file format.
103 * -newkey - make a key and a request.
104 * -modulus - print RSA modulus.
105 * -x509 - output a self signed X509 structure instead.
106 * -asn1-kludge - output new certificate request in a format that some CA's
107 * require. This format is wrong
110 static int make_REQ(X509_REQ
*req
,EVP_PKEY
*pkey
,int attribs
);
111 static int add_attribute_object(STACK
*n
, char *text
, char *def
,
112 char *value
, int nid
,int min
,int max
);
113 static int add_DN_object(X509_NAME
*n
, char *text
, char *def
, char *value
,
114 int nid
,int min
,int max
);
115 static void MS_CALLBACK
req_cb(int p
,int n
,char *arg
);
116 static int req_fix_data(int nid
,int *type
,int len
,int min
,int max
);
117 static int check_end(char *str
, char *end
);
118 static int add_oid_section(LHASH
*conf
);
120 static char *default_config_file
=NULL
;
121 static LHASH
*config
=NULL
;
123 static LHASH
*req_conf
=NULL
;
129 int MAIN(int argc
, char **argv
)
132 DSA
*dsa_params
=NULL
;
134 int ex
=1,x509
=0,days
=30;
138 int i
,badops
=0,newreq
=0,newkey
= -1,pkey_type
=0;
139 BIO
*in
=NULL
,*out
=NULL
;
140 int informat
,outformat
,verify
=0,noout
=0,text
=0,keyform
=FORMAT_PEM
;
141 int nodes
=0,kludge
=0;
142 char *infile
,*outfile
,*prog
,*keyfile
=NULL
,*template=NULL
,*keyout
=NULL
;
143 char *extensions
= NULL
;
144 EVP_CIPHER
*cipher
=NULL
;
147 const EVP_MD
*md_alg
=NULL
,*digest
=EVP_md5();
149 MS_STATIC
char config_name
[256];
153 cipher
=EVP_des_ede3_cbc();
158 if ((bio_err
=BIO_new(BIO_s_file())) != NULL
)
159 BIO_set_fp(bio_err
,stderr
,BIO_NOCLOSE
|BIO_FP_TEXT
);
164 outformat
=FORMAT_PEM
;
171 if (strcmp(*argv
,"-inform") == 0)
173 if (--argc
< 1) goto bad
;
174 informat
=str2fmt(*(++argv
));
176 else if (strcmp(*argv
,"-outform") == 0)
178 if (--argc
< 1) goto bad
;
179 outformat
=str2fmt(*(++argv
));
181 else if (strcmp(*argv
,"-key") == 0)
183 if (--argc
< 1) goto bad
;
186 else if (strcmp(*argv
,"-new") == 0)
191 else if (strcmp(*argv
,"-config") == 0)
193 if (--argc
< 1) goto bad
;
196 else if (strcmp(*argv
,"-keyform") == 0)
198 if (--argc
< 1) goto bad
;
199 keyform
=str2fmt(*(++argv
));
201 else if (strcmp(*argv
,"-in") == 0)
203 if (--argc
< 1) goto bad
;
206 else if (strcmp(*argv
,"-out") == 0)
208 if (--argc
< 1) goto bad
;
211 else if (strcmp(*argv
,"-keyout") == 0)
213 if (--argc
< 1) goto bad
;
216 else if (strcmp(*argv
,"-newkey") == 0)
220 if (--argc
< 1) goto bad
;
222 is_numeric
= p
[0] >= '0' && p
[0] <= '9';
223 if (strncmp("rsa:",p
,4) == 0 || is_numeric
)
232 if (strncmp("dsa:",p
,4) == 0)
239 if ((in
=BIO_new_file(p
,"r")) == NULL
)
244 if ((dsa_params
=PEM_read_bio_DSAparams(in
,NULL
,NULL
)) == NULL
)
248 if ((xtmp
=PEM_read_bio_X509(in
,NULL
,NULL
)) == NULL
)
250 BIO_printf(bio_err
,"unable to load DSA parameters from file\n");
254 dtmp
=X509_get_pubkey(xtmp
);
255 if (dtmp
->type
== EVP_PKEY_DSA
)
256 dsa_params
=DSAparams_dup(dtmp
->pkey
.dsa
);
259 if (dsa_params
== NULL
)
261 BIO_printf(bio_err
,"Certificate does not contain DSA parameters\n");
266 newkey
=BN_num_bits(dsa_params
->p
);
272 if (strncmp("dh:",p
,4) == 0)
283 else if (strcmp(*argv
,"-modulus") == 0)
285 else if (strcmp(*argv
,"-verify") == 0)
287 else if (strcmp(*argv
,"-nodes") == 0)
289 else if (strcmp(*argv
,"-noout") == 0)
291 else if (strcmp(*argv
,"-text") == 0)
293 else if (strcmp(*argv
,"-x509") == 0)
295 else if (strcmp(*argv
,"-asn1-kludge") == 0)
297 else if (strcmp(*argv
,"-no-asn1-kludge") == 0)
299 else if (strcmp(*argv
,"-days") == 0)
301 if (--argc
< 1) goto bad
;
302 days
= atoi(*(++argv
));
303 if (days
== 0) days
=30;
305 else if ((md_alg
=EVP_get_digestbyname(&((*argv
)[1]))) != NULL
)
313 BIO_printf(bio_err
,"unknown option %s\n",*argv
);
324 BIO_printf(bio_err
,"%s [options] <infile >outfile\n",prog
);
325 BIO_printf(bio_err
,"where options are\n");
326 BIO_printf(bio_err
," -inform arg input format - one of DER TXT PEM\n");
327 BIO_printf(bio_err
," -outform arg output format - one of DER TXT PEM\n");
328 BIO_printf(bio_err
," -in arg input file\n");
329 BIO_printf(bio_err
," -out arg output file\n");
330 BIO_printf(bio_err
," -text text form of request\n");
331 BIO_printf(bio_err
," -noout do not output REQ\n");
332 BIO_printf(bio_err
," -verify verify signature on REQ\n");
333 BIO_printf(bio_err
," -modulus RSA modulus\n");
334 BIO_printf(bio_err
," -nodes don't encrypt the output key\n");
335 BIO_printf(bio_err
," -key file use the private key contained in file\n");
336 BIO_printf(bio_err
," -keyform arg key file format\n");
337 BIO_printf(bio_err
," -keyout arg file to send the key to\n");
338 BIO_printf(bio_err
," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
339 BIO_printf(bio_err
," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
341 BIO_printf(bio_err
," -[digest] Digest to sign with (md5, sha1, md2, mdc2)\n");
342 BIO_printf(bio_err
," -config file request template file.\n");
343 BIO_printf(bio_err
," -new new request.\n");
344 BIO_printf(bio_err
," -x509 output a x509 structure instead of a cert. req.\n");
345 BIO_printf(bio_err
," -days number of days a x509 generated by -x509 is valid for.\n");
346 BIO_printf(bio_err
," -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n");
347 BIO_printf(bio_err
," have been reported as requiring\n");
348 BIO_printf(bio_err
," [ It is now always turned on but can be turned off with -no-asn1-kludge ]\n");
352 ERR_load_crypto_strings();
353 X509V3_add_standard_extensions();
356 /* Lets load up our environment a little */
357 p
=getenv("OPENSSL_CONF");
359 p
=getenv("SSLEAY_CONF");
362 strcpy(config_name
,X509_get_default_cert_area());
363 strcat(config_name
,"/lib/");
364 strcat(config_name
,OPENSSL_CONF
);
367 default_config_file
=p
;
368 config
=CONF_load(config
,p
,NULL
);
371 if (template != NULL
)
375 BIO_printf(bio_err
,"Using configuration from %s\n",template);
376 req_conf
=CONF_load(NULL
,template,&errline
);
377 if (req_conf
== NULL
)
379 BIO_printf(bio_err
,"error on line %ld of %s\n",errline
,template);
386 BIO_printf(bio_err
,"Using configuration from %s\n",
387 default_config_file
);
388 if (req_conf
== NULL
)
390 BIO_printf(bio_err
,"Unable to load config info\n");
394 if (req_conf
!= NULL
)
396 p
=CONF_get_string(req_conf
,NULL
,"oid_file");
401 oid_bio
=BIO_new_file(p
,"r");
405 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
406 ERR_print_errors(bio_err);
411 OBJ_create_objects(oid_bio
);
416 if(!add_oid_section(req_conf
)) goto end
;
418 if ((md_alg
== NULL
) &&
419 ((p
=CONF_get_string(req_conf
,SECTION
,"default_md")) != NULL
))
421 if ((md_alg
=EVP_get_digestbyname(p
)) != NULL
)
425 extensions
= CONF_get_string(req_conf
, SECTION
, V3_EXTENSIONS
);
427 /* Check syntax of file */
429 X509V3_set_ctx_test(&ctx
);
430 X509V3_set_conf_lhash(&ctx
, req_conf
);
431 if(!X509V3_EXT_add_conf(req_conf
, &ctx
, extensions
, NULL
)) {
433 "Error Loading extension section %s\n", extensions
);
438 in
=BIO_new(BIO_s_file());
439 out
=BIO_new(BIO_s_file());
440 if ((in
== NULL
) || (out
== NULL
))
445 if (BIO_read_filename(in
,keyfile
) <= 0)
451 /* if (keyform == FORMAT_ASN1)
452 rsa=d2i_RSAPrivateKey_bio(in,NULL);
454 if (keyform
== FORMAT_PEM
)
455 pkey
=PEM_read_bio_PrivateKey(in
,NULL
,NULL
);
458 BIO_printf(bio_err
,"bad input format specified for X509 request\n");
464 BIO_printf(bio_err
,"unable to load Private key\n");
469 if (newreq
&& (pkey
== NULL
))
474 if ((randfile
=CONF_get_string(req_conf
,SECTION
,"RANDFILE")) == NULL
)
475 randfile
=RAND_file_name(buffer
,200);
477 BIO_printf(bio_err
,"Loading 'screen' into random state -");
480 BIO_printf(bio_err
," done\n");
482 if ((randfile
== NULL
) || !RAND_load_file(randfile
,1024L*1024L))
484 BIO_printf(bio_err
,"unable to load 'random state'\n");
485 BIO_printf(bio_err
,"What this means is that the random number generator has not been seeded\n");
486 BIO_printf(bio_err
,"with much random data.\n");
487 BIO_printf(bio_err
,"Consider setting the RANDFILE environment variable to point at a file that\n");
488 BIO_printf(bio_err
,"'random' data can be kept in.\n");
492 newkey
=(int)CONF_get_number(req_conf
,SECTION
,BITS
);
494 newkey
=DEFAULT_KEY_LENGTH
;
497 if (newkey
< MIN_KEY_LENGTH
)
499 BIO_printf(bio_err
,"private key length is too short,\n");
500 BIO_printf(bio_err
,"it needs to be at least %d bits, not %d\n",MIN_KEY_LENGTH
,newkey
);
503 BIO_printf(bio_err
,"Generating a %d bit %s private key\n",
504 newkey
,(pkey_type
== TYPE_RSA
)?"RSA":"DSA");
506 if ((pkey
=EVP_PKEY_new()) == NULL
) goto end
;
509 if (pkey_type
== TYPE_RSA
)
511 if (!EVP_PKEY_assign_RSA(pkey
,
512 RSA_generate_key(newkey
,0x10001,
513 req_cb
,(char *)bio_err
)))
519 if (pkey_type
== TYPE_DSA
)
521 if (!DSA_generate_key(dsa_params
)) goto end
;
522 if (!EVP_PKEY_assign_DSA(pkey
,dsa_params
)) goto end
;
527 if ((randfile
== NULL
) || (RAND_write_file(randfile
) == 0))
528 BIO_printf(bio_err
,"unable to write 'random state'\n");
530 if (pkey
== NULL
) goto end
;
533 keyout
=CONF_get_string(req_conf
,SECTION
,KEYFILE
);
537 BIO_printf(bio_err
,"writing new private key to stdout\n");
538 BIO_set_fp(out
,stdout
,BIO_NOCLOSE
);
542 BIO_printf(bio_err
,"writing new private key to '%s'\n",keyout
);
543 if (BIO_write_filename(out
,keyout
) <= 0)
550 p
=CONF_get_string(req_conf
,SECTION
,"encrypt_rsa_key");
552 p
=CONF_get_string(req_conf
,SECTION
,"encrypt_key");
553 if ((p
!= NULL
) && (strcmp(p
,"no") == 0))
555 if (nodes
) cipher
=NULL
;
559 if (!PEM_write_bio_PrivateKey(out
,pkey
,cipher
,
562 if ((ERR_GET_REASON(ERR_peek_error()) ==
563 PEM_R_PROBLEMS_GETTING_PASSWORD
) && (i
< 3))
571 BIO_printf(bio_err
,"-----\n");
576 /* Since we are using a pre-existing certificate
577 * request, the kludge 'format' info should not be
581 BIO_set_fp(in
,stdin
,BIO_NOCLOSE
);
584 if (BIO_read_filename(in
,infile
) <= 0)
591 if (informat
== FORMAT_ASN1
)
592 req
=d2i_X509_REQ_bio(in
,NULL
);
593 else if (informat
== FORMAT_PEM
)
594 req
=PEM_read_bio_X509_REQ(in
,NULL
,NULL
);
597 BIO_printf(bio_err
,"bad input format specified for X509 request\n");
602 BIO_printf(bio_err
,"unable to load X509 request\n");
610 if (pkey
->type
== EVP_PKEY_DSA
)
616 BIO_printf(bio_err
,"you need to specify a private key\n");
627 i
=make_REQ(req
,pkey
,!x509
);
629 req
->req_info
->req_kludge
=kludge
;
632 BIO_printf(bio_err
,"problems making Certificate Request\n");
640 if ((x509ss
=X509_new()) == NULL
) goto end
;
642 /* Set version to V3 */
643 if(!X509_set_version(x509ss
, 2)) goto end
;
644 ASN1_INTEGER_set(X509_get_serialNumber(x509ss
),0L);
646 X509_set_issuer_name(x509ss
,
647 X509_REQ_get_subject_name(req
));
648 X509_gmtime_adj(X509_get_notBefore(x509ss
),0);
649 X509_gmtime_adj(X509_get_notAfter(x509ss
),
650 (long)60*60*24*days
);
651 X509_set_subject_name(x509ss
,
652 X509_REQ_get_subject_name(req
));
653 tmppkey
= X509_REQ_get_pubkey(req
);
654 X509_set_pubkey(x509ss
,tmppkey
);
655 EVP_PKEY_free(tmppkey
);
657 /* Set up V3 context struct */
659 X509V3_set_ctx(&ext_ctx
, x509ss
, x509ss
, NULL
, NULL
, 0);
660 X509V3_set_conf_lhash(&ext_ctx
, req_conf
);
663 if(extensions
&& !X509V3_EXT_add_conf(req_conf
,
664 &ext_ctx
, extensions
, x509ss
))
667 "Error Loading extension section %s\n",
672 if (!(i
=X509_sign(x509ss
,pkey
,digest
)))
677 if (!(i
=X509_REQ_sign(req
,pkey
,digest
)))
688 pkey
=X509_REQ_get_pubkey(req
);
690 if (pkey
== NULL
) goto end
;
693 i
=X509_REQ_verify(req
,pkey
);
705 BIO_printf(bio_err
,"verify failure\n");
707 else /* if (i > 0) */
708 BIO_printf(bio_err
,"verify OK\n");
711 if (noout
&& !text
&& !modulus
)
718 BIO_set_fp(out
,stdout
,BIO_NOCLOSE
);
721 if ((keyout
!= NULL
) && (strcmp(outfile
,keyout
) == 0))
722 i
=(int)BIO_append_filename(out
,outfile
);
724 i
=(int)BIO_write_filename(out
,outfile
);
735 X509_print(out
,x509ss
);
737 X509_REQ_print(out
,req
);
745 pubkey
=X509_get_pubkey(x509ss
);
747 pubkey
=X509_REQ_get_pubkey(req
);
750 fprintf(stdout
,"Modulus=unavailable\n");
753 fprintf(stdout
,"Modulus=");
755 if (pubkey
->type
== EVP_PKEY_RSA
)
756 BN_print(out
,pubkey
->pkey
.rsa
->n
);
759 fprintf(stdout
,"Wrong Algorithm type");
760 fprintf(stdout
,"\n");
765 if (outformat
== FORMAT_ASN1
)
766 i
=i2d_X509_REQ_bio(out
,req
);
767 else if (outformat
== FORMAT_PEM
)
768 i
=PEM_write_bio_X509_REQ(out
,req
);
770 BIO_printf(bio_err
,"bad output format specified for outfile\n");
775 BIO_printf(bio_err
,"unable to write X509 request\n");
779 if (!noout
&& x509
&& (x509ss
!= NULL
))
781 if (outformat
== FORMAT_ASN1
)
782 i
=i2d_X509_bio(out
,x509ss
);
783 else if (outformat
== FORMAT_PEM
)
784 i
=PEM_write_bio_X509(out
,x509ss
);
786 BIO_printf(bio_err
,"bad output format specified for outfile\n");
791 BIO_printf(bio_err
,"unable to write X509 certificate\n");
799 ERR_print_errors(bio_err
);
801 if ((req_conf
!= NULL
) && (req_conf
!= config
)) CONF_free(req_conf
);
807 X509V3_EXT_cleanup();
810 if (dsa_params
!= NULL
) DSA_free(dsa_params
);
815 static int make_REQ(X509_REQ
*req
, EVP_PKEY
*pkey
, int attribs
)
822 char *type
,*def
,*tmp
,*value
,*tmp_attr
;
823 STACK
*sk
,*attr
=NULL
;
826 tmp
=CONF_get_string(req_conf
,SECTION
,DISTINGUISHED_NAME
);
829 BIO_printf(bio_err
,"unable to find '%s' in config\n",
833 sk
=CONF_get_section(req_conf
,tmp
);
836 BIO_printf(bio_err
,"unable to get '%s' section\n",tmp
);
840 tmp_attr
=CONF_get_string(req_conf
,SECTION
,ATTRIBUTES
);
841 if (tmp_attr
== NULL
)
845 attr
=CONF_get_section(req_conf
,tmp_attr
);
848 BIO_printf(bio_err
,"unable to get '%s' section\n",tmp_attr
);
855 BIO_printf(bio_err
,"You are about to be asked to enter information that will be incorporated\n");
856 BIO_printf(bio_err
,"into your certificate request.\n");
857 BIO_printf(bio_err
,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
858 BIO_printf(bio_err
,"There are quite a few fields but you can leave some blank\n");
859 BIO_printf(bio_err
,"For some fields there will be a default value,\n");
860 BIO_printf(bio_err
,"If you enter '.', the field will be left blank.\n");
861 BIO_printf(bio_err
,"-----\n");
863 /* setup version number */
864 if (!ASN1_INTEGER_set(ri
->version
,0L)) goto err
; /* version 1 */
872 if ((int)sk_num(sk
) <= i
) break;
874 v
=(CONF_VALUE
*)sk_value(sk
,i
);
877 if(!check_end(type
,"_min") || !check_end(type
,"_max") ||
878 !check_end(type
,"_default") ||
879 !check_end(type
,"_value")) continue;
880 /* Skip past any leading X. X: X, etc to allow for
883 for(p
= v
->name
; *p
; p
++)
884 if ((*p
== ':') || (*p
== ',') ||
890 /* If OBJ not recognised ignore it */
891 if ((nid
=OBJ_txt2nid(type
)) == NID_undef
) goto start
;
892 sprintf(buf
,"%s_default",v
->name
);
893 if ((def
=CONF_get_string(req_conf
,tmp
,buf
)) == NULL
)
896 sprintf(buf
,"%s_value",v
->name
);
897 if ((value
=CONF_get_string(req_conf
,tmp
,buf
)) == NULL
)
900 sprintf(buf
,"%s_min",v
->name
);
901 min
=(int)CONF_get_number(req_conf
,tmp
,buf
);
903 sprintf(buf
,"%s_max",v
->name
);
904 max
=(int)CONF_get_number(req_conf
,tmp
,buf
);
906 if (!add_DN_object(ri
->subject
,v
->value
,def
,value
,nid
,
910 if (sk_X509_NAME_ENTRY_num(ri
->subject
->entries
) == 0)
912 BIO_printf(bio_err
,"error, no objects specified in config file\n");
918 if ((attr
!= NULL
) && (sk_num(attr
) > 0))
920 BIO_printf(bio_err
,"\nPlease enter the following 'extra' attributes\n");
921 BIO_printf(bio_err
,"to be sent with your certificate request\n");
928 if ((attr
== NULL
) || ((int)sk_num(attr
) <= i
))
931 v
=(CONF_VALUE
*)sk_value(attr
,i
);
933 if ((nid
=OBJ_txt2nid(type
)) == NID_undef
)
936 sprintf(buf
,"%s_default",type
);
937 if ((def
=CONF_get_string(req_conf
,tmp_attr
,buf
))
941 sprintf(buf
,"%s_value",type
);
942 if ((value
=CONF_get_string(req_conf
,tmp_attr
,buf
))
946 sprintf(buf
,"%s_min",type
);
947 min
=(int)CONF_get_number(req_conf
,tmp_attr
,buf
);
949 sprintf(buf
,"%s_max",type
);
950 max
=(int)CONF_get_number(req_conf
,tmp_attr
,buf
);
952 if (!add_attribute_object(ri
->attributes
,
953 v
->value
,def
,value
,nid
,min
,max
))
960 BIO_printf(bio_err
,"No template, please set one up.\n");
964 X509_REQ_set_pubkey(req
,pkey
);
971 static int add_DN_object(X509_NAME
*n
, char *text
, char *def
, char *value
,
972 int nid
, int min
, int max
)
975 X509_NAME_ENTRY
*ne
=NULL
;
976 MS_STATIC
char buf
[1024];
978 BIO_printf(bio_err
,"%s [%s]:",text
,def
);
984 BIO_printf(bio_err
,"%s\n",value
);
989 fgets(buf
,1024,stdin
);
992 if (buf
[0] == '\0') return(0);
993 else if (buf
[0] == '\n')
995 if ((def
== NULL
) || (def
[0] == '\0'))
1000 else if ((buf
[0] == '.') && (buf
[1] == '\n')) return(1);
1003 if (buf
[i
-1] != '\n')
1005 BIO_printf(bio_err
,"weird input :-(\n");
1010 j
=ASN1_PRINTABLE_type((unsigned char *)buf
,-1);
1011 if (req_fix_data(nid
,&j
,i
,min
,max
) == 0)
1013 if ((ne
=X509_NAME_ENTRY_create_by_NID(NULL
,nid
,j
,(unsigned char *)buf
,
1016 if (!X509_NAME_add_entry(n
,ne
,X509_NAME_entry_count(n
),0))
1021 if (ne
!= NULL
) X509_NAME_ENTRY_free(ne
);
1025 static int add_attribute_object(STACK
*n
, char *text
, char *def
, char *value
,
1026 int nid
, int min
, int max
)
1029 X509_ATTRIBUTE
*xa
=NULL
;
1030 static char buf
[1024];
1031 ASN1_BIT_STRING
*bs
=NULL
;
1035 BIO_printf(bio_err
,"%s [%s]:",text
,def
);
1041 BIO_printf(bio_err
,"%s\n",value
);
1046 fgets(buf
,1024,stdin
);
1049 if (buf
[0] == '\0') return(0);
1050 else if (buf
[0] == '\n')
1052 if ((def
== NULL
) || (def
[0] == '\0'))
1057 else if ((buf
[0] == '.') && (buf
[1] == '\n')) return(1);
1060 if (buf
[i
-1] != '\n')
1062 BIO_printf(bio_err
,"weird input :-(\n");
1067 /* add object plus value */
1068 if ((xa
=X509_ATTRIBUTE_new()) == NULL
)
1070 if ((xa
->value
.set
=sk_new_null()) == NULL
)
1074 if (xa
->object
!= NULL
) ASN1_OBJECT_free(xa
->object
);
1075 xa
->object
=OBJ_nid2obj(nid
);
1077 if ((bs
=ASN1_BIT_STRING_new()) == NULL
) goto err
;
1079 bs
->type
=ASN1_PRINTABLE_type((unsigned char *)buf
,-1);
1081 z
=req_fix_data(nid
,&bs
->type
,i
,min
,max
);
1089 if (!ASN1_STRING_set(bs
,(unsigned char *)buf
,i
+1))
1090 { BIO_printf(bio_err
,"Malloc failure\n"); goto err
; }
1092 if ((at
=ASN1_TYPE_new()) == NULL
)
1093 { BIO_printf(bio_err
,"Malloc failure\n"); goto err
; }
1095 ASN1_TYPE_set(at
,bs
->type
,(char *)bs
);
1096 sk_push(xa
->value
.set
,(char *)at
);
1099 /* only one item per attribute */
1101 if (!sk_push(n
,(char *)xa
)) goto err
;
1104 if (xa
!= NULL
) X509_ATTRIBUTE_free(xa
);
1105 if (at
!= NULL
) ASN1_TYPE_free(at
);
1106 if (bs
!= NULL
) ASN1_BIT_STRING_free(bs
);
1110 static void MS_CALLBACK
req_cb(int p
, int n
, char *arg
)
1118 BIO_write((BIO
*)arg
,&c
,1);
1119 BIO_flush((BIO
*)arg
);
1125 static int req_fix_data(int nid
, int *type
, int len
, int min
, int max
)
1127 if (nid
== NID_pkcs9_emailAddress
)
1128 *type
=V_ASN1_IA5STRING
;
1129 if ((nid
== NID_commonName
) && (*type
== V_ASN1_IA5STRING
))
1130 *type
=V_ASN1_T61STRING
;
1131 if ((nid
== NID_pkcs9_challengePassword
) &&
1132 (*type
== V_ASN1_IA5STRING
))
1133 *type
=V_ASN1_T61STRING
;
1135 if ((nid
== NID_pkcs9_unstructuredName
) &&
1136 (*type
== V_ASN1_T61STRING
))
1138 BIO_printf(bio_err
,"invalid characters in string, please re-enter the string\n");
1141 if (nid
== NID_pkcs9_unstructuredName
)
1142 *type
=V_ASN1_IA5STRING
;
1146 BIO_printf(bio_err
,"string is too short, it needs to be at least %d bytes long\n",min
);
1149 if ((max
!= 0) && (len
> max
))
1151 BIO_printf(bio_err
,"string is too long, it needs to be less than %d bytes long\n",max
);
1157 /* Check if the end of a string matches 'end' */
1158 static int check_end(char *str
, char *end
)
1164 if(elen
> slen
) return 1;
1165 tmp
= str
+ slen
- elen
;
1166 return strcmp(tmp
, end
);
1169 static int add_oid_section(LHASH
*conf
)
1175 if(!(p
=CONF_get_string(conf
,NULL
,"oid_section"))) return 1;
1176 if(!(sktmp
= CONF_get_section(conf
, p
))) {
1177 BIO_printf(bio_err
, "problem loading oid section %s\n", p
);
1180 for(i
= 0; i
< sk_num(sktmp
); i
++) {
1181 cnf
= (CONF_VALUE
*)sk_value(sktmp
, i
);
1182 if(OBJ_create(cnf
->value
, cnf
->name
, cnf
->name
) == NID_undef
) {
1183 BIO_printf(bio_err
, "problem creating object %s=%s\n",
1184 cnf
->name
, cnf
->value
);