/*
* Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* 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 <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 <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
/* Name of config entry that defines the OID file. */
# define ENV_OID_FILE "oid_file"
/* Is |EXACTLY_ONE| of three pointers set? */
# define EXACTLY_ONE(a, b, c) \
(( a && !b && !c) || \
( b && !a && !c) || \
( c && !a && !b))
static ASN1_OBJECT *txt2obj(const char *oid);
static CONF *load_config_file(const char *configfile);
/* Query related functions. */
static int query_command(const char *data, const char *digest,
const EVP_MD *md, const char *policy, int no_nonce,
int cert, const char *in, const char *out, int text);
static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md,
const char *policy, int no_nonce, int cert);
static int create_digest(BIO *input, const char *digest,
const EVP_MD *md, unsigned char **md_value);
static ASN1_INTEGER *create_nonce(int bits);
/* Reply related functions. */
static int reply_command(CONF *conf, const char *section, const char *engine,
const char *queryfile, const char *passin, const char *inkey,
const EVP_MD *md, const char *signer, const char *chain,
const char *policy, const char *in, int token_in,
const char *out, int token_out, int text);
static TS_RESP *read_PKCS7(BIO *in_bio);
static TS_RESP *create_response(CONF *conf, const char *section, const char *engine,
const char *queryfile, const char *passin,
const char *inkey, const EVP_MD *md, const char *signer,
const char *chain, const char *policy);
static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data);
static ASN1_INTEGER *next_serial(const char *serialfile);
static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
/* Verify related functions. */
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 *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 *untrusted,
X509_VERIFY_PARAM *vpm);
static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
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_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
OPT_DIGEST, OPT_RAND, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,