# Copyright (c) 2023 Yuki Kimoto
# MIT License
class Net::SSLeay::SSL_CTX : pointer {
use Net::SSLeay::Error;
use Net::SSLeay;
use Net::SSLeay::SSL_METHOD;
use Net::SSLeay::X509_STORE;
use Net::SSLeay::X509_NAME;
use Net::SSLeay::X509_VERIFY_PARAM;
use Net::SSLeay::EVP_PKEY;
use Net::SSLeay::EVP_CIPHER_CTX;
use List;
use Net::SSLeay::Callback::TlsextServername;
use Net::SSLeay::Callback::PemPassword;
use Net::SSLeay::Callback::Msg;
use Net::SSLeay::Callback::Verify;
use Net::SSLeay::Callback::AlpnSelect;
use Net::SSLeay::Util;
use Net::SSLeay::X509_STORE_CTX;
use Sync::Mutex;
use StringList;
# Class Variables
our $INSTANCES_H : Hash of Net::SSLeay::SSL_CTX;
our $MUTEX : Sync::Mutex;
INIT {
$INSTANCES_H = Hash->new;
$MUTEX = Sync::Mutex->new;
}
# Fields
has ref_output_for_set_alpn_select_cb : string;
has verify_callback : Net::SSLeay::Callback::Verify;
has verify_callback_arg : object;
has default_passwd_cb : Net::SSLeay::Callback::PemPassword;
has default_passwd_cb_arg : object;
has alpn_select_cb : Net::SSLeay::Callback::AlpnSelect;
has alpn_select_cb_arg : object;
has tlsext_servername_callback : Net::SSLeay::Callback::TlsextServername;
has tlsext_servername_callback_arg : object;
# Class Methods
native static method new : Net::SSLeay::SSL_CTX ($method : Net::SSLeay::SSL_METHOD);
private static method new_with_pointer : Net::SSLeay::SSL_CTX ($pointer : Address, $options : object[] = undef) {
my $self = new Net::SSLeay::SSL_CTX;
Fn->set_pointer($self, $pointer);
return $self;
}
protected method init : void ($options : object[] = undef) {
}
# Instance Methods
native method get_mode : long ();
native method set_mode : long ($mode : long);
native method get0_param : Net::SSLeay::X509_VERIFY_PARAM ();
native method load_verify_locations : int ($CAfile : string, $CApath : string);
native method set_default_verify_paths : int ();
native method set_default_verify_paths_windows : void ();
native method use_certificate_file : int ($file : string, $type : int = -1);
native method use_certificate_chain_file : int ($file : string);
native method use_PrivateKey_file : int ($file : string, $type : int = -1);
native method use_PrivateKey : int ($pkey : Net::SSLeay::EVP_PKEY);
native method set_cipher_list : int ($str : string);
native method set_ciphersuites : int ($str : string);
native method get_cert_store : Net::SSLeay::X509_STORE ();
native method set_options : long ($options : long);
native method get_options : long ();
native method clear_options : long ($options : long);
native method set_alpn_protos : int ($protos : byte[], $protos_len : int = -1);
method set_alpn_protos_with_protocols : int ($protocols : string[]) {
my $protos = Net::SSLeay::Util->convert_to_wire_format($protocols);
my $ret = $self->set_alpn_protos($protos);
return $ret;
}
native method set1_groups_list : int ($list : string);
native method set_post_handshake_auth : void ($val : int);
native method set_min_proto_version : int ($version : int);
native method set_client_CA_list : void ($list : Net::SSLeay::X509_NAME[]);
native method add_client_CA : int ($cacert : Net::SSLeay::X509);
native method add_extra_chain_cert : long ($x509 : Net::SSLeay::X509);
native method set_verify : void ($mode : int, $verify_callback : Net::SSLeay::Callback::Verify = undef, $arg : object = undef);
native method set_default_passwd_cb : void ($cb : Net::SSLeay::Callback::PemPassword, $arg : object = undef);
native method set_alpn_select_cb : void ($cb : Net::SSLeay::Callback::AlpnSelect, $arg : object);
native method set_alpn_select_cb_with_protocols : void ($protocols : string[]);
native method set_tlsext_servername_callback : long ($cb : Net::SSLeay::Callback::TlsextServername, $arg : object = undef);
native method DESTROY : void ();
private static method GET_INSTANCE : Net::SSLeay::SSL_CTX ($address : string) {
Fn->defer(method : void () {
$MUTEX->reader_unlock;
});
$MUTEX->reader_lock;
my $self = (Net::SSLeay::SSL_CTX)$INSTANCES_H->get($address);
return $self;
}
private static method INIT_INSTANCE : void ($address : string, $self : Net::SSLeay::SSL_CTX) {
Fn->defer(method : void () {
$MUTEX->unlock;
});
$MUTEX->lock;
unless ($INSTANCES_H->exists($address)) {
$INSTANCES_H->set($address, $self);
$INSTANCES_H->weaken($address);
}
}
private static method DELETE_INSTANCE : Net::SSLeay::SSL_CTX ($address : string) {
Fn->defer(method : void () {
$MUTEX->unlock;
});
$MUTEX->lock;
my $deleted = (Net::SSLeay::SSL_CTX)$INSTANCES_H->delete($address);
return $deleted;
}
}