MicrochipTech / cryptoauth-openssl-engine

DEPRECATED: Use https://github.com/MicrochipTech/cryptoauthlib/wiki/PKCS11-Linux-Setup
Other
76 stars 49 forks source link

Integration issues #5

Closed jimpnet closed 6 years ago

jimpnet commented 7 years ago

I'm having issues getting basic client cert authentication to work. I'm working with a device that was provided with the cryptoquth-openssl-engine already integrated by the vendor so I'm not doing the compilation/integration myself. I've attempted to make a test as basic as possible based on the scripts in this project. The file ec-params.pem as the prime256v1 params, the file my-ca.crt is a self-signed CA cert, and my-ca.key is it's key. I use these commands to generate my client key and certificate:

openssl req -keygen_engine ateccx08 -newkey ec:ec-params.pem -subj "/O=Example/CN=11000308" -sha256 -keyout client.key -out device-csr.pem -verify

openssl x509 -req -in device-csr.pem -days 2000000 -CA my-ca.crt -CAcreateserial -CAkey my-ca.key -out client.crt

openssl ec -in client.key -out client.key

I get this output:

ATECCX08: bind_fn()
ATECCX08: ECCX08 bind_helper()
ATECCX08: eccx08_rand_init()
ATECCX08: eccx08_pkey_meth_init()
ATECCX08: eccx08_pkey_meth_init()
ATECCX08: eccx08_ecdh_init() - HW
ATECCX08: eccx08_cmd_defn_init()
ATECCX08: returned normally()
ATECCX08: eccx08_init()
ATECCX08: eccx08_pkey_meth_f()
ATECCX08: eccx08_pkey_ec_init() - hw
ATECCX08: eccx08_pkey_ec_keygen_init()
Generating a 256 bit EC private key
ATECCX08: eccx08_pkey_ec_keygen() - HW
ATECCX08: eccx08_finish()
writing new private key to '/opt/ext/etc/keys/client.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
ATECCX08: eccx08_item_sign() - HW
ATECCX08: ECDSA_eccx08_do_sign(): int eckey HW
verify OK
ATECCX08: eccx08_int_ec_free()
ATECCX08: eccx08_pkey_meth_f()
ATECCX08: eccx08_pkey_asn1_meth_f()
ATECCX08: eccx08_destroy()
Signature ok
subject=/O=Example/CN=11000308
Getting CA Private Key
read EC key
Enter PEM pass phrase:
writing EC key

I have a server.crt and server.key that are also signed by my-ca.crt. I run a server that does not integrate with the ecc508A using this command:

openssl s_server -CAfile my-ca.crt -cert server.crt -key server.key -Verify 2

Finally, I run a client like this:

openssl s_client -engine ateccx08 -connect localhost:4433 -CAfile my-ca.crt -cert client.crt -key client.key

with this output

ATECCX08: bind_fn()
ATECCX08: ECCX08 bind_helper()
ATECCX08: eccx08_rand_init()
ATECCX08: eccx08_pkey_meth_init()
ATECCX08: eccx08_pkey_meth_init()
ATECCX08: eccx08_ecdh_init() - HW
ATECCX08: eccx08_cmd_defn_init()
ATECCX08: returned normally()
ATECCX08: eccx08_ctrl()
ATECCX08: eccx08_init()
ATECCX08: eccx08_pkey_meth_f()
ATECCX08: eccx08_pkey_asn1_meth_f()
engine "ateccx08" set.
ATECCX08: RAND_eccx08_rand_bytes() -  hw
CONNECTED(00000003)
ATECCX08: eccx08_rsa_init()
depth=1 C = US, ST = ..., L = ..., O = ..., CN = ...
verify return:1
ATECCX08: eccx08_rsa_init()
depth=0 C = US, ST = ..., L = ..., O = ..., CN = ...
verify return:1
ATECCX08: ECDH_eccx08_compute_key(): HW 
ATECCX08: ECDH_eccx08_get_pubkey() - hw
ATECCX08: ECDSA_eccx08_do_sign(): ERROR dgst_len
1995924688:error:14099006:SSL routines:ssl3_send_client_verify:EVP lib:s3_clnt.c:3286:
---
Certificate chain
 0 s:/C=US/ST=.../L=.../O=.../CN=...
   i:/C=US/ST=.../L=.../O=.../CN=...
 1 s:/C=US/ST=.../L=.../O=.../CN=...
   i:/C=US/ST=.../L=.../O=.../CN=...
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=/C=US/ST=.../L=.../O=.../CN=...
issuer=/C=US/ST=.../L=.../O=.../CN=...
---
Acceptable client certificate CA names
/C=US/ST=.../L=.../O=.../CN=...
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2297 bytes and written 1560 bytes
---
New, (NONE), Cipher is (NONE)
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: ED8D7DFD9ADCF5F896DE93D6AF2B581D217809AFA12EA7FA396A85D174FB2B5849DFFBA3AB5284981D33BFE9257B7F7A
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1498848897
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
ATECCX08: eccx08_finish()
ATECCX08: eccx08_pkey_meth_f()
ATECCX08: eccx08_pkey_asn1_meth_f()
ATECCX08: eccx08_destroy()

As you can see I get this error ATECCX08: ECDSA_eccx08_do_sign(): ERROR dgst_len. I'm not sure why there is a key file when the key is stored in the hardware but your scripts included it so I kept it.

I should also note that if I omit the -keygen ateccx08 and -engine ateccx08 this all works fine.

I'd greatly appreciate any help you can provide.

Thanks.

agostrer commented 7 years ago

Hi Jim,

The problem here that your openssl is built with SHA-512 support. ECC508 supports SHA-256 only. Openssl always tries to pick the best available algorithm (SHA-512 in you case). To go around this problem, we built openssl v.1.0.2 with SHA-512 disabled. You should be able to build this version of openssl using our makefile and patches from the GitHub repository.

I do not know if it is possible to specify SHA-256 with SHA-512 enabled. We didn't find a way so we went with the patch. Let me know if you can solve this problem or have more questions.

Regards, Alex Gostrer

Sent from my iPhone

On Jun 30, 2017, at 12:11 PM, Jim notifications@github.com wrote:

I'm having issues getting basic client cert authentication to work. I'm working with a device that was provided with the cryptoquth-openssl-engine already integrated by the vendor so I'm not doing the compilation/integration myself. I've attempted to make a test as basic as possible based on the scripts in this project. The file ec-params.pem as the prime256v1 params, the file my-ca.crt is a self-signed CA cert, and my-ca.key is it's key. I use these commands to generate my client key and certificate:

openssl req -keygen_engine ateccx08 -newkey ec:ec-params.pem -subj "/O=Example/CN=11000308" -sha256 -keyout client.key -out device-csr.pem -verify

openssl x509 -req -in device-csr.pem -days 2000000 -CA my-ca.crt -CAcreateserial -CAkey my-ca.key -out client.crt

openssl ec -in client.key -out client.key I get this output:

ATECCX08: bind_fn() ATECCX08: ECCX08 bind_helper() ATECCX08: eccx08_rand_init() ATECCX08: eccx08_pkey_meth_init() ATECCX08: eccx08_pkey_meth_init() ATECCX08: eccx08_ecdh_init() - HW ATECCX08: eccx08_cmd_defn_init() ATECCX08: returned normally() ATECCX08: eccx08_init() ATECCX08: eccx08_pkey_meth_f() ATECCX08: eccx08_pkey_ec_init() - hw ATECCX08: eccx08_pkey_ec_keygen_init() Generating a 256 bit EC private key ATECCX08: eccx08_pkey_ec_keygen() - HW ATECCX08: eccx08_finish() writing new private key to '/opt/ext/etc/keys/client.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase:

ATECCX08: eccx08_item_sign() - HW ATECCX08: ECDSA_eccx08_do_sign(): int eckey HW verify OK ATECCX08: eccx08_int_ec_free() ATECCX08: eccx08_pkey_meth_f() ATECCX08: eccx08_pkey_asn1_meth_f() ATECCX08: eccx08_destroy() Signature ok subject=/O=Example/CN=11000308 Getting CA Private Key read EC key Enter PEM pass phrase: writing EC key I have a server.crt and server.key that are also signed by my-ca.crt. I run a server that does not integrate with the ecc508A using this command:

openssl s_server -CAfile my-ca.crt -cert server.crt -key server.key -Verify 2 Finally, I run a client like this:

openssl s_client -engine ateccx08 -connect localhost:4433 -CAfile my-ca.crt -cert client.crt -key client.key with this output

ATECCX08: bind_fn() ATECCX08: ECCX08 bind_helper() ATECCX08: eccx08_rand_init() ATECCX08: eccx08_pkey_meth_init() ATECCX08: eccx08_pkey_meth_init() ATECCX08: eccx08_ecdh_init() - HW ATECCX08: eccx08_cmd_defn_init() ATECCX08: returned normally() ATECCX08: eccx08_ctrl() ATECCX08: eccx08_init() ATECCX08: eccx08_pkey_meth_f() ATECCX08: eccx08_pkey_asn1_meth_f() engine "ateccx08" set. ATECCX08: RAND_eccx08_rand_bytes() - hw CONNECTED(00000003) ATECCX08: eccx08_rsa_init() depth=1 C = US, ST = ..., L = ..., O = ..., CN = ... verify return:1 ATECCX08: eccx08_rsa_init() depth=0 C = US, ST = ..., L = ..., O = ..., CN = ... verify return:1 ATECCX08: ECDH_eccx08_compute_key(): HW ATECCX08: ECDH_eccx08_get_pubkey() - hw ATECCX08: ECDSA_eccx08_do_sign(): ERROR dgst_len 1995924688:error:14099006:SSL routines:ssl3_send_client_verify:EVP lib:s3_clnt.c:3286:

Certificate chain 0 s:/C=US/ST=.../L=.../O=.../CN=... i:/C=US/ST=.../L=.../O=.../CN=... 1 s:/C=US/ST=.../L=.../O=.../CN=... i:/C=US/ST=.../L=.../O=.../CN=...

Server certificate -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- subject=/C=US/ST=.../L=.../O=.../CN=... issuer=/C=US/ST=.../L=.../O=.../CN=...

Acceptable client certificate CA names /C=US/ST=.../L=.../O=.../CN=... Client Certificate Types: RSA sign, DSA sign, ECDSA sign Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1 Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1 Peer signing digest: SHA512 Server Temp Key: ECDH, P-256, 256 bits

SSL handshake has read 2297 bytes and written 1560 bytes

New, (NONE), Cipher is (NONE) Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: ED8D7DFD9ADCF5F896DE93D6AF2B581D217809AFA12EA7FA396A85D174FB2B5849DFFBA3AB5284981D33BFE9257B7F7A Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1498848897 Timeout : 300 (sec) Verify return code: 0 (ok)

ATECCX08: eccx08_finish() ATECCX08: eccx08_pkey_meth_f() ATECCX08: eccx08_pkey_asn1_meth_f() ATECCX08: eccx08_destroy() As you can see I get this error ATECCX08: ECDSA_eccx08_do_sign(): ERROR dgst_len. I'm not sure why there is a key file when the key is stored in the hardware but your scripts included it so I kept it.

I should also note that if I omit the -keygen ateccx08 and -engine ateccx08 this all works fine.

I'd greatly appreciate any help you can provide.

Thanks.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

jimpnet commented 7 years ago

Thank you so much. I will do that. Can you answer a couple more questions for me please:

How do I tell whether it's using SHA-512 or SHA-256?

What do I need to do to use this in code? I have something like this presently:

ENGINE_load_dynamic();
ENGINE *engine =  = ENGINE_by_id("ateccx08");
ENGINE_set_default_ECDH(engine) ;
ENGINE_set_default_RAND(engine);
ENGINE_set_default_pkey_asn1_meths(engine) ;
ENGINE_set_default_ECDSA(engine) ;
ENGINE_set_default_RSA(engine) ;
ENGINE_set_default_pkey_meths(engine) ;
ENGINE_set_default_ciphers(engine) ;
ENGINE_set_default_digests(engine) ;
ENGINE_set_default_DH(engine) ;
ENGINE_set_default_DSA(engine) ;
SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM);

Should I have calls I am missing or remove any I have? I just called all the ENGINE_set_default_... functions. Do I still need to use the key? I'm not clear why that is.

Does the patch affect libraries or just the openssl executable?

Thanks again. You've been extremely helpful.

jimpnet commented 7 years ago

Also, is this a problem when I'm generating the keys/certs or just when I'm trying to connect?

agostrer commented 7 years ago

Hi Jim,

We worked on this project 2 years ago so I may be forgetting some details - I can provide you with general ideas only.

I saw SHA-512 in your log. Normally you should not see it and the error should disappear. If it passes then it is using SHA-256 for sure :).

We are still using private key file. But this file does not contain the private key anymore: it has a special token to help the engine to match the ECC508 hardware. (Was it the question? Or you meant something else?)

The parch should affect the openssl executable only. It is pretty small patch, you can easy see what it is doing.

Regards, Alex

Sent from my iPhone

On Jun 30, 2017, at 1:16 PM, Jim notifications@github.com wrote:

Thank you so much. I will do that. Can you answer a couple more questions for me please:

How do I tell whether it's using SHA-512 or SHA-256?

What do I need to do to use this in code? I have something like this presently:

ENGINE_load_dynamic(); ENGINE *engine = = ENGINE_by_id("ateccx08"); ENGINE_set_default_ECDH(engine) ; ENGINE_set_default_RAND(engine); ENGINE_set_default_pkey_asn1_meths(engine) ; ENGINE_set_default_ECDSA(engine) ; ENGINE_set_default_RSA(engine) ; ENGINE_set_default_pkey_meths(engine) ; ENGINE_set_default_ciphers(engine) ; ENGINE_set_default_digests(engine) ; ENGINE_set_default_DH(engine) ; ENGINE_set_default_DSA(engine) ; SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM); Should I have calls I am missing or remove any I have? I just called all the ENGINE_setdefault... functions. Do I still need to use the key? I'm not clear why that is.

Does the patch affect libraries or just the openssl executable?

Thanks again. You've been extremely helpful.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

agostrer commented 7 years ago

You mean SHA512? I think it affects both cases. But I do not remember for sure

Alex

Sent from my iPhone

On Jun 30, 2017, at 1:21 PM, Jim notifications@github.com wrote:

Also, is this a problem when I'm generating the keys/certs or just when I'm trying to connect?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

jimpnet commented 7 years ago

I was able to get it to work by adding -client_sigalgs ECDSA+SHA256 to my openssl s_client ... command.

I'm still having issues getting it to work programatically though. Do you have an example of what I need to do as far as loading the engine, context settings, etc? The load and set default call in one of the comments above is all the farther I've gotten.

Thank you for all the help.

agostrer commented 7 years ago

Oh, this is good. I didn't' know about this option.

Check the "examples" directory. Or maybe "tests"? I am away from my desk. But all programmatic ways to run ecc508 should be in the repository.

Note that standard openssl will not allow ECDH in the hardware: they says that it has no added security because you still need to pass the master secret back. If you want to use the ECDH in ecc508 hardware for you TLS connection then you need to apply at least one of the patches.

Regards, Alex

Sent from my iPhone

On Jun 30, 2017, at 1:43 PM, Jim notifications@github.com wrote:

I was able to get it to work by adding -client_sigalgs ECDSA+SHA256 to my openssl s_client ... command.

I'm still having issues getting it to work programatically though. Do you have an example of what I need to do as far as loading the engine, context settings, etc? The load and set default call in one of the comments above is all the farther I've gotten.

Thank you for all the help.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

bryan-hunt commented 6 years ago

Jim, I assume you've probably already found what you need for programmatic use of an engine but for documentation and those encountering this issue later the general order of controlling the engine for all features would follow this pattern. The sigalgs and cipher sections are more generically applicable as they are how to restrict negotiation to just what is supported and can be used/tested without the engine being used.

    OpenSSL_add_all_algorithms();
    ERR_load_BIO_strings();
    ERR_load_crypto_strings();
    SSL_load_error_strings();

#ifdef USE_ENGINE
    ENGINE_load_dynamic();
    if (!CONF_modules_load_file(NULL, NULL, CONF_MFLAGS_DEFAULT_SECTION))
    {
        ERROR("Config failed to load");
    }

    /* Load the engine for testing */
    engine = ENGINE_by_id("ateccx08");

    if (engine == NULL)
    {
        ERROR("Engine failed to load");
    }

    if (!ENGINE_init(engine))
    {
        ERROR("Engine failed to initialize");
    }

    /* Register all engine functionality with OpenSSL */
    if (!ENGINE_register_complete(engine))
    {
        ERROR("Engine register failed");
    }
#endif

    if (SSL_library_init() < 0) {
        ret_val = SSL_INIT_ERROR;
    }

    method = TLSv1_2_method();

     if ((pSSLContext = SSL_CTX_new(method)) == NULL) {
          ERROR(" SSL INIT Failed - Unable to create SSL Context");
          ret_val = SSL_INIT_ERROR;
     }

#ifdef USE_ENGINE
     if(!SSL_CTX_set_client_cert_engine(pSSLContext, engine))
     {
          ERROR(" Error setting client cert engine");
     }
     ENGINE_free(engine);
#endif

     if(!SSL_CTX_set_cipher_list(pSSLContext, "ECDHE-ECDSA-AES128-GCM-SHA256"))
     {
          ERROR(" Unable to set cipher suite");
     }

     if(!SSL_CTX_set1_sigalgs_list(pSSLContext, "ECDSA+SHA256"))
     {
          ERROR(" Unable to set sigalgs");
     }

     if(!SSL_CTX_set1_client_sigalgs_list(pSSLContext, "ECDSA+SHA256"))
     {
          ERROR(" Unable to set client sigalgs");
     }