Questions about using Elliptic Curve ciphers in OpenSSL

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz

I’m somewhat confused as to what I need to do to use ECDHE ciphers (ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, etc). I’m hoping this list can help, or at least point me to a good tutorial somewhere. A lot of the information I’ve looked at is from the following links:

 

https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations

 

https://crypto.stackexchange.com/questions/19452/static-dh-static-ecdh-certificate-using-openssl

 

I’m only looking at getting something set up for testing for now; I have a self-signed certificate and a private key. Here is the certificate, with some info stripped (I didn’t create it so I don’t have the exact commands used):

 

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number:

            e7:64:34:3c:f2:b4:f5:cc

    Signature Algorithm: ecdsa-with-SHA256

        Issuer: C=US, ST=MyState, L=City, O=Org, OU=Dept, CN=MyCN/emailAddress=[hidden email]

        Validity

            Not Before: Jan 29 20:11:44 2020 GMT

            Not After : Jan 28 20:11:44 2021 GMT

        Subject: C=US, ST= MyState, L=City, O=Org, OU=Dept, CN=MyCN/emailAddress=[hidden email]

        Subject Public Key Info:

            Public Key Algorithm: id-ecPublicKey

                Public-Key: (256 bit)

                pub:

                    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

                    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

                    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

                    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

                    58:68:82:a4:3e

                ASN1 OID: prime256v1

                NIST CURVE: P-256

        X509v3 extensions:

            X509v3 Subject Key Identifier:

                DA:B7:A7:5A:16:85:40:61:36:D7:37:5E:AF:BE:E4:90:80:05:C7:FA

            X509v3 Authority Key Identifier:

                keyid:DA:B7:A7:5A:16:85:40:61:36:D7:37:5E:AF:BE:E4:90:80:05:C7:FA

 

            X509v3 Basic Constraints:

                CA:TRUE

    Signature Algorithm: ecdsa-with-SHA256

         30:45:02:21:00:bc:9c:cb:f1:ca:30:24:d3:7e:86:b4:d4:6f:

         f6:5a:3c:ab:c2:8d:24:b5:bc:03:b2:f9:55:74:0d:5d:cc:2c:

         11:02:20:56:f8:05:4d:88:e6:35:ab:7b:db:01:02:1c:3d:ae:

         ab:5d:5a:86:61:5b:e5:2d:1a:3f:4d:bf:5b:ea:12:c2:50

 

 

I also didn’t generate the private key, but I’ll dump some info on it here, again to make sure it looks OK. It’s also part of the equation that I’m not 100% sure about (if my private key is set up correctly). This is a non-production key, used only for initial testing:

 

---:/etc/ssl # openssl ec -in private/mykey.pem -text

read EC key

Private-Key: (256 bit)

priv:

    00:96:f8:5b:9d:a3:fb:3d:27:de:01:75:54:0f:51:

    69:38:d1:8f:2d:62:19:80:67:14:4a:da:1e:b5:d8:

    57:8f:e8

pub:

    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

    58:68:82:a4:3e

ASN1 OID: prime256v1

NIST CURVE: P-256

writing EC key

-----BEGIN EC PRIVATE KEY-----

MHcCAQEEIJb4W52j+z0n3gF1VA9RaTjRjy1iGYBnFEraHrXYV4/ooAoGCCqGSM49

AwEHoUQDQgAEHwfn6gm0lD6pC8TG0mUx20ycM5zN+734sQ6OaVx0zY2YDGcJ+x0B

n/aI1AKJnWZ4/840CecFzGMfUwdYaIKkPg==

-----END EC PRIVATE KEY-----

 

---:/etc/ssl # openssl ec -in private/mykey.pem -text -param_out

read EC key

Private-Key: (256 bit)

priv:

    00:96:f8:5b:9d:a3:fb:3d:27:de:01:75:54:0f:51:

    69:38:d1:8f:2d:62:19:80:67:14:4a:da:1e:b5:d8:

    57:8f:e8

pub:

    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

    58:68:82:a4:3e

ASN1 OID: prime256v1

NIST CURVE: P-256

writing EC key

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----

 

For my server code, the setup I use is very similar to if I was using an RSA certificate/key pair; setting up a CTX and calling the appropriate APIs for specifying the private key and certificate. Pseudocode:

 

ctx = SSL_CTX_new(TLS_method());

 

status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);

status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

 

// Verify the cert and key are a pair

status = SSL_CTX_check_private_key(ctx);

 

I do some validation of the certificate, the code for which I’ll skip as I don’t think it’s important here. I also set the protocol version I support with SSL_CTX_set_max_proto_version() and call SSL_CTX_set_cipher_list() to set the ciphers the server supports. The ciphers include the following:

 

ECDHE_RSA_WITH_AES_128_CBC_SHA256

ECDHE_RSA_WITH_AES_128_GCM_SHA256

ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

ECDHE_RSA_WITH_AES_256_CBC_SHA384

ECDHE_RSA_WITH_AES_256_GCM_SHA384

ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

 

Since I’m supporting ECDHE ciphers, I also call the following API, because I need to set the curves I support:

 

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");

 

Then another API call so the server will select the appropriate curve for the client:

 

status = SSL_CTX_set_ecdh_auto(ctx, 1);

 

First question, for the ECDHE_RSA* ciphers, I just need an RSA certificate and key, correct? Nothing else to do here?

 

 Most of my confusion is on the ECDHE_ECDSA* ciphers. Do I need to do anything else in addition to the above to use them? I’ve read about “EC parameters” files (and “ECDHE parameters” files?). Do I need to create another file to read in to support the ECDHE_ECDSA* ciphers? From the second command displaying the private key above, it looks like there are “EC parameters” embedded in the private key. Since I’m not 100% sure how the key was generated, that could be what’s causing my confusion.

 

Is the code I have above enough, or do I need another file? If so, how is that file generated, and what API do I need to read it in and use it?

 

Thanks in advance.


Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Anyone have any advice on Elliptic Curve?

Thanks in advance.


From: openssl-users <[hidden email]> on behalf of Jason Schultz <[hidden email]>
Sent: Friday, February 7, 2020 2:58 AM
To: [hidden email] <[hidden email]>
Subject: Questions about using Elliptic Curve ciphers in OpenSSL
 

I’m somewhat confused as to what I need to do to use ECDHE ciphers (ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, etc). I’m hoping this list can help, or at least point me to a good tutorial somewhere. A lot of the information I’ve looked at is from the following links:

 

https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations

 

https://crypto.stackexchange.com/questions/19452/static-dh-static-ecdh-certificate-using-openssl

 

I’m only looking at getting something set up for testing for now; I have a self-signed certificate and a private key. Here is the certificate, with some info stripped (I didn’t create it so I don’t have the exact commands used):

 

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number:

            e7:64:34:3c:f2:b4:f5:cc

    Signature Algorithm: ecdsa-with-SHA256

        Issuer: C=US, ST=MyState, L=City, O=Org, OU=Dept, CN=MyCN/emailAddress=[hidden email]

        Validity

            Not Before: Jan 29 20:11:44 2020 GMT

            Not After : Jan 28 20:11:44 2021 GMT

        Subject: C=US, ST= MyState, L=City, O=Org, OU=Dept, CN=MyCN/emailAddress=[hidden email]

        Subject Public Key Info:

            Public Key Algorithm: id-ecPublicKey

                Public-Key: (256 bit)

                pub:

                    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

                    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

                    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

                    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

                    58:68:82:a4:3e

                ASN1 OID: prime256v1

                NIST CURVE: P-256

        X509v3 extensions:

            X509v3 Subject Key Identifier:

                DA:B7:A7:5A:16:85:40:61:36:D7:37:5E:AF:BE:E4:90:80:05:C7:FA

            X509v3 Authority Key Identifier:

                keyid:DA:B7:A7:5A:16:85:40:61:36:D7:37:5E:AF:BE:E4:90:80:05:C7:FA

 

            X509v3 Basic Constraints:

                CA:TRUE

    Signature Algorithm: ecdsa-with-SHA256

         30:45:02:21:00:bc:9c:cb:f1:ca:30:24:d3:7e:86:b4:d4:6f:

         f6:5a:3c:ab:c2:8d:24:b5:bc:03:b2:f9:55:74:0d:5d:cc:2c:

         11:02:20:56:f8:05:4d:88:e6:35:ab:7b:db:01:02:1c:3d:ae:

         ab:5d:5a:86:61:5b:e5:2d:1a:3f:4d:bf:5b:ea:12:c2:50

 

 

I also didn’t generate the private key, but I’ll dump some info on it here, again to make sure it looks OK. It’s also part of the equation that I’m not 100% sure about (if my private key is set up correctly). This is a non-production key, used only for initial testing:

 

---:/etc/ssl # openssl ec -in private/mykey.pem -text

read EC key

Private-Key: (256 bit)

priv:

    00:96:f8:5b:9d:a3:fb:3d:27:de:01:75:54:0f:51:

    69:38:d1:8f:2d:62:19:80:67:14:4a:da:1e:b5:d8:

    57:8f:e8

pub:

    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

    58:68:82:a4:3e

ASN1 OID: prime256v1

NIST CURVE: P-256

writing EC key

-----BEGIN EC PRIVATE KEY-----

MHcCAQEEIJb4W52j+z0n3gF1VA9RaTjRjy1iGYBnFEraHrXYV4/ooAoGCCqGSM49

AwEHoUQDQgAEHwfn6gm0lD6pC8TG0mUx20ycM5zN+734sQ6OaVx0zY2YDGcJ+x0B

n/aI1AKJnWZ4/840CecFzGMfUwdYaIKkPg==

-----END EC PRIVATE KEY-----

 

---:/etc/ssl # openssl ec -in private/mykey.pem -text -param_out

read EC key

Private-Key: (256 bit)

priv:

    00:96:f8:5b:9d:a3:fb:3d:27:de:01:75:54:0f:51:

    69:38:d1:8f:2d:62:19:80:67:14:4a:da:1e:b5:d8:

    57:8f:e8

pub:

    04:1f:07:e7:ea:09:b4:94:3e:a9:0b:c4:c6:d2:65:

    31:db:4c:9c:33:9c:cd:fb:bd:f8:b1:0e:8e:69:5c:

    74:cd:8d:98:0c:67:09:fb:1d:01:9f:f6:88:d4:02:

    89:9d:66:78:ff:ce:34:09:e7:05:cc:63:1f:53:07:

    58:68:82:a4:3e

ASN1 OID: prime256v1

NIST CURVE: P-256

writing EC key

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----

 

For my server code, the setup I use is very similar to if I was using an RSA certificate/key pair; setting up a CTX and calling the appropriate APIs for specifying the private key and certificate. Pseudocode:

 

ctx = SSL_CTX_new(TLS_method());

 

status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);

status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

 

// Verify the cert and key are a pair

status = SSL_CTX_check_private_key(ctx);

 

I do some validation of the certificate, the code for which I’ll skip as I don’t think it’s important here. I also set the protocol version I support with SSL_CTX_set_max_proto_version() and call SSL_CTX_set_cipher_list() to set the ciphers the server supports. The ciphers include the following:

 

ECDHE_RSA_WITH_AES_128_CBC_SHA256

ECDHE_RSA_WITH_AES_128_GCM_SHA256

ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

ECDHE_RSA_WITH_AES_256_CBC_SHA384

ECDHE_RSA_WITH_AES_256_GCM_SHA384

ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

 

Since I’m supporting ECDHE ciphers, I also call the following API, because I need to set the curves I support:

 

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");

 

Then another API call so the server will select the appropriate curve for the client:

 

status = SSL_CTX_set_ecdh_auto(ctx, 1);

 

First question, for the ECDHE_RSA* ciphers, I just need an RSA certificate and key, correct? Nothing else to do here?

 

 Most of my confusion is on the ECDHE_ECDSA* ciphers. Do I need to do anything else in addition to the above to use them? I’ve read about “EC parameters” files (and “ECDHE parameters” files?). Do I need to create another file to read in to support the ECDHE_ECDSA* ciphers? From the second command displaying the private key above, it looks like there are “EC parameters” embedded in the private key. Since I’m not 100% sure how the key was generated, that could be what’s causing my confusion.

 

Is the code I have above enough, or do I need another file? If so, how is that file generated, and what API do I need to read it in and use it?

 

Thanks in advance.


Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

OpenSSL - User mailing list

The first thing I would suggest is to separate ECDH, the session key exchange, from ECDSA, the signature.  Try to make ECDH with RSA work.  Then just load your ECDSA cert; you can load one cert of each type (RSA DSA) and the runtime will figure out what to do, depending on what the client offers.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Rich-

Thanks for your reply. At this point I'm 99% sure I have ECDH with RSA working. My question in the previous post was just to confirm. But I have my RSA cert and key pair, and a client can successfully connect to my server using ECDHE_RSA* ciphers. 

My questions are more related to ECDSA. For example, you said "just load your ECDSA cert", which is easy enough. My question is, is that all I need? For example, with DSA (which we don't really use anymore), I also needed a DH parameters file, which I read in with PEM_read_DHparams(). Do I need to do something similar with "EC params" or "ECDSA params"? I've seen references to both, and I'm not sure if and when I need them.

As I pointed out, it looks like there are "EC PARAMETERS" in my private key file. Are these needed? If so, how and when do I use them? Or do I need them in a separate file?




From: Salz, Rich <[hidden email]>
Sent: Tuesday, February 11, 2020 4:37 PM
To: Jason Schultz <[hidden email]>; [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 

The first thing I would suggest is to separate ECDH, the session key exchange, from ECDSA, the signature.  Try to make ECDH with RSA work.  Then just load your ECDSA cert; you can load one cert of each type (RSA DSA) and the runtime will figure out what to do, depending on what the client offers.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

OpenSSL - User mailing list

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Kyle Hamilton
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Yes, absolutely. As I said in my first post, these are throwaway key pairs, not for production use, just a short time for testing to get things working. 

Thanks,

Jason


On Feb 16, 2020, at 4:49 PM, Kyle Hamilton <[hidden email]> wrote:


Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
In reply to this post by Kyle Hamilton
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Nicola Tuveri-2
The ec parameters are public anyway, so there is no real need to store such files somewhere with restricted reading access.

On the other hand, I want to reiterate that if you are using (and this is highly recommended) one of the named curves (e.g. NIST P-256) you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate.

In the same way, for the ECDHE part, pick curves that you want to support (most TLS 1.2 and 1.3 clients will be happy to support P-256 and X25519 key exchanges) from the named curves: also in this case there is no need to generate a separate ecparam file.

Hope this helps!

Best regards,

Nicola Tuveri


On Tue, 18 Feb 2020 at 15:27, Jason Schultz <[hidden email]> wrote:
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Nicola-

Thanks for your response. It does help, but at the same time it also raises questions and maybe conflicts with what I thought I was doing correct earlier in this thread. I'm talking mostly about where I landed in this post:



I am only using named curves. You also said:

"...you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate."

Let me apply that and start from the beginning and outline everything (I think) I need to do in that case:

1 - Generate a certificate and private key pair. Using the OpenSSL command line:

openssl req -nodes -sha256 -newkey ec:<(openssl ecparam -name prime256v1) 
-keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf 
-x509 -days 365 -outform pem

Note: the "ec:" parameter basically substitutes the openssl command above with the file I had created and used in this command. Also, the "-genkey" parameter I included in the ecparam command was probably not needed, or potentially bad?

2 - Call the SSL_CTX_use_PrivateKey_file() and SSL_CTX_use_certificate_file() to use the certificate and private key pair. (Same as before)

3 - Call the APIs to set the curves and allow the server to pick the appropriate curves for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

Do I have this right? Is the only difference combining the two commands into one in Step 1 above, instead of the intermediate ecparams file? Or is there something else I'm missing on the generation of certificate/private key pairs?

Thanks,

Jason





From: Nicola Tuveri <[hidden email]>
Sent: Tuesday, February 18, 2020 2:50 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
The ec parameters are public anyway, so there is no real need to store such files somewhere with restricted reading access.

On the other hand, I want to reiterate that if you are using (and this is highly recommended) one of the named curves (e.g. NIST P-256) you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate.

In the same way, for the ECDHE part, pick curves that you want to support (most TLS 1.2 and 1.3 clients will be happy to support P-256 and X25519 key exchanges) from the named curves: also in this case there is no need to generate a separate ecparam file.

Hope this helps!

Best regards,

Nicola Tuveri


On Tue, 18 Feb 2020 at 15:27, Jason Schultz <[hidden email]> wrote:
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Nicola Tuveri-2
I think there might be some confusion.

The "parameters" files are a legacy from when cryptosystems using "custom" domains were not widely deprecated.
Such parameter files were required for any instance of key generation, to make sure that a key was generated in the defined custom domain, and were part of any key serialization because in cryptosystems that define domain parameters a keypair is generally void of operational meaning if it isn't associated with a domain in which that keypair can be used to perform operations and also because when two or more peers are involved we need  to make sure that exchanged keys belonged to the same domain in which we chose to operate.

Nowadays the experts discourage "custom" domains (see e.g. RFC 8422), as they bring way more disadvantages than advantages, especially considering that the disadvantages include potential serious security pitfalls.

Historically you needed to pregenerate a domain parameters file for ephemeral DH used in the key exchange part of the TLS handshake, because key generation is a relatively cheap operation, but generating the big random primes required for creating new domain parameters is a quite demanding process: this was the params file that was provided to the SSL/TLS backend and needed to be saved alongside keys and certificates.
With ECDH, parameter generation for custom domains is even more involved, error prone, and the validation of custom parameters received from a peer is very expensive and littered with risks for the overall security if not done properly.

That being said, recommending "use named curves" just means to use well-established and studied set of parameters that standardizing bodies deemed recommendable for secure use: this way both peers refer to a set of parameters with a given common name rather than explicit parameters, and the clients can trust the evaluation done by experts rather than having to verify the received parameters for complex mathematical properties.

Now, to the commands in your email, it must be clear that there are a few cryptosystems involved in a generic TLS handshake:
1. key exchange: usually ephemeral ECDH
2. digital signature (to validate the handshake with the server credentials): commonly RSA, ECDSA or EdDSA (depending on the server key type)
3. digital signature (to validate the certificate where the CA states "this public key belongs to this subject"): commonly RSA, ECDSA or EdDSA (depending on the CA key type)

(We should note that 3 does not necessarily require a `verify()` operation for every handshake, because both the issuer and the subject credentials are static, so a certificate for a server could be validated once and cached for later use).

1)

Ephemeral ECDH generates a new keypair for every handshake, so the parties need to agree on which domain parameters to use.
We negotiate named curves rather than explicit parameters, and that is what `status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");` does: both parties specify a list of supported curves, and one in common is picked (preference on multiple hits is an irrelevant detail here).
So no need for a parameters file here, we use a list of names, and this is independent from the cryptosystem picked for the two digital signature operations.

2)

The server needs to have its own keypair, this means a one-time-only keygen operation for which parameters are necessary if we pick ECDSA as the cryptosystem of our choice.
You can do this using explicit parameters or a named curve, and the latter is preferred. In any case there is no need to store a parameters file after the key has been generated, as the key parameters are saved in the key serialization anyway, both for named and for custom curves.

There is no harm in generating an intermediary params file, but it is superfluous, and also the fact that there is no need to create such a file should answer to your original question about where/how it is best to store the parameter file. 

To generate such a private key without the need for an intermediate params file you could run:

~~~sh
curve_name=prime256v1
privkey_file=mykeyout.pem

openssl genpkey \
    -algorithm EC -pkeyopt ec_paramgen_curve:$curve_name \
    -pkeyopt ec_param_enc:named_curve \
    -outform pem -out $privkey_file
~~~

Once you have a private key you could generate a certificate signing request (CSR) for your CA to issue a certificate for your server:

~~~sh
csr_file=mycsrout.pem
csr_config=/etc/ssl/openssl.cnf

openssl req -sha256 \
   -key $privkey_file \
   -new -out $csr_file -outform pem \
   -config $csr_config
~~~

Your CA upon receiving your CSR would do its due diligence to verify this is a valid request, that you are indeed entitled to request such a certificate for the requested subject, and all kinds of checks.
If the CSR meets all the CA criteria, they will proceed to generate a certificate out of your CSR. The CA key type is often RSA, so it wouldn't be uncommon to obtain a certificate in which the issuer (the CA) owns an RSA key, and the subject is associated with an EC key. As an example I created my own fake CA key+certificate and signed a CSR for "Internet Widgits Pty Ltd".

The CA could sign your CSR using openssl like this:

~~~sh
ca_cert=ca_cert.pem
ca_privkey=ca_privkey.pem
ca_config=/etc/ssl/openssl.cnf
days=30
cert_file=mycertfileout.pem

openssl x509 \
    -req -in $csr_file \
    -CA $ca_cert -CAkey $ca_privkey \
    -CAcreateserial -config $ca_config \
    -days $days -sha256 \
    -out $cert_file
~~~

The resulting certificate could be inspected by:

~~~sh
openssl x509 -in $cert_file -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            5a:59:46:22:0c:71:16:24:31:52:bc:9c:d7:ac:39:11:36:44:97:d7
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = AU, ST = Some-State, O = Fake CA, OU = CA, CN = ca.fake.example.com
        Validity
            Not Before: Feb 19 20:50:47 2020 GMT
            Not After : Mar 20 20:50:47 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:6c:2d:42:83:8a:17:dc:8f:9f:c4:b4:e6:84:eb:
                    ac:90:7a:98:23:a2:9c:cf:35:da:cf:f7:79:bd:5d:
                    56:4d:de:5a:2a:72:7b:82:6c:bb:fa:ee:14:d7:2c:
                    45:d1:bf:a5:7c:ec:e2:30:01:9c:98:c9:42:0c:ae:
                    fd:84:a4:91:c4
                ASN1 OID: prime256v1
                NIST CURVE: P-256
    Signature Algorithm: sha256WithRSAEncryption
         c0:02:28:4e:3d:f0:b8:2a:a1:31:30:ec:f8:4f:8c:c3:d1:e2:
         c4:57:1e:ff:ce:d7:49:ad:44:68:71:00:43:f5:49:2e:2d:c0:
         06:0e:92:fa:d0:64:5c:b7:d9:ff:69:0b:0f:7b:7d:b5:32:48:
         1a:e4:87:8d:38:b5:01:1d:0a:3f:d1:f9:14:d5:27:c1:ad:54:
         c1:03:12:e7:ed:7e:35:af:db:82:25:e6:c5:29:84:52:45:5a:
         ed:8d:9c:d8:16:56:d5:3e:14:5c:5d:94:88:f5:b2:c1:d1:48:
         95:a2:c7:dc:17:a8:37:39:51:c5:42:a0:2a:76:7d:86:6c:cb:
         c9:84:63:df:86:bb:87:2e:17:b5:da:9b:08:ff:d6:2a:92:c0:
         9b:8b:29:cf:c4:73:c9:83:3a:e7:89:81:37:4d:52:1f:a2:f4:
         f4:01:4f:7d:67:d5:d1:50:44:f1:6c:f9:04:62:89:29:0e:40:
         4b:f2:04:c4:bc:78:02:25:05:e8:41:47:10:36:43:19:54:6f:
         77:1e:02:a9:63:c3:4a:23:7f:86:c9:88:f8:aa:57:89:49:87:
         d8:26:de:32:54:f1:8b:72:ac:75:08:ec:2c:cc:cc:c6:d9:66:
         00:a0:4d:a4:f1:d8:ae:c7:5e:b8:fd:62:6d:2a:ba:ce:63:17:
         30:bd:0c:cb
~~~

As you can see the signature on the certificate is an RSA signature (because the CA key in this example was an RSA key), while the Subject Public Key that the certificate authenticates is an EC key (over the NIST P-256 curve).
Normally you would distribute such certificate alongside a chain of certificates that can validate a trust link up to some trusted third party that your clients will recognize as trustworthy. 



Now in your first command in the last email you are merging all the 3 steps (keygen, CSR generation, CSR signing) into a single command to generate a key and a self signed certificate where the subject/issuer/signer is certifying itself.
This kind of certificate is not particularly useful if not for testing purposes or unless you are bootstrapping your own private PKI and control all your clients so that you can force them to include your new root CA certificate among their trusted certificates.

Compared to your original command, even here there is no need to create a separate param file as long as you are using named curves:

~~~sh
openssl req -sha256 \
   -newkey ec -pkeyopt ec_paramgen_curve:$curve_name -pkeyopt ec_param_enc:named_curve \
   -keyout $privkey_file \
   -new -x509 -out $cert_file -outform pem \
   -config $ca_config -days $days
~~~

This can be inspected with:

~~~sh
openssl x509 -noout -text -in $cert_file
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1d:ba:c3:dc:35:db:3f:3a:ca:21:ca:06:fe:4b:2b:3d:78:f8:e4:a7
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Validity
            Not Before: Feb 19 21:27:58 2020 GMT
            Not After : Mar 20 21:27:58 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:77:ce:fb:29:ed:1d:25:27:09:bd:27:56:95:88:
                    42:71:82:49:2f:ab:be:be:45:99:22:a8:1c:43:74:
                    af:f9:07:1b:49:b7:91:d1:5a:ea:bd:f1:b9:12:65:
                    dd:42:e2:83:ec:0b:96:03:b8:1d:5b:ea:81:02:28:
                    6d:a3:53:6a:2f
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD
            X509v3 Authority Key Identifier:
                keyid:D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:8c:9c:39:a1:70:0b:27:69:c9:2c:7d:52:7f:
         31:3d:b1:73:bf:15:9d:6c:df:73:98:58:2b:14:15:2d:87:63:
         25:02:20:2a:3f:b2:c0:f5:cd:83:8c:92:5d:e5:69:ad:34:33:
         7e:2a:ca:b1:2a:c0:21:2a:82:a1:51:f8:1c:07:7b:50:c5
~~~

From which it is evident that Issuer and Subject are identical, that the Subject key identifier matches the Authority key identifier, ans where the certificate signature is ECDSA because the Issuer key is an EC key.


I hope this long email clarified the doubts you expressed.


Cheers,

Nicola Tuveri


On Tue, 18 Feb 2020 at 19:45, Jason Schultz <[hidden email]> wrote:
Nicola-

Thanks for your response. It does help, but at the same time it also raises questions and maybe conflicts with what I thought I was doing correct earlier in this thread. I'm talking mostly about where I landed in this post:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions.


I am only using named curves. You also said:

"...you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate."

Let me apply that and start from the beginning and outline everything (I think) I need to do in that case:

1 - Generate a certificate and private key pair. Using the OpenSSL command line:

openssl req -nodes -sha256 -newkey ec:<(openssl ecparam -name prime256v1) 
-keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf 
-x509 -days 365 -outform pem

Note: the "ec:" parameter basically substitutes the openssl command above with the file I had created and used in this command. Also, the "-genkey" parameter I included in the ecparam command was probably not needed, or potentially bad?

2 - Call the SSL_CTX_use_PrivateKey_file() and SSL_CTX_use_certificate_file() to use the certificate and private key pair. (Same as before)

3 - Call the APIs to set the curves and allow the server to pick the appropriate curves for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

Do I have this right? Is the only difference combining the two commands into one in Step 1 above, instead of the intermediate ecparams file? Or is there something else I'm missing on the generation of certificate/private key pairs?

Thanks,

Jason





From: Nicola Tuveri <[hidden email]>
Sent: Tuesday, February 18, 2020 2:50 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
The ec parameters are public anyway, so there is no real need to store such files somewhere with restricted reading access.

On the other hand, I want to reiterate that if you are using (and this is highly recommended) one of the named curves (e.g. NIST P-256) you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate.

In the same way, for the ECDHE part, pick curves that you want to support (most TLS 1.2 and 1.3 clients will be happy to support P-256 and X25519 key exchanges) from the named curves: also in this case there is no need to generate a separate ecparam file.

Hope this helps!

Best regards,

Nicola Tuveri


On Tue, 18 Feb 2020 at 15:27, Jason Schultz <[hidden email]> wrote:
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Nicole-

This was very helpful, thank you for taking the time to respond. I was confused about the parameters files, I understand why they are not needed. 

Also, I should have been more clear, the creation of these cert/key pairs is strictly for testing purposes (and to give our users an easy way to test before they have their own certificate, signed by a CA). 

Thanks again.



From: Nicola Tuveri <[hidden email]>
Sent: Wednesday, February 19, 2020 9:42 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
I think there might be some confusion.

The "parameters" files are a legacy from when cryptosystems using "custom" domains were not widely deprecated.
Such parameter files were required for any instance of key generation, to make sure that a key was generated in the defined custom domain, and were part of any key serialization because in cryptosystems that define domain parameters a keypair is generally void of operational meaning if it isn't associated with a domain in which that keypair can be used to perform operations and also because when two or more peers are involved we need  to make sure that exchanged keys belonged to the same domain in which we chose to operate.

Nowadays the experts discourage "custom" domains (see e.g. RFC 8422), as they bring way more disadvantages than advantages, especially considering that the disadvantages include potential serious security pitfalls.

Historically you needed to pregenerate a domain parameters file for ephemeral DH used in the key exchange part of the TLS handshake, because key generation is a relatively cheap operation, but generating the big random primes required for creating new domain parameters is a quite demanding process: this was the params file that was provided to the SSL/TLS backend and needed to be saved alongside keys and certificates.
With ECDH, parameter generation for custom domains is even more involved, error prone, and the validation of custom parameters received from a peer is very expensive and littered with risks for the overall security if not done properly.

That being said, recommending "use named curves" just means to use well-established and studied set of parameters that standardizing bodies deemed recommendable for secure use: this way both peers refer to a set of parameters with a given common name rather than explicit parameters, and the clients can trust the evaluation done by experts rather than having to verify the received parameters for complex mathematical properties.

Now, to the commands in your email, it must be clear that there are a few cryptosystems involved in a generic TLS handshake:
1. key exchange: usually ephemeral ECDH
2. digital signature (to validate the handshake with the server credentials): commonly RSA, ECDSA or EdDSA (depending on the server key type)
3. digital signature (to validate the certificate where the CA states "this public key belongs to this subject"): commonly RSA, ECDSA or EdDSA (depending on the CA key type)

(We should note that 3 does not necessarily require a `verify()` operation for every handshake, because both the issuer and the subject credentials are static, so a certificate for a server could be validated once and cached for later use).

1)

Ephemeral ECDH generates a new keypair for every handshake, so the parties need to agree on which domain parameters to use.
We negotiate named curves rather than explicit parameters, and that is what `status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");` does: both parties specify a list of supported curves, and one in common is picked (preference on multiple hits is an irrelevant detail here).
So no need for a parameters file here, we use a list of names, and this is independent from the cryptosystem picked for the two digital signature operations.

2)

The server needs to have its own keypair, this means a one-time-only keygen operation for which parameters are necessary if we pick ECDSA as the cryptosystem of our choice.
You can do this using explicit parameters or a named curve, and the latter is preferred. In any case there is no need to store a parameters file after the key has been generated, as the key parameters are saved in the key serialization anyway, both for named and for custom curves.

There is no harm in generating an intermediary params file, but it is superfluous, and also the fact that there is no need to create such a file should answer to your original question about where/how it is best to store the parameter file. 

To generate such a private key without the need for an intermediate params file you could run:

~~~sh
curve_name=prime256v1
privkey_file=mykeyout.pem

openssl genpkey \
    -algorithm EC -pkeyopt ec_paramgen_curve:$curve_name \
    -pkeyopt ec_param_enc:named_curve \
    -outform pem -out $privkey_file
~~~

Once you have a private key you could generate a certificate signing request (CSR) for your CA to issue a certificate for your server:

~~~sh
csr_file=mycsrout.pem
csr_config=/etc/ssl/openssl.cnf

openssl req -sha256 \
   -key $privkey_file \
   -new -out $csr_file -outform pem \
   -config $csr_config
~~~

Your CA upon receiving your CSR would do its due diligence to verify this is a valid request, that you are indeed entitled to request such a certificate for the requested subject, and all kinds of checks.
If the CSR meets all the CA criteria, they will proceed to generate a certificate out of your CSR. The CA key type is often RSA, so it wouldn't be uncommon to obtain a certificate in which the issuer (the CA) owns an RSA key, and the subject is associated with an EC key. As an example I created my own fake CA key+certificate and signed a CSR for "Internet Widgits Pty Ltd".

The CA could sign your CSR using openssl like this:

~~~sh
ca_cert=ca_cert.pem
ca_privkey=ca_privkey.pem
ca_config=/etc/ssl/openssl.cnf
days=30
cert_file=mycertfileout.pem

openssl x509 \
    -req -in $csr_file \
    -CA $ca_cert -CAkey $ca_privkey \
    -CAcreateserial -config $ca_config \
    -days $days -sha256 \
    -out $cert_file
~~~

The resulting certificate could be inspected by:

~~~sh
openssl x509 -in $cert_file -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            5a:59:46:22:0c:71:16:24:31:52:bc:9c:d7:ac:39:11:36:44:97:d7
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = AU, ST = Some-State, O = Fake CA, OU = CA, CN = ca.fake.example.com
        Validity
            Not Before: Feb 19 20:50:47 2020 GMT
            Not After : Mar 20 20:50:47 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:6c:2d:42:83:8a:17:dc:8f:9f:c4:b4:e6:84:eb:
                    ac:90:7a:98:23:a2:9c:cf:35:da:cf:f7:79:bd:5d:
                    56:4d:de:5a:2a:72:7b:82:6c:bb:fa:ee:14:d7:2c:
                    45:d1:bf:a5:7c:ec:e2:30:01:9c:98:c9:42:0c:ae:
                    fd:84:a4:91:c4
                ASN1 OID: prime256v1
                NIST CURVE: P-256
    Signature Algorithm: sha256WithRSAEncryption
         c0:02:28:4e:3d:f0:b8:2a:a1:31:30:ec:f8:4f:8c:c3:d1:e2:
         c4:57:1e:ff:ce:d7:49:ad:44:68:71:00:43:f5:49:2e:2d:c0:
         06:0e:92:fa:d0:64:5c:b7:d9:ff:69:0b:0f:7b:7d:b5:32:48:
         1a:e4:87:8d:38:b5:01:1d:0a:3f:d1:f9:14:d5:27:c1:ad:54:
         c1:03:12:e7:ed:7e:35:af:db:82:25:e6:c5:29:84:52:45:5a:
         ed:8d:9c:d8:16:56:d5:3e:14:5c:5d:94:88:f5:b2:c1:d1:48:
         95:a2:c7:dc:17:a8:37:39:51:c5:42:a0:2a:76:7d:86:6c:cb:
         c9:84:63:df:86:bb:87:2e:17:b5:da:9b:08:ff:d6:2a:92:c0:
         9b:8b:29:cf:c4:73:c9:83:3a:e7:89:81:37:4d:52:1f:a2:f4:
         f4:01:4f:7d:67:d5:d1:50:44:f1:6c:f9:04:62:89:29:0e:40:
         4b:f2:04:c4:bc:78:02:25:05:e8:41:47:10:36:43:19:54:6f:
         77:1e:02:a9:63:c3:4a:23:7f:86:c9:88:f8:aa:57:89:49:87:
         d8:26:de:32:54:f1:8b:72:ac:75:08:ec:2c:cc:cc:c6:d9:66:
         00:a0:4d:a4:f1:d8:ae:c7:5e:b8:fd:62:6d:2a:ba:ce:63:17:
         30:bd:0c:cb
~~~

As you can see the signature on the certificate is an RSA signature (because the CA key in this example was an RSA key), while the Subject Public Key that the certificate authenticates is an EC key (over the NIST P-256 curve).
Normally you would distribute such certificate alongside a chain of certificates that can validate a trust link up to some trusted third party that your clients will recognize as trustworthy. 



Now in your first command in the last email you are merging all the 3 steps (keygen, CSR generation, CSR signing) into a single command to generate a key and a self signed certificate where the subject/issuer/signer is certifying itself.
This kind of certificate is not particularly useful if not for testing purposes or unless you are bootstrapping your own private PKI and control all your clients so that you can force them to include your new root CA certificate among their trusted certificates.

Compared to your original command, even here there is no need to create a separate param file as long as you are using named curves:

~~~sh
openssl req -sha256 \
   -newkey ec -pkeyopt ec_paramgen_curve:$curve_name -pkeyopt ec_param_enc:named_curve \
   -keyout $privkey_file \
   -new -x509 -out $cert_file -outform pem \
   -config $ca_config -days $days
~~~

This can be inspected with:

~~~sh
openssl x509 -noout -text -in $cert_file
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1d:ba:c3:dc:35:db:3f:3a:ca:21:ca:06:fe:4b:2b:3d:78:f8:e4:a7
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Validity
            Not Before: Feb 19 21:27:58 2020 GMT
            Not After : Mar 20 21:27:58 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:77:ce:fb:29:ed:1d:25:27:09:bd:27:56:95:88:
                    42:71:82:49:2f:ab:be:be:45:99:22:a8:1c:43:74:
                    af:f9:07:1b:49:b7:91:d1:5a:ea:bd:f1:b9:12:65:
                    dd:42:e2:83:ec:0b:96:03:b8:1d:5b:ea:81:02:28:
                    6d:a3:53:6a:2f
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD
            X509v3 Authority Key Identifier:
                keyid:D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:8c:9c:39:a1:70:0b:27:69:c9:2c:7d:52:7f:
         31:3d:b1:73:bf:15:9d:6c:df:73:98:58:2b:14:15:2d:87:63:
         25:02:20:2a:3f:b2:c0:f5:cd:83:8c:92:5d:e5:69:ad:34:33:
         7e:2a:ca:b1:2a:c0:21:2a:82:a1:51:f8:1c:07:7b:50:c5
~~~

From which it is evident that Issuer and Subject are identical, that the Subject key identifier matches the Authority key identifier, ans where the certificate signature is ECDSA because the Issuer key is an EC key.


I hope this long email clarified the doubts you expressed.


Cheers,

Nicola Tuveri


On Tue, 18 Feb 2020 at 19:45, Jason Schultz <[hidden email]> wrote:
Nicola-

Thanks for your response. It does help, but at the same time it also raises questions and maybe conflicts with what I thought I was doing correct earlier in this thread. I'm talking mostly about where I landed in this post:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions.


I am only using named curves. You also said:

"...you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate."

Let me apply that and start from the beginning and outline everything (I think) I need to do in that case:

1 - Generate a certificate and private key pair. Using the OpenSSL command line:

openssl req -nodes -sha256 -newkey ec:<(openssl ecparam -name prime256v1) 
-keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf 
-x509 -days 365 -outform pem

Note: the "ec:" parameter basically substitutes the openssl command above with the file I had created and used in this command. Also, the "-genkey" parameter I included in the ecparam command was probably not needed, or potentially bad?

2 - Call the SSL_CTX_use_PrivateKey_file() and SSL_CTX_use_certificate_file() to use the certificate and private key pair. (Same as before)

3 - Call the APIs to set the curves and allow the server to pick the appropriate curves for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

Do I have this right? Is the only difference combining the two commands into one in Step 1 above, instead of the intermediate ecparams file? Or is there something else I'm missing on the generation of certificate/private key pairs?

Thanks,

Jason





From: Nicola Tuveri <[hidden email]>
Sent: Tuesday, February 18, 2020 2:50 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
The ec parameters are public anyway, so there is no real need to store such files somewhere with restricted reading access.

On the other hand, I want to reiterate that if you are using (and this is highly recommended) one of the named curves (e.g. NIST P-256) you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate.

In the same way, for the ECDHE part, pick curves that you want to support (most TLS 1.2 and 1.3 clients will be happy to support P-256 and X25519 key exchanges) from the named curves: also in this case there is no need to generate a separate ecparam file.

Hope this helps!

Best regards,

Nicola Tuveri


On Tue, 18 Feb 2020 at 15:27, Jason Schultz <[hidden email]> wrote:
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.

 

Reply | Threaded
Open this post in threaded view
|

Re: Questions about using Elliptic Curve ciphers in OpenSSL

Jason Schultz
Nicola...my apologies for the typo...


From: openssl-users <[hidden email]> on behalf of Jason Schultz <[hidden email]>
Sent: Friday, February 21, 2020 1:05 PM
To: Nicola Tuveri <[hidden email]>
Cc: openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Nicole-

This was very helpful, thank you for taking the time to respond. I was confused about the parameters files, I understand why they are not needed. 

Also, I should have been more clear, the creation of these cert/key pairs is strictly for testing purposes (and to give our users an easy way to test before they have their own certificate, signed by a CA). 

Thanks again.



From: Nicola Tuveri <[hidden email]>
Sent: Wednesday, February 19, 2020 9:42 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
I think there might be some confusion.

The "parameters" files are a legacy from when cryptosystems using "custom" domains were not widely deprecated.
Such parameter files were required for any instance of key generation, to make sure that a key was generated in the defined custom domain, and were part of any key serialization because in cryptosystems that define domain parameters a keypair is generally void of operational meaning if it isn't associated with a domain in which that keypair can be used to perform operations and also because when two or more peers are involved we need  to make sure that exchanged keys belonged to the same domain in which we chose to operate.

Nowadays the experts discourage "custom" domains (see e.g. RFC 8422), as they bring way more disadvantages than advantages, especially considering that the disadvantages include potential serious security pitfalls.

Historically you needed to pregenerate a domain parameters file for ephemeral DH used in the key exchange part of the TLS handshake, because key generation is a relatively cheap operation, but generating the big random primes required for creating new domain parameters is a quite demanding process: this was the params file that was provided to the SSL/TLS backend and needed to be saved alongside keys and certificates.
With ECDH, parameter generation for custom domains is even more involved, error prone, and the validation of custom parameters received from a peer is very expensive and littered with risks for the overall security if not done properly.

That being said, recommending "use named curves" just means to use well-established and studied set of parameters that standardizing bodies deemed recommendable for secure use: this way both peers refer to a set of parameters with a given common name rather than explicit parameters, and the clients can trust the evaluation done by experts rather than having to verify the received parameters for complex mathematical properties.

Now, to the commands in your email, it must be clear that there are a few cryptosystems involved in a generic TLS handshake:
1. key exchange: usually ephemeral ECDH
2. digital signature (to validate the handshake with the server credentials): commonly RSA, ECDSA or EdDSA (depending on the server key type)
3. digital signature (to validate the certificate where the CA states "this public key belongs to this subject"): commonly RSA, ECDSA or EdDSA (depending on the CA key type)

(We should note that 3 does not necessarily require a `verify()` operation for every handshake, because both the issuer and the subject credentials are static, so a certificate for a server could be validated once and cached for later use).

1)

Ephemeral ECDH generates a new keypair for every handshake, so the parties need to agree on which domain parameters to use.
We negotiate named curves rather than explicit parameters, and that is what `status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");` does: both parties specify a list of supported curves, and one in common is picked (preference on multiple hits is an irrelevant detail here).
So no need for a parameters file here, we use a list of names, and this is independent from the cryptosystem picked for the two digital signature operations.

2)

The server needs to have its own keypair, this means a one-time-only keygen operation for which parameters are necessary if we pick ECDSA as the cryptosystem of our choice.
You can do this using explicit parameters or a named curve, and the latter is preferred. In any case there is no need to store a parameters file after the key has been generated, as the key parameters are saved in the key serialization anyway, both for named and for custom curves.

There is no harm in generating an intermediary params file, but it is superfluous, and also the fact that there is no need to create such a file should answer to your original question about where/how it is best to store the parameter file. 

To generate such a private key without the need for an intermediate params file you could run:

~~~sh
curve_name=prime256v1
privkey_file=mykeyout.pem

openssl genpkey \
    -algorithm EC -pkeyopt ec_paramgen_curve:$curve_name \
    -pkeyopt ec_param_enc:named_curve \
    -outform pem -out $privkey_file
~~~

Once you have a private key you could generate a certificate signing request (CSR) for your CA to issue a certificate for your server:

~~~sh
csr_file=mycsrout.pem
csr_config=/etc/ssl/openssl.cnf

openssl req -sha256 \
   -key $privkey_file \
   -new -out $csr_file -outform pem \
   -config $csr_config
~~~

Your CA upon receiving your CSR would do its due diligence to verify this is a valid request, that you are indeed entitled to request such a certificate for the requested subject, and all kinds of checks.
If the CSR meets all the CA criteria, they will proceed to generate a certificate out of your CSR. The CA key type is often RSA, so it wouldn't be uncommon to obtain a certificate in which the issuer (the CA) owns an RSA key, and the subject is associated with an EC key. As an example I created my own fake CA key+certificate and signed a CSR for "Internet Widgits Pty Ltd".

The CA could sign your CSR using openssl like this:

~~~sh
ca_cert=ca_cert.pem
ca_privkey=ca_privkey.pem
ca_config=/etc/ssl/openssl.cnf
days=30
cert_file=mycertfileout.pem

openssl x509 \
    -req -in $csr_file \
    -CA $ca_cert -CAkey $ca_privkey \
    -CAcreateserial -config $ca_config \
    -days $days -sha256 \
    -out $cert_file
~~~

The resulting certificate could be inspected by:

~~~sh
openssl x509 -in $cert_file -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            5a:59:46:22:0c:71:16:24:31:52:bc:9c:d7:ac:39:11:36:44:97:d7
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = AU, ST = Some-State, O = Fake CA, OU = CA, CN = ca.fake.example.com
        Validity
            Not Before: Feb 19 20:50:47 2020 GMT
            Not After : Mar 20 20:50:47 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:6c:2d:42:83:8a:17:dc:8f:9f:c4:b4:e6:84:eb:
                    ac:90:7a:98:23:a2:9c:cf:35:da:cf:f7:79:bd:5d:
                    56:4d:de:5a:2a:72:7b:82:6c:bb:fa:ee:14:d7:2c:
                    45:d1:bf:a5:7c:ec:e2:30:01:9c:98:c9:42:0c:ae:
                    fd:84:a4:91:c4
                ASN1 OID: prime256v1
                NIST CURVE: P-256
    Signature Algorithm: sha256WithRSAEncryption
         c0:02:28:4e:3d:f0:b8:2a:a1:31:30:ec:f8:4f:8c:c3:d1:e2:
         c4:57:1e:ff:ce:d7:49:ad:44:68:71:00:43:f5:49:2e:2d:c0:
         06:0e:92:fa:d0:64:5c:b7:d9:ff:69:0b:0f:7b:7d:b5:32:48:
         1a:e4:87:8d:38:b5:01:1d:0a:3f:d1:f9:14:d5:27:c1:ad:54:
         c1:03:12:e7:ed:7e:35:af:db:82:25:e6:c5:29:84:52:45:5a:
         ed:8d:9c:d8:16:56:d5:3e:14:5c:5d:94:88:f5:b2:c1:d1:48:
         95:a2:c7:dc:17:a8:37:39:51:c5:42:a0:2a:76:7d:86:6c:cb:
         c9:84:63:df:86:bb:87:2e:17:b5:da:9b:08:ff:d6:2a:92:c0:
         9b:8b:29:cf:c4:73:c9:83:3a:e7:89:81:37:4d:52:1f:a2:f4:
         f4:01:4f:7d:67:d5:d1:50:44:f1:6c:f9:04:62:89:29:0e:40:
         4b:f2:04:c4:bc:78:02:25:05:e8:41:47:10:36:43:19:54:6f:
         77:1e:02:a9:63:c3:4a:23:7f:86:c9:88:f8:aa:57:89:49:87:
         d8:26:de:32:54:f1:8b:72:ac:75:08:ec:2c:cc:cc:c6:d9:66:
         00:a0:4d:a4:f1:d8:ae:c7:5e:b8:fd:62:6d:2a:ba:ce:63:17:
         30:bd:0c:cb
~~~

As you can see the signature on the certificate is an RSA signature (because the CA key in this example was an RSA key), while the Subject Public Key that the certificate authenticates is an EC key (over the NIST P-256 curve).
Normally you would distribute such certificate alongside a chain of certificates that can validate a trust link up to some trusted third party that your clients will recognize as trustworthy. 



Now in your first command in the last email you are merging all the 3 steps (keygen, CSR generation, CSR signing) into a single command to generate a key and a self signed certificate where the subject/issuer/signer is certifying itself.
This kind of certificate is not particularly useful if not for testing purposes or unless you are bootstrapping your own private PKI and control all your clients so that you can force them to include your new root CA certificate among their trusted certificates.

Compared to your original command, even here there is no need to create a separate param file as long as you are using named curves:

~~~sh
openssl req -sha256 \
   -newkey ec -pkeyopt ec_paramgen_curve:$curve_name -pkeyopt ec_param_enc:named_curve \
   -keyout $privkey_file \
   -new -x509 -out $cert_file -outform pem \
   -config $ca_config -days $days
~~~

This can be inspected with:

~~~sh
openssl x509 -noout -text -in $cert_file
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1d:ba:c3:dc:35:db:3f:3a:ca:21:ca:06:fe:4b:2b:3d:78:f8:e4:a7
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Validity
            Not Before: Feb 19 21:27:58 2020 GMT
            Not After : Mar 20 21:27:58 2020 GMT
        Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, OU = private root CA, CN = root_ca.example.com                                                                                                                  
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:77:ce:fb:29:ed:1d:25:27:09:bd:27:56:95:88:
                    42:71:82:49:2f:ab:be:be:45:99:22:a8:1c:43:74:
                    af:f9:07:1b:49:b7:91:d1:5a:ea:bd:f1:b9:12:65:
                    dd:42:e2:83:ec:0b:96:03:b8:1d:5b:ea:81:02:28:
                    6d:a3:53:6a:2f
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD
            X509v3 Authority Key Identifier:
                keyid:D8:87:52:0C:DE:12:5F:2F:04:22:7B:EE:CF:E9:A2:4B:18:E2:AE:FD

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:8c:9c:39:a1:70:0b:27:69:c9:2c:7d:52:7f:
         31:3d:b1:73:bf:15:9d:6c:df:73:98:58:2b:14:15:2d:87:63:
         25:02:20:2a:3f:b2:c0:f5:cd:83:8c:92:5d:e5:69:ad:34:33:
         7e:2a:ca:b1:2a:c0:21:2a:82:a1:51:f8:1c:07:7b:50:c5
~~~

From which it is evident that Issuer and Subject are identical, that the Subject key identifier matches the Authority key identifier, ans where the certificate signature is ECDSA because the Issuer key is an EC key.


I hope this long email clarified the doubts you expressed.


Cheers,

Nicola Tuveri


On Tue, 18 Feb 2020 at 19:45, Jason Schultz <[hidden email]> wrote:
Nicola-

Thanks for your response. It does help, but at the same time it also raises questions and maybe conflicts with what I thought I was doing correct earlier in this thread. I'm talking mostly about where I landed in this post:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions.


I am only using named curves. You also said:

"...you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate."

Let me apply that and start from the beginning and outline everything (I think) I need to do in that case:

1 - Generate a certificate and private key pair. Using the OpenSSL command line:

openssl req -nodes -sha256 -newkey ec:<(openssl ecparam -name prime256v1) 
-keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf 
-x509 -days 365 -outform pem

Note: the "ec:" parameter basically substitutes the openssl command above with the file I had created and used in this command. Also, the "-genkey" parameter I included in the ecparam command was probably not needed, or potentially bad?

2 - Call the SSL_CTX_use_PrivateKey_file() and SSL_CTX_use_certificate_file() to use the certificate and private key pair. (Same as before)

3 - Call the APIs to set the curves and allow the server to pick the appropriate curves for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

Do I have this right? Is the only difference combining the two commands into one in Step 1 above, instead of the intermediate ecparams file? Or is there something else I'm missing on the generation of certificate/private key pairs?

Thanks,

Jason





From: Nicola Tuveri <[hidden email]>
Sent: Tuesday, February 18, 2020 2:50 PM
To: Jason Schultz <[hidden email]>
Cc: Kyle Hamilton <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
The ec parameters are public anyway, so there is no real need to store such files somewhere with restricted reading access.

On the other hand, I want to reiterate that if you are using (and this is highly recommended) one of the named curves (e.g. NIST P-256) you don't really need at all to generate a ecparam file (which only contains the name): the private key file already contains the very same name and fully contains what you need to perform ECDSA signatures that can be validated against a matching certificate.

In the same way, for the ECDHE part, pick curves that you want to support (most TLS 1.2 and 1.3 clients will be happy to support P-256 and X25519 key exchanges) from the named curves: also in this case there is no need to generate a separate ecparam file.

Hope this helps!

Best regards,

Nicola Tuveri


On Tue, 18 Feb 2020 at 15:27, Jason Schultz <[hidden email]> wrote:
This comment does spark another question though. Do I need to protect the ecparam file I created for us in generating the private key? I know the private key should reside in /etc/ssl/private/ as that directory has no read access. Right now I have the ecparam generated file in /etc/ssl/dsaparams/, which is readable. Should that file also reside in /etc/ssl/private/ so it's protected?

Thanks.



From: Kyle Hamilton <[hidden email]>
Sent: Sunday, February 16, 2020 10:49 PM
To: Jason Schultz <[hidden email]>
Cc: Thulasi Goriparthi <[hidden email]>; openssl-users <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
Be aware that you just posted your certificate's private key, and thus you should regenerate a new keypair/certificate to use.  Otherwise, anyone who can manipulate traffic to your machine can execute a man-in-the-middle attack.

-Kyle H


On Fri, Feb 14, 2020, 07:40 Jason Schultz <[hidden email]> wrote:

Thank you for your response Thulasi, this helped. I'm posting this back to the OpenSSL users list in case it helps anyone else, and in case anyone can help with my additional questions. While waiting for responses, I've been able to find out how my certificate and keys were generated. I'd like to walk through that to hopefully verify I'm handling things correctly.

First, here is how my EC parameters file was generated:

openssl ecparam -name prime256v1 -genkey -out myecparamsfile.pem

And the resulting file:

M640A-SAIL:/etc/ssl # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


 # openssl ecparam -in myecparamsfile.pem -text

ASN1 OID: prime256v1

NIST CURVE: P-256

-----BEGIN EC PARAMETERS-----

BggqhkjOPQMBBw==

-----END EC PARAMETERS-----


Is this good so far? Do I need the -genkey?

Then I take this file and use it when I generate my certificate and private key pair, here is the openssl command I used:

openssl req -nodes -sha256 -newkey ec:/etc/ssl/private/myecparamsfile.pem -keyout mykeyout.pem -new -out mycertfileout.pem -config /etc/ssl/openssl.cnf -x509 -days 365 -outform pem
Generating a EC private key
writing new private key to 'mykeyout.pem'
<parameter input snipped>

And the resulting key:

# cat mykeyout.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgbfUwVhomun9Q5IAY
xTOAn+sDoXZ+k4UWkvUyfshPBJ6hRANCAAQsakFVUTV4JmfVJH31XOvHVhhBodnV
8evYCJSd2Jgo4uOomCSh3oekKL+Tia+LOmynygfvmneOX2YadoNr9uzH
-----END PRIVATE KEY-----

# openssl ec -noout -text -in mykeyout.pem
read EC key
Private-Key: (256 bit)
priv:
    6d:f5:30:56:1a:26:ba:7f:50:e4:80:18:c5:33:80:
    9f:eb:03:a1:76:7e:93:85:16:92:f5:32:7e:c8:4f:
    04:9e
pub:
    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
    83:6b:f6:ec:c7
ASN1 OID: prime256v1
NIST CURVE: P-256

And certificate:

M740A-PMM1:/etc/ssl # openssl x509 -text -in mycertfileout.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e2:2f:c6:e4:bf:f1:de:20
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Validity
            Not Before: Feb 13 16:11:39 2020 GMT
            Not After : Feb 12 16:11:39 2021 GMT
        Subject: C=US, ST=NY, L=Loc, O=Org, OU=test, CN=My Name/emailAddress=test@example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:2c:6a:41:55:51:35:78:26:67:d5:24:7d:f5:5c:
                    eb:c7:56:18:41:a1:d9:d5:f1:eb:d8:08:94:9d:d8:
                    98:28:e2:e3:a8:98:24:a1:de:87:a4:28:bf:93:89:
                    af:8b:3a:6c:a7:ca:07:ef:9a:77:8e:5f:66:1a:76:
                    83:6b:f6:ec:c7
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9
            X509v3 Authority Key Identifier:
                keyid:D6:8A:F3:3B:4E:A1:F8:F8:34:C1:1B:7A:EC:BF:9B:58:7F:68:4A:D9

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:37:f0:f7:f7:4a:b4:8e:8f:64:72:e4:d1:31:9f:
         a1:36:c5:5d:f3:42:4c:24:37:75:cf:b6:55:b0:66:1b:6e:63:
         02:20:39:18:81:f8:6c:86:3a:57:74:05:cc:99:6c:d9:dc:6a:
         a2:20:98:4c:66:a1:97:d1:c7:ea:42:b4:01:1a:f7:b2

Then I call the APIs as described in my first email to use them:

ctx = SSL_CTX_new(TLS_method());
status = SSL_CTX_use_PrivateKey_file(ctx,<keyfile>,SSL_FILETYPE_PEM);
status = SSL_CTX_use_certificate_file(ctx, ,<certfile>,SSL_FILETYPE_PEM);

// Verify the cert and key are a pair
status = SSL_CTX_check_private_key(ctx);

Then call the APIs to set the curves and allow the server to pick the appropriate curve for the client:

status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");
status = SSL_CTX_set_ecdh_auto(ctx, 1);

That should be it, right? The EC parameters file has been used to generate the private key, it does not need to be read in by an API call.

With the steps above, I get a successful TLS connection from a client using ECDHE-ECDSA-AES256-GCM-SHA384.

And yes, I think my main confusion was on what to do with the DH parameters file. I thought using ECDHE key exchange was similar to DSA with DH. With ECDHE, I don't need to read in a parameters file at all.

If there's anything wrong above, please let me know, otherwise, thanks for all the help!



From: Thulasi Goriparthi <[hidden email]>
Sent: Wednesday, February 12, 2020 8:29 AM
To: [hidden email] <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: Questions about using Elliptic Curve ciphers in OpenSSL
 
To clarify further, EC keys can be generated from either explicit (group) parameters or named curves which are standardized numbers to specific group parameters.

Explicit/Custom EC parameters are not recommended/convenient/usual. Your key contains parameters in the form of a named curve (p-256).

You are probably getting confused between dhparam used to generate ephemeral keys for DHE based key exchange and EC curve selection for ECDHE based key exchange. 

Curve selection for ECDHE will be done from the list of curves offered by the client and can be different from the curve used in the server's certificate(ECDSA).

Thanks,
Thulasi.


On Tue, 11 Feb, 2020, 23:24 Salz, Rich via openssl-users, <[hidden email]> wrote:

I believe you just load your ECDSA cert and the other stuff – Dhparams!! – is not needed.