1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.ssl.ocsp;
17
18 import io.netty.buffer.ByteBufUtil;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.channel.SimpleChannelInboundHandler;
21 import io.netty.handler.codec.http.FullHttpResponse;
22 import io.netty.handler.codec.http.HttpHeaderNames;
23 import io.netty.util.concurrent.Promise;
24 import io.netty.util.internal.logging.InternalLogger;
25 import io.netty.util.internal.logging.InternalLoggerFactory;
26 import org.bouncycastle.cert.ocsp.OCSPException;
27 import org.bouncycastle.cert.ocsp.OCSPResp;
28
29 import static io.netty.handler.codec.http.HttpResponseStatus.OK;
30 import static io.netty.util.internal.ObjectUtil.checkNotNull;
31
32 final class OcspHttpHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
33
34 private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(OcspHttpHandler.class);
35 private final Promise<OCSPResp> responseFuture;
36
37 static final String OCSP_REQUEST_TYPE = "application/ocsp-request";
38 static final String OCSP_RESPONSE_TYPE = "application/ocsp-response";
39
40
41
42
43
44
45 OcspHttpHandler(Promise<OCSPResp> responsePromise) {
46 this.responseFuture = checkNotNull(responsePromise, "ResponsePromise");
47 }
48
49 @Override
50 protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse response) throws Exception {
51 try {
52
53 if (LOGGER.isDebugEnabled()) {
54 LOGGER.debug("Received OCSP HTTP Response: {}", response);
55 }
56
57
58 String contentType = response.headers().get(HttpHeaderNames.CONTENT_TYPE);
59 if (contentType == null) {
60 throw new OCSPException("HTTP Response does not contain 'CONTENT-TYPE' header");
61 }
62
63
64 if (!contentType.equalsIgnoreCase(OCSP_RESPONSE_TYPE)) {
65 throw new OCSPException("Response Content-Type was: " + contentType +
66 "; Expected: " + OCSP_RESPONSE_TYPE);
67 }
68
69
70 if (response.status() != OK) {
71 throw new IllegalArgumentException("HTTP Response Code was: " + response.status().code() +
72 "; Expected: 200");
73 }
74
75 responseFuture.trySuccess(new OCSPResp(ByteBufUtil.getBytes(response.content())));
76 } finally {
77 ctx.channel().close();
78 }
79 }
80
81 @Override
82 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
83 responseFuture.tryFailure(cause);
84 }
85 }