HTTPS/Client-authenticated
Demonstrate how to connect to a web server over HTTPS where that server requires that the client present a certificate to prove who (s)he is. Unlike with the HTTPS request with authentication task, it is not acceptable to perform the authentication by a username/password or a set cookie.
You are encouraged to solve this task according to the task description, using any language you may know.
This task is in general useful for use with webservice clients as it offers a high level of assurance that the client is an acceptable counterparty for the server. For example, Amazon Web Services uses this style of authentication.
C#
<lang csharp> using System; using System.Net;
class Program {
class MyWebClient : WebClient { protected override WebRequest GetWebRequest(Uri address) { HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address); request.ClientCertificates.Add(new X509Certificate()); return request; } } static void Main(string[] args) { var client = new MyWebClient();
var data = client.DownloadString("https://example.com");
Console.WriteLine(data); }
} </lang>
Kotlin
<lang scala>// version 1.2.0
import java.security.KeyStore import javax.net.ssl.KeyManagerFactory import javax.net.ssl.SSLContext import javax.net.ssl.HttpsURLConnection import java.net.URL import java.io.FileInputStream import java.io.InputStreamReader import java.io.BufferedReader
fun getSSLContext(p12Path: String, password: String): SSLContext {
val ks = KeyStore.getInstance("pkcs12") val fis = FileInputStream(p12Path) val pwd = password.toCharArray() ks.load(fis, pwd) val kmf = KeyManagerFactory.getInstance("PKIX") kmf.init(ks, pwd) val sc = SSLContext.getInstance("TLS") sc.init(kmf.keyManagers, null, null) return sc
}
fun main(args: Array<String>) {
// The .p12 file contains the client certificate and private key val sc = getSSLContext("whatever.p12", "password") val url = URL("https://somehost.com") val con = url.openConnection() as HttpsURLConnection con.sslSocketFactory = sc.socketFactory val isr = InputStreamReader(con.inputStream) val br = BufferedReader(isr) while (true) { val line = br.readLine() if (line == null) break println(line) }
}</lang>
Lasso
<lang Lasso>local(sslcert = file('myCert.pem')) local(x = curl('https://sourceforge.net'))
- x->set(CURLOPT_SSLCERT, #sslcert->readstring)
- sslcert->close
- x->result->asString</lang>
Mathematica / Wolfram Language
<lang Mathematica>a = RunThrough["curl -E myCert.pem https://www.example.com", 1] For[ i=0, i < Length[a] , i++, SomeFunction[a]]</lang>
Perl
<lang python>#!/usr/bin/env perl -T use 5.018_002; use warnings; use LWP;
our $VERSION = 1.000_000;
my $ua = LWP::UserAgent->new(
ssl_opts => { SSL_cert_file => 'certificate.pem', SSL_key_file => 'key.pem', verify_hostname => 1, }
); my $req = HTTP::Request->new( GET => 'https://www.example.com' ); my $res = $ua->request($req); if ( $res->is_success ) {
say $res->content;
} else {
say $res->status_line;
}</lang>
PicoLisp
<lang PicoLisp>(in '(curl "-E" "myCert.pem" "https://www.example.com")
(while (line) (doSomeProcessingWithLine @) ) )</lang>
Python
<lang python>import httplib
connection = httplib.HTTPSConnection('www.example.com',cert_file='myCert.PEM') connection.request('GET','/index.html') response = connection.getresponse() data = response.read() </lang>
Racket
Skeleton code to connect to a server: <lang racket>
- lang racket
(require openssl/mzssl) (define ctx (ssl-make-client-context)) (ssl-set-verify! ctx #t) ; verify the connection (ssl-load-verify-root-certificates! ctx "my-cert.pem") (define-values [I O] (ssl-connect "www.example.com" 443 ctx)) </lang>
Tcl
Uses the Tls package. <lang tcl>package require http package require tls
set cert myCert.p12 http::register https 443 [list \
::tls::socket -certfile $cert -password getPass]
proc getPass {} {
return "myPassword"; # Just a noddy example...
}
- Make a secure authenticated connection
set token [http::geturl https://verysecure.example.com/]
- Now as for conventional use of the “http” package
set data [http::data $token] http::cleanup $token</lang>
zkl
Uses libCurl. <lang zkl>var CURL=Import("zklCurl"), c=CURL(); c.setOpt("SSLCERT","certFile.pem"); c.setOpt("SSLCERTTYPE","pem"); c.get("http://zenkinetic.com"); // lame example to show how to read</lang>