74 #define NONCE_LENGTH 64
77 #define ENV_OID_FILE "oid_file"
82 static CONF *load_config_file(
const char *configfile);
85 static int query_command(
const char *
data,
char *digest,
86 const EVP_MD *md,
const char *policy,
int no_nonce,
87 int cert,
const char *in,
const char *out,
int text);
88 static BIO *BIO_open_with_default(
const char *
file,
const char *mode,
90 static TS_REQ *create_query(
BIO *data_bio,
char *digest,
const EVP_MD *md,
91 const char *policy,
int no_nonce,
int cert);
92 static int create_digest(
BIO *input,
char *digest,
93 const EVP_MD *md,
unsigned char **md_value);
97 static int reply_command(
CONF *conf,
char *section,
char *engine,
98 char *queryfile,
char *passin,
char *inkey,
99 char *signer,
char *chain,
const char *policy,
100 char *in,
int token_in,
char *out,
int token_out,
103 static TS_RESP *create_response(
CONF *conf,
const char *section,
char *engine,
104 char *queryfile,
char *passin,
char *inkey,
105 char *signer,
char *chain,
const char *policy);
107 static ASN1_INTEGER *next_serial(
const char *serialfile);
108 static int save_ts_serial(
const char *serialfile,
ASN1_INTEGER *serial);
111 static int verify_command(
char *
data,
char *digest,
char *queryfile,
112 char *in,
int token_in,
113 char *ca_path,
char *ca_file,
char *untrusted);
116 char *ca_path,
char *ca_file,
118 static X509_STORE *create_cert_store(
char *ca_path,
char *ca_file);
122 int MAIN(
int,
char **);
124 int MAIN(
int argc,
char **argv)
127 char *configfile = NULL;
131 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
143 char *queryfile = NULL;
145 char *password =NULL;
149 char *ca_path = NULL;
150 char *ca_file = NULL;
151 char *untrusted = NULL;
157 int free_bio_err = 0;
171 for (argc--, argv++; argc > 0; argc--, argv++)
173 if (strcmp(*argv,
"-config") == 0)
175 if (argc-- < 1)
goto usage;
176 configfile = *++argv;
178 else if (strcmp(*argv,
"-section") == 0)
180 if (argc-- < 1)
goto usage;
183 else if (strcmp(*argv,
"-query") == 0)
185 if (mode != CMD_NONE)
goto usage;
188 else if (strcmp(*argv,
"-data") == 0)
190 if (argc-- < 1)
goto usage;
193 else if (strcmp(*argv,
"-digest") == 0)
195 if (argc-- < 1)
goto usage;
198 else if (strcmp(*argv,
"-rand") == 0)
200 if (argc-- < 1)
goto usage;
203 else if (strcmp(*argv,
"-policy") == 0)
205 if (argc-- < 1)
goto usage;
208 else if (strcmp(*argv,
"-no_nonce") == 0)
212 else if (strcmp(*argv,
"-cert") == 0)
216 else if (strcmp(*argv,
"-in") == 0)
218 if (argc-- < 1)
goto usage;
221 else if (strcmp(*argv,
"-token_in") == 0)
225 else if (strcmp(*argv,
"-out") == 0)
227 if (argc-- < 1)
goto usage;
230 else if (strcmp(*argv,
"-token_out") == 0)
234 else if (strcmp(*argv,
"-text") == 0)
238 else if (strcmp(*argv,
"-reply") == 0)
240 if (mode != CMD_NONE)
goto usage;
243 else if (strcmp(*argv,
"-queryfile") == 0)
245 if (argc-- < 1)
goto usage;
248 else if (strcmp(*argv,
"-passin") == 0)
250 if (argc-- < 1)
goto usage;
253 else if (strcmp(*argv,
"-inkey") == 0)
255 if (argc-- < 1)
goto usage;
258 else if (strcmp(*argv,
"-signer") == 0)
260 if (argc-- < 1)
goto usage;
263 else if (strcmp(*argv,
"-chain") == 0)
265 if (argc-- < 1)
goto usage;
268 else if (strcmp(*argv,
"-verify") == 0)
270 if (mode != CMD_NONE)
goto usage;
273 else if (strcmp(*argv,
"-CApath") == 0)
275 if (argc-- < 1)
goto usage;
278 else if (strcmp(*argv,
"-CAfile") == 0)
280 if (argc-- < 1)
goto usage;
283 else if (strcmp(*argv,
"-untrusted") == 0)
285 if (argc-- < 1)
goto usage;
288 else if (strcmp(*argv,
"-engine") == 0)
290 if (argc-- < 1)
goto usage;
302 if (mode == CMD_QUERY && !no_nonce)
306 "data, consider using the -rand option\n");
313 if(mode == CMD_REPLY && passin &&
329 ret = data != NULL && digest != NULL;
332 conf = load_config_file(configfile);
333 ret = !query_command(data, digest, md, policy, no_nonce, cert,
337 conf = load_config_file(configfile);
340 ret = !(queryfile != NULL && conf != NULL && !token_in);
346 ret = !(queryfile == NULL);
350 ret = !reply_command(conf, section, engine, queryfile,
351 password, inkey, signer, chain, policy,
352 in, token_in, out, token_out, text);
355 ret = !(((queryfile && !data && !digest)
356 || (!queryfile && data && !digest)
357 || (!queryfile && !data && digest))
361 ret = !verify_command(data, digest, queryfile, in, token_in,
362 ca_path, ca_file, untrusted);
369 "ts -query [-rand file%cfile%c...] [-config configfile] "
370 "[-data file_to_hash] [-digest digest_bytes]"
371 "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
372 "[-policy object_id] [-no_nonce] [-cert] "
373 "[-in request.tsq] [-out request.tsq] [-text]\n",
376 "ts -reply [-config configfile] [-section tsa_section] "
377 "[-queryfile request.tsq] [-passin password] "
378 "[-signer tsa_cert.pem] [-inkey private_key.pem] "
379 "[-chain certs_file.pem] [-policy object_id] "
380 "[-in response.tsr] [-token_in] "
381 "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
383 "ts -verify [-data file_to_hash] [-digest digest_bytes] "
384 "[-queryfile request.tsq] "
385 "-in response.tsr [-token_in] "
386 "-CApath ca_path -CAfile ca_file.pem "
387 "-untrusted cert_file.pem\n");
417 static CONF *load_config_file(
const char *configfile)
422 if (!configfile) configfile = getenv(
"OPENSSL_CONF");
423 if (!configfile) configfile = getenv(
"SSLEAY_CONF");
427 NCONF_load(conf, configfile, &errorline) <= 0))
431 "'%s'\n", configfile);
434 "'%s'\n", errorline, configfile);
466 static int query_command(
const char *data,
char *digest,
const EVP_MD *md,
467 const char *policy,
int no_nonce,
468 int cert,
const char *in,
const char *out,
int text)
473 BIO *data_bio = NULL;
479 if ((in_bio =
BIO_new_file(in,
"rb")) == NULL)
goto end;
486 && !(data_bio = BIO_open_with_default(data,
"rb", stdin)))
489 query = create_query(data_bio, digest, md,
490 policy, no_nonce, cert);
493 if (query == NULL)
goto end;
496 if ((out_bio = BIO_open_with_default(out,
"wb", stdout)) == NULL)
525 static BIO *BIO_open_with_default(
const char *
file,
const char *mode,
528 return file == NULL ?
533 static TS_REQ *create_query(
BIO *data_bio,
char *digest,
const EVP_MD *md,
534 const char *policy,
int no_nonce,
int cert)
541 unsigned char *data = NULL;
558 if (!(algo = X509_ALGOR_new()))
goto err;
560 if (!(algo->
parameter = ASN1_TYPE_new()))
goto err;
565 if ((len = create_digest(data_bio, digest, md, &data)) == 0)
572 if (policy && !(policy_obj = txt2obj(policy)))
goto err;
576 if (!no_nonce && !(nonce_asn1 = create_nonce(
NONCE_LENGTH)))
goto err;
591 X509_ALGOR_free(algo);
594 ASN1_INTEGER_free(nonce_asn1);
598 static int create_digest(
BIO *input,
char *digest,
const EVP_MD *md,
599 unsigned char **md_value)
604 if (md_value_len < 0)
610 unsigned char buffer[4096];
614 if (*md_value == 0)
goto err;
617 while ((length =
BIO_read(input, buffer,
sizeof(buffer))) > 0)
628 if (!*md_value || md_value_len != digest_len)
633 "must be specified\n", md_value_len);
645 unsigned char buf[20];
647 int len = (bits - 1) / 8 + 1;
651 if (len > (
int)
sizeof(buf))
goto err;
655 for (i = 0; i < len && !buf[i]; ++i);
656 if (!(nonce = ASN1_INTEGER_new()))
goto err;
666 ASN1_INTEGER_free(nonce);
673 static int reply_command(
CONF *conf,
char *section,
char *engine,
674 char *queryfile,
char *passin,
char *inkey,
675 char *signer,
char *chain,
const char *policy,
676 char *in,
int token_in,
677 char *out,
int token_out,
int text)
682 BIO *query_bio = NULL;
683 BIO *inkey_bio = NULL;
684 BIO *signer_bio = NULL;
690 if ((in_bio =
BIO_new_file(in,
"rb")) == NULL)
goto end;
695 response = read_PKCS7(in_bio);
705 response = create_response(conf, section, engine, queryfile,
706 passin, inkey, signer, chain,
713 if (response == NULL)
goto end;
716 if ((out_bio = BIO_open_with_default(out,
"wb", stdout)) == NULL)
800 static TS_RESP *create_response(
CONF *conf,
const char *section,
char *engine,
801 char *queryfile,
char *passin,
char *inkey,
802 char *signer,
char *chain,
const char *policy)
806 BIO *query_bio = NULL;
821 #ifndef OPENSSL_NO_ENGINE
880 const char *serial_file = (
const char *) data;
886 "Error during serial number "
892 save_ts_serial(serial_file, serial);
897 static ASN1_INTEGER *next_serial(
const char *serialfile)
904 if (!(serial = ASN1_INTEGER_new()))
goto err;
910 "reading, using serial number: 1\n", serialfile);
923 ASN1_INTEGER_free(serial);
932 ASN1_INTEGER_free(serial);
940 static int save_ts_serial(
const char *serialfile,
ASN1_INTEGER *serial)
947 if (
BIO_puts(out,
"\n") <= 0)
goto err;
961 static int verify_command(
char *data,
char *digest,
char *queryfile,
962 char *in,
int token_in,
963 char *ca_path,
char *ca_file,
char *untrusted)
982 if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
983 ca_path, ca_file, untrusted)))
992 printf(
"Verification: ");
1010 static TS_VERIFY_CTX *create_verify_ctx(
char *data,
char *digest,
1012 char *ca_path,
char *ca_file,
1020 if (data != NULL || digest != NULL)
1029 else if (digest != NULL)
1043 else if (queryfile != NULL)
1047 if (!(input =
BIO_new_file(queryfile,
"rb")))
goto err;
1058 if (!(ctx->
store = create_cert_store(ca_path, ca_file)))
goto err;
1061 if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
1076 static X509_STORE *create_cert_store(
char *ca_path,
char *ca_file)