| Crypt-NSS documentation | Contained in the Crypt-NSS distribution. |
Net::NSS::SSL - SSL sockets using NSS
The prefered way of creating sockets is by using the new constructor. This creates this socket,
sets the desired options, imports it into SSL layer and connects to the peer host, or binds and sets up
a listening socket, in the correct order. If you need more control it's possible to create a new socket
using create_socket which in turn must be SSL enabled by calling import_into_ssl_layer before
connecting or listening.
Creates a new socket, sets it up correctly, imports it into NSS SSL layer and optionally if it's a client-side socket connect to the remote host.
The peer to connect to in form of <host>, <host:<port>> or <host:<service>> where host is either an IP number or a hostname, port
a integer in the range 1-65535. If a service is specified such as http or ftp, its port number is looked up using getservbyname with
the proto tcp.
The numerical port or a service name to connect to. If PeerAddr is specified it may take precedence over this.
The host to connect to as either an IP number or a hostname. If PeerAddr is specified is may take precedence over this.
If true then create the socket, import it into SSL, set the specfied options but don't connect. Defaults to false if omitted.
Periodically test whether connection is still alive. Default to false if omitted.
Blocking or non-blocking I/O. Default to 1 if omitted or what the class method blocking returns if such exists.
Sets the PKCS11 pin arg that is sent along to various funcions for the socket.
See also: set_pkcs11_pin_arg in Net::NSS::SSL
Sets the client certificte hook for the socket. If ommited defaults $DefaultClientCertHook if one is defined.
See also: set_client_certificate_hook in Net::NSS::SSL.
Sets the client certificate hook argument for the socket. If ommited defaults to $DefaultClientCertHookArg if defined.
Sets the hook that is called to verify the certificate. If ommited defaults to $DefaultVerifyCertHook if one is defined.
See also: set_verify_certificate_hook in Net::NSS::SSL.
A list of options to enable where the items are either numeric or a constant name from Crypt::NSS::SSL::Constants.
A list of options to enable where the items are either numeric or a constant name from Crypt::NSS::SSL::Constants.
Sets the host/URL that the server certificate will be verified against. If ommited defaults to $DefaultURL if defined, otherwise uses PeerHost.
Creates a new socket of the TYPE tcp or udp. Does not set any socket options nor imports it into
the SSL layer. You probablly want to use new instead of this method.
Imports the socket into NSS SSL layer if not already done. The constructor new does this automatically for
you.
This is done for you if you use new.
Conencts to the host, $host, on the given $port. The optional argument $timeout sets how many seconds
connect has to complete the connection setup. If ommited PR_INTERVAL_NO_TIMEOUT is used.
You don't need to bind and listen if you use new to create your socket.
Binds an the socket to a network address, ie host + port.
Listens for connections on the socket. The optional argument $queue_length is the maximum length of the queue of pending connections. Defaults to 10.
Configures a listening socket with the information needed to handshake as a SSL server.
Accepts a connection on the socket and returns the new socket used to communicate with the connected client. The
optional argument $timeout specified determined how long the connection setup might take. If ommited PR_INTERVAL_NO_TIMEOUT is used.
This method blocks the calling thread until either a new connection is successfully accepted or an error occurs.
Tells the the SSL library to start over with the handshake at the next I/O operation. This is not necessary for sockets that are already SSL:ed. The argument $as_server tells whether the socket should handshake as server or client.
Gets and sets socket options. The following options are valid:
Periodically test whether connection is still alive.
Disable Nagle algorithm. Don't delay send to coalesce packets.
Do blocking or non-blocking (network) I/O.
This method also works with SSL options if passed a numeric argument as exported by Crypt::NSS::Constants qw(:ssl) and
passing either SSL_OPTION_ENABLED or SSL_OPTION_DISABLED as the value.
Sets or gets the argument that is passed along to pkcs11 callbacks for the given socket. $arg can be any Perl scalar but in most cases you'll just want this to be a string.
The default password callback (set_password_hook in Crypt::NSS::PKCS11), returns this value.
Set or get the domain name of the host we connect to (or actually what the CN in the servers certificate says). This is used in handshaking and if not matching the handshake will fail.
Sets a custom hook to verify an incoming certificate. The hook is passed the Net::NSS::SSL-object that the
hook is registered on, a boolean indicating whether signature should be checked and a boolean indicating if
the certificate should be verified as a server (if true) or as a client (if false). The hook can obtain the
certificate to be verified by calling peer_certificate on the passed Net::NSS::SSL-object.
To indicate that verification was ok the hook must return SEC_SUCCESS, or SEC_FAILURE if not. Both constants
are exported by requesting the tag :sec from Crypt::NSS::Constants.
If not set, NSS uses a default hook that does the right thing in most cases. If you've replaced this with
your own reverting to the built-in can be done by passing undef to this method.
Example:
sub my_verify_certificate_hook {
my ($self, $check_signature, $is_server) = @_;
my $cert = $self->peer_certificate():
return SEC_SUCCESS;
}
If you pass built-in-ignore as the name we use a hook that never verifies the cert.
Sets a custom hook that is called when certficate authentication (the callback specified above) fails.
Sets a custom hook that is called when a server requests a certificate for authentication. The hook is passed
the Net::NSS::SSL-object that is the subject of the authentication request and an array reference containing
the names of the CAs the server accepts and optionally the nickname (or data) specified. The hook must return
a 2-element list containing: 1) A Crypt::NSS::Certificate-object representing the authentication certificate
and 2) a Crypt::NSS::PrivateKey-object representing the certificates private key.
By default no hook is set and one must be provided if your client application is to support client authentication.
NSS provides a built-in hook that should be sufficient in most cases - if $arg is set to a string it uses that
as a nickname find the right cert and key otherwise it scans the database for a match. To use the built-in hook
pass "built-in" as the hook argument.
If you're using new to construct the socket you can declare your callback using the key ClientAuthHook.
Returns the certificate recived from the remote end of the connection. If we're a client that means we get the servers certificate and if we're the server we get the clients authentication certificate (if used).
Returns the length (in bits) of the key used in the session.
Returns the length (in bits) of the secret part in the key used in the session. Also known as effective key size.
Returns the distinguished name of issuer for the certificate on the other side. Returns no certificate if no certificate is used.
Returns the name of the cipher used in the session.
Returns the distinguished name of the certificate on the other side.
Returns the number of bytes of undecrypted data available for read. This might not be the same amount when read.
Returns the host of the remote side.
Returns the port on the remote side.
Returns the host on the local side.
Returns the port on the local side.
Returns true if the socket is connected to a peer or false if it's not.
Returns true if the sockets has been imported into the SSL layer or false if it has not.
Reads data the scalar passed as $target 8192 bytes at the time or $length. Returns the actual number of bytes read or 0 if we've reached EOF.
If $offset is specified the data will not be placed at the beginning of $target but at the specified offset.
This method is blocking.
Writes the contents of $data to the socket and returns the number of bytes actually written.
Closes the socket.
Removes the SSL session from the cache. Communication can continue on the current socket but no new connections can resume the SSL session.
| Crypt-NSS documentation | Contained in the Crypt-NSS distribution. |
package Net::NSS::SSL; use strict; use warnings; use Carp qw(croak); use Socket; use Crypt::NSS::Constants qw(:ssl); use Net::NSS::SSL::LWPCompat; my %socket_type = ( tcp => SOCK_STREAM, udp => SOCK_DGRAM, icmp => SOCK_RAW, ); # What client cert hook to use if not specified our $DefaultClientCertHook; # What argument to send to the client cert hook if not specified our $DefaultClientCertHookArg; # What URL to set on the socket that the verification should be against if not specified. our $DefaultURL; # The callback to use for verifing certs our $DefaultVerifyCertHook; sub new { my $pkg = shift; my %args = @_ & 1 ? do { my $addr = shift; (@_, PeerAddr => $addr); } : @_; my $proto = "tcp"; my $type = defined $args{Type} ? $args{Type} : SOCK_STREAM; # Convert (Peer|Local)Addr to ${1}Host + ${1}Port unless specified and convert named port for my $pre (qw(Peer Local)) { if ($args{"${pre}Addr"}) { ($args{"${pre}Port"}) = $args{"${pre}Addr"} =~ /:(\w+)$/ if !defined $args{"${pre}Port"}; $args{"${pre}Host"} = $args{"${pre}Addr"}; $args{"${pre}Host"} =~ s/:.*$//; } # Non-numerical port, look up from /etc/services or equivalent if (exists $args{"${pre}Port"} && $args{"${pre}Port"} !~ /^\d+$/) { my @serv = getservbyname($args{"${pre}Port"}, "tcp"); croak "Can't get port for protocol '", $args{"${pre}Port"}, "'" unless @serv; $args{"${pre}Port"} = $serv[2]; } } # Blocking is a bit special. We should consult a callback for this unless it's specified if (!exists $args{Blocking} && $pkg->can("blocking")) { $args{Blocking} = $pkg->blocking; } $args{Blocking} = 1 unless defined $args{Blocking}; # Always create tcp sockets right now my $sock = Net::NSS::SSL->create_socket("tcp"); $sock->set_option(Blocking => $args{Blocking}); # Optional options for my $option (qw(KeepAlive ReuseAddr)) { next unless exists $args{$option} && defined $args{$option}; $sock->set_option($option, ($args{$option} ? 1 : 0)); } # Upgrade to SSL socket $sock->import_into_ssl_layer(); if (!exists $args{SSL_PKCS11_PinArg}) { $sock->set_pkcs11_pin_arg($Crypt::NSS::PKCS11::DefaultPinArg); } # Client certificates, only for client sockets if ($args{PeerHost} && $args{PeerPort}) { my @client_cert_arg = exists $args{SSL_ClientCertHookArg} ? $args{SSL_ClientCertHookArg} : defined $DefaultClientCertHookArg ? $DefaultClientCertHookArg : (); if (!exists $args{SSL_ClientCertHook}) { if ($DefaultClientCertHook) { $sock->set_client_certificate_hook($DefaultClientCertHook, @client_cert_arg); } } else { $sock->set_client_certificate_hook($args{SSL_ClientCertHook}, @client_cert_arg); } } # Verification callback if ($args{SSL_VerifyCertHook}) { $sock->set_verify_certificate_hook($args{SSL_VerifyCertHook}); } elsif ($DefaultVerifyCertHook) { $sock->set_verify_certificate_hook($DefaultVerifyCertHook); } # SSL Options my @options; push @options, map { [$_ => SSL_OPTION_ENABLED] } @{$args{SSL_EnableOptions}} if ref $args{SSL_EnableOptions} eq "ARRAY"; push @options, map { [$_ => SSL_OPTION_DISABLED] } @{$args{SSL_DisableOptions}} if ref $args{SSL_DisableOptions} eq "ARRAY"; for my $opt (@options) { my ($opt_name, $on) = @$opt; eval { $opt_name = Crypt::NSS::Constants->$opt_name(); }; croak "Unkown option '$opt_name'" if $@; $sock->set_option($opt_name, $on); } # Maybe connect if ($args{PeerHost} && $args{PeerPort} && !(exists $args{Connect} && !$args{Connect})) { if ($args{SSL_URL}) { $sock->set_URL($args{SSL_URL}); } elsif ($DefaultURL) { $sock->set_URL($DefaultURL); } else { $sock->set_URL($args{PeerHost}); } $sock->connect($args{PeerHost}, $args{PeerPort}, ($args{Timeout} ? $args{Timeout} : ())); } return $sock; } sub peerhost { my ($host, undef) = shift->_peeraddr; return $host; } sub peerport { my (undef, $port) = shift->_peeraddr; return $port; } sub sockhost { my ($host, undef) = shift->_sockaddr; return $host; } sub sockport { my (undef, $port) = shift->_sockaddr; return $port; } # Alias needed for LWP among other things *get_peer_certificate = \&peer_certificate; *get_cipher = \&cipher; *get_keysize = \&keysize; *get_secret_keysize = \&secret_keysize; *get_issuer = \&issuer; *get_cipher = \&cipher; *syswrite = \&write; *sysread = \&read; 1; __END__