Search code examples
c++opensslx509

OpenSSL certificate generation for DHE exchange


I'm a beginner in the matter of security and OpenSSL. My objective is to programatically generate a certificate that passes the "obsolete" shaming that Chrome does. The certificates I used to generate used AES_128_GCM with RSA even though I tried setting the cipher list to kEECDH:kEDH:!ADH:AES256-SHA256 and the server context uses SSL_CTX_new(TLSv1_2_server_method());.

Based on the example from the documentation I tried the following :

X509 *x = NULL;
EVP_PKEY *pk = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *params = NULL;

if(NULL == (params = EVP_PKEY_new()))
    goto err;

if(1 != EVP_PKEY_set1_DH(params, DH_get_2048_256()))
    goto err;

if(!(ctx = EVP_PKEY_CTX_new(params, NULL)))
    goto err;

if(!EVP_PKEY_keygen_init(ctx))
    goto err;

if(!EVP_PKEY_keygen(ctx, &pk))
    goto err;

if ((x=X509_new()) == NULL)
    goto err;

X509_set_version(x,2);
X509_set_pubkey(x,pk);

//... (setting the issuer, subject, etc)

//Here is where it fails
if (!X509_sign(x,pk,EVP_sha256()))
    goto err;

The same code for RSA instead of DH works. The error that X509_sign gives is EVP_PKEY_sign_init operation not supported for this keytype.

What could I do? I would prefer the connection to use ECDHE but I have no idea how to set that up. I need this to be secure within reason but my knowledge of security is really limited. I am working on it though. Any help would be appreciated but please provide code with your answer (not command-line generation).


Solution

  • My objective is to programatically generate a certificate that passes the "obsolete" shaming that Chrome does...
    What could I do? I would prefer the connection to use ECDHE but I have no idea how to set that up....
    I tried setting the cipher list to kEECDH:kEDH:!ADH:AES256-SHA256...

    Usually, HIGH:!aNULL:!RC4:!MD5 is enough. Since you want to use the ephemeral key exchanges (whihc is a good thing), you should remove RSA key transport, too: HIGH:!aNULL:!kRSA:!RC4:!MD5.


    Based on the example from the documentation...

    Also see SSL/TLS Client on the OpenSSL wiki. Its a client, but it shows you how to set up a context.

    Because its a server, you will also probably want context options like SSL_OP_SAFARI_ECDHE_ECDSA_BUG.


    OpenSSL certificate generation for DHE exchange

    Just about any certificate will do. It can be a RSA key, an DSS key or an ECDSA key. The key in the certificate will be used to sign server messages (some hand waiving), so its used for server authentication.

    Ephemeral key exchanges are different. You ensure that with SSL_CTX_set_cipher_list and the cipher suite string.


    Since you are not using cipher suites like SRP and PSK you can remove them too. RSA still shows up, but its for server authentication, and not key transport:

    $ openssl ciphers -v 'HIGH:!aNULL:!kRSA:!RC4:!MD5:!3DES:!DSS:!DSA:!SRP:!PSK'
    ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
    ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
    ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
    ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
    ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
    ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
    DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
    DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
    DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
    DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
    ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
    ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
    ECDH-RSA-AES256-SHA384  TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA384
    ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA384
    ECDH-RSA-AES256-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256)  Mac=SHA1
    ECDH-ECDSA-AES256-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256)  Mac=SHA1
    ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
    ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
    ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
    ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256
    ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
    ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
    DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(128) Mac=AEAD
    DHE-RSA-AES128-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA256
    DHE-RSA-AES128-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(128)  Mac=SHA1
    DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(128) Mac=SHA1
    ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
    ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
    ECDH-RSA-AES128-SHA256  TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128)  Mac=SHA256
    ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128)  Mac=SHA256
    ECDH-RSA-AES128-SHA     SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128)  Mac=SHA1
    ECDH-ECDSA-AES128-SHA   SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128)  Mac=SHA1