Skip to content

Ensure X509KeyManager methods are called on the correct time when using server-side and support more methods of ExtendedSSLSession.#8283

Merged
normanmaurer merged 1 commit into4.1from
correctly_use_keymanager_server_side
Sep 28, 2018
Merged

Ensure X509KeyManager methods are called on the correct time when using server-side and support more methods of ExtendedSSLSession.#8283
normanmaurer merged 1 commit into4.1from
correctly_use_keymanager_server_side

Conversation

@normanmaurer
Copy link
Copy Markdown
Member

Motivation:

Before when on server-side we just called the X509KeyManager methods when handshake() was called the first time which is not quite correct as we may not have received the full SSL hello / handshake and so could not extra for example the SNI hostname that was requested.
OpenSSL exposes the SSL_CTX_set_cert_cb function which allows to set a callback which is executed at the correct moment, so we should use it. This also allows us to support more methods of ExtendedSSLSession easily.

Modifications:

- Make use of new methods exposed by netty-tcnative since https://github.com/netty/netty-tcnative/pull/388 to ensure we select the key material at the correct time.
- Implement more methods of ExtendedOpenSslSession
- Add unit tests to ensure we are able to retrieve various things on server-side in the X509KeyManager and so verify it is called at the correct time.
- Simplify code by using new netty-tcnative methods.

Result:

More correct implementation for server-side usage and more complete implemented of ExtendedSSLSession.

@normanmaurer normanmaurer changed the base branch from 4.1 to extended_ssl_session September 12, 2018 10:41
@normanmaurer
Copy link
Copy Markdown
Member Author

This depends on netty/netty-tcnative#388 and #8281

@normanmaurer normanmaurer force-pushed the correctly_use_keymanager_server_side branch 2 times, most recently from d867eff to 23fcb7e Compare September 12, 2018 10:45

private SignatureAlgorithmConverter() { }

// OpenSSL has 3 different formats it uses at the moment we will match against all of these.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not just enumerate them in the regex then?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@carl-mastrangelo not sure I understand... Can you show me some code ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Make the regex "^(SHA256withECDSA|SHA512withRSA|SHA256withDSA)$"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah ok... maybe the comment is misleading. It supports more then 3 algorithms. It has just 3 different way to format the supported algorithms

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I guess the comment is correct - it says 'formats' which is not 'algorithms', but it's probably better giving some examples in the comment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

if (matcher.matches()) {
String group2 = matcher.group(2);
if (group2 != null) {
return group2.toUpperCase(Locale.US) + "with" + matcher.group(3).toUpperCase(Locale.US);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You probably want Locale.ROOT I think

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

addressed and rebased.

@normanmaurer normanmaurer force-pushed the correctly_use_keymanager_server_side branch from 23fcb7e to f24e5cf Compare September 14, 2018 13:01
@normanmaurer normanmaurer changed the base branch from extended_ssl_session to 4.1 September 14, 2018 13:02
@normanmaurer
Copy link
Copy Markdown
Member Author

@carl-mastrangelo PTAL again

Copy link
Copy Markdown
Member

@carl-mastrangelo carl-mastrangelo left a comment

Choose a reason for hiding this comment

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

LGTM

@normanmaurer normanmaurer force-pushed the correctly_use_keymanager_server_side branch from f24e5cf to 239dc86 Compare September 14, 2018 19:43
Copy link
Copy Markdown
Member

@trustin trustin left a comment

Choose a reason for hiding this comment

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

Mostly nits

}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: Better leaving this as is?

try {
ServerContext context = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
sessionContext = newSessionContext(this, ctx, engineMap, trustCertCollection, trustManagerFactory,
keyCertChain, key, keyPassword, keyManagerFactory);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Indentation

@Override
public String[] getPeerSupportedSignatureAlgorithms() {
synchronized (ReferenceCountedOpenSslEngine.this) {
if (peerSupportedSignatureAlgorithms == null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

More readable by returning early when peerSupportedSignatureAlgorithms != null?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I dont think so

synchronized (ReferenceCountedOpenSslEngine.this) {
if (peerSupportedSignatureAlgorithms == null) {
if (isDestroyed()) {
peerSupportedSignatureAlgorithms = EmptyArrays.EMPTY_STRINGS;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need to clone after this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

} else {
String[] algs = SSL.getSigAlgs(ssl);
if (algs == null) {
peerSupportedSignatureAlgorithms = EmptyArrays.EMPTY_STRINGS;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need to clone since the array is empty

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

cloning an empty array is super cheap and it simplifies the flow of the method so let me leave the method like it is.

// OpenJDK SSLEngineImpl does.
keyManagerHolder.setKeyMaterialServerSide(engine);
} catch (Throwable cause) {
logger.debug("request of key failed", cause);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about: `"Failed to set the server-side key material:", cause


private SignatureAlgorithmConverter() { }

// OpenSSL has 3 different formats it uses at the moment we will match against all of these.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I guess the comment is correct - it says 'formats' which is not 'algorithms', but it's probably better giving some examples in the comment.

if (matcher.matches()) {
String group2 = matcher.group(2);
if (group2 != null) {
return group2.toUpperCase(Locale.ROOT) + "with" + matcher.group(3).toUpperCase(Locale.ROOT);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Learned Locale.ROOT just today. 👍

}

static boolean isBoringSSL() {
return "BoringSSL".equals(OpenSsl.versionString());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Curious if we should be case-insensitive here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think its fine ...


@Test
public void testInvalid() {
assertNull(SignatureAlgorithmConverter.toJavaName("ThisIsSomeThingInvalid"));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: SomeThing -> Something

…ng server-side and support more methods of ExtendedSSLSession.

Motivation:

Before when on server-side we just called the X509KeyManager methods when handshake() was called the first time which is not quite correct as we may not have received the full SSL hello / handshake and so could not extra for example the SNI hostname that was requested.
OpenSSL exposes the SSL_CTX_set_cert_cb function which allows to set a callback which is executed at the correct moment, so we should use it. This also allows us to support more methods of ExtendedSSLSession easily.

Modifications:

- Make use of new methods exposed by netty-tcnative since netty/netty-tcnative#388 to ensure we select the key material at the correct time.
- Implement more methods of ExtendedOpenSslSession
- Add unit tests to ensure we are able to retrieve various things on server-side in the X509KeyManager and so verify it is called at the correct time.
- Simplify code by using new netty-tcnative methods.

Result:

More correct implementation for server-side usage and more complete implemented of ExtendedSSLSession.
@normanmaurer normanmaurer force-pushed the correctly_use_keymanager_server_side branch from 239dc86 to 00ca995 Compare September 28, 2018 08:52
@normanmaurer
Copy link
Copy Markdown
Member Author

I will merge this once the CI is done

@normanmaurer normanmaurer merged commit 59973e9 into 4.1 Sep 28, 2018
@normanmaurer normanmaurer deleted the correctly_use_keymanager_server_side branch September 28, 2018 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants