Name

SPVM::IO::Socket::SSL - Sockets for SSL Communication.

Description

IO::Socket::SSL class in SPVM represents sockets for SSL communication.

Usage

use IO::Socket::SSL;

# Client
my $host = "www.google.com";
my $port = 443;
my $socket = IO::Socket::SSL->new({PeerAddr => $host, PeerPort => $port});

my $write_buffer = "GET / HTTP/1.0\r\nHost: $host\r\n\r\n";
$socket->write($write_buffer);

my $read_buffer = (mutable string)new_string_len 100000;
while (1) {
  my $read_length = $socket->read($read_buffer);
  
  if ($read_length < 0) {
    die "Read error";
  }
  
  if ($read_length < length $read_buffer) {
    last;
  }
}

# Server
my $server_socket = IO::Socket::SSL->new({
  Listen => 10,
});
my $accepted_socket = $server_socket->accept;

Super Class

IO::Socket::IP

Fields

ssl_ctx

has ssl_ctx : ro Net::SSLeay::SSL_CTX;

A Net::SSLeay::SSL_CTX object.

ssl

has ssl : ro Net::SSLeay;

A Net::SSLeay object. This object is set after "connect_SSL" method or "accept_SSL" method succeeds.

before_connect_SSL_cbs_list

has before_connect_SSL_cbs_list : ro List of IO::Socket::SSL::Callback::BeforeConnectSSL;

A list of callbacks called before "connect_SSL" method.

before_accept_SSL_cbs_list

has before_accept_SSL_cbs_list : ro List of IO::Socket::SSL::Callback::BeforeAcceptSSL;

A list of callbacks called before "accept_SSL" method.

Constructor Options

The following options are available adding to the options of its super class IO::Socket::IP.

SSL_startHandshake

Type: Int

Default: 1

It this option is a true value, "configure" method calls "connect_SSL" method for a client socket, and "accept" method calls "accept_SSL".

SSL_verify_mode

Type: Int

If "SSL_verify_mode" option is not specified and the instance is a client socket, the option value is set to SSL_VERIFY_PEER.

"configure_SSL" method calls set_verify method given the string specified by "SSL_verify_mode" option, the callback specified by "SSL_verify_callback" option.

SSL_verify_callback

Type: Net::SSLeay::Callback::Verify

See "SSL_verify_mode" option.

SSL_hostname

Type: string

This option only has effect in a client socket.

If the string specified by "SSL_hostname" option is not defined and the string specified by PeerAddr option does not represents an IP address, it is set to the string specified by PeerAddr option.

If the string is a non-empty string, a callback that calls Net::SSLeay#set_tlsext_host_name method just before calling "connect_SSL" is added.

SSL_passwd_cb

Type: Net::SSLeay::Callback::PemPassword

If the callback specified by this option is defined, "configure_SSL" method calls Net::SSLeay::SSL_CTX#set_default_passwd_cb method given the callback.

SSL_ca

Type: Net::SSLeay::X509[]

If the array specified by "SSL_ca" option is defined, the certificates are added to the X509 store by calling Net::SSLeay::X509_STORE#add_cert method repeatedly.

Otherwise if the file name specified by "SSL_ca_file" option or the path name specified by "SSL_ca_path" option is defined, the locations are added by calling Net::SSLeay::SSL_CTX#load_verify_locations method given the file name, the path name.

Otherwise the default CA certificates are set by calling Net::SSLeay::SSL_CTX#set_default_verify_paths or Net::SSLeay::SSL_CTX#set_default_verify_paths_windows in Windows.

SSL_ca_file

Type: string

See "SSL_ca".

SSL_ca_path

Type: string

See "SSL_ca".

SSL_cert

Type: Net::SSLeay::X509[]

If the array specified by "SSL_cert" option is defined, the first element is added as a certificate by calling Net::SSLeay::SSL_CTX#use_certificate method and the rest elements are added as chain certificates using Net::SSLeay::SSL_CTX#add_extra_chain_cert method repeatedly.

Otherwise if the file name specified by "SSL_cert_file" option is defined, a certificate and chain certificates contained in the file are added by calling Net::SSLeay::SSL_CTX#use_certificate_chain_file method.

SSL_cert_file

Type: string

See "SSL_cert"

SSL_key

Type: Net::SSLeay::EVP_PKEY

If the Net::SSLeay::EVP_PKEY object specified by "SSL_key" option is defined, the object is added as a private key by calling Net::SSLeay::SSL_CTX#use_PrivateKey method.

Otherwise if the file name specified by "SSL_key_file" option is defined, the private key contained in the file is added by calling Net::SSLeay::SSL_CTX#use_PrivateKey_file method given the file name, SSL_FILETYPE_PEM.

SSL_key_file

Type: string

See "SSL_key".

SSL_check_crl

Type: Int

The option value is a true value, X509_V_FLAG_CRL_CHECK flag is set by calling Net::SSLeay::X509_VERIFY_PARAM#set_flags method.

SSL_crl_file

Type: string

Adds all CRLs contained in the file specified by this option to the certificate store by calling Net::SSLeay::X509_STORE#add_crl method.

SSL_alpn_protocols

Type: string[]

If the value of SSL_alpn_protocols option is defined, performs the following logic.

In client socket, calls Net::SSLeay::SSL_CTX#set_alpn_protos_with_protocols method given the option value.

In server socket, calls Net::SSLeay::SSL_CTX#set_alpn_select_cb_with_protocols method given the option value.

Class Methods

new

static method new : IO::Socket::SSL ($options : object[] = undef);

Creates a new IO::Socket::SSL object, calls "init" method given the options $options, calls "configure" method, and returns the new object.

See "Constructor Options" about $options.

Note:

If the value of "PeerAddr" option is defined, a client socket is created.

If the value of "Listen" option is a positive value, a server socket is created.

If the socket is a client socket and "PeerAddr" is assumed to be a domain name, the domain name is used for SNI.

If the socket is a client socket, the verify mode is set to SSL_VERIFY_PEER.

If "PeerAddr" is assumed to be a domain name(Nor IPv4(Exactly match IPv4 pattern) and IPv6(Contains :)), the host name verification is enabled by calling X509_VERIFY_PARAM#set1_host method. X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS is added to the host flags.

The socket is set to non-blocking mode, but the goroutine scheduler allows it to be treated as if it were synchronous.

Instance Methods

init

protected method init : void ($options : object[] = undef);

Initialize the instance given the options $options.

See "Constructor Options" about $options.

option_names

protected method option_names : string[] ();

Returns available option names passed to "init" method.

configure

protected method configure : void ();

Congigures the instance by the following logic.

Calls configure method in the super class and calls "configure_SSL" method.

If the value of "SSL_startHandshake" option is a true value and the instance is a client socket, calls "connect_SSL" method.

configure_SSL

protected method configure_SSL : void ();

Creates a new Net::SSLeay::SSL_CTX object, configures the new Net::SSLeay::SSL_CTX using options passed to "init" method, and sets "ssl_ctx" field to the new Net::SSLeay::SSL_CTX object.

connect_SSL

method connect_SSL : void ();

Creates a new Net::SSLeay object, and connects the SSL connection by calling Net::SSLeay#connect method.

If there are callbacks in "before_connect_SSL_cbs_list" field, these callbacks are performed given the instance, the new Net::SSLeay object before calling Net::SSLeay#connect method.

If an IO wait occurs, the program jumps to the goroutine scheduler, and retries this operation until it succeeds or the timeout seconds set by Timeout field expires.

Exceptions:

Exceptions thrown by Net::SSLeay#connect method could be thrown.

If timeout occurs, an exception is thrown with eval_error_id set to the basic type ID of Go::Error::IOTimeout.

accept_SSL

method accept_SSL : void ();

Creates a new Net::SSLeay object, and accepts the SSL connection by calling Net::SSLeay#accept method.

If there are callbacks in "before_accept_SSL_cbs_list" field, these callbacks are performed given the instance, the new Net::SSLeay object before calling Net::SSLeay#accept method.

If an IO wait occurs, the program jumps to the goroutine scheduler, and retries this operation until it succeeds or the timeout seconds set by Timeout field expires.

Exceptions:

Exceptions thrown by Net::SSLeay#accept method could be thrown.

If timeout occurs, an exception is thrown with eval_error_id set to the basic type ID of Go::Error::IOTimeout.

accept

method accept : IO::Socket::SSL ($peer_ref : Sys::Socket::Sockaddr[] = undef);

Creates a new IO::Socket::SSL object by calling accept method in the super class.

And sets the "ssl_ctx" field in the new object to the value of "ssl_ctx" field in the instance.

And if the value of "SSL_startHandshake" option is a true value, calls "accept_SSL" method.

And returns the new object.

read

method read : int ($buffer : mutable string, $length : int = -1, $offset : int = 0);

Reads the buffer $buffer at offset $offset to the length $length from the socket by calling Net::SSLeay#read method.

If an IO wait occurs, the program jumps to the goroutine scheduler, and retries this operation until it succeeds or the timeout seconds set by Timeout field expires.

Exceptions:

Exceptions thrown by Net::SSLeay#read method could be thrown.

If timeout occurs, an exception is thrown with eval_error_id set to the basic type ID of Go::Error::IOTimeout.

write

method write : int ($buffer : string, $length : int = -1, $offset : int = 0);

Writes the buffer $buffer at offset $offset to the length $length to the socket by calling Net::SSLeay#write method.

If an IO wait occurs, the program jumps to the goroutine scheduler, and retries this operation until it succeeds or the timeout seconds set by Timeout field expires.

Exceptions:

Exceptions thrown by Net::SSLeay#write method could be thrown.

If timeout occurs, an exception is thrown with eval_error_id set to the basic type ID of Go::Error::IOTimeout.

shutdown_SSL

method shutdown_SSL : int ();

Shutdowns the SSL connection by calling Net::SSLeay#shutdown method.

If an IO wait occurs, the program jumps to the goroutine scheduler, and retries this operation until it succeeds or the timeout seconds set by Timeout field expires.

Exceptions:

Exceptions thrown by Net::SSLeay#shutdown method could be thrown.

If timeout occurs, an exception is thrown with eval_error_id set to the basic type ID of Go::Error::IOTimeout.

alpn_selected

method alpn_selected : string ();

Calls Net::SSLeay#get0_alpn_selected_return_string method and returns its return value.

get_sslversion

method get_sslversion : string ();

Calls Net::SSLeay#get_version method given the value of "ssl" field, and returns its return value.

Exceptions:

If the version number is unknown, an exception is thrown.

get_sslversion_int

method get_sslversion_int : int ();

Calls Net::SSLeay#version method given the value of "ssl" field, and returns its return value.

get_cipher

method get_cipher : string ();

Calls Net::SSLeay#get_cipher method given the value of "ssl" field, and returns its return value.

Exceptions:

Exceptions thrown by Net::SSLeay#get_cipher method could be thrown.

get_servername

method get_servername : string ();

Calls Net::SSLeay#get_servername method given the value of "ssl" field, the value of TLSEXT_NAMETYPE_host_name, and returns its return value.

Exceptions:

Exceptions thrown by Net::SSLeay#get_servername method could be thrown.

peer_certificate

method peer_certificate : Net::SSLeay::X509 ();

Calls Net::SSLeay#get_peer_certificate method given the value of "ssl" field, and returns its return value.

Exceptions:

Exceptions thrown by Net::SSLeay#get1_peer_certificate method could be thrown.

peer_certificates

method peer_certificates : Net::SSLeay::X509[];

Returns the array that contains a certificate and all chain certificates of the peer.

If a certificate cannot be got, return an empty array.

sock_certificate

method sock_certificate : Net::SSLeay::X509 ();

Calls Net::SSLeay#get_certificate method given the value of "ssl" field, and returns its return value.

Exceptions:

Exceptions thrown by Net::SSLeay#get_certificate method could be thrown.

add_before_connect_SSL_cb

method add_before_connect_SSL_cb : void ($cb : IO::Socket::SSL::Callback::BeforeConnectSSL);

Adds the callback $cb to the end of the elements of "before_connect_SSL_cb_list" field.

add_before_accept_SSL_cb

method add_before_accept_SSL_cb : void ($cb : IO::Socket::SSL::Callback::BeforeAcceptSSL);

Adds the callback $cb to the end of the elements of "before_accept_SSL_cb_list" field.

dump_peer_certificate

method dump_peer_certificate : string ();

Calls Net::SSLeay#dump_peer_certificate method given the value of "ssl" field, and returns its return value.

Exceptions:

Exceptions thrown by Net::SSLeay#dump_peer_certificate method could be thrown.

stat

method stat : Sys::IO::Stat ();

This method is not supported in IO::Socket::SSL.

Exceptions:

An exception is thrown.

send

method send : int ($buffer : string, $flags : int = 0, $length : int = -1, $offset : int = 0);

This method is not supported in IO::Socket::SSL.

Exceptions:

An exception is thrown.

sendto

method sendto : int ($buffer : string, $flags : int, $to : Sys::Socket::Sockaddr, $length : int = -1, $offset : int = 0);

This method is not supported in IO::Socket::SSL.

Exceptions:

An exception is thrown.

recv

method recv : int ($buffer : mutable string, $length : int = -1, $flags : int = 0, $offset : int = 0);

This method is not supported in IO::Socket::SSL.

Exceptions:

An exception is thrown.

recvfrom

method recvfrom : int ($buffer : mutable string, $length : int, $flags : int, $from_ref : Sys::Socket::Sockaddr[], $offset : int = 0);

This method is not supported in IO::Socket::SSL.

Exceptions:

An exception is thrown.

DESTROY

method DESTROY : void ();

Shutdowns the SSL connection and closes the socket.

Implementation:

If the socket is opened, performs the following logic.

If the SSL connection is established, calls "shutdown_SSL" method.

And closes the socket.

FAQ

How to customize Net::SSLeay::SSL_CTX object?

Sets "SSL_startHandshake" option to 0, gets a Net::SSLeay::SSL_CTX object by "ssl_ctx" getter, customizes it, and calls "connect_SSL" method in a client or calls "accept_SSL" method.

Client:

use Net::SSLeay::Constant as SSL;

my $host = "www.google.com";
my $port = 443;
my $socket = IO::Socket::SSL->new({PeerAddr => $host, PeerPort => $port, SSL_startHandshake => 0});

my $ssl_ctx = $socket->ssl_ctx;

$ssl_ctx->set_min_proto_version(SSL->TLS1_1_VERSION);

$socket->connect_SSL;

my $ssl = $socket->ssl;

Server:

use Net::SSLeay::Constant as SSL;

my $host = "www.google.com";
my $port = 443;
my $socket = IO::Socket::SSL->new({Listen => 1, SSL_startHandshake => 0});

my $ssl_ctx = $socket->ssl_ctx;

$ssl_ctx->set_min_proto_version(SSL->TLS1_1_VERSION);

my $accepted_socket = $socket->accept;

$accepted_socket->accept_SSL;

How to create Net::SSLeay::X509 objects for SSL_ca option from the return value of Mozilla::CA#SSL_ca method?

use Mozilla::CA;
use Net::SSLeay::BIO;
use Net::SSLeay::PEM;
use List;

my $ca_content = Mozilla::CA->SSL_ca;

my $bio = Net::SSLeay::BIO->new;

$bio->write($ca_content);

my $cas_list = List->new(new Net::SSLeay::X509[0]);
while (1) {
  my $ca = (Net::SSLeay::X509)undef;
  
  eval { $ca = Net::SSLeay::PEM->read_bio_X509($bio); }
  
  if ($@) {
    if (eval_error_id isa_error Net::SSLeay::Error::PEM_R_NO_START_LINE) {
      last;
    }
    else {
      die $@;
    }
  }
  
  $cas_list->push($ca);
}

my $cas = (Net::SSLeay::X509[])$cas_list->to_array;

my $SSL_ca = $cas;

See Also

Repository

SPVM::IO::Socket::SSL - Github

Author

Yuki Kimoto kimoto.yuki@gmail.com

Copyright & License

Copyright (c) 2024 Yuki Kimoto

MIT License