import ballerina/http;
import ballerina/log;
http:ListenerConfiguration helloWorldEPConfig = {
    secureSocket: {
        keyStore: {
            path: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
            password: "ballerina"
        },
        protocol: {
            name: "TLS",
            versions: ["TLSv1.2", "TLSv1.1"]
        },
        ciphers: ["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"],
        sslVerifyClient: "require"
    }
};
listener http:Listener helloWorldEP = new(9095, helloWorldEPConfig);@http:ServiceConfig {
    basePath: "/hello"
}
service helloWorld on helloWorldEP {    @http:ResourceConfig {
        methods: ["GET"],
        path: "/"
    }
    resource function sayHello(http:Caller caller, http:Request req) {
        var result = caller->respond("Successful");
        if (result is error) {
            log:printError("Error in responding", err = result);
        }
    }
}import ballerina/http;
import ballerina/log;
http:ClientConfiguration clientEPConfig = {
    secureSocket: {
        keyStore: {
            path: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
            password: "ballerina"
        },
        protocol: {
            name: "TLS"
        },
        ciphers: ["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"]
    }
};public function main() {
    http:Client clientEP = new("https://localhost:9095", clientEPConfig);
    var resp = clientEP->get("/hello");
    if (resp is http:Response) {
        var payload = resp.getTextPayload();
        if (payload is string) {
            log:printInfo(payload);
        } else {
            log:printError(<string>payload.detail()["message"]);
        }
    } else {
        log:printError(<string>resp.detail()["message"]);
    }
}

Mutual SSL

Ballerina supports mutual SSL, which is a certificate-based authentication process where two parties (client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other’s identity.

import ballerina/http;
import ballerina/log;
http:ListenerConfiguration helloWorldEPConfig = {
    secureSocket: {
        keyStore: {
            path: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
            password: "ballerina"
        },

Create an HTTP listener configuration, which will configure a listener to accept new connections that are secured via mutual SSL.

        protocol: {
            name: "TLS",
            versions: ["TLSv1.2", "TLSv1.1"]
        },

Enable the preferred SSL protocol and its versions.

        ciphers: ["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"],

Configure the preferred ciphers.

        sslVerifyClient: "require"
    }
};

Enable mutual SSL.

listener http:Listener helloWorldEP = new(9095, helloWorldEPConfig);

Create a listener endpoint.

@http:ServiceConfig {
    basePath: "/hello"
}
service helloWorld on helloWorldEP {

Bind the service to the listener endpoint that you declared earlier.

    @http:ResourceConfig {
        methods: ["GET"],
        path: "/"
    }
    resource function sayHello(http:Caller caller, http:Request req) {
        var result = caller->respond("Successful");
        if (result is error) {
            log:printError("Error in responding", err = result);
        }
    }
}

Send the response to the caller.

# To start the service, navigate to the directory that contains the
# `.bal` file and execute the `ballerina run` command.
$ ballerina run mutual_ssl_service.bal
[ballerina/http] started HTTPS/WSS listener 0.0.0.0:9095
import ballerina/http;
import ballerina/log;
http:ClientConfiguration clientEPConfig = {
    secureSocket: {
        keyStore: {
            path: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            path: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
            password: "ballerina"
        },
        protocol: {
            name: "TLS"
        },
        ciphers: ["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"]
    }
};

Create a client configuration to be passed to the client endpoint. Configure the keyStoreFile, keyStorePassword, trustStoreFile, and thetrustStorePassword, which are required to enable mutual SSL.

public function main() {
    http:Client clientEP = new("https://localhost:9095", clientEPConfig);

Create an HTTP client to interact with the created listener endpoint.

    var resp = clientEP->get("/hello");
    if (resp is http:Response) {

Send a GET request to the listener.

        var payload = resp.getTextPayload();
        if (payload is string) {

If the request is successful, retrieve the text payload from the response.

            log:printInfo(payload);
        } else {

Log the retrieved text payload.

            log:printError(<string>payload.detail()["message"]);
        }
    } else {

If an error occurs while retrieving the text payload, log the error.

        log:printError(<string>resp.detail()["message"]);
    }
}

If an error occurs while getting the response, log the error.

# To start the service, navigate to the directory that contains the
# `.bal` file and execute the `ballerina run` command.
$ ballerina run ssl_client.bal
INFO  [] - Successful