2008/5/12 Isaias Punktin:
 > Hi all.
 >
 > I have been reading the code of openssl/apps/ts.c and there is no
 > possible for the TSA to sign using a private key stored in a
 > token/SmartCard/engine. I think this is interesting because it makes
 > possible to make a TSA compliant with RFC 3628 ("Requirements for
 > Time-Stamping Authorities"). Is somebody working on this?
 >
 > Thanks for all.
 >
 > Punkto
 >

I have been looking for a solution for the problem about using ts with 
private keys placed into engines. I have made a patch for ts, in the 
bottom of this mail, that solves the problem for me.

You can see that I had to create a new option called "keyform" where the 
user selects a PEM key or an ENGINE key. I use load_key function in 
order to load the private key wherever it is.

With this patch there is no need to change any application that uses ts 
because the key format is PEM if the option is not specified. The id of 
the engine can be written in the same formats that OpenSSL uses. So, in 
my tests i use commands like this:

ts -config CAtsa.cnf -reply -section tsa_config1 -queryfile req.tsq -out 
res.tsr -engine pkcs11 -keyform ENGINE -inkey id_50


Please, can you see if this patch can be added to OpenSSL source? Maybe 
you don't have any SmartCards to play with and make tests. But, at 
least, you can check using the tests you have in order to see if ts 
works well with no engines using this patch.

As you can see below, I have only changed ts.c. The diff was applied 
OpenSSL patched with OpenTSA. I know that OpenTSA is included in OpenSSL 
0.9.9, should i submit the patch against that version?

Thanks in advance.

Jorge Muñoz



--- ./ts.c.orig 2008-07-18 16:05:17.000000000 +0200
+++ ./ts.c      2008-07-21 12:44:09.000000000 +0200
@@ -93,13 +93,13 @@
static ASN1_INTEGER *create_nonce(int bits);

/* Reply related functions. */
-static int reply_command(CONF *conf, char *section, char *engine,
+static int reply_command(CONF *conf, char *section, char *engine, int 
keyform,
                     char *queryfile, char *passin, char *inkey,
                     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,
+static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine, int keyform,
                            char *queryfile, char *passin, char *inkey,
                            char *signer, char *chain, const char *policy);
static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
@@ -348,7 +348,7 @@
                    if (ret) goto usage;
                    }

-               ret = !reply_command(conf, section, engine, queryfile,
+               ret = !reply_command(conf, section, engine, keyform, 
queryfile,
                                 password, inkey, signer, chain, policy,
                                 in, token_in, out, token_out, text);
            break;
@@ -670,7 +670,7 @@
* Reply-related method definitions.
*/

-static int reply_command(CONF *conf, char *section, char *engine,
+static int reply_command(CONF *conf, char *section, char *engine, int 
keyform,
                     char *queryfile, char *passin, char *inkey,
                     char *signer, char *chain, const char *policy,
                     char *in, int token_in,
@@ -702,7 +702,7 @@
            }
    else
            {
-               response = create_response(conf, section, engine, 
queryfile,
+               response = create_response(conf, section, engine, 
keyform, queryfile,
                                       passin, inkey, signer, chain,
                                       policy);
            if (response)
@@ -797,7 +797,7 @@
    return resp;
    }

-static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine,
+static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine, int keyform,
                            char *queryfile, char *passin, char *inkey,
                            char *signer, char *chain, const char *policy)
    {
@@ -805,6 +805,8 @@
    TS_RESP *response = NULL;
    BIO *query_bio = NULL;
    TS_RESP_CTX *resp_ctx = NULL;
+       EVP_PKEY *sigkey = NULL;
+       ENGINE *e = NULL;

    if (!(query_bio = BIO_new_file(queryfile, "rb")))
            goto end;
@@ -829,8 +831,26 @@
    if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;

    /* Setting TSA signer private key. */
-       if (!TS_CONF_set_signer_key(conf, section, inkey, passin, 
resp_ctx))
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+       if (!inkey)
+               inkey = NCONF_get_string(conf, section, "signer_key");
+       if (!inkey)
+       {
+               BIO_printf(bio_err, "variable lookup failed for 
section::signer_key\n");
+               goto end;
+       }
+
+
+       sigkey = load_key(bio_err, inkey, keyform, 0, passin, e, "key 
file");
+       if (!sigkey)
+       {
+               /* load_key() has already printed an appropriate message */
            goto end;
+       }
+       if (!TS_RESP_CTX_set_signer_key(resp_ctx, sigkey)) goto end;
+

    /* Setting default policy OID. */
    if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
@@ -869,6 +889,7 @@
            response = NULL;
            }
    TS_RESP_CTX_free(resp_ctx);
+       EVP_PKEY_free(sigkey);
    BIO_free_all(query_bio);

    return response;

-- 

Jorge Muñoz Castañer

e-mail: jorgem(en)det.uvigo.es

Departamento de Ingeniería Telemática

Universidad de Vigo

ETSI Telecomunicación
Campus 36310 Vigo SPAIN 


Jorge Muñoz Castañer escribió:
> Hi, list
>
> 2008/5/12 Isaias Punktin:
> > Hi all.
> >
> > I have been reading the code of openssl/apps/ts.c and there is no
> > possible for the TSA to sign using a private key stored in a
> > token/SmartCard/engine. I think this is interesting because it makes
> > possible to make a TSA compliant with RFC 3628 ("Requirements for
> > Time-Stamping Authorities"). Is somebody working on this?
> >
> > Thanks for all.
> >
> > Punkto
> >
>
> I have been looking for a solution for the problem about using ts with 
> private keys placed into engines. I have made a patch for ts, in the 
> bottom of this mail, that solves the problem for me.
>
> You can see that I had to create a new option called "keyform" where 
> the user selects a PEM key or an ENGINE key. I use load_key function 
> in order to load the private key wherever it is.
>
> With this patch there is no need to change any application that uses 
> ts because the key format is PEM if the option is not specified. The 
> id of the engine can be written in the same formats that OpenSSL uses. 
> So, in my tests i use commands like this:
>
> ts -config CAtsa.cnf -reply -section tsa_config1 -queryfile req.tsq 
> -out res.tsr -engine pkcs11 -keyform ENGINE -inkey id_50
>
>
> Please, can you see if this patch can be added to OpenSSL source? 
> Maybe you don't have any SmartCards to play with and make tests. But, 
> at least, you can check using the tests you have in order to see if ts 
> works well with no engines using this patch.
>
>
> Thanks in advance.
>
> Jorge Muñoz
>
> PS: As you can see, I have only changed ts.c. The diff was applied to 
> the OpenTSA patch for OpenSSL version 0.9.8c.
Mmm not really. The patch has been applied to OpenSSL patched with OpenTSA.

--- ./ts.c.orig 2008-07-18 16:05:17.000000000 +0200
+++ ./ts.c      2008-07-21 12:44:09.000000000 +0200
@@ -93,13 +93,13 @@
static ASN1_INTEGER *create_nonce(int bits);

/* Reply related functions. */
-static int reply_command(CONF *conf, char *section, char *engine,
+static int reply_command(CONF *conf, char *section, char *engine, int 
keyform,
                      char *queryfile, char *passin, char *inkey,
                      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,
+static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine, int keyform,
                             char *queryfile, char *passin, char *inkey,
                             char *signer, char *chain, const char *policy);
static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
@@ -348,7 +348,7 @@
                     if (ret) goto usage;
                     }

-               ret = !reply_command(conf, section, engine, queryfile,
+               ret = !reply_command(conf, section, engine, keyform, 
queryfile,
                                  password, inkey, signer, chain, policy,
                                  in, token_in, out, token_out, text);
             break;
@@ -670,7 +670,7 @@
* Reply-related method definitions.
*/

-static int reply_command(CONF *conf, char *section, char *engine,
+static int reply_command(CONF *conf, char *section, char *engine, int 
keyform,
                      char *queryfile, char *passin, char *inkey,
                      char *signer, char *chain, const char *policy,
                      char *in, int token_in,
@@ -702,7 +702,7 @@
             }
     else
             {
-               response = create_response(conf, section, engine, queryfile,
+               response = create_response(conf, section, engine, 
keyform, queryfile,
                                        passin, inkey, signer, chain,
                                        policy);
             if (response)
@@ -797,7 +797,7 @@
     return resp;
     }

-static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine,
+static TS_RESP *create_response(CONF *conf, const char *section, char 
*engine, int keyform,
                             char *queryfile, char *passin, char *inkey,
                             char *signer, char *chain, const char *policy)
     {
@@ -805,6 +805,8 @@
     TS_RESP *response = NULL;
     BIO *query_bio = NULL;
     TS_RESP_CTX *resp_ctx = NULL;
+       EVP_PKEY *sigkey = NULL;
+       ENGINE *e = NULL;

     if (!(query_bio = BIO_new_file(queryfile, "rb")))
             goto end;
@@ -829,8 +831,26 @@
     if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;

     /* Setting TSA signer private key. */
-       if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+       if (!inkey)
+               inkey = NCONF_get_string(conf, section, "signer_key");
+       if (!inkey)
+       {
+               BIO_printf(bio_err, "variable lookup failed for 
section::signer_key\n");
+               goto end;
+       }
+
+
+       sigkey = load_key(bio_err, inkey, keyform, 0, passin, e, "key 
file");
+       if (!sigkey)
+       {
+               /* load_key() has already printed an appropriate message */
             goto end;
+       }
+       if (!TS_RESP_CTX_set_signer_key(resp_ctx, sigkey)) goto end;
+

     /* Setting default policy OID. */
     if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
@@ -869,6 +889,7 @@
             response = NULL;
             }
     TS_RESP_CTX_free(resp_ctx);
+       EVP_PKEY_free(sigkey);
     BIO_free_all(query_bio);

     return response;

-- 

Jorge Muñoz Castañer

e-mail: jorgem(en)det.uvigo.es

Departamento de Ingeniería Telemática

Universidad de Vigo

ETSI Telecomunicación
Campus 36310 Vigo SPAIN 


Reply via email to