static Promise<BasicOCSPResp> query(final X509Certificate x509Certificate,
                                        final X509Certificate issuer, final boolean validateResponseNonce,
                                        final IoTransport ioTransport, final DnsNameResolver dnsNameResolver) {
        final EventLoop eventLoop = ioTransport.eventLoop();
        final Promise<BasicOCSPResp> responsePromise = eventLoop.newPromise();
        eventLoop.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    CertificateID certificateID = new CertificateID(new JcaDigestCalculatorProviderBuilder()
                            .build().get(HASH_SHA1), new JcaX509CertificateHolder(issuer),
                            x509Certificate.getSerialNumber());

                    // Initialize OCSP Request Builder and add CertificateID into it.
                    OCSPReqBuilder builder = new OCSPReqBuilder();
                    builder.addRequest(certificateID);

                    // Generate 16-bytes (octets) of nonce and add it into OCSP Request builder.
                    // Because as per RFC-8954#2.1:
                    //
                    //   OCSP responders MUST accept lengths of at least
                    //   16 octets and MAY choose to ignore the Nonce extension for requests
                    //   where the length of the nonce is less than 16 octets.
                    byte[] nonce = new byte[16];
                    SECURE_RANDOM.nextBytes(nonce);
                    final DEROctetString derNonce = new DEROctetString(nonce);
                    builder.setRequestExtensions(new Extensions(new Extension(id_pkix_ocsp_nonce, false, derNonce)));

                    // Get OCSP URL from Certificate and query it.
                    URL uri = new URL(parseOcspUrlFromCertificate(x509Certificate));

                    // Find port
                    int port = uri.getPort();
                    if (port == -1) {
                        port = uri.getDefaultPort();
                    }

                    // Configure path
                    String path = uri.getPath();
                    if (path.isEmpty()) {
                        path = "/";
                    } else {
                        if (uri.getQuery() != null) {
                            path = path + '?' + uri.getQuery();
                        }
                    }

                    Promise<OCSPResp> ocspResponsePromise = query(eventLoop,
                            Unpooled.wrappedBuffer(builder.build().getEncoded()),
                            uri.getHost(), port, path, ioTransport, dnsNameResolver);

                    // Validate OCSP response
                    ocspResponsePromise.addListener(new GenericFutureListener<Future<OCSPResp>>() {
                        @Override
                        public void operationComplete(Future<OCSPResp> future) throws Exception {
                            // If Future was successful then we have received OCSP response
                            // We will now validate it.
                            if (future.isSuccess()) {
                                BasicOCSPResp resp = (BasicOCSPResp) future.get().getResponseObject();
                                validateResponse(responsePromise, resp, derNonce, issuer, validateResponseNonce);
                            } else {
                                responsePromise.tryFailure(future.cause());
                            }
                        }
                    });

                } catch (Exception ex) {
                    responsePromise.tryFailure(ex);
                }
            }
        });
        return responsePromise;
    }
@Test
    void simpleOcspQueryTest() throws IOException, ExecutionException, InterruptedException {
        HttpsURLConnection httpsConnection = null;
        try {
            URL url = new URL("https://netty.io");
            httpsConnection = (HttpsURLConnection) url.openConnection();
            httpsConnection.connect();

            // Pull server certificates for validation
            X509Certificate[] certs = (X509Certificate[]) httpsConnection.getServerCertificates();
            X509Certificate serverCert = certs[0];
            X509Certificate certIssuer = certs[1];

            Promise<BasicOCSPResp> promise = OcspClient.query(serverCert, certIssuer, false,
                    IoTransport.DEFAULT, createDefaultResolver(IoTransport.DEFAULT));
            BasicOCSPResp basicOCSPResp = promise.get();

            // 'null' means certificate is valid
            assertNull(basicOCSPResp.getResponses()[0].getCertStatus());
        } finally {
            if (httpsConnection != null) {
                httpsConnection.disconnect();
            }
        }
    }