xref: /dflybsd-src/crypto/libressl/apps/openssl/x509.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: x509.c,v 1.29 2021/12/12 20:34:04 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59f5b1c8a1SJohn Marino #include <assert.h>
60*de0e0e4dSAntonio Huete Jimenez #include <limits.h>
61f5b1c8a1SJohn Marino #include <stdio.h>
62f5b1c8a1SJohn Marino #include <stdlib.h>
63f5b1c8a1SJohn Marino #include <string.h>
64f5b1c8a1SJohn Marino 
65f5b1c8a1SJohn Marino #include "apps.h"
66f5b1c8a1SJohn Marino 
67f5b1c8a1SJohn Marino #include <openssl/asn1.h>
68f5b1c8a1SJohn Marino #include <openssl/bio.h>
69f5b1c8a1SJohn Marino #include <openssl/bn.h>
70*de0e0e4dSAntonio Huete Jimenez #include <openssl/dsa.h>
71f5b1c8a1SJohn Marino #include <openssl/err.h>
72f5b1c8a1SJohn Marino #include <openssl/evp.h>
73f5b1c8a1SJohn Marino #include <openssl/objects.h>
74f5b1c8a1SJohn Marino #include <openssl/pem.h>
75*de0e0e4dSAntonio Huete Jimenez #include <openssl/rsa.h>
76f5b1c8a1SJohn Marino #include <openssl/x509.h>
77f5b1c8a1SJohn Marino #include <openssl/x509v3.h>
78f5b1c8a1SJohn Marino 
79f5b1c8a1SJohn Marino #define	POSTFIX	".srl"
80f5b1c8a1SJohn Marino #define DEF_DAYS	30
81f5b1c8a1SJohn Marino 
82f5b1c8a1SJohn Marino static int callb(int ok, X509_STORE_CTX *ctx);
83f5b1c8a1SJohn Marino static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
84f5b1c8a1SJohn Marino     const EVP_MD *digest, CONF *conf, char *section);
85f5b1c8a1SJohn Marino static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
86f5b1c8a1SJohn Marino     X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
87f5b1c8a1SJohn Marino     char *serial, int create, int days, int clrext, CONF *conf, char *section,
88f5b1c8a1SJohn Marino     ASN1_INTEGER *sno);
89f5b1c8a1SJohn Marino static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
90*de0e0e4dSAntonio Huete Jimenez 
91*de0e0e4dSAntonio Huete Jimenez static struct {
92*de0e0e4dSAntonio Huete Jimenez 	char *alias;
93*de0e0e4dSAntonio Huete Jimenez 	int aliasout;
94*de0e0e4dSAntonio Huete Jimenez 	int badops;
95*de0e0e4dSAntonio Huete Jimenez 	int C;
96*de0e0e4dSAntonio Huete Jimenez 	int CA_createserial;
97*de0e0e4dSAntonio Huete Jimenez 	int CA_flag;
98*de0e0e4dSAntonio Huete Jimenez 	char *CAfile;
99*de0e0e4dSAntonio Huete Jimenez 	int CAformat;
100*de0e0e4dSAntonio Huete Jimenez 	char *CAkeyfile;
101*de0e0e4dSAntonio Huete Jimenez 	int CAkeyformat;
102*de0e0e4dSAntonio Huete Jimenez 	char *CAserial;
103*de0e0e4dSAntonio Huete Jimenez 	unsigned long certflag;
104*de0e0e4dSAntonio Huete Jimenez 	int checkend;
105*de0e0e4dSAntonio Huete Jimenez 	int checkoffset;
106*de0e0e4dSAntonio Huete Jimenez 	int clrext;
107*de0e0e4dSAntonio Huete Jimenez 	int clrreject;
108*de0e0e4dSAntonio Huete Jimenez 	int clrtrust;
109*de0e0e4dSAntonio Huete Jimenez 	int days;
110*de0e0e4dSAntonio Huete Jimenez 	const EVP_MD *digest;
111*de0e0e4dSAntonio Huete Jimenez 	int email;
112*de0e0e4dSAntonio Huete Jimenez 	int enddate;
113*de0e0e4dSAntonio Huete Jimenez 	char *extfile;
114*de0e0e4dSAntonio Huete Jimenez 	char *extsect;
115*de0e0e4dSAntonio Huete Jimenez 	int fingerprint;
116*de0e0e4dSAntonio Huete Jimenez 	char *infile;
117*de0e0e4dSAntonio Huete Jimenez 	int informat;
118*de0e0e4dSAntonio Huete Jimenez 	int issuer;
119*de0e0e4dSAntonio Huete Jimenez 	int issuer_hash;
120*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_MD5
121*de0e0e4dSAntonio Huete Jimenez 	int issuer_hash_old;
122*de0e0e4dSAntonio Huete Jimenez #endif
123*de0e0e4dSAntonio Huete Jimenez 	char *keyfile;
124*de0e0e4dSAntonio Huete Jimenez 	int keyformat;
125*de0e0e4dSAntonio Huete Jimenez 	const EVP_MD *md_alg;
126*de0e0e4dSAntonio Huete Jimenez 	int modulus;
127*de0e0e4dSAntonio Huete Jimenez 	int next_serial;
128*de0e0e4dSAntonio Huete Jimenez 	unsigned long nmflag;
129*de0e0e4dSAntonio Huete Jimenez 	int noout;
130*de0e0e4dSAntonio Huete Jimenez 	int num;
131*de0e0e4dSAntonio Huete Jimenez 	int ocspid;
132*de0e0e4dSAntonio Huete Jimenez 	ASN1_OBJECT *objtmp;
133*de0e0e4dSAntonio Huete Jimenez 	int ocsp_uri;
134*de0e0e4dSAntonio Huete Jimenez 	char *outfile;
135*de0e0e4dSAntonio Huete Jimenez 	int outformat;
136*de0e0e4dSAntonio Huete Jimenez 	char *passargin;
137*de0e0e4dSAntonio Huete Jimenez 	int pprint;
138*de0e0e4dSAntonio Huete Jimenez 	int pubkey;
139*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(ASN1_OBJECT) *reject;
140*de0e0e4dSAntonio Huete Jimenez 	int reqfile;
141*de0e0e4dSAntonio Huete Jimenez 	int serial;
142*de0e0e4dSAntonio Huete Jimenez 	int sign_flag;
143*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(OPENSSL_STRING) *sigopts;
144*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER *sno;
145*de0e0e4dSAntonio Huete Jimenez 	int startdate;
146*de0e0e4dSAntonio Huete Jimenez 	int subject;
147*de0e0e4dSAntonio Huete Jimenez 	int subject_hash;
148*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_MD5
149*de0e0e4dSAntonio Huete Jimenez 	int subject_hash_old;
150*de0e0e4dSAntonio Huete Jimenez #endif
151*de0e0e4dSAntonio Huete Jimenez 	int text;
152*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(ASN1_OBJECT) *trust;
153*de0e0e4dSAntonio Huete Jimenez 	int trustout;
154*de0e0e4dSAntonio Huete Jimenez 	int x509req;
155*de0e0e4dSAntonio Huete Jimenez } x509_config;
156*de0e0e4dSAntonio Huete Jimenez 
157*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_addreject(char * arg)158*de0e0e4dSAntonio Huete Jimenez x509_opt_addreject(char *arg)
159*de0e0e4dSAntonio Huete Jimenez {
160*de0e0e4dSAntonio Huete Jimenez 	if ((x509_config.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
161*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Invalid reject object value %s\n", arg);
162*de0e0e4dSAntonio Huete Jimenez 		return (1);
163*de0e0e4dSAntonio Huete Jimenez 	}
164*de0e0e4dSAntonio Huete Jimenez 
165*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.reject == NULL &&
166*de0e0e4dSAntonio Huete Jimenez 	    (x509_config.reject = sk_ASN1_OBJECT_new_null()) == NULL)
167*de0e0e4dSAntonio Huete Jimenez 		return (1);
168*de0e0e4dSAntonio Huete Jimenez 
169*de0e0e4dSAntonio Huete Jimenez 	if (!sk_ASN1_OBJECT_push(x509_config.reject, x509_config.objtmp))
170*de0e0e4dSAntonio Huete Jimenez 		return (1);
171*de0e0e4dSAntonio Huete Jimenez 
172*de0e0e4dSAntonio Huete Jimenez 	x509_config.trustout = 1;
173*de0e0e4dSAntonio Huete Jimenez 	return (0);
174*de0e0e4dSAntonio Huete Jimenez }
175*de0e0e4dSAntonio Huete Jimenez 
176*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_addtrust(char * arg)177*de0e0e4dSAntonio Huete Jimenez x509_opt_addtrust(char *arg)
178*de0e0e4dSAntonio Huete Jimenez {
179*de0e0e4dSAntonio Huete Jimenez 	if ((x509_config.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
180*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Invalid trust object value %s\n", arg);
181*de0e0e4dSAntonio Huete Jimenez 		return (1);
182*de0e0e4dSAntonio Huete Jimenez 	}
183*de0e0e4dSAntonio Huete Jimenez 
184*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.trust == NULL &&
185*de0e0e4dSAntonio Huete Jimenez 	    (x509_config.trust = sk_ASN1_OBJECT_new_null()) == NULL)
186*de0e0e4dSAntonio Huete Jimenez 		return (1);
187*de0e0e4dSAntonio Huete Jimenez 
188*de0e0e4dSAntonio Huete Jimenez 	if (!sk_ASN1_OBJECT_push(x509_config.trust, x509_config.objtmp))
189*de0e0e4dSAntonio Huete Jimenez 		return (1);
190*de0e0e4dSAntonio Huete Jimenez 
191*de0e0e4dSAntonio Huete Jimenez 	x509_config.trustout = 1;
192*de0e0e4dSAntonio Huete Jimenez 	return (0);
193*de0e0e4dSAntonio Huete Jimenez }
194*de0e0e4dSAntonio Huete Jimenez 
195*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_ca(char * arg)196*de0e0e4dSAntonio Huete Jimenez x509_opt_ca(char *arg)
197*de0e0e4dSAntonio Huete Jimenez {
198*de0e0e4dSAntonio Huete Jimenez 	x509_config.CAfile = arg;
199*de0e0e4dSAntonio Huete Jimenez 	x509_config.CA_flag = ++x509_config.num;
200*de0e0e4dSAntonio Huete Jimenez 	return (0);
201*de0e0e4dSAntonio Huete Jimenez }
202*de0e0e4dSAntonio Huete Jimenez 
203*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_certopt(char * arg)204*de0e0e4dSAntonio Huete Jimenez x509_opt_certopt(char *arg)
205*de0e0e4dSAntonio Huete Jimenez {
206*de0e0e4dSAntonio Huete Jimenez 	if (!set_cert_ex(&x509_config.certflag, arg))
207*de0e0e4dSAntonio Huete Jimenez 		return (1);
208*de0e0e4dSAntonio Huete Jimenez 
209*de0e0e4dSAntonio Huete Jimenez 	return (0);
210*de0e0e4dSAntonio Huete Jimenez }
211*de0e0e4dSAntonio Huete Jimenez 
212*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_checkend(char * arg)213*de0e0e4dSAntonio Huete Jimenez x509_opt_checkend(char *arg)
214*de0e0e4dSAntonio Huete Jimenez {
215*de0e0e4dSAntonio Huete Jimenez 	const char *errstr;
216*de0e0e4dSAntonio Huete Jimenez 
217*de0e0e4dSAntonio Huete Jimenez 	x509_config.checkoffset = strtonum(arg, 0, INT_MAX, &errstr);
218*de0e0e4dSAntonio Huete Jimenez 	if (errstr != NULL) {
219*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
220*de0e0e4dSAntonio Huete Jimenez 		return (1);
221*de0e0e4dSAntonio Huete Jimenez 	}
222*de0e0e4dSAntonio Huete Jimenez 	x509_config.checkend = 1;
223*de0e0e4dSAntonio Huete Jimenez 	return (0);
224*de0e0e4dSAntonio Huete Jimenez }
225*de0e0e4dSAntonio Huete Jimenez 
226*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_dates(void)227*de0e0e4dSAntonio Huete Jimenez x509_opt_dates(void)
228*de0e0e4dSAntonio Huete Jimenez {
229*de0e0e4dSAntonio Huete Jimenez 	x509_config.startdate = ++x509_config.num;
230*de0e0e4dSAntonio Huete Jimenez 	x509_config.enddate = ++x509_config.num;
231*de0e0e4dSAntonio Huete Jimenez 	return (0);
232*de0e0e4dSAntonio Huete Jimenez }
233*de0e0e4dSAntonio Huete Jimenez 
234*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_days(char * arg)235*de0e0e4dSAntonio Huete Jimenez x509_opt_days(char *arg)
236*de0e0e4dSAntonio Huete Jimenez {
237*de0e0e4dSAntonio Huete Jimenez 	const char *errstr;
238*de0e0e4dSAntonio Huete Jimenez 
239*de0e0e4dSAntonio Huete Jimenez 	x509_config.days = strtonum(arg, 1, INT_MAX, &errstr);
240*de0e0e4dSAntonio Huete Jimenez 	if (errstr != NULL) {
241*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "bad number of days: %s\n", errstr);
242*de0e0e4dSAntonio Huete Jimenez 		return (1);
243*de0e0e4dSAntonio Huete Jimenez 	}
244*de0e0e4dSAntonio Huete Jimenez 	return (0);
245*de0e0e4dSAntonio Huete Jimenez }
246*de0e0e4dSAntonio Huete Jimenez 
247*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_digest(int argc,char ** argv,int * argsused)248*de0e0e4dSAntonio Huete Jimenez x509_opt_digest(int argc, char **argv, int *argsused)
249*de0e0e4dSAntonio Huete Jimenez {
250*de0e0e4dSAntonio Huete Jimenez 	char *name = argv[0];
251*de0e0e4dSAntonio Huete Jimenez 
252*de0e0e4dSAntonio Huete Jimenez 	if (*name++ != '-')
253*de0e0e4dSAntonio Huete Jimenez 		return (1);
254*de0e0e4dSAntonio Huete Jimenez 
255*de0e0e4dSAntonio Huete Jimenez 	if ((x509_config.md_alg = EVP_get_digestbyname(name)) != NULL) {
256*de0e0e4dSAntonio Huete Jimenez 		x509_config.digest = x509_config.md_alg;
257*de0e0e4dSAntonio Huete Jimenez 	} else {
258*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "unknown option %s\n", *argv);
259*de0e0e4dSAntonio Huete Jimenez 		x509_config.badops = 1;
260*de0e0e4dSAntonio Huete Jimenez 		return (1);
261*de0e0e4dSAntonio Huete Jimenez 	}
262*de0e0e4dSAntonio Huete Jimenez 
263*de0e0e4dSAntonio Huete Jimenez 	*argsused = 1;
264*de0e0e4dSAntonio Huete Jimenez 	return (0);
265*de0e0e4dSAntonio Huete Jimenez }
266*de0e0e4dSAntonio Huete Jimenez 
267*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_nameopt(char * arg)268*de0e0e4dSAntonio Huete Jimenez x509_opt_nameopt(char *arg)
269*de0e0e4dSAntonio Huete Jimenez {
270*de0e0e4dSAntonio Huete Jimenez 	if (!set_name_ex(&x509_config.nmflag, arg))
271*de0e0e4dSAntonio Huete Jimenez 		return (1);
272*de0e0e4dSAntonio Huete Jimenez 
273*de0e0e4dSAntonio Huete Jimenez 	return (0);
274*de0e0e4dSAntonio Huete Jimenez }
275*de0e0e4dSAntonio Huete Jimenez 
276*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_set_serial(char * arg)277*de0e0e4dSAntonio Huete Jimenez x509_opt_set_serial(char *arg)
278*de0e0e4dSAntonio Huete Jimenez {
279*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER_free(x509_config.sno);
280*de0e0e4dSAntonio Huete Jimenez 	if ((x509_config.sno = s2i_ASN1_INTEGER(NULL, arg)) == NULL)
281*de0e0e4dSAntonio Huete Jimenez 		return (1);
282*de0e0e4dSAntonio Huete Jimenez 
283*de0e0e4dSAntonio Huete Jimenez 	return (0);
284*de0e0e4dSAntonio Huete Jimenez }
285*de0e0e4dSAntonio Huete Jimenez 
286*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_setalias(char * arg)287*de0e0e4dSAntonio Huete Jimenez x509_opt_setalias(char *arg)
288*de0e0e4dSAntonio Huete Jimenez {
289*de0e0e4dSAntonio Huete Jimenez 	x509_config.alias = arg;
290*de0e0e4dSAntonio Huete Jimenez 	x509_config.trustout = 1;
291*de0e0e4dSAntonio Huete Jimenez 	return (0);
292*de0e0e4dSAntonio Huete Jimenez }
293*de0e0e4dSAntonio Huete Jimenez 
294*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_signkey(char * arg)295*de0e0e4dSAntonio Huete Jimenez x509_opt_signkey(char *arg)
296*de0e0e4dSAntonio Huete Jimenez {
297*de0e0e4dSAntonio Huete Jimenez 	x509_config.keyfile = arg;
298*de0e0e4dSAntonio Huete Jimenez 	x509_config.sign_flag = ++x509_config.num;
299*de0e0e4dSAntonio Huete Jimenez 	return (0);
300*de0e0e4dSAntonio Huete Jimenez }
301*de0e0e4dSAntonio Huete Jimenez 
302*de0e0e4dSAntonio Huete Jimenez static int
x509_opt_sigopt(char * arg)303*de0e0e4dSAntonio Huete Jimenez x509_opt_sigopt(char *arg)
304*de0e0e4dSAntonio Huete Jimenez {
305*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.sigopts == NULL &&
306*de0e0e4dSAntonio Huete Jimenez 	    (x509_config.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
307*de0e0e4dSAntonio Huete Jimenez 		return (1);
308*de0e0e4dSAntonio Huete Jimenez 
309*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(x509_config.sigopts, arg))
310*de0e0e4dSAntonio Huete Jimenez 		return (1);
311*de0e0e4dSAntonio Huete Jimenez 
312*de0e0e4dSAntonio Huete Jimenez 	return (0);
313*de0e0e4dSAntonio Huete Jimenez }
314*de0e0e4dSAntonio Huete Jimenez 
315*de0e0e4dSAntonio Huete Jimenez static const struct option x509_options[] = {
316*de0e0e4dSAntonio Huete Jimenez 	{
317*de0e0e4dSAntonio Huete Jimenez 		.name = "C",
318*de0e0e4dSAntonio Huete Jimenez 		.desc = "Convert the certificate into C code",
319*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
320*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.C,
321*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
322*de0e0e4dSAntonio Huete Jimenez 	},
323*de0e0e4dSAntonio Huete Jimenez 	{
324*de0e0e4dSAntonio Huete Jimenez 		.name = "addreject",
325*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
326*de0e0e4dSAntonio Huete Jimenez 		.desc = "Reject certificate for a given purpose",
327*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
328*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_addreject,
329*de0e0e4dSAntonio Huete Jimenez 	},
330*de0e0e4dSAntonio Huete Jimenez 	{
331*de0e0e4dSAntonio Huete Jimenez 		.name = "addtrust",
332*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
333*de0e0e4dSAntonio Huete Jimenez 		.desc = "Trust certificate for a given purpose",
334*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
335*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_addtrust,
336*de0e0e4dSAntonio Huete Jimenez 	},
337*de0e0e4dSAntonio Huete Jimenez 	{
338*de0e0e4dSAntonio Huete Jimenez 		.name = "alias",
339*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output certificate alias",
340*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
341*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.aliasout,
342*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
343*de0e0e4dSAntonio Huete Jimenez 	},
344*de0e0e4dSAntonio Huete Jimenez 	{
345*de0e0e4dSAntonio Huete Jimenez 		.name = "CA",
346*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
347*de0e0e4dSAntonio Huete Jimenez 		.desc = "CA certificate in PEM format unless -CAform is specified",
348*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
349*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_ca,
350*de0e0e4dSAntonio Huete Jimenez 	},
351*de0e0e4dSAntonio Huete Jimenez 	{
352*de0e0e4dSAntonio Huete Jimenez 		.name = "CAcreateserial",
353*de0e0e4dSAntonio Huete Jimenez 		.desc = "Create serial number file if it does not exist",
354*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
355*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.CA_createserial,
356*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
357*de0e0e4dSAntonio Huete Jimenez 	},
358*de0e0e4dSAntonio Huete Jimenez 	{
359*de0e0e4dSAntonio Huete Jimenez 		.name = "CAform",
360*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
361*de0e0e4dSAntonio Huete Jimenez 		.desc = "CA format - default PEM",
362*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
363*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &x509_config.CAformat,
364*de0e0e4dSAntonio Huete Jimenez 	},
365*de0e0e4dSAntonio Huete Jimenez 	{
366*de0e0e4dSAntonio Huete Jimenez 		.name = "CAkey",
367*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
368*de0e0e4dSAntonio Huete Jimenez 		.desc = "CA key in PEM format unless -CAkeyform is specified\n"
369*de0e0e4dSAntonio Huete Jimenez 			"if omitted, the key is assumed to be in the CA file",
370*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
371*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.CAkeyfile,
372*de0e0e4dSAntonio Huete Jimenez 	},
373*de0e0e4dSAntonio Huete Jimenez 	{
374*de0e0e4dSAntonio Huete Jimenez 		.name = "CAkeyform",
375*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
376*de0e0e4dSAntonio Huete Jimenez 		.desc = "CA key format - default PEM",
377*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
378*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &x509_config.CAkeyformat,
379*de0e0e4dSAntonio Huete Jimenez 	},
380*de0e0e4dSAntonio Huete Jimenez 	{
381*de0e0e4dSAntonio Huete Jimenez 		.name = "CAserial",
382*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
383*de0e0e4dSAntonio Huete Jimenez 		.desc = "Serial file",
384*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
385*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.CAserial,
386*de0e0e4dSAntonio Huete Jimenez 	},
387*de0e0e4dSAntonio Huete Jimenez 	{
388*de0e0e4dSAntonio Huete Jimenez 		.name = "certopt",
389*de0e0e4dSAntonio Huete Jimenez 		.argname = "option",
390*de0e0e4dSAntonio Huete Jimenez 		.desc = "Various certificate text options",
391*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
392*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_certopt,
393*de0e0e4dSAntonio Huete Jimenez 	},
394*de0e0e4dSAntonio Huete Jimenez 	{
395*de0e0e4dSAntonio Huete Jimenez 		.name = "checkend",
396*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
397*de0e0e4dSAntonio Huete Jimenez 		.desc = "Check whether the cert expires in the next arg seconds\n"
398*de0e0e4dSAntonio Huete Jimenez 			"exit 1 if so, 0 if not",
399*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
400*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_checkend,
401*de0e0e4dSAntonio Huete Jimenez 	},
402*de0e0e4dSAntonio Huete Jimenez 	{
403*de0e0e4dSAntonio Huete Jimenez 		.name = "clrext",
404*de0e0e4dSAntonio Huete Jimenez 		.desc = "Clear all extensions",
405*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
406*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &x509_config.clrext,
407*de0e0e4dSAntonio Huete Jimenez 	},
408*de0e0e4dSAntonio Huete Jimenez 	{
409*de0e0e4dSAntonio Huete Jimenez 		.name = "clrreject",
410*de0e0e4dSAntonio Huete Jimenez 		.desc = "Clear all rejected purposes",
411*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
412*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.clrreject,
413*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
414*de0e0e4dSAntonio Huete Jimenez 	},
415*de0e0e4dSAntonio Huete Jimenez 	{
416*de0e0e4dSAntonio Huete Jimenez 		.name = "clrtrust",
417*de0e0e4dSAntonio Huete Jimenez 		.desc = "Clear all trusted purposes",
418*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
419*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.clrtrust,
420*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
421*de0e0e4dSAntonio Huete Jimenez 	},
422*de0e0e4dSAntonio Huete Jimenez 	{
423*de0e0e4dSAntonio Huete Jimenez 		.name = "dates",
424*de0e0e4dSAntonio Huete Jimenez 		.desc = "Both Before and After dates",
425*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FUNC,
426*de0e0e4dSAntonio Huete Jimenez 		.opt.func = x509_opt_dates,
427*de0e0e4dSAntonio Huete Jimenez 	},
428*de0e0e4dSAntonio Huete Jimenez 	{
429*de0e0e4dSAntonio Huete Jimenez 		.name = "days",
430*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
431*de0e0e4dSAntonio Huete Jimenez 		.desc = "How long till expiry of a signed certificate - def 30 days",
432*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
433*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_days,
434*de0e0e4dSAntonio Huete Jimenez 	},
435*de0e0e4dSAntonio Huete Jimenez 	{
436*de0e0e4dSAntonio Huete Jimenez 		.name = "email",
437*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print email address(es)",
438*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
439*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.email,
440*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
441*de0e0e4dSAntonio Huete Jimenez 	},
442*de0e0e4dSAntonio Huete Jimenez 	{
443*de0e0e4dSAntonio Huete Jimenez 		.name = "enddate",
444*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print notAfter field",
445*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
446*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.enddate,
447*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
448*de0e0e4dSAntonio Huete Jimenez 	},
449*de0e0e4dSAntonio Huete Jimenez 	{
450*de0e0e4dSAntonio Huete Jimenez 		.name = "extensions",
451*de0e0e4dSAntonio Huete Jimenez 		.argname = "section",
452*de0e0e4dSAntonio Huete Jimenez 		.desc = "Section from config file with X509V3 extensions to add",
453*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
454*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.extsect,
455*de0e0e4dSAntonio Huete Jimenez 	},
456*de0e0e4dSAntonio Huete Jimenez 	{
457*de0e0e4dSAntonio Huete Jimenez 		.name = "extfile",
458*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
459*de0e0e4dSAntonio Huete Jimenez 		.desc = "Configuration file with X509V3 extensions to add",
460*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
461*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.extfile,
462*de0e0e4dSAntonio Huete Jimenez 	},
463*de0e0e4dSAntonio Huete Jimenez 	{
464*de0e0e4dSAntonio Huete Jimenez 		.name = "fingerprint",
465*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print the certificate fingerprint",
466*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
467*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.fingerprint,
468*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
469*de0e0e4dSAntonio Huete Jimenez 	},
470*de0e0e4dSAntonio Huete Jimenez 	{
471*de0e0e4dSAntonio Huete Jimenez 		.name = "hash",
472*de0e0e4dSAntonio Huete Jimenez 		.desc = "Synonym for -subject_hash",
473*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
474*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.subject_hash,
475*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
476*de0e0e4dSAntonio Huete Jimenez 	},
477*de0e0e4dSAntonio Huete Jimenez 	{
478*de0e0e4dSAntonio Huete Jimenez 		.name = "in",
479*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
480*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input file - default stdin",
481*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
482*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.infile,
483*de0e0e4dSAntonio Huete Jimenez 	},
484*de0e0e4dSAntonio Huete Jimenez 	{
485*de0e0e4dSAntonio Huete Jimenez 		.name = "inform",
486*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
487*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input format - default PEM (one of DER, NET or PEM)",
488*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
489*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &x509_config.informat,
490*de0e0e4dSAntonio Huete Jimenez 	},
491*de0e0e4dSAntonio Huete Jimenez 	{
492*de0e0e4dSAntonio Huete Jimenez 		.name = "issuer",
493*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print issuer name",
494*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
495*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.issuer,
496*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
497*de0e0e4dSAntonio Huete Jimenez 	},
498*de0e0e4dSAntonio Huete Jimenez 	{
499*de0e0e4dSAntonio Huete Jimenez 		.name = "issuer_hash",
500*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print issuer hash value",
501*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
502*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.issuer_hash,
503*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
504*de0e0e4dSAntonio Huete Jimenez 	},
505*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_MD5
506*de0e0e4dSAntonio Huete Jimenez 	{
507*de0e0e4dSAntonio Huete Jimenez 		.name = "issuer_hash_old",
508*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print old-style (MD5) issuer hash value",
509*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
510*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.issuer_hash_old,
511*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
512*de0e0e4dSAntonio Huete Jimenez 	},
513*de0e0e4dSAntonio Huete Jimenez #endif
514*de0e0e4dSAntonio Huete Jimenez 	{
515*de0e0e4dSAntonio Huete Jimenez 		.name = "keyform",
516*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
517*de0e0e4dSAntonio Huete Jimenez 		.desc = "Private key format - default PEM",
518*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
519*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &x509_config.keyformat,
520*de0e0e4dSAntonio Huete Jimenez 	},
521*de0e0e4dSAntonio Huete Jimenez 	{
522*de0e0e4dSAntonio Huete Jimenez 		.name = "modulus",
523*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print the RSA key modulus",
524*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
525*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.modulus,
526*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
527*de0e0e4dSAntonio Huete Jimenez 	},
528*de0e0e4dSAntonio Huete Jimenez 	{
529*de0e0e4dSAntonio Huete Jimenez 		.name = "nameopt",
530*de0e0e4dSAntonio Huete Jimenez 		.argname = "option",
531*de0e0e4dSAntonio Huete Jimenez 		.desc = "Various certificate name options",
532*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
533*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_nameopt,
534*de0e0e4dSAntonio Huete Jimenez 	},
535*de0e0e4dSAntonio Huete Jimenez 	{
536*de0e0e4dSAntonio Huete Jimenez 		.name = "next_serial",
537*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print the next serial number",
538*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
539*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.next_serial,
540*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
541*de0e0e4dSAntonio Huete Jimenez 	},
542*de0e0e4dSAntonio Huete Jimenez 	{
543*de0e0e4dSAntonio Huete Jimenez 		.name = "noout",
544*de0e0e4dSAntonio Huete Jimenez 		.desc = "No certificate output",
545*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
546*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.noout,
547*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
548*de0e0e4dSAntonio Huete Jimenez 	},
549*de0e0e4dSAntonio Huete Jimenez 	{
550*de0e0e4dSAntonio Huete Jimenez 		.name = "ocsp_uri",
551*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print OCSP Responder URL(s)",
552*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
553*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.ocsp_uri,
554*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
555*de0e0e4dSAntonio Huete Jimenez 	},
556*de0e0e4dSAntonio Huete Jimenez 	{
557*de0e0e4dSAntonio Huete Jimenez 		.name = "ocspid",
558*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print OCSP hash values for the subject name and public key",
559*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
560*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.ocspid,
561*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
562*de0e0e4dSAntonio Huete Jimenez 	},
563*de0e0e4dSAntonio Huete Jimenez 	{
564*de0e0e4dSAntonio Huete Jimenez 		.name = "out",
565*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
566*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output file - default stdout",
567*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
568*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.outfile,
569*de0e0e4dSAntonio Huete Jimenez 	},
570*de0e0e4dSAntonio Huete Jimenez 	{
571*de0e0e4dSAntonio Huete Jimenez 		.name = "outform",
572*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
573*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output format - default PEM (one of DER, NET or PEM)",
574*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
575*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &x509_config.outformat,
576*de0e0e4dSAntonio Huete Jimenez 	},
577*de0e0e4dSAntonio Huete Jimenez 	{
578*de0e0e4dSAntonio Huete Jimenez 		.name = "passin",
579*de0e0e4dSAntonio Huete Jimenez 		.argname = "src",
580*de0e0e4dSAntonio Huete Jimenez 		.desc = "Private key password source",
581*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
582*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &x509_config.passargin,
583*de0e0e4dSAntonio Huete Jimenez 	},
584*de0e0e4dSAntonio Huete Jimenez 	{
585*de0e0e4dSAntonio Huete Jimenez 		.name = "pubkey",
586*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output the public key",
587*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
588*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.pubkey,
589*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
590*de0e0e4dSAntonio Huete Jimenez 	},
591*de0e0e4dSAntonio Huete Jimenez 	{
592*de0e0e4dSAntonio Huete Jimenez 		.name = "purpose",
593*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print out certificate purposes",
594*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
595*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.pprint,
596*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
597*de0e0e4dSAntonio Huete Jimenez 	},
598*de0e0e4dSAntonio Huete Jimenez 	{
599*de0e0e4dSAntonio Huete Jimenez 		.name = "req",
600*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input is a certificate request, sign and output",
601*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
602*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &x509_config.reqfile,
603*de0e0e4dSAntonio Huete Jimenez 	},
604*de0e0e4dSAntonio Huete Jimenez 	{
605*de0e0e4dSAntonio Huete Jimenez 		.name = "serial",
606*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print serial number value",
607*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
608*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.serial,
609*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
610*de0e0e4dSAntonio Huete Jimenez 	},
611*de0e0e4dSAntonio Huete Jimenez 	{
612*de0e0e4dSAntonio Huete Jimenez 		.name = "set_serial",
613*de0e0e4dSAntonio Huete Jimenez 		.argname = "n",
614*de0e0e4dSAntonio Huete Jimenez 		.desc = "Serial number to use",
615*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
616*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_set_serial,
617*de0e0e4dSAntonio Huete Jimenez 	},
618*de0e0e4dSAntonio Huete Jimenez 	{
619*de0e0e4dSAntonio Huete Jimenez 		.name = "setalias",
620*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
621*de0e0e4dSAntonio Huete Jimenez 		.desc = "Set certificate alias",
622*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
623*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_setalias,
624*de0e0e4dSAntonio Huete Jimenez 	},
625*de0e0e4dSAntonio Huete Jimenez 	{
626*de0e0e4dSAntonio Huete Jimenez 		.name = "signkey",
627*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
628*de0e0e4dSAntonio Huete Jimenez 		.desc = "Self sign cert with arg",
629*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
630*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_signkey,
631*de0e0e4dSAntonio Huete Jimenez 	},
632*de0e0e4dSAntonio Huete Jimenez 	{
633*de0e0e4dSAntonio Huete Jimenez 		.name = "sigopt",
634*de0e0e4dSAntonio Huete Jimenez 		.argname = "nm:v",
635*de0e0e4dSAntonio Huete Jimenez 		.desc = "Various signature algorithm options",
636*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
637*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = x509_opt_sigopt,
638*de0e0e4dSAntonio Huete Jimenez 	},
639*de0e0e4dSAntonio Huete Jimenez 	{
640*de0e0e4dSAntonio Huete Jimenez 		.name = "startdate",
641*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print notBefore field",
642*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
643*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.startdate,
644*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
645*de0e0e4dSAntonio Huete Jimenez 	},
646*de0e0e4dSAntonio Huete Jimenez 	{
647*de0e0e4dSAntonio Huete Jimenez 		.name = "subject",
648*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print subject name",
649*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
650*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.subject,
651*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
652*de0e0e4dSAntonio Huete Jimenez 	},
653*de0e0e4dSAntonio Huete Jimenez 	{
654*de0e0e4dSAntonio Huete Jimenez 		.name = "subject_hash",
655*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print subject hash value",
656*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
657*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.subject_hash,
658*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
659*de0e0e4dSAntonio Huete Jimenez 	},
660*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_MD5
661*de0e0e4dSAntonio Huete Jimenez 	{
662*de0e0e4dSAntonio Huete Jimenez 		.name = "subject_hash_old",
663*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print old-style (MD5) subject hash value",
664*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
665*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.subject_hash_old,
666*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
667*de0e0e4dSAntonio Huete Jimenez 	},
668*de0e0e4dSAntonio Huete Jimenez #endif
669*de0e0e4dSAntonio Huete Jimenez 	{
670*de0e0e4dSAntonio Huete Jimenez 		.name = "text",
671*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print the certificate in text form",
672*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
673*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.text,
674*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
675*de0e0e4dSAntonio Huete Jimenez 	},
676*de0e0e4dSAntonio Huete Jimenez 	{
677*de0e0e4dSAntonio Huete Jimenez 		.name = "trustout",
678*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output a trusted certificate",
679*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
680*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &x509_config.trustout,
681*de0e0e4dSAntonio Huete Jimenez 	},
682*de0e0e4dSAntonio Huete Jimenez 	{
683*de0e0e4dSAntonio Huete Jimenez 		.name = "x509toreq",
684*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output a certification request object",
685*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ORDER,
686*de0e0e4dSAntonio Huete Jimenez 		.opt.order = &x509_config.x509req,
687*de0e0e4dSAntonio Huete Jimenez 		.order = &x509_config.num,
688*de0e0e4dSAntonio Huete Jimenez 	},
689*de0e0e4dSAntonio Huete Jimenez 	{
690*de0e0e4dSAntonio Huete Jimenez 		.name = NULL,
691*de0e0e4dSAntonio Huete Jimenez 		.desc = "",
692*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
693*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = x509_opt_digest,
694*de0e0e4dSAntonio Huete Jimenez 	},
695*de0e0e4dSAntonio Huete Jimenez 	{ NULL },
696*de0e0e4dSAntonio Huete Jimenez };
697*de0e0e4dSAntonio Huete Jimenez 
698*de0e0e4dSAntonio Huete Jimenez static void
x509_usage(void)699*de0e0e4dSAntonio Huete Jimenez x509_usage(void)
700*de0e0e4dSAntonio Huete Jimenez {
701*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "usage: x509 "
702*de0e0e4dSAntonio Huete Jimenez 	    "[-C] [-addreject arg] [-addtrust arg] [-alias] [-CA file]\n"
703*de0e0e4dSAntonio Huete Jimenez 	    "    [-CAcreateserial] [-CAform der | pem] [-CAkey file]\n"
704*de0e0e4dSAntonio Huete Jimenez 	    "    [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n"
705*de0e0e4dSAntonio Huete Jimenez 	    "    [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n"
706*de0e0e4dSAntonio Huete Jimenez 	    "    [-days arg] [-email] [-enddate] [-extensions section]\n"
707*de0e0e4dSAntonio Huete Jimenez 	    "    [-extfile file] [-fingerprint] [-hash] [-in file]\n"
708*de0e0e4dSAntonio Huete Jimenez 	    "    [-inform der | net | pem] [-issuer] [-issuer_hash]\n"
709*de0e0e4dSAntonio Huete Jimenez 	    "    [-issuer_hash_old] [-keyform der | pem] [-md5 | -sha1]\n"
710*de0e0e4dSAntonio Huete Jimenez 	    "    [-modulus] [-nameopt option] [-next_serial] [-noout]\n"
711*de0e0e4dSAntonio Huete Jimenez 	    "    [-ocsp_uri] [-ocspid] [-out file]\n"
712*de0e0e4dSAntonio Huete Jimenez 	    "    [-outform der | net | pem] [-passin arg] [-pubkey]\n"
713*de0e0e4dSAntonio Huete Jimenez 	    "    [-purpose] [-req] [-serial] [-set_serial n] [-setalias arg]\n"
714*de0e0e4dSAntonio Huete Jimenez 	    "    [-signkey file] [-sigopt nm:v] [-startdate] [-subject]\n"
715*de0e0e4dSAntonio Huete Jimenez 	    "    [-subject_hash] [-subject_hash_old] [-text] [-trustout]\n"
716*de0e0e4dSAntonio Huete Jimenez 	    "    [-x509toreq]\n");
717*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "\n");
718*de0e0e4dSAntonio Huete Jimenez 	options_usage(x509_options);
719*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "\n");
720*de0e0e4dSAntonio Huete Jimenez }
721f5b1c8a1SJohn Marino 
722f5b1c8a1SJohn Marino int
x509_main(int argc,char ** argv)723f5b1c8a1SJohn Marino x509_main(int argc, char **argv)
724f5b1c8a1SJohn Marino {
725f5b1c8a1SJohn Marino 	int ret = 1;
726f5b1c8a1SJohn Marino 	X509_REQ *req = NULL;
727f5b1c8a1SJohn Marino 	X509 *x = NULL, *xca = NULL;
728f5b1c8a1SJohn Marino 	EVP_PKEY *Upkey = NULL, *CApkey = NULL;
729*de0e0e4dSAntonio Huete Jimenez 	int i;
730f5b1c8a1SJohn Marino 	BIO *out = NULL;
731f5b1c8a1SJohn Marino 	BIO *STDout = NULL;
732f5b1c8a1SJohn Marino 	X509_STORE *ctx = NULL;
733f5b1c8a1SJohn Marino 	X509_REQ *rq = NULL;
734f5b1c8a1SJohn Marino 	char buf[256];
735f5b1c8a1SJohn Marino 	CONF *extconf = NULL;
736*de0e0e4dSAntonio Huete Jimenez 	char *passin = NULL;
737f5b1c8a1SJohn Marino 
738f5b1c8a1SJohn Marino 	if (single_execution) {
73972c33676SMaxim Ag 		if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
740f5b1c8a1SJohn Marino 			perror("pledge");
741f5b1c8a1SJohn Marino 			exit(1);
742f5b1c8a1SJohn Marino 		}
743f5b1c8a1SJohn Marino 	}
744f5b1c8a1SJohn Marino 
745*de0e0e4dSAntonio Huete Jimenez 	memset(&x509_config, 0, sizeof(x509_config));
746*de0e0e4dSAntonio Huete Jimenez 	x509_config.days = DEF_DAYS;
747*de0e0e4dSAntonio Huete Jimenez 	x509_config.informat = FORMAT_PEM;
748*de0e0e4dSAntonio Huete Jimenez 	x509_config.outformat = FORMAT_PEM;
749*de0e0e4dSAntonio Huete Jimenez 	x509_config.keyformat = FORMAT_PEM;
750*de0e0e4dSAntonio Huete Jimenez 	x509_config.CAformat = FORMAT_PEM;
751*de0e0e4dSAntonio Huete Jimenez 	x509_config.CAkeyformat = FORMAT_PEM;
752f5b1c8a1SJohn Marino 
753f5b1c8a1SJohn Marino 	STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
754f5b1c8a1SJohn Marino 
755f5b1c8a1SJohn Marino 	ctx = X509_STORE_new();
756f5b1c8a1SJohn Marino 	if (ctx == NULL)
757f5b1c8a1SJohn Marino 		goto end;
758f5b1c8a1SJohn Marino 	X509_STORE_set_verify_cb(ctx, callb);
759f5b1c8a1SJohn Marino 
760*de0e0e4dSAntonio Huete Jimenez 	if (options_parse(argc, argv, x509_options, NULL, NULL) != 0)
761f5b1c8a1SJohn Marino 		goto bad;
762f5b1c8a1SJohn Marino 
763*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.badops) {
764f5b1c8a1SJohn Marino  bad:
765*de0e0e4dSAntonio Huete Jimenez 		x509_usage();
766f5b1c8a1SJohn Marino 		goto end;
767f5b1c8a1SJohn Marino 	}
768f5b1c8a1SJohn Marino 
769*de0e0e4dSAntonio Huete Jimenez 	if (!app_passwd(bio_err, x509_config.passargin, NULL, &passin, NULL)) {
770f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "Error getting password\n");
771f5b1c8a1SJohn Marino 		goto end;
772f5b1c8a1SJohn Marino 	}
773f5b1c8a1SJohn Marino 	if (!X509_STORE_set_default_paths(ctx)) {
774f5b1c8a1SJohn Marino 		ERR_print_errors(bio_err);
775f5b1c8a1SJohn Marino 		goto end;
776f5b1c8a1SJohn Marino 	}
777*de0e0e4dSAntonio Huete Jimenez 	if ((x509_config.CAkeyfile == NULL) && (x509_config.CA_flag) &&
778*de0e0e4dSAntonio Huete Jimenez 	    (x509_config.CAformat == FORMAT_PEM)) {
779*de0e0e4dSAntonio Huete Jimenez 		x509_config.CAkeyfile = x509_config.CAfile;
780*de0e0e4dSAntonio Huete Jimenez 	} else if ((x509_config.CA_flag) && (x509_config.CAkeyfile == NULL)) {
781f5b1c8a1SJohn Marino 		BIO_printf(bio_err,
782f5b1c8a1SJohn Marino 		    "need to specify a CAkey if using the CA command\n");
783f5b1c8a1SJohn Marino 		goto end;
784f5b1c8a1SJohn Marino 	}
785*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.extfile != NULL) {
786f5b1c8a1SJohn Marino 		long errorline = -1;
787f5b1c8a1SJohn Marino 		X509V3_CTX ctx2;
788f5b1c8a1SJohn Marino 		extconf = NCONF_new(NULL);
789*de0e0e4dSAntonio Huete Jimenez 		if (!NCONF_load(extconf, x509_config.extfile, &errorline)) {
790f5b1c8a1SJohn Marino 			if (errorline <= 0)
791f5b1c8a1SJohn Marino 				BIO_printf(bio_err,
792f5b1c8a1SJohn Marino 				    "error loading the config file '%s'\n",
793*de0e0e4dSAntonio Huete Jimenez 				    x509_config.extfile);
794f5b1c8a1SJohn Marino 			else
795f5b1c8a1SJohn Marino 				BIO_printf(bio_err,
796f5b1c8a1SJohn Marino 				    "error on line %ld of config file '%s'\n",
797*de0e0e4dSAntonio Huete Jimenez 				    errorline, x509_config.extfile);
798f5b1c8a1SJohn Marino 			goto end;
799f5b1c8a1SJohn Marino 		}
800*de0e0e4dSAntonio Huete Jimenez 		if (x509_config.extsect == NULL) {
801*de0e0e4dSAntonio Huete Jimenez 			x509_config.extsect = NCONF_get_string(extconf,
802*de0e0e4dSAntonio Huete Jimenez 			    "default", "extensions");
803*de0e0e4dSAntonio Huete Jimenez 			if (x509_config.extsect == NULL) {
804f5b1c8a1SJohn Marino 				ERR_clear_error();
805*de0e0e4dSAntonio Huete Jimenez 				x509_config.extsect = "default";
806f5b1c8a1SJohn Marino 			}
807f5b1c8a1SJohn Marino 		}
808f5b1c8a1SJohn Marino 		X509V3_set_ctx_test(&ctx2);
809f5b1c8a1SJohn Marino 		X509V3_set_nconf(&ctx2, extconf);
810*de0e0e4dSAntonio Huete Jimenez 		if (!X509V3_EXT_add_nconf(extconf, &ctx2, x509_config.extsect,
811*de0e0e4dSAntonio Huete Jimenez 		    NULL)) {
812f5b1c8a1SJohn Marino 			BIO_printf(bio_err,
813f5b1c8a1SJohn Marino 			    "Error Loading extension section %s\n",
814*de0e0e4dSAntonio Huete Jimenez 			    x509_config.extsect);
815f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
816f5b1c8a1SJohn Marino 			goto end;
817f5b1c8a1SJohn Marino 		}
818f5b1c8a1SJohn Marino 	}
819*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.reqfile) {
820f5b1c8a1SJohn Marino 		EVP_PKEY *pkey;
821f5b1c8a1SJohn Marino 		BIO *in;
822f5b1c8a1SJohn Marino 
823*de0e0e4dSAntonio Huete Jimenez 		if (!x509_config.sign_flag && !x509_config.CA_flag) {
824*de0e0e4dSAntonio Huete Jimenez 			BIO_printf(bio_err,
825*de0e0e4dSAntonio Huete Jimenez 			    "We need a private key to sign with\n");
826f5b1c8a1SJohn Marino 			goto end;
827f5b1c8a1SJohn Marino 		}
828f5b1c8a1SJohn Marino 		in = BIO_new(BIO_s_file());
829f5b1c8a1SJohn Marino 		if (in == NULL) {
830f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
831f5b1c8a1SJohn Marino 			goto end;
832f5b1c8a1SJohn Marino 		}
833*de0e0e4dSAntonio Huete Jimenez 		if (x509_config.infile == NULL)
834f5b1c8a1SJohn Marino 			BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
835f5b1c8a1SJohn Marino 		else {
836*de0e0e4dSAntonio Huete Jimenez 			if (BIO_read_filename(in, x509_config.infile) <= 0) {
837*de0e0e4dSAntonio Huete Jimenez 				perror(x509_config.infile);
838f5b1c8a1SJohn Marino 				BIO_free(in);
839f5b1c8a1SJohn Marino 				goto end;
840f5b1c8a1SJohn Marino 			}
841f5b1c8a1SJohn Marino 		}
842f5b1c8a1SJohn Marino 		req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
843f5b1c8a1SJohn Marino 		BIO_free(in);
844f5b1c8a1SJohn Marino 
845f5b1c8a1SJohn Marino 		if (req == NULL) {
846f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
847f5b1c8a1SJohn Marino 			goto end;
848f5b1c8a1SJohn Marino 		}
849*de0e0e4dSAntonio Huete Jimenez 		if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
850f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "error unpacking public key\n");
851f5b1c8a1SJohn Marino 			goto end;
852f5b1c8a1SJohn Marino 		}
853f5b1c8a1SJohn Marino 		i = X509_REQ_verify(req, pkey);
854f5b1c8a1SJohn Marino 		if (i < 0) {
855f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "Signature verification error\n");
856f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
857f5b1c8a1SJohn Marino 			goto end;
858f5b1c8a1SJohn Marino 		}
859f5b1c8a1SJohn Marino 		if (i == 0) {
860*de0e0e4dSAntonio Huete Jimenez 			BIO_printf(bio_err,
861*de0e0e4dSAntonio Huete Jimenez 			    "Signature did not match the certificate request\n");
862f5b1c8a1SJohn Marino 			goto end;
863f5b1c8a1SJohn Marino 		} else
864f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "Signature ok\n");
865f5b1c8a1SJohn Marino 
866*de0e0e4dSAntonio Huete Jimenez 		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
867*de0e0e4dSAntonio Huete Jimenez 		    x509_config.nmflag);
868f5b1c8a1SJohn Marino 
869f5b1c8a1SJohn Marino 		if ((x = X509_new()) == NULL)
870f5b1c8a1SJohn Marino 			goto end;
871f5b1c8a1SJohn Marino 
872*de0e0e4dSAntonio Huete Jimenez 		if (x509_config.sno == NULL) {
873*de0e0e4dSAntonio Huete Jimenez 			x509_config.sno = ASN1_INTEGER_new();
874*de0e0e4dSAntonio Huete Jimenez 			if (x509_config.sno == NULL ||
875*de0e0e4dSAntonio Huete Jimenez 			    !rand_serial(NULL, x509_config.sno))
876f5b1c8a1SJohn Marino 				goto end;
877*de0e0e4dSAntonio Huete Jimenez 			if (!X509_set_serialNumber(x, x509_config.sno))
878f5b1c8a1SJohn Marino 				goto end;
879*de0e0e4dSAntonio Huete Jimenez 			ASN1_INTEGER_free(x509_config.sno);
880*de0e0e4dSAntonio Huete Jimenez 			x509_config.sno = NULL;
881*de0e0e4dSAntonio Huete Jimenez 		} else if (!X509_set_serialNumber(x, x509_config.sno))
882f5b1c8a1SJohn Marino 			goto end;
883f5b1c8a1SJohn Marino 
884*de0e0e4dSAntonio Huete Jimenez 		if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
885f5b1c8a1SJohn Marino 			goto end;
886*de0e0e4dSAntonio Huete Jimenez 		if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
887f5b1c8a1SJohn Marino 			goto end;
888f5b1c8a1SJohn Marino 
889*de0e0e4dSAntonio Huete Jimenez 		if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
890*de0e0e4dSAntonio Huete Jimenez 			goto end;
891*de0e0e4dSAntonio Huete Jimenez 		if (X509_time_adj_ex(X509_get_notAfter(x), x509_config.days, 0,
892*de0e0e4dSAntonio Huete Jimenez 		    NULL) == NULL)
893*de0e0e4dSAntonio Huete Jimenez 			goto end;
894f5b1c8a1SJohn Marino 
895*de0e0e4dSAntonio Huete Jimenez 		if ((pkey = X509_REQ_get0_pubkey(req)) == NULL)
896*de0e0e4dSAntonio Huete Jimenez 			goto end;
897*de0e0e4dSAntonio Huete Jimenez 		if (!X509_set_pubkey(x, pkey)) {
898f5b1c8a1SJohn Marino 			EVP_PKEY_free(pkey);
899*de0e0e4dSAntonio Huete Jimenez 			goto end;
900*de0e0e4dSAntonio Huete Jimenez 		}
901*de0e0e4dSAntonio Huete Jimenez 	} else {
902*de0e0e4dSAntonio Huete Jimenez 		x = load_cert(bio_err, x509_config.infile, x509_config.informat,
903*de0e0e4dSAntonio Huete Jimenez 		    NULL, "Certificate");
904*de0e0e4dSAntonio Huete Jimenez 	}
905f5b1c8a1SJohn Marino 	if (x == NULL)
906f5b1c8a1SJohn Marino 		goto end;
907*de0e0e4dSAntonio Huete Jimenez 
908*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.CA_flag) {
909*de0e0e4dSAntonio Huete Jimenez 		xca = load_cert(bio_err, x509_config.CAfile,
910*de0e0e4dSAntonio Huete Jimenez 		    x509_config.CAformat, NULL, "CA Certificate");
911f5b1c8a1SJohn Marino 		if (xca == NULL)
912f5b1c8a1SJohn Marino 			goto end;
913f5b1c8a1SJohn Marino 	}
914*de0e0e4dSAntonio Huete Jimenez 	if (!x509_config.noout || x509_config.text || x509_config.next_serial) {
915*de0e0e4dSAntonio Huete Jimenez 		OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
916f5b1c8a1SJohn Marino 
917f5b1c8a1SJohn Marino 		out = BIO_new(BIO_s_file());
918f5b1c8a1SJohn Marino 		if (out == NULL) {
919f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
920f5b1c8a1SJohn Marino 			goto end;
921f5b1c8a1SJohn Marino 		}
922*de0e0e4dSAntonio Huete Jimenez 		if (x509_config.outfile == NULL) {
923f5b1c8a1SJohn Marino 			BIO_set_fp(out, stdout, BIO_NOCLOSE);
924f5b1c8a1SJohn Marino 		} else {
925*de0e0e4dSAntonio Huete Jimenez 			if (BIO_write_filename(out, x509_config.outfile) <= 0) {
926*de0e0e4dSAntonio Huete Jimenez 				perror(x509_config.outfile);
927f5b1c8a1SJohn Marino 				goto end;
928f5b1c8a1SJohn Marino 			}
929f5b1c8a1SJohn Marino 		}
930f5b1c8a1SJohn Marino 	}
931*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.alias != NULL) {
932*de0e0e4dSAntonio Huete Jimenez 		if (!X509_alias_set1(x, (unsigned char *)x509_config.alias, -1))
933*de0e0e4dSAntonio Huete Jimenez 			goto end;
934*de0e0e4dSAntonio Huete Jimenez 	}
935f5b1c8a1SJohn Marino 
936*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.clrtrust)
937f5b1c8a1SJohn Marino 		X509_trust_clear(x);
938*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.clrreject)
939f5b1c8a1SJohn Marino 		X509_reject_clear(x);
940f5b1c8a1SJohn Marino 
941*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.trust != NULL) {
942*de0e0e4dSAntonio Huete Jimenez 		for (i = 0; i < sk_ASN1_OBJECT_num(x509_config.trust); i++) {
943*de0e0e4dSAntonio Huete Jimenez 			x509_config.objtmp = sk_ASN1_OBJECT_value(
944*de0e0e4dSAntonio Huete Jimenez 			    x509_config.trust, i);
945*de0e0e4dSAntonio Huete Jimenez 			if (!X509_add1_trust_object(x, x509_config.objtmp))
946*de0e0e4dSAntonio Huete Jimenez 				goto end;
947f5b1c8a1SJohn Marino 		}
948f5b1c8a1SJohn Marino 	}
949*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.reject != NULL) {
950*de0e0e4dSAntonio Huete Jimenez 		for (i = 0; i < sk_ASN1_OBJECT_num(x509_config.reject); i++) {
951*de0e0e4dSAntonio Huete Jimenez 			x509_config.objtmp = sk_ASN1_OBJECT_value(
952*de0e0e4dSAntonio Huete Jimenez 			    x509_config.reject, i);
953*de0e0e4dSAntonio Huete Jimenez 			if (!X509_add1_reject_object(x, x509_config.objtmp))
954*de0e0e4dSAntonio Huete Jimenez 				goto end;
955f5b1c8a1SJohn Marino 		}
956f5b1c8a1SJohn Marino 	}
957*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.num) {
958*de0e0e4dSAntonio Huete Jimenez 		for (i = 1; i <= x509_config.num; i++) {
959*de0e0e4dSAntonio Huete Jimenez 			if (x509_config.issuer == i) {
960f5b1c8a1SJohn Marino 				print_name(STDout, "issuer= ",
961*de0e0e4dSAntonio Huete Jimenez 				    X509_get_issuer_name(x),
962*de0e0e4dSAntonio Huete Jimenez 				    x509_config.nmflag);
963*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.subject == i) {
964f5b1c8a1SJohn Marino 				print_name(STDout, "subject= ",
965*de0e0e4dSAntonio Huete Jimenez 				    X509_get_subject_name(x),
966*de0e0e4dSAntonio Huete Jimenez 				    x509_config.nmflag);
967*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.serial == i) {
968f5b1c8a1SJohn Marino 				BIO_printf(STDout, "serial=");
969f5b1c8a1SJohn Marino 				i2a_ASN1_INTEGER(STDout,
970f5b1c8a1SJohn Marino 				    X509_get_serialNumber(x));
971f5b1c8a1SJohn Marino 				BIO_printf(STDout, "\n");
972*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.next_serial == i) {
973f5b1c8a1SJohn Marino 				BIGNUM *bnser;
974f5b1c8a1SJohn Marino 				ASN1_INTEGER *ser;
975f5b1c8a1SJohn Marino 				ser = X509_get_serialNumber(x);
976*de0e0e4dSAntonio Huete Jimenez 				if (ser == NULL)
977*de0e0e4dSAntonio Huete Jimenez 					goto end;
978f5b1c8a1SJohn Marino 				bnser = ASN1_INTEGER_to_BN(ser, NULL);
979*de0e0e4dSAntonio Huete Jimenez 				if (bnser == NULL)
980f5b1c8a1SJohn Marino 					goto end;
981*de0e0e4dSAntonio Huete Jimenez 				if (!BN_add_word(bnser, 1)) {
982*de0e0e4dSAntonio Huete Jimenez 					BN_free(bnser);
983f5b1c8a1SJohn Marino 					goto end;
984*de0e0e4dSAntonio Huete Jimenez 				}
985f5b1c8a1SJohn Marino 				ser = BN_to_ASN1_INTEGER(bnser, NULL);
986*de0e0e4dSAntonio Huete Jimenez 				if (ser == NULL) {
987*de0e0e4dSAntonio Huete Jimenez 					BN_free(bnser);
988f5b1c8a1SJohn Marino 					goto end;
989*de0e0e4dSAntonio Huete Jimenez 				}
990f5b1c8a1SJohn Marino 				BN_free(bnser);
991f5b1c8a1SJohn Marino 				i2a_ASN1_INTEGER(out, ser);
992f5b1c8a1SJohn Marino 				ASN1_INTEGER_free(ser);
993f5b1c8a1SJohn Marino 				BIO_puts(out, "\n");
994*de0e0e4dSAntonio Huete Jimenez 			} else if ((x509_config.email == i) ||
995*de0e0e4dSAntonio Huete Jimenez 			    (x509_config.ocsp_uri == i)) {
996f5b1c8a1SJohn Marino 				int j;
997f5b1c8a1SJohn Marino 				STACK_OF(OPENSSL_STRING) *emlst;
998*de0e0e4dSAntonio Huete Jimenez 				if (x509_config.email == i)
999f5b1c8a1SJohn Marino 					emlst = X509_get1_email(x);
1000f5b1c8a1SJohn Marino 				else
1001f5b1c8a1SJohn Marino 					emlst = X509_get1_ocsp(x);
1002f5b1c8a1SJohn Marino 				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
1003f5b1c8a1SJohn Marino 					BIO_printf(STDout, "%s\n",
1004f5b1c8a1SJohn Marino 					    sk_OPENSSL_STRING_value(emlst, j));
1005f5b1c8a1SJohn Marino 				X509_email_free(emlst);
1006*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.aliasout == i) {
1007*de0e0e4dSAntonio Huete Jimenez 				unsigned char *albuf;
1008*de0e0e4dSAntonio Huete Jimenez 				int buflen;
1009*de0e0e4dSAntonio Huete Jimenez 				albuf = X509_alias_get0(x, &buflen);
1010*de0e0e4dSAntonio Huete Jimenez 				if (albuf != NULL)
1011*de0e0e4dSAntonio Huete Jimenez 					BIO_printf(STDout, "%.*s\n",
1012*de0e0e4dSAntonio Huete Jimenez 					    buflen, albuf);
1013f5b1c8a1SJohn Marino 				else
1014f5b1c8a1SJohn Marino 					BIO_puts(STDout, "<No Alias>\n");
1015*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.subject_hash == i) {
1016*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout, "%08lx\n",
1017*de0e0e4dSAntonio Huete Jimenez 				    X509_subject_name_hash(x));
1018f5b1c8a1SJohn Marino 			}
1019f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_MD5
1020*de0e0e4dSAntonio Huete Jimenez 			else if (x509_config.subject_hash_old == i) {
1021*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout, "%08lx\n",
1022*de0e0e4dSAntonio Huete Jimenez 				    X509_subject_name_hash_old(x));
1023f5b1c8a1SJohn Marino 			}
1024f5b1c8a1SJohn Marino #endif
1025*de0e0e4dSAntonio Huete Jimenez 			else if (x509_config.issuer_hash == i) {
1026*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout, "%08lx\n",
1027*de0e0e4dSAntonio Huete Jimenez 				    X509_issuer_name_hash(x));
1028f5b1c8a1SJohn Marino 			}
1029f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_MD5
1030*de0e0e4dSAntonio Huete Jimenez 			else if (x509_config.issuer_hash_old == i) {
1031*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout, "%08lx\n",
1032*de0e0e4dSAntonio Huete Jimenez 				    X509_issuer_name_hash_old(x));
1033f5b1c8a1SJohn Marino 			}
1034f5b1c8a1SJohn Marino #endif
1035*de0e0e4dSAntonio Huete Jimenez 			else if (x509_config.pprint == i) {
1036f5b1c8a1SJohn Marino 				X509_PURPOSE *ptmp;
1037f5b1c8a1SJohn Marino 				int j;
1038f5b1c8a1SJohn Marino 				BIO_printf(STDout, "Certificate purposes:\n");
1039f5b1c8a1SJohn Marino 				for (j = 0; j < X509_PURPOSE_get_count(); j++) {
1040f5b1c8a1SJohn Marino 					ptmp = X509_PURPOSE_get0(j);
1041f5b1c8a1SJohn Marino 					purpose_print(STDout, x, ptmp);
1042f5b1c8a1SJohn Marino 				}
1043*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.modulus == i) {
1044f5b1c8a1SJohn Marino 				EVP_PKEY *pkey;
1045f5b1c8a1SJohn Marino 
1046*de0e0e4dSAntonio Huete Jimenez 				pkey = X509_get0_pubkey(x);
1047f5b1c8a1SJohn Marino 				if (pkey == NULL) {
1048*de0e0e4dSAntonio Huete Jimenez 					BIO_printf(bio_err,
1049*de0e0e4dSAntonio Huete Jimenez 					    "Modulus=unavailable\n");
1050f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
1051f5b1c8a1SJohn Marino 					goto end;
1052f5b1c8a1SJohn Marino 				}
1053f5b1c8a1SJohn Marino 				BIO_printf(STDout, "Modulus=");
1054*de0e0e4dSAntonio Huete Jimenez 				if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
1055*de0e0e4dSAntonio Huete Jimenez 					RSA *rsa = EVP_PKEY_get0_RSA(pkey);
1056*de0e0e4dSAntonio Huete Jimenez 					const BIGNUM *n = NULL;
1057*de0e0e4dSAntonio Huete Jimenez 
1058*de0e0e4dSAntonio Huete Jimenez 					RSA_get0_key(rsa, &n, NULL, NULL);
1059*de0e0e4dSAntonio Huete Jimenez 					BN_print(STDout, n);
1060*de0e0e4dSAntonio Huete Jimenez 				} else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) {
1061*de0e0e4dSAntonio Huete Jimenez 					DSA *dsa = EVP_PKEY_get0_DSA(pkey);
1062*de0e0e4dSAntonio Huete Jimenez 					const BIGNUM *pub_key = NULL;
1063*de0e0e4dSAntonio Huete Jimenez 
1064*de0e0e4dSAntonio Huete Jimenez 					DSA_get0_key(dsa, &pub_key, NULL);
1065*de0e0e4dSAntonio Huete Jimenez 
1066*de0e0e4dSAntonio Huete Jimenez 					BN_print(STDout, pub_key);
1067*de0e0e4dSAntonio Huete Jimenez 				} else
1068*de0e0e4dSAntonio Huete Jimenez 					BIO_printf(STDout,
1069*de0e0e4dSAntonio Huete Jimenez 					    "Wrong Algorithm type");
1070f5b1c8a1SJohn Marino 				BIO_printf(STDout, "\n");
1071*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.pubkey == i) {
1072f5b1c8a1SJohn Marino 				EVP_PKEY *pkey;
1073f5b1c8a1SJohn Marino 
1074*de0e0e4dSAntonio Huete Jimenez 				pkey = X509_get0_pubkey(x);
1075f5b1c8a1SJohn Marino 				if (pkey == NULL) {
1076*de0e0e4dSAntonio Huete Jimenez 					BIO_printf(bio_err,
1077*de0e0e4dSAntonio Huete Jimenez 					    "Error getting public key\n");
1078f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
1079f5b1c8a1SJohn Marino 					goto end;
1080f5b1c8a1SJohn Marino 				}
1081f5b1c8a1SJohn Marino 				PEM_write_bio_PUBKEY(STDout, pkey);
1082*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.C == i) {
1083f5b1c8a1SJohn Marino 				unsigned char *d;
1084f5b1c8a1SJohn Marino 				char *m;
1085f5b1c8a1SJohn Marino 				int y, z;
1086f5b1c8a1SJohn Marino 
1087*de0e0e4dSAntonio Huete Jimenez 				m = X509_NAME_oneline(X509_get_subject_name(x),
1088f5b1c8a1SJohn Marino 				    buf, sizeof buf);
1089*de0e0e4dSAntonio Huete Jimenez 				if (m == NULL)
1090*de0e0e4dSAntonio Huete Jimenez 					goto end;
1091f5b1c8a1SJohn Marino 				BIO_printf(STDout, "/* subject:%s */\n", buf);
1092*de0e0e4dSAntonio Huete Jimenez 				m = X509_NAME_oneline(X509_get_issuer_name(x),
1093*de0e0e4dSAntonio Huete Jimenez 				    buf, sizeof buf);
1094*de0e0e4dSAntonio Huete Jimenez 				if (m == NULL)
1095*de0e0e4dSAntonio Huete Jimenez 					goto end;
1096f5b1c8a1SJohn Marino 				BIO_printf(STDout, "/* issuer :%s */\n", buf);
1097f5b1c8a1SJohn Marino 
1098f5b1c8a1SJohn Marino 				z = i2d_X509(x, NULL);
1099*de0e0e4dSAntonio Huete Jimenez 				if (z < 0)
1100*de0e0e4dSAntonio Huete Jimenez 					goto end;
1101*de0e0e4dSAntonio Huete Jimenez 
1102f5b1c8a1SJohn Marino 				m = malloc(z);
1103f5b1c8a1SJohn Marino 				if (m == NULL) {
1104f5b1c8a1SJohn Marino 					BIO_printf(bio_err, "out of mem\n");
1105f5b1c8a1SJohn Marino 					goto end;
1106f5b1c8a1SJohn Marino 				}
1107f5b1c8a1SJohn Marino 
1108f5b1c8a1SJohn Marino 				d = (unsigned char *) m;
1109f5b1c8a1SJohn Marino 				z = i2d_X509_NAME(X509_get_subject_name(x), &d);
1110*de0e0e4dSAntonio Huete Jimenez 				if (z < 0) {
1111*de0e0e4dSAntonio Huete Jimenez 					free(m);
1112*de0e0e4dSAntonio Huete Jimenez 					goto end;
1113*de0e0e4dSAntonio Huete Jimenez 				}
1114*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout,
1115*de0e0e4dSAntonio Huete Jimenez 				    "unsigned char XXX_subject_name[%d]={\n", z);
1116f5b1c8a1SJohn Marino 				d = (unsigned char *) m;
1117f5b1c8a1SJohn Marino 				for (y = 0; y < z; y++) {
1118f5b1c8a1SJohn Marino 					BIO_printf(STDout, "0x%02X,", d[y]);
1119f5b1c8a1SJohn Marino 					if ((y & 0x0f) == 0x0f)
1120f5b1c8a1SJohn Marino 						BIO_printf(STDout, "\n");
1121f5b1c8a1SJohn Marino 				}
1122f5b1c8a1SJohn Marino 				if (y % 16 != 0)
1123f5b1c8a1SJohn Marino 					BIO_printf(STDout, "\n");
1124f5b1c8a1SJohn Marino 				BIO_printf(STDout, "};\n");
1125f5b1c8a1SJohn Marino 
1126f5b1c8a1SJohn Marino 				z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
1127*de0e0e4dSAntonio Huete Jimenez 				if (z < 0) {
1128*de0e0e4dSAntonio Huete Jimenez 					free(m);
1129*de0e0e4dSAntonio Huete Jimenez 					goto end;
1130*de0e0e4dSAntonio Huete Jimenez 				}
1131*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout,
1132*de0e0e4dSAntonio Huete Jimenez 				    "unsigned char XXX_public_key[%d]={\n", z);
1133f5b1c8a1SJohn Marino 				d = (unsigned char *) m;
1134f5b1c8a1SJohn Marino 				for (y = 0; y < z; y++) {
1135f5b1c8a1SJohn Marino 					BIO_printf(STDout, "0x%02X,", d[y]);
1136f5b1c8a1SJohn Marino 					if ((y & 0x0f) == 0x0f)
1137f5b1c8a1SJohn Marino 						BIO_printf(STDout, "\n");
1138f5b1c8a1SJohn Marino 				}
1139f5b1c8a1SJohn Marino 				if (y % 16 != 0)
1140f5b1c8a1SJohn Marino 					BIO_printf(STDout, "\n");
1141f5b1c8a1SJohn Marino 				BIO_printf(STDout, "};\n");
1142f5b1c8a1SJohn Marino 
1143f5b1c8a1SJohn Marino 				z = i2d_X509(x, &d);
1144*de0e0e4dSAntonio Huete Jimenez 				if (z < 0) {
1145*de0e0e4dSAntonio Huete Jimenez 					free(m);
1146*de0e0e4dSAntonio Huete Jimenez 					goto end;
1147*de0e0e4dSAntonio Huete Jimenez 				}
1148*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(STDout,
1149*de0e0e4dSAntonio Huete Jimenez 				    "unsigned char XXX_certificate[%d]={\n", z);
1150f5b1c8a1SJohn Marino 				d = (unsigned char *) m;
1151f5b1c8a1SJohn Marino 				for (y = 0; y < z; y++) {
1152f5b1c8a1SJohn Marino 					BIO_printf(STDout, "0x%02X,", d[y]);
1153f5b1c8a1SJohn Marino 					if ((y & 0x0f) == 0x0f)
1154f5b1c8a1SJohn Marino 						BIO_printf(STDout, "\n");
1155f5b1c8a1SJohn Marino 				}
1156f5b1c8a1SJohn Marino 				if (y % 16 != 0)
1157f5b1c8a1SJohn Marino 					BIO_printf(STDout, "\n");
1158f5b1c8a1SJohn Marino 				BIO_printf(STDout, "};\n");
1159f5b1c8a1SJohn Marino 
1160f5b1c8a1SJohn Marino 				free(m);
1161*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.text == i) {
1162*de0e0e4dSAntonio Huete Jimenez 				if(!X509_print_ex(STDout, x, x509_config.nmflag,
1163*de0e0e4dSAntonio Huete Jimenez 				    x509_config.certflag))
1164*de0e0e4dSAntonio Huete Jimenez 					goto end;
1165*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.startdate == i) {
11668edacedfSDaniel Fojt 				ASN1_TIME *nB = X509_get_notBefore(x);
1167f5b1c8a1SJohn Marino 				BIO_puts(STDout, "notBefore=");
1168*de0e0e4dSAntonio Huete Jimenez 				if (ASN1_time_parse(nB->data, nB->length, NULL,
1169*de0e0e4dSAntonio Huete Jimenez 				    0) == -1)
1170*de0e0e4dSAntonio Huete Jimenez 					BIO_puts(STDout,
1171*de0e0e4dSAntonio Huete Jimenez 					    "INVALID RFC5280 TIME");
11728edacedfSDaniel Fojt 				else
11738edacedfSDaniel Fojt 					ASN1_TIME_print(STDout, nB);
1174f5b1c8a1SJohn Marino 				BIO_puts(STDout, "\n");
1175*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.enddate == i) {
11768edacedfSDaniel Fojt 				ASN1_TIME *nA = X509_get_notAfter(x);
1177f5b1c8a1SJohn Marino 				BIO_puts(STDout, "notAfter=");
1178*de0e0e4dSAntonio Huete Jimenez 				if (ASN1_time_parse(nA->data, nA->length, NULL,
1179*de0e0e4dSAntonio Huete Jimenez 				    0) == -1)
1180*de0e0e4dSAntonio Huete Jimenez 					BIO_puts(STDout,
1181*de0e0e4dSAntonio Huete Jimenez 					    "INVALID RFC5280 TIME");
11828edacedfSDaniel Fojt 				else
11838edacedfSDaniel Fojt 					ASN1_TIME_print(STDout, nA);
1184f5b1c8a1SJohn Marino 				BIO_puts(STDout, "\n");
1185*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.fingerprint == i) {
1186f5b1c8a1SJohn Marino 				int j;
1187f5b1c8a1SJohn Marino 				unsigned int n;
1188f5b1c8a1SJohn Marino 				unsigned char md[EVP_MAX_MD_SIZE];
1189*de0e0e4dSAntonio Huete Jimenez 				const EVP_MD *fdig = x509_config.digest;
1190f5b1c8a1SJohn Marino 
1191*de0e0e4dSAntonio Huete Jimenez 				if (fdig == NULL)
119272c33676SMaxim Ag 					fdig = EVP_sha256();
1193f5b1c8a1SJohn Marino 
1194f5b1c8a1SJohn Marino 				if (!X509_digest(x, fdig, md, &n)) {
1195f5b1c8a1SJohn Marino 					BIO_printf(bio_err, "out of memory\n");
1196f5b1c8a1SJohn Marino 					goto end;
1197f5b1c8a1SJohn Marino 				}
1198f5b1c8a1SJohn Marino 				BIO_printf(STDout, "%s Fingerprint=",
1199f5b1c8a1SJohn Marino 				    OBJ_nid2sn(EVP_MD_type(fdig)));
1200f5b1c8a1SJohn Marino 				for (j = 0; j < (int) n; j++) {
1201f5b1c8a1SJohn Marino 					BIO_printf(STDout, "%02X%c", md[j],
1202f5b1c8a1SJohn Marino 					    (j + 1 == (int)n) ? '\n' : ':');
1203f5b1c8a1SJohn Marino 				}
1204*de0e0e4dSAntonio Huete Jimenez 
1205f5b1c8a1SJohn Marino 			/* should be in the library */
1206*de0e0e4dSAntonio Huete Jimenez 			} else if ((x509_config.sign_flag == i) &&
1207*de0e0e4dSAntonio Huete Jimenez 			    (x509_config.x509req == 0)) {
1208f5b1c8a1SJohn Marino 				BIO_printf(bio_err, "Getting Private key\n");
1209f5b1c8a1SJohn Marino 				if (Upkey == NULL) {
1210f5b1c8a1SJohn Marino 					Upkey = load_key(bio_err,
1211*de0e0e4dSAntonio Huete Jimenez 					    x509_config.keyfile,
1212*de0e0e4dSAntonio Huete Jimenez 					    x509_config.keyformat, 0, passin,
1213*de0e0e4dSAntonio Huete Jimenez 					    "Private key");
1214f5b1c8a1SJohn Marino 					if (Upkey == NULL)
1215f5b1c8a1SJohn Marino 						goto end;
1216f5b1c8a1SJohn Marino 				}
1217*de0e0e4dSAntonio Huete Jimenez 				if (!sign(x, Upkey, x509_config.days,
1218*de0e0e4dSAntonio Huete Jimenez 				    x509_config.clrext, x509_config.digest,
1219*de0e0e4dSAntonio Huete Jimenez 				    extconf, x509_config.extsect))
1220f5b1c8a1SJohn Marino 					goto end;
1221*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.CA_flag == i) {
1222f5b1c8a1SJohn Marino 				BIO_printf(bio_err, "Getting CA Private Key\n");
1223*de0e0e4dSAntonio Huete Jimenez 				if (x509_config.CAkeyfile != NULL) {
1224f5b1c8a1SJohn Marino 					CApkey = load_key(bio_err,
1225*de0e0e4dSAntonio Huete Jimenez 					    x509_config.CAkeyfile,
1226*de0e0e4dSAntonio Huete Jimenez 					    x509_config.CAkeyformat, 0, passin,
1227*de0e0e4dSAntonio Huete Jimenez 					    "CA Private Key");
1228f5b1c8a1SJohn Marino 					if (CApkey == NULL)
1229f5b1c8a1SJohn Marino 						goto end;
1230f5b1c8a1SJohn Marino 				}
1231*de0e0e4dSAntonio Huete Jimenez 				if (!x509_certify(ctx, x509_config.CAfile,
1232*de0e0e4dSAntonio Huete Jimenez 				    x509_config.digest, x, xca, CApkey,
1233*de0e0e4dSAntonio Huete Jimenez 				    x509_config.sigopts, x509_config.CAserial,
1234*de0e0e4dSAntonio Huete Jimenez 				    x509_config.CA_createserial,
1235*de0e0e4dSAntonio Huete Jimenez 				    x509_config.days, x509_config.clrext,
1236*de0e0e4dSAntonio Huete Jimenez 				    extconf, x509_config.extsect,
1237*de0e0e4dSAntonio Huete Jimenez 				    x509_config.sno))
1238f5b1c8a1SJohn Marino 					goto end;
1239*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.x509req == i) {
1240f5b1c8a1SJohn Marino 				EVP_PKEY *pk;
1241f5b1c8a1SJohn Marino 
1242*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(bio_err,
1243*de0e0e4dSAntonio Huete Jimenez 				    "Getting request Private Key\n");
1244*de0e0e4dSAntonio Huete Jimenez 				if (x509_config.keyfile == NULL) {
1245*de0e0e4dSAntonio Huete Jimenez 					BIO_printf(bio_err,
1246*de0e0e4dSAntonio Huete Jimenez 					    "no request key file specified\n");
1247f5b1c8a1SJohn Marino 					goto end;
1248f5b1c8a1SJohn Marino 				} else {
1249f5b1c8a1SJohn Marino 					pk = load_key(bio_err,
1250*de0e0e4dSAntonio Huete Jimenez 					    x509_config.keyfile,
1251*de0e0e4dSAntonio Huete Jimenez 					    x509_config.keyformat, 0, passin,
1252*de0e0e4dSAntonio Huete Jimenez 					    "request key");
1253f5b1c8a1SJohn Marino 					if (pk == NULL)
1254f5b1c8a1SJohn Marino 						goto end;
1255f5b1c8a1SJohn Marino 				}
1256f5b1c8a1SJohn Marino 
1257*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(bio_err,
1258*de0e0e4dSAntonio Huete Jimenez 				    "Generating certificate request\n");
1259f5b1c8a1SJohn Marino 
1260*de0e0e4dSAntonio Huete Jimenez 				rq = X509_to_X509_REQ(x, pk, x509_config.digest);
1261f5b1c8a1SJohn Marino 				EVP_PKEY_free(pk);
1262f5b1c8a1SJohn Marino 				if (rq == NULL) {
1263f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
1264f5b1c8a1SJohn Marino 					goto end;
1265f5b1c8a1SJohn Marino 				}
1266*de0e0e4dSAntonio Huete Jimenez 				if (!x509_config.noout) {
1267*de0e0e4dSAntonio Huete Jimenez 					if (!X509_REQ_print(out, rq))
1268*de0e0e4dSAntonio Huete Jimenez 						goto end;
1269*de0e0e4dSAntonio Huete Jimenez 					if (!PEM_write_bio_X509_REQ(out, rq))
1270*de0e0e4dSAntonio Huete Jimenez 						goto end;
1271f5b1c8a1SJohn Marino 				}
1272*de0e0e4dSAntonio Huete Jimenez 				x509_config.noout = 1;
1273*de0e0e4dSAntonio Huete Jimenez 			} else if (x509_config.ocspid == i) {
1274*de0e0e4dSAntonio Huete Jimenez 				if (!X509_ocspid_print(out, x))
1275*de0e0e4dSAntonio Huete Jimenez 					goto end;
1276f5b1c8a1SJohn Marino 			}
1277f5b1c8a1SJohn Marino 		}
1278f5b1c8a1SJohn Marino 	}
1279*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.checkend) {
1280*de0e0e4dSAntonio Huete Jimenez 		time_t tcheck = time(NULL) + x509_config.checkoffset;
12818edacedfSDaniel Fojt 		int timecheck = X509_cmp_time(X509_get_notAfter(x), &tcheck);
12828edacedfSDaniel Fojt 		if (timecheck == 0) {
12838edacedfSDaniel Fojt 			BIO_printf(out, "Certificate expiry time is invalid\n");
12848edacedfSDaniel Fojt 			ret = 1;
12858edacedfSDaniel Fojt 		} else if (timecheck < 0) {
1286f5b1c8a1SJohn Marino 			BIO_printf(out, "Certificate will expire\n");
1287f5b1c8a1SJohn Marino 			ret = 1;
1288f5b1c8a1SJohn Marino 		} else {
1289f5b1c8a1SJohn Marino 			BIO_printf(out, "Certificate will not expire\n");
1290f5b1c8a1SJohn Marino 			ret = 0;
1291f5b1c8a1SJohn Marino 		}
1292f5b1c8a1SJohn Marino 		goto end;
1293f5b1c8a1SJohn Marino 	}
1294*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.noout) {
1295f5b1c8a1SJohn Marino 		ret = 0;
1296f5b1c8a1SJohn Marino 		goto end;
1297f5b1c8a1SJohn Marino 	}
1298*de0e0e4dSAntonio Huete Jimenez 	if (x509_config.outformat == FORMAT_ASN1)
1299f5b1c8a1SJohn Marino 		i = i2d_X509_bio(out, x);
1300*de0e0e4dSAntonio Huete Jimenez 	else if (x509_config.outformat == FORMAT_PEM) {
1301*de0e0e4dSAntonio Huete Jimenez 		if (x509_config.trustout)
1302f5b1c8a1SJohn Marino 			i = PEM_write_bio_X509_AUX(out, x);
1303f5b1c8a1SJohn Marino 		else
1304f5b1c8a1SJohn Marino 			i = PEM_write_bio_X509(out, x);
1305f5b1c8a1SJohn Marino 	} else {
1306*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err,
1307*de0e0e4dSAntonio Huete Jimenez 		    "bad output format specified for outfile\n");
1308f5b1c8a1SJohn Marino 		goto end;
1309f5b1c8a1SJohn Marino 	}
1310f5b1c8a1SJohn Marino 	if (!i) {
1311f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "unable to write certificate\n");
1312f5b1c8a1SJohn Marino 		ERR_print_errors(bio_err);
1313f5b1c8a1SJohn Marino 		goto end;
1314f5b1c8a1SJohn Marino 	}
1315f5b1c8a1SJohn Marino 	ret = 0;
1316f5b1c8a1SJohn Marino 
1317f5b1c8a1SJohn Marino  end:
1318f5b1c8a1SJohn Marino 	OBJ_cleanup();
1319f5b1c8a1SJohn Marino 	NCONF_free(extconf);
1320f5b1c8a1SJohn Marino 	BIO_free_all(out);
1321f5b1c8a1SJohn Marino 	BIO_free_all(STDout);
1322f5b1c8a1SJohn Marino 	X509_STORE_free(ctx);
1323f5b1c8a1SJohn Marino 	X509_REQ_free(req);
1324f5b1c8a1SJohn Marino 	X509_free(x);
1325f5b1c8a1SJohn Marino 	X509_free(xca);
1326f5b1c8a1SJohn Marino 	EVP_PKEY_free(Upkey);
1327f5b1c8a1SJohn Marino 	EVP_PKEY_free(CApkey);
1328*de0e0e4dSAntonio Huete Jimenez 	sk_OPENSSL_STRING_free(x509_config.sigopts);
1329f5b1c8a1SJohn Marino 	X509_REQ_free(rq);
1330*de0e0e4dSAntonio Huete Jimenez 	ASN1_INTEGER_free(x509_config.sno);
1331*de0e0e4dSAntonio Huete Jimenez 	sk_ASN1_OBJECT_pop_free(x509_config.trust, ASN1_OBJECT_free);
1332*de0e0e4dSAntonio Huete Jimenez 	sk_ASN1_OBJECT_pop_free(x509_config.reject, ASN1_OBJECT_free);
1333f5b1c8a1SJohn Marino 	free(passin);
1334f5b1c8a1SJohn Marino 
1335f5b1c8a1SJohn Marino 	return (ret);
1336f5b1c8a1SJohn Marino }
1337f5b1c8a1SJohn Marino 
1338f5b1c8a1SJohn Marino static ASN1_INTEGER *
x509_load_serial(char * CAfile,char * serialfile,int create)1339f5b1c8a1SJohn Marino x509_load_serial(char *CAfile, char *serialfile, int create)
1340f5b1c8a1SJohn Marino {
1341f5b1c8a1SJohn Marino 	char *buf = NULL, *p;
1342f5b1c8a1SJohn Marino 	ASN1_INTEGER *bs = NULL;
1343f5b1c8a1SJohn Marino 	BIGNUM *serial = NULL;
1344f5b1c8a1SJohn Marino 	size_t len;
1345f5b1c8a1SJohn Marino 
1346f5b1c8a1SJohn Marino 	len = ((serialfile == NULL) ? (strlen(CAfile) + strlen(POSTFIX) + 1) :
1347f5b1c8a1SJohn Marino 	    (strlen(serialfile))) + 1;
1348f5b1c8a1SJohn Marino 	buf = malloc(len);
1349f5b1c8a1SJohn Marino 	if (buf == NULL) {
1350f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "out of mem\n");
1351f5b1c8a1SJohn Marino 		goto end;
1352f5b1c8a1SJohn Marino 	}
1353f5b1c8a1SJohn Marino 	if (serialfile == NULL) {
1354f5b1c8a1SJohn Marino 		strlcpy(buf, CAfile, len);
1355f5b1c8a1SJohn Marino 		for (p = buf; *p; p++)
1356f5b1c8a1SJohn Marino 			if (*p == '.') {
1357f5b1c8a1SJohn Marino 				*p = '\0';
1358f5b1c8a1SJohn Marino 				break;
1359f5b1c8a1SJohn Marino 			}
1360f5b1c8a1SJohn Marino 		strlcat(buf, POSTFIX, len);
1361f5b1c8a1SJohn Marino 	} else
1362f5b1c8a1SJohn Marino 		strlcpy(buf, serialfile, len);
1363f5b1c8a1SJohn Marino 
1364f5b1c8a1SJohn Marino 	serial = load_serial(buf, create, NULL);
1365f5b1c8a1SJohn Marino 	if (serial == NULL)
1366f5b1c8a1SJohn Marino 		goto end;
1367f5b1c8a1SJohn Marino 
1368f5b1c8a1SJohn Marino 	if (!BN_add_word(serial, 1)) {
1369f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "add_word failure\n");
1370f5b1c8a1SJohn Marino 		goto end;
1371f5b1c8a1SJohn Marino 	}
1372f5b1c8a1SJohn Marino 	if (!save_serial(buf, NULL, serial, &bs))
1373f5b1c8a1SJohn Marino 		goto end;
1374f5b1c8a1SJohn Marino 
1375f5b1c8a1SJohn Marino  end:
1376f5b1c8a1SJohn Marino 	free(buf);
1377f5b1c8a1SJohn Marino 	BN_free(serial);
1378f5b1c8a1SJohn Marino 
1379f5b1c8a1SJohn Marino 	return bs;
1380f5b1c8a1SJohn Marino }
1381f5b1c8a1SJohn Marino 
1382f5b1c8a1SJohn Marino static int
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)1383f5b1c8a1SJohn Marino x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
1384f5b1c8a1SJohn Marino     X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
1385f5b1c8a1SJohn Marino     char *serialfile, int create, int days, int clrext, CONF *conf,
1386f5b1c8a1SJohn Marino     char *section, ASN1_INTEGER *sno)
1387f5b1c8a1SJohn Marino {
1388f5b1c8a1SJohn Marino 	int ret = 0;
1389f5b1c8a1SJohn Marino 	ASN1_INTEGER *bs = NULL;
1390*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX *xsc = NULL;
1391f5b1c8a1SJohn Marino 	EVP_PKEY *upkey;
1392f5b1c8a1SJohn Marino 
1393*de0e0e4dSAntonio Huete Jimenez 	upkey = X509_get0_pubkey(xca);
1394*de0e0e4dSAntonio Huete Jimenez 	if (upkey == NULL)
1395*de0e0e4dSAntonio Huete Jimenez 		goto end;
1396f5b1c8a1SJohn Marino 	EVP_PKEY_copy_parameters(upkey, pkey);
1397f5b1c8a1SJohn Marino 
1398*de0e0e4dSAntonio Huete Jimenez 	if ((xsc = X509_STORE_CTX_new()) == NULL)
1399*de0e0e4dSAntonio Huete Jimenez 		goto end;
1400*de0e0e4dSAntonio Huete Jimenez 	if (!X509_STORE_CTX_init(xsc, ctx, x, NULL)) {
1401f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "Error initialising X509 store\n");
1402f5b1c8a1SJohn Marino 		goto end;
1403f5b1c8a1SJohn Marino 	}
1404*de0e0e4dSAntonio Huete Jimenez 	if (sno != NULL)
1405f5b1c8a1SJohn Marino 		bs = sno;
1406*de0e0e4dSAntonio Huete Jimenez 	else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
1407f5b1c8a1SJohn Marino 		goto end;
1408f5b1c8a1SJohn Marino 
1409f5b1c8a1SJohn Marino /*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
1410f5b1c8a1SJohn Marino 
1411f5b1c8a1SJohn Marino 	/*
1412f5b1c8a1SJohn Marino 	 * NOTE: this certificate can/should be self signed, unless it was a
1413f5b1c8a1SJohn Marino 	 * certificate request in which case it is not.
1414f5b1c8a1SJohn Marino 	 */
1415*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX_set_cert(xsc, x);
1416*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
1417*de0e0e4dSAntonio Huete Jimenez 	if (!x509_config.reqfile && X509_verify_cert(xsc) <= 0)
1418f5b1c8a1SJohn Marino 		goto end;
1419f5b1c8a1SJohn Marino 
1420f5b1c8a1SJohn Marino 	if (!X509_check_private_key(xca, pkey)) {
1421*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err,
1422*de0e0e4dSAntonio Huete Jimenez 		    "CA certificate and CA private key do not match\n");
1423f5b1c8a1SJohn Marino 		goto end;
1424f5b1c8a1SJohn Marino 	}
1425f5b1c8a1SJohn Marino 	if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
1426f5b1c8a1SJohn Marino 		goto end;
1427f5b1c8a1SJohn Marino 	if (!X509_set_serialNumber(x, bs))
1428f5b1c8a1SJohn Marino 		goto end;
1429f5b1c8a1SJohn Marino 
1430f5b1c8a1SJohn Marino 	if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
1431f5b1c8a1SJohn Marino 		goto end;
1432f5b1c8a1SJohn Marino 
1433f5b1c8a1SJohn Marino 	/* hardwired expired */
1434f5b1c8a1SJohn Marino 	if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
1435f5b1c8a1SJohn Marino 		goto end;
1436f5b1c8a1SJohn Marino 
1437f5b1c8a1SJohn Marino 	if (clrext) {
1438*de0e0e4dSAntonio Huete Jimenez 		while (X509_get_ext_count(x) > 0) {
1439*de0e0e4dSAntonio Huete Jimenez 			if (X509_delete_ext(x, 0) == NULL)
1440*de0e0e4dSAntonio Huete Jimenez 				goto end;
1441f5b1c8a1SJohn Marino 		}
1442*de0e0e4dSAntonio Huete Jimenez 	}
1443*de0e0e4dSAntonio Huete Jimenez 	if (conf != NULL) {
1444f5b1c8a1SJohn Marino 		X509V3_CTX ctx2;
1445*de0e0e4dSAntonio Huete Jimenez 		if (!X509_set_version(x, 2))	/* version 3 certificate */
1446*de0e0e4dSAntonio Huete Jimenez 			goto end;
1447f5b1c8a1SJohn Marino 		X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
1448f5b1c8a1SJohn Marino 		X509V3_set_nconf(&ctx2, conf);
1449f5b1c8a1SJohn Marino 		if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
1450f5b1c8a1SJohn Marino 			goto end;
1451f5b1c8a1SJohn Marino 	}
1452f5b1c8a1SJohn Marino 	if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
1453f5b1c8a1SJohn Marino 		goto end;
1454*de0e0e4dSAntonio Huete Jimenez 
1455f5b1c8a1SJohn Marino 	ret = 1;
1456f5b1c8a1SJohn Marino  end:
1457*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX_free(xsc);
1458f5b1c8a1SJohn Marino 	if (!ret)
1459f5b1c8a1SJohn Marino 		ERR_print_errors(bio_err);
1460*de0e0e4dSAntonio Huete Jimenez 	if (sno == NULL)
1461f5b1c8a1SJohn Marino 		ASN1_INTEGER_free(bs);
1462f5b1c8a1SJohn Marino 	return ret;
1463f5b1c8a1SJohn Marino }
1464f5b1c8a1SJohn Marino 
1465f5b1c8a1SJohn Marino static int
callb(int ok,X509_STORE_CTX * ctx)1466f5b1c8a1SJohn Marino callb(int ok, X509_STORE_CTX *ctx)
1467f5b1c8a1SJohn Marino {
1468f5b1c8a1SJohn Marino 	int err;
1469f5b1c8a1SJohn Marino 	X509 *err_cert;
1470f5b1c8a1SJohn Marino 
1471f5b1c8a1SJohn Marino 	/*
1472f5b1c8a1SJohn Marino 	 * it is ok to use a self signed certificate This case will catch
1473f5b1c8a1SJohn Marino 	 * both the initial ok == 0 and the final ok == 1 calls to this
1474f5b1c8a1SJohn Marino 	 * function
1475f5b1c8a1SJohn Marino 	 */
1476f5b1c8a1SJohn Marino 	err = X509_STORE_CTX_get_error(ctx);
1477f5b1c8a1SJohn Marino 	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
1478f5b1c8a1SJohn Marino 		return 1;
1479f5b1c8a1SJohn Marino 
1480f5b1c8a1SJohn Marino 	/*
1481f5b1c8a1SJohn Marino 	 * BAD we should have gotten an error.  Normally if everything worked
1482f5b1c8a1SJohn Marino 	 * X509_STORE_CTX_get_error(ctx) will still be set to
1483f5b1c8a1SJohn Marino 	 * DEPTH_ZERO_SELF_....
1484f5b1c8a1SJohn Marino 	 */
1485f5b1c8a1SJohn Marino 	if (ok) {
1486*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err,
1487*de0e0e4dSAntonio Huete Jimenez 		    "error with certificate to be certified - should be self signed\n");
1488f5b1c8a1SJohn Marino 		return 0;
1489f5b1c8a1SJohn Marino 	} else {
1490f5b1c8a1SJohn Marino 		err_cert = X509_STORE_CTX_get_current_cert(ctx);
1491f5b1c8a1SJohn Marino 		print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
1492*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err,
1493*de0e0e4dSAntonio Huete Jimenez 		    "error with certificate - error %d at depth %d\n%s\n",
1494f5b1c8a1SJohn Marino 		    err, X509_STORE_CTX_get_error_depth(ctx),
1495f5b1c8a1SJohn Marino 		    X509_verify_cert_error_string(err));
1496f5b1c8a1SJohn Marino 		return 1;
1497f5b1c8a1SJohn Marino 	}
1498f5b1c8a1SJohn Marino }
1499f5b1c8a1SJohn Marino 
1500f5b1c8a1SJohn Marino /* self sign */
1501f5b1c8a1SJohn Marino static int
sign(X509 * x,EVP_PKEY * pkey,int days,int clrext,const EVP_MD * digest,CONF * conf,char * section)1502f5b1c8a1SJohn Marino sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1503f5b1c8a1SJohn Marino     CONF *conf, char *section)
1504f5b1c8a1SJohn Marino {
1505f5b1c8a1SJohn Marino 	EVP_PKEY *pktmp;
1506f5b1c8a1SJohn Marino 
1507*de0e0e4dSAntonio Huete Jimenez 	pktmp = X509_get0_pubkey(x);
1508*de0e0e4dSAntonio Huete Jimenez 	if (pktmp == NULL)
1509*de0e0e4dSAntonio Huete Jimenez 		goto err;
1510f5b1c8a1SJohn Marino 	EVP_PKEY_copy_parameters(pktmp, pkey);
1511f5b1c8a1SJohn Marino 	EVP_PKEY_save_parameters(pktmp, 1);
1512f5b1c8a1SJohn Marino 
1513f5b1c8a1SJohn Marino 	if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
1514f5b1c8a1SJohn Marino 		goto err;
1515f5b1c8a1SJohn Marino 	if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
1516f5b1c8a1SJohn Marino 		goto err;
1517f5b1c8a1SJohn Marino 
1518f5b1c8a1SJohn Marino 	/* Lets just make it 12:00am GMT, Jan 1 1970 */
1519f5b1c8a1SJohn Marino 	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
1520f5b1c8a1SJohn Marino 	/* 28 days to be certified */
1521f5b1c8a1SJohn Marino 
1522f5b1c8a1SJohn Marino 	if (X509_gmtime_adj(X509_get_notAfter(x),
1523f5b1c8a1SJohn Marino 	    (long) 60 * 60 * 24 * days) == NULL)
1524f5b1c8a1SJohn Marino 		goto err;
1525f5b1c8a1SJohn Marino 
1526f5b1c8a1SJohn Marino 	if (!X509_set_pubkey(x, pkey))
1527f5b1c8a1SJohn Marino 		goto err;
1528f5b1c8a1SJohn Marino 	if (clrext) {
1529*de0e0e4dSAntonio Huete Jimenez 		while (X509_get_ext_count(x) > 0) {
1530*de0e0e4dSAntonio Huete Jimenez 			if (X509_delete_ext(x, 0) == NULL)
1531*de0e0e4dSAntonio Huete Jimenez 				goto err;
1532f5b1c8a1SJohn Marino 		}
1533*de0e0e4dSAntonio Huete Jimenez 	}
1534*de0e0e4dSAntonio Huete Jimenez 	if (conf != NULL) {
1535f5b1c8a1SJohn Marino 		X509V3_CTX ctx;
1536*de0e0e4dSAntonio Huete Jimenez 		if (!X509_set_version(x, 2))	/* version 3 certificate */
1537*de0e0e4dSAntonio Huete Jimenez 			goto err;
1538f5b1c8a1SJohn Marino 		X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
1539f5b1c8a1SJohn Marino 		X509V3_set_nconf(&ctx, conf);
1540f5b1c8a1SJohn Marino 		if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
1541f5b1c8a1SJohn Marino 			goto err;
1542f5b1c8a1SJohn Marino 	}
1543f5b1c8a1SJohn Marino 	if (!X509_sign(x, pkey, digest))
1544f5b1c8a1SJohn Marino 		goto err;
1545*de0e0e4dSAntonio Huete Jimenez 
1546f5b1c8a1SJohn Marino 	return 1;
1547f5b1c8a1SJohn Marino 
1548f5b1c8a1SJohn Marino  err:
1549f5b1c8a1SJohn Marino 	ERR_print_errors(bio_err);
1550f5b1c8a1SJohn Marino 	return 0;
1551f5b1c8a1SJohn Marino }
1552f5b1c8a1SJohn Marino 
1553f5b1c8a1SJohn Marino static int
purpose_print(BIO * bio,X509 * cert,X509_PURPOSE * pt)1554f5b1c8a1SJohn Marino purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
1555f5b1c8a1SJohn Marino {
1556f5b1c8a1SJohn Marino 	int id, i, idret;
1557f5b1c8a1SJohn Marino 	char *pname;
1558f5b1c8a1SJohn Marino 
1559f5b1c8a1SJohn Marino 	id = X509_PURPOSE_get_id(pt);
1560f5b1c8a1SJohn Marino 	pname = X509_PURPOSE_get0_name(pt);
1561f5b1c8a1SJohn Marino 	for (i = 0; i < 2; i++) {
1562f5b1c8a1SJohn Marino 		idret = X509_check_purpose(cert, id, i);
1563f5b1c8a1SJohn Marino 		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
1564f5b1c8a1SJohn Marino 		if (idret == 1)
1565f5b1c8a1SJohn Marino 			BIO_printf(bio, "Yes\n");
1566f5b1c8a1SJohn Marino 		else if (idret == 0)
1567f5b1c8a1SJohn Marino 			BIO_printf(bio, "No\n");
1568f5b1c8a1SJohn Marino 		else
1569f5b1c8a1SJohn Marino 			BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
1570f5b1c8a1SJohn Marino 	}
1571f5b1c8a1SJohn Marino 	return 1;
1572f5b1c8a1SJohn Marino }
1573