Authentication with Certificates

The following example script illustrates the process for authentication with username and certificates.

private void loginWithCertificate() {

        String username = getUserInput("Username : ");
        byte[] clientChallengeBytes = String.valueOf(new Random().nextLong()).getBytes();
        String encodedClientChallenge = Base64.encodeBase64URLSafeString(clientChallengeBytes);

        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<String, String>();
        requestParams.add("user_name", username);
        requestParams.add("auth_type", "server");
        requestParams.add("client_challenge", encodedClientChallenge);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
                requestParams, headers);

        ServerChallengeResponse challengeResponse = null;
        try {
            challengeResponse = invokeApiWithPost(RestApi.LOGIN_CERT_SVR, requestEntity,
                    ServerChallengeResponse.class);
        }
        catch (RestServiceException e) {
            sop("************************************");
            sop("Authenticate Server Failed");
            sop("************************************");
            sop("Error Code: " + e.getError().toString() + "\r\nError: "
                    + e.getError().getErrorMessage() + "\r\nDetail : " + e.getMessage());
            return;
        }

        byte[] encryptedClientChallengeBytes = Base64.decodeBase64(challengeResponse
                .getClientChallenge());
        byte[] serverChallengeBytes = Base64.decodeBase64(challengeResponse.getServerChallenge());

        String serverCertName = getUserInput("Enter the name & location of the server certificate : ");
        File certFile = new File(serverCertName);
        if (!certFile.exists()) {
            sop("Server certificate doesn't exist in that location");
            return;
        }

        X509Certificate serverCertificate = null;


        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            serverCertificate = (X509Certificate) certFactory
                    .generateCertificate(new FileInputStream(certFile));

            Cipher decryptCipher = Cipher.getInstance("RSA");
            decryptCipher.init(Cipher.DECRYPT_MODE, serverCertificate.getPublicKey());
            byte[] decryptedClientChallengeBytes = decryptCipher
                    .doFinal(encryptedClientChallengeBytes);

            // Compare the clientChallenge with decryptedClientChallenge.
            boolean serverValidated = Arrays.equals(clientChallengeBytes,
                    decryptedClientChallengeBytes);

            if (serverValidated) {
                sop("Server response validation 'PASSED' ... proceeding further to login to REST service");
            }
            else {
                sop("Server response validation 'FAILED'");
                return;
            }
        }
        catch (Exception e) {
            sop("Could not process with the ceritificate : " + e.getMessage());
            return;
        }
        // Get the private key of the client certificate
        PrivateKey privateKey = getPrivateKeyForClientCertificate();
        if (privateKey == null) {
            sop("Couldn't get private key from the client certificate");
            return;
        }

        byte[] encryptedServerChallengeBytes = null;

        try {
            Cipher encryptCipher = Cipher.getInstance("RSA");
            encryptCipher.init(Cipher.ENCRYPT_MODE, privateKey);
            encryptedServerChallengeBytes = encryptCipher.doFinal(serverChallengeBytes);
        }
        catch (Exception e) {
            sop("Couldn't encrypt server challenge : " + e.getMessage());
            return;
        }

        requestParams = new LinkedMultiValueMap<String, String>();
        requestParams.add("user_name", username);
        requestParams.add("auth_type", "client");
        requestParams.add("server_challenge",
                Base64.encodeBase64URLSafeString(encryptedServerChallengeBytes));

        headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Authorization", challengeResponse.getAuthToken());

        requestEntity = new HttpEntity<MultiValueMap<String, String>>(requestParams, headers);

        LoginResponse loginResponse = null;
        try {
            loginResponse = invokeApiWithPost(RestApi.LOGIN_CERT_CL, requestEntity,
                    LoginResponse.class);
        }
        catch (RestServiceException e) {
            sop("************************************");
            sop("Login with ceritficate : FAILED");
            sop("************************************");
            sop("Error Code: " + e.getError().toString() + "\r\nError: "
                    + e.getError().getErrorMessage() + "\r\nDetail : " + e.getMessage());
        }

        if (loginResponse != null) {
            String restEndPoint = loginResponse.getEndPoint();
            if (!isEmpty(restEndPoint)) {
                sop("************************************");
                sop("Login with ceritficate : PASSED");
                sop("************************************");
                this.svcEndPoint = restEndPoint;
                this.token = loginResponse.getAuthToken();
            }
            else {
                sop("************************************");
                sop("Login with user/pwd : FAILED");
                sop("************************************");
                sop("Error: RestEndPoint has not been defined for this ARG."
                        + "Please check REST API settings in PodConfig.ini.");
            }
        }
    }