forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
102
Kha/Tools/macos/std/eval/_std/sys/ssl/Certificate.hx
Normal file
102
Kha/Tools/macos/std/eval/_std/sys/ssl/Certificate.hx
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C)2005-2019 Haxe Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package sys.ssl;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import sys.ssl.Mbedtls;
|
||||
import mbedtls.X509Crt;
|
||||
|
||||
@:coreApi
|
||||
class Certificate {
|
||||
var native:X509Crt;
|
||||
|
||||
function new(native:X509Crt) {
|
||||
this.native = native;
|
||||
}
|
||||
|
||||
public static function loadFile(file:String):Certificate {
|
||||
var cert = new X509Crt();
|
||||
cert.parse_file(file);
|
||||
return new Certificate(cert);
|
||||
}
|
||||
|
||||
public static function loadPath(path:String):Certificate {
|
||||
var cert = new X509Crt();
|
||||
cert.parse_path(path);
|
||||
return new Certificate(cert);
|
||||
}
|
||||
|
||||
public static function fromString(str:String):Certificate {
|
||||
var cert = new X509Crt();
|
||||
trace(mbedtls.Error.strerror(cert.parse(Bytes.ofString(str))));
|
||||
return new Certificate(cert);
|
||||
}
|
||||
|
||||
public static function loadDefaults():Certificate {
|
||||
var cert = new X509Crt();
|
||||
Mbedtls.loadDefaultCertificates(cert);
|
||||
return new Certificate(cert);
|
||||
}
|
||||
|
||||
public var commonName(get, null):Null<String>;
|
||||
|
||||
public var altNames(get, null):Array<String>;
|
||||
|
||||
public var notBefore(get, null):Date;
|
||||
|
||||
public var notAfter(get, null):Date;
|
||||
|
||||
extern public function subject(field:String):Null<String>;
|
||||
|
||||
extern public function issuer(field:String):Null<String>;
|
||||
|
||||
public function next():Null<Certificate> {
|
||||
var cert = native.next();
|
||||
if (cert == null) {
|
||||
return null;
|
||||
}
|
||||
return new Certificate(cert);
|
||||
}
|
||||
|
||||
public function add(pem:String):Void {
|
||||
native.parse(Bytes.ofString(pem));
|
||||
}
|
||||
|
||||
public function addDER(der:Bytes):Void {
|
||||
native.parse(der);
|
||||
}
|
||||
|
||||
private function get_commonName():Null<String> {
|
||||
return subject("CN");
|
||||
}
|
||||
|
||||
extern private function get_altNames():Array<String>;
|
||||
|
||||
extern private function get_notBefore():Date;
|
||||
|
||||
extern private function get_notAfter():Date;
|
||||
|
||||
private inline function getNative():X509Crt {
|
||||
return native;
|
||||
}
|
||||
}
|
69
Kha/Tools/macos/std/eval/_std/sys/ssl/Key.hx
Normal file
69
Kha/Tools/macos/std/eval/_std/sys/ssl/Key.hx
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C)2005-2019 Haxe Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package sys.ssl;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import mbedtls.PkContext;
|
||||
|
||||
@:coreApi
|
||||
class Key {
|
||||
var native:PkContext;
|
||||
|
||||
function new() {
|
||||
native = new PkContext();
|
||||
}
|
||||
|
||||
static public function loadFile(file:String, ?isPublic:Bool, ?pass:String):Key {
|
||||
var key = new Key();
|
||||
var code = if (isPublic) {
|
||||
key.native.parse_public_keyfile(file);
|
||||
} else {
|
||||
key.native.parse_keyfile(file, pass);
|
||||
}
|
||||
if (code != 0) {
|
||||
throw(mbedtls.Error.strerror(code));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
static function parse(data:Bytes, isPublic:Bool, ?pass:String):Key {
|
||||
var key = new Key();
|
||||
var code = if (isPublic) {
|
||||
key.native.parse_public_key(data);
|
||||
} else {
|
||||
key.native.parse_key(data);
|
||||
}
|
||||
if (code != 0) {
|
||||
throw(mbedtls.Error.strerror(code));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
static public function readPEM(data:String, isPublic:Bool, ?pass:String):Key {
|
||||
return parse(Bytes.ofString(data), isPublic, pass);
|
||||
}
|
||||
|
||||
static public function readDER(data:haxe.io.Bytes, isPublic:Bool):Key {
|
||||
return parse(data, isPublic);
|
||||
}
|
||||
}
|
66
Kha/Tools/macos/std/eval/_std/sys/ssl/Mbedtls.hx
Normal file
66
Kha/Tools/macos/std/eval/_std/sys/ssl/Mbedtls.hx
Normal file
@ -0,0 +1,66 @@
|
||||
package sys.ssl;
|
||||
|
||||
import eval.vm.NativeSocket;
|
||||
import mbedtls.Ssl;
|
||||
import mbedtls.Entropy;
|
||||
import mbedtls.CtrDrbg;
|
||||
import mbedtls.X509Crt;
|
||||
|
||||
class Mbedtls {
|
||||
static var entropy:Null<Entropy>;
|
||||
static var ctr:Null<CtrDrbg>;
|
||||
|
||||
static public function getDefaultEntropy() {
|
||||
if (entropy == null) {
|
||||
entropy = new Entropy();
|
||||
}
|
||||
return entropy;
|
||||
}
|
||||
|
||||
static public function getDefaultCtrDrbg() {
|
||||
if (ctr == null) {
|
||||
ctr = new CtrDrbg();
|
||||
ctr.seed(getDefaultEntropy());
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
static public function loadDefaultCertificates(certificate:X509Crt) {
|
||||
if (loadDefaults(certificate) == 0) {
|
||||
return;
|
||||
}
|
||||
var defPaths = switch (Sys.systemName()) {
|
||||
case "Linux":
|
||||
[
|
||||
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
|
||||
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
|
||||
"/etc/ssl/ca-bundle.pem", // OpenSUSE
|
||||
"/etc/pki/tls/cacert.pem", // OpenELEC
|
||||
"/etc/ssl/certs", // SLES10/SLES11
|
||||
"/system/etc/security/cacerts" // Android
|
||||
];
|
||||
case "BSD":
|
||||
[
|
||||
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
|
||||
"/etc/ssl/cert.pem", // OpenBSD
|
||||
"/etc/openssl/certs/ca-certificates.crt", // NetBSD
|
||||
];
|
||||
case "Android":
|
||||
["/system/etc/security/cacerts"];
|
||||
default:
|
||||
[];
|
||||
}
|
||||
for (path in defPaths) {
|
||||
if (sys.FileSystem.exists(path)) {
|
||||
if (sys.FileSystem.isDirectory(path))
|
||||
certificate.parse_path(path);
|
||||
else
|
||||
certificate.parse_file(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern static public function setSocket(ssl:Ssl, socket:NativeSocket):Int;
|
||||
|
||||
extern static function loadDefaults(certificate:X509Crt):Int;
|
||||
}
|
206
Kha/Tools/macos/std/eval/_std/sys/ssl/Socket.hx
Normal file
206
Kha/Tools/macos/std/eval/_std/sys/ssl/Socket.hx
Normal file
@ -0,0 +1,206 @@
|
||||
package sys.ssl;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import eval.vm.NativeSocket;
|
||||
import mbedtls.Config;
|
||||
import mbedtls.Ssl;
|
||||
|
||||
private class SocketInput extends haxe.io.Input {
|
||||
@:allow(sys.ssl.Socket) private var socket:Socket;
|
||||
var readBuf:Bytes;
|
||||
|
||||
public function new(s:Socket) {
|
||||
this.socket = s;
|
||||
readBuf = Bytes.alloc(1);
|
||||
}
|
||||
|
||||
public override function readByte() {
|
||||
socket.handshake();
|
||||
var r = @:privateAccess socket.ssl.read(readBuf, 0, 1);
|
||||
if (r == -1)
|
||||
throw haxe.io.Error.Blocked;
|
||||
else if (r < 0)
|
||||
throw new haxe.io.Eof();
|
||||
return readBuf.get(0);
|
||||
}
|
||||
|
||||
public override function readBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
|
||||
if (pos < 0 || len < 0 || ((pos + len) : UInt) > (buf.length : UInt))
|
||||
throw haxe.io.Error.OutsideBounds;
|
||||
socket.handshake();
|
||||
var r = @:privateAccess socket.ssl.read(buf, pos, len);
|
||||
if (r == -1)
|
||||
throw haxe.io.Error.Blocked;
|
||||
else if (r <= 0)
|
||||
throw new haxe.io.Eof();
|
||||
return r;
|
||||
}
|
||||
|
||||
public override function close() {
|
||||
super.close();
|
||||
if (socket != null)
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
private class SocketOutput extends haxe.io.Output {
|
||||
@:allow(sys.ssl.Socket) private var socket:Socket;
|
||||
var writeBuf:Bytes;
|
||||
|
||||
public function new(s:Socket) {
|
||||
this.socket = s;
|
||||
writeBuf = Bytes.alloc(1);
|
||||
}
|
||||
|
||||
public override function writeByte(c:Int) {
|
||||
socket.handshake();
|
||||
writeBuf.set(0, c);
|
||||
var r = @:privateAccess socket.ssl.write(writeBuf, 0, 1);
|
||||
if (r == -1)
|
||||
throw haxe.io.Error.Blocked;
|
||||
else if (r < 0)
|
||||
throw new haxe.io.Eof();
|
||||
}
|
||||
|
||||
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
|
||||
if (pos < 0 || len < 0 || ((pos + len) : UInt) > (buf.length : UInt))
|
||||
throw haxe.io.Error.OutsideBounds;
|
||||
socket.handshake();
|
||||
var r = @:privateAccess socket.ssl.write(buf, pos, len);
|
||||
if (r == -1)
|
||||
throw haxe.io.Error.Blocked;
|
||||
else if (r < 0)
|
||||
throw new haxe.io.Eof();
|
||||
return r;
|
||||
}
|
||||
|
||||
public override function close() {
|
||||
super.close();
|
||||
if (socket != null)
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@:coreApi
|
||||
class Socket extends sys.net.Socket {
|
||||
public static var DEFAULT_VERIFY_CERT:Null<Bool> = true;
|
||||
|
||||
public static var DEFAULT_CA:Null<Certificate>;
|
||||
|
||||
private var conf:Config;
|
||||
private var ssl:Ssl;
|
||||
|
||||
public var verifyCert:Null<Bool>;
|
||||
|
||||
private var caCert:Null<Certificate>;
|
||||
private var hostname:String;
|
||||
|
||||
private var handshakeDone:Bool;
|
||||
private var isBlocking:Bool = true;
|
||||
|
||||
override function init(socket:NativeSocket):Void {
|
||||
this.socket = socket;
|
||||
input = new SocketInput(this);
|
||||
output = new SocketOutput(this);
|
||||
if (DEFAULT_VERIFY_CERT && DEFAULT_CA == null) {
|
||||
DEFAULT_CA = Certificate.loadDefaults();
|
||||
}
|
||||
verifyCert = DEFAULT_VERIFY_CERT;
|
||||
caCert = DEFAULT_CA;
|
||||
}
|
||||
|
||||
public override function connect(host:sys.net.Host, port:Int):Void {
|
||||
conf = buildConfig(false);
|
||||
ssl = new Ssl();
|
||||
ssl.setup(conf);
|
||||
Mbedtls.setSocket(ssl, socket);
|
||||
handshakeDone = false;
|
||||
if (hostname == null)
|
||||
hostname = host.host;
|
||||
if (hostname != null)
|
||||
ssl.set_hostname(hostname);
|
||||
socket.connect(host.ip, port);
|
||||
if (isBlocking)
|
||||
handshake();
|
||||
}
|
||||
|
||||
public function handshake():Void {
|
||||
if (!handshakeDone) {
|
||||
var r = ssl.handshake();
|
||||
if (r == 0)
|
||||
handshakeDone = true;
|
||||
else if (r == -1)
|
||||
throw haxe.io.Error.Blocked;
|
||||
else
|
||||
throw mbedtls.Error.strerror(r);
|
||||
}
|
||||
}
|
||||
|
||||
override function setBlocking(b:Bool):Void {
|
||||
super.setBlocking(b);
|
||||
isBlocking = b;
|
||||
}
|
||||
|
||||
public function setCA(cert:Certificate):Void {
|
||||
caCert = cert;
|
||||
}
|
||||
|
||||
public function setHostname(name:String):Void {
|
||||
hostname = name;
|
||||
}
|
||||
|
||||
public override function close():Void {
|
||||
super.close();
|
||||
var input:SocketInput = cast input;
|
||||
var output:SocketOutput = cast output;
|
||||
@:privateAccess input.socket = output.socket = null;
|
||||
input.close();
|
||||
output.close();
|
||||
}
|
||||
|
||||
public override function bind(host:sys.net.Host, port:Int):Void {
|
||||
conf = buildConfig(true);
|
||||
|
||||
socket.bind(host.ip, port);
|
||||
}
|
||||
|
||||
public override function accept():Socket {
|
||||
var c = socket.accept();
|
||||
var cssl = new Ssl();
|
||||
cssl.setup(conf);
|
||||
Mbedtls.setSocket(cssl, c);
|
||||
|
||||
var s = Type.createEmptyInstance(sys.ssl.Socket);
|
||||
s.socket = c;
|
||||
s.ssl = cssl;
|
||||
s.input = new SocketInput(s);
|
||||
s.output = new SocketOutput(s);
|
||||
s.handshakeDone = false;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public function addSNICertificate(cbServernameMatch:String->Bool, cert:Certificate, key:Key):Void {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public function peerCertificate():Certificate {
|
||||
return @:privateAccess new Certificate(ssl.get_peer_cert());
|
||||
}
|
||||
|
||||
public function setCertificate(cert:Certificate, key:Key):Void {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
private function buildConfig(server:Bool):Config {
|
||||
var conf = new Config();
|
||||
conf.defaults(server ? SSL_IS_SERVER : SSL_IS_CLIENT, SSL_TRANSPORT_STREAM, SSL_PRESET_DEFAULT);
|
||||
conf.rng(Mbedtls.getDefaultCtrDrbg());
|
||||
|
||||
if (caCert != null) {
|
||||
conf.ca_chain(@:privateAccess caCert.getNative());
|
||||
}
|
||||
conf.authmode(if (verifyCert) SSL_VERIFY_REQUIRED else if (verifyCert == null) SSL_VERIFY_OPTIONAL else SSL_VERIFY_NONE);
|
||||
return conf;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user