Search code examples
sslopenssltls1.2tls-psk

openSSL 1.1.1 API Doubts


I want to set up and run SSL client and server with TLS 1.2 using openSSL 1.1.1 for my project.

I have a few doubts and/or requirements with openSSL:

  1. what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?

  2. I need to run an SSL clinet with following handshake extensions.

    • ec_point_formats with "uncompressed" as value
    • supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"
    • encrypt_then_mac with value 0
    • server_name
    • extended_master_secret without any value and length set to 0
  3. I need to run an SSL server with following handshake extensions

    • encrypt_then_mac with value 0
    • extended_master_secret without any value and length set to 0
  4. Apart from above header extension fields I want to disable everything else. How to accomplish that?

  5. From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.

  6. Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?

  7. Is there any example or open source client-server implementation with PSK authentication?


Solution

  • what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?

    TLS_client_method() is the correct method to use. To specify that no version below TLSv1.2 is used you should do this:

    SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
    

    Where ctx is your SSL_CTX object.

    If you also want to prevent anything higher than TLSv1.2 from being used then do this:

    SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
    

    See this page for information on these calls: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_min_proto_version.html

    I need to run an SSL clinet with following handshake extensions.

    • ec_point_formats with "uncompressed" as value
    • supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"

    These extensions aren't used if you specify the PSK ciphersuite that you've selected so OpenSSL won't send them (assuming you've restricted the max TLS protocol version as described above, and have configured only that ciphersuite). Doing so would be pointless. Even if it did, OpenSSL 1.1.1 does not support "ffdhe2048". It does support all the others.

    • encrypt_then_mac with value 0

    Not sure what you mean by "with value 0" since this extension is always empty and has no value. I assume you mean with length 0. This extension is sent by default so you don't need to do anything.

    • server_name

    You should call:

    SSL_set_tlsext_host_name(ssl, "hostname of the server");
    

    Where ssl is your SSL object, and replacing "hostname of the server" with the server's real hostname.

    See this page for information on this call: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_tlsext_host_name.html

    • extended_master_secret without any value and length set to 0

    This extension is sent by default so you don't need to do anything.

    I need to run an SSL server with following handshake extensions

    • encrypt_then_mac with value 0
    • extended_master_secret without any value and length set to 0

    If the client sent them, then the server will echo them back by default. You don't need to do anything.

    Apart from above header extension fields I want to disable everything else. How to accomplish that?

    An OpenSSL client will additionally send the session_ticket extension. Its harmless, but if you really want to disable it you can do this:

    SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
    

    See this page for further information: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_options.html

    An OpenSSL server will additionally send the "renegotiate" extension. You must not disable this (in fact you cannot). Ignore it. Its harmless.

    From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.

    That is the official IANA name for the ciphersuite. OpenSSL knows it as "PSK-AES128-CBC-SHA256".

    Configure it on both the client and the server like this:

    SSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256");
    

    See this page for further information: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cipher_list.html

    In addition you will need to provide PSK callbacks to tell OpenSSL what the PSK is that you want to use.

    On the client you need to call SSL_CTX_set_psk_client_callback(). On the server you must call SSL_CTX_set_psk_server_callback().

    See these pages for further information: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_client_callback.html https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_server_callback.html

    TLSv1.3 ciphersuites will still automatically be sent unless you have additionally restricted the max TLS protocol version to TLSv1.2 as described above. Finally you will also see a ciphersuite called "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" being sent. This isn't actually a real ciphersuite at all. It is always sent and cannot be suppressed. It will never be negotiated and is harmless. Ignore it.

    Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?

    No.

    Is there any example or open source client-server implementation with PSK authentication?

    You can look at how s_client and s_server do it:

    https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_client.c https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_server.c