X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fx509.c;h=9e5101259f158bf67920e3bced7b77d407641e64;hp=31ae38aeaaa665f3eff72445f30fbc3d81a51b92;hb=08f6ae5b2896a22e1e16de3e363d1ea314700b0b;hpb=b548a1f11c06ccdfa4f52a539912d22d77ee309e diff --git a/apps/x509.c b/apps/x509.c index 31ae38aeaa..9e5101259f 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -1,61 +1,12 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ -#include #include #include #include @@ -82,18 +33,14 @@ static int callb(int ok, X509_STORE_CTX *ctx); static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, char *section); -static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, + const EVP_MD *digest, CONF *conf, const char *section); +static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, X509 *x, X509 *xca, EVP_PKEY *pkey, - STACK_OF(OPENSSL_STRING) *sigopts, char *serial, + STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile, int create, int days, int clrext, CONF *conf, - char *section, ASN1_INTEGER *sno, int reqfile); + const char *section, ASN1_INTEGER *sno, int reqfile); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL -static int force_version = 2; -#endif - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, @@ -107,13 +54,8 @@ typedef enum OPTION_choice { OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST, OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST, OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID, -#ifndef OPENSSL_NO_MD5 OPT_SUBJECT_HASH_OLD, OPT_ISSUER_HASH_OLD, -#endif -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - OPT_FORCE_VERSION, -#endif OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT } OPTION_CHOICE; @@ -126,16 +68,10 @@ OPTIONS x509_options[] = { "Output format - default PEM (one of DER, NET or PEM)"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, - {"passin", OPT_PASSIN, 's', "Private key password source"}, + {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"}, {"serial", OPT_SERIAL, '-', "Print serial number value"}, {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, -#ifndef OPENSSL_NO_MD5 - {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', - "Print old-style (MD5) issuer hash value"}, - {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', - "Print old-style (MD5) subject hash value"}, -#endif {"hash", OPT_HASH, '-', "Synonym for -subject_hash"}, {"subject", OPT_SUBJECT, '-', "Print subject DN"}, {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, @@ -163,7 +99,7 @@ OPTIONS x509_options[] = { {"setalias", OPT_SETALIAS, 's', "Set certificate alias"}, {"days", OPT_DAYS, 'n', "How long till expiry of a signed certificate - def 30 days"}, - {"checkend", OPT_CHECKEND, 'p', + {"checkend", OPT_CHECKEND, 'M', "Check whether the cert expires in the next arg seconds"}, {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"}, @@ -171,11 +107,11 @@ OPTIONS x509_options[] = { "Output a certification request object"}, {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, - {"CAkey", OPT_CAKEY, '<', + {"CAkey", OPT_CAKEY, 's', "The CA key, must be PEM format; if not in CAfile"}, {"CAcreateserial", OPT_CACREATESERIAL, '-', "Create serial number file if it does not exist"}, - {"CAserial", OPT_CASERIAL, '<', "Serial file"}, + {"CAserial", OPT_CASERIAL, 's', "Serial file"}, {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, {"text", OPT_TEXT, '-', "Print the certificate in text form"}, {"C", OPT_C, '-', "Print out C code forms"}, @@ -188,17 +124,20 @@ OPTIONS x509_options[] = { {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"}, {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, {"CAkeyform", OPT_CAKEYFORM, 'F', "CA key format - default PEM"}, - {"sigopt", OPT_SIGOPT, 's'}, + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, {"force_pubkey", OPT_FORCE_PUBKEY, '<'}, {"next_serial", OPT_NEXT_SERIAL, '-'}, {"clrreject", OPT_CLRREJECT, '-'}, - {"badsig", OPT_BADSIG, '-'}, + {"badsig", OPT_BADSIG, '-', "Corrupt last byte of certificate signature (for test)"}, {"", OPT_MD, '-', "Any supported digest"}, +#ifndef OPENSSL_NO_MD5 + {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', + "Print old-style (MD5) issuer hash value"}, + {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', + "Print old-style (MD5) subject hash value"}, +#endif #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -#endif -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - {"force_version", OPT_FORCE_VERSION, 'p'}, #endif {NULL} }; @@ -206,7 +145,7 @@ OPTIONS x509_options[] = { int x509_main(int argc, char **argv) { ASN1_INTEGER *sno = NULL; - ASN1_OBJECT *objtmp; + ASN1_OBJECT *objtmp = NULL; BIO *out = NULL; CONF *extconf = NULL; EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; @@ -230,8 +169,10 @@ int x509_main(int argc, char **argv) int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0; - int checkoffset = 0, enddate = 0; + int enddate = 0; + time_t checkoffset = 0; unsigned long nmflag = 0, certflag = 0; + char nmflag_set = 0; OPTION_CHOICE o; ENGINE *e = NULL; #ifndef OPENSSL_NO_MD5 @@ -275,7 +216,7 @@ int x509_main(int argc, char **argv) goto opthelp; break; case OPT_CAKEYFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat)) + if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat)) goto opthelp; break; case OPT_OUT: @@ -291,11 +232,6 @@ int x509_main(int argc, char **argv) if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - case OPT_FORCE_VERSION: - force_version = atoi(opt_arg()) - 1; - break; -#endif case OPT_DAYS: days = atoi(opt_arg()); break; @@ -325,6 +261,10 @@ int x509_main(int argc, char **argv) CAserial = opt_arg(); break; case OPT_SET_SERIAL: + if (sno != NULL) { + /* Cannot be supplied twice */ + goto opthelp; + } if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) goto opthelp; break; @@ -341,6 +281,7 @@ int x509_main(int argc, char **argv) if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(trust, objtmp); + objtmp = NULL; trustout = 1; break; case OPT_ADDREJECT: @@ -354,6 +295,7 @@ int x509_main(int argc, char **argv) && (reject = sk_ASN1_OBJECT_new_null()) == NULL) goto end; sk_ASN1_OBJECT_push(reject, objtmp); + objtmp = NULL; trustout = 1; break; case OPT_SETALIAS: @@ -365,6 +307,7 @@ int x509_main(int argc, char **argv) goto opthelp; break; case OPT_NAMEOPT: + nmflag_set = 1; if (!set_name_ex(&nmflag, opt_arg())) goto opthelp; break; @@ -459,14 +402,28 @@ int x509_main(int argc, char **argv) case OPT_ISSUER_HASH_OLD: issuer_hash_old = ++num; break; +#else + case OPT_SUBJECT_HASH_OLD: + case OPT_ISSUER_HASH_OLD: + break; #endif case OPT_DATES: startdate = ++num; enddate = ++num; break; case OPT_CHECKEND: - checkoffset = atoi(opt_arg()); checkend = 1; + { + intmax_t temp = 0; + if (!opt_imax(opt_arg(), &temp)) + goto opthelp; + checkoffset = (time_t)temp; + if ((intmax_t)checkoffset != temp) { + BIO_printf(bio_err, "%s: checkend time out of range %s\n", + prog, opt_arg()); + goto opthelp; + } + } break; case OPT_CHECKHOST: checkhost = opt_arg(); @@ -489,7 +446,10 @@ int x509_main(int argc, char **argv) goto opthelp; } - out = bio_open_default(outfile, "w"); + if (!nmflag_set) + nmflag = XN_FLAG_ONELINE; + + out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; @@ -521,19 +481,9 @@ int x509_main(int argc, char **argv) } if (extfile) { - long errorline = -1; X509V3_CTX ctx2; - extconf = NCONF_new(NULL); - if (!NCONF_load(extconf, extfile, &errorline)) { - if (errorline <= 0) - BIO_printf(bio_err, - "error loading the config file '%s'\n", extfile); - else - BIO_printf(bio_err, - "error on line %ld of config file '%s'\n", - errorline, extfile); + if ((extconf = app_load_config(extfile)) == NULL) goto end; - } if (!extsect) { extsect = NCONF_get_string(extconf, "default", "extensions"); if (!extsect) { @@ -559,7 +509,7 @@ int x509_main(int argc, char **argv) BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } - in = bio_open_default(infile, "r"); + in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); @@ -570,21 +520,11 @@ int x509_main(int argc, char **argv) goto end; } - if ((req->req_info == NULL) || - (req->req_info->pubkey == NULL) || - (req->req_info->pubkey->public_key == NULL) || - (req->req_info->pubkey->public_key->data == NULL)) { - BIO_printf(bio_err, - "The certificate request appears to corrupted\n"); - BIO_printf(bio_err, "It does not contain a public key\n"); - goto end; - } - if ((pkey = X509_REQ_get_pubkey(req)) == NULL) { + if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } i = X509_REQ_verify(req, pkey); - EVP_PKEY_free(pkey); if (i < 0) { BIO_printf(bio_err, "Signature verification error\n"); ERR_print_errors(bio_err); @@ -605,7 +545,7 @@ int x509_main(int argc, char **argv) if (sno == NULL) { sno = ASN1_INTEGER_new(); - if (!sno || !rand_serial(NULL, sno)) + if (sno == NULL || !rand_serial(NULL, sno)) goto end; if (!X509_set_serialNumber(x, sno)) goto end; @@ -614,27 +554,26 @@ int x509_main(int argc, char **argv) } else if (!X509_set_serialNumber(x, sno)) goto end; - if (!X509_set_issuer_name(x, req->req_info->subject)) + if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req))) + goto end; + if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req))) goto end; - if (!X509_set_subject_name(x, req->req_info->subject)) + if (!set_cert_times(x, NULL, NULL, days)) goto end; - X509_gmtime_adj(X509_get_notBefore(x), 0); - X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL); if (fkey) X509_set_pubkey(x, fkey); else { - pkey = X509_REQ_get_pubkey(req); + pkey = X509_REQ_get0_pubkey(req); X509_set_pubkey(x, pkey); - EVP_PKEY_free(pkey); } } else - x = load_cert(infile, informat, NULL, e, "Certificate"); + x = load_cert(infile, informat, "Certificate"); if (x == NULL) goto end; if (CA_flag) { - xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate"); + xca = load_cert(CAfile, CAformat, "CA Certificate"); if (xca == NULL) goto end; } @@ -657,6 +596,7 @@ int x509_main(int argc, char **argv) objtmp = sk_ASN1_OBJECT_value(trust, i); X509_add1_trust_object(x, objtmp); } + objtmp = NULL; } if (reject) { @@ -664,14 +604,22 @@ int x509_main(int argc, char **argv) objtmp = sk_ASN1_OBJECT_value(reject, i); X509_add1_reject_object(x, objtmp); } + objtmp = NULL; + } + + if (badsig) { + const ASN1_BIT_STRING *signature; + + X509_get0_signature(&signature, NULL, x); + corrupt_signature(signature); } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { - print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag); + print_name(out, "issuer=", X509_get_issuer_name(x), nmflag); } else if (subject == i) { - print_name(out, "subject= ", + print_name(out, "subject=", X509_get_subject_name(x), nmflag); } else if (serial == i) { BIO_printf(out, "serial="); @@ -738,7 +686,7 @@ int x509_main(int argc, char **argv) } else if (modulus == i) { EVP_PKEY *pkey; - pkey = X509_get_pubkey(x); + pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Modulus=unavailable\n"); ERR_print_errors(bio_err); @@ -746,29 +694,33 @@ int x509_main(int argc, char **argv) } BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - BN_print(out, pkey->pkey.rsa->n); - else + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + const BIGNUM *n; + RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL); + BN_print(out, n); + } else #endif #ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - BN_print(out, pkey->pkey.dsa->pub_key); - else + if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) { + const BIGNUM *dsapub = NULL; + DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL); + BN_print(out, dsapub); + } else #endif + { BIO_printf(out, "Wrong Algorithm type"); + } BIO_printf(out, "\n"); - EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; - pkey = X509_get_pubkey(x); + pkey = X509_get0_pubkey(x); if (pkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); ERR_print_errors(bio_err); goto end; } PEM_write_bio_PUBKEY(out, pkey); - EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; @@ -778,7 +730,7 @@ int x509_main(int argc, char **argv) BIO_printf(out, "/*\n" " * Subject: %s\n", buf); - m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); + X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); BIO_printf(out, " * Issuer: %s\n" " */\n", buf); @@ -798,11 +750,11 @@ int x509_main(int argc, char **argv) X509_print_ex(out, x, nmflag, certflag); } else if (startdate == i) { BIO_puts(out, "notBefore="); - ASN1_TIME_print(out, X509_get_notBefore(x)); + ASN1_TIME_print(out, X509_get0_notBefore(x)); BIO_puts(out, "\n"); } else if (enddate == i) { BIO_puts(out, "notAfter="); - ASN1_TIME_print(out, X509_get_notAfter(x)); + ASN1_TIME_print(out, X509_get0_notAfter(x)); BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; @@ -889,7 +841,7 @@ int x509_main(int argc, char **argv) if (checkend) { time_t tcheck = time(NULL) + checkoffset; - if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) { + if (X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0) { BIO_printf(out, "Certificate will expire\n"); ret = 1; } else { @@ -906,9 +858,6 @@ int x509_main(int argc, char **argv) goto end; } - if (badsig) - x->signature->data[x->signature->length - 1] ^= 0x1; - if (outformat == FORMAT_ASN1) i = i2d_X509_bio(out, x); else if (outformat == FORMAT_PEM) { @@ -916,16 +865,6 @@ int x509_main(int argc, char **argv) i = PEM_write_bio_X509_AUX(out, x); else i = PEM_write_bio_X509(out, x); - } else if (outformat == FORMAT_NETSCAPE) { - NETSCAPE_X509 nx; - ASN1_OCTET_STRING hdr; - - hdr.data = (unsigned char *)NETSCAPE_CERT_HDR; - hdr.length = strlen(NETSCAPE_CERT_HDR); - nx.header = &hdr; - nx.cert = x; - - i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx); } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; @@ -939,7 +878,6 @@ int x509_main(int argc, char **argv) end: if (need_rand) app_RAND_write_file(NULL); - OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); @@ -949,17 +887,17 @@ int x509_main(int argc, char **argv) EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); EVP_PKEY_free(fkey); - if (sigopts) - sk_OPENSSL_STRING_free(sigopts); + sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); + ASN1_OBJECT_free(objtmp); OPENSSL_free(passin); return (ret); } -static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, +static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile, int create) { char *buf = NULL, *p; @@ -972,15 +910,15 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, : (strlen(serialfile))) + 1; buf = app_malloc(len, "serial# buffer"); if (serialfile == NULL) { - BUF_strlcpy(buf, CAfile, len); + OPENSSL_strlcpy(buf, CAfile, len); for (p = buf; *p; p++) if (*p == '.') { *p = '\0'; break; } - BUF_strlcat(buf, POSTFIX, len); + OPENSSL_strlcat(buf, POSTFIX, len); } else - BUF_strlcpy(buf, serialfile, len); + OPENSSL_strlcpy(buf, serialfile, len); serial = load_serial(buf, create, NULL); if (serial == NULL) @@ -1000,40 +938,42 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, return bs; } -static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, +static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, - char *serialfile, int create, - int days, int clrext, CONF *conf, char *section, + const char *serialfile, int create, + int days, int clrext, CONF *conf, const char *section, ASN1_INTEGER *sno, int reqfile) { int ret = 0; ASN1_INTEGER *bs = NULL; - X509_STORE_CTX xsc; + X509_STORE_CTX *xsc = NULL; EVP_PKEY *upkey; - upkey = X509_get_pubkey(xca); + upkey = X509_get0_pubkey(xca); + if (upkey == NULL) { + BIO_printf(bio_err, "Error obtaining CA X509 public key\n"); + goto end; + } EVP_PKEY_copy_parameters(upkey, pkey); - EVP_PKEY_free(upkey); - if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) { + xsc = X509_STORE_CTX_new(); + if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, x, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } if (sno) bs = sno; - else if (!(bs = x509_load_serial(CAfile, serialfile, create))) + else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL) goto end; -/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/ - /* * NOTE: this certificate can/should be self signed, unless it was a * certificate request in which case it is not. */ - X509_STORE_CTX_set_cert(&xsc, x); - X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); - if (!reqfile && X509_verify_cert(&xsc) <= 0) + X509_STORE_CTX_set_cert(xsc, x); + X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); + if (!reqfile && X509_verify_cert(xsc) <= 0) goto end; if (!X509_check_private_key(xca, pkey)) { @@ -1047,11 +987,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, if (!X509_set_serialNumber(x, bs)) goto end; - if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL) - goto end; - - /* hardwired expired */ - if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL) + if (!set_cert_times(x, NULL, NULL, days)) goto end; if (clrext) { @@ -1061,11 +997,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, if (conf) { X509V3_CTX ctx2; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - X509_set_version(x, force_version); -#else X509_set_version(x, 2); /* version 3 certificate */ -#endif X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); X509V3_set_nconf(&ctx2, conf); if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) @@ -1076,7 +1008,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; ret = 1; end: - X509_STORE_CTX_cleanup(&xsc); + X509_STORE_CTX_free(xsc); if (!ret) ERR_print_errors(bio_err); if (!sno) @@ -1119,18 +1051,13 @@ static int callb(int ok, X509_STORE_CTX *ctx) /* self sign */ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, char *section) + const EVP_MD *digest, CONF *conf, const char *section) { if (!X509_set_issuer_name(x, X509_get_subject_name(x))) goto err; - if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) - goto err; - - if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) == - NULL) + if (!set_cert_times(x, NULL, NULL, days)) goto err; - if (!X509_set_pubkey(x, pkey)) goto err; if (clrext) { @@ -1139,11 +1066,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, } if (conf) { X509V3_CTX ctx; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - X509_set_version(x, force_version); -#else X509_set_version(x, 2); /* version 3 certificate */ -#endif X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); X509V3_set_nconf(&ctx, conf); if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) @@ -1160,7 +1083,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) { int id, i, idret; - char *pname; + const char *pname; id = X509_PURPOSE_get_id(pt); pname = X509_PURPOSE_get0_name(pt); for (i = 0; i < 2; i++) {