xref: /onnv-gate/usr/src/common/openssl/apps/x509.c (revision 8545:a1b3fd5884fd)
10Sstevel@tonic-gate /* apps/x509.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <assert.h>
600Sstevel@tonic-gate #include <stdio.h>
610Sstevel@tonic-gate #include <stdlib.h>
620Sstevel@tonic-gate #include <string.h>
630Sstevel@tonic-gate #ifdef OPENSSL_NO_STDIO
640Sstevel@tonic-gate #define APPS_WIN16
650Sstevel@tonic-gate #endif
660Sstevel@tonic-gate #include "apps.h"
670Sstevel@tonic-gate #include <openssl/bio.h>
680Sstevel@tonic-gate #include <openssl/asn1.h>
690Sstevel@tonic-gate #include <openssl/err.h>
700Sstevel@tonic-gate #include <openssl/bn.h>
710Sstevel@tonic-gate #include <openssl/evp.h>
720Sstevel@tonic-gate #include <openssl/x509.h>
730Sstevel@tonic-gate #include <openssl/x509v3.h>
740Sstevel@tonic-gate #include <openssl/objects.h>
750Sstevel@tonic-gate #include <openssl/pem.h>
762139Sjp161948 #ifndef OPENSSL_NO_RSA
772139Sjp161948 #include <openssl/rsa.h>
782139Sjp161948 #endif
792139Sjp161948 #ifndef OPENSSL_NO_DSA
802139Sjp161948 #include <openssl/dsa.h>
812139Sjp161948 #endif
820Sstevel@tonic-gate 
830Sstevel@tonic-gate #undef PROG
840Sstevel@tonic-gate #define PROG x509_main
850Sstevel@tonic-gate 
860Sstevel@tonic-gate #undef POSTFIX
870Sstevel@tonic-gate #define	POSTFIX	".srl"
880Sstevel@tonic-gate #define DEF_DAYS	30
890Sstevel@tonic-gate 
902139Sjp161948 static const char *x509_usage[]={
910Sstevel@tonic-gate "usage: x509 args\n",
920Sstevel@tonic-gate " -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
930Sstevel@tonic-gate " -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
940Sstevel@tonic-gate " -keyform arg    - private key format - default PEM\n",
950Sstevel@tonic-gate " -CAform arg     - CA format - default PEM\n",
960Sstevel@tonic-gate " -CAkeyform arg  - CA key format - default PEM\n",
970Sstevel@tonic-gate " -in arg         - input file - default stdin\n",
980Sstevel@tonic-gate " -out arg        - output file - default stdout\n",
990Sstevel@tonic-gate " -passin arg     - private key password source\n",
1000Sstevel@tonic-gate " -serial         - print serial number value\n",
1012139Sjp161948 " -subject_hash   - print subject hash value\n",
1022139Sjp161948 " -issuer_hash    - print issuer hash value\n",
1032139Sjp161948 " -hash           - synonym for -subject_hash\n",
1040Sstevel@tonic-gate " -subject        - print subject DN\n",
1050Sstevel@tonic-gate " -issuer         - print issuer DN\n",
1060Sstevel@tonic-gate " -email          - print email address(es)\n",
1070Sstevel@tonic-gate " -startdate      - notBefore field\n",
1080Sstevel@tonic-gate " -enddate        - notAfter field\n",
1090Sstevel@tonic-gate " -purpose        - print out certificate purposes\n",
1100Sstevel@tonic-gate " -dates          - both Before and After dates\n",
1110Sstevel@tonic-gate " -modulus        - print the RSA key modulus\n",
1120Sstevel@tonic-gate " -pubkey         - output the public key\n",
1130Sstevel@tonic-gate " -fingerprint    - print the certificate fingerprint\n",
1140Sstevel@tonic-gate " -alias          - output certificate alias\n",
1150Sstevel@tonic-gate " -noout          - no certificate output\n",
1160Sstevel@tonic-gate " -ocspid         - print OCSP hash values for the subject name and public key\n",
1170Sstevel@tonic-gate " -trustout       - output a \"trusted\" certificate\n",
1180Sstevel@tonic-gate " -clrtrust       - clear all trusted purposes\n",
1190Sstevel@tonic-gate " -clrreject      - clear all rejected purposes\n",
1200Sstevel@tonic-gate " -addtrust arg   - trust certificate for a given purpose\n",
1210Sstevel@tonic-gate " -addreject arg  - reject certificate for a given purpose\n",
1220Sstevel@tonic-gate " -setalias arg   - set certificate alias\n",
1230Sstevel@tonic-gate " -days arg       - How long till expiry of a signed certificate - def 30 days\n",
1240Sstevel@tonic-gate " -checkend arg   - check whether the cert expires in the next arg seconds\n",
1250Sstevel@tonic-gate "                   exit 1 if so, 0 if not\n",
1260Sstevel@tonic-gate " -signkey arg    - self sign cert with arg\n",
1270Sstevel@tonic-gate " -x509toreq      - output a certification request object\n",
1280Sstevel@tonic-gate " -req            - input is a certificate request, sign and output.\n",
1290Sstevel@tonic-gate " -CA arg         - set the CA certificate, must be PEM format.\n",
1300Sstevel@tonic-gate " -CAkey arg      - set the CA key, must be PEM format\n",
1310Sstevel@tonic-gate "                   missing, it is assumed to be in the CA file.\n",
1320Sstevel@tonic-gate " -CAcreateserial - create serial number file if it does not exist\n",
1330Sstevel@tonic-gate " -CAserial arg   - serial file\n",
1340Sstevel@tonic-gate " -set_serial     - serial number to use\n",
1350Sstevel@tonic-gate " -text           - print the certificate in text form\n",
1360Sstevel@tonic-gate " -C              - print out C code forms\n",
1370Sstevel@tonic-gate " -md2/-md5/-sha1/-mdc2 - digest to use\n",
1380Sstevel@tonic-gate " -extfile        - configuration file with X509V3 extensions to add\n",
1390Sstevel@tonic-gate " -extensions     - section from config file with X509V3 extensions to add\n",
1400Sstevel@tonic-gate " -clrext         - delete extensions before signing and input certificate\n",
1410Sstevel@tonic-gate " -nameopt arg    - various certificate name options\n",
1420Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1430Sstevel@tonic-gate " -engine e       - use engine e, possibly a hardware device.\n",
1440Sstevel@tonic-gate #endif
1450Sstevel@tonic-gate " -certopt arg    - various certificate text options\n",
1460Sstevel@tonic-gate NULL
1470Sstevel@tonic-gate };
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
1500Sstevel@tonic-gate static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
1510Sstevel@tonic-gate 						CONF *conf, char *section);
1520Sstevel@tonic-gate static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
1530Sstevel@tonic-gate 			 X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
1540Sstevel@tonic-gate 			 int create,int days, int clrext, CONF *conf, char *section,
1550Sstevel@tonic-gate 						ASN1_INTEGER *sno);
1560Sstevel@tonic-gate static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
1570Sstevel@tonic-gate static int reqfile=0;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate int MAIN(int, char **);
1600Sstevel@tonic-gate 
MAIN(int argc,char ** argv)1610Sstevel@tonic-gate int MAIN(int argc, char **argv)
1620Sstevel@tonic-gate 	{
1630Sstevel@tonic-gate 	ENGINE *e = NULL;
1640Sstevel@tonic-gate 	int ret=1;
1650Sstevel@tonic-gate 	X509_REQ *req=NULL;
1660Sstevel@tonic-gate 	X509 *x=NULL,*xca=NULL;
1670Sstevel@tonic-gate 	ASN1_OBJECT *objtmp;
1680Sstevel@tonic-gate 	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
1690Sstevel@tonic-gate 	ASN1_INTEGER *sno = NULL;
1700Sstevel@tonic-gate 	int i,num,badops=0;
1710Sstevel@tonic-gate 	BIO *out=NULL;
1720Sstevel@tonic-gate 	BIO *STDout=NULL;
1730Sstevel@tonic-gate 	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
1740Sstevel@tonic-gate 	int informat,outformat,keyformat,CAformat,CAkeyformat;
1750Sstevel@tonic-gate 	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
1760Sstevel@tonic-gate 	char *CAkeyfile=NULL,*CAserial=NULL;
1770Sstevel@tonic-gate 	char *alias=NULL;
1782139Sjp161948 	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
1792139Sjp161948 	int next_serial=0;
1802139Sjp161948 	int subject_hash=0,issuer_hash=0,ocspid=0;
1810Sstevel@tonic-gate 	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
1820Sstevel@tonic-gate 	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
1830Sstevel@tonic-gate 	int C=0;
1840Sstevel@tonic-gate 	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
1850Sstevel@tonic-gate 	int pprint = 0;
1862139Sjp161948 	const char **pp;
1870Sstevel@tonic-gate 	X509_STORE *ctx=NULL;
1880Sstevel@tonic-gate 	X509_REQ *rq=NULL;
1890Sstevel@tonic-gate 	int fingerprint=0;
1900Sstevel@tonic-gate 	char buf[256];
1912139Sjp161948 	const EVP_MD *md_alg,*digest=EVP_sha1();
1920Sstevel@tonic-gate 	CONF *extconf = NULL;
1930Sstevel@tonic-gate 	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
1940Sstevel@tonic-gate 	int need_rand = 0;
1950Sstevel@tonic-gate 	int checkend=0,checkoffset=0;
1960Sstevel@tonic-gate 	unsigned long nmflag = 0, certflag = 0;
1970Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1980Sstevel@tonic-gate 	char *engine=NULL;
1990Sstevel@tonic-gate #endif
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	reqfile=0;
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	apps_startup();
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	if (bio_err == NULL)
2060Sstevel@tonic-gate 		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 	if (!load_config(bio_err, NULL))
2090Sstevel@tonic-gate 		goto end;
2100Sstevel@tonic-gate 	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
2110Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS
2120Sstevel@tonic-gate 	{
2130Sstevel@tonic-gate 	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
2140Sstevel@tonic-gate 	STDout = BIO_push(tmpbio, STDout);
2150Sstevel@tonic-gate 	}
2160Sstevel@tonic-gate #endif
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	informat=FORMAT_PEM;
2190Sstevel@tonic-gate 	outformat=FORMAT_PEM;
2200Sstevel@tonic-gate 	keyformat=FORMAT_PEM;
2210Sstevel@tonic-gate 	CAformat=FORMAT_PEM;
2220Sstevel@tonic-gate 	CAkeyformat=FORMAT_PEM;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	ctx=X509_STORE_new();
2250Sstevel@tonic-gate 	if (ctx == NULL) goto end;
2260Sstevel@tonic-gate 	X509_STORE_set_verify_cb_func(ctx,callb);
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	argc--;
2290Sstevel@tonic-gate 	argv++;
2300Sstevel@tonic-gate 	num=0;
2310Sstevel@tonic-gate 	while (argc >= 1)
2320Sstevel@tonic-gate 		{
2330Sstevel@tonic-gate 		if 	(strcmp(*argv,"-inform") == 0)
2340Sstevel@tonic-gate 			{
2350Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2360Sstevel@tonic-gate 			informat=str2fmt(*(++argv));
2370Sstevel@tonic-gate 			}
2380Sstevel@tonic-gate 		else if (strcmp(*argv,"-outform") == 0)
2390Sstevel@tonic-gate 			{
2400Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2410Sstevel@tonic-gate 			outformat=str2fmt(*(++argv));
2420Sstevel@tonic-gate 			}
2430Sstevel@tonic-gate 		else if (strcmp(*argv,"-keyform") == 0)
2440Sstevel@tonic-gate 			{
2450Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2460Sstevel@tonic-gate 			keyformat=str2fmt(*(++argv));
2470Sstevel@tonic-gate 			}
2480Sstevel@tonic-gate 		else if (strcmp(*argv,"-req") == 0)
2490Sstevel@tonic-gate 			{
2500Sstevel@tonic-gate 			reqfile=1;
2510Sstevel@tonic-gate 			need_rand = 1;
2520Sstevel@tonic-gate 			}
2530Sstevel@tonic-gate 		else if (strcmp(*argv,"-CAform") == 0)
2540Sstevel@tonic-gate 			{
2550Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2560Sstevel@tonic-gate 			CAformat=str2fmt(*(++argv));
2570Sstevel@tonic-gate 			}
2580Sstevel@tonic-gate 		else if (strcmp(*argv,"-CAkeyform") == 0)
2590Sstevel@tonic-gate 			{
2600Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2610Sstevel@tonic-gate 			CAkeyformat=str2fmt(*(++argv));
2620Sstevel@tonic-gate 			}
2630Sstevel@tonic-gate 		else if (strcmp(*argv,"-days") == 0)
2640Sstevel@tonic-gate 			{
2650Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2660Sstevel@tonic-gate 			days=atoi(*(++argv));
2670Sstevel@tonic-gate 			if (days == 0)
2680Sstevel@tonic-gate 				{
2690Sstevel@tonic-gate 				BIO_printf(STDout,"bad number of days\n");
2700Sstevel@tonic-gate 				goto bad;
2710Sstevel@tonic-gate 				}
2720Sstevel@tonic-gate 			}
2730Sstevel@tonic-gate 		else if (strcmp(*argv,"-passin") == 0)
2740Sstevel@tonic-gate 			{
2750Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2760Sstevel@tonic-gate 			passargin= *(++argv);
2770Sstevel@tonic-gate 			}
2780Sstevel@tonic-gate 		else if (strcmp(*argv,"-extfile") == 0)
2790Sstevel@tonic-gate 			{
2800Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2810Sstevel@tonic-gate 			extfile= *(++argv);
2820Sstevel@tonic-gate 			}
2830Sstevel@tonic-gate 		else if (strcmp(*argv,"-extensions") == 0)
2840Sstevel@tonic-gate 			{
2850Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2860Sstevel@tonic-gate 			extsect= *(++argv);
2870Sstevel@tonic-gate 			}
2880Sstevel@tonic-gate 		else if (strcmp(*argv,"-in") == 0)
2890Sstevel@tonic-gate 			{
2900Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2910Sstevel@tonic-gate 			infile= *(++argv);
2920Sstevel@tonic-gate 			}
2930Sstevel@tonic-gate 		else if (strcmp(*argv,"-out") == 0)
2940Sstevel@tonic-gate 			{
2950Sstevel@tonic-gate 			if (--argc < 1) goto bad;
2960Sstevel@tonic-gate 			outfile= *(++argv);
2970Sstevel@tonic-gate 			}
2980Sstevel@tonic-gate 		else if (strcmp(*argv,"-signkey") == 0)
2990Sstevel@tonic-gate 			{
3000Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3010Sstevel@tonic-gate 			keyfile= *(++argv);
3020Sstevel@tonic-gate 			sign_flag= ++num;
3030Sstevel@tonic-gate 			need_rand = 1;
3040Sstevel@tonic-gate 			}
3050Sstevel@tonic-gate 		else if (strcmp(*argv,"-CA") == 0)
3060Sstevel@tonic-gate 			{
3070Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3080Sstevel@tonic-gate 			CAfile= *(++argv);
3090Sstevel@tonic-gate 			CA_flag= ++num;
3100Sstevel@tonic-gate 			need_rand = 1;
3110Sstevel@tonic-gate 			}
3120Sstevel@tonic-gate 		else if (strcmp(*argv,"-CAkey") == 0)
3130Sstevel@tonic-gate 			{
3140Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3150Sstevel@tonic-gate 			CAkeyfile= *(++argv);
3160Sstevel@tonic-gate 			}
3170Sstevel@tonic-gate 		else if (strcmp(*argv,"-CAserial") == 0)
3180Sstevel@tonic-gate 			{
3190Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3200Sstevel@tonic-gate 			CAserial= *(++argv);
3210Sstevel@tonic-gate 			}
3220Sstevel@tonic-gate 		else if (strcmp(*argv,"-set_serial") == 0)
3230Sstevel@tonic-gate 			{
3240Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3250Sstevel@tonic-gate 			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
3260Sstevel@tonic-gate 				goto bad;
3270Sstevel@tonic-gate 			}
3280Sstevel@tonic-gate 		else if (strcmp(*argv,"-addtrust") == 0)
3290Sstevel@tonic-gate 			{
3300Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3310Sstevel@tonic-gate 			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
3320Sstevel@tonic-gate 				{
3330Sstevel@tonic-gate 				BIO_printf(bio_err,
3340Sstevel@tonic-gate 					"Invalid trust object value %s\n", *argv);
3350Sstevel@tonic-gate 				goto bad;
3360Sstevel@tonic-gate 				}
3370Sstevel@tonic-gate 			if (!trust) trust = sk_ASN1_OBJECT_new_null();
3380Sstevel@tonic-gate 			sk_ASN1_OBJECT_push(trust, objtmp);
3390Sstevel@tonic-gate 			trustout = 1;
3400Sstevel@tonic-gate 			}
3410Sstevel@tonic-gate 		else if (strcmp(*argv,"-addreject") == 0)
3420Sstevel@tonic-gate 			{
3430Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3440Sstevel@tonic-gate 			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
3450Sstevel@tonic-gate 				{
3460Sstevel@tonic-gate 				BIO_printf(bio_err,
3470Sstevel@tonic-gate 					"Invalid reject object value %s\n", *argv);
3480Sstevel@tonic-gate 				goto bad;
3490Sstevel@tonic-gate 				}
3500Sstevel@tonic-gate 			if (!reject) reject = sk_ASN1_OBJECT_new_null();
3510Sstevel@tonic-gate 			sk_ASN1_OBJECT_push(reject, objtmp);
3520Sstevel@tonic-gate 			trustout = 1;
3530Sstevel@tonic-gate 			}
3540Sstevel@tonic-gate 		else if (strcmp(*argv,"-setalias") == 0)
3550Sstevel@tonic-gate 			{
3560Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3570Sstevel@tonic-gate 			alias= *(++argv);
3580Sstevel@tonic-gate 			trustout = 1;
3590Sstevel@tonic-gate 			}
3600Sstevel@tonic-gate 		else if (strcmp(*argv,"-certopt") == 0)
3610Sstevel@tonic-gate 			{
3620Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3630Sstevel@tonic-gate 			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
3640Sstevel@tonic-gate 			}
3650Sstevel@tonic-gate 		else if (strcmp(*argv,"-nameopt") == 0)
3660Sstevel@tonic-gate 			{
3670Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3680Sstevel@tonic-gate 			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
3690Sstevel@tonic-gate 			}
3700Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
3710Sstevel@tonic-gate 		else if (strcmp(*argv,"-engine") == 0)
3720Sstevel@tonic-gate 			{
3730Sstevel@tonic-gate 			if (--argc < 1) goto bad;
3740Sstevel@tonic-gate 			engine= *(++argv);
3750Sstevel@tonic-gate 			}
3760Sstevel@tonic-gate #endif
3770Sstevel@tonic-gate 		else if (strcmp(*argv,"-C") == 0)
3780Sstevel@tonic-gate 			C= ++num;
3790Sstevel@tonic-gate 		else if (strcmp(*argv,"-email") == 0)
3800Sstevel@tonic-gate 			email= ++num;
3810Sstevel@tonic-gate 		else if (strcmp(*argv,"-serial") == 0)
3820Sstevel@tonic-gate 			serial= ++num;
3832139Sjp161948 		else if (strcmp(*argv,"-next_serial") == 0)
3842139Sjp161948 			next_serial= ++num;
3850Sstevel@tonic-gate 		else if (strcmp(*argv,"-modulus") == 0)
3860Sstevel@tonic-gate 			modulus= ++num;
3870Sstevel@tonic-gate 		else if (strcmp(*argv,"-pubkey") == 0)
3880Sstevel@tonic-gate 			pubkey= ++num;
3890Sstevel@tonic-gate 		else if (strcmp(*argv,"-x509toreq") == 0)
3900Sstevel@tonic-gate 			x509req= ++num;
3910Sstevel@tonic-gate 		else if (strcmp(*argv,"-text") == 0)
3920Sstevel@tonic-gate 			text= ++num;
3932139Sjp161948 		else if (strcmp(*argv,"-hash") == 0
3942139Sjp161948 			|| strcmp(*argv,"-subject_hash") == 0)
3952139Sjp161948 			subject_hash= ++num;
3962139Sjp161948 		else if (strcmp(*argv,"-issuer_hash") == 0)
3972139Sjp161948 			issuer_hash= ++num;
3980Sstevel@tonic-gate 		else if (strcmp(*argv,"-subject") == 0)
3990Sstevel@tonic-gate 			subject= ++num;
4000Sstevel@tonic-gate 		else if (strcmp(*argv,"-issuer") == 0)
4010Sstevel@tonic-gate 			issuer= ++num;
4020Sstevel@tonic-gate 		else if (strcmp(*argv,"-fingerprint") == 0)
4030Sstevel@tonic-gate 			fingerprint= ++num;
4040Sstevel@tonic-gate 		else if (strcmp(*argv,"-dates") == 0)
4050Sstevel@tonic-gate 			{
4060Sstevel@tonic-gate 			startdate= ++num;
4070Sstevel@tonic-gate 			enddate= ++num;
4080Sstevel@tonic-gate 			}
4090Sstevel@tonic-gate 		else if (strcmp(*argv,"-purpose") == 0)
4100Sstevel@tonic-gate 			pprint= ++num;
4110Sstevel@tonic-gate 		else if (strcmp(*argv,"-startdate") == 0)
4120Sstevel@tonic-gate 			startdate= ++num;
4130Sstevel@tonic-gate 		else if (strcmp(*argv,"-enddate") == 0)
4140Sstevel@tonic-gate 			enddate= ++num;
4150Sstevel@tonic-gate 		else if (strcmp(*argv,"-checkend") == 0)
4160Sstevel@tonic-gate 			{
4170Sstevel@tonic-gate 			if (--argc < 1) goto bad;
4180Sstevel@tonic-gate 			checkoffset=atoi(*(++argv));
4190Sstevel@tonic-gate 			checkend=1;
4200Sstevel@tonic-gate 			}
4210Sstevel@tonic-gate 		else if (strcmp(*argv,"-noout") == 0)
4220Sstevel@tonic-gate 			noout= ++num;
4230Sstevel@tonic-gate 		else if (strcmp(*argv,"-trustout") == 0)
4240Sstevel@tonic-gate 			trustout= 1;
4250Sstevel@tonic-gate 		else if (strcmp(*argv,"-clrtrust") == 0)
4260Sstevel@tonic-gate 			clrtrust= ++num;
4270Sstevel@tonic-gate 		else if (strcmp(*argv,"-clrreject") == 0)
4280Sstevel@tonic-gate 			clrreject= ++num;
4290Sstevel@tonic-gate 		else if (strcmp(*argv,"-alias") == 0)
4300Sstevel@tonic-gate 			aliasout= ++num;
4310Sstevel@tonic-gate 		else if (strcmp(*argv,"-CAcreateserial") == 0)
4320Sstevel@tonic-gate 			CA_createserial= ++num;
4330Sstevel@tonic-gate 		else if (strcmp(*argv,"-clrext") == 0)
4340Sstevel@tonic-gate 			clrext = 1;
4350Sstevel@tonic-gate #if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
4360Sstevel@tonic-gate 		else if (strcmp(*argv,"-crlext") == 0)
4370Sstevel@tonic-gate 			{
4380Sstevel@tonic-gate 			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
4390Sstevel@tonic-gate 			clrext = 1;
4400Sstevel@tonic-gate 			}
4410Sstevel@tonic-gate #endif
4420Sstevel@tonic-gate 		else if (strcmp(*argv,"-ocspid") == 0)
4430Sstevel@tonic-gate 			ocspid= ++num;
4440Sstevel@tonic-gate 		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
4450Sstevel@tonic-gate 			{
4460Sstevel@tonic-gate 			/* ok */
4470Sstevel@tonic-gate 			digest=md_alg;
4480Sstevel@tonic-gate 			}
4490Sstevel@tonic-gate 		else
4500Sstevel@tonic-gate 			{
4510Sstevel@tonic-gate 			BIO_printf(bio_err,"unknown option %s\n",*argv);
4520Sstevel@tonic-gate 			badops=1;
4530Sstevel@tonic-gate 			break;
4540Sstevel@tonic-gate 			}
4550Sstevel@tonic-gate 		argc--;
4560Sstevel@tonic-gate 		argv++;
4570Sstevel@tonic-gate 		}
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 	if (badops)
4600Sstevel@tonic-gate 		{
4610Sstevel@tonic-gate bad:
4620Sstevel@tonic-gate 		for (pp=x509_usage; (*pp != NULL); pp++)
4630Sstevel@tonic-gate 			BIO_printf(bio_err,"%s",*pp);
4640Sstevel@tonic-gate 		goto end;
4650Sstevel@tonic-gate 		}
4660Sstevel@tonic-gate 
4670Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
4680Sstevel@tonic-gate         e = setup_engine(bio_err, engine, 0);
4690Sstevel@tonic-gate #endif
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	if (need_rand)
4720Sstevel@tonic-gate 		app_RAND_load_file(NULL, bio_err, 0);
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate 	ERR_load_crypto_strings();
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
4770Sstevel@tonic-gate 		{
4780Sstevel@tonic-gate 		BIO_printf(bio_err, "Error getting password\n");
4790Sstevel@tonic-gate 		goto end;
4800Sstevel@tonic-gate 		}
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 	if (!X509_STORE_set_default_paths(ctx))
4830Sstevel@tonic-gate 		{
4840Sstevel@tonic-gate 		ERR_print_errors(bio_err);
4850Sstevel@tonic-gate 		goto end;
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate 	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
4890Sstevel@tonic-gate 		{ CAkeyfile=CAfile; }
4900Sstevel@tonic-gate 	else if ((CA_flag) && (CAkeyfile == NULL))
4910Sstevel@tonic-gate 		{
4920Sstevel@tonic-gate 		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
4930Sstevel@tonic-gate 		goto end;
4940Sstevel@tonic-gate 		}
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	if (extfile)
4970Sstevel@tonic-gate 		{
4980Sstevel@tonic-gate 		long errorline = -1;
4990Sstevel@tonic-gate 		X509V3_CTX ctx2;
5000Sstevel@tonic-gate 		extconf = NCONF_new(NULL);
5010Sstevel@tonic-gate 		if (!NCONF_load(extconf, extfile,&errorline))
5020Sstevel@tonic-gate 			{
5030Sstevel@tonic-gate 			if (errorline <= 0)
5040Sstevel@tonic-gate 				BIO_printf(bio_err,
5050Sstevel@tonic-gate 					"error loading the config file '%s'\n",
5060Sstevel@tonic-gate 								extfile);
5070Sstevel@tonic-gate                 	else
5080Sstevel@tonic-gate                         	BIO_printf(bio_err,
5090Sstevel@tonic-gate 				       "error on line %ld of config file '%s'\n"
5100Sstevel@tonic-gate 							,errorline,extfile);
5110Sstevel@tonic-gate 			goto end;
5120Sstevel@tonic-gate 			}
5130Sstevel@tonic-gate 		if (!extsect)
5140Sstevel@tonic-gate 			{
5150Sstevel@tonic-gate 			extsect = NCONF_get_string(extconf, "default", "extensions");
5160Sstevel@tonic-gate 			if (!extsect)
5170Sstevel@tonic-gate 				{
5180Sstevel@tonic-gate 				ERR_clear_error();
5190Sstevel@tonic-gate 				extsect = "default";
5200Sstevel@tonic-gate 				}
5210Sstevel@tonic-gate 			}
5220Sstevel@tonic-gate 		X509V3_set_ctx_test(&ctx2);
5230Sstevel@tonic-gate 		X509V3_set_nconf(&ctx2, extconf);
5240Sstevel@tonic-gate 		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
5250Sstevel@tonic-gate 			{
5260Sstevel@tonic-gate 			BIO_printf(bio_err,
5270Sstevel@tonic-gate 				"Error Loading extension section %s\n",
5280Sstevel@tonic-gate 								 extsect);
5290Sstevel@tonic-gate 			ERR_print_errors(bio_err);
5300Sstevel@tonic-gate 			goto end;
5310Sstevel@tonic-gate 			}
5320Sstevel@tonic-gate 		}
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 	if (reqfile)
5360Sstevel@tonic-gate 		{
5370Sstevel@tonic-gate 		EVP_PKEY *pkey;
5380Sstevel@tonic-gate 		X509_CINF *ci;
5390Sstevel@tonic-gate 		BIO *in;
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 		if (!sign_flag && !CA_flag)
5420Sstevel@tonic-gate 			{
5430Sstevel@tonic-gate 			BIO_printf(bio_err,"We need a private key to sign with\n");
5440Sstevel@tonic-gate 			goto end;
5450Sstevel@tonic-gate 			}
5460Sstevel@tonic-gate 		in=BIO_new(BIO_s_file());
5470Sstevel@tonic-gate 		if (in == NULL)
5480Sstevel@tonic-gate 			{
5490Sstevel@tonic-gate 			ERR_print_errors(bio_err);
5500Sstevel@tonic-gate 			goto end;
5510Sstevel@tonic-gate 			}
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate 		if (infile == NULL)
5540Sstevel@tonic-gate 			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
5550Sstevel@tonic-gate 		else
5560Sstevel@tonic-gate 			{
5570Sstevel@tonic-gate 			if (BIO_read_filename(in,infile) <= 0)
5580Sstevel@tonic-gate 				{
5590Sstevel@tonic-gate 				perror(infile);
5600Sstevel@tonic-gate 				BIO_free(in);
5610Sstevel@tonic-gate 				goto end;
5620Sstevel@tonic-gate 				}
5630Sstevel@tonic-gate 			}
5640Sstevel@tonic-gate 		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
5650Sstevel@tonic-gate 		BIO_free(in);
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate 		if (req == NULL)
5680Sstevel@tonic-gate 			{
5690Sstevel@tonic-gate 			ERR_print_errors(bio_err);
5700Sstevel@tonic-gate 			goto end;
5710Sstevel@tonic-gate 			}
5720Sstevel@tonic-gate 
5730Sstevel@tonic-gate 		if (	(req->req_info == NULL) ||
5740Sstevel@tonic-gate 			(req->req_info->pubkey == NULL) ||
5750Sstevel@tonic-gate 			(req->req_info->pubkey->public_key == NULL) ||
5760Sstevel@tonic-gate 			(req->req_info->pubkey->public_key->data == NULL))
5770Sstevel@tonic-gate 			{
5780Sstevel@tonic-gate 			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
5790Sstevel@tonic-gate 			BIO_printf(bio_err,"It does not contain a public key\n");
5800Sstevel@tonic-gate 			goto end;
5810Sstevel@tonic-gate 			}
5820Sstevel@tonic-gate 		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
5830Sstevel@tonic-gate 	                {
5840Sstevel@tonic-gate 	                BIO_printf(bio_err,"error unpacking public key\n");
5850Sstevel@tonic-gate 	                goto end;
5860Sstevel@tonic-gate 	                }
5870Sstevel@tonic-gate 		i=X509_REQ_verify(req,pkey);
5880Sstevel@tonic-gate 		EVP_PKEY_free(pkey);
5890Sstevel@tonic-gate 		if (i < 0)
5900Sstevel@tonic-gate 			{
5910Sstevel@tonic-gate 			BIO_printf(bio_err,"Signature verification error\n");
5920Sstevel@tonic-gate 			ERR_print_errors(bio_err);
5930Sstevel@tonic-gate 			goto end;
5940Sstevel@tonic-gate 			}
5950Sstevel@tonic-gate 	        if (i == 0)
5960Sstevel@tonic-gate 			{
5970Sstevel@tonic-gate 			BIO_printf(bio_err,"Signature did not match the certificate request\n");
5980Sstevel@tonic-gate 			goto end;
5990Sstevel@tonic-gate 			}
6000Sstevel@tonic-gate 		else
6010Sstevel@tonic-gate 			BIO_printf(bio_err,"Signature ok\n");
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
6040Sstevel@tonic-gate 
6050Sstevel@tonic-gate 		if ((x=X509_new()) == NULL) goto end;
6060Sstevel@tonic-gate 		ci=x->cert_info;
6070Sstevel@tonic-gate 
6082139Sjp161948 		if (sno == NULL)
6090Sstevel@tonic-gate 			{
6102139Sjp161948 			sno = ASN1_INTEGER_new();
6112139Sjp161948 			if (!sno || !rand_serial(NULL, sno))
6122139Sjp161948 				goto end;
6132139Sjp161948 			if (!X509_set_serialNumber(x, sno))
6140Sstevel@tonic-gate 				goto end;
6152139Sjp161948 			ASN1_INTEGER_free(sno);
6162139Sjp161948 			sno = NULL;
6170Sstevel@tonic-gate 			}
6182139Sjp161948 		else if (!X509_set_serialNumber(x, sno))
6192139Sjp161948 			goto end;
6202139Sjp161948 
6210Sstevel@tonic-gate 		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
6220Sstevel@tonic-gate 		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 		X509_gmtime_adj(X509_get_notBefore(x),0);
6250Sstevel@tonic-gate 	        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate 		pkey = X509_REQ_get_pubkey(req);
6280Sstevel@tonic-gate 		X509_set_pubkey(x,pkey);
6290Sstevel@tonic-gate 		EVP_PKEY_free(pkey);
6300Sstevel@tonic-gate 		}
6310Sstevel@tonic-gate 	else
6320Sstevel@tonic-gate 		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	if (x == NULL) goto end;
6350Sstevel@tonic-gate 	if (CA_flag)
6360Sstevel@tonic-gate 		{
6370Sstevel@tonic-gate 		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
6380Sstevel@tonic-gate 		if (xca == NULL) goto end;
6390Sstevel@tonic-gate 		}
6400Sstevel@tonic-gate 
6412139Sjp161948 	if (!noout || text || next_serial)
6420Sstevel@tonic-gate 		{
6430Sstevel@tonic-gate 		OBJ_create("2.99999.3",
6440Sstevel@tonic-gate 			"SET.ex3","SET x509v3 extension 3");
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate 		out=BIO_new(BIO_s_file());
6470Sstevel@tonic-gate 		if (out == NULL)
6480Sstevel@tonic-gate 			{
6490Sstevel@tonic-gate 			ERR_print_errors(bio_err);
6500Sstevel@tonic-gate 			goto end;
6510Sstevel@tonic-gate 			}
6520Sstevel@tonic-gate 		if (outfile == NULL)
6530Sstevel@tonic-gate 			{
6540Sstevel@tonic-gate 			BIO_set_fp(out,stdout,BIO_NOCLOSE);
6550Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS
6560Sstevel@tonic-gate 			{
6570Sstevel@tonic-gate 			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
6580Sstevel@tonic-gate 			out = BIO_push(tmpbio, out);
6590Sstevel@tonic-gate 			}
6600Sstevel@tonic-gate #endif
6610Sstevel@tonic-gate 			}
6620Sstevel@tonic-gate 		else
6630Sstevel@tonic-gate 			{
6640Sstevel@tonic-gate 			if (BIO_write_filename(out,outfile) <= 0)
6650Sstevel@tonic-gate 				{
6660Sstevel@tonic-gate 				perror(outfile);
6670Sstevel@tonic-gate 				goto end;
6680Sstevel@tonic-gate 				}
6690Sstevel@tonic-gate 			}
6700Sstevel@tonic-gate 		}
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	if (clrtrust) X509_trust_clear(x);
6750Sstevel@tonic-gate 	if (clrreject) X509_reject_clear(x);
6760Sstevel@tonic-gate 
6770Sstevel@tonic-gate 	if (trust)
6780Sstevel@tonic-gate 		{
6790Sstevel@tonic-gate 		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
6800Sstevel@tonic-gate 			{
6810Sstevel@tonic-gate 			objtmp = sk_ASN1_OBJECT_value(trust, i);
6820Sstevel@tonic-gate 			X509_add1_trust_object(x, objtmp);
6830Sstevel@tonic-gate 			}
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 	if (reject)
6870Sstevel@tonic-gate 		{
6880Sstevel@tonic-gate 		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
6890Sstevel@tonic-gate 			{
6900Sstevel@tonic-gate 			objtmp = sk_ASN1_OBJECT_value(reject, i);
6910Sstevel@tonic-gate 			X509_add1_reject_object(x, objtmp);
6920Sstevel@tonic-gate 			}
6930Sstevel@tonic-gate 		}
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	if (num)
6960Sstevel@tonic-gate 		{
6970Sstevel@tonic-gate 		for (i=1; i<=num; i++)
6980Sstevel@tonic-gate 			{
6990Sstevel@tonic-gate 			if (issuer == i)
7000Sstevel@tonic-gate 				{
7010Sstevel@tonic-gate 				print_name(STDout, "issuer= ",
7020Sstevel@tonic-gate 					X509_get_issuer_name(x), nmflag);
7030Sstevel@tonic-gate 				}
7040Sstevel@tonic-gate 			else if (subject == i)
7050Sstevel@tonic-gate 				{
7060Sstevel@tonic-gate 				print_name(STDout, "subject= ",
7070Sstevel@tonic-gate 					X509_get_subject_name(x), nmflag);
7080Sstevel@tonic-gate 				}
7090Sstevel@tonic-gate 			else if (serial == i)
7100Sstevel@tonic-gate 				{
7110Sstevel@tonic-gate 				BIO_printf(STDout,"serial=");
7122139Sjp161948 				i2a_ASN1_INTEGER(STDout,
7132139Sjp161948 					X509_get_serialNumber(x));
7140Sstevel@tonic-gate 				BIO_printf(STDout,"\n");
7150Sstevel@tonic-gate 				}
7162139Sjp161948 			else if (next_serial == i)
7172139Sjp161948 				{
7182139Sjp161948 				BIGNUM *bnser;
7192139Sjp161948 				ASN1_INTEGER *ser;
7202139Sjp161948 				ser = X509_get_serialNumber(x);
7212139Sjp161948 				bnser = ASN1_INTEGER_to_BN(ser, NULL);
7222139Sjp161948 				if (!bnser)
7232139Sjp161948 					goto end;
7242139Sjp161948 				if (!BN_add_word(bnser, 1))
7252139Sjp161948 					goto end;
7262139Sjp161948 				ser = BN_to_ASN1_INTEGER(bnser, NULL);
7272139Sjp161948 				if (!ser)
7282139Sjp161948 					goto end;
7292139Sjp161948 				BN_free(bnser);
7302139Sjp161948 				i2a_ASN1_INTEGER(out, ser);
7312139Sjp161948 				ASN1_INTEGER_free(ser);
7322139Sjp161948 				BIO_puts(out, "\n");
7332139Sjp161948 				}
7340Sstevel@tonic-gate 			else if (email == i)
7350Sstevel@tonic-gate 				{
7360Sstevel@tonic-gate 				int j;
7370Sstevel@tonic-gate 				STACK *emlst;
7380Sstevel@tonic-gate 				emlst = X509_get1_email(x);
7390Sstevel@tonic-gate 				for (j = 0; j < sk_num(emlst); j++)
7400Sstevel@tonic-gate 					BIO_printf(STDout, "%s\n", sk_value(emlst, j));
7410Sstevel@tonic-gate 				X509_email_free(emlst);
7420Sstevel@tonic-gate 				}
7430Sstevel@tonic-gate 			else if (aliasout == i)
7440Sstevel@tonic-gate 				{
7450Sstevel@tonic-gate 				unsigned char *alstr;
7460Sstevel@tonic-gate 				alstr = X509_alias_get0(x, NULL);
7470Sstevel@tonic-gate 				if (alstr) BIO_printf(STDout,"%s\n", alstr);
7480Sstevel@tonic-gate 				else BIO_puts(STDout,"<No Alias>\n");
7490Sstevel@tonic-gate 				}
7502139Sjp161948 			else if (subject_hash == i)
7510Sstevel@tonic-gate 				{
7520Sstevel@tonic-gate 				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
7530Sstevel@tonic-gate 				}
7542139Sjp161948 			else if (issuer_hash == i)
7552139Sjp161948 				{
7562139Sjp161948 				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
7572139Sjp161948 				}
7580Sstevel@tonic-gate 			else if (pprint == i)
7590Sstevel@tonic-gate 				{
7600Sstevel@tonic-gate 				X509_PURPOSE *ptmp;
7610Sstevel@tonic-gate 				int j;
7620Sstevel@tonic-gate 				BIO_printf(STDout, "Certificate purposes:\n");
7630Sstevel@tonic-gate 				for (j = 0; j < X509_PURPOSE_get_count(); j++)
7640Sstevel@tonic-gate 					{
7650Sstevel@tonic-gate 					ptmp = X509_PURPOSE_get0(j);
7660Sstevel@tonic-gate 					purpose_print(STDout, x, ptmp);
7670Sstevel@tonic-gate 					}
7680Sstevel@tonic-gate 				}
7690Sstevel@tonic-gate 			else
7700Sstevel@tonic-gate 				if (modulus == i)
7710Sstevel@tonic-gate 				{
7720Sstevel@tonic-gate 				EVP_PKEY *pkey;
7730Sstevel@tonic-gate 
7740Sstevel@tonic-gate 				pkey=X509_get_pubkey(x);
7750Sstevel@tonic-gate 				if (pkey == NULL)
7760Sstevel@tonic-gate 					{
7770Sstevel@tonic-gate 					BIO_printf(bio_err,"Modulus=unavailable\n");
7780Sstevel@tonic-gate 					ERR_print_errors(bio_err);
7790Sstevel@tonic-gate 					goto end;
7800Sstevel@tonic-gate 					}
7810Sstevel@tonic-gate 				BIO_printf(STDout,"Modulus=");
7820Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
7830Sstevel@tonic-gate 				if (pkey->type == EVP_PKEY_RSA)
7840Sstevel@tonic-gate 					BN_print(STDout,pkey->pkey.rsa->n);
7850Sstevel@tonic-gate 				else
7860Sstevel@tonic-gate #endif
7870Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
7880Sstevel@tonic-gate 				if (pkey->type == EVP_PKEY_DSA)
7890Sstevel@tonic-gate 					BN_print(STDout,pkey->pkey.dsa->pub_key);
7900Sstevel@tonic-gate 				else
7910Sstevel@tonic-gate #endif
7920Sstevel@tonic-gate 					BIO_printf(STDout,"Wrong Algorithm type");
7930Sstevel@tonic-gate 				BIO_printf(STDout,"\n");
7940Sstevel@tonic-gate 				EVP_PKEY_free(pkey);
7950Sstevel@tonic-gate 				}
7960Sstevel@tonic-gate 			else
7970Sstevel@tonic-gate 				if (pubkey == i)
7980Sstevel@tonic-gate 				{
7990Sstevel@tonic-gate 				EVP_PKEY *pkey;
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate 				pkey=X509_get_pubkey(x);
8020Sstevel@tonic-gate 				if (pkey == NULL)
8030Sstevel@tonic-gate 					{
8040Sstevel@tonic-gate 					BIO_printf(bio_err,"Error getting public key\n");
8050Sstevel@tonic-gate 					ERR_print_errors(bio_err);
8060Sstevel@tonic-gate 					goto end;
8070Sstevel@tonic-gate 					}
8080Sstevel@tonic-gate 				PEM_write_bio_PUBKEY(STDout, pkey);
8090Sstevel@tonic-gate 				EVP_PKEY_free(pkey);
8100Sstevel@tonic-gate 				}
8110Sstevel@tonic-gate 			else
8120Sstevel@tonic-gate 				if (C == i)
8130Sstevel@tonic-gate 				{
8140Sstevel@tonic-gate 				unsigned char *d;
8150Sstevel@tonic-gate 				char *m;
8160Sstevel@tonic-gate 				int y,z;
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 				X509_NAME_oneline(X509_get_subject_name(x),
8190Sstevel@tonic-gate 					buf,sizeof buf);
8200Sstevel@tonic-gate 				BIO_printf(STDout,"/* subject:%s */\n",buf);
8210Sstevel@tonic-gate 				m=X509_NAME_oneline(
8220Sstevel@tonic-gate 					X509_get_issuer_name(x),buf,
8230Sstevel@tonic-gate 					sizeof buf);
8240Sstevel@tonic-gate 				BIO_printf(STDout,"/* issuer :%s */\n",buf);
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 				z=i2d_X509(x,NULL);
8270Sstevel@tonic-gate 				m=OPENSSL_malloc(z);
8280Sstevel@tonic-gate 
8290Sstevel@tonic-gate 				d=(unsigned char *)m;
8300Sstevel@tonic-gate 				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
8310Sstevel@tonic-gate 				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
8320Sstevel@tonic-gate 				d=(unsigned char *)m;
8330Sstevel@tonic-gate 				for (y=0; y<z; y++)
8340Sstevel@tonic-gate 					{
8350Sstevel@tonic-gate 					BIO_printf(STDout,"0x%02X,",d[y]);
8360Sstevel@tonic-gate 					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
8370Sstevel@tonic-gate 					}
8380Sstevel@tonic-gate 				if (y%16 != 0) BIO_printf(STDout,"\n");
8390Sstevel@tonic-gate 				BIO_printf(STDout,"};\n");
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
8420Sstevel@tonic-gate 				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
8430Sstevel@tonic-gate 				d=(unsigned char *)m;
8440Sstevel@tonic-gate 				for (y=0; y<z; y++)
8450Sstevel@tonic-gate 					{
8460Sstevel@tonic-gate 					BIO_printf(STDout,"0x%02X,",d[y]);
8470Sstevel@tonic-gate 					if ((y & 0x0f) == 0x0f)
8480Sstevel@tonic-gate 						BIO_printf(STDout,"\n");
8490Sstevel@tonic-gate 					}
8500Sstevel@tonic-gate 				if (y%16 != 0) BIO_printf(STDout,"\n");
8510Sstevel@tonic-gate 				BIO_printf(STDout,"};\n");
8520Sstevel@tonic-gate 
8530Sstevel@tonic-gate 				z=i2d_X509(x,&d);
8540Sstevel@tonic-gate 				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
8550Sstevel@tonic-gate 				d=(unsigned char *)m;
8560Sstevel@tonic-gate 				for (y=0; y<z; y++)
8570Sstevel@tonic-gate 					{
8580Sstevel@tonic-gate 					BIO_printf(STDout,"0x%02X,",d[y]);
8590Sstevel@tonic-gate 					if ((y & 0x0f) == 0x0f)
8600Sstevel@tonic-gate 						BIO_printf(STDout,"\n");
8610Sstevel@tonic-gate 					}
8620Sstevel@tonic-gate 				if (y%16 != 0) BIO_printf(STDout,"\n");
8630Sstevel@tonic-gate 				BIO_printf(STDout,"};\n");
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 				OPENSSL_free(m);
8660Sstevel@tonic-gate 				}
8670Sstevel@tonic-gate 			else if (text == i)
8680Sstevel@tonic-gate 				{
8690Sstevel@tonic-gate 				X509_print_ex(out,x,nmflag, certflag);
8700Sstevel@tonic-gate 				}
8710Sstevel@tonic-gate 			else if (startdate == i)
8720Sstevel@tonic-gate 				{
8730Sstevel@tonic-gate 				BIO_puts(STDout,"notBefore=");
8740Sstevel@tonic-gate 				ASN1_TIME_print(STDout,X509_get_notBefore(x));
8750Sstevel@tonic-gate 				BIO_puts(STDout,"\n");
8760Sstevel@tonic-gate 				}
8770Sstevel@tonic-gate 			else if (enddate == i)
8780Sstevel@tonic-gate 				{
8790Sstevel@tonic-gate 				BIO_puts(STDout,"notAfter=");
8800Sstevel@tonic-gate 				ASN1_TIME_print(STDout,X509_get_notAfter(x));
8810Sstevel@tonic-gate 				BIO_puts(STDout,"\n");
8820Sstevel@tonic-gate 				}
8830Sstevel@tonic-gate 			else if (fingerprint == i)
8840Sstevel@tonic-gate 				{
8850Sstevel@tonic-gate 				int j;
8860Sstevel@tonic-gate 				unsigned int n;
8870Sstevel@tonic-gate 				unsigned char md[EVP_MAX_MD_SIZE];
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 				if (!X509_digest(x,digest,md,&n))
8900Sstevel@tonic-gate 					{
8910Sstevel@tonic-gate 					BIO_printf(bio_err,"out of memory\n");
8920Sstevel@tonic-gate 					goto end;
8930Sstevel@tonic-gate 					}
8940Sstevel@tonic-gate 				BIO_printf(STDout,"%s Fingerprint=",
8950Sstevel@tonic-gate 						OBJ_nid2sn(EVP_MD_type(digest)));
8960Sstevel@tonic-gate 				for (j=0; j<(int)n; j++)
8970Sstevel@tonic-gate 					{
8980Sstevel@tonic-gate 					BIO_printf(STDout,"%02X%c",md[j],
8990Sstevel@tonic-gate 						(j+1 == (int)n)
9000Sstevel@tonic-gate 						?'\n':':');
9010Sstevel@tonic-gate 					}
9020Sstevel@tonic-gate 				}
9030Sstevel@tonic-gate 
9040Sstevel@tonic-gate 			/* should be in the library */
9050Sstevel@tonic-gate 			else if ((sign_flag == i) && (x509req == 0))
9060Sstevel@tonic-gate 				{
9070Sstevel@tonic-gate 				BIO_printf(bio_err,"Getting Private key\n");
9080Sstevel@tonic-gate 				if (Upkey == NULL)
9090Sstevel@tonic-gate 					{
9100Sstevel@tonic-gate 					Upkey=load_key(bio_err,
9110Sstevel@tonic-gate 						keyfile, keyformat, 0,
9120Sstevel@tonic-gate 						passin, e, "Private key");
9130Sstevel@tonic-gate 					if (Upkey == NULL) goto end;
9140Sstevel@tonic-gate 					}
9150Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
9160Sstevel@tonic-gate 		                if (Upkey->type == EVP_PKEY_DSA)
9170Sstevel@tonic-gate 		                        digest=EVP_dss1();
9180Sstevel@tonic-gate #endif
9192139Sjp161948 #ifndef OPENSSL_NO_ECDSA
9202139Sjp161948 				if (Upkey->type == EVP_PKEY_EC)
9212139Sjp161948 					digest=EVP_ecdsa();
9222139Sjp161948 #endif
9230Sstevel@tonic-gate 
9240Sstevel@tonic-gate 				assert(need_rand);
9250Sstevel@tonic-gate 				if (!sign(x,Upkey,days,clrext,digest,
9260Sstevel@tonic-gate 						 extconf, extsect)) goto end;
9270Sstevel@tonic-gate 				}
9280Sstevel@tonic-gate 			else if (CA_flag == i)
9290Sstevel@tonic-gate 				{
9300Sstevel@tonic-gate 				BIO_printf(bio_err,"Getting CA Private Key\n");
9310Sstevel@tonic-gate 				if (CAkeyfile != NULL)
9320Sstevel@tonic-gate 					{
9330Sstevel@tonic-gate 					CApkey=load_key(bio_err,
9340Sstevel@tonic-gate 						CAkeyfile, CAkeyformat,
9350Sstevel@tonic-gate 						0, passin, e,
9360Sstevel@tonic-gate 						"CA Private Key");
9370Sstevel@tonic-gate 					if (CApkey == NULL) goto end;
9380Sstevel@tonic-gate 					}
9390Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
9400Sstevel@tonic-gate 		                if (CApkey->type == EVP_PKEY_DSA)
9410Sstevel@tonic-gate 		                        digest=EVP_dss1();
9420Sstevel@tonic-gate #endif
9432139Sjp161948 #ifndef OPENSSL_NO_ECDSA
9442139Sjp161948 				if (CApkey->type == EVP_PKEY_EC)
9452139Sjp161948 					digest = EVP_ecdsa();
9462139Sjp161948 #endif
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate 				assert(need_rand);
9490Sstevel@tonic-gate 				if (!x509_certify(ctx,CAfile,digest,x,xca,
9500Sstevel@tonic-gate 					CApkey, CAserial,CA_createserial,days, clrext,
9510Sstevel@tonic-gate 					extconf, extsect, sno))
9520Sstevel@tonic-gate 					goto end;
9530Sstevel@tonic-gate 				}
9540Sstevel@tonic-gate 			else if (x509req == i)
9550Sstevel@tonic-gate 				{
9560Sstevel@tonic-gate 				EVP_PKEY *pk;
9570Sstevel@tonic-gate 
9580Sstevel@tonic-gate 				BIO_printf(bio_err,"Getting request Private Key\n");
9590Sstevel@tonic-gate 				if (keyfile == NULL)
9600Sstevel@tonic-gate 					{
9610Sstevel@tonic-gate 					BIO_printf(bio_err,"no request key file specified\n");
9620Sstevel@tonic-gate 					goto end;
9630Sstevel@tonic-gate 					}
9640Sstevel@tonic-gate 				else
9650Sstevel@tonic-gate 					{
9660Sstevel@tonic-gate 					pk=load_key(bio_err,
9670Sstevel@tonic-gate 						keyfile, FORMAT_PEM, 0,
9680Sstevel@tonic-gate 						passin, e, "request key");
9690Sstevel@tonic-gate 					if (pk == NULL) goto end;
9700Sstevel@tonic-gate 					}
9710Sstevel@tonic-gate 
9720Sstevel@tonic-gate 				BIO_printf(bio_err,"Generating certificate request\n");
9730Sstevel@tonic-gate 
9740Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
9750Sstevel@tonic-gate 		                if (pk->type == EVP_PKEY_DSA)
9760Sstevel@tonic-gate 		                        digest=EVP_dss1();
9770Sstevel@tonic-gate #endif
9782139Sjp161948 #ifndef OPENSSL_NO_ECDSA
9792139Sjp161948 				if (pk->type == EVP_PKEY_EC)
9802139Sjp161948 					digest=EVP_ecdsa();
9812139Sjp161948 #endif
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 				rq=X509_to_X509_REQ(x,pk,digest);
9840Sstevel@tonic-gate 				EVP_PKEY_free(pk);
9850Sstevel@tonic-gate 				if (rq == NULL)
9860Sstevel@tonic-gate 					{
9870Sstevel@tonic-gate 					ERR_print_errors(bio_err);
9880Sstevel@tonic-gate 					goto end;
9890Sstevel@tonic-gate 					}
9900Sstevel@tonic-gate 				if (!noout)
9910Sstevel@tonic-gate 					{
9920Sstevel@tonic-gate 					X509_REQ_print(out,rq);
9930Sstevel@tonic-gate 					PEM_write_bio_X509_REQ(out,rq);
9940Sstevel@tonic-gate 					}
9950Sstevel@tonic-gate 				noout=1;
9960Sstevel@tonic-gate 				}
9970Sstevel@tonic-gate 			else if (ocspid == i)
9980Sstevel@tonic-gate 				{
9990Sstevel@tonic-gate 				X509_ocspid_print(out, x);
10000Sstevel@tonic-gate 				}
10010Sstevel@tonic-gate 			}
10020Sstevel@tonic-gate 		}
10030Sstevel@tonic-gate 
10040Sstevel@tonic-gate 	if (checkend)
10050Sstevel@tonic-gate 		{
10062139Sjp161948 		time_t tcheck=time(NULL) + checkoffset;
10070Sstevel@tonic-gate 
10082139Sjp161948 		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
10090Sstevel@tonic-gate 			{
10100Sstevel@tonic-gate 			BIO_printf(out,"Certificate will expire\n");
10110Sstevel@tonic-gate 			ret=1;
10120Sstevel@tonic-gate 			}
10130Sstevel@tonic-gate 		else
10140Sstevel@tonic-gate 			{
10150Sstevel@tonic-gate 			BIO_printf(out,"Certificate will not expire\n");
10160Sstevel@tonic-gate 			ret=0;
10170Sstevel@tonic-gate 			}
10180Sstevel@tonic-gate 		goto end;
10190Sstevel@tonic-gate 		}
10200Sstevel@tonic-gate 
10210Sstevel@tonic-gate 	if (noout)
10220Sstevel@tonic-gate 		{
10230Sstevel@tonic-gate 		ret=0;
10240Sstevel@tonic-gate 		goto end;
10250Sstevel@tonic-gate 		}
10260Sstevel@tonic-gate 
10270Sstevel@tonic-gate 	if 	(outformat == FORMAT_ASN1)
10280Sstevel@tonic-gate 		i=i2d_X509_bio(out,x);
10290Sstevel@tonic-gate 	else if (outformat == FORMAT_PEM)
10300Sstevel@tonic-gate 		{
10310Sstevel@tonic-gate 		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
10320Sstevel@tonic-gate 		else i=PEM_write_bio_X509(out,x);
10330Sstevel@tonic-gate 		}
10340Sstevel@tonic-gate 	else if (outformat == FORMAT_NETSCAPE)
10350Sstevel@tonic-gate 		{
10360Sstevel@tonic-gate 		ASN1_HEADER ah;
10370Sstevel@tonic-gate 		ASN1_OCTET_STRING os;
10380Sstevel@tonic-gate 
10390Sstevel@tonic-gate 		os.data=(unsigned char *)NETSCAPE_CERT_HDR;
10400Sstevel@tonic-gate 		os.length=strlen(NETSCAPE_CERT_HDR);
10410Sstevel@tonic-gate 		ah.header= &os;
10420Sstevel@tonic-gate 		ah.data=(char *)x;
10430Sstevel@tonic-gate 		ah.meth=X509_asn1_meth();
10440Sstevel@tonic-gate 
10452139Sjp161948 		i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah);
10460Sstevel@tonic-gate 		}
10470Sstevel@tonic-gate 	else	{
10480Sstevel@tonic-gate 		BIO_printf(bio_err,"bad output format specified for outfile\n");
10490Sstevel@tonic-gate 		goto end;
10500Sstevel@tonic-gate 		}
10510Sstevel@tonic-gate 	if (!i)
10520Sstevel@tonic-gate 		{
10530Sstevel@tonic-gate 		BIO_printf(bio_err,"unable to write certificate\n");
10540Sstevel@tonic-gate 		ERR_print_errors(bio_err);
10550Sstevel@tonic-gate 		goto end;
10560Sstevel@tonic-gate 		}
10570Sstevel@tonic-gate 	ret=0;
10580Sstevel@tonic-gate end:
10590Sstevel@tonic-gate 	if (need_rand)
10600Sstevel@tonic-gate 		app_RAND_write_file(NULL, bio_err);
10610Sstevel@tonic-gate 	OBJ_cleanup();
10620Sstevel@tonic-gate 	NCONF_free(extconf);
10630Sstevel@tonic-gate 	BIO_free_all(out);
10640Sstevel@tonic-gate 	BIO_free_all(STDout);
10650Sstevel@tonic-gate 	X509_STORE_free(ctx);
10660Sstevel@tonic-gate 	X509_REQ_free(req);
10670Sstevel@tonic-gate 	X509_free(x);
10680Sstevel@tonic-gate 	X509_free(xca);
10690Sstevel@tonic-gate 	EVP_PKEY_free(Upkey);
10700Sstevel@tonic-gate 	EVP_PKEY_free(CApkey);
10710Sstevel@tonic-gate 	X509_REQ_free(rq);
10720Sstevel@tonic-gate 	ASN1_INTEGER_free(sno);
10730Sstevel@tonic-gate 	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
10740Sstevel@tonic-gate 	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
10750Sstevel@tonic-gate 	if (passin) OPENSSL_free(passin);
10760Sstevel@tonic-gate 	apps_shutdown();
10770Sstevel@tonic-gate 	OPENSSL_EXIT(ret);
10780Sstevel@tonic-gate 	}
10790Sstevel@tonic-gate 
x509_load_serial(char * CAfile,char * serialfile,int create)10800Sstevel@tonic-gate static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
10810Sstevel@tonic-gate 	{
10820Sstevel@tonic-gate 	char *buf = NULL, *p;
10830Sstevel@tonic-gate 	ASN1_INTEGER *bs = NULL;
10840Sstevel@tonic-gate 	BIGNUM *serial = NULL;
10850Sstevel@tonic-gate 	size_t len;
10860Sstevel@tonic-gate 
10870Sstevel@tonic-gate 	len = ((serialfile == NULL)
10880Sstevel@tonic-gate 		?(strlen(CAfile)+strlen(POSTFIX)+1)
10890Sstevel@tonic-gate 		:(strlen(serialfile)))+1;
10900Sstevel@tonic-gate 	buf=OPENSSL_malloc(len);
10910Sstevel@tonic-gate 	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
10920Sstevel@tonic-gate 	if (serialfile == NULL)
10930Sstevel@tonic-gate 		{
10940Sstevel@tonic-gate 		BUF_strlcpy(buf,CAfile,len);
10950Sstevel@tonic-gate 		for (p=buf; *p; p++)
10960Sstevel@tonic-gate 			if (*p == '.')
10970Sstevel@tonic-gate 				{
10980Sstevel@tonic-gate 				*p='\0';
10990Sstevel@tonic-gate 				break;
11000Sstevel@tonic-gate 				}
11010Sstevel@tonic-gate 		BUF_strlcat(buf,POSTFIX,len);
11020Sstevel@tonic-gate 		}
11030Sstevel@tonic-gate 	else
11040Sstevel@tonic-gate 		BUF_strlcpy(buf,serialfile,len);
11050Sstevel@tonic-gate 
11060Sstevel@tonic-gate 	serial = load_serial(buf, create, NULL);
11070Sstevel@tonic-gate 	if (serial == NULL) goto end;
11080Sstevel@tonic-gate 
11090Sstevel@tonic-gate 	if (!BN_add_word(serial,1))
11100Sstevel@tonic-gate 		{ BIO_printf(bio_err,"add_word failure\n"); goto end; }
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 	if (!save_serial(buf, NULL, serial, &bs)) goto end;
11130Sstevel@tonic-gate 
11140Sstevel@tonic-gate  end:
11150Sstevel@tonic-gate 	if (buf) OPENSSL_free(buf);
11160Sstevel@tonic-gate 	BN_free(serial);
11170Sstevel@tonic-gate 	return bs;
11180Sstevel@tonic-gate 	}
11190Sstevel@tonic-gate 
x509_certify(X509_STORE * ctx,char * CAfile,const EVP_MD * digest,X509 * x,X509 * xca,EVP_PKEY * pkey,char * serialfile,int create,int days,int clrext,CONF * conf,char * section,ASN1_INTEGER * sno)11200Sstevel@tonic-gate static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
11210Sstevel@tonic-gate 	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
11220Sstevel@tonic-gate 	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
11230Sstevel@tonic-gate 	{
11240Sstevel@tonic-gate 	int ret=0;
11250Sstevel@tonic-gate 	ASN1_INTEGER *bs=NULL;
11260Sstevel@tonic-gate 	X509_STORE_CTX xsc;
11270Sstevel@tonic-gate 	EVP_PKEY *upkey;
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	upkey = X509_get_pubkey(xca);
11300Sstevel@tonic-gate 	EVP_PKEY_copy_parameters(upkey,pkey);
11310Sstevel@tonic-gate 	EVP_PKEY_free(upkey);
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
11340Sstevel@tonic-gate 		{
11350Sstevel@tonic-gate 		BIO_printf(bio_err,"Error initialising X509 store\n");
11360Sstevel@tonic-gate 		goto end;
11370Sstevel@tonic-gate 		}
11380Sstevel@tonic-gate 	if (sno) bs = sno;
11390Sstevel@tonic-gate 	else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
11400Sstevel@tonic-gate 		goto end;
11410Sstevel@tonic-gate 
11420Sstevel@tonic-gate /*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
11430Sstevel@tonic-gate 
11440Sstevel@tonic-gate 	/* NOTE: this certificate can/should be self signed, unless it was
11450Sstevel@tonic-gate 	 * a certificate request in which case it is not. */
11460Sstevel@tonic-gate 	X509_STORE_CTX_set_cert(&xsc,x);
1147*8545SJan.Pechanec@Sun.COM 	if (!reqfile && X509_verify_cert(&xsc) <= 0)
11480Sstevel@tonic-gate 		goto end;
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 	if (!X509_check_private_key(xca,pkey))
11510Sstevel@tonic-gate 		{
11520Sstevel@tonic-gate 		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
11530Sstevel@tonic-gate 		goto end;
11540Sstevel@tonic-gate 		}
11550Sstevel@tonic-gate 
11560Sstevel@tonic-gate 	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
11570Sstevel@tonic-gate 	if (!X509_set_serialNumber(x,bs)) goto end;
11580Sstevel@tonic-gate 
11590Sstevel@tonic-gate 	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
11600Sstevel@tonic-gate 		goto end;
11610Sstevel@tonic-gate 
11620Sstevel@tonic-gate 	/* hardwired expired */
11630Sstevel@tonic-gate 	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
11640Sstevel@tonic-gate 		goto end;
11650Sstevel@tonic-gate 
11660Sstevel@tonic-gate 	if (clrext)
11670Sstevel@tonic-gate 		{
11680Sstevel@tonic-gate 		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
11690Sstevel@tonic-gate 		}
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate 	if (conf)
11720Sstevel@tonic-gate 		{
11730Sstevel@tonic-gate 		X509V3_CTX ctx2;
11740Sstevel@tonic-gate 		X509_set_version(x,2); /* version 3 certificate */
11750Sstevel@tonic-gate                 X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
11760Sstevel@tonic-gate                 X509V3_set_nconf(&ctx2, conf);
11770Sstevel@tonic-gate                 if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
11780Sstevel@tonic-gate 		}
11790Sstevel@tonic-gate 
11800Sstevel@tonic-gate 	if (!X509_sign(x,pkey,digest)) goto end;
11810Sstevel@tonic-gate 	ret=1;
11820Sstevel@tonic-gate end:
11830Sstevel@tonic-gate 	X509_STORE_CTX_cleanup(&xsc);
11840Sstevel@tonic-gate 	if (!ret)
11850Sstevel@tonic-gate 		ERR_print_errors(bio_err);
11860Sstevel@tonic-gate 	if (!sno) ASN1_INTEGER_free(bs);
11870Sstevel@tonic-gate 	return ret;
11880Sstevel@tonic-gate 	}
11890Sstevel@tonic-gate 
callb(int ok,X509_STORE_CTX * ctx)11900Sstevel@tonic-gate static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
11910Sstevel@tonic-gate 	{
11920Sstevel@tonic-gate 	int err;
11930Sstevel@tonic-gate 	X509 *err_cert;
11940Sstevel@tonic-gate 
11950Sstevel@tonic-gate 	/* it is ok to use a self signed certificate
11960Sstevel@tonic-gate 	 * This case will catch both the initial ok == 0 and the
11970Sstevel@tonic-gate 	 * final ok == 1 calls to this function */
11980Sstevel@tonic-gate 	err=X509_STORE_CTX_get_error(ctx);
11990Sstevel@tonic-gate 	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
12000Sstevel@tonic-gate 		return 1;
12010Sstevel@tonic-gate 
12020Sstevel@tonic-gate 	/* BAD we should have gotten an error.  Normally if everything
12030Sstevel@tonic-gate 	 * worked X509_STORE_CTX_get_error(ctx) will still be set to
12040Sstevel@tonic-gate 	 * DEPTH_ZERO_SELF_.... */
12050Sstevel@tonic-gate 	if (ok)
12060Sstevel@tonic-gate 		{
12070Sstevel@tonic-gate 		BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
12080Sstevel@tonic-gate 		return 0;
12090Sstevel@tonic-gate 		}
12100Sstevel@tonic-gate 	else
12110Sstevel@tonic-gate 		{
12120Sstevel@tonic-gate 		err_cert=X509_STORE_CTX_get_current_cert(ctx);
12130Sstevel@tonic-gate 		print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
12140Sstevel@tonic-gate 		BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
12150Sstevel@tonic-gate 			err,X509_STORE_CTX_get_error_depth(ctx),
12160Sstevel@tonic-gate 			X509_verify_cert_error_string(err));
12170Sstevel@tonic-gate 		return 1;
12180Sstevel@tonic-gate 		}
12190Sstevel@tonic-gate 	}
12200Sstevel@tonic-gate 
12210Sstevel@tonic-gate /* self sign */
sign(X509 * x,EVP_PKEY * pkey,int days,int clrext,const EVP_MD * digest,CONF * conf,char * section)12220Sstevel@tonic-gate static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
12230Sstevel@tonic-gate 						CONF *conf, char *section)
12240Sstevel@tonic-gate 	{
12250Sstevel@tonic-gate 
12260Sstevel@tonic-gate 	EVP_PKEY *pktmp;
12270Sstevel@tonic-gate 
12280Sstevel@tonic-gate 	pktmp = X509_get_pubkey(x);
12290Sstevel@tonic-gate 	EVP_PKEY_copy_parameters(pktmp,pkey);
12300Sstevel@tonic-gate 	EVP_PKEY_save_parameters(pktmp,1);
12310Sstevel@tonic-gate 	EVP_PKEY_free(pktmp);
12320Sstevel@tonic-gate 
12330Sstevel@tonic-gate 	if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
12340Sstevel@tonic-gate 	if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;
12350Sstevel@tonic-gate 
12360Sstevel@tonic-gate 	/* Lets just make it 12:00am GMT, Jan 1 1970 */
12370Sstevel@tonic-gate 	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
12380Sstevel@tonic-gate 	/* 28 days to be certified */
12390Sstevel@tonic-gate 
12400Sstevel@tonic-gate 	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
12410Sstevel@tonic-gate 		goto err;
12420Sstevel@tonic-gate 
12430Sstevel@tonic-gate 	if (!X509_set_pubkey(x,pkey)) goto err;
12440Sstevel@tonic-gate 	if (clrext)
12450Sstevel@tonic-gate 		{
12460Sstevel@tonic-gate 		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
12470Sstevel@tonic-gate 		}
12480Sstevel@tonic-gate 	if (conf)
12490Sstevel@tonic-gate 		{
12500Sstevel@tonic-gate 		X509V3_CTX ctx;
12510Sstevel@tonic-gate 		X509_set_version(x,2); /* version 3 certificate */
12520Sstevel@tonic-gate                 X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
12530Sstevel@tonic-gate                 X509V3_set_nconf(&ctx, conf);
12540Sstevel@tonic-gate                 if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
12550Sstevel@tonic-gate 		}
12560Sstevel@tonic-gate 	if (!X509_sign(x,pkey,digest)) goto err;
12570Sstevel@tonic-gate 	return 1;
12580Sstevel@tonic-gate err:
12590Sstevel@tonic-gate 	ERR_print_errors(bio_err);
12600Sstevel@tonic-gate 	return 0;
12610Sstevel@tonic-gate 	}
12620Sstevel@tonic-gate 
purpose_print(BIO * bio,X509 * cert,X509_PURPOSE * pt)12630Sstevel@tonic-gate static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
12640Sstevel@tonic-gate {
12650Sstevel@tonic-gate 	int id, i, idret;
12660Sstevel@tonic-gate 	char *pname;
12670Sstevel@tonic-gate 	id = X509_PURPOSE_get_id(pt);
12680Sstevel@tonic-gate 	pname = X509_PURPOSE_get0_name(pt);
12690Sstevel@tonic-gate 	for (i = 0; i < 2; i++)
12700Sstevel@tonic-gate 		{
12710Sstevel@tonic-gate 		idret = X509_check_purpose(cert, id, i);
12720Sstevel@tonic-gate 		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
12730Sstevel@tonic-gate 		if (idret == 1) BIO_printf(bio, "Yes\n");
12740Sstevel@tonic-gate 		else if (idret == 0) BIO_printf(bio, "No\n");
12750Sstevel@tonic-gate 		else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
12760Sstevel@tonic-gate 		}
12770Sstevel@tonic-gate 	return 1;
12780Sstevel@tonic-gate }
1279