Run util/openssl-format-source -v -c .
[openssl.git] / apps / x509.c
1 /* apps/x509.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
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.
8  *
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).
15  *
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.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
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)"
40  *
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
51  * SUCH DAMAGE.
52  *
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.]
57  */
58
59 #include <assert.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #ifdef OPENSSL_NO_STDIO
64 # define APPS_WIN16
65 #endif
66 #include "apps.h"
67 #include <openssl/bio.h>
68 #include <openssl/asn1.h>
69 #include <openssl/err.h>
70 #include <openssl/bn.h>
71 #include <openssl/evp.h>
72 #include <openssl/x509.h>
73 #include <openssl/x509v3.h>
74 #include <openssl/objects.h>
75 #include <openssl/pem.h>
76 #ifndef OPENSSL_NO_RSA
77 # include <openssl/rsa.h>
78 #endif
79 #ifndef OPENSSL_NO_DSA
80 # include <openssl/dsa.h>
81 #endif
82
83 #undef PROG
84 #define PROG x509_main
85
86 #undef POSTFIX
87 #define POSTFIX ".srl"
88 #define DEF_DAYS        30
89
90 static const char *x509_usage[] = {
91     "usage: x509 args\n",
92     " -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
93     " -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
94     " -keyform arg    - private key format - default PEM\n",
95     " -CAform arg     - CA format - default PEM\n",
96     " -CAkeyform arg  - CA key format - default PEM\n",
97     " -in arg         - input file - default stdin\n",
98     " -out arg        - output file - default stdout\n",
99     " -passin arg     - private key password source\n",
100     " -serial         - print serial number value\n",
101     " -subject_hash   - print subject hash value\n",
102     " -issuer_hash    - print issuer hash value\n",
103     " -hash           - synonym for -subject_hash\n",
104     " -subject        - print subject DN\n",
105     " -issuer         - print issuer DN\n",
106     " -email          - print email address(es)\n",
107     " -startdate      - notBefore field\n",
108     " -enddate        - notAfter field\n",
109     " -purpose        - print out certificate purposes\n",
110     " -dates          - both Before and After dates\n",
111     " -modulus        - print the RSA key modulus\n",
112     " -pubkey         - output the public key\n",
113     " -fingerprint    - print the certificate fingerprint\n",
114     " -alias          - output certificate alias\n",
115     " -noout          - no certificate output\n",
116     " -ocspid         - print OCSP hash values for the subject name and public key\n",
117     " -ocsp_uri       - print OCSP Responder URL(s)\n",
118     " -trustout       - output a \"trusted\" certificate\n",
119     " -clrtrust       - clear all trusted purposes\n",
120     " -clrreject      - clear all rejected purposes\n",
121     " -addtrust arg   - trust certificate for a given purpose\n",
122     " -addreject arg  - reject certificate for a given purpose\n",
123     " -setalias arg   - set certificate alias\n",
124     " -days arg       - How long till expiry of a signed certificate - def 30 days\n",
125     " -checkend arg   - check whether the cert expires in the next arg seconds\n",
126     "                   exit 1 if so, 0 if not\n",
127     " -signkey arg    - self sign cert with arg\n",
128     " -x509toreq      - output a certification request object\n",
129     " -req            - input is a certificate request, sign and output.\n",
130     " -CA arg         - set the CA certificate, must be PEM format.\n",
131     " -CAkey arg      - set the CA key, must be PEM format\n",
132     "                   missing, it is assumed to be in the CA file.\n",
133     " -CAcreateserial - create serial number file if it does not exist\n",
134     " -CAserial arg   - serial file\n",
135     " -set_serial     - serial number to use\n",
136     " -text           - print the certificate in text form\n",
137     " -C              - print out C code forms\n",
138     " -md2/-md5/-sha1/-mdc2 - digest to use\n",
139     " -extfile        - configuration file with X509V3 extensions to add\n",
140     " -extensions     - section from config file with X509V3 extensions to add\n",
141     " -clrext         - delete extensions before signing and input certificate\n",
142     " -nameopt arg    - various certificate name options\n",
143 #ifndef OPENSSL_NO_ENGINE
144     " -engine e       - use engine e, possibly a hardware device.\n",
145 #endif
146     " -certopt arg    - various certificate text options\n",
147     NULL
148 };
149
150 static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
151 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
152                 const EVP_MD *digest, CONF *conf, char *section);
153 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
154                         X509 *x, X509 *xca, EVP_PKEY *pkey, char *serial,
155                         int create, int days, int clrext, CONF *conf,
156                         char *section, ASN1_INTEGER *sno);
157 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
158 static int reqfile = 0;
159
160 int MAIN(int, char **);
161
162 int MAIN(int argc, char **argv)
163 {
164     ENGINE *e = NULL;
165     int ret = 1;
166     X509_REQ *req = NULL;
167     X509 *x = NULL, *xca = NULL;
168     ASN1_OBJECT *objtmp;
169     EVP_PKEY *Upkey = NULL, *CApkey = NULL;
170     ASN1_INTEGER *sno = NULL;
171     int i, num, badops = 0;
172     BIO *out = NULL;
173     BIO *STDout = NULL;
174     STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
175     int informat, outformat, keyformat, CAformat, CAkeyformat;
176     char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
177     char *CAkeyfile = NULL, *CAserial = NULL;
178     char *alias = NULL;
179     int text = 0, serial = 0, subject = 0, issuer = 0, startdate =
180         0, enddate = 0;
181     int next_serial = 0;
182     int subject_hash = 0, issuer_hash = 0, ocspid = 0;
183     int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
184     int ocsp_uri = 0;
185     int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
186     int C = 0;
187     int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0;
188     int pprint = 0;
189     const char **pp;
190     X509_STORE *ctx = NULL;
191     X509_REQ *rq = NULL;
192     int fingerprint = 0;
193     char buf[256];
194     const EVP_MD *md_alg, *digest = EVP_sha1();
195     CONF *extconf = NULL;
196     char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
197     int need_rand = 0;
198     int checkend = 0, checkoffset = 0;
199     unsigned long nmflag = 0, certflag = 0;
200 #ifndef OPENSSL_NO_ENGINE
201     char *engine = NULL;
202 #endif
203
204     reqfile = 0;
205
206     apps_startup();
207
208     if (bio_err == NULL)
209         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
210
211     if (!load_config(bio_err, NULL))
212         goto end;
213     STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
214 #ifdef OPENSSL_SYS_VMS
215     {
216         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
217         STDout = BIO_push(tmpbio, STDout);
218     }
219 #endif
220
221     informat = FORMAT_PEM;
222     outformat = FORMAT_PEM;
223     keyformat = FORMAT_PEM;
224     CAformat = FORMAT_PEM;
225     CAkeyformat = FORMAT_PEM;
226
227     ctx = X509_STORE_new();
228     if (ctx == NULL)
229         goto end;
230     X509_STORE_set_verify_cb_func(ctx, callb);
231
232     argc--;
233     argv++;
234     num = 0;
235     while (argc >= 1) {
236         if (strcmp(*argv, "-inform") == 0) {
237             if (--argc < 1)
238                 goto bad;
239             informat = str2fmt(*(++argv));
240         } else if (strcmp(*argv, "-outform") == 0) {
241             if (--argc < 1)
242                 goto bad;
243             outformat = str2fmt(*(++argv));
244         } else if (strcmp(*argv, "-keyform") == 0) {
245             if (--argc < 1)
246                 goto bad;
247             keyformat = str2fmt(*(++argv));
248         } else if (strcmp(*argv, "-req") == 0) {
249             reqfile = 1;
250             need_rand = 1;
251         } else if (strcmp(*argv, "-CAform") == 0) {
252             if (--argc < 1)
253                 goto bad;
254             CAformat = str2fmt(*(++argv));
255         } else if (strcmp(*argv, "-CAkeyform") == 0) {
256             if (--argc < 1)
257                 goto bad;
258             CAkeyformat = str2fmt(*(++argv));
259         } else if (strcmp(*argv, "-days") == 0) {
260             if (--argc < 1)
261                 goto bad;
262             days = atoi(*(++argv));
263             if (days == 0) {
264                 BIO_printf(STDout, "bad number of days\n");
265                 goto bad;
266             }
267         } else if (strcmp(*argv, "-passin") == 0) {
268             if (--argc < 1)
269                 goto bad;
270             passargin = *(++argv);
271         } else if (strcmp(*argv, "-extfile") == 0) {
272             if (--argc < 1)
273                 goto bad;
274             extfile = *(++argv);
275         } else if (strcmp(*argv, "-extensions") == 0) {
276             if (--argc < 1)
277                 goto bad;
278             extsect = *(++argv);
279         } else if (strcmp(*argv, "-in") == 0) {
280             if (--argc < 1)
281                 goto bad;
282             infile = *(++argv);
283         } else if (strcmp(*argv, "-out") == 0) {
284             if (--argc < 1)
285                 goto bad;
286             outfile = *(++argv);
287         } else if (strcmp(*argv, "-signkey") == 0) {
288             if (--argc < 1)
289                 goto bad;
290             keyfile = *(++argv);
291             sign_flag = ++num;
292             need_rand = 1;
293         } else if (strcmp(*argv, "-CA") == 0) {
294             if (--argc < 1)
295                 goto bad;
296             CAfile = *(++argv);
297             CA_flag = ++num;
298             need_rand = 1;
299         } else if (strcmp(*argv, "-CAkey") == 0) {
300             if (--argc < 1)
301                 goto bad;
302             CAkeyfile = *(++argv);
303         } else if (strcmp(*argv, "-CAserial") == 0) {
304             if (--argc < 1)
305                 goto bad;
306             CAserial = *(++argv);
307         } else if (strcmp(*argv, "-set_serial") == 0) {
308             if (--argc < 1)
309                 goto bad;
310             if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
311                 goto bad;
312         } else if (strcmp(*argv, "-addtrust") == 0) {
313             if (--argc < 1)
314                 goto bad;
315             if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
316                 BIO_printf(bio_err, "Invalid trust object value %s\n", *argv);
317                 goto bad;
318             }
319             if (!trust)
320                 trust = sk_ASN1_OBJECT_new_null();
321             sk_ASN1_OBJECT_push(trust, objtmp);
322             trustout = 1;
323         } else if (strcmp(*argv, "-addreject") == 0) {
324             if (--argc < 1)
325                 goto bad;
326             if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
327                 BIO_printf(bio_err,
328                            "Invalid reject object value %s\n", *argv);
329                 goto bad;
330             }
331             if (!reject)
332                 reject = sk_ASN1_OBJECT_new_null();
333             sk_ASN1_OBJECT_push(reject, objtmp);
334             trustout = 1;
335         } else if (strcmp(*argv, "-setalias") == 0) {
336             if (--argc < 1)
337                 goto bad;
338             alias = *(++argv);
339             trustout = 1;
340         } else if (strcmp(*argv, "-certopt") == 0) {
341             if (--argc < 1)
342                 goto bad;
343             if (!set_cert_ex(&certflag, *(++argv)))
344                 goto bad;
345         } else if (strcmp(*argv, "-nameopt") == 0) {
346             if (--argc < 1)
347                 goto bad;
348             if (!set_name_ex(&nmflag, *(++argv)))
349                 goto bad;
350         }
351 #ifndef OPENSSL_NO_ENGINE
352         else if (strcmp(*argv, "-engine") == 0) {
353             if (--argc < 1)
354                 goto bad;
355             engine = *(++argv);
356         }
357 #endif
358         else if (strcmp(*argv, "-C") == 0)
359             C = ++num;
360         else if (strcmp(*argv, "-email") == 0)
361             email = ++num;
362         else if (strcmp(*argv, "-ocsp_uri") == 0)
363             ocsp_uri = ++num;
364         else if (strcmp(*argv, "-serial") == 0)
365             serial = ++num;
366         else if (strcmp(*argv, "-next_serial") == 0)
367             next_serial = ++num;
368         else if (strcmp(*argv, "-modulus") == 0)
369             modulus = ++num;
370         else if (strcmp(*argv, "-pubkey") == 0)
371             pubkey = ++num;
372         else if (strcmp(*argv, "-x509toreq") == 0)
373             x509req = ++num;
374         else if (strcmp(*argv, "-text") == 0)
375             text = ++num;
376         else if (strcmp(*argv, "-hash") == 0
377                  || strcmp(*argv, "-subject_hash") == 0)
378             subject_hash = ++num;
379         else if (strcmp(*argv, "-issuer_hash") == 0)
380             issuer_hash = ++num;
381         else if (strcmp(*argv, "-subject") == 0)
382             subject = ++num;
383         else if (strcmp(*argv, "-issuer") == 0)
384             issuer = ++num;
385         else if (strcmp(*argv, "-fingerprint") == 0)
386             fingerprint = ++num;
387         else if (strcmp(*argv, "-dates") == 0) {
388             startdate = ++num;
389             enddate = ++num;
390         } else if (strcmp(*argv, "-purpose") == 0)
391             pprint = ++num;
392         else if (strcmp(*argv, "-startdate") == 0)
393             startdate = ++num;
394         else if (strcmp(*argv, "-enddate") == 0)
395             enddate = ++num;
396         else if (strcmp(*argv, "-checkend") == 0) {
397             if (--argc < 1)
398                 goto bad;
399             checkoffset = atoi(*(++argv));
400             checkend = 1;
401         } else if (strcmp(*argv, "-noout") == 0)
402             noout = ++num;
403         else if (strcmp(*argv, "-trustout") == 0)
404             trustout = 1;
405         else if (strcmp(*argv, "-clrtrust") == 0)
406             clrtrust = ++num;
407         else if (strcmp(*argv, "-clrreject") == 0)
408             clrreject = ++num;
409         else if (strcmp(*argv, "-alias") == 0)
410             aliasout = ++num;
411         else if (strcmp(*argv, "-CAcreateserial") == 0)
412             CA_createserial = ++num;
413         else if (strcmp(*argv, "-clrext") == 0)
414             clrext = 1;
415 #if 1                           /* stay backwards-compatible with 0.9.5; this
416                                  * should go away soon */
417         else if (strcmp(*argv, "-crlext") == 0) {
418             BIO_printf(bio_err, "use -clrext instead of -crlext\n");
419             clrext = 1;
420         }
421 #endif
422         else if (strcmp(*argv, "-ocspid") == 0)
423             ocspid = ++num;
424         else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
425             /* ok */
426             digest = md_alg;
427         } else {
428             BIO_printf(bio_err, "unknown option %s\n", *argv);
429             badops = 1;
430             break;
431         }
432         argc--;
433         argv++;
434     }
435
436     if (badops) {
437  bad:
438         for (pp = x509_usage; (*pp != NULL); pp++)
439             BIO_printf(bio_err, "%s", *pp);
440         goto end;
441     }
442 #ifndef OPENSSL_NO_ENGINE
443     e = setup_engine(bio_err, engine, 0);
444 #endif
445
446     if (need_rand)
447         app_RAND_load_file(NULL, bio_err, 0);
448
449     ERR_load_crypto_strings();
450
451     if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
452         BIO_printf(bio_err, "Error getting password\n");
453         goto end;
454     }
455
456     if (!X509_STORE_set_default_paths(ctx)) {
457         ERR_print_errors(bio_err);
458         goto end;
459     }
460
461     if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
462         CAkeyfile = CAfile;
463     } else if ((CA_flag) && (CAkeyfile == NULL)) {
464         BIO_printf(bio_err,
465                    "need to specify a CAkey if using the CA command\n");
466         goto end;
467     }
468
469     if (extfile) {
470         long errorline = -1;
471         X509V3_CTX ctx2;
472         extconf = NCONF_new(NULL);
473         if (!NCONF_load(extconf, extfile, &errorline)) {
474             if (errorline <= 0)
475                 BIO_printf(bio_err,
476                            "error loading the config file '%s'\n", extfile);
477             else
478                 BIO_printf(bio_err,
479                            "error on line %ld of config file '%s'\n",
480                            errorline, extfile);
481             goto end;
482         }
483         if (!extsect) {
484             extsect = NCONF_get_string(extconf, "default", "extensions");
485             if (!extsect) {
486                 ERR_clear_error();
487                 extsect = "default";
488             }
489         }
490         X509V3_set_ctx_test(&ctx2);
491         X509V3_set_nconf(&ctx2, extconf);
492         if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
493             BIO_printf(bio_err,
494                        "Error Loading extension section %s\n", extsect);
495             ERR_print_errors(bio_err);
496             goto end;
497         }
498     }
499
500     if (reqfile) {
501         EVP_PKEY *pkey;
502         BIO *in;
503
504         if (!sign_flag && !CA_flag) {
505             BIO_printf(bio_err, "We need a private key to sign with\n");
506             goto end;
507         }
508         in = BIO_new(BIO_s_file());
509         if (in == NULL) {
510             ERR_print_errors(bio_err);
511             goto end;
512         }
513
514         if (infile == NULL)
515             BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
516         else {
517             if (BIO_read_filename(in, infile) <= 0) {
518                 perror(infile);
519                 BIO_free(in);
520                 goto end;
521             }
522         }
523         req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
524         BIO_free(in);
525
526         if (req == NULL) {
527             ERR_print_errors(bio_err);
528             goto end;
529         }
530
531         if ((req->req_info == NULL) ||
532             (req->req_info->pubkey == NULL) ||
533             (req->req_info->pubkey->public_key == NULL) ||
534             (req->req_info->pubkey->public_key->data == NULL)) {
535             BIO_printf(bio_err,
536                        "The certificate request appears to corrupted\n");
537             BIO_printf(bio_err, "It does not contain a public key\n");
538             goto end;
539         }
540         if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
541             BIO_printf(bio_err, "error unpacking public key\n");
542             goto end;
543         }
544         i = X509_REQ_verify(req, pkey);
545         EVP_PKEY_free(pkey);
546         if (i < 0) {
547             BIO_printf(bio_err, "Signature verification error\n");
548             ERR_print_errors(bio_err);
549             goto end;
550         }
551         if (i == 0) {
552             BIO_printf(bio_err,
553                        "Signature did not match the certificate request\n");
554             goto end;
555         } else
556             BIO_printf(bio_err, "Signature ok\n");
557
558         print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
559                    nmflag);
560
561         if ((x = X509_new()) == NULL)
562             goto end;
563
564         if (sno == NULL) {
565             sno = ASN1_INTEGER_new();
566             if (!sno || !rand_serial(NULL, sno))
567                 goto end;
568             if (!X509_set_serialNumber(x, sno))
569                 goto end;
570             ASN1_INTEGER_free(sno);
571             sno = NULL;
572         } else if (!X509_set_serialNumber(x, sno))
573             goto end;
574
575         if (!X509_set_issuer_name(x, req->req_info->subject))
576             goto end;
577         if (!X509_set_subject_name(x, req->req_info->subject))
578             goto end;
579
580         X509_gmtime_adj(X509_get_notBefore(x), 0);
581         X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
582
583         pkey = X509_REQ_get_pubkey(req);
584         X509_set_pubkey(x, pkey);
585         EVP_PKEY_free(pkey);
586     } else
587         x = load_cert(bio_err, infile, informat, NULL, e, "Certificate");
588
589     if (x == NULL)
590         goto end;
591     if (CA_flag) {
592         xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate");
593         if (xca == NULL)
594             goto end;
595     }
596
597     if (!noout || text || next_serial) {
598         OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
599
600         out = BIO_new(BIO_s_file());
601         if (out == NULL) {
602             ERR_print_errors(bio_err);
603             goto end;
604         }
605         if (outfile == NULL) {
606             BIO_set_fp(out, stdout, BIO_NOCLOSE);
607 #ifdef OPENSSL_SYS_VMS
608             {
609                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
610                 out = BIO_push(tmpbio, out);
611             }
612 #endif
613         } else {
614             if (BIO_write_filename(out, outfile) <= 0) {
615                 perror(outfile);
616                 goto end;
617             }
618         }
619     }
620
621     if (alias)
622         X509_alias_set1(x, (unsigned char *)alias, -1);
623
624     if (clrtrust)
625         X509_trust_clear(x);
626     if (clrreject)
627         X509_reject_clear(x);
628
629     if (trust) {
630         for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
631             objtmp = sk_ASN1_OBJECT_value(trust, i);
632             X509_add1_trust_object(x, objtmp);
633         }
634     }
635
636     if (reject) {
637         for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
638             objtmp = sk_ASN1_OBJECT_value(reject, i);
639             X509_add1_reject_object(x, objtmp);
640         }
641     }
642
643     if (num) {
644         for (i = 1; i <= num; i++) {
645             if (issuer == i) {
646                 print_name(STDout, "issuer= ",
647                            X509_get_issuer_name(x), nmflag);
648             } else if (subject == i) {
649                 print_name(STDout, "subject= ",
650                            X509_get_subject_name(x), nmflag);
651             } else if (serial == i) {
652                 BIO_printf(STDout, "serial=");
653                 i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x));
654                 BIO_printf(STDout, "\n");
655             } else if (next_serial == i) {
656                 BIGNUM *bnser;
657                 ASN1_INTEGER *ser;
658                 ser = X509_get_serialNumber(x);
659                 bnser = ASN1_INTEGER_to_BN(ser, NULL);
660                 if (!bnser)
661                     goto end;
662                 if (!BN_add_word(bnser, 1))
663                     goto end;
664                 ser = BN_to_ASN1_INTEGER(bnser, NULL);
665                 if (!ser)
666                     goto end;
667                 BN_free(bnser);
668                 i2a_ASN1_INTEGER(out, ser);
669                 ASN1_INTEGER_free(ser);
670                 BIO_puts(out, "\n");
671             } else if ((email == i) || (ocsp_uri == i)) {
672                 int j;
673                 STACK *emlst;
674                 if (email == i)
675                     emlst = X509_get1_email(x);
676                 else
677                     emlst = X509_get1_ocsp(x);
678                 for (j = 0; j < sk_num(emlst); j++)
679                     BIO_printf(STDout, "%s\n", sk_value(emlst, j));
680                 X509_email_free(emlst);
681             } else if (aliasout == i) {
682                 unsigned char *alstr;
683                 alstr = X509_alias_get0(x, NULL);
684                 if (alstr)
685                     BIO_printf(STDout, "%s\n", alstr);
686                 else
687                     BIO_puts(STDout, "<No Alias>\n");
688             } else if (subject_hash == i) {
689                 BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
690             } else if (issuer_hash == i) {
691                 BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
692             } else if (pprint == i) {
693                 X509_PURPOSE *ptmp;
694                 int j;
695                 BIO_printf(STDout, "Certificate purposes:\n");
696                 for (j = 0; j < X509_PURPOSE_get_count(); j++) {
697                     ptmp = X509_PURPOSE_get0(j);
698                     purpose_print(STDout, x, ptmp);
699                 }
700             } else if (modulus == i) {
701                 EVP_PKEY *pkey;
702
703                 pkey = X509_get_pubkey(x);
704                 if (pkey == NULL) {
705                     BIO_printf(bio_err, "Modulus=unavailable\n");
706                     ERR_print_errors(bio_err);
707                     goto end;
708                 }
709                 BIO_printf(STDout, "Modulus=");
710 #ifndef OPENSSL_NO_RSA
711                 if (pkey->type == EVP_PKEY_RSA)
712                     BN_print(STDout, pkey->pkey.rsa->n);
713                 else
714 #endif
715 #ifndef OPENSSL_NO_DSA
716                 if (pkey->type == EVP_PKEY_DSA)
717                     BN_print(STDout, pkey->pkey.dsa->pub_key);
718                 else
719 #endif
720                     BIO_printf(STDout, "Wrong Algorithm type");
721                 BIO_printf(STDout, "\n");
722                 EVP_PKEY_free(pkey);
723             } else if (pubkey == i) {
724                 EVP_PKEY *pkey;
725
726                 pkey = X509_get_pubkey(x);
727                 if (pkey == NULL) {
728                     BIO_printf(bio_err, "Error getting public key\n");
729                     ERR_print_errors(bio_err);
730                     goto end;
731                 }
732                 PEM_write_bio_PUBKEY(STDout, pkey);
733                 EVP_PKEY_free(pkey);
734             } else if (C == i) {
735                 unsigned char *d;
736                 char *m;
737                 int y, z;
738
739                 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
740                 BIO_printf(STDout, "/* subject:%s */\n", buf);
741                 m = X509_NAME_oneline(X509_get_issuer_name(x), buf,
742                                       sizeof buf);
743                 BIO_printf(STDout, "/* issuer :%s */\n", buf);
744
745                 z = i2d_X509(x, NULL);
746                 m = OPENSSL_malloc(z);
747
748                 d = (unsigned char *)m;
749                 z = i2d_X509_NAME(X509_get_subject_name(x), &d);
750                 BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n",
751                            z);
752                 d = (unsigned char *)m;
753                 for (y = 0; y < z; y++) {
754                     BIO_printf(STDout, "0x%02X,", d[y]);
755                     if ((y & 0x0f) == 0x0f)
756                         BIO_printf(STDout, "\n");
757                 }
758                 if (y % 16 != 0)
759                     BIO_printf(STDout, "\n");
760                 BIO_printf(STDout, "};\n");
761
762                 z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
763                 BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z);
764                 d = (unsigned char *)m;
765                 for (y = 0; y < z; y++) {
766                     BIO_printf(STDout, "0x%02X,", d[y]);
767                     if ((y & 0x0f) == 0x0f)
768                         BIO_printf(STDout, "\n");
769                 }
770                 if (y % 16 != 0)
771                     BIO_printf(STDout, "\n");
772                 BIO_printf(STDout, "};\n");
773
774                 z = i2d_X509(x, &d);
775                 BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n",
776                            z);
777                 d = (unsigned char *)m;
778                 for (y = 0; y < z; y++) {
779                     BIO_printf(STDout, "0x%02X,", d[y]);
780                     if ((y & 0x0f) == 0x0f)
781                         BIO_printf(STDout, "\n");
782                 }
783                 if (y % 16 != 0)
784                     BIO_printf(STDout, "\n");
785                 BIO_printf(STDout, "};\n");
786
787                 OPENSSL_free(m);
788             } else if (text == i) {
789                 X509_print_ex(out, x, nmflag, certflag);
790             } else if (startdate == i) {
791                 BIO_puts(STDout, "notBefore=");
792                 ASN1_TIME_print(STDout, X509_get_notBefore(x));
793                 BIO_puts(STDout, "\n");
794             } else if (enddate == i) {
795                 BIO_puts(STDout, "notAfter=");
796                 ASN1_TIME_print(STDout, X509_get_notAfter(x));
797                 BIO_puts(STDout, "\n");
798             } else if (fingerprint == i) {
799                 int j;
800                 unsigned int n;
801                 unsigned char md[EVP_MAX_MD_SIZE];
802
803                 if (!X509_digest(x, digest, md, &n)) {
804                     BIO_printf(bio_err, "out of memory\n");
805                     goto end;
806                 }
807                 BIO_printf(STDout, "%s Fingerprint=",
808                            OBJ_nid2sn(EVP_MD_type(digest)));
809                 for (j = 0; j < (int)n; j++) {
810                     BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n)
811                                ? '\n' : ':');
812                 }
813             }
814
815             /* should be in the library */
816             else if ((sign_flag == i) && (x509req == 0)) {
817                 BIO_printf(bio_err, "Getting Private key\n");
818                 if (Upkey == NULL) {
819                     Upkey = load_key(bio_err,
820                                      keyfile, keyformat, 0,
821                                      passin, e, "Private key");
822                     if (Upkey == NULL)
823                         goto end;
824                 }
825 #ifndef OPENSSL_NO_DSA
826                 if (Upkey->type == EVP_PKEY_DSA)
827                     digest = EVP_dss1();
828 #endif
829 #ifndef OPENSSL_NO_ECDSA
830                 if (Upkey->type == EVP_PKEY_EC)
831                     digest = EVP_ecdsa();
832 #endif
833
834                 assert(need_rand);
835                 if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
836                     goto end;
837             } else if (CA_flag == i) {
838                 BIO_printf(bio_err, "Getting CA Private Key\n");
839                 if (CAkeyfile != NULL) {
840                     CApkey = load_key(bio_err,
841                                       CAkeyfile, CAkeyformat,
842                                       0, passin, e, "CA Private Key");
843                     if (CApkey == NULL)
844                         goto end;
845                 }
846 #ifndef OPENSSL_NO_DSA
847                 if (CApkey->type == EVP_PKEY_DSA)
848                     digest = EVP_dss1();
849 #endif
850 #ifndef OPENSSL_NO_ECDSA
851                 if (CApkey->type == EVP_PKEY_EC)
852                     digest = EVP_ecdsa();
853 #endif
854
855                 assert(need_rand);
856                 if (!x509_certify(ctx, CAfile, digest, x, xca,
857                                   CApkey, CAserial, CA_createserial, days,
858                                   clrext, extconf, extsect, sno))
859                     goto end;
860             } else if (x509req == i) {
861                 EVP_PKEY *pk;
862
863                 BIO_printf(bio_err, "Getting request Private Key\n");
864                 if (keyfile == NULL) {
865                     BIO_printf(bio_err, "no request key file specified\n");
866                     goto end;
867                 } else {
868                     pk = load_key(bio_err,
869                                   keyfile, keyformat, 0,
870                                   passin, e, "request key");
871                     if (pk == NULL)
872                         goto end;
873                 }
874
875                 BIO_printf(bio_err, "Generating certificate request\n");
876
877 #ifndef OPENSSL_NO_DSA
878                 if (pk->type == EVP_PKEY_DSA)
879                     digest = EVP_dss1();
880 #endif
881 #ifndef OPENSSL_NO_ECDSA
882                 if (pk->type == EVP_PKEY_EC)
883                     digest = EVP_ecdsa();
884 #endif
885
886                 rq = X509_to_X509_REQ(x, pk, digest);
887                 EVP_PKEY_free(pk);
888                 if (rq == NULL) {
889                     ERR_print_errors(bio_err);
890                     goto end;
891                 }
892                 if (!noout) {
893                     X509_REQ_print(out, rq);
894                     PEM_write_bio_X509_REQ(out, rq);
895                 }
896                 noout = 1;
897             } else if (ocspid == i) {
898                 X509_ocspid_print(out, x);
899             }
900         }
901     }
902
903     if (checkend) {
904         time_t tcheck = time(NULL) + checkoffset;
905
906         if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
907             BIO_printf(out, "Certificate will expire\n");
908             ret = 1;
909         } else {
910             BIO_printf(out, "Certificate will not expire\n");
911             ret = 0;
912         }
913         goto end;
914     }
915
916     if (noout) {
917         ret = 0;
918         goto end;
919     }
920
921     if (outformat == FORMAT_ASN1)
922         i = i2d_X509_bio(out, x);
923     else if (outformat == FORMAT_PEM) {
924         if (trustout)
925             i = PEM_write_bio_X509_AUX(out, x);
926         else
927             i = PEM_write_bio_X509(out, x);
928     } else if (outformat == FORMAT_NETSCAPE) {
929         ASN1_HEADER ah;
930         ASN1_OCTET_STRING os;
931
932         os.data = (unsigned char *)NETSCAPE_CERT_HDR;
933         os.length = strlen(NETSCAPE_CERT_HDR);
934         ah.header = &os;
935         ah.data = (char *)x;
936         ah.meth = X509_asn1_meth();
937
938         i = ASN1_i2d_bio_of(ASN1_HEADER, i2d_ASN1_HEADER, out, &ah);
939     } else {
940         BIO_printf(bio_err, "bad output format specified for outfile\n");
941         goto end;
942     }
943     if (!i) {
944         BIO_printf(bio_err, "unable to write certificate\n");
945         ERR_print_errors(bio_err);
946         goto end;
947     }
948     ret = 0;
949  end:
950     if (need_rand)
951         app_RAND_write_file(NULL, bio_err);
952     OBJ_cleanup();
953     NCONF_free(extconf);
954     BIO_free_all(out);
955     BIO_free_all(STDout);
956     X509_STORE_free(ctx);
957     X509_REQ_free(req);
958     X509_free(x);
959     X509_free(xca);
960     EVP_PKEY_free(Upkey);
961     EVP_PKEY_free(CApkey);
962     X509_REQ_free(rq);
963     ASN1_INTEGER_free(sno);
964     sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
965     sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
966     if (passin)
967         OPENSSL_free(passin);
968     apps_shutdown();
969     OPENSSL_EXIT(ret);
970 }
971
972 static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile,
973                                       int create)
974 {
975     char *buf = NULL, *p;
976     ASN1_INTEGER *bs = NULL;
977     BIGNUM *serial = NULL;
978     size_t len;
979
980     len = ((serialfile == NULL)
981            ? (strlen(CAfile) + strlen(POSTFIX) + 1)
982            : (strlen(serialfile))) + 1;
983     buf = OPENSSL_malloc(len);
984     if (buf == NULL) {
985         BIO_printf(bio_err, "out of mem\n");
986         goto end;
987     }
988     if (serialfile == NULL) {
989         BUF_strlcpy(buf, CAfile, len);
990         for (p = buf; *p; p++)
991             if (*p == '.') {
992                 *p = '\0';
993                 break;
994             }
995         BUF_strlcat(buf, POSTFIX, len);
996     } else
997         BUF_strlcpy(buf, serialfile, len);
998
999     serial = load_serial(buf, create, NULL);
1000     if (serial == NULL)
1001         goto end;
1002
1003     if (!BN_add_word(serial, 1)) {
1004         BIO_printf(bio_err, "add_word failure\n");
1005         goto end;
1006     }
1007
1008     if (!save_serial(buf, NULL, serial, &bs))
1009         goto end;
1010
1011  end:
1012     if (buf)
1013         OPENSSL_free(buf);
1014     BN_free(serial);
1015     return bs;
1016 }
1017
1018 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
1019                         X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile,
1020                         int create, int days, int clrext, CONF *conf,
1021                         char *section, ASN1_INTEGER *sno)
1022 {
1023     int ret = 0;
1024     ASN1_INTEGER *bs = NULL;
1025     X509_STORE_CTX xsc;
1026     EVP_PKEY *upkey;
1027
1028     upkey = X509_get_pubkey(xca);
1029     EVP_PKEY_copy_parameters(upkey, pkey);
1030     EVP_PKEY_free(upkey);
1031
1032     if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
1033         BIO_printf(bio_err, "Error initialising X509 store\n");
1034         goto end;
1035     }
1036     if (sno)
1037         bs = sno;
1038     else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
1039         goto end;
1040
1041 /*      if (!X509_STORE_add_cert(ctx,x)) goto end;*/
1042
1043     /*
1044      * NOTE: this certificate can/should be self signed, unless it was a
1045      * certificate request in which case it is not.
1046      */
1047     X509_STORE_CTX_set_cert(&xsc, x);
1048     X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
1049     if (!reqfile && X509_verify_cert(&xsc) <= 0)
1050         goto end;
1051
1052     if (!X509_check_private_key(xca, pkey)) {
1053         BIO_printf(bio_err,
1054                    "CA certificate and CA private key do not match\n");
1055         goto end;
1056     }
1057
1058     if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
1059         goto end;
1060     if (!X509_set_serialNumber(x, bs))
1061         goto end;
1062
1063     if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
1064         goto end;
1065
1066     /* hardwired expired */
1067     if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) ==
1068         NULL)
1069         goto end;
1070
1071     if (clrext) {
1072         while (X509_get_ext_count(x) > 0)
1073             X509_delete_ext(x, 0);
1074     }
1075
1076     if (conf) {
1077         X509V3_CTX ctx2;
1078         X509_set_version(x, 2); /* version 3 certificate */
1079         X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
1080         X509V3_set_nconf(&ctx2, conf);
1081         if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
1082             goto end;
1083     }
1084
1085     if (!X509_sign(x, pkey, digest))
1086         goto end;
1087     ret = 1;
1088  end:
1089     X509_STORE_CTX_cleanup(&xsc);
1090     if (!ret)
1091         ERR_print_errors(bio_err);
1092     if (!sno)
1093         ASN1_INTEGER_free(bs);
1094     return ret;
1095 }
1096
1097 static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
1098 {
1099     int err;
1100     X509 *err_cert;
1101
1102     /*
1103      * it is ok to use a self signed certificate This case will catch both
1104      * the initial ok == 0 and the final ok == 1 calls to this function
1105      */
1106     err = X509_STORE_CTX_get_error(ctx);
1107     if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
1108         return 1;
1109
1110     /*
1111      * BAD we should have gotten an error.  Normally if everything worked
1112      * X509_STORE_CTX_get_error(ctx) will still be set to
1113      * DEPTH_ZERO_SELF_....
1114      */
1115     if (ok) {
1116         BIO_printf(bio_err,
1117                    "error with certificate to be certified - should be self signed\n");
1118         return 0;
1119     } else {
1120         err_cert = X509_STORE_CTX_get_current_cert(ctx);
1121         print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
1122         BIO_printf(bio_err,
1123                    "error with certificate - error %d at depth %d\n%s\n", err,
1124                    X509_STORE_CTX_get_error_depth(ctx),
1125                    X509_verify_cert_error_string(err));
1126         return 1;
1127     }
1128 }
1129
1130 /* self sign */
1131 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
1132                 const EVP_MD *digest, CONF *conf, char *section)
1133 {
1134
1135     EVP_PKEY *pktmp;
1136
1137     pktmp = X509_get_pubkey(x);
1138     EVP_PKEY_copy_parameters(pktmp, pkey);
1139     EVP_PKEY_save_parameters(pktmp, 1);
1140     EVP_PKEY_free(pktmp);
1141
1142     if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
1143         goto err;
1144     if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
1145         goto err;
1146
1147     /* Lets just make it 12:00am GMT, Jan 1 1970 */
1148     /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
1149     /* 28 days to be certified */
1150
1151     if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) ==
1152         NULL)
1153         goto err;
1154
1155     if (!X509_set_pubkey(x, pkey))
1156         goto err;
1157     if (clrext) {
1158         while (X509_get_ext_count(x) > 0)
1159             X509_delete_ext(x, 0);
1160     }
1161     if (conf) {
1162         X509V3_CTX ctx;
1163         X509_set_version(x, 2); /* version 3 certificate */
1164         X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
1165         X509V3_set_nconf(&ctx, conf);
1166         if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
1167             goto err;
1168     }
1169     if (!X509_sign(x, pkey, digest))
1170         goto err;
1171     return 1;
1172  err:
1173     ERR_print_errors(bio_err);
1174     return 0;
1175 }
1176
1177 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
1178 {
1179     int id, i, idret;
1180     char *pname;
1181     id = X509_PURPOSE_get_id(pt);
1182     pname = X509_PURPOSE_get0_name(pt);
1183     for (i = 0; i < 2; i++) {
1184         idret = X509_check_purpose(cert, id, i);
1185         BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
1186         if (idret == 1)
1187             BIO_printf(bio, "Yes\n");
1188         else if (idret == 0)
1189             BIO_printf(bio, "No\n");
1190         else
1191             BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
1192     }
1193     return 1;
1194 }