Authentication over ECDHE

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

Authentication over ECDHE

Christian
Hello, people. I'm a beginner with OpenSSL and with cryptography in
general, and have been wondering how to best implement an upcoming system.

I apologise in advance for any grammar or orthography mistakes, as
English isn't my native language.

We have a local network with a databse in which we do most of our
processing, and a public machine that runs a webserver. Periodically we
have to connect to that server and query new data to process it. The
connection to that server is not necessarily trusted.

The problem is that our webserver is slow and clunky and generally just
issues another process to deal with any request, which is unnecessary
and slow. We want to streamline that process by having a local program
run on the server sending a set of predefined queries over a predefined
protocol, and then just sent that data back to the client. However, only
a select few machines are supposed to be able to get any data from the
server, like, those who have a certain private key. If a client can sign
a ping that can be decrypted with the client side public key, and if the
server can sign a ping that can be decrypted with the servers public
key, then both sides are authenticated, and - from my limited understand
- a MITM scenario is foiled (unless the MITM manages to steal either
private key, which is why I also want to have password protection for
the key. I'm away that putting the key into a program compromises the
security of the key if an attacker manages to gain access to the server,
but in this case it's just supposed to give us some time to stop the
programs, close all holes, and generate new keys).

This sounds like a typical RSA scenario, however I also want to have
forward security, which requires me to use something with temporary keys
only - I'm having ECDHE in mind for that, ECDHE-RSA-AES128-GCM-SHA256 in
particular. However, after some research I found out that the "RSA" in
that cipher only refers to the temporary keys that are being generated
for this connection, and thus authentication would have to be issued on
top of TLS, not within the means of TLS itself.

And last, but not least I've read about an attack a little while back
how some DH parameters (usually those with a size of 1024 bits) have
become stale. If I want to have extra security,

Speed isn't an incredible huge problem, as there will always be just
one, at most two connections running with the server. As such its design
can be incredible simple, and the connection can be more secure in terms
of cryptography than default (4096 RSA keys and 2048 DH params wouldn't
be an issue). I expect the bulk of the runtime to be spent on the
database server side of things anyway.

I don't want to use certificates. Either a client/server has the
necessary private keys to sign data, or the connection is simply
refused. I also don't want to use any password, because that requires to
share a secret over a to this moment still unverified channel.

My question is thusly how to implement authentication over ECDHE in the
best way. My searches for "openssl c sign data with private key" doesn't
yield any usable results, which suggests that there is some sort of
misunderstanding with the concept of "signing ping/pong with respective
private keys". Are there any functions or further documentation to be of
help here? Please keep in mind that all of this has been Greek to me
until last Friday, and that I'm by no way a cryptography expert.

Thank you for your time and effort in advance.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Viktor Dukhovni
On Mon, Dec 24, 2018 at 12:51:17PM +0100, Christian wrote:

> This sounds like a typical RSA scenario, however I also want to have
> forward security, which requires me to use something with temporary keys
> only - I'm having ECDHE in mind for that, ECDHE-RSA-AES128-GCM-SHA256 in
> particular. However, after some research I found out that the "RSA" in
> that cipher only refers to the temporary keys that are being generated
> for this connection, and thus authentication would have to be issued on
> top of TLS, not within the means of TLS itself.

Your research has led you astray.  The ECDHE-RSA-AES128-GCM-SHA25
ciphersuiteo *is* RSA authenticated and offers forward secrecy,
the same is true also of its 256-bit twin:

    $ openssl ciphers -v kECDHE+AESGCM+aRSA | sed 's/  */ /g'
    ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
    ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD

they are both quite strong, use 128-bit to optimize for speed or
256-bit against hypothetical attacks on 128-bit AES that don't break
AES-256.  These ciphers are for TLS 1.2.  With OpenSSL 1.1.1 you
might also consider TLS 1.3 ciphers, where the public algorithm is
negotiated separately,

    TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
    TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
    TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD

and you could use Ed25519 certificates and/or X25519 key exchange.

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Christian
> Your research has led you astray.  The ECDHE-RSA-AES128-GCM-SHA25
> ciphersuiteo *is* RSA authenticated and offers forward secrecy,

Then how would I load my static RSA keys into my SSL_CTX? Simply by
using SSL_CTX_use_PrivateKey_file on client and server? As far as I
understand the mechanism that would only enable encryption, but not
decryption.

> they are both quite strong, use 128-bit to optimize for speed or
> 256-bit against hypothetical attacks on 128-bit AES that don't break
> AES-256.

Actually, I've been told that AES256 is weaker than AES128 in theory,
and have been discouraged to use it.

> and you could use Ed25519 certificates and/or X25519 key exchange.

I said I'd like to avoid using any certificates. I don't see the point
of them if I'm going to use static keys anyways. And certificates, from
my limited understanding, only establish external trust anyways. I want
direct trust.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Viktor Dukhovni
On Mon, Dec 24, 2018 at 04:25:54PM +0100, Christian wrote:

> > Your research has led you astray.  The ECDHE-RSA-AES128-GCM-SHA25
> > ciphersuiteo *is* RSA authenticated and offers forward secrecy,
>
> Then how would I load my static RSA keys into my SSL_CTX? Simply by
> using SSL_CTX_use_PrivateKey_file on client and server?

To avoid trusted CAs, you have to load both a private key *and*
a self-signed certificate.  While certificate-less TLS is in
theory possible with RFC7250 bare public keys, in practice no
libraries I know of support this.

Also, your CA does not have to be a third-party CA, you can generate
your trusted issuer CA, its private key can be "off-line", making
recovery from server key compromise somewhat simpler, but with so
few systems in scope the difference is minor.

> As far as I understand the mechanism that would only enable encryption,
> but not decryption.

Again, that's not the case, but you still need a certificate to go
with that key.  In the simplest case that certificate can be
self-signed, and would be the only one (or one of a few) trusted
by the verifier (via suitable settings of CAfile and CApath).

> > they are both quite strong, use 128-bit to optimize for speed or
> > 256-bit against hypothetical attacks on 128-bit AES that don't break
> > AES-256.
>
> Actually, I've been told that AES256 is weaker than AES128 in theory,
> and have been discouraged to use it.

There are some concerns about the key schedule, but they've not
panned out to attacks that make AES256 weaker than AES128.

> > and you could use Ed25519 certificates and/or X25519 key exchange.
>
> I said I'd like to avoid using any certificates. I don't see the point
> of them if I'm going to use static keys anyways.

You're going to have (self-signed) certificates.  They're essentially
slightly bloated key containers.

> And certificates, from my limited understanding, only establish external
> trust anyways. I want direct trust.

Certificates do not preclude direct trust.  Self-signed certificates do
not entail any outside parties.  A suitable self-signed certificate and
private key can be generated via:

    $ temp=$(mktemp chain.XXXXXXX)
    $ openssl req -new -newkey rsa:2048 -nodes -keyout /dev/stdout \
        -x509 -subj / -days 36524 >> $temp && mv $temp self-chain.pem

I think that password protection for the keys is a waste of time,
but if you can use it if you wish.

    $ temp=$(mktemp chain.XXXXXXX)
    $ openssl genrsa -aes128 -out $temp 2048
    $ openssl req -new -key $temp -x509 -subj / -days 36524 >> $temp &&
        mv $temp self-chain.pem

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Matt Caswell-2
In reply to this post by Christian


On 24/12/2018 11:51, Christian wrote:

> Hello, people. I'm a beginner with OpenSSL and with cryptography in general, and
> have been wondering how to best implement an upcoming system.
>
> I apologise in advance for any grammar or orthography mistakes, as English isn't
> my native language.
>
> We have a local network with a databse in which we do most of our processing,
> and a public machine that runs a webserver. Periodically we have to connect to
> that server and query new data to process it. The connection to that server is
> not necessarily trusted.
>
> The problem is that our webserver is slow and clunky and generally just issues
> another process to deal with any request, which is unnecessary and slow. We want
> to streamline that process by having a local program run on the server sending a
> set of predefined queries over a predefined protocol, and then just sent that
> data back to the client. However, only a select few machines are supposed to be
> able to get any data from the server, like, those who have a certain private
> key. If a client can sign a ping that can be decrypted with the client side
> public key, and if the server can sign a ping that can be decrypted with the
> servers public key, then both sides are authenticated, and - from my limited
> understand - a MITM scenario is foiled (unless the MITM manages to steal either
> private key, which is why I also want to have password protection for the key.
> I'm away that putting the key into a program compromises the security of the key
> if an attacker manages to gain access to the server, but in this case it's just
> supposed to give us some time to stop the programs, close all holes, and
> generate new keys).
>
> This sounds like a typical RSA scenario, however I also want to have forward
> security, which requires me to use something with temporary keys only - I'm
> having ECDHE in mind for that, ECDHE-RSA-AES128-GCM-SHA256 in particular.
> However, after some research I found out that the "RSA" in that cipher only
> refers to the temporary keys that are being generated for this connection, and
> thus authentication would have to be issued on top of TLS, not within the means
> of TLS itself.
>
> And last, but not least I've read about an attack a little while back how some
> DH parameters (usually those with a size of 1024 bits) have become stale. If I
> want to have extra security,
>
> Speed isn't an incredible huge problem, as there will always be just one, at
> most two connections running with the server. As such its design can be
> incredible simple, and the connection can be more secure in terms of
> cryptography than default (4096 RSA keys and 2048 DH params wouldn't be an
> issue). I expect the bulk of the runtime to be spent on the database server side
> of things anyway.
>
> I don't want to use certificates. Either a client/server has the necessary
> private keys to sign data, or the connection is simply refused. I also don't
> want to use any password, because that requires to share a secret over a to this
> moment still unverified channel.
>
> My question is thusly how to implement authentication over ECDHE in the best
> way. My searches for "openssl c sign data with private key" doesn't yield any
> usable results, which suggests that there is some sort of misunderstanding with
> the concept of "signing ping/pong with respective private keys". Are there any
> functions or further documentation to be of help here? Please keep in mind that
> all of this has been Greek to me until last Friday, and that I'm by no way a
> cryptography expert.
>
> Thank you for your time and effort in advance.

How about using PSKs? That way you completely avoid the need for a certificate.
Authentication is implied since both peers must have access to the PSK for the
connection to succeed. ECDHE can be combined with the PSK to create a temporary
key for the connection, thus giving you forward secrecy, e.g. using a
ciphersuite such as ECDHE-PSK-AES128-CBC-SHA256.

Matt


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Viktor Dukhovni
On Mon, Dec 24, 2018 at 04:29:49PM +0000, Matt Caswell wrote:

> How about using PSKs? That way you completely avoid the need for a certificate.
> Authentication is implied since both peers must have access to the PSK for the
> connection to succeed. ECDHE can be combined with the PSK to create a temporary
> key for the connection, thus giving you forward secrecy, e.g. using a
> ciphersuite such as ECDHE-PSK-AES128-CBC-SHA256.

This requires more complex application code on the client and server,
so I would not recommend it.  And IIRC there may be some complications
with getting PSKs to work across both TLS 1.2 and TLS 1.3???

--
        Viktor.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

OpenSSL - User mailing list
In reply to this post by Viktor Dukhovni
>    While certificate-less TLS is in theory possible with RFC7250 bare public keys

Pre-shared keys (PSK) don't require certs, maybe that meets the need.  A thing to know about PSK is that each side is fully trusted, and if one side gets the key stolen, then the thief can pretend to be either side.
 

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Viktor Dukhovni
> On Dec 24, 2018, at 2:44 PM, Salz, Rich via openssl-users <[hidden email]> wrote:
>
> Pre-shared keys (PSK) don't require certs, maybe that meets the need.  A thing to know about PSK is that each side is fully trusted, and if one side gets the key stolen, then the thief can pretend to be either side.

PSK only makes sense for svelte SSL libraries that either run
on devices with too little CPU to do public key crypto, or don't
want to the pay the code footprint of X.509 certificate processing.

For OpenSSL on a typical computer, PSK deployment and application
support is more complex than just going with self-signed certs.

The OP is IMHO better off avoiding PSKs.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Matt Caswell-2


On 24/12/2018 19:52, Viktor Dukhovni wrote:

>> On Dec 24, 2018, at 2:44 PM, Salz, Rich via openssl-users <[hidden email]> wrote:
>>
>> Pre-shared keys (PSK) don't require certs, maybe that meets the need.  A thing to know about PSK is that each side is fully trusted, and if one side gets the key stolen, then the thief can pretend to be either side.
>
> PSK only makes sense for svelte SSL libraries that either run
> on devices with too little CPU to do public key crypto, or don't
> want to the pay the code footprint of X.509 certificate processing.
>
> For OpenSSL on a typical computer, PSK deployment and application
> support is more complex than just going with self-signed certs.
>
> The OP is IMHO better off avoiding PSKs.
>

I disagree with this assessment of what PSKs are good for. As with any
technology choice there are trade offs that have to be made. PSKs are actually
*simple* to deploy (far simpler than X.509 based certificates IMO) and are
perfectly suitable for all sorts of environments - it doesn't just have to be
"devices with too little CPU to do public key crypto". The problem with PSKs is
that they do not scale well. If you have lots of endpoints then the cost of
deploying and managing keys across all of them becomes too high too quickly. By
comparison X.509 certificate based authentication is complex and costly to
deploy and manage. Such a solution does scale well though.

If you've got a small number of endpoints then PSKs may be a suitable choice. If
you've got lots of endpoints then, probably, an X.509 certificate based solution
is the way to go.

The OP talks about a "select few machines" being able to access a database
server. This sounds precisely the sort of environment where PSKs would work well.

On 24/12/2018 16:43, Viktor Dukhovni wrote:
> This requires more complex application code on the client and server,
> so I would not recommend it.

Not really. The application code for PSKs is quite straight forward in most cases.

> And IIRC there may be some complications
> with getting PSKs to work across both TLS 1.2 and TLS 1.3???

Yes, there are differences between PSKs in TLSv1.2 and TLSv1.3, so if supporting
both of those is a requirement then there are additional things to bear in mind.

In TLSv1.2:
1) A server (optionally) provides an identity hint to the client
2) The client looks up the identity to be used and the associated PSK value
(possibly using the hint provided by the server to select the right identity)
3) The client sends the identity to the server
4) The server receives the identity from the client and finds the PSK associated
with it
5) Both sides derive keys for the session based on the PSK (possibly
additionally using (EC)DHE to add forward secrecy)

In TLSv1.3 there is no identity hint - the client just finds the identity
without the use of a hint. The identity has an associated key (as in TLSv1.2)
but it *also* has an associated hash algorithm. If no hash algorithm is
explicitly specified then SHA256 is assumed by default.

OpenSSL 1.1.0 (and earlier) provided an API for TLSv1.2 PSKs. This continues to
work in OpenSSL 1.1.1 and it can be used in both TLSv1.2 *and* TLSv1.3. However
the callbacks will get called with a NULL identity hint on the client side.
Since this older API was not designed with TLSv1.3 in mind there is no way to
specify the hash to be used - so if you use this older API then SHA256 is always
in use (and a SHA256 based TLSv1.3 ciphersuite must be available).

OpenSSL 1.1.1 provides additional APIs for doing TLSv1.3 PSKs that may be used
instead of (or as well as) the TLSv1.2 PSK API. This API *does* allow you to
specify the hash to be used, but does not work in TLSv1.2.

So, if you're happy with the SHA256 default, then you can just use the older PSK
API and it will work quite happily in both TLSv1.2 and TLSv1.3. If you want more
control in TLSv1.3 then you might need to use a combination of the old API (in
TLSv1.2) and the new API (in TLSv1.3).

Matt
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Michel
Thanks Matt for the reminder about the use of PSK in TLS 1.3.
This leads me to this other question :
Can someone please clarify what is the future of SRP starting with TLS 1.3 ?





--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Matt Caswell-2


On 25/12/2018 20:07, Michel wrote:
> Thanks Matt for the reminder about the use of PSK in TLS 1.3.
> This leads me to this other question :
> Can someone please clarify what is the future of SRP starting with TLS 1.3 ?

SRP is not currently supported in OpenSSL with TLSv1.3. AFAIK there is no
standard available to define it. We'd need to see such a standard first before
we could integrate support for it.

Matt

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Christian
In reply to this post by Matt Caswell-2
Thank you for the suggestions thus far. I've been working on a simple
SSL client/server system in the last couple days. Unfortunately the SSL
documentation is a right mess, so I don't know what is allowed and what
is not, which leads to some problems that I don't know exactly how to
tackle on.

First of all, I opted out for the cipher "ECDHE-PSK-AES128-CBC-SHA256".
As Matt suggested, using PSKs does reduce a lot of complexity in this
scenario - if I've been understanding him correctly, this cipher should
give us forward secrecy while still relying on a pre-shared key, which
also authenticates both sides to each other. When I run my server, and
then run my client, it receives the data the server sends without any
problems.

However, things start to get messy once the keys mismatch, as would in
any attacker scenario. The client initiates the handshake, but on the
server side SSL_accept() returns -1, the client receives no data (as
should). Then I start the client *again*. On the server side
SSL_accept() returns -1 again, but this time the client blocks in
SSL_read() (I haven't not implemented timeout handling yet, as this
still all runs on my testing environments). It's almost as if
SSL_shutdown on the server side does not notify the client that the
connection is to be closed.

For the BIO object on the server side I'm using a permanent BIO object
which I just call BIO_set_fd() upon to set the socket I receive from
accept(). The call chain looks like this:

===================
First connection, client closes connection as excepted.
===================
BIO_set_fd with 4|1         #Socket 4, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear
===================
Second connection, client suddenly blocks, has to be interrupted
with CTRL + C.
===================
BIO_set_fd with 5|1         #Socket 5, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear
===================
Third connection, client blocks again, has to be interrupted again.
===================
BIO_set_fd with 4|1
SSL_set_accept_state
SSL_accept
SSL_accept returned with -1
SSL_shutdown
SSL_clear

What am I doing wrong on the server side? I assume it's the server; the
client process ends right after the connection attempt, and it's the
server that keeps running. And once I reset the server the first
connection closes properly again. Am I supposed to use a new BIO object
for each incoming connection? If so, that's pretty dumb. You usually
want to have your accept() loop to be free of as much code as possible,
and setting up everything in advance during server startup. The current
server code for setting up the SSL object and using it looks like this:

 > if(NULL == (bio = BIO_new_socket(0,BIO_NOCLOSE))) /*Socket doesn't
really matter, we're gonna reset this soon enough.*/
 > {
 >         goto LABEL_END_NO_BIO;
 > }
 >
 > if(NULL == (ssl = SSL_new(ssl_ctx)))
 > {
 >         BIO_free(bio);
 >         goto LABEL_END_NO_SSL;
 > }
 >
 > SSL_clear(ssl);
 > SSL_set_bio(ssl,bio,bio);
 >
 > tmp = 1;
 > setsockopt
 > (
 >         socket_server,
 >         SOL_SOCKET,
 >         SO_REUSEADDR,
 >         &tmp,
 >         sizeof(tmp)
 > );
 >
 > if(-1 == bind
 > (
 >         socket_server,
 >         (struct sockaddr*)&sin_server,
 >         sizeof(sin_server)
 > ))
 > {
 >         fprintf(stderr,"Can't bind socket.\n");
 >         goto LABEL_END;
 > }
 >
 > if(-1 == listen(socket_server,1))
 >         goto LABEL_END;
 >
 > while(0 <= (socket_client = accept
 > (
 >         socket_server,
 >         (struct sockaddr*)&sin_client,
 >         &sin_client_length
 > )))
 > {
 >         fprintf(stderr,"BIO_set_fd with
%u|%u\n",socket_client,BIO_CLOSE);
 >         BIO_set_fd(bio,socket_client,BIO_CLOSE);
 >         fprintf(stderr,"SSL_set_accept_state\n");
 >         SSL_set_accept_state(ssl);
 >         fprintf(stderr,"SSL_accept\n");
 >         tmp = SSL_accept(ssl);
 >         if(tmp != 1)
 >         {
 >                 fprintf(stderr,"SSL_accept returned with %i\n",tmp);
 >                 goto LABEL_NEXT_CLIENT;
 >         }
 >
 >         fprintf(stderr,"SSL_write\n");
 >         SSL_write(ssl,"That is my string",sizeof("That is my string")
- 1);
 >
 > LABEL_NEXT_CLIENT:
 >         fprintf(stderr,"SSL_shutdown\n");
 >         SSL_shutdown(ssl);
 >         fprintf(stderr,"SSL_clear\n");
 >         SSL_clear(ssl);
 > }
 >
 > /*Rest of cleanup, doesn't matter, this is hopefully never reached.*/

Thank you for your continued help.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Christian
I should also add that printing the error stack doesn't yield much info
other than "you dun goof'd":

===================
First connection, client closes connection as excepted.
===================
BIO_set_fd with 4|1                     #Socket 4, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept failed, SSL_get_error: 1     #SSL_ERROR_SSL
140059505588032:error:1408F119:SSL routines:ssl3_get_record:decryption
failed or bad record mac:../ssl/record/ssl3_record.c:375:
SSL_shutdown
SSL_clear

===================
Second connection, client suddenly blocks, has to be interrupted
with CTRL + C.
===================
BIO_set_fd with 5|1                     #Socket 5, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept failed, SSL_get_error: 1     #SSL_ERROR_SSL
140059505588032:error:140A4044:SSL routines:SSL_clear:internal
error:../ssl/ssl_lib.c:559:
SSL_shutdown
SSL_clear

===================
Third connection, client blocks again, has to be interrupted again.
===================
BIO_set_fd with 4|1                     #Socket 4, BIO_CLOSE
SSL_set_accept_state
SSL_accept
SSL_accept failed, SSL_get_error: 1     #SSL_ERROR_SSL
140059505588032:error:140A4044:SSL routines:SSL_clear:internal
error:../ssl/ssl_lib.c:559:
SSL_shutdown
SSL_clear

The error messages are being generated by ERR_print_errors_fp(stderr);
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Matt Caswell-2
In reply to this post by Christian


On 28/12/2018 10:22, Christian wrote:

> Thank you for the suggestions thus far. I've been working on a simple SSL
> client/server system in the last couple days. Unfortunately the SSL
> documentation is a right mess, so I don't know what is allowed and what is not,
> which leads to some problems that I don't know exactly how to tackle on.
>
> First of all, I opted out for the cipher "ECDHE-PSK-AES128-CBC-SHA256". As Matt
> suggested, using PSKs does reduce a lot of complexity in this scenario - if I've
> been understanding him correctly, this cipher should give us forward secrecy
> while still relying on a pre-shared key, which also authenticates both sides to
> each other.

Yes, this is correct.

> When I run my server, and then run my client, it receives the data
> the server sends without any problems.
>
> However, things start to get messy once the keys mismatch, as would in any
> attacker scenario. The client initiates the handshake, but on the server side
> SSL_accept() returns -1, the client receives no data (as should). Then I start
> the client *again*. On the server side SSL_accept() returns -1 again, but this
> time the client blocks in SSL_read() (I haven't not implemented timeout handling
> yet, as this still all runs on my testing environments). It's almost as if
> SSL_shutdown on the server side does not notify the client that the connection
> is to be closed.

Which version of OpenSSL is this? (I don't remember if you said this already).

Note that SSL_shutdown is intended for orderly shutdown of a successful, active
SSL/TLS connection. It is not supposed to be called if the connection has failed
for some reason. If the server decides to abort the connection it should have
already sent a fatal alert.

>> LABEL_NEXT_CLIENT:
>>         fprintf(stderr,"SSL_shutdown\n");
>>         SSL_shutdown(ssl);
>>         fprintf(stderr,"SSL_clear\n");
>>         SSL_clear(ssl);

Please check the return code of this SSL_clear function. It can fail, and if it
does it means the SSL object has not been cleared properly, and that will cause
all sorts of weird, difficult to debug failures later on.

Matt

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Viktor Dukhovni
In reply to this post by Christian


> On Dec 28, 2018, at 6:17 AM, Christian <[hidden email]> wrote:
>
> BIO_set_fd with 4|1                     #Socket 4, BIO_CLOSE
> SSL_set_accept_state
> SSL_accept
> SSL_accept failed, SSL_get_error: 1     #SSL_ERROR_SSL
> 140059505588032:error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac:../ssl/record/ssl3_record.c:375:
> SSL_shutdown
> SSL_clear

1.  Don't call SSL_shutdown(), rather just call SSL_free() and close the
    socket using close(), IIRC SSL_set_fd() (you should not need to use
    BIO_set_fd) leaves you as the owner of the socket to close or not.

2.  DO NOT reuse the same SSL handle for multiple connections, create a
    new one for subsequent connections, but you can and generally should
    reuse the SSL_CTX.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

C.Wehrmeyer
In reply to this post by Christian
I don't have access to the actual testing environments until Wednesday
next year, so I've had to create a private account.

 > Which version of OpenSSL is this? (I don't remember if you said this
 > already).

I'm not entirely sure, but I *think* it's 1.1.0.

=====================================================================

OK, so I've been reading the mails before going to sleep and spent some
time thinking and researching about this, and I've come to a conclusion:
OpenSSL is a goddamn mess, SSL_clear() is pretty much superfluous, and
as such shouldn't exist.

Why? Well, to quote Viktor here:

 > DO NOT reuse the same SSL handle for multiple connections,

And that is fricking bullshit. Not the quote itself or the suggestion -
it's unlikely you had anything to do with the actual code - but the way
things have been thought through (or rather, have not been thought
through) by the library devs. I've written highly scalable libraries in
the past before, and one thing you always want to do there is to trim
fat. And "object allocation and initialisation" is something that you
very much want to trim fat of, not only for obvious reasons such as
malloc() and free() (or whatever OpenSSL uses as wrappers) being
complexity monsters, but also for cache reasons (loading different cache
line hurts performance). That's why you usually have functions like
XXX_clear() or XXX_reset(), which do exactly that - prepare an object
for another usage. memset() (or the OpenSSL equivalent of a secure
memset) your allocated resources. I don't really see the problem here.

Now add to that the fact that OpenSSL has been moving towards making its
structures opaque, thus falling into the same trap that Microsoft has
with COM and DirectX, and you can kind of see why, if you can't really
determine anymore WHERE your object is going to be stored, you at least
want to keep reusing it. This is not PHP, where people allocate memory
all willy-nilly, or C++, where people don't even have shame anymore to
use std::vector<std::strings> str_array instead of good old static const
char*const str_array[] while expecting things to be made faster by
invisible memory pools (and horribly failing at it), but C, where you
want to think about each step quite carefully.

Then OpenSSL even provides an SSL_clear function which is advertised
like this:

 > SSL_clear - reset SSL object to allow another connection

, and then, only later, in a big warning block, decides to tell the
reader that this function only works when the stars align quite
correctly and you've sacrificed at least two virgins, because:

 > The reset operation however keeps several settings of the last
 > sessions

Then, as the documentation suggests, I read the entry for SSL_get_session:

 > The ssl session contains all information required to re-establish the
 > connection without a full handshake for SSL versions up to and
 > including TLSv1.2. In TLSv1.3 the same is true, but sessions are
 > established after the main handshake has occurred.

And at this point it all falls apart. From my understanding OpenSSL
keeps a session cache for servers so that key exchanges and protocol
handshakes can be avoided. Problem is, *we're using ECDHE, where the
last E stands for "ephemeral"*. In simple English: throw away the keys
after you're done, we want to have forward secrecy. And then OpenSSL
keeps a fresh copy of those for everyone who happened to be logged on at
this point. Heartbleed apparently wasn't enough of a warning. Oh, but
lets move everything to the heap so that it's more secure there now.

I don't want to reuse a session with ephemeral keys; I want to reuse an
object that is supposed to already have resources allocated for doing
its job, as is indicated by the documentation of this function except
for a small note at the end that tells you that the devs didn't really
think about what "ephemeral" means.

Creating a new SSL object (EVEN FROM AN EXISTING SSL_CTX object) entails:

- allocating the memory for the object itself on the heap (via
OPENSSL_zalloc)
- creating and managing a new lock for the object, and who knows for
much more subobjects
- creating a duplicate of the cipher suite stack (which isn't even a
flat copy, but something that can cause the code to call OPENSSL_malloc
*twice* in the worst case)
- creating a duplicate of the certificates (which I don't even use, but
that doesn't stop the code of ssl_cert_dup() to call OPENSSL_zalloc *in
its very first line!*)
- setting up a bunch of callbacks
- copying 32 bytes for a sid_ctx
- creating an X509_VERIFY_PARAM object (*which calls OPENSSL_zalloc
again*) as well as creating a deep copy of the SSL_CTX's parameter via
X509_VERIFY_PARAM_inherit(), with Thor knows how many copies hidden in
all those *set* and *deep_copy* routines
- copying EC point formats from the context - deep again, of course, at
least that's what OPENSSL_memdup() makes me think
- copying supported group informations, and of course deep again!
- deep-copying an ALPN object
- SSL_clear()-ing the object (no, really!)
- deep-copying a CRYPTO_EX_DATA object via CRYPTO_new_ex_data ... at
this point, is anyone surprised here that timing attacks against crypto
are *still* so successful? Because I'm not. Not at all.

I didn't bother looking up what freeing entails - it's obvious to anyone
at this point that OpenSSL is a severe victim of feature creep, that its
memory allocation scheme is a mess, and long story short: I will NOT
free a perfectly fine object just because of incompetent devs' chutzpah
expecting their users to allocate memory dynamically en mass for no
goddamn reason whenever a new connection comes in. Fix your goddamn code.

And don't give me any "trust us, we're experienced programmers"
bullshit. I've *seen* ssl/record/ssl3_record.c:

 > static const unsigned char ssl3_pad_1[48] = {
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
 >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
 > };
 > static const unsigned char ssl3_pad_2[48] = {
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
 >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
 > };

What's wrong with that, you ask? Let me show you how I'd have done that:

 > static const unsigned char ssl3_pad_1[] =
 > {
 >     "66666666"
 >     "66666666"
 >     "66666666"
 >     "66666666"
 >     "66666666"
 >     "66666666"
 > };
 >
 > static const unsigned char*ssl3_pad_2[] =
 > {
 >     "\\\\\\\\\\\\\\\\"
 >     "\\\\\\\\\\\\\\\\"
 >     "\\\\\\\\\\\\\\\\"
 >     "\\\\\\\\\\\\\\\\"
 >     "\\\\\\\\\\\\\\\\"
 >     "\\\\\\\\\\\\\\\\"
 > };

So, no. I don't trust anyone. Especially not this mess of a code.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

OpenSSL - User mailing list
On 29/12/2018 14:19, C.Wehrmeyer wrote:

> I don't have access to the actual testing environments until Wednesday
> next year, so I've had to create a private account.
>
> > Which version of OpenSSL is this? (I don't remember if you said this
> > already).
>
> I'm not entirely sure, but I *think* it's 1.1.0.
>
> =====================================================================
>
> OK, so I've been reading the mails before going to sleep and spent
> some time thinking and researching about this, and I've come to a
> conclusion: OpenSSL is a goddamn mess, SSL_clear() is pretty much
> superfluous, and as such shouldn't exist.
>
> Why? Well, to quote Viktor here:
>
> > DO NOT reuse the same SSL handle for multiple connections,
>
> And that is fricking bullshit. Not the quote itself or the suggestion
> - it's unlikely you had anything to do with the actual code - but the
> way things have been thought through (or rather, have not been thought
> through) by the library devs. I've written highly scalable libraries
> in the past before, and one thing you always want to do there is to
> trim fat. And "object allocation and initialisation" is something that
> you very much want to trim fat of, not only for obvious reasons such
> as malloc() and free() (or whatever OpenSSL uses as wrappers) being
> complexity monsters, but also for cache reasons (loading different
> cache line hurts performance). That's why you usually have functions
> like XXX_clear() or XXX_reset(), which do exactly that - prepare an
> object for another usage. memset() (or the OpenSSL equivalent of a
> secure memset) your allocated resources. I don't really see the
> problem here.
>
> Now add to that the fact that OpenSSL has been moving towards making
> its structures opaque, thus falling into the same trap that Microsoft
> has with COM and DirectX, and you can kind of see why, if you can't
> really determine anymore WHERE your object is going to be stored, you
> at least want to keep reusing it. This is not PHP, where people
> allocate memory all willy-nilly, or C++, where people don't even have
> shame anymore to use std::vector<std::strings> str_array instead of
> good old static const char*const str_array[] while expecting things to
> be made faster by invisible memory pools (and horribly failing at it),
> but C, where you want to think about each step quite carefully.
>
> Then OpenSSL even provides an SSL_clear function which is advertised
> like this:
>
> > SSL_clear - reset SSL object to allow another connection
>
> , and then, only later, in a big warning block, decides to tell the
> reader that this function only works when the stars align quite
> correctly and you've sacrificed at least two virgins, because:
>
> > The reset operation however keeps several settings of the last
> > sessions
>
> Then, as the documentation suggests, I read the entry for
> SSL_get_session:
>
> > The ssl session contains all information required to re-establish the
> > connection without a full handshake for SSL versions up to and
> > including TLSv1.2. In TLSv1.3 the same is true, but sessions are
> > established after the main handshake has occurred.
>
> And at this point it all falls apart. From my understanding OpenSSL
> keeps a session cache for servers so that key exchanges and protocol
> handshakes can be avoided. Problem is, *we're using ECDHE, where the
> last E stands for "ephemeral"*. In simple English: throw away the keys
> after you're done, we want to have forward secrecy. And then OpenSSL
> keeps a fresh copy of those for everyone who happened to be logged on
> at this point. Heartbleed apparently wasn't enough of a warning. Oh,
> but lets move everything to the heap so that it's more secure there now.
>
> I don't want to reuse a session with ephemeral keys; I want to reuse
> an object that is supposed to already have resources allocated for
> doing its job, as is indicated by the documentation of this function
> except for a small note at the end that tells you that the devs didn't
> really think about what "ephemeral" means.
>
The session caching in the SSL and TLS protocols is to skip the
expensive key exchange when reconnecting within a few seconds,
as is extremely common with web browsers opening up to 8 parallel
connections to each server.

There is hopefully a configuration option to tell the OpenSSL server
end SSL_CTX to not do this, just as there should (for multi-process
web servers) be an option to hand the state storage over to the web
server application for inter-process sharing in whatever the web
server application (and its configuration) deems secure.

> Creating a new SSL object (EVEN FROM AN EXISTING SSL_CTX object) entails:
>
> - allocating the memory for the object itself on the heap (via
> OPENSSL_zalloc)
> - creating and managing a new lock for the object, and who knows for
> much more subobjects
> - creating a duplicate of the cipher suite stack (which isn't even a
> flat copy, but something that can cause the code to call
> OPENSSL_malloc *twice* in the worst case)
> - creating a duplicate of the certificates (which I don't even use,
> but that doesn't stop the code of ssl_cert_dup() to call
> OPENSSL_zalloc *in its very first line!*)
> - setting up a bunch of callbacks
> - copying 32 bytes for a sid_ctx
> - creating an X509_VERIFY_PARAM object (*which calls OPENSSL_zalloc
> again*) as well as creating a deep copy of the SSL_CTX's parameter via
> X509_VERIFY_PARAM_inherit(), with Thor knows how many copies hidden in
> all those *set* and *deep_copy* routines
> - copying EC point formats from the context - deep again, of course,
> at least that's what OPENSSL_memdup() makes me think
> - copying supported group informations, and of course deep again!
> - deep-copying an ALPN object
> - SSL_clear()-ing the object (no, really!)
> - deep-copying a CRYPTO_EX_DATA object via CRYPTO_new_ex_data ... at
> this point, is anyone surprised here that timing attacks against
> crypto are *still* so successful? Because I'm not. Not at all.
>
> I didn't bother looking up what freeing entails - it's obvious to
> anyone at this point that OpenSSL is a severe victim of feature creep,
> that its memory allocation scheme is a mess, and long story short: I
> will NOT free a perfectly fine object just because of incompetent
> devs' chutzpah expecting their users to allocate memory dynamically en
> mass for no goddamn reason whenever a new connection comes in. Fix
> your goddamn code.
>
> And don't give me any "trust us, we're experienced programmers"
> bullshit. I've *seen* ssl/record/ssl3_record.c:
>
> > static const unsigned char ssl3_pad_1[48] = {
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
> > };
> > static const unsigned char ssl3_pad_2[48] = {
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
> > };
>
> What's wrong with that, you ask? Let me show you how I'd have done that:
>
> > static const unsigned char ssl3_pad_1[] =
> > {
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> > };
> >
> > static const unsigned char*ssl3_pad_2[] =
> > {
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> > };
>
> So, no. I don't trust anyone. Especially not this mess of a code.

Well, these two latter arrays look like a stray copy of the HMAC
constants "ipad" and "opad", which (while looking like ASCII), are
defined as exact hex constants even on a non-ASCII machine, such
as PDP-11 or an IBM mainframe.

I wonder if those constants are actually still used somewhere in
the SSL3 code, or if they have been properly replaced by calls to
the HMAC implementation in libcrypto.

Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

Richard Levitte - VMS Whacker-2
In reply to this post by C.Wehrmeyer
In message <[hidden email]> on Sat, 29 Dec 2018 14:19:47 +0100, "C.Wehrmeyer" <[hidden email]> said:

> I've written highly scalable libraries in the past before, and one
> thing you always want to do there is to trim fat.

Sure, but:

> Now add to that the fact that OpenSSL has been moving towards making
> its structures opaque, thus falling into the same trap that Microsoft
> has with COM and DirectX,

...  I'm not sure about you, but I have a hard time seeing how one
would trim off fat from *public* structures that everyone and their
stray cat might be tinkering in.  Trimming off fat usually means
restructuring the structures, and unless they're opaque, the freedom
to do so is severily limited.

Mind you, though, that I agree we could do with some cleanup.

> And don't give me any "trust us, we're experienced programmers"
> bullshit. I've *seen* ssl/record/ssl3_record.c:
>
> > static const unsigned char ssl3_pad_1[48] = {
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
> >     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
> > };
> > static const unsigned char ssl3_pad_2[48] = {
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
> >     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
> > };
>
> What's wrong with that, you ask? Let me show you how I'd have done
> that:
>
> > static const unsigned char ssl3_pad_1[] =
> > {
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> >     "66666666"
> > };
> >
> > static const unsigned char*ssl3_pad_2[] =
> > {
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> >     "\\\\\\\\\\\\\\\\"
> > };
>
> So, no. I don't trust anyone. Especially not this mess of a code.

You do know that your string insert NUL bytes, right?  If you have a
look at how they're used, you might see why those stray NUL bytes
aren't a good thing.

Cheers,
Richard

P.S. as a side note, your message triggered profanity filters.  I
don't really care, it's not our filters, but this is just to inform
you that your rant didn't quite reach everyone (those with profanity
filters in place)
/postmaster

--
Richard Levitte         [hidden email]
OpenSSL Project         http://www.openssl.org/~levitte/
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

J. J. Farrell-2
In reply to this post by C.Wehrmeyer
On 29/12/2018 13:19, C.Wehrmeyer wrote:
...

Your corrections, improvements and enhancements would be very welcome as pull requests at https://github.com/openssl/openssl - thank you for your contributions.

And don't give me any "trust us, we're experienced programmers" bullshit. I've *seen* ssl/record/ssl3_record.c:

> static const unsigned char ssl3_pad_1[48] = {
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
>     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
> };
> static const unsigned char ssl3_pad_2[48] = {
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
>     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
> };

What's wrong with that, you ask?

Yes, I ask; why not tell us?

Let me show you how I'd have done that:

> static const unsigned char ssl3_pad_1[] =
> {
>     "66666666"
>     "66666666"
>     "66666666"
>     "66666666"
>     "66666666"
>     "66666666"
> };
>
> static const unsigned char*ssl3_pad_2[] =
> {
>     "\\\\\\\\\\\\\\\\"
>     "\\\\\\\\\\\\\\\\"
>     "\\\\\\\\\\\\\\\\"
>     "\\\\\\\\\\\\\\\\"
>     "\\\\\\\\\\\\\\\\"
>     "\\\\\\\\\\\\\\\\"
> };

So, no. I don't trust anyone. Especially not this mess of a code.

So instead of correct portable code which derives obviously and straightforwardly from the specification, you'd write arrays of a different length from the original, the first 48 bytes of which would only be correct in some compilation environments, and even in the cases where those 48 bytes end up correct they have no obvious relationship to the specification they are implementing (your obfuscation making the code much more difficult to review). How are these changes improvements? I'd walk you out of an interview if you offered this as an implementation, let alone as an improvement.

For the record, I have nothing to do with any of the code in OpenSSL.

-- 
J. J. Farrell
Not speaking for Oracle

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Authentication over ECDHE

C.Wehrmeyer
In reply to this post by OpenSSL - User mailing list
On 29.12.18 16:53, Jakob Bohm via openssl-users wrote:
 > The session caching in the SSL and TLS protocols is to skip the
 > expensive key exchange when reconnecting within a few seconds,
 > as is extremely common with web browsers opening up to 8 parallel
 > connections to each server.

My outburst was somewhat out of line. SSL_clear() is not *completely*
superfluous, you're right, but it's incredibly limited.

 > There is hopefully a configuration option to tell the OpenSSL server
 > end SSL_CTX to not do this, just as there should (for multi-process
 > web servers) be an option to hand the state storage over to the web
 > server application for inter-process sharing in whatever the web
 > server application (and its configuration) deems secure.

Then why doesn't the documentation page of SSL_clear() mention this
directly? "If you want to reuse an SSL object, use this function to set
some option on the SSL_CTX object".

On 29.12.18 17:08, Richard Levitte wrote:
 > ...  I'm not sure about you, but I have a hard time seeing how one
 > would trim off fat from *public* structures that everyone and their
 > stray cat might be tinkering in.  Trimming off fat usually means
 > restructuring the structures, and unless they're opaque, the freedom
 > to do so is severily limited.

You're implying that people can't do that anymore. Let me assure you
that they still can, you just made it a little harder for people who're
really determined to walk outside of the API bounds.

On the other hand you've made the normal applications programmers job -
which is to know where and when to allocate and free memory - a lot
harder. Here I am, having a bunch of objects all sitting in a designated
memory area of mine - which I can initialise, reset, and reuse just how
I seem fit (not that I want to horribly break SSL objects, I just want
to determine where they are stored) - and I can't use them because the
OpenSSL devs are working on taking a little bit of power from me that I
need in order to help the library do smart things.

Like, imagine that I know I'll need:

- a context object
- a connection object
- a BIO object
- some X.509 cert object/memory/whatever
- and so forth and so on

And that not just once, but for a thousand connections. As an
application programmer who knows a thing or two about scalable
programming I'd be like: OK, that's fantastic. I can mmap the necessary
memory, use hugepages, reduce the TLB, and just have all that stuff
written on the same chunk without metadata or padding inbetween, which
doesn't bloat our D$. Sweet money!

And now I can't do that because the devs want me to use their
single-object-only creation functions who return already allocated
memory to me. I don't get to decide anymore where my objects are
written, I don't get to decide what caching objects are used (maybe I
don't WANT an X.509 cert object, so I could pass NULL to the function
that creates it, or maybe I already HAVE a couple hundred of those lying
here, so you can have them ... no? You prefer your structures to be
opaque? Oh well).

But, you know, it could still be argued that this is safer somehow.
*Somehow*. If not ... for the fact that I don't even seem to be able to
KEEP the objects OpenSSL created for me quite elaborately.

 > You do know that your string insert NUL bytes, right?  If you have a
 > look at how they're used, you might see why those stray NUL bytes
 > aren't a good thing.

Yes, I do. See below, I wrote the last part first.

(Also, what? Please have a look again, those stray NUL bytes wouldn't
have ANY effect, at least not that I see it. One memcpy(), two
EVP_DigestUpdate(), and it's always a separately calculated length).

 > P.S. as a side note, your message triggered profanity filters.  I
 > don't really care, it's not our filters, but this is just to inform
 > you that your rant didn't quite reach everyone (those with profanity
 > filters in place)
 > /postmaster

It's just that this is so stupid to me. I'm no crypto master, I know
that. But I constantly hear about timing attacks and side channels and
all that, so I tried to avoid stepping into the pitfalls that other
people would do - and then I'm being told it's SUPPOSED to be like that.
Come on, please! It's almost as if the devs aren't even trying.

On 29.12.18 17:21, J. J. Farrell wrote:> So instead of correct portable
code which derives obviously and
 > straightforwardly from the specification, you'd write arrays of a
 > different length from the original, the first 48 bytes of which would
 > only be correct in some compilation environments, and even in the cases
 > where those 48 bytes end up correct they have no obvious relationship to
 > the specification they are implementing (your obfuscation making the
 > code much more difficult to review). How are these changes improvements?
Another implication, this time that my code isn't perfectly portable
code. There is *one* environment I could think of where this wouldn't be
the case - that being Shift JIS environments that tinker with ASCII
standard by replacing a backslash with a Japanese half-width Yen sign -
however:

1. we'll already have much, MUCH bigger problems if ASCII isn't the
encoding the compiler is expecting here, so exchanging 0x5c for '\' is
not going to ruin much more here. And it doesn't even matter anyway
because any Shift JIS editor would display this as the half-width Yen
sign *anyways*. (And that being said, since the main criticism of the
Han unification of the Unicode consortium came from the Japanese, I
don't care if they're going to throw another fit. They can't even
prevent mojibake between mainly Japanese character encodings. At least
ISO-8859-1/CP1252 has the excuse of being the most popular encoding in
the entire west, so ... whatever. Just let them rail.)
2. to be honest I wouldn't have have this be a static array at all, but
rather an exportable pointer and an exportable variable that would hold
the string's size minus one. However, if you actually HAD looked at the
code as is - which you obviously haven't because you wouldn't have even
brought it up then - the size of the array is completely inconsequential
in that particular code. That's right: they don't even derive the
amounts of bytes to copy from the string directly, but rather just use a
constant:

 > npad = (48 / md_size) * md_size;

Oh, you want me to change that? No problem:

 > #define STRING \
 >         "xxxxxxxx" \
 >         "xxxxxxxx" \
 >         "xxxxxxxx" \
 >         "xxxxxxxx" \
 >         "xxxxxxxx" \
 >         "xxxxxxxx"
 >
 > const unsigned char string_length = sizeof(STRING) - 1;
 > const char*string = STRING;
 >
 > npad = (string_length / md_size) * md_size;

Hell, I could even create a macro for this so that I don't even need the
explicit definition of STRING here. It's not as if OpenSSL shies away
from the concept of using macros to auto-generate a plethora of symbols
(I'm looking at include/openssl/crypto.h right now).

 > I'd walk you out of an interview if you offered this as an
 > implementation, let alone as an improvement.

Don't worry, I'd fire you on the spot if you had checked in the existing
code, so I'll call it quits.
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
12