-
-
Notifications
You must be signed in to change notification settings - Fork 16.3k
Ability to pass along attributes via SslContext #6542
Description
This is related to the #6158 OCSP pull request.
The #6158 PR is demonstrating the most simple way of obtaining and dealing with OCSP stapling but it gets a bit more complicated in practice. In particular when you look at how SniHandler and AsyncMapping work (which we use).
AsyncMappingreturnsFuture<SslContext>SniHandlerusesFuture<SslContext>to constructSslEngine+SslHandler
... but how do I pass along the info that is needed to obtain a staple or the OCSP staple itself? I'm currently using the delegate pattern around SslContext but it gets quickly rather messy and error prone in conjunction with reference counting. It'd be great if it was possible to pass along arbitrary attributes via SslContext (e.g. via AttributeMap or simply as a Map<Object, Object>).
A more general way of looking at is the desire to pass configuration parameters from SslContext to "things" that use it. One scenario is described above but other use-cases could be other config parameters for the SslEngine such as setEnabledProtocols() or some custom behavior for the SslHandler etc etc.
Here's some pseudo code to illustrate it. WDYT - happy to PR it.
public class MySniHandler extends SniHandler {
public static final AttributeKey<OcspKey> OCSP_KEY = AttributeKey.valueOf(OcspKey.class, "OCSP_KEY");
public static final AttributeKey<String[]> PROTOCOLS_KEY = AttributeKey.valueOf(String[].class, "PROTOCOLS_KEY");
private final OcspCache<OcspKey, Future<byte[]>> ocspCache;
public MySniHandler(AsyncMapping<String, SslContext> mapping, OcspCache<OcspKey, Future<byte[]>> ocspCache) {
super(mapping);
this.ocspCache = ocspCache;
}
@Override
protected void replaceHandler(ChannelHandlerContext ctx, String hostname, SslContext sslContext) throws Exception {
SslHandler sslHandler = sslContext.newHandler(ctx.alloc());
ReferenceCountedOpenSslEngine engine = (ReferenceCountedOpenSslEngine) sslHandler.engine();
OcspKey ocspKey = sslContext.attr(OCSP_KEY).get();
// I (the server) may or may not have a staple and I don't want
// to make the client wait for it.
Future<byte[]> future = ocspCache.get(ocspKey);
if (future.isSuccess()) {
engine.setOcspResponse(future.getNow());
}
String[] protocols = sslContext.attr(PROTOCOLS_KEY).get();
engine.setEnabledProtocols(protocols);
ctx.pipeline().replace(this, SslHandler.class.getName(), sslHandler);
}
}