155714Skris/* apps/x509.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5959191Skris#include <assert.h> 6055714Skris#include <stdio.h> 6155714Skris#include <stdlib.h> 6255714Skris#include <string.h> 63109998Smarkm#ifdef OPENSSL_NO_STDIO 64296465Sdelphij# define APPS_WIN16 6555714Skris#endif 6655714Skris#include "apps.h" 6755714Skris#include <openssl/bio.h> 6855714Skris#include <openssl/asn1.h> 6955714Skris#include <openssl/err.h> 7055714Skris#include <openssl/bn.h> 7155714Skris#include <openssl/evp.h> 7255714Skris#include <openssl/x509.h> 7355714Skris#include <openssl/x509v3.h> 7455714Skris#include <openssl/objects.h> 7555714Skris#include <openssl/pem.h> 76160814Ssimon#ifndef OPENSSL_NO_RSA 77296465Sdelphij# include <openssl/rsa.h> 78160814Ssimon#endif 79160814Ssimon#ifndef OPENSSL_NO_DSA 80296465Sdelphij# include <openssl/dsa.h> 81160814Ssimon#endif 8255714Skris 8355714Skris#undef PROG 8455714Skris#define PROG x509_main 8555714Skris 8655714Skris#undef POSTFIX 87296465Sdelphij#define POSTFIX ".srl" 88296465Sdelphij#define DEF_DAYS 30 8955714Skris 90296465Sdelphijstatic const char *x509_usage[] = { 91296465Sdelphij "usage: x509 args\n", 92296465Sdelphij " -inform arg - input format - default PEM (one of DER, NET or PEM)\n", 93296465Sdelphij " -outform arg - output format - default PEM (one of DER, NET or PEM)\n", 94296465Sdelphij " -keyform arg - private key format - default PEM\n", 95296465Sdelphij " -CAform arg - CA format - default PEM\n", 96296465Sdelphij " -CAkeyform arg - CA key format - default PEM\n", 97296465Sdelphij " -in arg - input file - default stdin\n", 98296465Sdelphij " -out arg - output file - default stdout\n", 99296465Sdelphij " -passin arg - private key password source\n", 100296465Sdelphij " -serial - print serial number value\n", 101296465Sdelphij " -subject_hash - print subject hash value\n", 102296465Sdelphij " -issuer_hash - print issuer hash value\n", 103296465Sdelphij " -hash - synonym for -subject_hash\n", 104296465Sdelphij " -subject - print subject DN\n", 105296465Sdelphij " -issuer - print issuer DN\n", 106296465Sdelphij " -email - print email address(es)\n", 107296465Sdelphij " -startdate - notBefore field\n", 108296465Sdelphij " -enddate - notAfter field\n", 109296465Sdelphij " -purpose - print out certificate purposes\n", 110296465Sdelphij " -dates - both Before and After dates\n", 111296465Sdelphij " -modulus - print the RSA key modulus\n", 112296465Sdelphij " -pubkey - output the public key\n", 113296465Sdelphij " -fingerprint - print the certificate fingerprint\n", 114296465Sdelphij " -alias - output certificate alias\n", 115296465Sdelphij " -noout - no certificate output\n", 116296465Sdelphij " -ocspid - print OCSP hash values for the subject name and public key\n", 117296465Sdelphij " -ocsp_uri - print OCSP Responder URL(s)\n", 118296465Sdelphij " -trustout - output a \"trusted\" certificate\n", 119296465Sdelphij " -clrtrust - clear all trusted purposes\n", 120296465Sdelphij " -clrreject - clear all rejected purposes\n", 121296465Sdelphij " -addtrust arg - trust certificate for a given purpose\n", 122296465Sdelphij " -addreject arg - reject certificate for a given purpose\n", 123296465Sdelphij " -setalias arg - set certificate alias\n", 124296465Sdelphij " -days arg - How long till expiry of a signed certificate - def 30 days\n", 125296465Sdelphij " -checkend arg - check whether the cert expires in the next arg seconds\n", 126296465Sdelphij " exit 1 if so, 0 if not\n", 127296465Sdelphij " -signkey arg - self sign cert with arg\n", 128296465Sdelphij " -x509toreq - output a certification request object\n", 129296465Sdelphij " -req - input is a certificate request, sign and output.\n", 130296465Sdelphij " -CA arg - set the CA certificate, must be PEM format.\n", 131296465Sdelphij " -CAkey arg - set the CA key, must be PEM format\n", 132296465Sdelphij " missing, it is assumed to be in the CA file.\n", 133296465Sdelphij " -CAcreateserial - create serial number file if it does not exist\n", 134296465Sdelphij " -CAserial arg - serial file\n", 135296465Sdelphij " -set_serial - serial number to use\n", 136296465Sdelphij " -text - print the certificate in text form\n", 137296465Sdelphij " -C - print out C code forms\n", 138296465Sdelphij " -md2/-md5/-sha1/-mdc2 - digest to use\n", 139296465Sdelphij " -extfile - configuration file with X509V3 extensions to add\n", 140296465Sdelphij " -extensions - section from config file with X509V3 extensions to add\n", 141296465Sdelphij " -clrext - delete extensions before signing and input certificate\n", 142296465Sdelphij " -nameopt arg - various certificate name options\n", 143111147Snectar#ifndef OPENSSL_NO_ENGINE 144296465Sdelphij " -engine e - use engine e, possibly a hardware device.\n", 145111147Snectar#endif 146296465Sdelphij " -certopt arg - various certificate text options\n", 147296465Sdelphij NULL 14855714Skris}; 14955714Skris 15055714Skrisstatic int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx); 151296465Sdelphijstatic int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, 152296465Sdelphij const EVP_MD *digest, CONF *conf, char *section); 153296465Sdelphijstatic int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 154296465Sdelphij X509 *x, X509 *xca, EVP_PKEY *pkey, char *serial, 155296465Sdelphij int create, int days, int clrext, CONF *conf, 156296465Sdelphij char *section, ASN1_INTEGER *sno); 15759191Skrisstatic int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); 158296465Sdelphijstatic int reqfile = 0; 15955714Skris 16059191Skrisint MAIN(int, char **); 16159191Skris 16255714Skrisint MAIN(int argc, char **argv) 163296465Sdelphij{ 164296465Sdelphij ENGINE *e = NULL; 165296465Sdelphij int ret = 1; 166296465Sdelphij X509_REQ *req = NULL; 167296465Sdelphij X509 *x = NULL, *xca = NULL; 168296465Sdelphij ASN1_OBJECT *objtmp; 169296465Sdelphij EVP_PKEY *Upkey = NULL, *CApkey = NULL; 170296465Sdelphij ASN1_INTEGER *sno = NULL; 171296465Sdelphij int i, num, badops = 0; 172296465Sdelphij BIO *out = NULL; 173296465Sdelphij BIO *STDout = NULL; 174296465Sdelphij STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; 175296465Sdelphij int informat, outformat, keyformat, CAformat, CAkeyformat; 176296465Sdelphij char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; 177296465Sdelphij char *CAkeyfile = NULL, *CAserial = NULL; 178296465Sdelphij char *alias = NULL; 179296465Sdelphij int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 180296465Sdelphij 0, enddate = 0; 181296465Sdelphij int next_serial = 0; 182296465Sdelphij int subject_hash = 0, issuer_hash = 0, ocspid = 0; 183296465Sdelphij int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; 184296465Sdelphij int ocsp_uri = 0; 185296465Sdelphij int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0; 186296465Sdelphij int C = 0; 187296465Sdelphij int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0; 188296465Sdelphij int pprint = 0; 189296465Sdelphij const char **pp; 190296465Sdelphij X509_STORE *ctx = NULL; 191296465Sdelphij X509_REQ *rq = NULL; 192296465Sdelphij int fingerprint = 0; 193296465Sdelphij char buf[256]; 194296465Sdelphij const EVP_MD *md_alg, *digest = EVP_sha1(); 195296465Sdelphij CONF *extconf = NULL; 196296465Sdelphij char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; 197296465Sdelphij int need_rand = 0; 198296465Sdelphij int checkend = 0, checkoffset = 0; 199296465Sdelphij unsigned long nmflag = 0, certflag = 0; 200111147Snectar#ifndef OPENSSL_NO_ENGINE 201296465Sdelphij char *engine = NULL; 202111147Snectar#endif 20355714Skris 204296465Sdelphij reqfile = 0; 20555714Skris 206296465Sdelphij apps_startup(); 20755714Skris 208296465Sdelphij if (bio_err == NULL) 209296465Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 210109998Smarkm 211296465Sdelphij if (!load_config(bio_err, NULL)) 212296465Sdelphij goto end; 213296465Sdelphij STDout = BIO_new_fp(stdout, BIO_NOCLOSE); 214109998Smarkm#ifdef OPENSSL_SYS_VMS 215296465Sdelphij { 216296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 217296465Sdelphij STDout = BIO_push(tmpbio, STDout); 218296465Sdelphij } 21968651Skris#endif 22055714Skris 221296465Sdelphij informat = FORMAT_PEM; 222296465Sdelphij outformat = FORMAT_PEM; 223296465Sdelphij keyformat = FORMAT_PEM; 224296465Sdelphij CAformat = FORMAT_PEM; 225296465Sdelphij CAkeyformat = FORMAT_PEM; 22655714Skris 227296465Sdelphij ctx = X509_STORE_new(); 228296465Sdelphij if (ctx == NULL) 229296465Sdelphij goto end; 230296465Sdelphij X509_STORE_set_verify_cb_func(ctx, callb); 23155714Skris 232296465Sdelphij argc--; 233296465Sdelphij argv++; 234296465Sdelphij num = 0; 235296465Sdelphij while (argc >= 1) { 236296465Sdelphij if (strcmp(*argv, "-inform") == 0) { 237296465Sdelphij if (--argc < 1) 238296465Sdelphij goto bad; 239296465Sdelphij informat = str2fmt(*(++argv)); 240296465Sdelphij } else if (strcmp(*argv, "-outform") == 0) { 241296465Sdelphij if (--argc < 1) 242296465Sdelphij goto bad; 243296465Sdelphij outformat = str2fmt(*(++argv)); 244296465Sdelphij } else if (strcmp(*argv, "-keyform") == 0) { 245296465Sdelphij if (--argc < 1) 246296465Sdelphij goto bad; 247296465Sdelphij keyformat = str2fmt(*(++argv)); 248296465Sdelphij } else if (strcmp(*argv, "-req") == 0) { 249296465Sdelphij reqfile = 1; 250296465Sdelphij need_rand = 1; 251296465Sdelphij } else if (strcmp(*argv, "-CAform") == 0) { 252296465Sdelphij if (--argc < 1) 253296465Sdelphij goto bad; 254296465Sdelphij CAformat = str2fmt(*(++argv)); 255296465Sdelphij } else if (strcmp(*argv, "-CAkeyform") == 0) { 256296465Sdelphij if (--argc < 1) 257296465Sdelphij goto bad; 258296465Sdelphij CAkeyformat = str2fmt(*(++argv)); 259296465Sdelphij } else if (strcmp(*argv, "-days") == 0) { 260296465Sdelphij if (--argc < 1) 261296465Sdelphij goto bad; 262296465Sdelphij days = atoi(*(++argv)); 263296465Sdelphij if (days == 0) { 264296465Sdelphij BIO_printf(STDout, "bad number of days\n"); 265296465Sdelphij goto bad; 266296465Sdelphij } 267296465Sdelphij } else if (strcmp(*argv, "-passin") == 0) { 268296465Sdelphij if (--argc < 1) 269296465Sdelphij goto bad; 270296465Sdelphij passargin = *(++argv); 271296465Sdelphij } else if (strcmp(*argv, "-extfile") == 0) { 272296465Sdelphij if (--argc < 1) 273296465Sdelphij goto bad; 274296465Sdelphij extfile = *(++argv); 275296465Sdelphij } else if (strcmp(*argv, "-extensions") == 0) { 276296465Sdelphij if (--argc < 1) 277296465Sdelphij goto bad; 278296465Sdelphij extsect = *(++argv); 279296465Sdelphij } else if (strcmp(*argv, "-in") == 0) { 280296465Sdelphij if (--argc < 1) 281296465Sdelphij goto bad; 282296465Sdelphij infile = *(++argv); 283296465Sdelphij } else if (strcmp(*argv, "-out") == 0) { 284296465Sdelphij if (--argc < 1) 285296465Sdelphij goto bad; 286296465Sdelphij outfile = *(++argv); 287296465Sdelphij } else if (strcmp(*argv, "-signkey") == 0) { 288296465Sdelphij if (--argc < 1) 289296465Sdelphij goto bad; 290296465Sdelphij keyfile = *(++argv); 291296465Sdelphij sign_flag = ++num; 292296465Sdelphij need_rand = 1; 293296465Sdelphij } else if (strcmp(*argv, "-CA") == 0) { 294296465Sdelphij if (--argc < 1) 295296465Sdelphij goto bad; 296296465Sdelphij CAfile = *(++argv); 297296465Sdelphij CA_flag = ++num; 298296465Sdelphij need_rand = 1; 299296465Sdelphij } else if (strcmp(*argv, "-CAkey") == 0) { 300296465Sdelphij if (--argc < 1) 301296465Sdelphij goto bad; 302296465Sdelphij CAkeyfile = *(++argv); 303296465Sdelphij } else if (strcmp(*argv, "-CAserial") == 0) { 304296465Sdelphij if (--argc < 1) 305296465Sdelphij goto bad; 306296465Sdelphij CAserial = *(++argv); 307296465Sdelphij } else if (strcmp(*argv, "-set_serial") == 0) { 308296465Sdelphij if (--argc < 1) 309296465Sdelphij goto bad; 310296465Sdelphij if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) 311296465Sdelphij goto bad; 312296465Sdelphij } else if (strcmp(*argv, "-addtrust") == 0) { 313296465Sdelphij if (--argc < 1) 314296465Sdelphij goto bad; 315296465Sdelphij if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { 316296465Sdelphij BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); 317296465Sdelphij goto bad; 318296465Sdelphij } 319296465Sdelphij if (!trust) 320296465Sdelphij trust = sk_ASN1_OBJECT_new_null(); 321296465Sdelphij sk_ASN1_OBJECT_push(trust, objtmp); 322296465Sdelphij trustout = 1; 323296465Sdelphij } else if (strcmp(*argv, "-addreject") == 0) { 324296465Sdelphij if (--argc < 1) 325296465Sdelphij goto bad; 326296465Sdelphij if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { 327296465Sdelphij BIO_printf(bio_err, 328296465Sdelphij "Invalid reject object value %s\n", *argv); 329296465Sdelphij goto bad; 330296465Sdelphij } 331296465Sdelphij if (!reject) 332296465Sdelphij reject = sk_ASN1_OBJECT_new_null(); 333296465Sdelphij sk_ASN1_OBJECT_push(reject, objtmp); 334296465Sdelphij trustout = 1; 335296465Sdelphij } else if (strcmp(*argv, "-setalias") == 0) { 336296465Sdelphij if (--argc < 1) 337296465Sdelphij goto bad; 338296465Sdelphij alias = *(++argv); 339296465Sdelphij trustout = 1; 340296465Sdelphij } else if (strcmp(*argv, "-certopt") == 0) { 341296465Sdelphij if (--argc < 1) 342296465Sdelphij goto bad; 343296465Sdelphij if (!set_cert_ex(&certflag, *(++argv))) 344296465Sdelphij goto bad; 345296465Sdelphij } else if (strcmp(*argv, "-nameopt") == 0) { 346296465Sdelphij if (--argc < 1) 347296465Sdelphij goto bad; 348296465Sdelphij if (!set_name_ex(&nmflag, *(++argv))) 349296465Sdelphij goto bad; 350296465Sdelphij } 351111147Snectar#ifndef OPENSSL_NO_ENGINE 352296465Sdelphij else if (strcmp(*argv, "-engine") == 0) { 353296465Sdelphij if (--argc < 1) 354296465Sdelphij goto bad; 355296465Sdelphij engine = *(++argv); 356296465Sdelphij } 357111147Snectar#endif 358296465Sdelphij else if (strcmp(*argv, "-C") == 0) 359296465Sdelphij C = ++num; 360296465Sdelphij else if (strcmp(*argv, "-email") == 0) 361296465Sdelphij email = ++num; 362296465Sdelphij else if (strcmp(*argv, "-ocsp_uri") == 0) 363296465Sdelphij ocsp_uri = ++num; 364296465Sdelphij else if (strcmp(*argv, "-serial") == 0) 365296465Sdelphij serial = ++num; 366296465Sdelphij else if (strcmp(*argv, "-next_serial") == 0) 367296465Sdelphij next_serial = ++num; 368296465Sdelphij else if (strcmp(*argv, "-modulus") == 0) 369296465Sdelphij modulus = ++num; 370296465Sdelphij else if (strcmp(*argv, "-pubkey") == 0) 371296465Sdelphij pubkey = ++num; 372296465Sdelphij else if (strcmp(*argv, "-x509toreq") == 0) 373296465Sdelphij x509req = ++num; 374296465Sdelphij else if (strcmp(*argv, "-text") == 0) 375296465Sdelphij text = ++num; 376296465Sdelphij else if (strcmp(*argv, "-hash") == 0 377296465Sdelphij || strcmp(*argv, "-subject_hash") == 0) 378296465Sdelphij subject_hash = ++num; 379296465Sdelphij else if (strcmp(*argv, "-issuer_hash") == 0) 380296465Sdelphij issuer_hash = ++num; 381296465Sdelphij else if (strcmp(*argv, "-subject") == 0) 382296465Sdelphij subject = ++num; 383296465Sdelphij else if (strcmp(*argv, "-issuer") == 0) 384296465Sdelphij issuer = ++num; 385296465Sdelphij else if (strcmp(*argv, "-fingerprint") == 0) 386296465Sdelphij fingerprint = ++num; 387296465Sdelphij else if (strcmp(*argv, "-dates") == 0) { 388296465Sdelphij startdate = ++num; 389296465Sdelphij enddate = ++num; 390296465Sdelphij } else if (strcmp(*argv, "-purpose") == 0) 391296465Sdelphij pprint = ++num; 392296465Sdelphij else if (strcmp(*argv, "-startdate") == 0) 393296465Sdelphij startdate = ++num; 394296465Sdelphij else if (strcmp(*argv, "-enddate") == 0) 395296465Sdelphij enddate = ++num; 396296465Sdelphij else if (strcmp(*argv, "-checkend") == 0) { 397296465Sdelphij if (--argc < 1) 398296465Sdelphij goto bad; 399296465Sdelphij checkoffset = atoi(*(++argv)); 400296465Sdelphij checkend = 1; 401296465Sdelphij } else if (strcmp(*argv, "-noout") == 0) 402296465Sdelphij noout = ++num; 403296465Sdelphij else if (strcmp(*argv, "-trustout") == 0) 404296465Sdelphij trustout = 1; 405296465Sdelphij else if (strcmp(*argv, "-clrtrust") == 0) 406296465Sdelphij clrtrust = ++num; 407296465Sdelphij else if (strcmp(*argv, "-clrreject") == 0) 408296465Sdelphij clrreject = ++num; 409296465Sdelphij else if (strcmp(*argv, "-alias") == 0) 410296465Sdelphij aliasout = ++num; 411296465Sdelphij else if (strcmp(*argv, "-CAcreateserial") == 0) 412296465Sdelphij CA_createserial = ++num; 413296465Sdelphij else if (strcmp(*argv, "-clrext") == 0) 414296465Sdelphij clrext = 1; 415296465Sdelphij#if 1 /* stay backwards-compatible with 0.9.5; this 416296465Sdelphij * should go away soon */ 417296465Sdelphij else if (strcmp(*argv, "-crlext") == 0) { 418296465Sdelphij BIO_printf(bio_err, "use -clrext instead of -crlext\n"); 419296465Sdelphij clrext = 1; 420296465Sdelphij } 42159191Skris#endif 422296465Sdelphij else if (strcmp(*argv, "-ocspid") == 0) 423296465Sdelphij ocspid = ++num; 424296465Sdelphij else if ((md_alg = EVP_get_digestbyname(*argv + 1))) { 425296465Sdelphij /* ok */ 426296465Sdelphij digest = md_alg; 427296465Sdelphij } else { 428296465Sdelphij BIO_printf(bio_err, "unknown option %s\n", *argv); 429296465Sdelphij badops = 1; 430296465Sdelphij break; 431296465Sdelphij } 432296465Sdelphij argc--; 433296465Sdelphij argv++; 434296465Sdelphij } 43555714Skris 436296465Sdelphij if (badops) { 437296465Sdelphij bad: 438296465Sdelphij for (pp = x509_usage; (*pp != NULL); pp++) 439296465Sdelphij BIO_printf(bio_err, "%s", *pp); 440296465Sdelphij goto end; 441296465Sdelphij } 442111147Snectar#ifndef OPENSSL_NO_ENGINE 443296465Sdelphij e = setup_engine(bio_err, engine, 0); 444111147Snectar#endif 445109998Smarkm 446296465Sdelphij if (need_rand) 447296465Sdelphij app_RAND_load_file(NULL, bio_err, 0); 44859191Skris 449296465Sdelphij ERR_load_crypto_strings(); 45055714Skris 451296465Sdelphij if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 452296465Sdelphij BIO_printf(bio_err, "Error getting password\n"); 453296465Sdelphij goto end; 454296465Sdelphij } 45559191Skris 456296465Sdelphij if (!X509_STORE_set_default_paths(ctx)) { 457296465Sdelphij ERR_print_errors(bio_err); 458296465Sdelphij goto end; 459296465Sdelphij } 46055714Skris 461296465Sdelphij if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) { 462296465Sdelphij CAkeyfile = CAfile; 463296465Sdelphij } else if ((CA_flag) && (CAkeyfile == NULL)) { 464296465Sdelphij BIO_printf(bio_err, 465296465Sdelphij "need to specify a CAkey if using the CA command\n"); 466296465Sdelphij goto end; 467296465Sdelphij } 46855714Skris 469296465Sdelphij if (extfile) { 470296465Sdelphij long errorline = -1; 471296465Sdelphij X509V3_CTX ctx2; 472296465Sdelphij extconf = NCONF_new(NULL); 473296465Sdelphij if (!NCONF_load(extconf, extfile, &errorline)) { 474296465Sdelphij if (errorline <= 0) 475296465Sdelphij BIO_printf(bio_err, 476296465Sdelphij "error loading the config file '%s'\n", extfile); 477296465Sdelphij else 478296465Sdelphij BIO_printf(bio_err, 479296465Sdelphij "error on line %ld of config file '%s'\n", 480296465Sdelphij errorline, extfile); 481296465Sdelphij goto end; 482296465Sdelphij } 483296465Sdelphij if (!extsect) { 484296465Sdelphij extsect = NCONF_get_string(extconf, "default", "extensions"); 485296465Sdelphij if (!extsect) { 486296465Sdelphij ERR_clear_error(); 487296465Sdelphij extsect = "default"; 488296465Sdelphij } 489296465Sdelphij } 490296465Sdelphij X509V3_set_ctx_test(&ctx2); 491296465Sdelphij X509V3_set_nconf(&ctx2, extconf); 492296465Sdelphij if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { 493296465Sdelphij BIO_printf(bio_err, 494296465Sdelphij "Error Loading extension section %s\n", extsect); 495296465Sdelphij ERR_print_errors(bio_err); 496296465Sdelphij goto end; 497296465Sdelphij } 498296465Sdelphij } 49955714Skris 500296465Sdelphij if (reqfile) { 501296465Sdelphij EVP_PKEY *pkey; 502296465Sdelphij BIO *in; 50355714Skris 504296465Sdelphij if (!sign_flag && !CA_flag) { 505296465Sdelphij BIO_printf(bio_err, "We need a private key to sign with\n"); 506296465Sdelphij goto end; 507296465Sdelphij } 508296465Sdelphij in = BIO_new(BIO_s_file()); 509296465Sdelphij if (in == NULL) { 510296465Sdelphij ERR_print_errors(bio_err); 511296465Sdelphij goto end; 512296465Sdelphij } 51355714Skris 514296465Sdelphij if (infile == NULL) 515296465Sdelphij BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT); 516296465Sdelphij else { 517296465Sdelphij if (BIO_read_filename(in, infile) <= 0) { 518296465Sdelphij perror(infile); 519296465Sdelphij BIO_free(in); 520296465Sdelphij goto end; 521296465Sdelphij } 522296465Sdelphij } 523296465Sdelphij req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); 524296465Sdelphij BIO_free(in); 52555714Skris 526296465Sdelphij if (req == NULL) { 527296465Sdelphij ERR_print_errors(bio_err); 528296465Sdelphij goto end; 529296465Sdelphij } 53055714Skris 531296465Sdelphij if ((req->req_info == NULL) || 532296465Sdelphij (req->req_info->pubkey == NULL) || 533296465Sdelphij (req->req_info->pubkey->public_key == NULL) || 534296465Sdelphij (req->req_info->pubkey->public_key->data == NULL)) { 535296465Sdelphij BIO_printf(bio_err, 536296465Sdelphij "The certificate request appears to corrupted\n"); 537296465Sdelphij BIO_printf(bio_err, "It does not contain a public key\n"); 538296465Sdelphij goto end; 539296465Sdelphij } 540296465Sdelphij if ((pkey = X509_REQ_get_pubkey(req)) == NULL) { 541296465Sdelphij BIO_printf(bio_err, "error unpacking public key\n"); 542296465Sdelphij goto end; 543296465Sdelphij } 544296465Sdelphij i = X509_REQ_verify(req, pkey); 545296465Sdelphij EVP_PKEY_free(pkey); 546296465Sdelphij if (i < 0) { 547296465Sdelphij BIO_printf(bio_err, "Signature verification error\n"); 548296465Sdelphij ERR_print_errors(bio_err); 549296465Sdelphij goto end; 550296465Sdelphij } 551296465Sdelphij if (i == 0) { 552296465Sdelphij BIO_printf(bio_err, 553296465Sdelphij "Signature did not match the certificate request\n"); 554296465Sdelphij goto end; 555296465Sdelphij } else 556296465Sdelphij BIO_printf(bio_err, "Signature ok\n"); 55755714Skris 558296465Sdelphij print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), 559296465Sdelphij nmflag); 56055714Skris 561296465Sdelphij if ((x = X509_new()) == NULL) 562296465Sdelphij goto end; 56368651Skris 564296465Sdelphij if (sno == NULL) { 565296465Sdelphij sno = ASN1_INTEGER_new(); 566296465Sdelphij if (!sno || !rand_serial(NULL, sno)) 567296465Sdelphij goto end; 568296465Sdelphij if (!X509_set_serialNumber(x, sno)) 569296465Sdelphij goto end; 570296465Sdelphij ASN1_INTEGER_free(sno); 571296465Sdelphij sno = NULL; 572296465Sdelphij } else if (!X509_set_serialNumber(x, sno)) 573296465Sdelphij goto end; 57455714Skris 575296465Sdelphij if (!X509_set_issuer_name(x, req->req_info->subject)) 576296465Sdelphij goto end; 577296465Sdelphij if (!X509_set_subject_name(x, req->req_info->subject)) 578296465Sdelphij goto end; 579142425Snectar 580296465Sdelphij X509_gmtime_adj(X509_get_notBefore(x), 0); 581296465Sdelphij X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days); 58255714Skris 583296465Sdelphij pkey = X509_REQ_get_pubkey(req); 584296465Sdelphij X509_set_pubkey(x, pkey); 585296465Sdelphij EVP_PKEY_free(pkey); 586296465Sdelphij } else 587296465Sdelphij x = load_cert(bio_err, infile, informat, NULL, e, "Certificate"); 58855714Skris 589296465Sdelphij if (x == NULL) 590296465Sdelphij goto end; 591296465Sdelphij if (CA_flag) { 592296465Sdelphij xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate"); 593296465Sdelphij if (xca == NULL) 594296465Sdelphij goto end; 595296465Sdelphij } 59655714Skris 597296465Sdelphij if (!noout || text || next_serial) { 598296465Sdelphij OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); 59955714Skris 600296465Sdelphij out = BIO_new(BIO_s_file()); 601296465Sdelphij if (out == NULL) { 602296465Sdelphij ERR_print_errors(bio_err); 603296465Sdelphij goto end; 604296465Sdelphij } 605296465Sdelphij if (outfile == NULL) { 606296465Sdelphij BIO_set_fp(out, stdout, BIO_NOCLOSE); 607109998Smarkm#ifdef OPENSSL_SYS_VMS 608296465Sdelphij { 609296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 610296465Sdelphij out = BIO_push(tmpbio, out); 611296465Sdelphij } 61268651Skris#endif 613296465Sdelphij } else { 614296465Sdelphij if (BIO_write_filename(out, outfile) <= 0) { 615296465Sdelphij perror(outfile); 616296465Sdelphij goto end; 617296465Sdelphij } 618296465Sdelphij } 619296465Sdelphij } 62055714Skris 621296465Sdelphij if (alias) 622296465Sdelphij X509_alias_set1(x, (unsigned char *)alias, -1); 62359191Skris 624296465Sdelphij if (clrtrust) 625296465Sdelphij X509_trust_clear(x); 626296465Sdelphij if (clrreject) 627296465Sdelphij X509_reject_clear(x); 62859191Skris 629296465Sdelphij if (trust) { 630296465Sdelphij for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { 631296465Sdelphij objtmp = sk_ASN1_OBJECT_value(trust, i); 632296465Sdelphij X509_add1_trust_object(x, objtmp); 633296465Sdelphij } 634296465Sdelphij } 63559191Skris 636296465Sdelphij if (reject) { 637296465Sdelphij for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { 638296465Sdelphij objtmp = sk_ASN1_OBJECT_value(reject, i); 639296465Sdelphij X509_add1_reject_object(x, objtmp); 640296465Sdelphij } 641296465Sdelphij } 64259191Skris 643296465Sdelphij if (num) { 644296465Sdelphij for (i = 1; i <= num; i++) { 645296465Sdelphij if (issuer == i) { 646296465Sdelphij print_name(STDout, "issuer= ", 647296465Sdelphij X509_get_issuer_name(x), nmflag); 648296465Sdelphij } else if (subject == i) { 649296465Sdelphij print_name(STDout, "subject= ", 650296465Sdelphij X509_get_subject_name(x), nmflag); 651296465Sdelphij } else if (serial == i) { 652296465Sdelphij BIO_printf(STDout, "serial="); 653296465Sdelphij i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x)); 654296465Sdelphij BIO_printf(STDout, "\n"); 655296465Sdelphij } else if (next_serial == i) { 656296465Sdelphij BIGNUM *bnser; 657296465Sdelphij ASN1_INTEGER *ser; 658296465Sdelphij ser = X509_get_serialNumber(x); 659296465Sdelphij bnser = ASN1_INTEGER_to_BN(ser, NULL); 660296465Sdelphij if (!bnser) 661296465Sdelphij goto end; 662296465Sdelphij if (!BN_add_word(bnser, 1)) 663296465Sdelphij goto end; 664296465Sdelphij ser = BN_to_ASN1_INTEGER(bnser, NULL); 665296465Sdelphij if (!ser) 666296465Sdelphij goto end; 667296465Sdelphij BN_free(bnser); 668296465Sdelphij i2a_ASN1_INTEGER(out, ser); 669296465Sdelphij ASN1_INTEGER_free(ser); 670296465Sdelphij BIO_puts(out, "\n"); 671296465Sdelphij } else if ((email == i) || (ocsp_uri == i)) { 672296465Sdelphij int j; 673296465Sdelphij STACK *emlst; 674296465Sdelphij if (email == i) 675296465Sdelphij emlst = X509_get1_email(x); 676296465Sdelphij else 677296465Sdelphij emlst = X509_get1_ocsp(x); 678296465Sdelphij for (j = 0; j < sk_num(emlst); j++) 679296465Sdelphij BIO_printf(STDout, "%s\n", sk_value(emlst, j)); 680296465Sdelphij X509_email_free(emlst); 681296465Sdelphij } else if (aliasout == i) { 682296465Sdelphij unsigned char *alstr; 683296465Sdelphij alstr = X509_alias_get0(x, NULL); 684296465Sdelphij if (alstr) 685296465Sdelphij BIO_printf(STDout, "%s\n", alstr); 686296465Sdelphij else 687296465Sdelphij BIO_puts(STDout, "<No Alias>\n"); 688296465Sdelphij } else if (subject_hash == i) { 689296465Sdelphij BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x)); 690296465Sdelphij } else if (issuer_hash == i) { 691296465Sdelphij BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x)); 692296465Sdelphij } else if (pprint == i) { 693296465Sdelphij X509_PURPOSE *ptmp; 694296465Sdelphij int j; 695296465Sdelphij BIO_printf(STDout, "Certificate purposes:\n"); 696296465Sdelphij for (j = 0; j < X509_PURPOSE_get_count(); j++) { 697296465Sdelphij ptmp = X509_PURPOSE_get0(j); 698296465Sdelphij purpose_print(STDout, x, ptmp); 699296465Sdelphij } 700296465Sdelphij } else if (modulus == i) { 701296465Sdelphij EVP_PKEY *pkey; 70255714Skris 703296465Sdelphij pkey = X509_get_pubkey(x); 704296465Sdelphij if (pkey == NULL) { 705296465Sdelphij BIO_printf(bio_err, "Modulus=unavailable\n"); 706296465Sdelphij ERR_print_errors(bio_err); 707296465Sdelphij goto end; 708296465Sdelphij } 709296465Sdelphij BIO_printf(STDout, "Modulus="); 710109998Smarkm#ifndef OPENSSL_NO_RSA 711296465Sdelphij if (pkey->type == EVP_PKEY_RSA) 712296465Sdelphij BN_print(STDout, pkey->pkey.rsa->n); 713296465Sdelphij else 71455714Skris#endif 715109998Smarkm#ifndef OPENSSL_NO_DSA 716296465Sdelphij if (pkey->type == EVP_PKEY_DSA) 717296465Sdelphij BN_print(STDout, pkey->pkey.dsa->pub_key); 718296465Sdelphij else 71955714Skris#endif 720296465Sdelphij BIO_printf(STDout, "Wrong Algorithm type"); 721296465Sdelphij BIO_printf(STDout, "\n"); 722296465Sdelphij EVP_PKEY_free(pkey); 723296465Sdelphij } else if (pubkey == i) { 724296465Sdelphij EVP_PKEY *pkey; 72559191Skris 726296465Sdelphij pkey = X509_get_pubkey(x); 727296465Sdelphij if (pkey == NULL) { 728296465Sdelphij BIO_printf(bio_err, "Error getting public key\n"); 729296465Sdelphij ERR_print_errors(bio_err); 730296465Sdelphij goto end; 731296465Sdelphij } 732296465Sdelphij PEM_write_bio_PUBKEY(STDout, pkey); 733296465Sdelphij EVP_PKEY_free(pkey); 734296465Sdelphij } else if (C == i) { 735296465Sdelphij unsigned char *d; 736296465Sdelphij char *m; 737296465Sdelphij int y, z; 73855714Skris 739296465Sdelphij X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf); 740296465Sdelphij BIO_printf(STDout, "/* subject:%s */\n", buf); 741296465Sdelphij m = X509_NAME_oneline(X509_get_issuer_name(x), buf, 742296465Sdelphij sizeof buf); 743296465Sdelphij BIO_printf(STDout, "/* issuer :%s */\n", buf); 74455714Skris 745296465Sdelphij z = i2d_X509(x, NULL); 746296465Sdelphij m = OPENSSL_malloc(z); 74755714Skris 748296465Sdelphij d = (unsigned char *)m; 749296465Sdelphij z = i2d_X509_NAME(X509_get_subject_name(x), &d); 750296465Sdelphij BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n", 751296465Sdelphij z); 752296465Sdelphij d = (unsigned char *)m; 753296465Sdelphij for (y = 0; y < z; y++) { 754296465Sdelphij BIO_printf(STDout, "0x%02X,", d[y]); 755296465Sdelphij if ((y & 0x0f) == 0x0f) 756296465Sdelphij BIO_printf(STDout, "\n"); 757296465Sdelphij } 758296465Sdelphij if (y % 16 != 0) 759296465Sdelphij BIO_printf(STDout, "\n"); 760296465Sdelphij BIO_printf(STDout, "};\n"); 76155714Skris 762296465Sdelphij z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); 763296465Sdelphij BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z); 764296465Sdelphij d = (unsigned char *)m; 765296465Sdelphij for (y = 0; y < z; y++) { 766296465Sdelphij BIO_printf(STDout, "0x%02X,", d[y]); 767296465Sdelphij if ((y & 0x0f) == 0x0f) 768296465Sdelphij BIO_printf(STDout, "\n"); 769296465Sdelphij } 770296465Sdelphij if (y % 16 != 0) 771296465Sdelphij BIO_printf(STDout, "\n"); 772296465Sdelphij BIO_printf(STDout, "};\n"); 77355714Skris 774296465Sdelphij z = i2d_X509(x, &d); 775296465Sdelphij BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n", 776296465Sdelphij z); 777296465Sdelphij d = (unsigned char *)m; 778296465Sdelphij for (y = 0; y < z; y++) { 779296465Sdelphij BIO_printf(STDout, "0x%02X,", d[y]); 780296465Sdelphij if ((y & 0x0f) == 0x0f) 781296465Sdelphij BIO_printf(STDout, "\n"); 782296465Sdelphij } 783296465Sdelphij if (y % 16 != 0) 784296465Sdelphij BIO_printf(STDout, "\n"); 785296465Sdelphij BIO_printf(STDout, "};\n"); 78655714Skris 787296465Sdelphij OPENSSL_free(m); 788296465Sdelphij } else if (text == i) { 789296465Sdelphij X509_print_ex(out, x, nmflag, certflag); 790296465Sdelphij } else if (startdate == i) { 791296465Sdelphij BIO_puts(STDout, "notBefore="); 792296465Sdelphij ASN1_TIME_print(STDout, X509_get_notBefore(x)); 793296465Sdelphij BIO_puts(STDout, "\n"); 794296465Sdelphij } else if (enddate == i) { 795296465Sdelphij BIO_puts(STDout, "notAfter="); 796296465Sdelphij ASN1_TIME_print(STDout, X509_get_notAfter(x)); 797296465Sdelphij BIO_puts(STDout, "\n"); 798296465Sdelphij } else if (fingerprint == i) { 799296465Sdelphij int j; 800296465Sdelphij unsigned int n; 801296465Sdelphij unsigned char md[EVP_MAX_MD_SIZE]; 80255714Skris 803296465Sdelphij if (!X509_digest(x, digest, md, &n)) { 804296465Sdelphij BIO_printf(bio_err, "out of memory\n"); 805296465Sdelphij goto end; 806296465Sdelphij } 807296465Sdelphij BIO_printf(STDout, "%s Fingerprint=", 808296465Sdelphij OBJ_nid2sn(EVP_MD_type(digest))); 809296465Sdelphij for (j = 0; j < (int)n; j++) { 810296465Sdelphij BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n) 811296465Sdelphij ? '\n' : ':'); 812296465Sdelphij } 813296465Sdelphij } 81455714Skris 815296465Sdelphij /* should be in the library */ 816296465Sdelphij else if ((sign_flag == i) && (x509req == 0)) { 817296465Sdelphij BIO_printf(bio_err, "Getting Private key\n"); 818296465Sdelphij if (Upkey == NULL) { 819296465Sdelphij Upkey = load_key(bio_err, 820296465Sdelphij keyfile, keyformat, 0, 821296465Sdelphij passin, e, "Private key"); 822296465Sdelphij if (Upkey == NULL) 823296465Sdelphij goto end; 824296465Sdelphij } 825109998Smarkm#ifndef OPENSSL_NO_DSA 826296465Sdelphij if (Upkey->type == EVP_PKEY_DSA) 827296465Sdelphij digest = EVP_dss1(); 82855714Skris#endif 829160814Ssimon#ifndef OPENSSL_NO_ECDSA 830296465Sdelphij if (Upkey->type == EVP_PKEY_EC) 831296465Sdelphij digest = EVP_ecdsa(); 832160814Ssimon#endif 83355714Skris 834296465Sdelphij assert(need_rand); 835296465Sdelphij if (!sign(x, Upkey, days, clrext, digest, extconf, extsect)) 836296465Sdelphij goto end; 837296465Sdelphij } else if (CA_flag == i) { 838296465Sdelphij BIO_printf(bio_err, "Getting CA Private Key\n"); 839296465Sdelphij if (CAkeyfile != NULL) { 840296465Sdelphij CApkey = load_key(bio_err, 841296465Sdelphij CAkeyfile, CAkeyformat, 842296465Sdelphij 0, passin, e, "CA Private Key"); 843296465Sdelphij if (CApkey == NULL) 844296465Sdelphij goto end; 845296465Sdelphij } 846109998Smarkm#ifndef OPENSSL_NO_DSA 847296465Sdelphij if (CApkey->type == EVP_PKEY_DSA) 848296465Sdelphij digest = EVP_dss1(); 84955714Skris#endif 850160814Ssimon#ifndef OPENSSL_NO_ECDSA 851296465Sdelphij if (CApkey->type == EVP_PKEY_EC) 852296465Sdelphij digest = EVP_ecdsa(); 853160814Ssimon#endif 85455714Skris 855296465Sdelphij assert(need_rand); 856296465Sdelphij if (!x509_certify(ctx, CAfile, digest, x, xca, 857296465Sdelphij CApkey, CAserial, CA_createserial, days, 858296465Sdelphij clrext, extconf, extsect, sno)) 859296465Sdelphij goto end; 860296465Sdelphij } else if (x509req == i) { 861296465Sdelphij EVP_PKEY *pk; 86255714Skris 863296465Sdelphij BIO_printf(bio_err, "Getting request Private Key\n"); 864296465Sdelphij if (keyfile == NULL) { 865296465Sdelphij BIO_printf(bio_err, "no request key file specified\n"); 866296465Sdelphij goto end; 867296465Sdelphij } else { 868296465Sdelphij pk = load_key(bio_err, 869296465Sdelphij keyfile, keyformat, 0, 870296465Sdelphij passin, e, "request key"); 871296465Sdelphij if (pk == NULL) 872296465Sdelphij goto end; 873296465Sdelphij } 87455714Skris 875296465Sdelphij BIO_printf(bio_err, "Generating certificate request\n"); 876296465Sdelphij 877109998Smarkm#ifndef OPENSSL_NO_DSA 878296465Sdelphij if (pk->type == EVP_PKEY_DSA) 879296465Sdelphij digest = EVP_dss1(); 88076866Skris#endif 881160814Ssimon#ifndef OPENSSL_NO_ECDSA 882296465Sdelphij if (pk->type == EVP_PKEY_EC) 883296465Sdelphij digest = EVP_ecdsa(); 884160814Ssimon#endif 88559191Skris 886296465Sdelphij rq = X509_to_X509_REQ(x, pk, digest); 887296465Sdelphij EVP_PKEY_free(pk); 888296465Sdelphij if (rq == NULL) { 889296465Sdelphij ERR_print_errors(bio_err); 890296465Sdelphij goto end; 891296465Sdelphij } 892296465Sdelphij if (!noout) { 893296465Sdelphij X509_REQ_print(out, rq); 894296465Sdelphij PEM_write_bio_X509_REQ(out, rq); 895296465Sdelphij } 896296465Sdelphij noout = 1; 897296465Sdelphij } else if (ocspid == i) { 898296465Sdelphij X509_ocspid_print(out, x); 899296465Sdelphij } 900296465Sdelphij } 901296465Sdelphij } 90255714Skris 903296465Sdelphij if (checkend) { 904296465Sdelphij time_t tcheck = time(NULL) + checkoffset; 90568651Skris 906296465Sdelphij if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { 907296465Sdelphij BIO_printf(out, "Certificate will expire\n"); 908296465Sdelphij ret = 1; 909296465Sdelphij } else { 910296465Sdelphij BIO_printf(out, "Certificate will not expire\n"); 911296465Sdelphij ret = 0; 912296465Sdelphij } 913296465Sdelphij goto end; 914296465Sdelphij } 91568651Skris 916296465Sdelphij if (noout) { 917296465Sdelphij ret = 0; 918296465Sdelphij goto end; 919296465Sdelphij } 92055714Skris 921296465Sdelphij if (outformat == FORMAT_ASN1) 922296465Sdelphij i = i2d_X509_bio(out, x); 923296465Sdelphij else if (outformat == FORMAT_PEM) { 924296465Sdelphij if (trustout) 925296465Sdelphij i = PEM_write_bio_X509_AUX(out, x); 926296465Sdelphij else 927296465Sdelphij i = PEM_write_bio_X509(out, x); 928296465Sdelphij } else if (outformat == FORMAT_NETSCAPE) { 929296465Sdelphij ASN1_HEADER ah; 930296465Sdelphij ASN1_OCTET_STRING os; 93155714Skris 932296465Sdelphij os.data = (unsigned char *)NETSCAPE_CERT_HDR; 933296465Sdelphij os.length = strlen(NETSCAPE_CERT_HDR); 934296465Sdelphij ah.header = &os; 935296465Sdelphij ah.data = (char *)x; 936296465Sdelphij ah.meth = X509_asn1_meth(); 93755714Skris 938296465Sdelphij i = ASN1_i2d_bio_of(ASN1_HEADER, i2d_ASN1_HEADER, out, &ah); 939296465Sdelphij } else { 940296465Sdelphij BIO_printf(bio_err, "bad output format specified for outfile\n"); 941296465Sdelphij goto end; 942296465Sdelphij } 943296465Sdelphij if (!i) { 944296465Sdelphij BIO_printf(bio_err, "unable to write certificate\n"); 945296465Sdelphij ERR_print_errors(bio_err); 946296465Sdelphij goto end; 947296465Sdelphij } 948296465Sdelphij ret = 0; 949296465Sdelphij end: 950296465Sdelphij if (need_rand) 951296465Sdelphij app_RAND_write_file(NULL, bio_err); 952296465Sdelphij OBJ_cleanup(); 953296465Sdelphij NCONF_free(extconf); 954296465Sdelphij BIO_free_all(out); 955296465Sdelphij BIO_free_all(STDout); 956296465Sdelphij X509_STORE_free(ctx); 957296465Sdelphij X509_REQ_free(req); 958296465Sdelphij X509_free(x); 959296465Sdelphij X509_free(xca); 960296465Sdelphij EVP_PKEY_free(Upkey); 961296465Sdelphij EVP_PKEY_free(CApkey); 962296465Sdelphij X509_REQ_free(rq); 963296465Sdelphij ASN1_INTEGER_free(sno); 964296465Sdelphij sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); 965296465Sdelphij sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); 966296465Sdelphij if (passin) 967296465Sdelphij OPENSSL_free(passin); 968296465Sdelphij apps_shutdown(); 969296465Sdelphij OPENSSL_EXIT(ret); 970296465Sdelphij} 97155714Skris 972296465Sdelphijstatic ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, 973296465Sdelphij int create) 974296465Sdelphij{ 975296465Sdelphij char *buf = NULL, *p; 976296465Sdelphij ASN1_INTEGER *bs = NULL; 977296465Sdelphij BIGNUM *serial = NULL; 978296465Sdelphij size_t len; 97955714Skris 980296465Sdelphij len = ((serialfile == NULL) 981296465Sdelphij ? (strlen(CAfile) + strlen(POSTFIX) + 1) 982296465Sdelphij : (strlen(serialfile))) + 1; 983296465Sdelphij buf = OPENSSL_malloc(len); 984296465Sdelphij if (buf == NULL) { 985296465Sdelphij BIO_printf(bio_err, "out of mem\n"); 986296465Sdelphij goto end; 987296465Sdelphij } 988296465Sdelphij if (serialfile == NULL) { 989296465Sdelphij BUF_strlcpy(buf, CAfile, len); 990296465Sdelphij for (p = buf; *p; p++) 991296465Sdelphij if (*p == '.') { 992296465Sdelphij *p = '\0'; 993296465Sdelphij break; 994296465Sdelphij } 995296465Sdelphij BUF_strlcat(buf, POSTFIX, len); 996296465Sdelphij } else 997296465Sdelphij BUF_strlcpy(buf, serialfile, len); 99855714Skris 999296465Sdelphij serial = load_serial(buf, create, NULL); 1000296465Sdelphij if (serial == NULL) 1001296465Sdelphij goto end; 100255714Skris 1003296465Sdelphij if (!BN_add_word(serial, 1)) { 1004296465Sdelphij BIO_printf(bio_err, "add_word failure\n"); 1005296465Sdelphij goto end; 1006296465Sdelphij } 1007109998Smarkm 1008296465Sdelphij if (!save_serial(buf, NULL, serial, &bs)) 1009296465Sdelphij goto end; 1010127128Snectar 1011127128Snectar end: 1012296465Sdelphij if (buf) 1013296465Sdelphij OPENSSL_free(buf); 1014296465Sdelphij BN_free(serial); 1015296465Sdelphij return bs; 1016296465Sdelphij} 1017109998Smarkm 1018109998Smarkmstatic int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 1019296465Sdelphij X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, 1020296465Sdelphij int create, int days, int clrext, CONF *conf, 1021296465Sdelphij char *section, ASN1_INTEGER *sno) 1022296465Sdelphij{ 1023296465Sdelphij int ret = 0; 1024296465Sdelphij ASN1_INTEGER *bs = NULL; 1025296465Sdelphij X509_STORE_CTX xsc; 1026296465Sdelphij EVP_PKEY *upkey; 1027109998Smarkm 1028296465Sdelphij upkey = X509_get_pubkey(xca); 1029296465Sdelphij EVP_PKEY_copy_parameters(upkey, pkey); 1030296465Sdelphij EVP_PKEY_free(upkey); 1031109998Smarkm 1032296465Sdelphij if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) { 1033296465Sdelphij BIO_printf(bio_err, "Error initialising X509 store\n"); 1034296465Sdelphij goto end; 1035296465Sdelphij } 1036296465Sdelphij if (sno) 1037296465Sdelphij bs = sno; 1038296465Sdelphij else if (!(bs = x509_load_serial(CAfile, serialfile, create))) 1039296465Sdelphij goto end; 1040109998Smarkm 1041296465Sdelphij/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/ 104255714Skris 1043296465Sdelphij /* 1044296465Sdelphij * NOTE: this certificate can/should be self signed, unless it was a 1045296465Sdelphij * certificate request in which case it is not. 1046296465Sdelphij */ 1047296465Sdelphij X509_STORE_CTX_set_cert(&xsc, x); 1048296465Sdelphij X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); 1049296465Sdelphij if (!reqfile && X509_verify_cert(&xsc) <= 0) 1050296465Sdelphij goto end; 105155714Skris 1052296465Sdelphij if (!X509_check_private_key(xca, pkey)) { 1053296465Sdelphij BIO_printf(bio_err, 1054296465Sdelphij "CA certificate and CA private key do not match\n"); 1055296465Sdelphij goto end; 1056296465Sdelphij } 105755714Skris 1058296465Sdelphij if (!X509_set_issuer_name(x, X509_get_subject_name(xca))) 1059296465Sdelphij goto end; 1060296465Sdelphij if (!X509_set_serialNumber(x, bs)) 1061296465Sdelphij goto end; 106255714Skris 1063296465Sdelphij if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL) 1064296465Sdelphij goto end; 106555714Skris 1066296465Sdelphij /* hardwired expired */ 1067296465Sdelphij if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) == 1068296465Sdelphij NULL) 1069296465Sdelphij goto end; 107055714Skris 1071296465Sdelphij if (clrext) { 1072296465Sdelphij while (X509_get_ext_count(x) > 0) 1073296465Sdelphij X509_delete_ext(x, 0); 1074296465Sdelphij } 107559191Skris 1076296465Sdelphij if (conf) { 1077296465Sdelphij X509V3_CTX ctx2; 1078296465Sdelphij X509_set_version(x, 2); /* version 3 certificate */ 1079296465Sdelphij X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); 1080296465Sdelphij X509V3_set_nconf(&ctx2, conf); 1081296465Sdelphij if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) 1082296465Sdelphij goto end; 1083296465Sdelphij } 108455714Skris 1085296465Sdelphij if (!X509_sign(x, pkey, digest)) 1086296465Sdelphij goto end; 1087296465Sdelphij ret = 1; 1088296465Sdelphij end: 1089296465Sdelphij X509_STORE_CTX_cleanup(&xsc); 1090296465Sdelphij if (!ret) 1091296465Sdelphij ERR_print_errors(bio_err); 1092296465Sdelphij if (!sno) 1093296465Sdelphij ASN1_INTEGER_free(bs); 1094296465Sdelphij return ret; 1095296465Sdelphij} 109655714Skris 109755714Skrisstatic int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx) 1098296465Sdelphij{ 1099296465Sdelphij int err; 1100296465Sdelphij X509 *err_cert; 110155714Skris 1102296465Sdelphij /* 1103296465Sdelphij * it is ok to use a self signed certificate This case will catch both 1104296465Sdelphij * the initial ok == 0 and the final ok == 1 calls to this function 1105296465Sdelphij */ 1106296465Sdelphij err = X509_STORE_CTX_get_error(ctx); 1107296465Sdelphij if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) 1108296465Sdelphij return 1; 110955714Skris 1110296465Sdelphij /* 1111296465Sdelphij * BAD we should have gotten an error. Normally if everything worked 1112296465Sdelphij * X509_STORE_CTX_get_error(ctx) will still be set to 1113296465Sdelphij * DEPTH_ZERO_SELF_.... 1114296465Sdelphij */ 1115296465Sdelphij if (ok) { 1116296465Sdelphij BIO_printf(bio_err, 1117296465Sdelphij "error with certificate to be certified - should be self signed\n"); 1118296465Sdelphij return 0; 1119296465Sdelphij } else { 1120296465Sdelphij err_cert = X509_STORE_CTX_get_current_cert(ctx); 1121296465Sdelphij print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0); 1122296465Sdelphij BIO_printf(bio_err, 1123296465Sdelphij "error with certificate - error %d at depth %d\n%s\n", err, 1124296465Sdelphij X509_STORE_CTX_get_error_depth(ctx), 1125296465Sdelphij X509_verify_cert_error_string(err)); 1126296465Sdelphij return 1; 1127296465Sdelphij } 1128296465Sdelphij} 112955714Skris 113055714Skris/* self sign */ 1131296465Sdelphijstatic int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, 1132296465Sdelphij const EVP_MD *digest, CONF *conf, char *section) 1133296465Sdelphij{ 113455714Skris 1135296465Sdelphij EVP_PKEY *pktmp; 113655714Skris 1137296465Sdelphij pktmp = X509_get_pubkey(x); 1138296465Sdelphij EVP_PKEY_copy_parameters(pktmp, pkey); 1139296465Sdelphij EVP_PKEY_save_parameters(pktmp, 1); 1140296465Sdelphij EVP_PKEY_free(pktmp); 114155714Skris 1142296465Sdelphij if (!X509_set_issuer_name(x, X509_get_subject_name(x))) 1143296465Sdelphij goto err; 1144296465Sdelphij if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) 1145296465Sdelphij goto err; 114655714Skris 1147296465Sdelphij /* Lets just make it 12:00am GMT, Jan 1 1970 */ 1148296465Sdelphij /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */ 1149296465Sdelphij /* 28 days to be certified */ 115055714Skris 1151296465Sdelphij if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) == 1152296465Sdelphij NULL) 1153296465Sdelphij goto err; 115455714Skris 1155296465Sdelphij if (!X509_set_pubkey(x, pkey)) 1156296465Sdelphij goto err; 1157296465Sdelphij if (clrext) { 1158296465Sdelphij while (X509_get_ext_count(x) > 0) 1159296465Sdelphij X509_delete_ext(x, 0); 1160296465Sdelphij } 1161296465Sdelphij if (conf) { 1162296465Sdelphij X509V3_CTX ctx; 1163296465Sdelphij X509_set_version(x, 2); /* version 3 certificate */ 1164296465Sdelphij X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); 1165296465Sdelphij X509V3_set_nconf(&ctx, conf); 1166296465Sdelphij if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) 1167296465Sdelphij goto err; 1168296465Sdelphij } 1169296465Sdelphij if (!X509_sign(x, pkey, digest)) 1170296465Sdelphij goto err; 1171296465Sdelphij return 1; 1172296465Sdelphij err: 1173296465Sdelphij ERR_print_errors(bio_err); 1174296465Sdelphij return 0; 1175296465Sdelphij} 117659191Skris 117759191Skrisstatic int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) 117859191Skris{ 1179296465Sdelphij int id, i, idret; 1180296465Sdelphij char *pname; 1181296465Sdelphij id = X509_PURPOSE_get_id(pt); 1182296465Sdelphij pname = X509_PURPOSE_get0_name(pt); 1183296465Sdelphij for (i = 0; i < 2; i++) { 1184296465Sdelphij idret = X509_check_purpose(cert, id, i); 1185296465Sdelphij BIO_printf(bio, "%s%s : ", pname, i ? " CA" : ""); 1186296465Sdelphij if (idret == 1) 1187296465Sdelphij BIO_printf(bio, "Yes\n"); 1188296465Sdelphij else if (idret == 0) 1189296465Sdelphij BIO_printf(bio, "No\n"); 1190296465Sdelphij else 1191296465Sdelphij BIO_printf(bio, "Yes (WARNING code=%d)\n", idret); 1192296465Sdelphij } 1193296465Sdelphij return 1; 119459191Skris} 1195