HTTPS/Client-authenticated: Difference between revisions

m
→‎{{header|Wren}}: Another minor change
m (→‎{{header|Wren}}: Another minor change)
 
(16 intermediate revisions by 9 users not shown)
Line 4:
 
This task is in general useful for use with [[Creating a SOAP Client|webservice client]]s as it offers a high level of assurance that the client is an acceptable counterparty for the server. For example, [http://aws.amazon.com/ Amazon Web Services] uses this style of authentication.
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">r: request.get.certificate:"mycert.pem" "https://www.example.com" ø</syntaxhighlight>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|3.0}}
 
<langsyntaxhighlight lang="csharp">
using System;
using System.Net;
Line 32 ⟶ 36:
}
}
</syntaxhighlight>
</lang>
 
 
=={{header|Go}}==
<langsyntaxhighlight Golang="go">package main
 
import (
Line 74 ⟶ 77:
 
}
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.net.URI;
import java.net.URL;
import java.security.KeyStore;
import java.util.Scanner;
 
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
 
public final class HTTPSClientAuthenticated {
 
public static void main(String[] aArgs) throws Exception {
final String keyStorePath = "the/path/to/keystore"; // The key store contains the client's certificate
final String keyStorePassword = "my-password";
SSLContext sslContext = getSSLContext(keyStorePath, keyStorePassword);
URL url = new URI("https://somehost.com").toURL();
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
// Obtain response from the url
BufferedInputStream response = (BufferedInputStream) connection.getInputStream();
try ( Scanner scanner = new Scanner(response) ) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}
}
private static SSLContext getSSLContext(String aPath, String aPassword) throws Exception {
KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load( new FileInputStream(aPath), aPassword.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
keyManagerFactory.init(keyStore, aPassword.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
return sslContext;
}
}
</syntaxhighlight>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using HTTP, MbedTLS
 
conf = MbedTLS.SSLConfig(true, log_secrets="/utl/secret_key_log.log")
Line 83 ⟶ 132:
 
println(resp)
</langsyntaxhighlight>{{output}}<pre>
HTTP.Messages.Response:
"""
Line 97 ⟶ 146:
 
{
"origin": "xx104.xx28.x10.xxx103"
}
"""
Line 103 ⟶ 152:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.2.0
 
import java.security.KeyStore
Line 139 ⟶ 188:
println(line)
}
}</langsyntaxhighlight>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">local(sslcert = file('myCert.pem'))
local(x = curl('https://sourceforge.net'))
#x->set(CURLOPT_SSLCERT, #sslcert->readstring)
#sslcert->close
#x->result->asString</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">a = RunThrough["curl -E myCert.pem https://www.example.com", 1]
For[ i=0, i < Length[a] , i++, SomeFunction[a]]</langsyntaxhighlight>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import httpclient, net
var client = newHttpClient(sslContext = newContext(certFile = "mycert.pem"))
var r = client.get("https://www.example.com")</syntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight pythonlang="perl">#!/usr/bin/env perl -T
use 5.018_002;
use warnings;
Line 173 ⟶ 228:
else {
say $res->status_line;
}</langsyntaxhighlight>
 
=={{header|Phix}}==
{{libheader|Phix/libcurl}}
Exactly the same as the HTTP#Phix task, except for the CURLOPT_SSLCERT part.
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">libcurl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #7060A8;">curl_global_init</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">curl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_init</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CURLOPT_URL</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"https://sourceforge.net"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"myCert.pem"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CURLOPT_SSLCERT</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_perform_ex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">curl_easy_cleanup</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">curl_global_cleanup</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(in '(curl "-E" "myCert.pem" "https://www.example.com")
(while (line)
(doSomeProcessingWithLine @) ) )</syntaxhighlight>
 
=={{header|Python}}==
<syntaxhighlight 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()
</syntaxhighlight>
 
=={{header|Racket}}==
 
Skeleton code to connect to a server:
<syntaxhighlight 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))
</syntaxhighlight>
 
=={{header|Perl 6Raku}}==
(formerly Perl 6)
<lang perl6>
<syntaxhighlight lang="raku" line>
# cert creation commands
 
Line 205 ⟶ 306:
$s.close;
 
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
{{libheader|libcurl}}
Exactly the same as the HTTP#Phix task, except for the CURLOPT_SSLCERT part.
<lang Phix>include builtins\libcurl.e
curl_global_init()
atom curl = curl_easy_init()
curl_easy_setopt(curl, CURLOPT_URL, "https://sourceforge.net")
integer fn = open("myCert.pem","r")
curl_easy_setopt(curl, CURLOPT_SSLCERT, get_text(fn))
close(fn)
object res = curl_easy_perform_ex(curl)
curl_easy_cleanup(curl)
curl_global_cleanup()
puts(1,res)</lang>
 
=={{header|PicoLisp}}==
<lang PicoLisp>(in '(curl "-E" "myCert.pem" "https://www.example.com")
(while (line)
(doSomeProcessingWithLine @) ) )</lang>
 
=={{header|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>
 
=={{header|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>
 
=={{header|Ruby}}==
<langsyntaxhighlight Rubylang="ruby">require 'uri'
require 'net/http'
 
Line 261 ⟶ 320:
request = Net::HTTP::Get.new uri
http.request request
end</langsyntaxhighlight>
=={{header|Rust}}==
{{works with|Rust|2021}}
This implementation uses [https://crates.io/crates/reqwest reqwest], the de facto standard high-level HTTP(S) rust library. It is roughly equivalent in purpose and functionality to Python's [https://docs.python-requests.org/en/master/index.html requests].
===Cargo.toml dependencies===
The blocking variant of the reqwest library is used here for simplicity's sake. An asynchronous API is also available.
 
Native (system) TLS libraries are used instead of Rustls, the Rust TLS implementation, because we use a PKCS#12 certificate which at the time of writing does not seem to be available on Rustls. A PKCS#12 certificate is used instead of its PEM equivalent because reading password-protected PEM files [https://docs.rs/reqwest/0.11.6/reqwest/tls/struct.Identity.html#method.from_pem does not seem to be available] either.
<syntaxhighlight lang="toml">reqwest = {version = "0.11", features = ["native-tls", "blocking"]}</syntaxhighlight>
===src/main.rs===
<syntaxhighlight lang="rust">use std::fs::File;
use std::io::Read;
 
use reqwest::blocking::Client;
use reqwest::Identity;
 
fn main() -> std::io::Result<()> {
let identity = {
let mut buf = Vec::new();
 
// Downloaded from https://badssl.com/certs/badssl.com-client.p12
File::open("badssl.com-client.p12")?.read_to_end(&mut buf)?;
 
// Password is badssl.com
Identity::from_pkcs12_der(&buf, "badssl.com").unwrap()
};
 
let client = Client::builder().identity(identity).build().unwrap();
let response = client.get("https://client.badssl.com/").send().unwrap();
 
if !response.status().is_success() {
eprintln!("HTTP error requesting URL: {}", response.status());
}
 
println!("Got response from server: {}", response.text().unwrap());
 
Ok(())
}</syntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import java.io.FileInputStream
import java.net.URL
import java.security.KeyStore
Line 292 ⟶ 388:
new BufferedSource(con.getInputStream).getLines.foreach(println(_))
 
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
Uses the [http://tls.sourceforge.net Tls] package.
<langsyntaxhighlight lang="tcl">package require http
package require tls
 
Line 310 ⟶ 407:
# Now as for conventional use of the “http” package
set data [http::data $token]
http::cleanup $token</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|libcurl}}
An embedded program so we can ask the C host to communicate with libcurl for us.
<syntaxhighlight lang="wren">/* HTTPS_Client-authenticated.wren */
 
var CURLOPT_URL = 10002
var CURLOPT_SSLCERT = 10025
var CURLOPT_SSLKEY = 10087
var CURLOPT_KEYPASSWD = 10258
 
foreign class Curl {
construct easyInit() {}
 
foreign easySetOpt(opt, param)
 
foreign easyPerform()
 
foreign easyCleanup()
}
 
var curl = Curl.easyInit()
if (curl == 0) {
System.print("Error initializing cURL.")
return
}
 
curl.easySetOpt(CURLOPT_URL, "https://example.com/")
curl.easySetOpt(CURLOPT_SSLCERT, "cert.pem")
curl.easySetOpt(CURLOPT_SSLKEY, "key.pem")
curl.easySetOpt(CURLOPT_KEYPASSWD, "s3cret")
 
var status = curl.easyPerform()
if (status != 0) {
System.print("Failed to perform task.")
return
}
curl.easyCleanup()</syntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<syntaxhighlight lang="c">/* gcc HTTPS_Client-authenticated.c -o HTTPS_Client-authenticated -lcurl -lwren -lm */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
void C_curlAllocate(WrenVM* vm) {
CURL** pcurl = (CURL**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(CURL*));
*pcurl = curl_easy_init();
}
 
void C_easyPerform(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
CURLcode cc = curl_easy_perform(curl);
wrenSetSlotDouble(vm, 0, (double)cc);
}
 
void C_easyCleanup(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
curl_easy_cleanup(curl);
}
 
void C_easySetOpt(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
CURLoption opt = (CURLoption)wrenGetSlotDouble(vm, 1);
const char *arg = wrenGetSlotString(vm, 2);
curl_easy_setopt(curl, opt, arg);
}
 
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.allocate = NULL;
methods.finalize = NULL;
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Curl") == 0) {
methods.allocate = C_curlAllocate;
}
}
return methods;
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Curl") == 0) {
if (!isStatic && strcmp(signature, "easySetOpt(_,_)") == 0) return C_easySetOpt;
if (!isStatic && strcmp(signature, "easyPerform()") == 0) return C_easyPerform;
if (!isStatic && strcmp(signature, "easyCleanup()") == 0) return C_easyCleanup;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "HTTPS_Client-authenticated.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
=={{header|zkl}}==
Uses libCurl.
<langsyntaxhighlight 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</langsyntaxhighlight>
 
{{omit from|Batch File|Does not have network access.}}
{{omit from|Brainf***}}
{{omit from|Commodore BASIC|Does not have network access}}
{{omit from|EasyLang|Has no internet functions}}
{{omit from|Inform 7|Does not have network access.}}
{{omit from|Locomotive Basic|Does not have network access.}}
9,476

edits