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

SPVM::Net::SSLeay - Github

Author

Yuki Kimoto<kimoto.yuki@gmail.com>

Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License