import ballerina/io;
import ballerina/http;
import ballerina/mime;endpoint http:Listener helloWorldEP {
    port:9095,
    secureSocket: {
        keyStore: {
            filePath: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            filePath: "${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"
    }
};@http:ServiceConfig {
     endpoints:[helloWorldEP],
     basePath:"/hello"
}service<http:Service> helloWorld bind helloWorldEP {
    @http:ResourceConfig {
        methods:["GET"],
        path:"/"
    }    sayHello (endpoint conn, http:Request req) {
        http:Response res = new;
        res.setStringPayload("Successful");
        _ = conn -> respond(res);
    }
}endpoint http:Client clientEP {
    targets: [{
        url: "https://localhost:9095",
        secureSocket: {
            keyStore: {
                filePath: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
                password: "ballerina"
            },
            trustStore: {
                filePath: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
                password: "ballerina"
            },
            protocol: {
                name: "TLS"
            },
            ciphers:["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"]
        }
    }]
};
function main (string[] args) {
    http:Request req = new;
    var resp = clientEP -> get("/hello/", req);
    match resp {
        http:HttpConnectorError err => io:println(err.message);
        http:Response response => {
            match (response.getStringPayload()) {
                http:PayloadError payloadError => io:println(payloadError.message);
                string res => io:println(res);
            }
        }
    }
}

Mutual SSL

Ballerina supports mutual ssl which is a certificate based authentication where two parties (client and server) authenticate each other by verifying digital certificates. So in simple terms both parties are assured of other's identity.

import ballerina/io;
import ballerina/http;
import ballerina/mime;
endpoint http:Listener helloWorldEP {
    port:9095,
    secureSocket: {
        keyStore: {
            filePath: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        },
        trustStore: {
            filePath: "${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"
    }
};
@http:ServiceConfig {
     endpoints:[helloWorldEP],
     basePath:"/hello"
}
service<http:Service> helloWorld bind helloWorldEP {
    @http:ResourceConfig {
        methods:["GET"],
        path:"/"
    }
    sayHello (endpoint conn, http:Request req) {
        http:Response res = new;
        res.setStringPayload("Successful");

Set response payload.

        _ = conn -> respond(res);
    }
}

Send response to client.

endpoint http:Client clientEP {
    targets: [{
        url: "https://localhost:9095",
        secureSocket: {
            keyStore: {
                filePath: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
                password: "ballerina"
            },
            trustStore: {
                filePath: "${ballerina.home}/bre/security/ballerinaTruststore.p12",
                password: "ballerina"
            },
            protocol: {
                name: "TLS"
            },
            ciphers:["TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"]
        }
    }]
};
function main (string[] args) {

Ballerina client connector can be used to connect to the created https server. You have to run the service before running this main function. As this is a mutual ssl connection, client also needs to provide keyStoreFile, keyStorePassword, trustStoreFile and trustStorePassword.

    http:Request req = new;
    var resp = clientEP -> get("/hello/", req);
    match resp {
        http:HttpConnectorError err => io:println(err.message);
        http:Response response => {
            match (response.getStringPayload()) {
                http:PayloadError payloadError => io:println(payloadError.message);
                string res => io:println(res);
            }
        }
    }
}

Creates a request.

$ ballerina run mutual-ssl.bal
ballerina: started HTTPS/WSS endpoint 0.0.0.0:9095
Successful
ballerina: stopped HTTPS/WSS endpoint 0.0.0.0:9095

Run the service