0

I'm building a prototype of an IOT device communicating through openssl with an online server. The software uses ECDSA certificate signed with my own subca.

The problem seems there isn't a cipher availlable for that certificate. To test the whole things i used openssl s_server on server side and nmap ssl-enum-ciphers script on client side. nmap returns a void list of ciphers.

The command given for the server is:

openssl s_server -accept 4433 -cert server1.crt -certform PEM -key server1.key

this is the certificate i use on server side.

Certificate:
Data:
    Version: 3 (0x2)
    Serial Number: 256 (0x100)
Signature Algorithm: ecdsa-with-SHA256
    Issuer: C=IT, O=wwwtech, CN=wwwtech Server CA
    Validity
        Not Before: Jul 17 12:11:31 2017 GMT
        Not After : Jul 17 12:11:31 2019 GMT
    Subject: C=IT, O=wwwtech, CN=server1
    Subject Public Key Info:
        Public Key Algorithm: id-ecPublicKey
            Public-Key: (160 bit)
            pub: 
                04:1c:e3:02:ec:bc:0f:88:7a:58:0b:36:b6:55:2c:
                e5:f1:67:5f:a0:7a:c3:c9:4b:7c:45:02:42:61:20:
                0c:4d:30:22:f6:c7:09:b5:ef:e1:8e
            ASN1 OID: brainpoolP160r1
    X509v3 extensions:
        X509v3 Basic Constraints: 
            CA:FALSE
        X509v3 Key Usage: 
            Key Encipherment
        Netscape Cert Type: 
            SSL Server
        Netscape Comment: 
            AreaWFI Server Certificate
        X509v3 Subject Key Identifier: 
            8D:92:1A:9F:6A:AB:D2:E5:6B:72:CB:25:A9:15:27:38:08:CE:DE:A9
        X509v3 Authority Key Identifier: 
            keyid:E7:2F:0E:A7:39:B4:85:46:FE:2A:EA:9F:0A:FE:54:F4:B9:A5:B6:AC

        X509v3 Subject Alternative Name: 
            IP Address:127.0.0.1
Signature Algorithm: ecdsa-with-SHA256
     30:44:02:20:32:f1:d1:90:08:f1:dc:a5:9d:30:d3:db:4b:05:
     6c:d2:41:cc:ac:6f:01:f8:90:0d:a5:25:27:4d:f9:38:62:14:
     02:20:19:37:c4:7c:07:e9:07:2d:c8:6e:1f:a4:db:4e:44:48:
     68:4a:e9:9d:03:68:b3:b0:c6:31:60:92:ed:54:5c:22
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219

2 Answers2

2

Your certificate is using the brainpoolP160r1 curve. This curve is supported by libcrypto but not by libssl. Probably because this is insufficiently secure (it only offers the equivalent of 80 bits of security). Probably if you tried a different (more secure) curve you will get better results.

You don't say what version of OpenSSL you are using. Note that in OpenSSL 1.1.0 the "default" curves supported by OpenSSL are X25519, P-256, P-384 and P-512. If you want to use other curves you will probably have to explicitly state them using the "-curves" parameter to s_server. The only brainpool curves that libssl supports in OpenSSL 1.1.0 are brainpoolP256r1, brainpoolP384r1 and brainpoolP512r1.

Edit:

I also note that you have an X509v3 Key Usage of "Key Encipherment" which doesn't make any sense for an ECDSA cert (ECDSA can't "encipher" anything; its a digital signature algorithm). Change the key usage to "Digital Signature" (or drop it altogether).

Matt Caswell
  • 8,167
  • 25
  • 28
  • I use OpenSSL 1.0.2g. I thought brainpoolP160r1 was supported because openssl ecparam -list_curves display it. Thank you very much. – Luca Rizzuti Jul 18 '17 at 11:34
  • That ecparam option lists all the curves supported by libcrypto which is a significantly longer list than that supported by libssl. Not all the curves are considered suitable for SSL/TLS usage. In 1.0.2g the libssl default curves list is longer than in 1.1.0. It includes P-256, P-384, P-512 as well as the similarly sized brainpool curves and a few miscellaneous, rarely used, others. The full list of supported curves in 1.0.2g (which you have to enable using "-curves") is quite a long list, but still does not include brainpoolP160r1. – Matt Caswell Jul 18 '17 at 12:37
  • The full list of supported curves in libssl in 1.0.2 is here: https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/ssl/t1_lib.c#L290 – Matt Caswell Jul 18 '17 at 12:37
  • I tried with prime256v1 curve (suggested by openssl in substitution of secp256r1 ), but without luck. nmap don't lists anything and if i try to connect s_server with -www switch with the browser i obtain SSL_ERROR_NO_CYPHER_OVERLAP. – Luca Rizzuti Jul 18 '17 at 14:53
  • prime256v1 and secp256r1 are synonymous. However I note that your original cert has a very strange key usage setting. If your new P-256 based cert has the same setting then this is going to be problematic. I updated my answer with this info. – Matt Caswell Jul 18 '17 at 16:22
  • i used as a reference for key usage and basic constraint the rfc 5280. Meybe i not correctly interpreted the rfc. – Luca Rizzuti Jul 18 '17 at 19:05
  • @LucaRizzuti I think [RFC 5639](https://datatracker.ietf.org/doc/rfc5639/?include_text=1) is more appropriate to refer to – YusufUMS Feb 25 '20 at 02:34
0

Problem solved. I changed brainpoolP160r1 with prime256v1 and removed keyUsage=KeyEncipherment from the openssl.conf of signing CA, then it start working as espected. Now i guess why? RFC 5280 section 4.2.1.3 says :

The keyEncipherment bit is asserted when the subject public key is used for enciphering private or secret keys, i.e., for key transport. For example, this bit shall be set when an RSA public key is to be used for encrypting a symmetric content-decryption key or an asymmetric private key.

Is this appening during ssl handshake or not?

  • Glad you got it working (please could mark my answer as correct?). RSA and ECDSA certs work differently in SSL/TLS. With an RSA cert the client selects a key and encrypts it using the public key. So setting "Key Encipherment" is correct for RSA. ECDSA is not used in this way. Instead it is used in conjunction with ECDHE. ECDHE is a key agreement algorithm, ie. both peers mutually calculate a shared secret - but the key itself is never sent on the wire. ECDSA is used by the server to digitally sign the handshake for authentication purposes. Therefore "Key Encipherment" is not correct for ECDSA. – Matt Caswell Jul 19 '17 at 08:59