/*
- * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
*/
#include <openssl/opensslconf.h>
-#ifdef OPENSSL_NO_TS
-NON_EMPTY_TRANSLATION_UNIT
-#else
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-# include "apps.h"
-# include "progs.h"
-# include <openssl/bio.h>
-# include <openssl/err.h>
-# include <openssl/pem.h>
-# include <openssl/rand.h>
-# include <openssl/ts.h>
-# include <openssl/bn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include "progs.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ts.h>
+#include <openssl/bn.h>
/* Request nonce length, in bits (must be a multiple of 8). */
-# define NONCE_LENGTH 64
+#define NONCE_LENGTH 64
/* Name of config entry that defines the OID file. */
-# define ENV_OID_FILE "oid_file"
+#define ENV_OID_FILE "oid_file"
/* Is |EXACTLY_ONE| of three pointers set? */
-# define EXACTLY_ONE(a, b, c) \
+#define EXACTLY_ONE(a, b, c) \
(( a && !b && !c) || \
( b && !a && !c) || \
( c && !a && !b))
const char *in, int token_in,
const char *CApath, const char *CAfile,
const char *CAstore,
- const char *untrusted, X509_VERIFY_PARAM *vpm);
+ char *untrusted, X509_VERIFY_PARAM *vpm);
static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
const char *queryfile,
const char *CApath, const char *CAfile,
const char *CAstore,
- const char *untrusted,
+ char *untrusted,
X509_VERIFY_PARAM *vpm);
static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
const char *CAstore, X509_VERIFY_PARAM *vpm);
static int verify_cb(int ok, X509_STORE_CTX *ctx);
typedef enum OPTION_choice {
- OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+ OPT_COMMON,
OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
{"help", OPT_HELP, '-', "Display this summary"},
{"config", OPT_CONFIG, '<', "Configuration file"},
{"section", OPT_SECTION, 's', "Section to use within config file"},
-# ifndef OPENSSL_NO_ENGINE
+#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-# endif
+#endif
{"inkey", OPT_INKEY, 's', "File with private key for reply"},
{"signer", OPT_SIGNER, 's', "Signer certificate file"},
{"chain", OPT_CHAIN, '<', "File with signer CA chain"},
- {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"},
{"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"},
+ {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"},
{"CAstore", OPT_CASTORE, ':', "URI to trusted CA store"},
- {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"},
+ {"untrusted", OPT_UNTRUSTED, '<', "Extra untrusted certs"},
{"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"},
{"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
" [-signer tsa_cert.pem] [-inkey private_key.pem]",
" [-chain certs_file.pem] [-tspolicy oid]",
" [-in file] [-token_in] [-out file] [-token_out]",
-# ifndef OPENSSL_NO_ENGINE
+#ifndef OPENSSL_NO_ENGINE
" [-text] [-engine id]",
-# else
+#else
" [-text]",
-# endif
+#endif
"",
- " openssl ts -verify -CApath dir -CAfile file.pem -CAstore uri",
- " -untrusted file.pem [-data file] [-digest hexstring]",
- " [-queryfile file] -in file [-token_in] ...",
+ " openssl ts -verify -CApath dir -CAfile root-cert.pem -CAstore uri",
+ " -untrusted extra-certs.pem [-data file] [-digest hexstring]",
+ " [-queryfile request.tsq] -in response.tsr [-token_in] ...",
NULL,
};
int ts_main(int argc, char **argv)
{
CONF *conf = NULL;
- const char *CAfile = NULL, *untrusted = NULL, *prog;
+ const char *CAfile = NULL, *prog;
+ char *untrusted = NULL;
const char *configfile = default_config_file, *engine = NULL;
- const char *section = NULL;
+ const char *section = NULL, *digestname = NULL;
char **helpp;
char *password = NULL;
char *data = NULL, *digest = NULL, *policy = NULL;
char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
char *CAstore = NULL;
- const EVP_MD *md = NULL;
+ EVP_MD *md = NULL;
OPTION_CHOICE o, mode = OPT_ERR;
int ret = 1, no_nonce = 0, cert = 0, text = 0;
int vpmtouched = 0;
engine = opt_arg();
break;
case OPT_MD:
- if (!opt_md(opt_unknown(), &md))
- goto opthelp;
+ digestname = opt_unknown();
break;
case OPT_V_CASES:
if (!opt_verify(o, vpm))
break;
}
}
- if (mode == OPT_ERR || opt_num_rest() != 0)
+
+ /* No extra arguments. */
+ argc = opt_num_rest();
+ if (argc != 0 || mode == OPT_ERR)
goto opthelp;
+ if (!app_RAND_load())
+ goto end;
+
+ if (digestname != NULL) {
+ if (!opt_md(digestname, &md))
+ goto opthelp;
+ }
if (mode == OPT_REPLY && passin &&
!app_passwd(passin, NULL, &password, NULL)) {
BIO_printf(bio_err, "Error getting password.\n");
end:
X509_VERIFY_PARAM_free(vpm);
+ EVP_MD_free(md);
NCONF_free(conf);
OPENSSL_free(password);
return ret;
goto err;
if ((algo = X509_ALGOR_new()) == NULL)
goto err;
- if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
+ if ((algo->algorithm = OBJ_nid2obj(EVP_MD_get_type(md))) == NULL)
goto err;
if ((algo->parameter = ASN1_TYPE_new()) == NULL)
goto err;
int rv = 0;
EVP_MD_CTX *md_ctx = NULL;
- md_value_len = EVP_MD_size(md);
+ md_value_len = EVP_MD_get_size(md);
if (md_value_len < 0)
return 0;
}
if (!EVP_DigestFinal(md_ctx, *md_value, NULL))
goto err;
- md_value_len = EVP_MD_size(md);
+ md_value_len = EVP_MD_get_size(md);
} else {
long digest_len;
goto end;
if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
goto end;
-# ifndef OPENSSL_NO_ENGINE
+#ifndef OPENSSL_NO_ENGINE
if (!TS_CONF_set_crypto_device(conf, section, engine))
goto end;
-# endif
+#endif
if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
goto end;
if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
static int verify_command(const char *data, const char *digest, const char *queryfile,
const char *in, int token_in,
const char *CApath, const char *CAfile,
- const char *CAstore, const char *untrusted,
+ const char *CAstore, char *untrusted,
X509_VERIFY_PARAM *vpm)
{
BIO *in_bio = NULL;
const char *queryfile,
const char *CApath, const char *CAfile,
const char *CAstore,
- const char *untrusted,
+ char *untrusted,
X509_VERIFY_PARAM *vpm)
{
TS_VERIFY_CTX *ctx = NULL;
+ STACK_OF(X509) *certs;
BIO *input = NULL;
TS_REQ *request = NULL;
int ret = 0;
== NULL)
goto err;
- /* Loading untrusted certificates. */
- if (untrusted
- && TS_VERIFY_CTX_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL)
- goto err;
+ /* Loading any extra untrusted certificates. */
+ if (untrusted != NULL) {
+ certs = load_certs_multifile(untrusted, NULL, "extra untrusted certs",
+ vpm);
+ if (certs == NULL || TS_VERIFY_CTX_set_certs(ctx, certs) == NULL)
+ goto err;
+ }
ret = 1;
err:
{
X509_STORE *cert_ctx = NULL;
X509_LOOKUP *lookup = NULL;
+ OSSL_LIB_CTX *libctx = app_get0_libctx();
+ const char *propq = app_get0_propq();
cert_ctx = X509_STORE_new();
X509_STORE_set_verify_cb(cert_ctx, verify_cb);
BIO_printf(bio_err, "memory allocation failure\n");
goto err;
}
- if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
+ if (!X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM, libctx,
+ propq)) {
BIO_printf(bio_err, "Error loading file %s\n", CAfile);
goto err;
}
BIO_printf(bio_err, "memory allocation failure\n");
goto err;
}
- if (!X509_LOOKUP_load_store(lookup, CAstore)) {
+ if (!X509_LOOKUP_load_store_ex(lookup, CAstore, libctx, propq)) {
BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
goto err;
}
{
return ok;
}
-#endif /* ndef OPENSSL_NO_TS */