Name
SPVM::Net::SSLeay - OpenSSL Binding to SPVM
Description
Net::SSLeay class in SPVM is a OpenSSL binding to SPVM.
This class itself represents SSL data structure in OpenSSL.
Usage
use Net::SSLeay;
use Net::SSLeay::Net::SSLeay::SSL_METHOD;
use Net::SSLeay::Net::SSLeay::SSL_CTX;
use Net::SSLeay::Constant as SSL;
my $ssl_method = Net::SSLeay::SSL_METHOD->TLS_method;
my $ssl_ctx = Net::SSLeay::SSL_CTX->new($ssl_method);
$ssl_ctx->set_verify(SSL->SSL_VERIFY_PEER);
my $ssl = Net::SSLeay->new($ssl_ctx);
my $socket_fd = ...; # Get a socket file descriptor in some way.
$ssl->set_fd($socket_fd);
$ssl->connect;
$ssl->write("foo");
my $buffer = (mutable string)new_string_len 100;
$ssl->read($buffer);
$ssl->shutdown;
See also the source codes of IO::Socket::SSL class to gets more examples.
Modules
Details
Requirement
OpenSSL 1.1.1
Porting
This class is a Perl's Net::SSLeay porting to SPVM.
Callback Hack
OpenSSL uses a number of callback functions.
These callbacks cannot receive a Net::SSLeay object.
So we use the following callback hack to get a Net::SSLeay object.
Initialization:
A thread variable thread_env
is set to the current runtime environment.
When a new native SSL
object and a new Net::SSLeay object are created at once, the new Net::SSLeay object is stored in a global Hash object keyed by the hex string of the address of the native SSL
object.
Getting a Net::SSLeay Object:
The callback gets a native SSL object from the information in the arguments. And the callback gets the Net::SSLeay object from the global Hash object using the hex string of the address of the native SSL
object.
Cleanup:
The key-value pair is removed by "DESTROY" method in Net::SSLeay class.
Note:
Access to the global Hash object is locked by a Sync::Mutex object, so the access is thread-safe.
This callback hack is also used in Net::SSLeay::SSL_CTX class. In this case, native SSL
object in the document is replaced with native SSL_CTX
object. And Net::SSLeay object in the document is replaced with Net::SSLeay::SSL_CTX object.
Config Builder
The classes binding to OpenSSL data structures are configured by SPVM::Net::SSLeay::ConfigBuilder class.
Fields
operation_error
has operation_error : ro int;
The place where the return value of SSL_get_error function is stored.
msg_callback
has msg_callback : ro Net::SSLeay::Callback::Msg;
A callback set by "set_msg_callback" method.
Class Methods
new
static method new : Net::SSLeay ($ssl_ctx : Net::SSLeay::SSL_CTX);
Creates a new Net::SSLeay object, calls native SSL_new function given the pointer value of $ssl_ctx, sets the pointer value of the new object to the return value of the native function.
And calls "init" method.
And returns the new Net::SSLeay object.
Exceptions:
If SSL_new failed, an exception is thrown with eval_error_id
set to the basic type ID of Net::SSLeay::Error class.
alert_desc_string_long
static method alert_desc_string_long : string ($value : int);
Calls native SSL_alert_desc_string_long function given $value, and returns a new string created by its return value.
load_client_CA_file
static method load_client_CA_file : Net::SSLeay::X509_NAME[] ($file : string);
Calls native SSL_load_client_CA_file function given $file.
And creates a new Net::SSLeay::X509_NAME array,
And performs the following loop: copies the element at index $i of the return value(STACK_OF(X509_NAME)
) of the native function using native X509_NAME_dup, creates a new Net::SSLeay::X509_NAME object, sets the pointer value of the new object to the native copied value, and puses the new object to the new array.
And returns the new array;
Exceptions:
The file $file must be defined. Otherwise an exception is thrown.
If SSL_load_client_CA_file failed, an exception is thrown with eval_error_id
set to the basic type ID of Net::SSLeay::Error class.
select_next_proto
static method select_next_proto : int ($out_ref : string[], $outlen_ref : byte*, $server : string, $server_len : int, $client : string, $client_len : int);
Calls native SSL_select_next_proto function given the address of a native temporary variable out_ref
, $outlen_ref, $server, $server_len, $client, $client_len.
If a native string is returned in *out_ref
, creates a new string from *out_ref
and $$outlen_ref
, sets $out_ref->[0]
to the new string.
And returns the return value of the native function.
Exceptions:
The output reference $out_ref must be 1-length array. Otherwise an exception is thrown.
$server must be defined. Otherwise an exception is thrown.
$client must be defined. Otherwise an exception is thrown.
Instance Methods
init
protected method init : void ($options : object[] = undef);
Initializes the instance given the options $options.
Performes Initialization process described in Callback Hack.
version
native method version : int ();
Calls native SSL_version function, and returns its return value.
get_version
method get_version : string ();
Calls native SSL_get_version function, and returns the string created by its return value.
get_mode
method get_mode : long ();
Calls native SSL_get_mode function given the pointer value of the instance, and returns its return value.
set_mode
method set_mode : long ($mode : long);
Calls native SSL_set_mode function given the pointer value of the instance, $mode, and returns its return value.
clear_mode
method clear_mode : long ($mode : long);
Calls native SSL_clear_mode function given the pointer value of the instance, $mode, and returns its return value.
set_tlsext_host_name
method set_tlsext_host_name : int ($name : string);
Calls native SSL_set_tlsext_host_name function given the pointer value of the instance, the host name $name, and returns its return value.
Exceptions:
The host name $name must be defined. Otherwise an exception is thrown.
If SSL_set_tlsext_host_name failed, an exception is thrown with eval_error_id
set to the basic type ID of Net::SSLeay::Error class.
get_servername
method get_servername : string ($type : int);
Calls native SSL_get_servername function given the pointer value of the instance, $type.
If its return value is NULL, returns undef.
Otherwise returns the new string created from its return value.
get_SSL_CTX
method get_SSL_CTX : Net::SSLeay::SSL_CTX ();
Calls native SSL_get_SSL_CTX function given the pointer value of the instance, creates a new Net::SSLeay::SSL_CTX object, calls native SSL_CTX_up_ref function on the return value of the native function, sets the pointer value of the new object to the return value of the native function, and returns the new object.
set_SSL_CTX
method set_SSL_CTX : void ($ssl_ctx : Net::SSLeay::SSL_CTX);
If the pointer value of $ssl_ctx is the same as the return value(named current_ssl_ctx
) of native SSL_get_SSL_CTX given the pointer value of instance, does nothing.
Otherwise calls SSL_CTX_up_ref given current_ssl_ctx
, calls native SSL_set_SSL_CTX(currently not documented) function given the pointer value of the instance, the pointer value of $ssl_ctx.
If SSL_set_SSL_CTX failed, calls native SSL_CTX_free function on current_ssl_ctx
.
Note:
Native SSL_set_SSL_CTX function allows $ssl_ctx to be NULL, but currently "set_SSL_CTX" method does not allow undef because SSL_set_SSL_CTX is undocumented and I'm not sure how it handles reference count.
Native SSL_set_SSL_CTX function returns a native SSL
object, but currently the return type of "set_SSL_CTX" method SSL_set_SSL_CTX is undocumented and I'm not sure how it handles reference count.
Exceptions:
The SSL_CTX object $ssl_ctx must be defined. Otherwise an exception is thrown.
If SSL_set_SSL_CTX failed, an exception is thrown with eval_error_id
set to the basic type ID of Net::SSLeay::Error class.
set_fd
method set_fd : int ($fd : int);
Calls native SSL_set_fd function given the pointer value of the instance, $fd, and returns its return value.
Exceptions:
If SSL_set_fd failed, an exception is thrown with eval_error_id
set to the basic type ID of Net::SSLeay::Error class.
connect
method connect : int ();
Calls native ERR_clear_error function.
And calls native SSL_connect function given the pointer value of the instance.
If SSL_connect failed, "operation_error" field is set to the return vlaue(named ssl_operation_error
) of SSL_get_error function given the return value of the native SSL_connect function.
And returns the return value of the native SSL_connect function.
Exceptions:
If SSL_connect failed, an exception is thrown with eval_error_id
set to the folowing value according to the error.
ssl_operation_error
is SSL_ERROR_WANT_READ
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_READ.
ssl_operation_error
is SSL_ERROR_WANT_WRITE
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_WRITE.
ssl_operation_error
is any other value, eval_error_id
is set to the basic type ID of Net::SSLeay::Error.
accept
method accept : int ();
Calls native ERR_clear_error function.
And calls native SSL_accept function given the pointer value of the instance.
If SSL_accept failed, "operation_error" field is set to the return vlaue(named ssl_operation_error
) of SSL_get_error function given the return value of the native SSL_accept function.
And returns the return value of the native SSL_accept function.
Exceptions:
If SSL_accept failed, an exception is thrown with eval_error_id
set to the folowing value according to the error.
ssl_operation_error
is SSL_ERROR_WANT_READ
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_READ.
ssl_operation_error
is SSL_ERROR_WANT_WRITE
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_WRITE.
ssl_operation_error
is any other value, eval_error_id
is set to the basic type ID of Net::SSLeay::Error.
read
method read : int ($buf : mutable string, $num : int = -1, $offset : int = 0);
Calls native ERR_clear_error function.
And calls native SSL_read function given the pointer value of the instance, $buf at the offest $offset, $num.
If SSL_read failed, "operation_error" field is set to the return vlaue(named ssl_operation_error
) of SSL_get_error function given the return value of the native SSL_read function.
And returns the return value of the native SSL_read function.
Exceptions:
The buffer $buf must be defined. Otherwise an exception is thrown.
The offset $offset must be greater than or equal to 0. Otherwise an exception is thrown.
The offset $offset + $num must be lower than or equal to the length of the buffer $buf. Otherwise an exception is thrown.
If SSL_read failed, an exception is thrown with eval_error_id
set to the folowing value according to the error.
ssl_operation_error
is SSL_ERROR_WANT_READ
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_READ.
ssl_operation_error
is SSL_ERROR_WANT_WRITE
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_WRITE.
ssl_operation_error
is any other value, eval_error_id
is set to the basic type ID of Net::SSLeay::Error.
write
method write : int ($buf : string, $num : int = -1, $offset : int = 0);
Calls native ERR_clear_error function.
And calls native SSL_write function given the pointer value of the instance, $buf at the offest $offset, $num.
If SSL_write failed, "operation_error" field is set to the return vlaue(named ssl_operation_error
) of SSL_get_error function given the return value of the native SSL_write function.
And returns the return value of the native SSL_write function.
Exceptions:
The buffer $buf must be defined. Otherwise an exception is thrown.
The offset $offset must be greater than or equal to 0. Otherwise an exception is thrown.
The offset $offset + $num must be lower than or equal to the length of the buffer $buf. Otherwise an exception is thrown.
If SSL_write failed, an exception is thrown with eval_error_id
set to the folowing value according to the error.
ssl_operation_error
is SSL_ERROR_WANT_READ
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_READ.
ssl_operation_error
is SSL_ERROR_WANT_WRITE
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_WRITE.
ssl_operation_error
is any other value, eval_error_id
is set to the basic type ID of Net::SSLeay::Error.
shutdown
method shutdown : int ();
Calls native ERR_clear_error function.
And calls native SSL_shutdown function given the pointer value of the instance.
If SSL_shutdown failed, "operation_error" field is set to the return vlaue(named ssl_operation_error
) of SSL_get_error function given the return value of the native SSL_shutdown function.
And returns the return value of the native SSL_shutdown function.
Exceptions:
If SSL_shutdown failed, an exception is thrown with eval_error_id
set to the folowing value according to the error.
ssl_operation_error
is SSL_ERROR_WANT_READ
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_READ.
ssl_operation_error
is SSL_ERROR_WANT_WRITE
, eval_error_id
is set to the basic type ID of Net::SSLeay::Error::SSL_ERROR_WANT_WRITE.
ssl_operation_error
is any other value, eval_error_id
is set to the basic type ID of Net::SSLeay::Error.
get_shutdown
method get_shutdown : int ();
Calls native SSL_get_shutdown function, and returns its return value.
get_cipher
method get_cipher : string ();
Calls native SSL_get_cipher function, and returns the string created from its return value.
get_certificate
method get_certificate : Net::SSLeay::X509 ();
Calls native SSL_get_certificate function.
If the return value of the native function is NULL, returns undef.
Otherwise, creates a new Net::SSLeay::X509 object, sets the pointer value of the new object to the return value of the native function, calls native X509_up_ref function on the return value of the native function, and returns the new object.
get_peer_certificate
method get_peer_certificate : Net::SSLeay::X509 ();
Calls native SSL_get_peer_certificate function.
If the return value of the native function is NULL, returns undef.
Otherwise, creates a new Net::SSLeay::X509 object, sets the pointer value of the new object to the return value of the native function, and returns the new object.
get_peer_cert_chain
method get_peer_cert_chain : Net::SSLeay::X509[] ();
Calls native SSL_get_peer_cert_chain function.
If its return value is NULL, returns undef.
Otherwise creates a new Net::SSLeay::X509 array,
And performs the following loop: creates a new Net::SSLeay::X509 object, calls native X509_up_ref function on the element at index $i of the return value(STACK_OF(X509)
) of the native function, and puses the new object to the new array.
And returns the new array.
get0_alpn_selected
method get0_alpn_selected : void ($data_ref : string[], $len_ref : int*);
Calls native SSL_get0_alpn_selected function given the pointer value of the instance, the address of a native temporary variable data_ref
, $len_ref.
If a native string is returned in *data_ref
, creates a new string from *data_ref
and $$len_ref
, sets $data_ref->[0]
to the new string.
Exceptions:
The data reference $data_ref must be 1-length array. Otherwise an exception is thrown.
get0_alpn_selected_return_string
method get0_alpn_selected_return_string : string ()
Calls "get0_alpn_selected" method given appropriate arguments, and returns $data_ref->[0]
.
dump_peer_certificate
static method dump_peer_certificate : string ();
Returns the same value of the return value of Perl's Net::SSLeay#dump_peer_certificate function.
Exceptions:
The return value of get_peer_certificate method must be defined. Otherwise an exception is thrown.
set_msg_callback
method set_msg_callback : void ($cb : Net::SSLeay::Callback::Msg);
If the callback $cb is defined, A native variable native_cb
is set to a function pointer of the native callback funcion described below, otherwise native_cb
is set to NULL.
And calls native SSL_set_msg_callback function given the pointer value of the instance, native_cb
.
And sets "msg_callback" field to $cb.
Native Callback Funcion:
The native callback function is defined by the following native code:
static void SPVM__Net__SSLeay__my__msg_callback(int write_p, int version, int content_type, const void* buf, size_t len, SSL* ssl, void* native_arg) {
int32_t error_id = 0;
SPVM_ENV* env = thread_env;
SPVM_VALUE* stack = env->new_stack(env);
int32_t scope_id = env->enter_scope(env, stack);
char* tmp_buffer = env->get_stack_tmp_buffer(env, stack);
snprintf(tmp_buffer, SPVM_NATIVE_C_STACK_TMP_BUFFER_SIZE, "%p", ssl);
stack[0].oval = env->new_string(env, stack, tmp_buffer, strlen(tmp_buffer));
env->call_class_method_by_name(env, stack, "Net::SSLeay", "GET_INSTANCE", 1, &error_id, __func__, FILE_NAME, __LINE__);
if (error_id) {
env->print_exception_to_stderr(env, stack);
goto END_OF_FUNC;
}
void* obj_self = stack[0].oval;
assert(obj_self);
void* obj_cb = env->get_field_object_by_name(env, stack, obj_self, "msg_callback", &error_id, __func__, FILE_NAME, __LINE__);
if (error_id) {
env->print_exception_to_stderr(env, stack);
goto END_OF_FUNC;
}
void* obj_buf = env->new_string(env, stack, buf, len);
stack[0].oval = obj_cb;
stack[1].ival = write_p;
stack[2].ival = version;
stack[3].ival = content_type;
stack[4].oval = obj_buf;
stack[5].ival = len;
stack[6].oval = obj_self;
env->call_instance_method_by_name(env, stack, "", 7, &error_id, __func__, FILE_NAME, __LINE__);
if (error_id) {
env->print_exception_to_stderr(env, stack);
goto END_OF_FUNC;
}
int32_t ret = stack[0].ival;
END_OF_FUNC:
env->leave_scope(env, stack, scope_id);
env->free_stack(env, stack);
return;
}
DESTROY
method DESTROY : void ();
Performes Cleanup process described in Callback Hack.
And calls native SSL_free function given the pointer value of the instance unless no_free
flag of the instance is a true value.
FAQ
Is LibreSSL supported?
Yes.
See Also
Repository
Author
Yuki Kimoto<kimoto.yuki@gmail.com>
Copyright & License
Copyright (c) 2023 Yuki Kimoto
MIT License