Hello,
I am attaching patch that introduces new parameter "signing_digest" to
the TSA section of OpenSSL configuration file. This parameter allows
user to set digest algorithm used for TS response signing. Instead of
previous default signature SHA1withRSA it is now possible to create TS
responses signed with SHA256RSA, SHA512RSA etc. I also updated
documentation and command line utility in apps directory to take the
advantage to of this new feature.
Patch was tested against "openssl-1.0.0-beta4.tar.gz" and builds also
against latest snapshot "openssl-1.0.0-stable-SNAP-20100117.tar.gz".
Feel free to include it in the upstream version if you find it useful.
Kind regards
--
Jaroslav Imrich
Disig, a.s.
Zahradnicka 151, 821 08 Bratislava 2
tel. +421 905 286 140
[email protected]
www.disig.sk
diff -ur openssl-1.0.0-beta4/apps/openssl.cnf
openssl-1.0.0-beta4-modified/apps/openssl.cnf
--- openssl-1.0.0-beta4/apps/openssl.cnf 2009-04-04 20:09:43.000000000
+0200
+++ openssl-1.0.0-beta4-modified/apps/openssl.cnf 2010-01-08
10:38:18.000000000 +0100
@@ -336,6 +336,8 @@
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+signing_digest = sha1 # Signing digest to use. (Optional)
+
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
diff -ur openssl-1.0.0-beta4/apps/ts.c openssl-1.0.0-beta4-modified/apps/ts.c
--- openssl-1.0.0-beta4/apps/ts.c 2009-10-18 16:42:26.000000000 +0200
+++ openssl-1.0.0-beta4-modified/apps/ts.c 2010-01-08 10:28:22.000000000
+0100
@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -83,9 +83,9 @@
/* Query related functions. */
static int query_command(const char *data, char *digest,
- const EVP_MD *md, const char *policy, int no_nonce,
+ const EVP_MD *md, const char *policy, int no_nonce,
int cert, const char *in, const char *out, int text);
-static BIO *BIO_open_with_default(const char *file, const char *mode,
+static BIO *BIO_open_with_default(const char *file, const char *mode,
FILE *default_fp);
static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
const char *policy, int no_nonce, int cert);
@@ -94,14 +94,14 @@
static ASN1_INTEGER *create_nonce(int bits);
/* Reply related functions. */
-static int reply_command(CONF *conf, char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy,
+static int reply_command(CONF *conf, char *section, char *engine,
+ char *queryfile, char *passin, char *inkey, const char
*md,
+ char *signer, char *chain, const char *policy,
char *in, int token_in, 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, char *engine,
- char *queryfile, char *passin, char *inkey,
+ char *queryfile, char *passin, char *inkey,
const char *md,
char *signer, char *chain, const char *policy);
static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
static ASN1_INTEGER *next_serial(const char *serialfile);
@@ -111,8 +111,8 @@
static int verify_command(char *data, char *digest, char *queryfile,
char *in, int token_in,
char *ca_path, char *ca_file, char *untrusted);
-static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
- char *queryfile,
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
+ char *queryfile,
char *ca_path, char *ca_file,
char *untrusted);
static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
@@ -128,11 +128,12 @@
char *section = NULL;
CONF *conf = NULL;
enum mode {
- CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
+ CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
} mode = CMD_NONE;
char *data = NULL;
char *digest = NULL;
const EVP_MD *md = NULL;
+ char *sign_digest = NULL;
char *rnd = NULL;
char *policy = NULL;
int no_nonce = 0;
@@ -151,7 +152,7 @@
char *untrusted = NULL;
char *engine = NULL;
/* Input is ContentInfo instead of TimeStampResp. */
- int token_in = 0;
+ int token_in = 0;
/* Output is ContentInfo instead of TimeStampResp. */
int token_out = 0;
int free_bio_err = 0;
@@ -292,12 +293,12 @@
}
else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
{
- /* empty. */
+ sign_digest = *argv + 1;
}
else
goto usage;
}
-
+
/* Seed the random number generator if it is going to be used. */
if (mode == CMD_QUERY && !no_nonce)
{
@@ -317,7 +318,7 @@
goto cleanup;
}
- /* Check consistency of parameters and execute
+ /* Check consistency of parameters and execute
the appropriate function. */
switch (mode)
{
@@ -337,7 +338,7 @@
conf = load_config_file(configfile);
if (in == NULL)
{
- ret = !(queryfile != NULL && conf != NULL && !token_in);
+ ret = !(queryfile != NULL && conf != NULL && !token_in);
if (ret) goto usage;
}
else
@@ -347,8 +348,8 @@
if (ret) goto usage;
}
- ret = !reply_command(conf, section, engine, queryfile,
- password, inkey, signer, chain, policy,
+ ret = !reply_command(conf, section, engine, queryfile,
+ password, inkey, sign_digest, signer,
chain, policy,
in, token_in, out, token_out, text);
break;
case CMD_VERIFY:
@@ -367,7 +368,7 @@
usage:
BIO_printf(bio_err, "usage:\n"
"ts -query [-rand file%cfile%c...] [-config configfile] "
- "[-data file_to_hash] [-digest digest_bytes]"
+ "[-data file_to_hash] [-digest digest_bytes] "
"[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
"[-policy object_id] [-no_nonce] [-cert] "
"[-in request.tsq] [-out request.tsq] [-text]\n",
@@ -376,6 +377,7 @@
"ts -reply [-config configfile] [-section tsa_section] "
"[-queryfile request.tsq] [-passin password] "
"[-signer tsa_cert.pem] [-inkey private_key.pem] "
+ "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
"[-chain certs_file.pem] [-policy object_id] "
"[-in response.tsr] [-token_in] "
"[-out response.tsr] [-token_out] [-text] [-engine id]\n");
@@ -443,7 +445,7 @@
if (p != NULL)
{
BIO *oid_bio = BIO_new_file(p, "r");
- if (!oid_bio)
+ if (!oid_bio)
ERR_print_errors(bio_err);
else
{
@@ -453,7 +455,7 @@
}
else
ERR_clear_error();
- if(!add_oid_section(bio_err, conf))
+ if(!add_oid_section(bio_err, conf))
ERR_print_errors(bio_err);
}
return conf;
@@ -464,7 +466,7 @@
*/
static int query_command(const char *data, char *digest, const EVP_MD *md,
- const char *policy, int no_nonce,
+ const char *policy, int no_nonce,
int cert, const char *in, const char *out, int text)
{
int ret = 0;
@@ -482,7 +484,7 @@
else
{
/* Open the file if no explicit digest bytes were specified. */
- if (!digest
+ if (!digest
&& !(data_bio = BIO_open_with_default(data, "rb", stdin)))
goto end;
/* Creating the query object. */
@@ -522,11 +524,11 @@
return ret;
}
-static BIO *BIO_open_with_default(const char *file, const char *mode,
+static BIO *BIO_open_with_default(const char *file, const char *mode,
FILE *default_fp)
{
- return file == NULL ?
- BIO_new_fp(default_fp, BIO_NOCLOSE)
+ return file == NULL ?
+ BIO_new_fp(default_fp, BIO_NOCLOSE)
: BIO_new_file(file, mode);
}
@@ -567,7 +569,7 @@
if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
-
+
/* Setting policy if requested. */
if (policy && !(policy_obj = txt2obj(policy))) goto err;
if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
@@ -670,9 +672,9 @@
* Reply-related method definitions.
*/
-static int reply_command(CONF *conf, char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
- char *signer, char *chain, const char *policy,
+static int reply_command(CONF *conf, char *section, char *engine,
+ char *queryfile, char *passin, char *inkey, const char
*md,
+ char *signer, char *chain, const char *policy,
char *in, int token_in,
char *out, int token_out, int text)
{
@@ -703,7 +705,7 @@
else
{
response = create_response(conf, section, engine, queryfile,
- passin, inkey, signer, chain,
+ passin, inkey, md, signer, chain,
policy);
if (response)
BIO_printf(bio_err, "Response has been generated.\n");
@@ -797,8 +799,8 @@
return resp;
}
-static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
- char *queryfile, char *passin, char *inkey,
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
+ char *queryfile, char *passin, char *inkey,
const char *md,
char *signer, char *chain, const char *policy)
{
int ret = 0;
@@ -833,6 +835,10 @@
if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
goto end;
+ /* Setting signing digest */
+ if (!TS_CONF_set_signing_digest(conf, section, md, resp_ctx))
+ goto end;
+
/* Setting default policy OID. */
if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
@@ -864,7 +870,7 @@
ret = 1;
end:
- if (!ret)
+ if (!ret)
{
TS_RESP_free(response);
response = NULL;
@@ -903,7 +909,7 @@
if (!(serial = ASN1_INTEGER_new())) goto err;
- if (!(in = BIO_new_file(serialfile, "r")))
+ if (!(in = BIO_new_file(serialfile, "r")))
{
ERR_clear_error();
BIO_printf(bio_err, "Warning: could not open file %s for "
@@ -979,7 +985,7 @@
if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
}
- if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
+ if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
ca_path, ca_file, untrusted)))
goto end;
@@ -998,7 +1004,7 @@
/* Print errors, if there are any. */
ERR_print_errors(bio_err);
}
-
+
/* Clean up. */
BIO_free_all(in_bio);
PKCS7_free(token);
@@ -1007,8 +1013,8 @@
return ret;
}
-static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
- char *queryfile,
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
+ char *queryfile,
char *ca_path, char *ca_file,
char *untrusted)
{
@@ -1038,7 +1044,7 @@
}
ctx->imprint_len = imprint_len;
}
-
+
}
else if (queryfile != NULL)
{
@@ -1058,7 +1064,7 @@
if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
/* Loading untrusted certificates. */
- if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
+ if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
goto err;
ret = 1;
diff -ur openssl-1.0.0-beta4/crypto/ts/ts_conf.c
openssl-1.0.0-beta4-modified/crypto/ts/ts_conf.c
--- openssl-1.0.0-beta4/crypto/ts/ts_conf.c 2008-12-20 18:04:39.000000000
+0100
+++ openssl-1.0.0-beta4-modified/crypto/ts/ts_conf.c 2010-01-08
12:51:51.000000000 +0100
@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -75,6 +75,7 @@
#define ENV_SIGNER_CERT "signer_cert"
#define ENV_CERTS "certs"
#define ENV_SIGNER_KEY "signer_key"
+#define ENV_SIGNING_DIGEST "signing_digest"
#define ENV_DEFAULT_POLICY "default_policy"
#define ENV_OTHER_POLICIES "other_policies"
#define ENV_DIGESTS "digests"
@@ -85,7 +86,7 @@
#define ENV_VALUE_SECS "secs"
#define ENV_VALUE_MILLISECS "millisecs"
#define ENV_VALUE_MICROSECS "microsecs"
-#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits"
+#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits"
#define ENV_VALUE_YES "yes"
#define ENV_VALUE_NO "no"
@@ -193,7 +194,7 @@
const char *device)
{
int ret = 0;
-
+
if (!device)
device = NCONF_get_string(conf, section,
ENV_CRYPTO_DEVICE);
@@ -218,7 +219,7 @@
if (!(e = ENGINE_by_id(name))) goto err;
/* Enable the use of the NCipher HSM for forked children. */
- if (strcmp(name, "chil") == 0)
+ if (strcmp(name, "chil") == 0)
ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
/* All the operations are going to be carried out by the engine. */
if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
@@ -226,7 +227,7 @@
err:
if (!ret)
{
- TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE,
+ TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE,
TS_R_COULD_NOT_SET_ENGINE);
ERR_add_error_data(2, "engine:", name);
}
@@ -241,7 +242,7 @@
{
int ret = 0;
X509 *cert_obj = NULL;
- if (!cert)
+ if (!cert)
cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
if (!cert)
{
@@ -264,7 +265,7 @@
{
int ret = 0;
STACK_OF(X509) *certs_obj = NULL;
- if (!certs)
+ if (!certs)
certs = NCONF_get_string(conf, section, ENV_CERTS);
/* Certificate chain is optional. */
if (!certs) goto end;
@@ -283,7 +284,7 @@
{
int ret = 0;
EVP_PKEY *key_obj = NULL;
- if (!key)
+ if (!key)
key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
if (!key)
{
@@ -299,13 +300,38 @@
return ret;
}
+int TS_CONF_set_signing_digest(CONF *conf, const char *section,
+ const char *md, TS_RESP_CTX *ctx)
+ {
+ int ret = 0;
+ const EVP_MD *sign_md = NULL;
+ if (!md)
+ md = NCONF_get_string(conf, section, ENV_SIGNING_DIGEST);
+ if (!md)
+ {
+ TS_CONF_lookup_fail(section, ENV_SIGNING_DIGEST);
+ goto err;
+ }
+ if (!(sign_md = (EVP_MD *) EVP_get_digestbyname(md)))
+ {
+ TS_CONF_invalid(section, ENV_SIGNING_DIGEST);
+ goto err;
+ }
+ if (!TS_RESP_CTX_set_signing_digest(ctx, sign_md))
+ goto err;
+
+ ret = 1;
+ err:
+ return ret;
+ }
+
int TS_CONF_set_def_policy(CONF *conf, const char *section,
const char *policy, TS_RESP_CTX *ctx)
{
int ret = 0;
ASN1_OBJECT *policy_obj = NULL;
- if (!policy)
- policy = NCONF_get_string(conf, section,
+ if (!policy)
+ policy = NCONF_get_string(conf, section,
ENV_DEFAULT_POLICY);
if (!policy)
{
@@ -332,7 +358,7 @@
int ret = 0;
int i;
STACK_OF(CONF_VALUE) *list = NULL;
- char *policies = NCONF_get_string(conf, section,
+ char *policies = NCONF_get_string(conf, section,
ENV_OTHER_POLICIES);
/* If no other policy is specified, that's fine. */
if (policies && !(list = X509V3_parse_list(policies)))
@@ -419,7 +445,7 @@
for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
{
CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
- if (strcmp(val->name, ENV_VALUE_SECS) == 0)
+ if (strcmp(val->name, ENV_VALUE_SECS) == 0)
{
if (val->value) secs = atoi(val->value);
}
@@ -451,7 +477,7 @@
{
int ret = 0;
long digits = 0;
-
+
/* If not specified, set the default value to 0, i.e. sec precision */
if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
&digits))
@@ -502,6 +528,6 @@
int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
TS_RESP_CTX *ctx)
{
- return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
+ return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
TS_ESS_CERT_ID_CHAIN, ctx);
}
diff -ur openssl-1.0.0-beta4/crypto/ts/ts.h
openssl-1.0.0-beta4-modified/crypto/ts/ts.h
--- openssl-1.0.0-beta4/crypto/ts/ts.h 2008-11-12 04:58:06.000000000 +0100
+++ openssl-1.0.0-beta4-modified/crypto/ts/ts.h 2010-01-08 11:10:12.000000000
+0100
@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -181,7 +181,7 @@
ASN1_INTEGER *nonce;
GENERAL_NAME *tsa;
STACK_OF(X509_EXTENSION) *extensions;
- } TS_TST_INFO;
+ } TS_TST_INFO;
/*
PKIStatusInfo ::= SEQUENCE {
@@ -324,7 +324,7 @@
TS_STATUS_INFO *TS_STATUS_INFO_new(void);
void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
-TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
+TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
const unsigned char **pp, long length);
TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
@@ -364,7 +364,7 @@
ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
-int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a,
+int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a,
unsigned char **pp);
ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
const unsigned char **pp, long length);
@@ -489,13 +489,13 @@
typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
/* This must return the seconds and microseconds since Jan 1, 1970 in
- the sec and usec variables allocated by the caller.
+ the sec and usec variables allocated by the caller.
Return non-zero for success and zero for failure. */
typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long
*usec);
/* This must process the given extension.
* It can modify the TS_TST_INFO object of the context.
- * Return values: !0 (processed), 0 (error, it must set the
+ * Return values: !0 (processed), 0 (error, it must set the
* status info/failure info of the response).
*/
typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *,
void *);
@@ -504,6 +504,7 @@
{
X509 *signer_cert;
EVP_PKEY *signer_key;
+ const EVP_MD *signing_digest;
STACK_OF(X509) *certs; /* Certs to include in signed data. */
STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
@@ -518,10 +519,10 @@
/* Callback functions. */
TS_serial_cb serial_cb;
void *serial_cb_data; /* User data for serial_cb. */
-
+
TS_time_cb time_cb;
void *time_cb_data; /* User data for time_cb. */
-
+
TS_extension_cb extension_cb;
void *extension_cb_data; /* User data for extension_cb. */
@@ -545,16 +546,19 @@
int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
/* This parameter must be set. */
+int TS_RESP_CTX_set_signing_digest(TS_RESP_CTX *ctx, const EVP_MD
*signing_digest);
+
+/* This parameter must be set. */
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
/* No additional certs are included in the response by default. */
int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
-/* Adds a new acceptable policy, only the default policy
+/* Adds a new acceptable policy, only the default policy
is accepted by default. */
int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
-/* Adds a new acceptable message digest. Note that no message digests
+/* Adds a new acceptable message digest. Note that no message digests
are accepted by default. The md argument is shared with the caller. */
int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
@@ -562,11 +566,11 @@
int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
int secs, int millis, int micros);
-/* Clock precision digits, i.e. the number of decimal digits:
- '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */
+/* Clock precision digits, i.e. the number of decimal digits:
+ '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */
int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
unsigned clock_precision_digits);
-/* At most we accept usec precision. */
+/* At most we accept usec precision. */
#define TS_MAX_CLOCK_PRECISION_DIGITS 6
/* No flags are set by default. */
@@ -578,18 +582,18 @@
/* Default callback uses the gettimeofday() and gmtime() system calls. */
void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
-/* Default callback rejects all extensions. The extension callback is called
+/* Default callback rejects all extensions. The extension callback is called
* when the TS_TST_INFO object is already set up and not signed yet. */
/* FIXME: extension handling is not tested yet. */
-void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
TS_extension_cb cb, void *data);
/* The following methods can be used in the callbacks. */
-int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
int status, const char *text);
/* Sets the status info only if it is still TS_STATUS_GRANTED. */
-int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
int status, const char *text);
int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
@@ -599,7 +603,7 @@
TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
-/*
+/*
* Creates the signed TS_TST_INFO and puts it in TS_RESP.
* In case of errors it sets the status info properly.
* Returns NULL only in case of memory allocation/fatal error.
@@ -664,7 +668,7 @@
/* Must be set only with TS_VFY_POLICY. */
ASN1_OBJECT *policy;
- /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL,
+ /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL,
the algorithm from the response is used. */
X509_ALGOR *md_alg;
unsigned char *imprint;
@@ -694,7 +698,7 @@
void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
-/*
+/*
* If ctx is NULL, it allocates and returns a new object, otherwise
* it returns ctx. It initialises all the members as follows:
* flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
@@ -744,6 +748,8 @@
TS_RESP_CTX *ctx);
int TS_CONF_set_signer_key(CONF *conf, const char *section,
const char *key, const char *pass, TS_RESP_CTX *ctx);
+int TS_CONF_set_signing_digest(CONF *conf, const char *section,
+ const char *md, TS_RESP_CTX *ctx);
int TS_CONF_set_def_policy(CONF *conf, const char *section,
const char *policy, TS_RESP_CTX *ctx);
int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
diff -ur openssl-1.0.0-beta4/crypto/ts/ts_rsp_sign.c
openssl-1.0.0-beta4-modified/crypto/ts/ts_rsp_sign.c
--- openssl-1.0.0-beta4/crypto/ts/ts_rsp_sign.c 2006-03-19 22:09:48.000000000
+0100
+++ openssl-1.0.0-beta4-modified/crypto/ts/ts_rsp_sign.c 2010-01-08
11:11:43.000000000 +0100
@@ -221,6 +221,16 @@
return 1;
}
+int TS_RESP_CTX_set_signing_digest(TS_RESP_CTX *ctx, const EVP_MD
*signing_digest)
+ {
+ if (signing_digest == NULL)
+ {
+ return 0;
+ }
+ ctx->signing_digest = signing_digest;
+ return 1;
+ }
+
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
{
if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
@@ -749,7 +759,7 @@
/* Add a new signer info. */
if (!(si = PKCS7_add_signature(p7, ctx->signer_cert,
- ctx->signer_key, EVP_sha1())))
+ ctx->signer_key, ctx->signing_digest)))
{
TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
goto err;
diff -ur openssl-1.0.0-beta4/doc/apps/ts.pod
openssl-1.0.0-beta4-modified/doc/apps/ts.pod
--- openssl-1.0.0-beta4/doc/apps/ts.pod 2009-04-10 13:25:54.000000000 +0200
+++ openssl-1.0.0-beta4-modified/doc/apps/ts.pod 2010-01-08
13:58:22.000000000 +0100
@@ -28,6 +28,7 @@
[B<-passin> password_src]
[B<-signer> tsa_cert.pem]
[B<-inkey> private.pem]
+[B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>]
[B<-chain> certs_file.pem]
[B<-policy> object_id]
[B<-in> response.tsr]
@@ -121,7 +122,7 @@
It is possible to specify the message imprint explicitly without the data
file. The imprint must be specified in a hexadecimal format, two characters
per byte, the bytes optionally separated by colons (e.g. 1A:F6:01:... or
-1AF601...). The number of bytes must match the message digest algorithm
+1AF601...). The number of bytes must match the message digest algorithm
in use. (Optional)
=item B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>
@@ -215,6 +216,11 @@
The signer private key of the TSA in PEM format. Overrides the
B<signer_key> config file option. (Optional)
+=item B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>
+
+Signing digest to use. Overrides the B<signing_digest> config file
+option. (Optional)
+
=item B<-chain> certs_file.pem
The collection of certificates in PEM format that will all
@@ -283,7 +289,7 @@
=item B<-data> file_to_hash
The response or token must be verified against file_to_hash. The file
-is hashed with the message digest algorithm specified in the token.
+is hashed with the message digest algorithm specified in the token.
The B<-digest> and B<-queryfile> options must not be specified with this one.
(Optional)
@@ -318,9 +324,9 @@
=item B<-CAfile> trusted_certs.pem
-The name of the file containing a set of trusted self-signed CA
-certificates in PEM format. See the similar option of
-L<verify(1)|verify(1)> for additional details. Either this option
+The name of the file containing a set of trusted self-signed CA
+certificates in PEM format. See the similar option of
+L<verify(1)|verify(1)> for additional details. Either this option
or B<-CApath> must be specified.
(Optional)
@@ -348,7 +354,7 @@
=over 4
-=item B<tsa> section, B<default_tsa>
+=item B<tsa> section, B<default_tsa>
This is the main section and it specifies the name of another section
that contains all the options for the B<-reply> command. This default
@@ -375,8 +381,8 @@
=item B<crypto_device>
-Specifies the OpenSSL engine that will be set as the default for
-all available algorithms. The default value is builtin, you can specify
+Specifies the OpenSSL engine that will be set as the default for
+all available algorithms. The default value is builtin, you can specify
any other engines supported by OpenSSL (e.g. use chil for the NCipher HSM).
(Optional)
@@ -396,6 +402,12 @@
The private key of the TSA in PEM format. The same as the B<-inkey>
command line option. (Optional)
+=item B<signing_digest>
+
+Signing digest to use. The same as the
+B<-md2>|B<-md4>|B<-md5>|B<-sha>|B<-sha1>|B<-mdc2>|B<-ripemd160>|B<...>
+command line option. (Optional)
+
=item B<default_policy>
The default policy to use when the request does not mandate any
@@ -419,7 +431,7 @@
=item B<clock_precision_digits>
-Specifies the maximum number of digits, which represent the fraction of
+Specifies the maximum number of digits, which represent the fraction of
seconds, that need to be included in the time field. The trailing zeroes
must be removed from the time, so there might actually be fewer digits,
or no fraction of seconds at all. Supported only on UNIX platforms.
@@ -458,12 +470,12 @@
=head1 EXAMPLES
All the examples below presume that B<OPENSSL_CONF> is set to a proper
-configuration file, e.g. the example configuration file
+configuration file, e.g. the example configuration file
openssl/apps/openssl.cnf will do.
=head2 Time Stamp Request
-To create a time stamp request for design1.txt with SHA-1
+To create a time stamp request for design1.txt with SHA-1
without nonce and policy and no certificate is required in the response:
openssl ts -query -data design1.txt -no_nonce \
@@ -479,7 +491,7 @@
openssl ts -query -in design1.tsq -text
-To create a time stamp request which includes the MD-5 digest
+To create a time stamp request which includes the MD-5 digest
of design2.txt, requests the signer certificate and nonce,
specifies a policy id (assuming the tsa_policy1 name is defined in the
OID section of the config file):
@@ -559,8 +571,8 @@
=over 4
=item * No support for time stamps over SMTP, though it is quite easy
-to implement an automatic e-mail based TSA with L<procmail(1)|procmail(1)>
-and L<perl(1)|perl(1)>. HTTP server support is provided in the form of
+to implement an automatic e-mail based TSA with L<procmail(1)|procmail(1)>
+and L<perl(1)|perl(1)>. HTTP server support is provided in the form of
a separate apache module. HTTP client support is provided by
L<tsget(1)|tsget(1)>. Pure TCP/IP protocol is not supported.
@@ -587,8 +599,8 @@
=head1 SEE ALSO
-L<tsget(1)|tsget(1)>, L<openssl(1)|openssl(1)>, L<req(1)|req(1)>,
-L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
+L<tsget(1)|tsget(1)>, L<openssl(1)|openssl(1)>, L<req(1)|req(1)>,
+L<x509(1)|x509(1)>, L<ca(1)|ca(1)>, L<genrsa(1)|genrsa(1)>,
L<config(5)|config(5)>
=cut
diff -ur openssl-1.0.0-beta4/include/openssl/ts.h
openssl-1.0.0-beta4-modified/include/openssl/ts.h
--- openssl-1.0.0-beta4/include/openssl/ts.h 2008-11-12 04:58:06.000000000
+0100
+++ openssl-1.0.0-beta4-modified/include/openssl/ts.h 2010-01-08
11:10:12.000000000 +0100
@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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
@@ -181,7 +181,7 @@
ASN1_INTEGER *nonce;
GENERAL_NAME *tsa;
STACK_OF(X509_EXTENSION) *extensions;
- } TS_TST_INFO;
+ } TS_TST_INFO;
/*
PKIStatusInfo ::= SEQUENCE {
@@ -324,7 +324,7 @@
TS_STATUS_INFO *TS_STATUS_INFO_new(void);
void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
-TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
+TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
const unsigned char **pp, long length);
TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
@@ -364,7 +364,7 @@
ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
-int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a,
+int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a,
unsigned char **pp);
ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
const unsigned char **pp, long length);
@@ -489,13 +489,13 @@
typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
/* This must return the seconds and microseconds since Jan 1, 1970 in
- the sec and usec variables allocated by the caller.
+ the sec and usec variables allocated by the caller.
Return non-zero for success and zero for failure. */
typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long
*usec);
/* This must process the given extension.
* It can modify the TS_TST_INFO object of the context.
- * Return values: !0 (processed), 0 (error, it must set the
+ * Return values: !0 (processed), 0 (error, it must set the
* status info/failure info of the response).
*/
typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *,
void *);
@@ -504,6 +504,7 @@
{
X509 *signer_cert;
EVP_PKEY *signer_key;
+ const EVP_MD *signing_digest;
STACK_OF(X509) *certs; /* Certs to include in signed data. */
STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
@@ -518,10 +519,10 @@
/* Callback functions. */
TS_serial_cb serial_cb;
void *serial_cb_data; /* User data for serial_cb. */
-
+
TS_time_cb time_cb;
void *time_cb_data; /* User data for time_cb. */
-
+
TS_extension_cb extension_cb;
void *extension_cb_data; /* User data for extension_cb. */
@@ -545,16 +546,19 @@
int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
/* This parameter must be set. */
+int TS_RESP_CTX_set_signing_digest(TS_RESP_CTX *ctx, const EVP_MD
*signing_digest);
+
+/* This parameter must be set. */
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
/* No additional certs are included in the response by default. */
int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
-/* Adds a new acceptable policy, only the default policy
+/* Adds a new acceptable policy, only the default policy
is accepted by default. */
int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
-/* Adds a new acceptable message digest. Note that no message digests
+/* Adds a new acceptable message digest. Note that no message digests
are accepted by default. The md argument is shared with the caller. */
int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
@@ -562,11 +566,11 @@
int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
int secs, int millis, int micros);
-/* Clock precision digits, i.e. the number of decimal digits:
- '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */
+/* Clock precision digits, i.e. the number of decimal digits:
+ '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */
int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
unsigned clock_precision_digits);
-/* At most we accept usec precision. */
+/* At most we accept usec precision. */
#define TS_MAX_CLOCK_PRECISION_DIGITS 6
/* No flags are set by default. */
@@ -578,18 +582,18 @@
/* Default callback uses the gettimeofday() and gmtime() system calls. */
void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
-/* Default callback rejects all extensions. The extension callback is called
+/* Default callback rejects all extensions. The extension callback is called
* when the TS_TST_INFO object is already set up and not signed yet. */
/* FIXME: extension handling is not tested yet. */
-void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
TS_extension_cb cb, void *data);
/* The following methods can be used in the callbacks. */
-int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
int status, const char *text);
/* Sets the status info only if it is still TS_STATUS_GRANTED. */
-int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
int status, const char *text);
int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
@@ -599,7 +603,7 @@
TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
-/*
+/*
* Creates the signed TS_TST_INFO and puts it in TS_RESP.
* In case of errors it sets the status info properly.
* Returns NULL only in case of memory allocation/fatal error.
@@ -664,7 +668,7 @@
/* Must be set only with TS_VFY_POLICY. */
ASN1_OBJECT *policy;
- /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL,
+ /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL,
the algorithm from the response is used. */
X509_ALGOR *md_alg;
unsigned char *imprint;
@@ -694,7 +698,7 @@
void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
-/*
+/*
* If ctx is NULL, it allocates and returns a new object, otherwise
* it returns ctx. It initialises all the members as follows:
* flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
@@ -744,6 +748,8 @@
TS_RESP_CTX *ctx);
int TS_CONF_set_signer_key(CONF *conf, const char *section,
const char *key, const char *pass, TS_RESP_CTX *ctx);
+int TS_CONF_set_signing_digest(CONF *conf, const char *section,
+ const char *md, TS_RESP_CTX *ctx);
int TS_CONF_set_def_policy(CONF *conf, const char *section,
const char *policy, TS_RESP_CTX *ctx);
int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
diff -ur openssl-1.0.0-beta4/test/CAtsa.cnf
openssl-1.0.0-beta4-modified/test/CAtsa.cnf
--- openssl-1.0.0-beta4/test/CAtsa.cnf 2006-11-07 17:21:16.000000000 +0100
+++ openssl-1.0.0-beta4-modified/test/CAtsa.cnf 2010-01-08 13:09:02.000000000
+0100
@@ -136,6 +136,8 @@
# (optional)
signer_key = $dir/tsa_key1.pem # The TSA private key (optional)
+signing_digest = sha1 # Signing digest to use. (Optional)
+
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
@@ -160,6 +162,8 @@
# (optional)
signer_key = $dir/tsa_key2.pem # The TSA private key (optional)
+signing_digest = sha1 # Signing digest to use. (Optional)
+
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)