/*
 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.io.File;

/**
 * Test for OCSP timeout.
 *
 * OCSP connection timeout can be set via com.sun.security.ocsp.timeout system
 * property.
 *
 * Test scenario: - a certificate is good - an application tries to check
 * revocation status of certificate via OCSP - HTTP proxy is used - Proxy server
 * delays responses - OCSP connection timeout value is greater than proxy delay
 *
 * Expected result: successful validation
 *
 */

/*
 * @test
 * @author Shivangi Gupta
 * @library ../../common ../../common/bcpkix-jdk15on.jar ../../common/bcprov-jdk15on.jar
 * @run main/othervm/policy=httpTimeNotpolicy -Djava.security.manager
 * HttpProxyOCSPTimeoutNotReachedTest
 */
public class HttpProxyOCSPTimeoutNotReachedTest {

    private static final String WORK_DIR = System.getProperty("test.src", ".");
    private X509Certificate cert;
    private X509Certificate trustedCert;
    private PrivateKey ocspResponderKey;

    private final int proxyDelay = 30;

    private final int ocspConnectionTimeout = 120; // 2 minutes

    public static void main(String[] args) throws Exception {
        HttpProxyOCSPTimeoutNotReachedTest test = new HttpProxyOCSPTimeoutNotReachedTest();
        test.runTest(args);
    }

    private void parseArgs(String[] args) throws Exception {
        String BASE = WORK_DIR.substring(0, WORK_DIR.indexOf("RevocationChecking") + "RevocationChecking".length());
        String certFile = BASE + File.separator + "common" + File.separator + "data" + File.separator + "ca"
                + File.separator + "valid.pem";
        String trustedCertFile = BASE + File.separator + "common" + File.separator + "data" + File.separator + "ca"
                + File.separator + "root.pem";
        String ocspResponderKeyFile = BASE + File.separator + "common" + File.separator + "data" + File.separator + "ca"
                + File.separator + "ocsp_responder_key";
        cert = Utils.getCertFromFile(certFile);
        trustedCert = Utils.getCertFromFile(trustedCertFile);
        ocspResponderKey = Utils.loadRsaPrivateKey(ocspResponderKeyFile);

        if (cert == null) {
            throw new IllegalArgumentException("Certificate is not set");
        }

        if (trustedCert == null) {
            throw new IllegalArgumentException("Trusted certificate is not set");
        }

        if (ocspResponderKey == null) {
            throw new IllegalArgumentException("OCSP responder key is not set");
        }
    }

    private void runTest(String[] args) throws Exception {
        parseArgs(args);
        int httpProxyPort = Utils.getFreePort();
        HttpProxyServer proxyServer = new HttpProxyServer(httpProxyPort);
        proxyServer.setDaemon(true);
        proxyServer.start();
        System.out.println("HTTP proxy server was started on  port" + httpProxyPort);
        proxyServer.setDelay(proxyDelay);
        Utils.sleep(5);

        System.setProperty("http.proxyHost", "localhost");
        System.setProperty("http.proxyPort", String.valueOf(httpProxyPort));
        System.setProperty("http.nonProxyHosts", "");

        SimpleOCSPResponderDataBase ocspResponderDatabase = new SimpleOCSPResponderDataBase();
        ocspResponderDatabase.addGood(cert.getSerialNumber());
        int simpleOcspResponderPort = Utils.getFreePort();
        SimpleOCSPResponder simpleOcspResponder = new SimpleOCSPResponder(simpleOcspResponderPort,
                ocspResponderDatabase, "SHA1withRSA", ocspResponderKey);
        simpleOcspResponder.setDaemon(true);
        simpleOcspResponder.start();
        Utils.sleep(5);
        // Set maximum allowable OCSP connection timeout
        System.setProperty("com.sun.security.ocsp.timeout", String.valueOf(ocspConnectionTimeout));
        System.out.println("com.sun.security.ocsp.timeout" + System.getProperty("com.sun.security.ocsp.timeout"));
        System.out.println("Testing with OCSP connection timeout that is greater than HTTP proxy delay");
        System.out.println("Expected result: successful validation");
        Utils.doOcspValidation(cert, trustedCert, simpleOcspResponderPort);
        System.out.println("Test passed");
    }
}
