x509.c revision 296465
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
90static 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
150static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
151static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
152                const EVP_MD *digest, CONF *conf, char *section);
153static 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);
157static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
158static int reqfile = 0;
159
160int MAIN(int, char **);
161
162int 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
972static 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
1018static 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
1097static 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 */
1131static 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
1177static 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}
1195