x509.c revision 246772
1180740Sdes/* apps/x509.c */ 2180740Sdes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3226046Sdes * All rights reserved. 4226046Sdes * 5226046Sdes * This package is an SSL implementation written 6180740Sdes * by Eric Young (eay@cryptsoft.com). 7180740Sdes * The implementation was written so as to conform with Netscapes SSL. 8180740Sdes * 9180740Sdes * This library is free for commercial and non-commercial use as long as 10180740Sdes * the following conditions are aheared to. The following conditions 11180740Sdes * apply to all code found in this distribution, be it the RC4, RSA, 12180740Sdes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13180746Sdes * included with this distribution is covered by the same copyright terms 14180746Sdes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15180746Sdes * 16180740Sdes * Copyright remains Eric Young's, and as such any Copyright notices in 17180740Sdes * the code are not to be removed. 18180740Sdes * If this package is used in a product, Eric Young should be given attribution 19240075Sdes * as the author of the parts of the library used. 20240075Sdes * This can be in the form of a textual message at program startup or 21240075Sdes * in documentation (online or textual) provided with the package. 22180740Sdes * 23180740Sdes * Redistribution and use in source and binary forms, with or without 24180740Sdes * modification, are permitted provided that the following conditions 25180740Sdes * are met: 26180740Sdes * 1. Redistributions of source code must retain the copyright 27180740Sdes * notice, this list of conditions and the following disclaimer. 28180740Sdes * 2. Redistributions in binary form must reproduce the above copyright 29180740Sdes * notice, this list of conditions and the following disclaimer in the 30180740Sdes * documentation and/or other materials provided with the distribution. 31180746Sdes * 3. All advertising materials mentioning features or use of this software 32180746Sdes * must display the following acknowledgement: 33180746Sdes * "This product includes cryptographic software written by 34180740Sdes * Eric Young (eay@cryptsoft.com)" 35180740Sdes * The word 'cryptographic' can be left out if the rouines from the library 36180740Sdes * being used are not cryptographic related :-). 37180740Sdes * 4. If you include any Windows specific code (or a derivative thereof) from 38180740Sdes * the apps directory (application code) you must include an acknowledgement: 39180740Sdes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40180740Sdes * 41180740Sdes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42180740Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43180740Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44180740Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45180740Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46180740Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47180750Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48180750Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49180750Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50262566Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51262566Sdes * SUCH DAMAGE. 52262566Sdes * 53262566Sdes * The licence and distribution terms for any publically available version or 54180740Sdes * derivative of this code cannot be changed. i.e. this code cannot simply be 55180740Sdes * copied and put under another distribution licence 56180740Sdes * [including the GNU Public Licence.] 57180740Sdes */ 58180740Sdes 59180740Sdes#include <assert.h> 60180740Sdes#include <stdio.h> 61180740Sdes#include <stdlib.h> 62180740Sdes#include <string.h> 63180740Sdes#ifdef OPENSSL_NO_STDIO 64180740Sdes#define APPS_WIN16 65180740Sdes#endif 66180740Sdes#include "apps.h" 67180740Sdes#include <openssl/bio.h> 68180740Sdes#include <openssl/asn1.h> 69180740Sdes#include <openssl/err.h> 70180740Sdes#include <openssl/bn.h> 71180740Sdes#include <openssl/evp.h> 72180740Sdes#include <openssl/x509.h> 73180740Sdes#include <openssl/x509v3.h> 74180740Sdes#include <openssl/objects.h> 75180746Sdes#include <openssl/pem.h> 76180746Sdes#ifndef OPENSSL_NO_RSA 77180746Sdes#include <openssl/rsa.h> 78180740Sdes#endif 79180740Sdes#ifndef OPENSSL_NO_DSA 80180740Sdes#include <openssl/dsa.h> 81262566Sdes#endif 82248619Sdes 83248619Sdes#undef PROG 84197679Sdes#define PROG x509_main 85197679Sdes 86197679Sdes#undef POSTFIX 87180740Sdes#define POSTFIX ".srl" 88180740Sdes#define DEF_DAYS 30 89180740Sdes 90180740Sdesstatic const char *x509_usage[]={ 91180740Sdes"usage: x509 args\n", 92180740Sdes" -inform arg - input format - default PEM (one of DER, NET or PEM)\n", 93180740Sdes" -outform arg - output format - default PEM (one of DER, NET or PEM)\n", 94180740Sdes" -keyform arg - private key format - default PEM\n", 95180740Sdes" -CAform arg - CA format - default PEM\n", 96180740Sdes" -CAkeyform arg - CA key format - default PEM\n", 97180740Sdes" -in arg - input file - default stdin\n", 98180740Sdes" -out arg - output file - default stdout\n", 99180740Sdes" -passin arg - private key password source\n", 100180740Sdes" -serial - print serial number value\n", 101180740Sdes" -subject_hash - print subject hash value\n", 102180740Sdes#ifndef OPENSSL_NO_MD5 103180740Sdes" -subject_hash_old - print old-style (MD5) subject hash value\n", 104180740Sdes#endif 105180740Sdes" -issuer_hash - print issuer hash value\n", 106180740Sdes#ifndef OPENSSL_NO_MD5 107180740Sdes" -issuer_hash_old - print old-style (MD5) issuer hash value\n", 108180740Sdes#endif 109180740Sdes" -hash - synonym for -subject_hash\n", 110180740Sdes" -subject - print subject DN\n", 111180740Sdes" -issuer - print issuer DN\n", 112180740Sdes" -email - print email address(es)\n", 113180740Sdes" -startdate - notBefore field\n", 114180740Sdes" -enddate - notAfter field\n", 115180740Sdes" -purpose - print out certificate purposes\n", 116180740Sdes" -dates - both Before and After dates\n", 117180740Sdes" -modulus - print the RSA key modulus\n", 118180740Sdes" -pubkey - output the public key\n", 119180740Sdes" -fingerprint - print the certificate fingerprint\n", 120180740Sdes" -alias - output certificate alias\n", 121180740Sdes" -noout - no certificate output\n", 122180740Sdes" -ocspid - print OCSP hash values for the subject name and public key\n", 123180740Sdes" -ocsp_uri - print OCSP Responder URL(s)\n", 124180740Sdes" -trustout - output a \"trusted\" certificate\n", 125180740Sdes" -clrtrust - clear all trusted purposes\n", 126180740Sdes" -clrreject - clear all rejected purposes\n", 127180740Sdes" -addtrust arg - trust certificate for a given purpose\n", 128180740Sdes" -addreject arg - reject certificate for a given purpose\n", 129180740Sdes" -setalias arg - set certificate alias\n", 130180740Sdes" -days arg - How long till expiry of a signed certificate - def 30 days\n", 131180740Sdes" -checkend arg - check whether the cert expires in the next arg seconds\n", 132180740Sdes" exit 1 if so, 0 if not\n", 133180740Sdes" -signkey arg - self sign cert with arg\n", 134180740Sdes" -x509toreq - output a certification request object\n", 135204917Sdes" -req - input is a certificate request, sign and output.\n", 136204917Sdes" -CA arg - set the CA certificate, must be PEM format.\n", 137204917Sdes" -CAkey arg - set the CA key, must be PEM format\n", 138221420Sdes" missing, it is assumed to be in the CA file.\n", 139221420Sdes" -CAcreateserial - create serial number file if it does not exist\n", 140221420Sdes" -CAserial arg - serial file\n", 141197679Sdes" -set_serial - serial number to use\n", 142180750Sdes" -text - print the certificate in text form\n", 143180750Sdes" -C - print out C code forms\n", 144197679Sdes" -md2/-md5/-sha1/-mdc2 - digest to use\n", 145197679Sdes" -extfile - configuration file with X509V3 extensions to add\n", 146197679Sdes" -extensions - section from config file with X509V3 extensions to add\n", 147180740Sdes" -clrext - delete extensions before signing and input certificate\n", 148180740Sdes" -nameopt arg - various certificate name options\n", 149180740Sdes#ifndef OPENSSL_NO_ENGINE 150180740Sdes" -engine e - use engine e, possibly a hardware device.\n", 151180740Sdes#endif 152180740Sdes" -certopt arg - various certificate text options\n", 153180740SdesNULL 154180740Sdes}; 155180740Sdes 156180740Sdesstatic int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx); 157180740Sdesstatic int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest, 158180740Sdes CONF *conf, char *section); 159221420Sdesstatic int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest, 160221420Sdes X509 *x,X509 *xca,EVP_PKEY *pkey, 161221420Sdes STACK_OF(OPENSSL_STRING) *sigopts, 162180740Sdes char *serial, int create ,int days, int clrext, 163180740Sdes CONF *conf, char *section, ASN1_INTEGER *sno); 164180740Sdesstatic int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); 165180740Sdesstatic int reqfile=0; 166180740Sdes 167180740Sdesint MAIN(int, char **); 168180740Sdes 169180740Sdesint MAIN(int argc, char **argv) 170180740Sdes { 171180740Sdes ENGINE *e = NULL; 172180740Sdes int ret=1; 173180740Sdes X509_REQ *req=NULL; 174180740Sdes X509 *x=NULL,*xca=NULL; 175180740Sdes ASN1_OBJECT *objtmp; 176180740Sdes STACK_OF(OPENSSL_STRING) *sigopts = NULL; 177180740Sdes EVP_PKEY *Upkey=NULL,*CApkey=NULL; 178180740Sdes ASN1_INTEGER *sno = NULL; 179180740Sdes int i,num,badops=0; 180180740Sdes BIO *out=NULL; 181180740Sdes BIO *STDout=NULL; 182180740Sdes STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; 183180740Sdes int informat,outformat,keyformat,CAformat,CAkeyformat; 184180740Sdes char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL; 185180740Sdes char *CAkeyfile=NULL,*CAserial=NULL; 186180750Sdes char *alias=NULL; 187180750Sdes int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0; 188180750Sdes int next_serial=0; 189262566Sdes int subject_hash=0,issuer_hash=0,ocspid=0; 190262566Sdes#ifndef OPENSSL_NO_MD5 191262566Sdes int subject_hash_old=0,issuer_hash_old=0; 192180750Sdes#endif 193180750Sdes int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; 194180750Sdes int ocsp_uri=0; 195180740Sdes int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; 196180740Sdes int C=0; 197180740Sdes int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0; 198180740Sdes int pprint = 0; 199180740Sdes const char **pp; 200180740Sdes X509_STORE *ctx=NULL; 201180744Sdes X509_REQ *rq=NULL; 202180744Sdes int fingerprint=0; 203180744Sdes char buf[256]; 204180740Sdes const EVP_MD *md_alg,*digest=NULL; 205180740Sdes CONF *extconf = NULL; 206180740Sdes char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; 207180746Sdes int need_rand = 0; 208180746Sdes int checkend=0,checkoffset=0; 209180746Sdes unsigned long nmflag = 0, certflag = 0; 210180740Sdes#ifndef OPENSSL_NO_ENGINE 211180740Sdes char *engine=NULL; 212180740Sdes#endif 213180740Sdes 214180740Sdes reqfile=0; 215180740Sdes 216180740Sdes apps_startup(); 217180740Sdes 218180740Sdes if (bio_err == NULL) 219180740Sdes bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 220180740Sdes 221180740Sdes if (!load_config(bio_err, NULL)) 222262566Sdes goto end; 223262566Sdes STDout=BIO_new_fp(stdout,BIO_NOCLOSE); 224262566Sdes#ifdef OPENSSL_SYS_VMS 225180740Sdes { 226180740Sdes BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 227180740Sdes STDout = BIO_push(tmpbio, STDout); 228262566Sdes } 229262566Sdes#endif 230262566Sdes 231262566Sdes informat=FORMAT_PEM; 232262566Sdes outformat=FORMAT_PEM; 233262566Sdes keyformat=FORMAT_PEM; 234262566Sdes CAformat=FORMAT_PEM; 235262566Sdes CAkeyformat=FORMAT_PEM; 236262566Sdes 237262566Sdes ctx=X509_STORE_new(); 238262566Sdes if (ctx == NULL) goto end; 239262566Sdes X509_STORE_set_verify_cb(ctx,callb); 240262566Sdes 241262566Sdes argc--; 242262566Sdes argv++; 243262566Sdes num=0; 244262566Sdes while (argc >= 1) 245262566Sdes { 246221420Sdes if (strcmp(*argv,"-inform") == 0) 247221420Sdes { 248221420Sdes if (--argc < 1) goto bad; 249248619Sdes informat=str2fmt(*(++argv)); 250248619Sdes } 251248619Sdes else if (strcmp(*argv,"-outform") == 0) 252180740Sdes { 253180740Sdes if (--argc < 1) goto bad; 254180740Sdes outformat=str2fmt(*(++argv)); 255180740Sdes } 256180740Sdes else if (strcmp(*argv,"-keyform") == 0) 257180740Sdes { 258262566Sdes if (--argc < 1) goto bad; 259262566Sdes keyformat=str2fmt(*(++argv)); 260262566Sdes } 261180740Sdes else if (strcmp(*argv,"-req") == 0) 262180740Sdes { 263180740Sdes reqfile=1; 264255767Sdes need_rand = 1; 265255767Sdes } 266255767Sdes else if (strcmp(*argv,"-CAform") == 0) 267180740Sdes { 268180740Sdes if (--argc < 1) goto bad; 269180740Sdes CAformat=str2fmt(*(++argv)); 270180740Sdes } 271180740Sdes else if (strcmp(*argv,"-CAkeyform") == 0) 272180740Sdes { 273180740Sdes if (--argc < 1) goto bad; 274180740Sdes CAkeyformat=str2fmt(*(++argv)); 275180740Sdes } 276180740Sdes else if (strcmp(*argv,"-sigopt") == 0) 277180740Sdes { 278180740Sdes if (--argc < 1) 279255767Sdes goto bad; 280255767Sdes if (!sigopts) 281255767Sdes sigopts = sk_OPENSSL_STRING_new_null(); 282180740Sdes if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) 283180740Sdes goto bad; 284180740Sdes } 285180740Sdes else if (strcmp(*argv,"-days") == 0) 286180740Sdes { 287180740Sdes if (--argc < 1) goto bad; 288180740Sdes days=atoi(*(++argv)); 289180740Sdes if (days == 0) 290180740Sdes { 291180740Sdes BIO_printf(bio_err,"bad number of days\n"); 292180740Sdes goto bad; 293180740Sdes } 294180740Sdes } 295180740Sdes else if (strcmp(*argv,"-passin") == 0) 296180740Sdes { 297180740Sdes if (--argc < 1) goto bad; 298180740Sdes passargin= *(++argv); 299180740Sdes } 300180740Sdes else if (strcmp(*argv,"-extfile") == 0) 301180740Sdes { 302248619Sdes if (--argc < 1) goto bad; 303248619Sdes extfile= *(++argv); 304248619Sdes } 305248619Sdes else if (strcmp(*argv,"-extensions") == 0) 306255767Sdes { 307255767Sdes if (--argc < 1) goto bad; 308255767Sdes extsect= *(++argv); 309255767Sdes } 310180740Sdes else if (strcmp(*argv,"-in") == 0) 311180740Sdes { 312180740Sdes if (--argc < 1) goto bad; 313180740Sdes infile= *(++argv); 314180740Sdes } 315180740Sdes else if (strcmp(*argv,"-out") == 0) 316180740Sdes { 317180740Sdes if (--argc < 1) goto bad; 318180740Sdes outfile= *(++argv); 319180740Sdes } 320180740Sdes else if (strcmp(*argv,"-signkey") == 0) 321180740Sdes { 322180740Sdes if (--argc < 1) goto bad; 323180740Sdes keyfile= *(++argv); 324180740Sdes sign_flag= ++num; 325180740Sdes need_rand = 1; 326180744Sdes } 327180744Sdes else if (strcmp(*argv,"-CA") == 0) 328180744Sdes { 329180744Sdes if (--argc < 1) goto bad; 330255767Sdes CAfile= *(++argv); 331255767Sdes CA_flag= ++num; 332255767Sdes need_rand = 1; 333255767Sdes } 334180744Sdes else if (strcmp(*argv,"-CAkey") == 0) 335180744Sdes { 336180744Sdes if (--argc < 1) goto bad; 337180744Sdes CAkeyfile= *(++argv); 338180740Sdes } 339180740Sdes else if (strcmp(*argv,"-CAserial") == 0) 340180740Sdes { 341180740Sdes if (--argc < 1) goto bad; 342180740Sdes CAserial= *(++argv); 343180740Sdes } 344180740Sdes else if (strcmp(*argv,"-set_serial") == 0) 345180740Sdes { 346180740Sdes if (--argc < 1) goto bad; 347180740Sdes if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) 348180740Sdes goto bad; 349180740Sdes } 350180740Sdes else if (strcmp(*argv,"-addtrust") == 0) 351180740Sdes { 352180740Sdes if (--argc < 1) goto bad; 353180740Sdes if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) 354180740Sdes { 355180740Sdes BIO_printf(bio_err, 356180740Sdes "Invalid trust object value %s\n", *argv); 357180740Sdes goto bad; 358180740Sdes } 359180740Sdes if (!trust) trust = sk_ASN1_OBJECT_new_null(); 360180740Sdes sk_ASN1_OBJECT_push(trust, objtmp); 361180740Sdes trustout = 1; 362180740Sdes } 363180740Sdes else if (strcmp(*argv,"-addreject") == 0) 364180740Sdes { 365180740Sdes if (--argc < 1) goto bad; 366255767Sdes if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) 367255767Sdes { 368255767Sdes BIO_printf(bio_err, 369180740Sdes "Invalid reject object value %s\n", *argv); 370180740Sdes goto bad; 371180740Sdes } 372180740Sdes if (!reject) reject = sk_ASN1_OBJECT_new_null(); 373180740Sdes sk_ASN1_OBJECT_push(reject, objtmp); 374180740Sdes trustout = 1; 375180740Sdes } 376180740Sdes else if (strcmp(*argv,"-setalias") == 0) 377180740Sdes { 378180740Sdes if (--argc < 1) goto bad; 379180740Sdes alias= *(++argv); 380180740Sdes trustout = 1; 381180740Sdes } 382180740Sdes else if (strcmp(*argv,"-certopt") == 0) 383180740Sdes { 384221420Sdes if (--argc < 1) goto bad; 385221420Sdes if (!set_cert_ex(&certflag, *(++argv))) goto bad; 386221420Sdes } 387248619Sdes else if (strcmp(*argv,"-nameopt") == 0) 388248619Sdes { 389248619Sdes if (--argc < 1) goto bad; 390255767Sdes if (!set_name_ex(&nmflag, *(++argv))) goto bad; 391255767Sdes } 392255767Sdes#ifndef OPENSSL_NO_ENGINE 393180740Sdes else if (strcmp(*argv,"-engine") == 0) 394180740Sdes { 395180740Sdes if (--argc < 1) goto bad; 396180740Sdes engine= *(++argv); 397180740Sdes } 398180740Sdes#endif 399180740Sdes else if (strcmp(*argv,"-C") == 0) 400180740Sdes C= ++num; 401180740Sdes else if (strcmp(*argv,"-email") == 0) 402180740Sdes email= ++num; 403180740Sdes else if (strcmp(*argv,"-ocsp_uri") == 0) 404180740Sdes ocsp_uri= ++num; 405248619Sdes else if (strcmp(*argv,"-serial") == 0) 406248619Sdes serial= ++num; 407248619Sdes else if (strcmp(*argv,"-next_serial") == 0) 408262566Sdes next_serial= ++num; 409262566Sdes else if (strcmp(*argv,"-modulus") == 0) 410262566Sdes modulus= ++num; 411262566Sdes else if (strcmp(*argv,"-pubkey") == 0) 412262566Sdes pubkey= ++num; 413262566Sdes else if (strcmp(*argv,"-x509toreq") == 0) 414262566Sdes x509req= ++num; 415262566Sdes else if (strcmp(*argv,"-text") == 0) 416262566Sdes text= ++num; 417264377Sdes else if (strcmp(*argv,"-hash") == 0 418264377Sdes || strcmp(*argv,"-subject_hash") == 0) 419264377Sdes subject_hash= ++num; 420262566Sdes#ifndef OPENSSL_NO_MD5 421262566Sdes else if (strcmp(*argv,"-subject_hash_old") == 0) 422262566Sdes subject_hash_old= ++num; 423180740Sdes#endif 424180740Sdes else if (strcmp(*argv,"-issuer_hash") == 0) 425180740Sdes issuer_hash= ++num; 426180740Sdes#ifndef OPENSSL_NO_MD5 427180740Sdes else if (strcmp(*argv,"-issuer_hash_old") == 0) 428180740Sdes issuer_hash_old= ++num; 429264377Sdes#endif 430264377Sdes else if (strcmp(*argv,"-subject") == 0) 431264377Sdes subject= ++num; 432180740Sdes else if (strcmp(*argv,"-issuer") == 0) 433180740Sdes issuer= ++num; 434180740Sdes else if (strcmp(*argv,"-fingerprint") == 0) 435180740Sdes fingerprint= ++num; 436180740Sdes else if (strcmp(*argv,"-dates") == 0) 437180740Sdes { 438180740Sdes startdate= ++num; 439180740Sdes enddate= ++num; 440180740Sdes } 441180740Sdes else if (strcmp(*argv,"-purpose") == 0) 442180740Sdes pprint= ++num; 443180740Sdes else if (strcmp(*argv,"-startdate") == 0) 444255767Sdes startdate= ++num; 445255767Sdes else if (strcmp(*argv,"-enddate") == 0) 446255767Sdes enddate= ++num; 447180740Sdes else if (strcmp(*argv,"-checkend") == 0) 448180740Sdes { 449180740Sdes if (--argc < 1) goto bad; 450180740Sdes checkoffset=atoi(*(++argv)); 451180740Sdes checkend=1; 452180740Sdes } 453180750Sdes else if (strcmp(*argv,"-noout") == 0) 454180750Sdes noout= ++num; 455180750Sdes else if (strcmp(*argv,"-trustout") == 0) 456180740Sdes trustout= 1; 457180740Sdes else if (strcmp(*argv,"-clrtrust") == 0) 458180740Sdes clrtrust= ++num; 459180750Sdes else if (strcmp(*argv,"-clrreject") == 0) 460180750Sdes clrreject= ++num; 461180750Sdes else if (strcmp(*argv,"-alias") == 0) 462180750Sdes aliasout= ++num; 463180750Sdes else if (strcmp(*argv,"-CAcreateserial") == 0) 464180750Sdes CA_createserial= ++num; 465262566Sdes else if (strcmp(*argv,"-clrext") == 0) 466262566Sdes clrext = 1; 467262566Sdes#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */ 468180750Sdes else if (strcmp(*argv,"-crlext") == 0) 469180750Sdes { 470180750Sdes BIO_printf(bio_err,"use -clrext instead of -crlext\n"); 471180740Sdes clrext = 1; 472180740Sdes } 473180740Sdes#endif 474180740Sdes else if (strcmp(*argv,"-ocspid") == 0) 475180740Sdes ocspid= ++num; 476180740Sdes else if ((md_alg=EVP_get_digestbyname(*argv + 1))) 477180740Sdes { 478180740Sdes /* ok */ 479180740Sdes digest=md_alg; 480180740Sdes } 481180740Sdes else 482180740Sdes { 483180740Sdes BIO_printf(bio_err,"unknown option %s\n",*argv); 484180740Sdes badops=1; 485180740Sdes break; 486180740Sdes } 487180740Sdes argc--; 488180740Sdes argv++; 489180740Sdes } 490180740Sdes 491180740Sdes if (badops) 492180746Sdes { 493180746Sdesbad: 494180746Sdes for (pp=x509_usage; (*pp != NULL); pp++) 495192595Sdes BIO_printf(bio_err,"%s",*pp); 496192595Sdes goto end; 497192595Sdes } 498180740Sdes 499180740Sdes#ifndef OPENSSL_NO_ENGINE 500180740Sdes e = setup_engine(bio_err, engine, 0); 501180740Sdes#endif 502180740Sdes 503180740Sdes if (need_rand) 504180740Sdes app_RAND_load_file(NULL, bio_err, 0); 505180740Sdes 506180740Sdes ERR_load_crypto_strings(); 507180740Sdes 508180740Sdes if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) 509180740Sdes { 510180740Sdes BIO_printf(bio_err, "Error getting password\n"); 511180740Sdes goto end; 512180740Sdes } 513180740Sdes 514180740Sdes if (!X509_STORE_set_default_paths(ctx)) 515180740Sdes { 516180740Sdes ERR_print_errors(bio_err); 517180740Sdes goto end; 518180740Sdes } 519180744Sdes 520180744Sdes if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) 521180744Sdes { CAkeyfile=CAfile; } 522248619Sdes else if ((CA_flag) && (CAkeyfile == NULL)) 523248619Sdes { 524248619Sdes BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n"); 525248619Sdes goto end; 526248619Sdes } 527248619Sdes 528180740Sdes if (extfile) 529180740Sdes { 530180740Sdes long errorline = -1; 531180740Sdes X509V3_CTX ctx2; 532180740Sdes extconf = NCONF_new(NULL); 533180740Sdes if (!NCONF_load(extconf, extfile,&errorline)) 534180740Sdes { 535180740Sdes if (errorline <= 0) 536180740Sdes BIO_printf(bio_err, 537180740Sdes "error loading the config file '%s'\n", 538180740Sdes extfile); 539180740Sdes else 540180740Sdes BIO_printf(bio_err, 541180740Sdes "error on line %ld of config file '%s'\n" 542180740Sdes ,errorline,extfile); 543180740Sdes goto end; 544180740Sdes } 545180740Sdes if (!extsect) 546180740Sdes { 547180740Sdes extsect = NCONF_get_string(extconf, "default", "extensions"); 548180740Sdes if (!extsect) 549180740Sdes { 550180740Sdes ERR_clear_error(); 551180740Sdes extsect = "default"; 552180740Sdes } 553180740Sdes } 554180740Sdes X509V3_set_ctx_test(&ctx2); 555180740Sdes X509V3_set_nconf(&ctx2, extconf); 556180740Sdes if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) 557180740Sdes { 558180740Sdes BIO_printf(bio_err, 559180740Sdes "Error Loading extension section %s\n", 560180740Sdes extsect); 561180740Sdes ERR_print_errors(bio_err); 562180740Sdes goto end; 563180740Sdes } 564180740Sdes } 565180740Sdes 566180740Sdes 567207319Sdes if (reqfile) 568207319Sdes { 569207319Sdes EVP_PKEY *pkey; 570180740Sdes BIO *in; 571180740Sdes 572180740Sdes if (!sign_flag && !CA_flag) 573180740Sdes { 574180740Sdes BIO_printf(bio_err,"We need a private key to sign with\n"); 575180740Sdes goto end; 576180740Sdes } 577180740Sdes in=BIO_new(BIO_s_file()); 578180740Sdes if (in == NULL) 579204917Sdes { 580204917Sdes ERR_print_errors(bio_err); 581204917Sdes goto end; 582180740Sdes } 583180740Sdes 584180740Sdes if (infile == NULL) 585180740Sdes BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); 586180740Sdes else 587180740Sdes { 588180740Sdes if (BIO_read_filename(in,infile) <= 0) 589180740Sdes { 590180740Sdes perror(infile); 591180740Sdes BIO_free(in); 592180740Sdes goto end; 593180740Sdes } 594180740Sdes } 595180740Sdes req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL); 596180740Sdes BIO_free(in); 597180740Sdes 598180740Sdes if (req == NULL) 599180740Sdes { 600180740Sdes ERR_print_errors(bio_err); 601180740Sdes goto end; 602180740Sdes } 603240075Sdes 604240075Sdes if ( (req->req_info == NULL) || 605240075Sdes (req->req_info->pubkey == NULL) || 606180740Sdes (req->req_info->pubkey->public_key == NULL) || 607180740Sdes (req->req_info->pubkey->public_key->data == NULL)) 608180740Sdes { 609180740Sdes BIO_printf(bio_err,"The certificate request appears to corrupted\n"); 610180740Sdes BIO_printf(bio_err,"It does not contain a public key\n"); 611180740Sdes goto end; 612180740Sdes } 613180740Sdes if ((pkey=X509_REQ_get_pubkey(req)) == NULL) 614180740Sdes { 615180740Sdes BIO_printf(bio_err,"error unpacking public key\n"); 616180740Sdes goto end; 617180740Sdes } 618180740Sdes i=X509_REQ_verify(req,pkey); 619180740Sdes EVP_PKEY_free(pkey); 620180740Sdes if (i < 0) 621180740Sdes { 622180740Sdes BIO_printf(bio_err,"Signature verification error\n"); 623180740Sdes ERR_print_errors(bio_err); 624180740Sdes goto end; 625180740Sdes } 626180740Sdes if (i == 0) 627180740Sdes { 628180740Sdes BIO_printf(bio_err,"Signature did not match the certificate request\n"); 629180740Sdes goto end; 630180740Sdes } 631180740Sdes else 632180740Sdes BIO_printf(bio_err,"Signature ok\n"); 633180740Sdes 634180740Sdes print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); 635180740Sdes 636180740Sdes if ((x=X509_new()) == NULL) goto end; 637180740Sdes 638180740Sdes if (sno == NULL) 639262566Sdes { 640262566Sdes sno = ASN1_INTEGER_new(); 641262566Sdes if (!sno || !rand_serial(NULL, sno)) 642180740Sdes goto end; 643180740Sdes if (!X509_set_serialNumber(x, sno)) 644180740Sdes goto end; 645180740Sdes ASN1_INTEGER_free(sno); 646180740Sdes sno = NULL; 647180740Sdes } 648180740Sdes else if (!X509_set_serialNumber(x, sno)) 649180740Sdes goto end; 650180740Sdes 651197679Sdes if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; 652197679Sdes if (!X509_set_subject_name(x,req->req_info->subject)) goto end; 653197679Sdes 654221420Sdes X509_gmtime_adj(X509_get_notBefore(x),0); 655221420Sdes X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL); 656221420Sdes 657255767Sdes pkey = X509_REQ_get_pubkey(req); 658255767Sdes X509_set_pubkey(x,pkey); 659255767Sdes EVP_PKEY_free(pkey); 660255767Sdes } 661255767Sdes else 662255767Sdes x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); 663255767Sdes 664255767Sdes if (x == NULL) goto end; 665255767Sdes if (CA_flag) 666180740Sdes { 667180740Sdes xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); 668180740Sdes if (xca == NULL) goto end; 669240075Sdes } 670240075Sdes 671240075Sdes if (!noout || text || next_serial) 672221420Sdes { 673221420Sdes OBJ_create("2.99999.3", 674221420Sdes "SET.ex3","SET x509v3 extension 3"); 675180740Sdes 676180740Sdes out=BIO_new(BIO_s_file()); 677180740Sdes if (out == NULL) 678180740Sdes { 679180740Sdes ERR_print_errors(bio_err); 680180740Sdes goto end; 681180740Sdes } 682180740Sdes if (outfile == NULL) 683180740Sdes { 684180740Sdes BIO_set_fp(out,stdout,BIO_NOCLOSE); 685180740Sdes#ifdef OPENSSL_SYS_VMS 686180740Sdes { 687180746Sdes BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 688180746Sdes out = BIO_push(tmpbio, out); 689180746Sdes } 690207319Sdes#endif 691207319Sdes } 692207319Sdes else 693180740Sdes { 694180740Sdes if (BIO_write_filename(out,outfile) <= 0) 695180740Sdes { 696180740Sdes perror(outfile); 697180740Sdes goto end; 698180740Sdes } 699180740Sdes } 700180740Sdes } 701180740Sdes 702180740Sdes if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); 703180740Sdes 704180740Sdes if (clrtrust) X509_trust_clear(x); 705180740Sdes if (clrreject) X509_reject_clear(x); 706180740Sdes 707180740Sdes if (trust) 708180740Sdes { 709180740Sdes for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) 710180740Sdes { 711180740Sdes objtmp = sk_ASN1_OBJECT_value(trust, i); 712180740Sdes X509_add1_trust_object(x, objtmp); 713180740Sdes } 714240075Sdes } 715240075Sdes 716240075Sdes if (reject) 717240075Sdes { 718240075Sdes for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) 719240075Sdes { 720180740Sdes objtmp = sk_ASN1_OBJECT_value(reject, i); 721180740Sdes X509_add1_reject_object(x, objtmp); 722180740Sdes } 723240075Sdes } 724240075Sdes 725240075Sdes if (num) 726255767Sdes { 727255767Sdes for (i=1; i<=num; i++) 728255767Sdes { 729240075Sdes if (issuer == i) 730180740Sdes { 731180740Sdes print_name(STDout, "issuer= ", 732180740Sdes X509_get_issuer_name(x), nmflag); 733180740Sdes } 734180740Sdes else if (subject == i) 735180740Sdes { 736180740Sdes print_name(STDout, "subject= ", 737180740Sdes X509_get_subject_name(x), nmflag); 738180740Sdes } 739180740Sdes else if (serial == i) 740180740Sdes { 741180740Sdes BIO_printf(STDout,"serial="); 742180740Sdes i2a_ASN1_INTEGER(STDout, 743180740Sdes X509_get_serialNumber(x)); 744180740Sdes BIO_printf(STDout,"\n"); 745180740Sdes } 746180740Sdes else if (next_serial == i) 747180740Sdes { 748180740Sdes BIGNUM *bnser; 749180740Sdes ASN1_INTEGER *ser; 750180740Sdes ser = X509_get_serialNumber(x); 751180740Sdes bnser = ASN1_INTEGER_to_BN(ser, NULL); 752180740Sdes if (!bnser) 753180740Sdes goto end; 754180740Sdes if (!BN_add_word(bnser, 1)) 755180740Sdes goto end; 756255767Sdes ser = BN_to_ASN1_INTEGER(bnser, NULL); 757255767Sdes if (!ser) 758255767Sdes goto end; 759180740Sdes BN_free(bnser); 760180740Sdes i2a_ASN1_INTEGER(out, ser); 761180740Sdes ASN1_INTEGER_free(ser); 762180740Sdes BIO_puts(out, "\n"); 763180740Sdes } 764180740Sdes else if ((email == i) || (ocsp_uri == i)) 765180740Sdes { 766180740Sdes int j; 767180740Sdes STACK_OF(OPENSSL_STRING) *emlst; 768180740Sdes if (email == i) 769180740Sdes emlst = X509_get1_email(x); 770180740Sdes else 771180740Sdes emlst = X509_get1_ocsp(x); 772180740Sdes for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) 773180740Sdes BIO_printf(STDout, "%s\n", 774180740Sdes sk_OPENSSL_STRING_value(emlst, j)); 775180740Sdes X509_email_free(emlst); 776180740Sdes } 777180740Sdes else if (aliasout == i) 778180740Sdes { 779180740Sdes unsigned char *alstr; 780180740Sdes alstr = X509_alias_get0(x, NULL); 781180740Sdes if (alstr) BIO_printf(STDout,"%s\n", alstr); 782180740Sdes else BIO_puts(STDout,"<No Alias>\n"); 783180740Sdes } 784180740Sdes else if (subject_hash == i) 785180740Sdes { 786180740Sdes BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); 787180740Sdes } 788180740Sdes#ifndef OPENSSL_NO_MD5 789180740Sdes else if (subject_hash_old == i) 790180740Sdes { 791180740Sdes BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x)); 792180740Sdes } 793180740Sdes#endif 794180740Sdes else if (issuer_hash == i) 795180740Sdes { 796180740Sdes BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x)); 797180740Sdes } 798180740Sdes#ifndef OPENSSL_NO_MD5 799180740Sdes else if (issuer_hash_old == i) 800180740Sdes { 801180740Sdes BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x)); 802180740Sdes } 803180740Sdes#endif 804180740Sdes else if (pprint == i) 805180740Sdes { 806180740Sdes X509_PURPOSE *ptmp; 807180740Sdes int j; 808180740Sdes BIO_printf(STDout, "Certificate purposes:\n"); 809180740Sdes for (j = 0; j < X509_PURPOSE_get_count(); j++) 810180740Sdes { 811180740Sdes ptmp = X509_PURPOSE_get0(j); 812180740Sdes purpose_print(STDout, x, ptmp); 813180740Sdes } 814180740Sdes } 815180740Sdes else 816180740Sdes if (modulus == i) 817180740Sdes { 818180740Sdes EVP_PKEY *pkey; 819180740Sdes 820180740Sdes pkey=X509_get_pubkey(x); 821180740Sdes if (pkey == NULL) 822180740Sdes { 823180740Sdes BIO_printf(bio_err,"Modulus=unavailable\n"); 824180740Sdes ERR_print_errors(bio_err); 825180740Sdes goto end; 826180740Sdes } 827180740Sdes BIO_printf(STDout,"Modulus="); 828180740Sdes#ifndef OPENSSL_NO_RSA 829180740Sdes if (pkey->type == EVP_PKEY_RSA) 830180740Sdes BN_print(STDout,pkey->pkey.rsa->n); 831180740Sdes else 832180740Sdes#endif 833180740Sdes#ifndef OPENSSL_NO_DSA 834180740Sdes if (pkey->type == EVP_PKEY_DSA) 835180740Sdes BN_print(STDout,pkey->pkey.dsa->pub_key); 836180740Sdes else 837180740Sdes#endif 838180740Sdes BIO_printf(STDout,"Wrong Algorithm type"); 839180740Sdes BIO_printf(STDout,"\n"); 840180740Sdes EVP_PKEY_free(pkey); 841180744Sdes } 842180744Sdes else 843180744Sdes if (pubkey == i) 844180744Sdes { 845180744Sdes EVP_PKEY *pkey; 846180744Sdes 847180740Sdes pkey=X509_get_pubkey(x); 848180740Sdes if (pkey == NULL) 849180740Sdes { 850180740Sdes BIO_printf(bio_err,"Error getting public key\n"); 851180740Sdes ERR_print_errors(bio_err); 852180740Sdes goto end; 853180740Sdes } 854180740Sdes PEM_write_bio_PUBKEY(STDout, pkey); 855180740Sdes EVP_PKEY_free(pkey); 856180740Sdes } 857180740Sdes else 858180740Sdes if (C == i) 859180740Sdes { 860180740Sdes unsigned char *d; 861180740Sdes char *m; 862180740Sdes int y,z; 863180740Sdes 864180740Sdes X509_NAME_oneline(X509_get_subject_name(x), 865180740Sdes buf,sizeof buf); 866180740Sdes BIO_printf(STDout,"/* subject:%s */\n",buf); 867180740Sdes m=X509_NAME_oneline( 868180740Sdes X509_get_issuer_name(x),buf, 869180740Sdes sizeof buf); 870180740Sdes BIO_printf(STDout,"/* issuer :%s */\n",buf); 871180740Sdes 872180740Sdes z=i2d_X509(x,NULL); 873180740Sdes m=OPENSSL_malloc(z); 874180740Sdes 875180740Sdes d=(unsigned char *)m; 876180740Sdes z=i2d_X509_NAME(X509_get_subject_name(x),&d); 877226046Sdes BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z); 878226046Sdes d=(unsigned char *)m; 879226046Sdes for (y=0; y<z; y++) 880180740Sdes { 881180740Sdes BIO_printf(STDout,"0x%02X,",d[y]); 882180740Sdes if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n"); 883180740Sdes } 884180740Sdes if (y%16 != 0) BIO_printf(STDout,"\n"); 885180740Sdes BIO_printf(STDout,"};\n"); 886221420Sdes 887221420Sdes z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d); 888221420Sdes BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z); 889221420Sdes d=(unsigned char *)m; 890221420Sdes for (y=0; y<z; y++) 891221420Sdes { 892226046Sdes BIO_printf(STDout,"0x%02X,",d[y]); 893226046Sdes if ((y & 0x0f) == 0x0f) 894226046Sdes BIO_printf(STDout,"\n"); 895226046Sdes } 896226046Sdes if (y%16 != 0) BIO_printf(STDout,"\n"); 897226046Sdes BIO_printf(STDout,"};\n"); 898180740Sdes 899180740Sdes z=i2d_X509(x,&d); 900180740Sdes BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z); 901255767Sdes d=(unsigned char *)m; 902255767Sdes for (y=0; y<z; y++) 903255767Sdes { 904180740Sdes BIO_printf(STDout,"0x%02X,",d[y]); 905180740Sdes if ((y & 0x0f) == 0x0f) 906180740Sdes BIO_printf(STDout,"\n"); 907180740Sdes } 908180740Sdes if (y%16 != 0) BIO_printf(STDout,"\n"); 909180740Sdes BIO_printf(STDout,"};\n"); 910180740Sdes 911180740Sdes OPENSSL_free(m); 912180740Sdes } 913180740Sdes else if (text == i) 914180740Sdes { 915180740Sdes X509_print_ex(STDout,x,nmflag, certflag); 916180740Sdes } 917180740Sdes else if (startdate == i) 918180740Sdes { 919180740Sdes BIO_puts(STDout,"notBefore="); 920180740Sdes ASN1_TIME_print(STDout,X509_get_notBefore(x)); 921180740Sdes BIO_puts(STDout,"\n"); 922180740Sdes } 923180740Sdes else if (enddate == i) 924180740Sdes { 925180740Sdes BIO_puts(STDout,"notAfter="); 926180740Sdes ASN1_TIME_print(STDout,X509_get_notAfter(x)); 927180740Sdes BIO_puts(STDout,"\n"); 928204917Sdes } 929204917Sdes else if (fingerprint == i) 930204917Sdes { 931180740Sdes int j; 932180740Sdes unsigned int n; 933180740Sdes unsigned char md[EVP_MAX_MD_SIZE]; 934240075Sdes const EVP_MD *fdig = digest; 935240075Sdes 936240075Sdes if (!fdig) 937180740Sdes fdig = EVP_sha1(); 938180740Sdes 939180740Sdes if (!X509_digest(x,fdig,md,&n)) 940180740Sdes { 941180740Sdes BIO_printf(bio_err,"out of memory\n"); 942180740Sdes goto end; 943204917Sdes } 944204917Sdes BIO_printf(STDout,"%s Fingerprint=", 945204917Sdes OBJ_nid2sn(EVP_MD_type(fdig))); 946180740Sdes for (j=0; j<(int)n; j++) 947180740Sdes { 948180740Sdes BIO_printf(STDout,"%02X%c",md[j], 949180740Sdes (j+1 == (int)n) 950180740Sdes ?'\n':':'); 951180740Sdes } 952180740Sdes } 953180740Sdes 954180740Sdes /* should be in the library */ 955180740Sdes else if ((sign_flag == i) && (x509req == 0)) 956180740Sdes { 957180740Sdes BIO_printf(bio_err,"Getting Private key\n"); 958180740Sdes if (Upkey == NULL) 959180740Sdes { 960180740Sdes Upkey=load_key(bio_err, 961180740Sdes keyfile, keyformat, 0, 962180740Sdes passin, e, "Private key"); 963180740Sdes if (Upkey == NULL) goto end; 964180740Sdes } 965180740Sdes 966180740Sdes assert(need_rand); 967180740Sdes if (!sign(x,Upkey,days,clrext,digest, 968180740Sdes extconf, extsect)) goto end; 969180740Sdes } 970180740Sdes else if (CA_flag == i) 971180740Sdes { 972180740Sdes BIO_printf(bio_err,"Getting CA Private Key\n"); 973207319Sdes if (CAkeyfile != NULL) 974207319Sdes { 975207319Sdes CApkey=load_key(bio_err, 976180740Sdes CAkeyfile, CAkeyformat, 977180740Sdes 0, passin, e, 978180740Sdes "CA Private Key"); 979180740Sdes if (CApkey == NULL) goto end; 980180740Sdes } 981180740Sdes 982180744Sdes assert(need_rand); 983180744Sdes if (!x509_certify(ctx,CAfile,digest,x,xca, 984180744Sdes CApkey, sigopts, 985180740Sdes CAserial,CA_createserial,days, clrext, 986180740Sdes extconf, extsect, sno)) 987180740Sdes goto end; 988180740Sdes } 989180740Sdes else if (x509req == i) 990180740Sdes { 991180740Sdes EVP_PKEY *pk; 992180740Sdes 993180740Sdes BIO_printf(bio_err,"Getting request Private Key\n"); 994180740Sdes if (keyfile == NULL) 995180740Sdes { 996180740Sdes BIO_printf(bio_err,"no request key file specified\n"); 997180740Sdes goto end; 998180740Sdes } 999180740Sdes else 1000180740Sdes { 1001180740Sdes pk=load_key(bio_err, 1002180740Sdes keyfile, keyformat, 0, 1003180740Sdes passin, e, "request key"); 1004180740Sdes if (pk == NULL) goto end; 1005180740Sdes } 1006180740Sdes 1007180740Sdes BIO_printf(bio_err,"Generating certificate request\n"); 1008180740Sdes 1009180740Sdes rq=X509_to_X509_REQ(x,pk,digest); 1010180740Sdes EVP_PKEY_free(pk); 1011180740Sdes if (rq == NULL) 1012180740Sdes { 1013180740Sdes ERR_print_errors(bio_err); 1014180740Sdes goto end; 1015180740Sdes } 1016180740Sdes if (!noout) 1017180740Sdes { 1018180740Sdes X509_REQ_print(out,rq); 1019180740Sdes PEM_write_bio_X509_REQ(out,rq); 1020180740Sdes } 1021180750Sdes noout=1; 1022180750Sdes } 1023180750Sdes else if (ocspid == i) 1024180750Sdes { 1025180750Sdes X509_ocspid_print(out, x); 1026180750Sdes } 1027180740Sdes } 1028180740Sdes } 1029180740Sdes 1030180740Sdes if (checkend) 1031180740Sdes { 1032180740Sdes time_t tcheck=time(NULL) + checkoffset; 1033180740Sdes 1034180740Sdes if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) 1035180740Sdes { 1036180740Sdes BIO_printf(out,"Certificate will expire\n"); 1037180740Sdes ret=1; 1038180740Sdes } 1039180740Sdes else 1040180740Sdes { 1041180740Sdes BIO_printf(out,"Certificate will not expire\n"); 1042180740Sdes ret=0; 1043180740Sdes } 1044180740Sdes goto end; 1045180740Sdes } 1046180740Sdes 1047180740Sdes if (noout) 1048180740Sdes { 1049180740Sdes ret=0; 1050180740Sdes goto end; 1051180740Sdes } 1052180740Sdes 1053180740Sdes if (outformat == FORMAT_ASN1) 1054180740Sdes i=i2d_X509_bio(out,x); 1055180740Sdes else if (outformat == FORMAT_PEM) 1056180740Sdes { 1057180740Sdes if (trustout) i=PEM_write_bio_X509_AUX(out,x); 1058180740Sdes else i=PEM_write_bio_X509(out,x); 1059180740Sdes } 1060180740Sdes else if (outformat == FORMAT_NETSCAPE) 1061180740Sdes { 1062180740Sdes NETSCAPE_X509 nx; 1063240075Sdes ASN1_OCTET_STRING hdr; 1064240075Sdes 1065240075Sdes hdr.data=(unsigned char *)NETSCAPE_CERT_HDR; 1066180740Sdes hdr.length=strlen(NETSCAPE_CERT_HDR); 1067180740Sdes nx.header= &hdr; 1068180740Sdes nx.cert=x; 1069215116Sdes 1070215116Sdes i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx); 1071215116Sdes } 1072180740Sdes else { 1073180740Sdes BIO_printf(bio_err,"bad output format specified for outfile\n"); 1074180740Sdes goto end; 1075180740Sdes } 1076180740Sdes if (!i) 1077180740Sdes { 1078180740Sdes BIO_printf(bio_err,"unable to write certificate\n"); 1079180740Sdes ERR_print_errors(bio_err); 1080180740Sdes goto end; 1081180740Sdes } 1082180740Sdes ret=0; 1083180740Sdesend: 1084248619Sdes if (need_rand) 1085248619Sdes app_RAND_write_file(NULL, bio_err); 1086248619Sdes OBJ_cleanup(); 1087180740Sdes NCONF_free(extconf); 1088180740Sdes BIO_free_all(out); 1089180740Sdes BIO_free_all(STDout); 1090180740Sdes X509_STORE_free(ctx); 1091180740Sdes X509_REQ_free(req); 1092180740Sdes X509_free(x); 1093255767Sdes X509_free(xca); 1094255767Sdes EVP_PKEY_free(Upkey); 1095255767Sdes EVP_PKEY_free(CApkey); 1096255767Sdes if (sigopts) 1097255767Sdes sk_OPENSSL_STRING_free(sigopts); 1098255767Sdes X509_REQ_free(rq); 1099255767Sdes ASN1_INTEGER_free(sno); 1100255767Sdes sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); 1101255767Sdes sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); 1102255767Sdes if (passin) OPENSSL_free(passin); 1103255767Sdes apps_shutdown(); 1104255767Sdes OPENSSL_EXIT(ret); 1105180740Sdes } 1106180740Sdes 1107180740Sdesstatic ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create) 1108226046Sdes { 1109192595Sdes char *buf = NULL, *p; 1110192595Sdes ASN1_INTEGER *bs = NULL; 1111180740Sdes BIGNUM *serial = NULL; 1112180740Sdes size_t len; 1113180740Sdes 1114226046Sdes len = ((serialfile == NULL) 1115180740Sdes ?(strlen(CAfile)+strlen(POSTFIX)+1) 1116180740Sdes :(strlen(serialfile)))+1; 1117180740Sdes buf=OPENSSL_malloc(len); 1118180740Sdes if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; } 1119180740Sdes if (serialfile == NULL) 1120180740Sdes { 1121180740Sdes BUF_strlcpy(buf,CAfile,len); 1122180740Sdes for (p=buf; *p; p++) 1123180744Sdes if (*p == '.') 1124180744Sdes { 1125180744Sdes *p='\0'; 1126180740Sdes break; 1127180740Sdes } 1128180740Sdes BUF_strlcat(buf,POSTFIX,len); 1129180740Sdes } 1130180740Sdes else 1131180740Sdes BUF_strlcpy(buf,serialfile,len); 1132180740Sdes 1133180740Sdes serial = load_serial(buf, create, NULL); 1134180740Sdes if (serial == NULL) goto end; 1135180740Sdes 1136180740Sdes if (!BN_add_word(serial,1)) 1137180740Sdes { BIO_printf(bio_err,"add_word failure\n"); goto end; } 1138180740Sdes 1139180740Sdes if (!save_serial(buf, NULL, serial, &bs)) goto end; 1140180740Sdes 1141262566Sdes end: 1142262566Sdes if (buf) OPENSSL_free(buf); 1143262566Sdes BN_free(serial); 1144180740Sdes return bs; 1145180740Sdes } 1146180740Sdes 1147180740Sdesstatic int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 1148180740Sdes X509 *x, X509 *xca, EVP_PKEY *pkey, 1149180740Sdes STACK_OF(OPENSSL_STRING) *sigopts, 1150180740Sdes char *serialfile, int create, 1151180740Sdes int days, int clrext, CONF *conf, char *section, 1152180740Sdes ASN1_INTEGER *sno) 1153180740Sdes { 1154180740Sdes int ret=0; 1155180740Sdes ASN1_INTEGER *bs=NULL; 1156180750Sdes X509_STORE_CTX xsc; 1157180750Sdes EVP_PKEY *upkey; 1158180750Sdes 1159180740Sdes upkey = X509_get_pubkey(xca); 1160180740Sdes EVP_PKEY_copy_parameters(upkey,pkey); 1161180740Sdes EVP_PKEY_free(upkey); 1162180740Sdes 1163180740Sdes if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL)) 1164180740Sdes { 1165180746Sdes BIO_printf(bio_err,"Error initialising X509 store\n"); 1166180746Sdes goto end; 1167180746Sdes } 1168180740Sdes if (sno) bs = sno; 1169180740Sdes else if (!(bs = x509_load_serial(CAfile, serialfile, create))) 1170180740Sdes goto end; 1171180740Sdes 1172180740Sdes/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/ 1173180740Sdes 1174180740Sdes /* NOTE: this certificate can/should be self signed, unless it was 1175180740Sdes * a certificate request in which case it is not. */ 1176180740Sdes X509_STORE_CTX_set_cert(&xsc,x); 1177180740Sdes X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); 1178180740Sdes if (!reqfile && X509_verify_cert(&xsc) <= 0) 1179180740Sdes goto end; 1180180750Sdes 1181180750Sdes if (!X509_check_private_key(xca,pkey)) 1182180750Sdes { 1183180740Sdes BIO_printf(bio_err,"CA certificate and CA private key do not match\n"); 1184180740Sdes goto end; 1185180740Sdes } 1186180740Sdes 1187180740Sdes if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end; 1188180740Sdes if (!X509_set_serialNumber(x,bs)) goto end; 1189180740Sdes 1190180740Sdes if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL) 1191180740Sdes goto end; 1192180740Sdes 1193180740Sdes /* hardwired expired */ 1194180740Sdes if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL) 1195180740Sdes goto end; 1196180740Sdes 1197180740Sdes if (clrext) 1198180740Sdes { 1199180740Sdes while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0); 1200180740Sdes } 1201180740Sdes 1202180740Sdes if (conf) 1203180740Sdes { 1204180740Sdes X509V3_CTX ctx2; 1205180740Sdes X509_set_version(x,2); /* version 3 certificate */ 1206180740Sdes X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); 1207180740Sdes X509V3_set_nconf(&ctx2, conf); 1208180740Sdes if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end; 1209180740Sdes } 1210180740Sdes 1211180740Sdes if (!do_X509_sign(bio_err, x, pkey, digest, sigopts)) 1212180740Sdes goto end; 1213180740Sdes ret=1; 1214180740Sdesend: 1215180740Sdes X509_STORE_CTX_cleanup(&xsc); 1216180740Sdes if (!ret) 1217180740Sdes ERR_print_errors(bio_err); 1218180740Sdes if (!sno) ASN1_INTEGER_free(bs); 1219180740Sdes return ret; 1220180740Sdes } 1221180740Sdes 1222180740Sdesstatic int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx) 1223180740Sdes { 1224180740Sdes int err; 1225180740Sdes X509 *err_cert; 1226180740Sdes 1227180740Sdes /* it is ok to use a self signed certificate 1228180740Sdes * This case will catch both the initial ok == 0 and the 1229180740Sdes * final ok == 1 calls to this function */ 1230180740Sdes err=X509_STORE_CTX_get_error(ctx); 1231221420Sdes if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) 1232221420Sdes return 1; 1233221420Sdes 1234180740Sdes /* BAD we should have gotten an error. Normally if everything 1235180740Sdes * worked X509_STORE_CTX_get_error(ctx) will still be set to 1236180740Sdes * DEPTH_ZERO_SELF_.... */ 1237180740Sdes if (ok) 1238180740Sdes { 1239180740Sdes BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n"); 1240180740Sdes return 0; 1241180740Sdes } 1242180740Sdes else 1243180740Sdes { 1244180740Sdes err_cert=X509_STORE_CTX_get_current_cert(ctx); 1245180740Sdes print_name(bio_err, NULL, X509_get_subject_name(err_cert),0); 1246180740Sdes BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n", 1247180740Sdes err,X509_STORE_CTX_get_error_depth(ctx), 1248180740Sdes X509_verify_cert_error_string(err)); 1249180740Sdes return 1; 1250180740Sdes } 1251180740Sdes } 1252180740Sdes 1253180740Sdes/* self sign */ 1254180740Sdesstatic int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 1255180744Sdes CONF *conf, char *section) 1256180744Sdes { 1257180744Sdes 1258262566Sdes EVP_PKEY *pktmp; 1259262566Sdes 1260262566Sdes pktmp = X509_get_pubkey(x); 1261180740Sdes EVP_PKEY_copy_parameters(pktmp,pkey); 1262180740Sdes EVP_PKEY_save_parameters(pktmp,1); 1263180740Sdes EVP_PKEY_free(pktmp); 1264180740Sdes 1265180740Sdes if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err; 1266180740Sdes if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err; 1267180740Sdes 1268180740Sdes /* Lets just make it 12:00am GMT, Jan 1 1970 */ 1269180740Sdes /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */ 1270180740Sdes /* 28 days to be certified */ 1271180740Sdes 1272180740Sdes if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL) 1273180740Sdes goto err; 1274180740Sdes 1275180740Sdes if (!X509_set_pubkey(x,pkey)) goto err; 1276180740Sdes if (clrext) 1277180740Sdes { 1278180740Sdes while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0); 1279180740Sdes } 1280180740Sdes if (conf) 1281180740Sdes { 1282204917Sdes X509V3_CTX ctx; 1283204917Sdes X509_set_version(x,2); /* version 3 certificate */ 1284204917Sdes X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); 1285248619Sdes X509V3_set_nconf(&ctx, conf); 1286248619Sdes if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err; 1287248619Sdes } 1288180740Sdes if (!X509_sign(x,pkey,digest)) goto err; 1289180740Sdes return 1; 1290180740Sdeserr: 1291180740Sdes ERR_print_errors(bio_err); 1292180740Sdes return 0; 1293180740Sdes } 1294180740Sdes 1295180740Sdesstatic int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) 1296180740Sdes{ 1297180740Sdes int id, i, idret; 1298180740Sdes char *pname; 1299180740Sdes id = X509_PURPOSE_get_id(pt); 1300180740Sdes pname = X509_PURPOSE_get0_name(pt); 1301180740Sdes for (i = 0; i < 2; i++) 1302180740Sdes { 1303180740Sdes idret = X509_check_purpose(cert, id, i); 1304180740Sdes BIO_printf(bio, "%s%s : ", pname, i ? " CA" : ""); 1305180740Sdes if (idret == 1) BIO_printf(bio, "Yes\n"); 1306180740Sdes else if (idret == 0) BIO_printf(bio, "No\n"); 1307180740Sdes else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret); 1308180740Sdes } 1309180740Sdes return 1; 1310180740Sdes} 1311180740Sdes