Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

also zero pad DHE public key in ClientKeyExchange message for interop #12331

Closed
wants to merge 3 commits into from

Conversation

heinzelotto
Copy link
Contributor

The Windows SChannel TLS stack has problems when the DHE pub key is encoded with fewer bytes than the DHE prime.

In #1320 padding has already been added to work around this problem for the OpenSSL server case, and I experimented a little and Microsoft seems to have also fixed this in their client code.

I guess that OpenSSL server <-> windows client is the more common case, but the opposite case still causes handshakes to randomly fail when a DHE suite is selected. By adding padding for the OpenSSL client key exchange I hope to fix that.

This is my first contribution to OpenSSL, I tried to follow the style guide and conventions. Any corrections are much appreciated.

@openssl-machine openssl-machine added the hold: cla required The contributor needs to submit a license agreement label Jun 30, 2020
ssl/statem/statem_clnt.c Outdated Show resolved Hide resolved
@heinzelotto heinzelotto closed this Jul 1, 2020
@heinzelotto heinzelotto reopened this Jul 1, 2020
@openssl-machine openssl-machine removed the hold: cla required The contributor needs to submit a license agreement label Jul 1, 2020
@heinzelotto heinzelotto force-pushed the master branch 2 times, most recently from 7737456 to 4ca393b Compare July 1, 2020 18:56
@heinzelotto heinzelotto requested a review from davidben July 2, 2020 14:45
davidben
davidben previously approved these changes Jul 6, 2020
Copy link
Contributor

@davidben davidben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me, but I'm not as familiar with the new provider-based APIs and WPACKET, so you should get a second review from someone more actively involved with the project.

ssl/statem/statem_clnt.c Outdated Show resolved Hide resolved
ssl/statem/statem_clnt.c Outdated Show resolved Hide resolved
@heinzelotto
Copy link
Contributor Author

@mattcaswell are you familiar with the WPACKET API and would you taking a look?

Copy link
Contributor

@kaduk kaduk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks fine to me; I just note some optional stylistic tweaks.
(Matt is on holiday at the moment, as I undestand it.)

/*
* for interoperability with some versions of the Microsoft TLS
* stack, we need to zero pad the DHE pub key to the same length
* as the prime, so use the length of the prime here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have to make other changes, we could use a capital 'F' to start the comment and a period at the end, to make it a complete sentence, but it's not worth changing just to fix that.
(And the ServerKeyExchange case doesn't do either, anyway.)

EVP_PKEY *ckey = NULL, *skey = NULL;
unsigned char *keybytes = NULL;
int np;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider a different name for this variable, maybe prime_len -- I'm not actually sure what "np" is supposed to indicate or stand for.

@kaduk
Copy link
Contributor

kaduk commented Jul 12, 2020

I'm going to dismiss @davidben 's review, since it was before the force-push.
(In some sense it doesn't matter, since we're both committers and this needs an OTC review in order to get merged.)

@kaduk kaduk added approval: otc review pending This pull request needs review by an OTC member branch: master Merge to master branch triaged: feature The issue/pr requests/adds a feature labels Jul 12, 2020
@kaduk kaduk dismissed davidben’s stale review July 12, 2020 00:44

invalidated by force-push

@kaduk
Copy link
Contributor

kaduk commented Jul 12, 2020

(the travis failures are the spurious "../../_srcdir/config: no such file or directory" that we've been seeing lately)

@heinzelotto
Copy link
Contributor Author

Thank you @kaduk for your comments. I wanted to ask whether there were any necessary steps on my side once marked as "approval: otc review pending"? And I figured that if I am going to do an additional round trip anyway, I will just add the changes you suggested. (Hopefully I did the fixup! correctly)

@kaduk
Copy link
Contributor

kaduk commented Jul 17, 2020

@heinzelotto the fixup looks good, thank you.
With the "approval: otc review pending" set we are not waiting on anything else from you (unless that review produces additional feedback/requested changes). Unfortunately, OTC time is in high demand right now, with the work towards the 3.0 release, so I don't have a great estimate for you.

SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE,
ERR_R_INTERNAL_ERROR);
goto err;
}

BN_bn2bin(pub_key, keybytes);
BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add check for the return value. Although it is in practice "can't happen" condition, if prime_len is lower than the length of the actual pub_key, the function will fail. You can move the call to the if condition above.

Copy link
Contributor

@kaduk kaduk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixup (check BN_bn2binpad return value) looks good.
The Travis failures are all the (unrelated) 'pem_to_der_deserializer_functions' declaration issue.

@openssl-machine
Copy link
Collaborator

This PR is in a state where it requires action by @openssl/otc but the last update was 30 days ago

Copy link
Member

@t8m t8m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@t8m t8m added approval: done This pull request has the required number of approvals and removed approval: otc review pending This pull request needs review by an OTC member labels Aug 31, 2020
@openssl-machine openssl-machine removed the approval: done This pull request has the required number of approvals label Sep 1, 2020
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@openssl-machine openssl-machine added the approval: ready to merge The 24 hour grace period has passed, ready to merge label Sep 1, 2020
openssl-machine pushed a commit that referenced this pull request Sep 1, 2020
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from #12331)
@t8m
Copy link
Member

t8m commented Sep 1, 2020

Merged to master. Thank you for your contribution and patience when waiting for the reviews.

@t8m t8m closed this Sep 1, 2020
swenkeratmicrosoft pushed a commit to swenkeratmicrosoft/openssl that referenced this pull request Sep 1, 2020
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from openssl#12331)
@paveljanik
Copy link

This makes openssl as the client send out zero padded DHE pubkey in TLSv1.2 which means it breaks the standard as leading zeros should be stripped in TLSv1.2 (as opposite to TLSv1.3 where they should be left in the stream!). Is this really what you need/want?

@davidben
Copy link
Contributor

davidben commented Feb 4, 2021

The spec says the resulting secret has leading zeros removed. I believe RFC5246 is silent as to whether the public key is padded. (Which is a mistake. It should have picked one, and the correct one to pick is fixed-width. But a bit late to fix that now, so implementations have to pick one.)

@paveljanik
Copy link

So on the server side, you have to support (try...) both because your clients could have picked padding and not-padding? ;-)

@davidben
Copy link
Contributor

davidben commented Feb 4, 2021

No, just have your parser tolerate leading zeros, as OpenSSL does. The resulting secret is different because it's a KDF input.

(Alternatively, stop doing TLS 1.2 DHE as it's beyond saving.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Merge to master branch triaged: feature The issue/pr requests/adds a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants