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