I am using RSA cipher for signing the certificate and SSL_CTX_set_tmp_ecdh_callback() api to set the ECDH parameters for key-exchange. The server always ends up choosing TLS_ECDHE_RSA_* cipher suite. If i make the client send only TLS_ECDH_* cipher suites in the clientHello, the server breaks the connection stating "no shared cipher".
Can someone tell me how to make a server choose a ECDH_* cipher over ECDHE_* ?
How is it that the server decides I should choose ECDH_* cipher over ECDHE_* ciphers ?
                        
Now that this is moved where it's ontopic, and clarified enough, and the partying is over:
Ephemeral ECDH suites: TLS suites that use ephemeral ECDH key exchange (
ECDHE-*) use at least nominally ephemeral ECDH keys, which OpenSSL calls 'temporary'. OpenSSL through 1.0.2 has 4-6 ways of setting these keys:SSL_CTX_set_tmp_ecdhorSSL_set_tmp_ecdhset (only) the 'curve' to be used; to be exact this is anEC_GROUPor formally 'parameter set' that consists of an actual curve defined by a curve equation on an underlying field, plus a specified base point which generates a subgroup on the curve of sufficiently high order and low cofactor, but most of the time we ignore this detail and just call it a 'curve'. OpenSSL then generates a random key on that curve for and during each handshake.SSL_CTX_set_tmp_ecdh_callbackorSSL_set_tmp_ecdh_callbacksets a function that is called during each handshake and can either set a specific key, or set a curve and OpenSSL generates a random key on that curve.SSL_CTX_set_ecdh_autoorSSL_set_ecdh_autonew in 1.0.2 causes OpenSSL during each handshake to choose a curve based on the client hello, and generate a random key on that curve.Note that each ciphersuite using ECDHE also defines the type of key with matching certificate chain the server must use to authenticate:
ECDHE-RSAmust use an RSA key&cert whileECDHE-ECDSAmust use an ECDSA key&cert (or to be precise EC key and ECDSA cert, since the same EC key can be used for ECDSA, ECDH, ECIES, and more, but usually shouldn't). OpenSSL library can be configured with multiple key&cert pairs, one of each type, and commandlines_servercan do two static pairs using-cert -key -dcert -dkeyplus one for SNI-cert2 -key2, but other programs may or may not.However, in 1.1.0 these functions are removed and it appears OpenSSL always does what was formerly
ecdh_auto.Static ECDH suites: TLS suites that use static aka fixed ECDH key exchange (
ECDH-*) use a static ECDH key and do not use an ephemeral or temporary ECDH key. Since they do not use a temporary key, the functions involved in setting a temporary curve or key are irrelevant and have no useful effect. Instead the static ECDH key must be in the server's configured key and certificate pair, and the certificate must allow ECDH i.e. it must not havekeyUsagethat excludeskeyAgreement. In addition, in TLS 1.0 and 1.1 the configured certificate must be signed by a CA using a signature algorithm matching the ciphersuite:ECDH-ECDSAciphersuites must use an ECDH cert signed by an ECDSA CA, andECDH-RSAciphersuites must use an ECDH cert signed by an RSA CA; see rfc4492 section 5.3. For TLS 1.2 rfc 5246 section 7.4.2 and A.7 for ECC relaxes this requirement and allows the CA cert to be any algorithm permitted by the client's signature_algorithms extension. However on checking I found OpenSSL doesn't implement this relaxation, so part of my earlier comment is wrong; even for 1.2 it requires the CA signature algorithm match the ciphersuite.In addition for all protocol versions the key and (EE) cert must use a curve supported by the client in supported_curves extension, and the cert must express that key in 'named' form (using an OID to identify the curve rather than explicit parameters) and a point format supported by the client in supported_formats extension. With OpenSSL client this is never an issue because it supports all named curves and point formats, and in practice certificates don't use explicit curve parameters.
Thus to get static ECDH with OpenSSL:
configure the server with an EC key (
SSL_[CTX_]use_PrivateKey*) and matching certificate (SSL_[CTX_]use_certificate[_chain]*) that allows keyAgreement and is signed by a CA using RSA or ECDSA -- and like all PK-based ciphersuites also configure any chain certs needed by the client(s) to validate the certconfigure both ends to allow (which is true by default) and at least one end to require or the preference end to prefer ciphersuite(s) using
ECDH-xyzwherexyzisRSAorECDSAto match the CA signature on the server certignore
ecdh_tmpandecdh_autoentirely... except in 1.1.0, which on checking I found no longer implements any static-ECDH or static-DH ciphersuites -- even though the static-DH suites are still in the manpage for ciphers. This is not in the CHANGES file that I can find, and I haven't had time to go through the code yet.