Net::SSLeay(3)

๐Ÿ’– Net::SSLeay(3) โ€” bestie, we're doing crypto bindings ๐Ÿ’–

Okay so this is Net::SSLeay(3), from the User Contributed Perl Documentation, and it's literally your guide to Perl bindings for OpenSSL and LibreSSL. It's giving โ€œbig library, big API, big main-character energy.โ€ ๐Ÿงšโœจ

๐ŸŒธ NAME ๐ŸŒธ

Net::SSLeay โ€” Perl bindings for OpenSSL and LibreSSL. Periodt. ๐Ÿ’…

โœจ SYNOPSIS โœจ

No cap, here's the whole vibe in code:

use Net::SSLeay qw(get_https post_https sslcat make_headers make_form);

($page) = get_https('www.bacus.pt', 443, '/');                 # Case 1

($page, $response, %reply_headers)
    = get_https('www.bacus.pt', 443, '/',                      # Case 2
        make_headers(User-Agent => 'Cryptozilla/5.0b1',
                     Referer    => 'https://www.bacus.pt')
      );

($page, $result, %headers)                                     # Case 2b
    = get_https('www.bacus.pt', 443, '/protected.html',
        make_headers(Authorization =>
            'Basic ' . MIME::Base64::encode("$user:$pass",''))
      );

($page, $response, %reply_headers)
    = post_https('www.bacus.pt', 443, '/foo.cgi', '',          # Case 3
        make_form(OK => '1', name => 'Sampo')
      );

$reply = sslcat($host, $port, $request);                       # Case 4

($reply, $err, $server_cert) = sslcat($host, $port, $request); # Case 5

$Net::SSLeay::trace = 2; # 0=no debugging, 1=ciphers, 2=trace, 3=dump data

Net::SSLeay::initialize(); # Initialize ssl library once

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

This module provides Perl bindings for libssl (an SSL/TLS API) and libcrypto (a cryptography API). That's the whole summary, bestie: one side is the SSL/TLS stuff, the other side is the crypto stuff. ๐Ÿซถ

๐Ÿ”ฅ COMPATIBILITY ๐Ÿ”ฅ

Net::SSLeay supports these libssl implementations:

  • Any stable release of OpenSSL (https://www.openssl.org) in the 0.9.8 - 3.2 branches, except for OpenSSL 0.9.8 - 0.9.8b.
  • Any stable release of LibreSSL (https://www.libressl.org) in the 2.0 - 3.8 series, except for LibreSSL 3.2.2 and 3.2.3.
Heads up: Net::SSLeay may not function as expected with releases other than the ones listed above, because of libssl API incompatibilities, or โ€” in the case of LibreSSL โ€” because of deviations from the libssl API. ๐Ÿ’€

Net::SSLeay is only as secure as the underlying libssl implementation you use. Even though it maintains compatibility with old versions of OpenSSL and LibreSSL, it is strongly recommended that you use a version of OpenSSL or LibreSSL that is supported by the OpenSSL/LibreSSL developers and/or your operating system vendor. Many unsupported versions of OpenSSL and LibreSSL are known to contain severe security vulnerabilities. Refer to the OpenSSL Release Strategy (https://www.openssl.org/policies/releasestrat.html) and LibreSSL Support Schedule (https://www.libressl.org/releases.html) for information on which versions are currently supported. ๐Ÿšจ

The libssl API has changed significantly since OpenSSL 0.9.8: hundreds of functions have been added, deprecated or removed in the intervening versions. Although this documentation lists all of the functions and constants that Net::SSLeay may expose, they will not be available for use if they are missing from the underlying libssl implementation. Refer to the compatibility notes in this documentation, as well as the OpenSSL/LibreSSL manual pages, for information on which OpenSSL/LibreSSL versions support each function or constant. At run-time, you can check whether a function or constant is exposed before calling it using the following convention:

if ( defined &Net::SSLeay::libssl_function ) {
    # libssl_function() (or SSL_libssl_function()) is available
    Net::SSLeay::libssl_function(...);
}

๐ŸŒˆ OVERVIEW ๐ŸŒˆ

The Net::SSLeay module basically comprises of:

  • High level functions for accessing web servers (by using HTTP/HTTPS)
  • Low level API (mostly mapped 1:1 to openssl's C functions)
  • Convenience functions (related to low level API but with more perl friendly interface)

There is also a related module called Net::SSLeay::Handle included in this distribution that you might want to use instead. It has its own pod documentation. ๐ŸŽ€

๐Ÿฆ‹ High level functions for accessing web servers ๐Ÿฆ‹

This module offers some high level convenience functions for accessing web pages on SSL servers (for symmetry, the same API is offered for accessing http servers, too), an sslcat() function for writing your own clients, and finally access to the SSL api of the SSLeay/OpenSSL package so you can write servers or clients for more complicated applications. Lowkey iconic. ๐Ÿ‘‘

For high level functions it is most convenient to import them into your main namespace as indicated in the synopsis.

๐ŸŒธ Basic set of functions ๐ŸŒธ

  • get_https
  • post_https
  • put_https
  • head_https
  • do_https
  • sslcat
  • https_cat
  • make_form
  • make_headers

Case 1 (in SYNOPSIS) demonstrates the typical invocation of get_https() to fetch an HTML page from secure server. The first argument provides the hostname or IP in dotted decimal notation of the remote server to contact. The second argument is the TCP port at the remote end (your own port is picked arbitrarily from high numbered ports as usual for TCP). The third argument is the URL of the page without the host name part. If in doubt consult the HTTP specifications at https://www.w3c.org.

Case 2 (in SYNOPSIS) demonstrates full fledged use of get_https(). As can be seen, get_https() parses the response and response headers and returns them as a list, which can be captured in a hash for later reference. Also a fourth argument to get_https() is used to insert some additional headers in the request. make_headers() is a function that will convert a list or hash to such headers. By default get_https() supplies "Host" (to make virtual hosting easy) and "Accept" (reportedly needed by IIS) headers.

Case 2b (in SYNOPSIS) demonstrates how to get a password protected page. Refer to the HTTP protocol specifications for further details (e.g. RFC-2617).

Case 3 (in SYNOPSIS) invokes post_https() to submit a HTML/CGI form to a secure server. The first four arguments are equal to get_https() (note that the empty string ('') is passed as header argument). The fifth argument is the contents of the form formatted according to CGI specification. Do not post UTF-8 data as content: use utf8::downgrade first. In this case the helper function make_https() is used to do the formatting, but you could pass any string. post_https() automatically adds "Content-Type" and "Content-Length" headers to the request.

Case 4 (in SYNOPSIS) shows the fundamental sslcat() function (inspired in spirit by the "netcat" utility :-). It's your swiss army knife that allows you to easily contact servers, send some data, and then get the response. You are responsible for formatting the data and parsing the response โ€” sslcat() is just a transport.

Case 5 (in SYNOPSIS) is a full invocation of sslcat() which allows the return of errors as well as the server (peer) certificate.

The $trace global variable can be used to control the verbosity of the high level functions. Level 0 guarantees silence, level 1 (the default) only emits error messages.

๐ŸŽ€ Alternate versions of high-level API ๐ŸŽ€

  • get_https3
  • post_https3
  • put_https3
  • get_https4
  • post_https4
  • put_https4

The above mentioned functions actually return the response headers as a list, which only gets converted to hash upon assignment (this assignment loses information if the same header occurs twice, as may be the case with cookies). There are also other variants of the functions that return unprocessed headers and that return a reference to a hash.

($page, $response, @headers) = get_https('www.bacus.pt', 443, '/');
for ($i = 0; $i < $#headers; $i+=2) {
    print "$headers[$i] = " . $headers[$i+1] . "\n";
}

($page, $response, $headers, $server_cert)
    = get_https3('www.bacus.pt', 443, '/');
print "$headers\n";

($page, $response, $headers_ref)
    = get_https4('www.bacus.pt', 443, '/');
for $k (sort keys %{$headers_ref}) {
    for $v (@{$$headers_ref{$k}}) {
        print "$k = $v\n";
    }
}

All of the above code fragments accomplish the same thing: display all values of all headers. The API functions ending in "3" return the headers simply as a scalar string and it is up to the application to split them up. The functions ending in "4" return a reference to a hash of arrays (see perlref and perllol if you are not familiar with complex perl data structures). To access a single value of such a header hash you would do something like

print $$headers_ref{COOKIE}[0];

Variants 3 and 4 also allow you to discover the server certificate in case you would like to store or display it, e.g.

($p, $resp, $hdrs, $server_cert) = get_https3('www.bacus.pt', 443, '/');
if (!defined($server_cert) || ($server_cert == 0)) {
    warn "Subject Name: undefined, Issuer  Name: undefined";
} else {
    warn sprintf('Subject Name: %s Issuer  Name: %s',
        Net::SSLeay::X509_NAME_oneline(
            Net::SSLeay::X509_get_subject_name($server_cert)),
        Net::SSLeay::X509_NAME_oneline(
            Net::SSLeay::X509_get_issuer_name($server_cert))
    );
}
Beware: this method only allows after the fact verification of the certificate. By the time get_https3() has returned, the https request has already been sent to the server, whether you decide to trust it or not. To do the verification correctly you must either employ the OpenSSL certificate verification framework or use the lower level API to first connect and verify the certificate and only then send the http data. See the implementation of ds_https3() for guidance on how to do this. ๐Ÿ˜ญ

๐Ÿ’œ Using client certificates ๐Ÿ’œ

Secure web communications are encrypted using symmetric crypto keys exchanged using encryption based on the certificate of the server. Therefore in all SSL connections the server must have a certificate. This serves both to authenticate the server to the clients and to perform the key exchange.

Sometimes it is necessary to authenticate the client as well. Two options are available: HTTP basic authentication and a client side certificate. The basic authentication over HTTPS is actually quite safe because HTTPS guarantees that the password will not travel in the clear. Never-the-less, problems like easily guessable passwords remain. The client certificate method involves authentication of the client at the SSL level using a certificate. For this to work, both the client and the server have certificates (which typically are different) and private keys. ๐Ÿ”โœจ

The API functions we just met can also take extra arguments so you can hand over the client side certificate and key files ๐Ÿ’–. Format-wise they're the exact same as server certs, and that whole caveat about encrypting your private keys? Yeah, still applies, no exceptions, bestie.

    ($page, $result, %headers)                                     # 2c
        = get_https('www.bacus.pt', 443, '/protected.html',
            make_headers(Authorization =>
                'Basic ' . MIME::Base64::encode("$user:$pass",'')),
            '', $mime_type6, $path_to_crt7, $path_to_key8
          );

    ($page, $response, %reply_headers)
        = post_https('www.bacus.pt', 443, '/foo.cgi',              # 3b
            make_headers('Authorization' =>
                'Basic ' . MIME::Base64::encode("$user:$pass",'')),
            make_form(OK   => '1', name => 'Sampo'),
            $mime_type6, $path_to_crt7, $path_to_key8
          );

So Case 2c (over in SYNOPSIS) is literally the moment where you grab a password-protected page that also wants a client certificate โ€” meaning yes, you can absolutely run both authentication methods at the same time, they coexist, it's giving teamwork ๐ŸŒˆ.

And Case 3b (also in SYNOPSIS) is a full-on blown POST to a secure server that demands password auth and a client certificate, same energy as case 2c. Full package deal, no notes ๐Ÿ‘‘

Note: the client will NOT send a certificate unless the server actually requests one. This is typically achieved by setting the verify mode to "VERIFY_PEER" on the server:
    Net::SSLeay::set_verify($ssl, Net::SSLeay::VERIFY_PEER, 0);

Want the whole story? perldoc ~openssl/doc/ssl/SSL_CTX_set_verify.pod has a full description, go read it, it's iconic ๐Ÿ“–โœจ


๐Ÿงš Working through a web proxy ๐Ÿงš

  • set_proxy

"Net::SSLeay" can absolutely use a web proxy for its connections, bestie. You just gotta set the proxy host and port first with set_proxy() and then carry on like nothing happened with the normal API functions, like:

    Net::SSLeay::set_proxy('gateway.myorg.com', 8080);
    ($page) = get_https('www.bacus.pt', 443, '/');

Proxy wants a login too? Say less, you can supply a username and password as well ๐Ÿ™ˆ

    Net::SSLeay::set_proxy('gateway.myorg.com', 8080, 'joe', 'salainen');
    ($page, $result, %headers)
        = get_https('www.bacus.pt', 443, '/protected.html',
            make_headers(Authorization =>
                'Basic ' . MIME::Base64::encode("susie:pass",''))
          );

Look at that beauty: we authenticate to the proxy as "joe" and to the final web server as "susie" โ€” two identities, one request, main character energy fr fr. Just know that proxy authentication requires the "MIME::Base64" module to work. Don't forget it ๐Ÿ’…


๐ŸŒธ HTTP (without S) API ๐ŸŒธ

  • get_http
  • post_http
  • tcpcat
  • get_httpx
  • post_httpx
  • tcpxcat

Over the years it became very clear that using the light-weight flavour API of "Net::SSLeay" for regular old HTTP would be super convenient too (if you're into the heavy-weight object-oriented approach, see "LWP"). Honestly it'd be nice to just flip https on and off on the fly, right? So regular HTTP support got evolved. Slay ๐Ÿฆ‹

    use Net::SSLeay qw(get_http post_http tcpcat
                       get_httpx post_httpx tcpxcat
                       make_headers make_form);

    ($page, $result, %headers)
        = get_http('www.bacus.pt', 443, '/protected.html',
            make_headers(Authorization =>
                'Basic ' . MIME::Base64::encode("$user:$pass",''))
          );

    ($page, $response, %reply_headers)
        = post_http('www.bacus.pt', 443, '/foo.cgi', '',
            make_form(OK => '1', name => 'Sampo')
          );

    ($reply, $err) = tcpcat($host, $port, $request);

    ($page, $result, %headers)
        = get_httpx($usessl, 'www.bacus.pt', 443, '/protected.html',
            make_headers(Authorization =>
                'Basic ' . MIME::Base64::encode("$user:$pass",''))
          );

    ($page, $response, %reply_headers)
        = post_httpx($usessl, 'www.bacus.pt', 443, '/foo.cgi', '',
            make_form(OK => '1',  name => 'Sampo')
          );

    ($reply, $err, $server_cert) = tcpxcat($usessl, $host, $port, $request);

See the pattern? The "x" family of APIs takes as its first argument a flag that says whether SSL is used or not. On/off, literally that simple โœจ


๐Ÿ”ฅ Certificate verification and Certificate Revocation Lists (CRLs) ๐Ÿ”ฅ

Okay so OpenSSL supports verifying peer certificates โ€” iconic. It can also optionally check that peer certificate against a Certificate Revocation List (CRL) from the certificate's issuer ๐Ÿ‘€. A CRL is a file, created by the certificate issuer, that lists all the certificates it previously signed but has now revoked. CRLs are in PEM format. Periodt.

You can enable "Net::SSLeay CRL" checking like this:

    &Net::SSLeay::X509_STORE_set_flags(
        &Net::SSLeay::CTX_get_cert_store($ssl),
        &Net::SSLeay::X509_V_FLAG_CRL_CHECK
    );

Once you've set that flag, if OpenSSL checks a peer's certificate it'll try to find a CRL for the issuer. How? By looking for a specially named file in the search directory specified by CTX_load_verify_locations. CRL files are named with the hash of the issuer's subject name, followed by .r0, .r1 etc. โ€” for example "ab1331b2.r0", "ab1331b2.r1". It reads all the .r files for that issuer, then checks for a revocation of the peer certificate across all of them. (You can also force it to look in a specific named CRL file โ€” see below ๐Ÿ‘‡)

Wanna know the hash of the issuer subject name in a CRL? Easy:

    openssl crl -in crl.pem -hash -noout

If the peer certificate does not pass the revocation list, or if no CRL is found at all, then the handshaking fails with an error. Yeah. It just dies on you ๐Ÿ˜ญ

You can also force OpenSSL to look for CRLs in one or more arbitrarily named files:

    my $bio = Net::SSLeay::BIO_new_file($crlfilename, 'r');
    my $crl = Net::SSLeay::PEM_read_bio_X509_CRL($bio);
    if ($crl) {
        Net::SSLeay::X509_STORE_add_crl(
               Net::SSLeay::CTX_get_cert_store($ssl, $crl)
        );
    } else {
        # error reading CRL....
    }

Usually the URLs where you can download the CRLs are contained in the certificate itself, and you can extract them with:

    my @url = Net::SSLeay::P_X509_get_crl_distribution_points($cert);

BUT โ€” and this is the important part, bestie โ€” there's no automatic downloading of the CRLs. And honestly those CRLs are often way too huge to just download them to verify a single certificate ๐Ÿซ . Also they're often in DER format, which you need to convert to PEM before you can even use it:

    openssl crl -in crl.der -inform der -out crl.pem

So as an alternative for faster and more timely revocation checks, you're way better off using the Online Status Revocation Protocol (OCSP). Foreshadowing ๐ŸŽ€


๐Ÿ’œ Certificate verification and Online Status Revocation Protocol (OCSP) ๐Ÿ’œ

So, checking for revoked certificates is possible and fast with Certificate Revocation Lists, but you need to download the complete โ€” and often huge โ€” list before you can verify a single certificate. Not it ๐Ÿ˜ญ

A faster way is to ask the CA to check the revocation of just a single certificate or a few of them, using OCSP. Basically: for each certificate you generate an OCSP_CERTID based on the certificate itself and its issuer, put those ids together into an OCSP_REQUEST, and send the request to the URL given in the certificate. Clean, targeted, efficient ๐Ÿ’…

As a result you get back an OCSP_RESPONSE, and then you need to check the status of the response, check that it's valid (e.g. signed by the CA), and finally extract the info about each OCSP_CERTID to find out if the certificate is still valid or got revoked. Three steps, no skipping.

With Net::SSLeay this can be done like this โ€” buckle up, it's a long one but every line matters:

    # get id(s) for given certs, like from get_peer_certificate
    # or get_peer_cert_chain. This will croak if
    # - one tries to make an OCSP_CERTID for a self-signed certificate
    # - the issuer of the certificate cannot be found in the SSL objects
    #   store, nor in the current certificate chain
    my $cert = Net::SSLeay::get_peer_certificate($ssl);
    my $id = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) };
    die "failed to make OCSP_CERTID: $@" if $@;

    # create OCSP_REQUEST from id(s)
    # Multiple can be put into the same request, if the same OCSP responder
    # is responsible for them.
    my $req = Net::SSLeay::OCSP_ids2req($id);

    # determine URI of OCSP responder
    my $uri = Net::SSLeay::P_X509_get_ocsp_uri($cert);

    # Send stringified OCSP_REQUEST with POST to $uri.
    # We can ignore certificate verification for https, because the OCSP
    # response itself is signed.
    my $ua = HTTP::Tiny->new(verify_SSL => 0);
    my $res = $ua->request( 'POST',$uri, {
        headers => { 'Content-type' => 'application/ocsp-request' },
        content => Net::SSLeay::i2d_OCSP_REQUEST($req)
    });
    my $content = $res && $res->{success} && $res->{content}
        or die "query failed";

    # Extract OCSP_RESPONSE.
    # this will croak if the string is not an OCSP_RESPONSE
    my $resp = eval { Net::SSLeay::d2i_OCSP_RESPONSE($content) };

    # Check status of response.
    my $status = Net::SSLeay::OCSP_response_status($resp);
    if ($status != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) {
        die "OCSP response failed: " .
            Net::SSLeay::OCSP_response_status_str($status);
    }

    # Verify signature of response and if nonce matches request.
    # This will croak if there is a nonce in the response, but it does not match
    # the request. It will return false if the signature could not be verified,
    # in which case details can be retrieved with Net::SSLeay::ERR_get_error.
    # It will not complain if the response does not contain a nonce, which is
    # usually the case with pre-signed responses.
    if ( ! eval { Net::SSLeay::OCSP_response_verify($ssl,$resp,$req) }) {
        die "OCSP response verification failed";
    }

    # Extract information from OCSP_RESPONSE for each of the ids.

    # If called in scalar context it will return the time (as time_t), when the
    # next update is due (minimum of all successful responses inside $resp). It
    # will croak on the following problems:
    # - response is expired or not yet valid
    # - no response for given OCSP_CERTID
    # - certificate status is not good (e.g. revoked or unknown)
    if ( my $nextupd = eval { Net::SSLeay::OCSP_response_results($resp,$id) }) {
        warn "certificate is valid, next update in " .
            ($nextupd-time()) . " seconds\n";
    } else {
        die "certificate is not valid: $@";
    }

No cap, that whole block is the vibe check for "is this cert still alive" and it does not miss ๐Ÿ”ฅ

# But in array context it will return detailed information about each given
# OCSP_CERTID instead croaking on errors:
# if no @ids are given it will return information about all single responses
# in the OCSP_RESPONSE
my @results = Net::SSLeay::OCSP_response_results($resp,@ids);
for my $r (@results) {
    print Dumper($r);
    # @results are in the same order as the @ids and contain:
    # $r->[0] - OCSP_CERTID
    # $r->[1] - undef if no error (certificate good) OR error message as string
    # $r->[2] - hash with details:
    #   thisUpdate - time_t of this single response
    #   nextUpdate - time_t when update is expected
    #   statusType - integer:
    #      V_OCSP_CERTSTATUS_GOOD(0)
    #      V_OCSP_CERTSTATUS_REVOKED(1)
    #      V_OCSP_CERTSTATUS_UNKNOWN(2)
    #   revocationTime - time_t (only if revoked)
    #   revocationReason - integer (only if revoked)
    #   revocationReason_str - reason as string (only if revoked)
}

Okay so if you wanna make revocation checking go even faster ๐Ÿ”ฅ, there's a TLS extension that literally lets you tell the server "bestie, staple that OCSP response on for me" โ€” it's giving efficiency, it's giving main character energy:

# set TLS extension before doing SSL_connect
Net::SSLeay::set_tlsext_status_type($ssl,
    Net::SSLeay::TLSEXT_STATUSTYPE_ocsp());

# setup callback to verify OCSP response
my $cert_valid = undef;
Net::SSLeay::CTX_set_tlsext_status_cb($context,sub {
    my ($ssl,$resp) = @_;
    if (!$resp) {
        # Lots of servers don't return an OCSP response.
        # In this case we must check the OCSP status outside the SSL
        # handshake.
        warn "server did not return stapled OCSP response\n";
        return 1;
    }
    # verify status
    my $status = Net::SSLeay::OCSP_response_status($resp);
    if ($status != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) {
        warn "OCSP response failure: $status\n";
        return 1;
    }
    # verify signature - we have no OCSP_REQUEST here to check nonce
    if (!eval { Net::SSLeay::OCSP_response_verify($ssl,$resp) }) {
        warn "OCSP response verify failed\n";
        return 1;
    }
    # check if the certificate is valid
    # we should check here against the peer_certificate
    my $cert = Net::SSLeay::get_peer_certificate();
    my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) } or do {
        warn "cannot get certid from cert: $@";
        $cert_valid = -1;
        return 1;
    };

    if ( $nextupd = eval {
        Net::SSLeay::OCSP_response_results($resp,$certid) }) {
        warn "certificate not revoked\n";
        $cert_valid = 1;
    } else {
        warn "certificate not valid: $@";
        $cert_valid = 0;
    }
});

# do SSL handshake here
# ....
# check if certificate revocation was checked already
if ( ! defined $cert_valid) {
    # check revocation outside of SSL handshake by asking OCSP responder
    ...
} elsif ( ! $cert_valid ) {
    die "certificate not valid - closing SSL connection";
} elsif ( $cert_valid<0 ) {
    die "cannot verify certificate revocation - self-signed ?";
} else {
    # everything fine
    ...
}

๐Ÿงต Using Net::SSLeay in multi-threaded applications ๐Ÿงต

IMPORTANT: versions 1.42 or earlier are not thread-safe! ๐Ÿ˜ญ

The Net::SSLeay module implements all the necessary stuff to be ready for a multi-threaded environment โ€” and yeah, it requires openssl-0.9.7 or newer. The whole implementation fully follows the thread-safety-related requirements of the openssl library (check https://www.openssl.org/docs/manmaster/man3/threads.html for the tea โ˜•).

So if you're about to use Net::SSLeay (or literally any other module based on Net::SSLeay) inside a multi-threaded perl app, the glow-up move is to follow this best practice:

โœจ Initialization โœจ

Load and initialize the Net::SSLeay module in the main thread:

use threads;
use Net::SSLeay;

Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

sub do_master_job {
    # ... call whatever from Net::SSLeay
}

sub do_worker_job {
    # ... call whatever from Net::SSLeay
}

# start threads
my $master  = threads->new(\&do_master_job, 'param1', 'param2');
my @workers = threads->new(\&do_worker_job, 'arg1', 'arg2') for (1..10);

# waiting for all threads to finish
$_->join() for (threads->list);
NOTE: Openssl's int SSL_library_init(void) function (which is also aliased as SSLeay_add_ssl_algorithms, OpenSSL_add_ssl_algorithms and add_ssl_algorithms) is not re-entrant, and multiple calls can cause a crash in a threaded application ๐Ÿ’€. Net::SSLeay implements flags preventing repeated calls to this function, so even multiple initialization via Net::SSLeay::SSLeay_add_ssl_algorithms() should work without any trouble. Phew ๐Ÿซถ

๐ŸŽ€ Using callbacks ๐ŸŽ€

Do not use callbacks across threads (the module blocks cross-thread callback operations and throws a warning, bestie). Always do the callback setup, the callback use, and the callback destruction all within the same thread. Same thread = same vibe check โœ…

๐Ÿฆ‹ Using openssl elements ๐Ÿฆ‹

All openssl elements (X509, SSL_CTX, ...) can be passed directly between threads. No cap.

use threads;
use Net::SSLeay;

Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

sub do_job {
    my $context = shift;
    Net::SSLeay::CTX_set_default_passwd_cb($context, sub { "secret" });
    # ...
}

my $c = Net::SSLeay::CTX_new();
threads->create(\&do_job, $c);

Or, like, this other way:

use threads;
use Net::SSLeay;

my $context; # does not need to be 'shared'

Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

sub do_job {
    Net::SSLeay::CTX_set_default_passwd_cb($context, sub { "secret" });
    # ...
}

$context = Net::SSLeay::CTX_new();
threads->create(\&do_job);

๐ŸŒˆ Using other perl modules based on Net::SSLeay ๐ŸŒˆ

It should be totally fine to use any other module based on Net::SSLeay (like IO::Socket::SSL) in multi-threaded applications. Generally the recommendation is: do any global initialization of such a module in the main thread before calling threads->new(..) or threads->create(..) โ€” but ngl it might differ module by module ๐Ÿ™ˆ

To be safe you can load and init Net::SSLeay explicitly in the main thread:

use Net::SSLeay;
use Other::SSLeay::Based::Module;

Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

Or even safer:

use Net::SSLeay;
use Other::SSLeay::Based::Module;

BEGIN {
    Net::SSLeay::load_error_strings();
    Net::SSLeay::SSLeay_add_ssl_algorithms();
    Net::SSLeay::randomize();
}

๐Ÿ’€ Combining Net::SSLeay with other modules linked with openssl ๐Ÿ’€

BEWARE: This might be a big trouble! This is not guaranteed to be thread-safe!

There are so many other (XS) modules linked directly to the openssl library (like Crypt::SSLeay, for example).

And since it's expected that also "another" module will call SSLeay_add_ssl_algorithms at some point, we've got that same trouble again with multiple openssl initializations from Net::SSLeay and the "another" module ๐Ÿ˜ญ

As you can expect, Net::SSLeay is not able to avoid multiple initialization of the openssl library called by "another" module, so you have to handle this on your own (and in some cases it might not be possible at all to avoid it โ€” sorry bestie).

๐Ÿ“ Threading with get_https and friends ๐Ÿ“

The convenience functions get_https, post_https etc. all initialize the SSL library by calling Net::SSLeay::initialize, which does the conventional library initialization:

Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

Net::SSLeay::initialize initializes the SSL library at most once. You can override the Net::SSLeay::initialize function if you desire some other type of initialization behaviour by get_https and friends. And you can call Net::SSLeay::initialize from your own code if you want this conventional library initialization โ€” iconic, flexible, we love to see it ๐Ÿ’…


๐Ÿ’– Convenience routines ๐Ÿ’–

To be used with Low level API

Net::SSLeay::randomize($rn_seed_file,$additional_seed);
Net::SSLeay::set_cert_and_key($ctx, $cert_path, $key_path);
$cert = Net::SSLeay::dump_peer_certificate($ssl);
Net::SSLeay::ssl_write_all($ssl, $message) or die "ssl write failure";
$got = Net::SSLeay::ssl_read_all($ssl) or die "ssl read failure";

$got = Net::SSLeay::ssl_read_CRLF($ssl [, $max_length]);
$got = Net::SSLeay::ssl_read_until($ssl [, $delimit [, $max_length]]);
Net::SSLeay::ssl_write_CRLF($ssl, $message);
  • randomize โ€” seeds the openssl PRNG with /dev/urandom (peep the top of SSLeay.pm for how to change or configure this) and optionally with user-provided data. It is very important to properly seed your random numbers, so do not forget to call this, fr fr. The high level API functions automatically call randomize() so it is not needed with them. See also caveats ๐Ÿ‘€
  • set_cert_and_key โ€” takes two file names as arguments and sets the certificate and private key to those. This can be used to set either server certificates or client certificates ๐ŸŽ€
  • dump_peer_certificate โ€” lets you get a plaintext description of the certificate the peer (usually the server) presented to us. It's giving "show me what you're working with" โœจ
  • ssl_read_all โ€” see ssl_write_all (below)
  • ssl_write_all โ€” ssl_read_all() and ssl_write_all() provide true blocking semantics for these operations (see limitation, below, for the explanation). These are much preferred to the low level API equivalents (which implement BSD blocking semantics). The message argument to ssl_write_all() can be a reference โ€” super helpful to avoid unnecessary copying when you're writing something big, e.g.:
$data = 'A' x 1000000000;
Net::SSLeay::ssl_write_all($ssl, \$data) or die "ssl write failed";
  • ssl_read_CRLF โ€” uses ssl_read_all() to read in a line terminated with a carriage return followed by a linefeed (CRLF). The CRLF is included in the returned scalar. Periodt. ๐Ÿ’…
  • ssl_read_until

uses ssl_read_all() to read from the SSL input stream until it hits a delimiter you picked out. If the delimiter isn't defined, $/ gets used instead. And if $/ is also undefined? Then "\n" is the fallback. You can optionally cap the max number of bytes to read from the SSL input stream too. ๐ŸŽ€

  • ssl_write_CRLF โ€” writes $message to the SSL output stream and appends CRLF to it. That's it, that's the whole vibe.

โœจ Initialization โœจ

Okay bestie, before you touch the low level API you gotta start your program with this little incantation โ€” think of it as lighting a candle before you do witchcraft ๐Ÿ”ฎ:

use Net::SSLeay qw(die_now die_if_ssl_error);
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();    # Important!
Net::SSLeay::ENGINE_load_builtin_engines();  # If you want built-in engines
Net::SSLeay::ENGINE_register_all_complete(); # If you want built-in engines
Net::SSLeay::randomize();

Note the # Important! on SSLeay_add_ssl_algorithms() โ€” that one is not optional, the rest of it is literally just vibes without it. ๐Ÿ’…


๐Ÿ’€ Error handling functions ๐Ÿ’€

I cannot stress this enough, and I mean cannot โ€” you need to check for errors. Use these functions even in the most baby-simple programs you write. They cut your debugging time down so much it's honestly not even funny. And fr fr: do not go asking questions on the mailing list until you've sprinkled these into your code first. The error stack is right there, bestie, just look at it ๐Ÿ˜ญ

  • die_now
  • die_if_ssl_error

die_now() and die_if_ssl_error() are the convenient little duo that prints the SSLeay error stack for you when something goes sideways:

Net::SSLeay::connect($ssl) or die_now("Failed SSL connect ($!)");

Net::SSLeay::write($ssl, "foo") or die_if_ssl_error("SSL write ($!)");
  • print_errs

And if you don't wanna bail out of the whole program, Net::SSLeay::print_errs() dumps the error stack without exiting. ๐Ÿซถ See how much more readable your code gets when you import the error reporting functions into your main namespace? Chef's kiss.


๐Ÿงฆ Sockets ๐Ÿงฆ

So here's the thing: Perl uses file handles for all I/O. SSLeay has its own whole flexible BIO mechanism, Perl has its own evolved PerlIO mechanism, and this module? This module still just sticks to file descriptors, no cap. So to attach SSLeay to a socket you extract the underlying file descriptor with fileno():

Net::SSLeay::set_fd($ssl, fileno(S));   # Must use fileno

Like, must. The comment says so. ๐Ÿ‘‘

You should also set $| to 1 so you kill off STDIO buffering โ€” otherwise you'll confuse yourself real bad if you use perl I/O functions to poke at your socket handle. ๐Ÿ™ˆ

Need to select(2) on the socket? Go off, do it. But be warned: OpenSSL does some internal buffering of its own, so SSL_read does not always hand you data even when the socket selected for reading. The move is just to keep on selecting and trying to read again. "Net::SSLeay" behaves no differently from C-language OpenSSL here โ€” that's just how it is, periodt.


๐ŸŽ€ Callbacks ๐ŸŽ€

You can set up a per-context verify callback function, something like this:

sub verify {
    my ($ok, $x509_store_ctx) = @_;
    print "Verifying certificate...\n";
    # ...
    return $ok;
}

And then you use it like this:

Net::SSLeay::set_verify ($ssl, Net::SSLeay::VERIFY_PEER, \&verify);

Also: per-context callbacks for decrypting private keys are implemented. Slay. ๐Ÿ”ฅ

Net::SSLeay::CTX_set_default_passwd_cb($ctx, sub { "top-secret" });
Net::SSLeay::CTX_use_PrivateKey_file($ctx, "key.pem",
                                     Net::SSLeay::FILETYPE_PEM)
    or die "Error reading private key";
Net::SSLeay::CTX_set_default_passwd_cb($ctx, undef);

If your OpenSSL supports Hello Extensions, you can set up a session secret callback that gets called whenever openssl sets a session secret. Set it up like this:

Net::SSLeay::set_session_secret_cb($ssl, \&session_secret_cb, $somedata);

And it gets called like this:

sub session_secret_cb {
    my ($secret, \@cipherlist, \$preferredcipher, $somedata) = @_;
}

That's it though โ€” no other callbacks are implemented. And honestly you don't need any callback at all for the simple (i.e. normal) cases, the ones where the SSLeay built-in verify mechanism already does what you need. ๐Ÿ’–

โš ๏ธ You must reset these callbacks to undef immediately after you're done using them. Not resetting them can cause memory leaks, thread safety problems, and crashes on exit โ€” especially if different threads set different callbacks. Not a cute look, please don't skip this. ๐Ÿ˜ญ

Wanna mess with callback stuff? Go look at examples/callback.pl! It's the only one the author was able to make work reliably, so, y'know. Take the win. ๐Ÿ†


๐Ÿ”ฅ Low level API ๐Ÿ”ฅ

On top of all the high level functions outlined above, this module also gives you straight-up, no-frills access to the CRYPTO and SSL parts of the OpenSSL C API.

Peep the "*.h" headers from the OpenSSL C distribution for a list of low level SSLeay functions you can call โ€” and check SSLeay.xs to see if some function has actually been implemented. The module strips the leading "SSL_" off of the SSLeay names, and generally you drop "Net::SSLeay::" in its place.

Heads up: some functions are prefixed with "P_" โ€” those are very close to the original API, but they've got some kind of wrapper on them making the interface more perl friendly. ๐Ÿฆ‹

For example. In C:

#include <ssl.h>

err = SSL_set_verify (ssl, SSL_VERIFY_CLIENT_ONCE, &your_call_back_here);

In Perl:

use Net::SSLeay;

$err = Net::SSLeay::set_verify ($ssl,
                                Net::SSLeay::VERIFY_CLIENT_ONCE,
                                \&your_call_back_here);

And if the function doesn't start with "SSL_" you just use the full function name, e.g.:

$err = Net::SSLeay::ERR_get_error;

The following new functions behave in a perlish way:

$got = Net::SSLeay::read($ssl);
                            # Performs SSL_read, but returns $got
                            # resized according to data received.
                            # Returns undef on failure.

Net::SSLeay::write($ssl, $foo) || die;
                            # Performs SSL_write, but automatically
                            # figures out the size of $foo
  • OpenSSL_version_num and SSLeay

COMPATIBILITY: SSLeay() is not available in Net-SSLeay-1.42 and before. SSLeay() was made an alias of OpenSSL_version_num() in OpenSSL 1.1.0 and LibreSSL 2.7.0.

COMPATIBILITY: OpenSSL_version_num() requires at least Net-SSLeay-1.82 with OpenSSL 1.1.0, or Net-SSLeay-1.88 with LibreSSL 2.7.0.

Both functions return the OPENSSL_VERSION_NUMBER constant (numeric) as defined by the underlying OpenSSL or LibreSSL library.

my $ver_number = Net::SSLeay::SSLeay();
# or
my $ver_number = Net::SSLeay::OpenSSL_version_num();
# returns: OPENSSL_VERSION_NUMBER constant

# OpenSSL version numbering is:
# 0x00903100 => openssl-0.9.3
# 0x00904100 => openssl-0.9.4
# 0x00905100 => openssl-0.9.5
# 0x0090600f => openssl-0.9.6
# 0x0090601f => openssl-0.9.6a
# ...
# 0x009060df => openssl-0.9.6m
# 0x0090700f => openssl-0.9.7
# 0x0090701f => openssl-0.9.7a
# ...
# 0x009070df => openssl-0.9.7m
# 0x0090800f => openssl-0.9.8
# 0x0090801f => openssl-0.9.8a
# ...
# 0x0090821f => openssl-0.9.8zh
# 0x1000000f => openssl-1.0.0
# ...
# 0x1000014f => openssl-1.0.0t
# 0x1000100f => openssl-1.0.1
# ...
# 0x1000115f => openssl-1.0.1u
# 0x1000200f => openssl-1.0.2
# ...
# 0x1000215f => openssl-1.0.2u
# 0x1010000f => openssl-1.1.0
# ...
# 0x101000cf => openssl-1.1.0l
# 0x1010100f => openssl-1.1.1
# ...
# 0x1010117f => openssl-1.1.1w
# 0x30000000 => openssl-3.0.0
# ...
# 0x300000c0 => openssl-3.0.12
# 0x30100000 => openssl-3.1.0
# ...
# 0x30100040 => openssl-3.1.4
# 0x30200000 => openssl-3.2.0

# Note that OpenSSL 3.0.0 and later do not set the status nibble in the
# least significant octet to f.

# LibreSSL returns 0x20000000 always:
# 0x20000000 => libressl-2.2.1
# ...
# 0x20000000 => libressl-3.8.2

When you know the underlying library is OpenSSL, you can use the version number like this:

if (Net::SSLeay::SSLeay() < 0x0090800f) {
    die "You need OpenSSL 0.9.8 or higher";
}

LibresSSL 2.2.2 and later define the constant LIBRESSL_VERSION_NUMBER, which gives you the LibreSSL version number. The format is the same one OpenSSL uses with OPENSSL_VERSION_NUMBER. So you can do this if you need to check that the underlying library is LibreSSL and that it's recent enough:

if (Net::SSLeay::SSLeay() != 0x20000000 ||
        Net::SSLeay::LIBRESSL_VERSION_NUMBER() < 0x3040200f) {
    die "You need LibreSSL. Version 3.4.2 or higher";
}

Check the openssl doc over at https://www.openssl.org/docs/manmaster/man3/OpenSSL_version_num.html ๐Ÿ“š

And peep the OpenSSL 1.1.1 and earlier documentation for the details of the status nibble and how to interpret the format. iykyk.

  • SSLeay_version

COMPATIBILITY: not available in Net-SSLeay-1.42 and before.

Returns different strings depending on $type.

my $ver_string = Net::SSLeay::SSLeay_version($type);
# $type
#   SSLEAY_VERSION  - e.g. 'OpenSSL 1.0.0d 8 Feb 2011'
#   SSLEAY_CFLAGS   - e.g. 'compiler: gcc -D_WINDLL -DOPENSSL_USE_APPLINK .....'
#   SSLEAY_BUILT_ON - e.g. 'built on: Fri May  6 00:00:46 GMT 2011'
#   SSLEAY_PLATFORM - e.g. 'platform: mingw'
#   SSLEAY_DIR      - e.g. 'OPENSSLDIR: "z:/...."'
#
# returns: string

Net::SSLeay::SSLeay_version();
# is equivalent to
Net::SSLeay::SSLeay_version(SSLEAY_VERSION);

OpenSSL 1.1.0 changed SSLeay_version() into an alias of OpenSSL_version(). So to make sure everything actually works with LibreSSL, use the SSLEAY_* constants with SSLeay_version() and the OPENSSL_* constants with OpenSSL_version(). Don't mix 'em up bestie ๐Ÿ’…

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OpenSSL_version.html

The OpenSSL website doesn't have a manual page for SSLeay_version() anymore. Gone, reduced to atoms. ๐Ÿ’€

  • OpenSSL_version

COMPATIBILITY: requires at least Net-SSLeay-1.82 with OpenSSL 1.1.0, or Net-SSLeay-1.88 with LibreSSL 2.7.0.

Returns different strings depending on $t. Which $t constants are available depends on your library version.

my $ver_string = Net::SSLeay::OpenSSL_version($t);
# $t
#   OPENSSL_VERSION     - e.g. 'OpenSSL 1.1.0g  2 Nov 2017'
#   OPENSSL_CFLAGS      - e.g. 'compiler: cc -DDSO_DLFCN -DHAVE_DLFCN_H .....'
#   OPENSSL_BUILT_ON    - e.g. 'built on: reproducible build, date unspecified'
#   OPENSSL_PLATFORM    - e.g. 'platform: darwin64-x86_64-cc'
#   OPENSSL_DIR         - e.g. 'OPENSSLDIR: "/opt/openssl-1.1.0g"'
#   OPENSSL_ENGINES_DIR - e.g. 'ENGINESDIR: "/opt/openssl-1.1.0g/lib/engines-1.1"'
#
# returns: string

Net::SSLeay::OpenSSL_version();
# is equivalent to
Net::SSLeay::OpenSSL_version(OPENSSL_VERSION);

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OpenSSL_version.html>

  • OPENSSL_info โ€” okay so this one's a little gossipy, it literally just returns different strings depending on $t, and the $t constants you get to play with depend on the library version ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1
my $info_string = Net::SSLeay::OPENSSL_info($t);
# $t
#   OPENSSL_INFO_CONFIG_DIR - e.g. '/opt/openssl-3.0.1'
#   OPENSSL_INFO_...
#
# returns: string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_info.html>

  • OPENSSL_version_major, OPENSSL_version_minor and OPENSSL_version_patch โ€” the trio that tells you exactly which flavor of OpenSSL you're dealing with, one number at a time ๐Ÿ“
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL

They return the constants OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR and OPENSSL_VERSION_PATCH, respectively. Respectively!! slay.

my $major = Net::SSLeay::OPENSSL_version_major();
my $minor = Net::SSLeay::OPENSSL_version_minor();
my $patch = Net::SSLeay::OPENSSL_version_patch();
#
# return: integer

For example with OpenSSL 3.0.1, $major is 3, $minor is 0 and $patch is 1. iconic behaviour honestly.

Note: the constants record Net::SSLeay compile time values whereas the three functions return values from the library. Typically these are the same, but they can be different if the library version is updated but Net::SSLeay is not re-compiled. See the OpenSSL and LibreSSL API/ABI compatibility statements for more information. (iykyk ๐Ÿ˜ญ)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_version_major.html>

  • OPENSSL_version_pre_release โ€” returns that constant string defined by the C macro OPENSSL_VERSION_PRE_RELEASE โœจ
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL
my $pre_release = Net::SSLeay::OPENSSL_version_pre_release();
#
# returns: string (For example: "-alpha3" or "" for a release version)

When the macro is not defined, an empty string is returned instead. no cap.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_version_pre_release.html>

  • OPENSSL_version_build_metadata โ€” same vibe, different macro: hands you the constant string defined by the C macro OPENSSL_VERSION_BUILD_METADATA ๐Ÿฆ‹
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL
my $metadata = Net::SSLeay::OPENSSL_version_build_metadata();
#
# returns: string (For example: "+fips" or "")

When the macro is not defined, an empty string is returned instead. she's consistent.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_version_build_metadata.html>


Okay bestie, this is the part where we warm the whole thing up. Grab a snack ๐ŸŽ€

  • library_init โ€” initializes the SSL library by registering algorithms. it's giving "first day of school" energy.
my $rv = Net::SSLeay::library_init();

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_library_init.html>

While the original function from OpenSSL always returns 1, Net::SSLeay adds a wrapper around it to make sure that the OpenSSL function is only called once. Thus the function will return 1 if initialization was done and 0 if not, i.e. if initialization was done already before. lowkey a glow-up ngl ๐Ÿ’…

  • add_ssl_algorithms โ€” the alias for library_init, literally twins ๐Ÿ‘ฏ
Net::SSLeay::add_ssl_algorithms();
  • OpenSSL_add_ssl_algorithms โ€” also an alias for library_init. yes another one. she has many names, main character energy ๐Ÿ‘‘
Net::SSLeay::OpenSSL_add_ssl_algorithms();
  • SSLeay_add_ssl_algorithms โ€” and the third alias for library_init. collect the whole set fr fr ๐ŸŽ€
Net::SSLeay::SSLeay_add_ssl_algorithms();
  • load_error_strings โ€” registers the error strings for all libcrypto + libssl related functions, so when stuff goes wrong it actually tells you why instead of just screaming ๐Ÿ˜ญ
Net::SSLeay::load_error_strings();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_load_crypto_strings.html>

  • ERR_load_crypto_strings โ€” registers the error strings for all libcrypto functions. No need to call this function if you have already called load_error_strings (she does it all for you, so don't be extra).
Net::SSLeay::ERR_load_crypto_strings();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_load_crypto_strings.html>

  • ERR_load_RAND_strings โ€” registers the error strings for RAND related functions. No need to call this function if you have already called load_error_strings.
Net::SSLeay::ERR_load_RAND_strings();
#
# returns: no return value
  • ERR_load_SSL_strings โ€” registers the error strings for SSL related functions. No need to call this function if you have already called load_error_strings. same deal, bestie ๐Ÿ’œ
Net::SSLeay::ERR_load_SSL_strings();
#
# returns: no return value
  • OpenSSL_add_all_algorithms โ€” adds algorithms to the internal table. the algorithm collection is expanding ๐Ÿ”ฅ
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
Net::SSLeay::OpenSSL_add_all_algorithms();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OpenSSL_add_all_algorithms.html>

  • OPENSSL_add_all_algorithms_conf โ€” similar to OpenSSL_add_all_algorithms โ€” will ALWAYS load the config file. always always. no skipping ๐Ÿ™ˆ
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
Net::SSLeay::OPENSSL_add_all_algorithms_conf();
#
# returns: no return value
  • OPENSSL_add_all_algorithms_noconf โ€” similar to OpenSSL_add_all_algorithms โ€” will NEVER load the config file. opposite twin, the duality of woman โœจ
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
Net::SSLeay::OPENSSL_add_all_algorithms_noconf();
#
# returns: no return value
  • OPENSSL_cleanup โ€” deinitialises OpenSSL libcrypto and libssl. the goodbye era ๐Ÿ’€
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3 or LibreSSL 3.6.0
Net::SSLeay::OPENSSL_cleanup();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_cleanup>

  • OPENSSL_init_crypto โ€” initialises OpenSSL libcrypto with non-default settings, i.e. you get to have opinions about it ๐Ÿงš
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3 not enabled for LibreSSL. LibreSSL does not define OPENSSL_INIT_SETTINGS.
my $rv = Net::SSLeay::OPENSSL_init_crypto($opts, $settings);
# $opts - (uin64_t) flags to be set (bitmask)
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure or undef (optional)
#
# returns: 1 on success or 0 on error

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_init_crypto>

  • OPENSSL_init_ssl โ€” same thing but for OpenSSL libssl with non-default settings. her sister ๐Ÿ’–
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3 not enabled for LibreSSL. LibreSSL does not define OPENSSL_INIT_SETTINGS.
my $rv = Net::SSLeay::OPENSSL_init_ssl($opts, $settings);
# $opts - (uin64_t) flags to be set (bitmask)
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure or undef (optional)
#
# returns: 1 on success or 0 on error

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_init_ssl>

  • OPENSSL_INIT_new โ€” allocates an OpenSSL OPENSSL_INIT_SETTINGS object. building the settings from scratch, we love a fresh start ๐ŸŒธ
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3, not in LibreSSL
my $settings = Net::SSLeay::OPENSSL_init_new()
#
# returns: value corresponding to OPENSSL_INIT_SETTINGS structure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_INIT_new>

  • OPENSSL_INIT_free โ€” releases an OpenSSL OPENSSL_INIT_SETTINGS object allocated with OPENSSL_INIT_new. clean up after yourself, bestie ๐Ÿซถ
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3, not in LibreSSL
Net::SSLeay::OPENSSL_init_free($settings)
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_INIT_free>

  • OPENSSL_INIT_set_config_filename โ€” specify a nondefault filename to load as OpenSSL configuration file. yes you can pick your own config file, she's flexible like that ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3, not in LibreSSL
my $rv = Net::SSLeay::OPENSSL_INIT_set_config_filename($settings, $filename);
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure
# $filename - (string) filename
#
# returns: 1 on success or 0 on error

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_INIT_set_config_filename>

  • OPENSSL_INIT_set_config_appname โ€” specify a nondefault application name. branding, basically ๐ŸŽ€
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0-pre3, not in LibreSSL
my $rv = Net::SSLeay::OPENSSL_INIT_set_config_appname($settings, $name);
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure
# $name - (string) application name
#
# returns: 1 on success or 0 on error

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_INIT_set_config_appname>

  • OPENSSL_INIT_set_config_file_flags
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL

So you wanna set nondefault flags for loading the OpenSSL config file? Say less, bestie, this one's for you:

my $rv = Net::SSLeay::OPENSSL_INIT_set_config_file_flags($settings, $flags);
# $settings - value corresponding to OPENSSL_INIT_SETTINGS structure
# $flags - (unsigned long) flags to be set (bitmask)
#
# returns: 1 on success or 0 on error

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OPENSSL_INIT_set_config_file_flags>


โš ๏ธ NOTE: heads up bestie โ€” the SSL_alert_* functions here have the "SSL_" part stripped from their names. So SSL_alert_desc_string shows up as just alert_desc_string. That's not a typo, that's just how this module rolls. ๐Ÿ’…
  • ERR_clear_error โ€” Clears the error queue. Poof, gone, empty, clean slate energy. โœจ
Net::SSLeay::ERR_clear_error();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_clear_error.html>

  • ERR_error_string โ€” Generates a human-readable string representing the error code $error. Basically translates cryptic number โ†’ words you can actually read. ๐Ÿซถ
my $rv = Net::SSLeay::ERR_error_string($error);
# $error - (unsigned integer) error code
#
# returns: string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_error_string.html>

  • ERR_get_error โ€” Returns the earliest error code from the thread's error queue and removes that entry. So this one is destructive in the cutest way โ€” you can keep calling it over and over until there are no more error codes left to return. ๐ŸŽ€
my $rv = Net::SSLeay::ERR_get_error();
#
# returns: (unsigned integer) error code

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_get_error.html>

  • ERR_peek_error โ€” Returns the earliest error code from the thread's error queue without modifying it. Peek, don't touch, that's the whole vibe. ๐Ÿ‘€
my $rv = Net::SSLeay::ERR_peek_error();
#
# returns: (unsigned integer) error code

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_get_error.html>

  • ERR_put_error โ€” Adds an error code to the thread's error queue. It signals that the error of $reason code reason occurred in function $func of library $lib, in line number $line of $file. Clocking the whole scene, fr fr. ๐Ÿ”ฅ
Net::SSLeay::ERR_put_error($lib, $func, $reason, $file, $line);
# $lib - (integer) library id (check openssl/err.h for constants e.g. ERR_LIB_SSL)
# $func - (integer) function id (check openssl/ssl.h for constants e.g. SSL_F_SSL23_READ)
# $reason - (integer) reason id (check openssl/ssl.h for constants e.g. SSL_R_SSL_HANDSHAKE_FAILURE)
# $file - (string) file name
# $line - (integer) line number in $file
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ERR_put_error.html> and <https://www.openssl.org/docs/manmaster/man3/err.html>

  • alert_desc_string โ€” Returns a two letter string as a short form describing the reason of the alert specified by value. Little two-letter summary, love that for us. ๐Ÿ“
my $rv = Net::SSLeay::alert_desc_string($value);
# $value - (integer) alert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants)
#
# returns: description string (2 letters)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_alert_type_string.html>

  • alert_desc_string_long โ€” Returns a string describing the reason of the alert specified by value. The long-form version, aka the one that actually spills the tea. ๐Ÿ’ฌ
my $rv = Net::SSLeay::alert_desc_string_long($value);
# $value - (integer) alert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants)
#
# returns: description string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_alert_type_string.html>

  • alert_type_string โ€” Returns a one letter string indicating the type of the alert specified by value. One letter. She's concise. ๐Ÿ’…
my $rv = Net::SSLeay::alert_type_string($value);
# $value - (integer) alert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants)
#
# returns: string (1 letter)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_alert_type_string.html>

  • alert_type_string_long โ€” Returns a string indicating the type of the alert specified by value. Same info as above but in its long-form era. โœจ
my $rv = Net::SSLeay::alert_type_string_long($value);
# $value - (integer) alert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants)
#
# returns: string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_alert_type_string.html>


  • SSLv23_method, SSLv23_server_method and SSLv23_client_method โ€” COMPATIBILITY: not available in Net-SSLeay-1.82 and before.

Returns SSL_METHOD structure corresponding to general-purpose version-flexible TLS method, and the return value can be later used as a param of "CTX_new_with_method".

๐Ÿ’€ NOTE: for real, consider using TLS_method, TLS_server_method or TLS_client_method with new code. Like, please. We're begging.
my $rv = Net::SSLeay::SSLv2_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)
  • SSLv2_method โ€” Returns SSL_METHOD structure corresponding to SSLv2 method, the return value can be later used as a param of "CTX_new_with_method". Only available where supported by the underlying openssl โ€” so like, no promises if your openssl isn't feeling her. ๐Ÿ™ˆ
my $rv = Net::SSLeay::SSLv2_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)
  • SSLv3_method โ€” Returns SSL_METHOD structure corresponding to SSLv3 method, the return value can be later used as a param of "CTX_new_with_method". Again: legacy icon behaviour, handle with care. ๐ŸŽ€
my $rv = Net::SSLeay::SSLv3_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

  • TLSv1_method, TLSv1_server_method and TLSv1_client_method โ€” COMPATIBILITY: requires OpenSSL or LibreSSL built with support for TLSv1. The server and client methods are not available in Net-SSLeay-1.82 and before.

Returns SSL_METHOD structure corresponding to TLSv1 method, the return value can be later used as a param of "CTX_new_with_method". ๐Ÿฆ‹

my $rv = Net::SSLeay::TLSv1_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

  • TLSv1_1_method, TLSv1_1_server_method and TLSv1_1_client_method โ€” COMPATIBILITY: requires OpenSSL >= 1.0.1 or LibreSSL built with support for TLSv1.1. The server and client methods are not available in Net-SSLeay-1.82 and before.

Returns SSL_METHOD structure corresponding to TLSv1_1 method, the return value can be later used as a param of "CTX_new_with_method". โœจ

my $rv = Net::SSLeay::TLSv1_1_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

  • TLSv1_2_method, TLSv1_2_server_method and TLSv1_2_client_method โ€” COMPATIBILITY: requires OpenSSL >= 1.0.1 or LibreSSL built with support for TLSv1.2. The server and client methods are not available in Net-SSLeay-1.82 and before.

Returns SSL_METHOD structure corresponding to TLSv1_2 method, the return value can be later used as a param of "CTX_new_with_method". She ate. ๐Ÿ”ฅ

my $rv = Net::SSLeay::TLSv1_2_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

  • TLS_method, TLS_server_method and TLS_client_method โ€” COMPATIBILITY: not available in Net-SSLeay-1.82 and before.

Returns SSL_METHOD structure corresponding to general-purpose version-flexible TLS method, the return value can be later used as a param of "CTX_new_with_method". Only available where supported by the underlying openssl. This is the main character of the method functions, ngl. ๐Ÿ‘‘

my $rv = Net::SSLeay::TLS_method();
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>


  • ENGINE_load_builtin_engines โ€” COMPATIBILITY: requires an OpenSSL build with dynamic engine loading support.

Loads all bundled ENGINEs into memory and makes them visible. Everyone into the group chat, let's go. ๐Ÿซถ

Net::SSLeay::ENGINE_load_builtin_engines();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ENGINE_by_id.html>

  • ENGINE_register_all_complete โ€” COMPATIBILITY: requires an OpenSSL build with dynamic engine loading support.

Registers all loaded ENGINEs for every algorithm they collectively implement. Team effort, no cap. โœจ

Net::SSLeay::ENGINE_register_all_complete();
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ENGINE_by_id.html>

  • ENGINE_set_default โ€” COMPATIBILITY: requires an OpenSSL build with dynamic engine loading support.

Sets the default engine to $e + sets its flags to $flags. The full bitmask menu, bestie, read it and weep: ๐Ÿ’…

my $rv = Net::SSLeay::ENGINE_set_default($e, $flags);
# $e - value corresponding to openssl's ENGINE structure
# $flags - (integer) engine flags
#          flags value can be made by bitwise "OR"ing:
#          0x0001 - ENGINE_METHOD_RSA
#          0x0002 - ENGINE_METHOD_DSA
#          0x0004 - ENGINE_METHOD_DH
#          0x0008 - ENGINE_METHOD_RAND
#          0x0010 - ENGINE_METHOD_ECDH
#          0x0020 - ENGINE_METHOD_ECDSA
#          0x0040 - ENGINE_METHOD_CIPHERS
#          0x0080 - ENGINE_METHOD_DIGESTS
#          0x0100 - ENGINE_METHOD_STORE
#          0x0200 - ENGINE_METHOD_PKEY_METHS
#          0x0400 - ENGINE_METHOD_PKEY_ASN1_METHS
#          Obvious all-or-nothing cases:
#          0xFFFF - ENGINE_METHOD_ALL
#          0x0000 - ENGINE_METHOD_NONE
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ENGINE_by_id.html>

  • ENGINE_by_id โ€” Gets the ENGINE by its identification $id. Find your fave by name, like a contacts app but for crypto engines. ๐Ÿ”

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/ENGINE_by_id.html>

COMPATIBILITY: needs an OpenSSL build that actually has dynamic engine loading support โ€” no support, no engine party ๐Ÿ’…

my $rv = Net::SSLeay::ENGINE_by_id($id);
# $id - (string) engine identification e.g. "dynamic"
#
# returns: value corresponding to openssl's ENGINE structure (0 on failure)

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/ENGINE_by_id.html ๐Ÿซถ


These are the key-object besties. Like, the actual cryptographic key structures. Handle with care ๐ŸŽ€

  • EVP_PKEY_copy_parameters โ€” literally copies the parameters from key $from over to key $to. That's it, that's the whole vibe.
my $rv = Net::SSLeay::EVP_PKEY_copy_parameters($to, $from);
# $to - value corresponding to openssl's EVP_PKEY structure
# $from - value corresponding to openssl's EVP_PKEY structure
#
# returns: 1 on success, 0 on failure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_cmp.html โญ

  • EVP_PKEY_new โ€” creates a brand new EVP_PKEY structure, fresh out the box, main character energy.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::EVP_PKEY_new();
#
# returns: value corresponding to openssl's EVP_PKEY structure (0 on failure)

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new.html ๐Ÿ’–

  • EVP_PKEY_free โ€” frees an allocated EVP_PKEY structure. Cleanup era, we love to see it ๐Ÿงน

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

Net::SSLeay::EVP_PKEY_free($pkey);
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: no return value

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new.html ๐Ÿ’–

  • EVP_PKEY_assign_RSA โ€” sets the key referenced by $pkey to $key. Slay, but read the note bestie ๐Ÿ‘‡

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

NOTE: the reference counter does not get increased โ€” meaning $key will be freed if $pkey is freed. So likeโ€ฆ they're linked, no take-backs, no cap. ๐Ÿ’€
my $rv = Net::SSLeay::EVP_PKEY_assign_RSA($pkey, $key);
# $pkey - value corresponding to openssl's EVP_PKEY structure
# $key - value corresponding to openssl's RSA structure
#
# returns: 1 on success, 0 on failure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_assign_RSA.html ๐ŸŒธ

  • EVP_PKEY_assign_EC_KEY โ€” same situation, but for EC. Sets the key referenced by $pkey to $key.

COMPATIBILITY: not available in Net-SSLeay-1.74 and before ๐Ÿ™ˆ

NOTE: again, no reference counter increase โ€” $key gets freed if $pkey gets freed. Same deal, different curve ๐ŸŒ€
my $rv = Net::SSLeay::EVP_PKEY_assign_EC_KEY($pkey, $key);
# $pkey - value corresponding to openssl's EVP_PKEY structure
# $key - value corresponding to openssl's EC_KEY structure
#
# returns: 1 on success, 0 on failure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_assign_EC_KEY.html ๐ŸŒธ

  • EVP_PKEY_bits โ€” tells you how big $pkey is, in bits. Size check, but for cryptography ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::EVP_PKEY_bits($pkey);
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: size in bits
  • EVP_PKEY_security_bits โ€” returns the size of the key $pkey in bits.

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.6.0 and Net-SSLeay-1.94 โš ๏ธ

my $rv = Net::SSLeay::EVP_PKEY_security_bits($pkey);
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: number of bits
  • EVP_PKEY_size โ€” gives you the maximum size of a signature in bytes. Lowkey important: the actual signature you get might be smaller than this. It's a ceiling, not a promise ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::EVP_PKEY_size($pkey);
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: the maximum size in bytes

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_size.html โญ

  • EVP_PKEY_id โ€” returns the $pkey type, as an integer value of the corresponding NID.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 1.0.0 ๐Ÿ‘‘

my $rv = Net::SSLeay::EVP_PKEY_id($pkey);
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: (integer) key type

Example โ€” here's how you'd actually use it:

my $pubkey = Net::SSLeay::X509_get_pubkey($x509);
my $type = Net::SSLeay::EVP_PKEY_id($pubkey);
print Net::SSLeay::OBJ_nid2sn($type);             # prints e.g. 'rsaEncryption'

Like, iconic. It literally tells you what kind of key you're holding ๐Ÿ”ฅ


PEM is the text-y -----BEGIN WHATEVER----- format, and these functions are the whole friend group that reads and writes it โœจ

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/pem.html ๐Ÿซถ

  • PEM_read_bio_X509 โ€” loads a PEM formatted X509 certificate through the BIO structure you hand it.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::PEM_read_bio_X509($bio);
# $bio - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509 structure (0 on failure)

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
my $x509 = Net::SSLeay::PEM_read_bio_X509($bio);
Net::SSLeay::BIO_free($bio);
  • PEM_read_bio_X509_REQ โ€” loads a PEM formatted X509_REQ object through the given BIO structure. That's your certificate signing request bestie ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::PEM_read_bio_X509_REQ($bio, $x=NULL, $cb=NULL, $u=NULL);
# $bio - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509_REQ structure (0 on failure)

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
my $x509_req = Net::SSLeay::PEM_read_bio_X509_REQ($bio);
Net::SSLeay::BIO_free($bio);
  • PEM_read_bio_DHparams โ€” reads a DH structure from a BIO. Diffie-Hellman said hi ๐Ÿ‘‹
my $rv = Net::SSLeay::PEM_read_bio_DHparams($bio);
# $bio - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's DH structure (0 on failure)
  • PEM_read_bio_X509_CRL โ€” reads an X509_CRL structure from a BIO. Certificate revocation lists, the unglamorous but necessary icon ๐Ÿ’…
my $rv = Net::SSLeay::PEM_read_bio_X509_CRL($bio);
# $bio - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509_CRL structure (0 on failure)
  • PEM_read_bio_PrivateKey โ€” loads a PEM formatted private key through the given BIO structure. The password handling here is genuinely the most extra part of this whole page, so stay with me ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

my $rv = Net::SSLeay::PEM_read_bio_PrivateKey($bio, $cb, $data);
# $bio - value corresponding to openssl's BIO structure
# $cb - reference to perl callback function
# $data - data that will be passed to callback function (see examples below)
#
# returns: value corresponding to openssl's EVP_PKEY structure (0 on failure)

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
my $privkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio); # ask for password if needed
Net::SSLeay::BIO_free($bio);

To use a password you have the following options:

$privkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio, \&callback_func); # use callback func for getting password
$privkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio, \&callback_func, $data); # use callback_func + pass $data to callback_func
$privkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio, undef, "secret"); # use password "secret"
$privkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio, undef, "");       # use empty password

Callback function signature:

sub callback_func {
    my ($max_passwd_size, $rwflag, $data) = @_;
    # $max_passwd_size - maximum size of returned password (longer values will be discarded)
    # $rwflag - indicates whether we are loading (0) or storing (1) - for PEM_read_bio_PrivateKey always 0
    # $data - the data passed to PEM_read_bio_PrivateKey as 3rd parameter

    return "secret";
}

See, the $rwflag thing? For PEM_read_bio_PrivateKey it's always 0. Loading only, we don't store here ๐Ÿ”’

  • PEM_X509_INFO_read_bio โ€” reads a BIO containing a PEM formatted file into a STACK_OF(X509_INFO) structure. Whole file, one stack, very efficient of it ๐ŸŒˆ
my $rv = Net::SSLeay::PEM_X509_INFO_read_bio($bio);
# $bio - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's STACK_OF(X509_INFO) structure.

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'r');
my $sk_x509_info = Net::SSLeay::PEM_X509_INFO_read_bio($bio);
Net::SSLeay::BIO_free($bio);
  • PEM_get_string_X509 โ€” converts/exports an X509 certificate to a string in PEM format.
NOTE: this one does not exactly correspond to any low level API function. It's a Net::SSLeay special, homegrown ๐Ÿงš
Net::SSLeay::PEM_get_string_X509($x509);
# $x509 - value corresponding to openssl's X509 structure
#
# returns: string with $x509 in PEM format
  • PEM_get_string_PrivateKey โ€” converts public key $pk into a PEM formatted string, optionally protected with a password. Glow-up: from key object to text ๐Ÿ’–

COMPATIBILITY: not available in Net-SSLeay-1.45 and before. Requires the legacy provider with OpenSSL 3.0 and later if the default value of $enc_alg ("DES_CBC") is used. โš ๏ธ Yeah, that's a real caveat โ€” default path needs the legacy provider on OpenSSL 3.0+.

my $rv = Net::SSLeay::PEM_get_string_PrivateKey($pk, $passwd, $enc_alg);
# $pk - value corresponding to openssl's EVP_PKEY structure
# $passwd - [optional] (string) password to use for key encryption
# $enc_alg - [optional] algorithm to use for key encryption (default: DES_CBC) - value corresponding to openssl's EVP_CIPHER structure
#
# returns: PEM formatted string

Examples:

$pem_privkey = Net::SSLeay::PEM_get_string_PrivateKey($pk);
$pem_privkey = Net::SSLeay::PEM_get_string_PrivateKey($pk, "secret");
$pem_privkey = Net::SSLeay::PEM_get_string_PrivateKey($pk, "secret", Net::SSLeay::EVP_get_cipherbyname("DES-EDE3-CBC"));
  • PEM_get_string_X509_CRL โ€” converts the X509_CRL object $x509_crl into a PEM formatted string.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

Net::SSLeay::PEM_get_string_X509_CRL($x509_crl);
# $x509_crl - value corresponding to openssl's X509_CRL structure
#
# returns: no return value
  • PEM_get_string_X509_REQ โ€” converts the X509_REQ object $x509_crl into a PEM formatted string.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before ๐Ÿ™ˆ

โ€ฆand the last lines of that example are literally:

Net::SSLeay::PEM_get_string_X509_REQ($x509_req);
# $x509_req - value corresponding to openssl's X509_REQ structure
#
# returns: no return value

Bestie, no return value, don't go looking for one. ๐Ÿ’…


d2i_X509_bio

COMPATIBILITY: not available in Net-SSLeay-1.45 and before โœจ

Loads a DER formatted X509 certificate through the BIO structure you hand it. That's it, that's the whole job.

my $rv = Net::SSLeay::d2i_X509_bio($bp);
# $bp - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509 structure (0 on failure)

Example, because seeing it is believing:

my $bio = Net::SSLeay::BIO_new_file($filename, 'rb');
my $x509 = Net::SSLeay::d2i_X509_bio($bio);
Net::SSLeay::BIO_free($bio);

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/d2i_X509.html>

d2i_X509_CRL_bio

COMPATIBILITY: not available in Net-SSLeay-1.45 and before โœจ

Loads a DER formatted X509_CRL object via the given BIO structure. Revocation lists, but make it DER.

my $rv = Net::SSLeay::d2i_X509_CRL_bio($bp);
# $bp - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509_CRL structure (0 on failure)

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'rb');
my $x509_crl = Net::SSLeay::d2i_X509_CRL_bio($bio);
Net::SSLeay::BIO_free($bio);

d2i_X509_REQ_bio

COMPATIBILITY: not available in Net-SSLeay-1.45 and before โœจ

Loads a DER formatted X509_REQ object via the given BIO structure. Certificate signing requests, decoded and ready.

my $rv = Net::SSLeay::d2i_X509_REQ_bio($bp);
# $bp - value corresponding to openssl's BIO structure
#
# returns: value corresponding to openssl's X509_REQ structure (0 on failure)

Example:

my $bio = Net::SSLeay::BIO_new_file($filename, 'rb');
my $x509_req = Net::SSLeay::d2i_X509_REQ_bio($bio);
Net::SSLeay::BIO_free($bio);

P_PKCS12_load_file

COMPATIBILITY: not available in Net-SSLeay-1.45 and before โœจ

Loads the X509 certificate + private key + the certificates of the CA chain (if they're actually in the PKCS12 file, iykyk). It's giving "one file to rule them all". ๐Ÿ‘‘

my ($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename, $load_chain, $password);
# $filename - name of PKCS12 file
# $load_chain - [optional] whether load (1) or not(0) CA chain (default: 0)
# $password - [optional] password for private key
#
# returns: triplet ($privkey, $cert, @cachain)
#          $privkey - value corresponding to openssl's EVP_PKEY structure
#          $cert - value corresponding to openssl's X509 structure
#          @cachain - array of values corresponding to openssl's X509 structure (empty if no CA chain in PKCS12)
IMPORTANT NOTE: after you do the job you need to call X509_free() on $privkey + all members of @cachain and EVP_PKEY_free() on $privkey. Cleanup is not optional, bestie, that's how you avoid looking a mess. ๐Ÿงš

Examples:

my ($privkey, $cert) = Net::SSLeay::P_PKCS12_load_file($filename);
# or
my ($privkey, $cert) = Net::SSLeay::P_PKCS12_load_file($filename, 0, $password);
# or
my ($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename, 1);
# or
my ($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename, 1, $password);

# BEWARE: THIS IS WRONG - MEMORY LEAKS! (you cannot free @cachain items)
my ($privkey, $cert) = Net::SSLeay::P_PKCS12_load_file($filename, 1, $password);

Okay that last one โ€” read it again. You asked for the chain (1) but only caught two values, so the @cachain items are just floating in the void and you literally cannot free them. Memory leak behavior, not cute. ๐Ÿ’€

NOTE Net::SSLeay 1.92_01 and earlier: with some combinations of Windows, perl, compiler and compiler options, you may see a runtime error "no OPENSSL_Applink", when calling Net::SSLeay::P_PKCS12_load_file. See README.Win32 for more details.


d2i_SSL_SESSION

COMPATIBILITY: does not work in Net-SSLeay-1.85 and before

Transforms the binary ASN1 representation string of an SSL/TLS session into an SSL_SESSION object. Glow-up, but for bytes. โœจ

my $ses = Net::SSLeay::d2i_SSL_SESSION($data);
# $data - the session as ASN1 representation string
#
# returns: $ses - the new SSL_SESSION

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/i2d_SSL_SESSION.html>

i2d_SSL_SESSION

COMPATIBILITY: does not work in Net-SSLeay-1.85 and before

Transforms the SSL_SESSION object in into the ASN1 representation and returns it as string. (Yes, "in into", the original said it and we respect the original. ๐Ÿซถ)

my $data = Net::SSLeay::i2d_SSL_SESSION($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: $data - session as string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/d2i_SSL_SESSION.html>

SESSION_new

Creates a new SSL_SESSION structure. Fresh session, fresh vibes. ๐ŸŒธ

my $rv = Net::SSLeay::SESSION_new();
#
# returns: value corresponding to openssl's SSL_SESSION structure (0 on failure)

SESSION_free

Free an allocated SSL_SESSION structure. The responsible thing to do, so do it.

Net::SSLeay::SESSION_free($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_free.html>

SESSION_up_ref

COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0-pre4 or LibreSSL 2.7.0

Increases the reference counter on a SSL_SESSION structure. Keeping it alive, main character energy. ๐Ÿ‘‘

Net::SSLeay::SESSION_up_ref($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success else 0

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_up_ref.html>

SESSION_dup

COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL

Duplicates a SSL_SESSION structure. Twin behavior. ๐ŸŽ€

Net::SSLeay::SESSION_dup($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: the duplicated session

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_dup.html>

SESSION_is_resumable

COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL

Determine whether an SSL_SESSION object can be used for resumption. A vibe check, but for sessions. ๐Ÿ”ฅ

Net::SSLeay::SESSION_is_resumable($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: (integer) 1 if it can or 0 if not

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_is_resumable.html>

SESSION_cmp

Compare two SSL_SESSION structures. Compatibility check, but make it cryptographic.

my $rv = Net::SSLeay::SESSION_cmp($sesa, $sesb);
# $sesa - value corresponding to openssl's SSL_SESSION structure
# $sesb - value corresponding to openssl's SSL_SESSION structure
#
# returns: 0 if the two structures are the same

NOTE: Not available in openssl 1.0 or later

SESSION_get_app_data

Can be used to get application defined value/data.

my $rv = Net::SSLeay::SESSION_get_app_data($ses);
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: string/buffer/pointer ???

The ??? is doing a lot of heavy lifting there and honestly, same. ๐Ÿซถ

SESSION_set_app_data

Can be used to set some application defined value/data.

my $rv = Net::SSLeay::SESSION_set_app_data($s, $a);
# $s - value corresponding to openssl's SSL_SESSION structure
# $a - (string/buffer/pointer ???) data
#
# returns: ???

SESSION_get_ex_data

Is used to retrieve the information for $idx from session $ses.

my $rv = Net::SSLeay::SESSION_get_ex_data($ses, $idx);
# $ses - value corresponding to openssl's SSL_SESSION structure
# $idx - (integer) index for application specific data
#
# returns: pointer to ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_ex_new_index.html>

SESSION_set_ex_data

Is used to store application data at arg for idx into the session object.

my $rv = Net::SSLeay::SESSION_set_ex_data($ss, $idx, $data);
# $ss - value corresponding to openssl's SSL_SESSION structure
# $idx - (integer) ???
# $data - (pointer) ???
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_ex_new_index.html>

SESSION_get_ex_new_index

Is used to register a new index for application specific data.

my $rv = Net::SSLeay::SESSION_get_ex_new_index($argl, $argp, $new_func, $dup_func, $free_func);
# $argl - (long) ???
# $argp - (pointer) ???
# $new_func - function pointer ??? (CRYPTO_EX_new *)
# $dup_func - function pointer ??? (CRYPTO_EX_dup *)
# $free_func - function pointer ??? (CRYPTO_EX_free *)
#
# returns: (integer) ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_ex_new_index.html>

SESSION_get_master_key

NOTE: Does not exactly correspond to any low level API function

Returns 'master_key' value from SSL_SESSION structure $s. The master key, the moment, the icon. ๐Ÿ”‘

Net::SSLeay::SESSION_get_master_key($s);
# $s - value corresponding to openssl's SSL_SESSION structure
#
# returns: master key (binary data)

SESSION_set1_master_key

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL

Sets the master key value associated with a SSL_SESSION.

my $ret = Net::SSLeay::SESSION_set1_master_key($sess, $key);
# $sess - value corresponding to OpenSSL SSL_SESSION structure
# $key - PSK key in packed binary format
#
# returns: 1 on success, 0 on failure

Example:

my $key = pack('H*', 'deadbeef');
my $ret = Net::SSLeay::SESSION_set1_master_key($sess, $key);

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_set1_master_key.html>

SESSION_set_master_key

Sets 'master_key' value for SSL_SESSION structure $s

Net::SSLeay::SESSION_set_master_key($s, $key);
# $s - value corresponding to openssl's SSL_SESSION structure
# $key - master key (binary data)
#
# returns: no return value
Not available with OpenSSL 1.1 and later. Code that previously used SESSION_set_master_key must now set $secret in the session_secret callback set with SSL_set_session_secret_cb.
  • SESSION_set_cipher โ€” okay so this one sets the ciphersuite that's chillin' with an SSL_SESSION. ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL

my $ret = Net::SSLeay::SESSION_set_cipher($s, $cipher);
# $s - value corresponding to OpenSSL SSL_SESSION structure
# $cipher - value corresponding to OpenSSL SSL_CIPHER structure
#
# returns: 1 on success, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_set_cipher.html

  • SESSION_set_protocol_version โ€” sets the protocol version tied to an SSL_SESSION. bestie pls note the version has to be an integer constant, like the iconic Net::SSLeay::TLS1_3_VERSION(). โœจ

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL

my $ret = Net::SSLeay::SESSION_set_protocol_version($s, $version);
# $s - value corresponding to OpenSSL SSL_SESSION structure
# $version - integer version constant. For example Net::SSLeay::TLS1_3_VERSION()
#
# returns: 1 on success, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_set_protocol_version.html

  • SESSION_get0_cipher โ€” grabs the value corresponding to OpenSSL's SSL_CIPHER that's hanging out with an SSL_SESSION. ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.0 or LibreSSL 3.4.0

my $ret = Net::SSLeay::SESSION_get0_cipher($s);
# $s - value corresponding to OpenSSL SSL_SESSION structure
#
# returns: A value corresponding to OpenSSL's SSL_CIPHER structure or undef if SSL_CIPHER can't be determined.

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get0_cipher.html

  • SESSION_get_time โ€” returns the time the session s was established, in seconds since 1.1.1970. it's giving very unix timestamp core. โฐ
my $rv = Net::SSLeay::SESSION_get_time($s);
# $s - value corresponding to openssl's SSL_SESSION structure
#
# returns: timestamp (seconds since 1.1.1970)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_time.html

  • get_time โ€” technically the same functionality as SESSION_get_time. literally twins. ๐Ÿ‘ฏ
my $rv = Net::SSLeay::get_time($s);
  • SESSION_get_timeout โ€” returns the timeout value that's been set for session $s, in seconds. ๐ŸŽ€
my $rv = Net::SSLeay::SESSION_get_timeout($s);
# $s - value corresponding to openssl's SSL_SESSION structure
#
# returns: timeout (in seconds)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_time.html

  • get_timeout โ€” technically the same functionality as SESSION_get_timeout. same vibe, shorter name. ๐Ÿ’ซ
my $rv = Net::SSLeay::get_timeout($s);
  • SESSION_print โ€” prints all the session deets (protocol version, cipher, session-id, the whole look ๐Ÿ‘‘) out to a BIO.

NOTE: Does not exactly correspond to any low level API function

my $rv = Net::SSLeay::SESSION_print($fp, $ses);
# $fp - value corresponding to openssl's BIO structure
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success, 0 on failure

so like, you do have to pull up the necessary BIO functions yourself, a lil something like this:

# let us have $ssl corresponding to openssl's SSL structure
my $ses = Net::SSLeay::get_session($ssl);
my $bio = Net::SSLeay::BIO_new(&Net::SSLeay::BIO_s_mem);
Net::SSLeay::SESSION_print($bio, $ses);
print Net::SSLeay::BIO_read($bio);
  • SESSION_print_fp โ€” prints those same session deets (protocol version, cipher, session-id, etc.) straight to a file handle. ๐Ÿ“

NOTE With some combinations of Windows, perl, compiler and compiler options, you may see a runtime error "no OPENSSL_Applink", when calling Net::SSLeay::SESSION_print_fp. See README.Win32 for more details.

my $rv = Net::SSLeay::SESSION_print_fp($fp, $ses);
# $fp - perl file handle
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success, 0 on failure

Example, because a demo just hits different:

# let us have $ssl corresponding to openssl's SSL structure
my $ses = Net::SSLeay::get_session($ssl);
open my $fh, ">", "output.txt";
Net::SSLeay::SESSION_print_fp($fh,$ses);

Similar functionality without Net::SSLeay::SESSION_print_fp:

my $ses = Net::SSLeay::get_session($ssl);
my $bio = Net::SSLeay::BIO_new_file('output.txt', 'w');
Net::SSLeay::SESSION_print($bio, $ses);
  • SESSION_set_time โ€” swaps out the creation time of session s for the value you picked, $t (seconds since 1.1.1970). time travel but make it TLS. ๐Ÿ•ฐ๏ธ
my $rv = Net::SSLeay::SESSION_set_time($ses, $t);
# $ses - value corresponding to openssl's SSL_SESSION structure
# $t - time value
#
# returns: 1 on success

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_time.html

  • set_time โ€” technically the same functionality as SESSION_set_time. ๐Ÿ’–
my $rv = Net::SSLeay::set_time($ses, $t);
  • SESSION_set_timeout โ€” sets the timeout value for session s to $t, in seconds.
my $rv = Net::SSLeay::SESSION_set_timeout($s, $t);
# $s - value corresponding to openssl's SSL_SESSION structure
# $t - timeout (in seconds)
#
# returns: 1 on success

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_SESSION_get_time.html

  • set_timeout โ€” technically the same functionality as SESSION_set_timeout. yes, again, iconic behaviour. โœจ
my $rv = Net::SSLeay::set_timeout($ses, $t);

NOTE: Please note that the function described in this chapter have "SSL_" part stripped from their original openssl names. so like SSL_CTX_add_session shows up here as CTX_add_session, yk? just be aware. ๐Ÿซถ
  • CTX_add_client_CA โ€” takes the CA name it extracted from $cacert and adds it to the list of CAs that get sent to the client when it's requesting a client certificate for $ctx.
my $rv = Net::SSLeay::CTX_add_client_CA($ctx, $cacert);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $cacert - value corresponding to openssl's X509 structure
#
# returns: 1 on success, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_CA_list.html

  • CTX_add_extra_chain_cert โ€” adds certificate $x509 to the certificate chain that gets presented along with the certificate. and bestie, you can stack several certs by adding them one after the other. ๐Ÿงš
my $rv = Net::SSLeay::CTX_add_extra_chain_cert($ctx, $x509);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $x509 - value corresponding to openssl's X509 structure
#
# returns: 1 on success, check out the error stack to find out the reason for failure otherwise

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_add_extra_chain_cert.html

  • CTX_add_session โ€” adds the session $ses to the context $ctx. simple as that, no notes. ๐Ÿ’…
my $rv = Net::SSLeay::CTX_add_session($ctx, $ses);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_add_session.html

  • CTX_callback_ctrl โ€” ??? (more info needed) ๐Ÿ˜ญ honestly the source says it, we're just relaying it, no cap.
my $rv = Net::SSLeay::CTX_callback_ctrl($ctx, $cmd, $fp);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $cmd - (integer) command id
# $fp - (function pointer) ???
#
# returns: ???

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_ctrl.html

  • CTX_check_private_key โ€” vibe-checks that the private key actually matches the certificate loaded into $ctx. consistency is key (literally). ๐Ÿ”‘
my $rv = Net::SSLeay::CTX_check_private_key($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • CTX_ctrl โ€” internal handling function for SSL_CTX objects.
BEWARE: openssl doc says: This function should never be called directly! for real, do not come for this one directly, it's giving "do not touch, this is not for you". ๐Ÿ’€
my $rv = Net::SSLeay::CTX_ctrl($ctx, $cmd, $larg, $parg);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $cmd - (integer) command id
# $larg - (integer) long ???
# $parg - (string/pointer) ???
#
# returns: (long) result of given command ???

โ€ฆand the big list of valid $cmd values just keeps going, bestie, so here's the rest of it in all its glory. No notes, just vibes and a whole lot of constants ๐Ÿ’…

# valid $cmd values
# 1 - SSL_CTRL_NEED_TMP_RSA
# 2 - SSL_CTRL_SET_TMP_RSA
# 3 - SSL_CTRL_SET_TMP_DH
# 4 - SSL_CTRL_SET_TMP_ECDH
# 5 - SSL_CTRL_SET_TMP_RSA_CB
# 6 - SSL_CTRL_SET_TMP_DH_CB
# 7 - SSL_CTRL_SET_TMP_ECDH_CB
# 8 - SSL_CTRL_GET_SESSION_REUSED
# 9 - SSL_CTRL_GET_CLIENT_CERT_REQUEST
# 10 - SSL_CTRL_GET_NUM_RENEGOTIATIONS
# 11 - SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS
# 12 - SSL_CTRL_GET_TOTAL_RENEGOTIATIONS
# 13 - SSL_CTRL_GET_FLAGS
# 14 - SSL_CTRL_EXTRA_CHAIN_CERT
# 15 - SSL_CTRL_SET_MSG_CALLBACK
# 16 - SSL_CTRL_SET_MSG_CALLBACK_ARG
# 17 - SSL_CTRL_SET_MTU
# 20 - SSL_CTRL_SESS_NUMBER
# 21 - SSL_CTRL_SESS_CONNECT
# 22 - SSL_CTRL_SESS_CONNECT_GOOD
# 23 - SSL_CTRL_SESS_CONNECT_RENEGOTIATE
# 24 - SSL_CTRL_SESS_ACCEPT
# 25 - SSL_CTRL_SESS_ACCEPT_GOOD
# 26 - SSL_CTRL_SESS_ACCEPT_RENEGOTIATE
# 27 - SSL_CTRL_SESS_HIT
# 28 - SSL_CTRL_SESS_CB_HIT
# 29 - SSL_CTRL_SESS_MISSES
# 30 - SSL_CTRL_SESS_TIMEOUTS
# 31 - SSL_CTRL_SESS_CACHE_FULL
# 32 - SSL_CTRL_OPTIONS
# 33 - SSL_CTRL_MODE
# 40 - SSL_CTRL_GET_READ_AHEAD
# 41 - SSL_CTRL_SET_READ_AHEAD
# 42 - SSL_CTRL_SET_SESS_CACHE_SIZE
# 43 - SSL_CTRL_GET_SESS_CACHE_SIZE
# 44 - SSL_CTRL_SET_SESS_CACHE_MODE
# 45 - SSL_CTRL_GET_SESS_CACHE_MODE
# 50 - SSL_CTRL_GET_MAX_CERT_LIST
# 51 - SSL_CTRL_SET_MAX_CERT_LIST
# 52 - SSL_CTRL_SET_MAX_SEND_FRAGMENT
# 53 - SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
# 54 - SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
# 55 - SSL_CTRL_SET_TLSEXT_HOSTNAME
# 56 - SSL_CTRL_SET_TLSEXT_DEBUG_CB
# 57 - SSL_CTRL_SET_TLSEXT_DEBUG_ARG
# 58 - SSL_CTRL_GET_TLSEXT_TICKET_KEYS
# 59 - SSL_CTRL_SET_TLSEXT_TICKET_KEYS
# 60 - SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT
# 61 - SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB
# 62 - SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG
# 63 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
# 64 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG
# 65 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE
# 66 - SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS
# 67 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS
# 68 - SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS
# 69 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS
# 70 - SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP
# 71 - SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP
# 72 - SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
# 73 - DTLS_CTRL_GET_TIMEOUT
# 74 - DTLS_CTRL_HANDLE_TIMEOUT
# 75 - DTLS_CTRL_LISTEN
# 76 - SSL_CTRL_GET_RI_SUPPORT
# 77 - SSL_CTRL_CLEAR_OPTIONS
# 78 - SSL_CTRL_CLEAR_MODE

# 82 - SSL_CTRL_GET_EXTRA_CHAIN_CERTS
# 83 - SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS

# 88 - SSL_CTRL_CHAIN
# 89 - SSL_CTRL_CHAIN_CERT

# 90 - SSL_CTRL_GET_CURVES
# 91 - SSL_CTRL_SET_CURVES
# 92 - SSL_CTRL_SET_CURVES_LIST
# 93 - SSL_CTRL_GET_SHARED_CURVE
# 94 - SSL_CTRL_SET_ECDH_AUTO
# 97 - SSL_CTRL_SET_SIGALGS
# 98 - SSL_CTRL_SET_SIGALGS_LIST
# 99 - SSL_CTRL_CERT_FLAGS
# 100 - SSL_CTRL_CLEAR_CERT_FLAGS
# 101 - SSL_CTRL_SET_CLIENT_SIGALGS
# 102 - SSL_CTRL_SET_CLIENT_SIGALGS_LIST
# 103 - SSL_CTRL_GET_CLIENT_CERT_TYPES
# 104 - SSL_CTRL_SET_CLIENT_CERT_TYPES
# 105 - SSL_CTRL_BUILD_CERT_CHAIN
# 106 - SSL_CTRL_SET_VERIFY_CERT_STORE
# 107 - SSL_CTRL_SET_CHAIN_CERT_STORE
# 108 - SSL_CTRL_GET_PEER_SIGNATURE_NID
# 109 - SSL_CTRL_GET_SERVER_TMP_KEY
# 110 - SSL_CTRL_GET_RAW_CIPHERLIST
# 111 - SSL_CTRL_GET_EC_POINT_FORMATS
# 112 - SSL_CTRL_GET_TLSA_RECORD
# 113 - SSL_CTRL_SET_TLSA_RECORD
# 114 - SSL_CTRL_PULL_TLSA_RECORD

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_ctrl.html>

  • CTX_flush_sessions โ€” takes a little stroll through the session cache of $ctx and yeets out everything that expired at time $tm. Spring cleaning but for sessions โœจ
Net::SSLeay::CTX_flush_sessions($ctx, $tm);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $tm - specifies the time which should be used for the expiration test (seconds since 1.1.1970)
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_flush_sessions.html>

  • CTX_free โ€” frees an allocated SSL_CTX object. Like, actually release it, bestie, don't just ghost it ๐Ÿ˜ญ
Net::SSLeay::CTX_free($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_free.html>

  • CTX_get_app_data โ€” lets you grab whatever application-defined value/data you stashed in there. Your data, your rules ๐Ÿ’…
my $rv = Net::SSLeay::CTX_get_app_data($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: string/buffer/pointer ???
  • CTX_set_app_data โ€” the flip side: stash some application-defined value/data in there for later. Little treat for future-you ๐ŸŽ€
my $rv = Net::SSLeay::CTX_set_app_data($ctx, $arg);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $arg - (string/buffer/pointer ???) data
#
# returns: ???
  • CTX_get0_param โ€” hands you back the current verification parameters. Iconic little accessor.
COMPATIBILITY tea โ˜•: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0
my $vpm = Net::SSLeay::CTX_get0_param($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's X509_VERIFY_PARAM structure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get0_param.html>

  • CTX_get_cert_store โ€” returns the current certificate verification storage. The vault where the trust lives ๐Ÿ—๏ธ
my $rv = Net::SSLeay::CTX_get_cert_store($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's X509_STORE structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cert_store.html>

  • CTX_get_client_CA_list โ€” returns the list of client CAs that were explicitly set for $ctx using CTX_set_client_CA_list. Receipts, basically ๐Ÿงพ
my $rv = Net::SSLeay::CTX_get_client_CA_list($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's X509_NAME_STACK structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_client_CA_list.html>

  • CTX_get_ex_data โ€” retrieves the info stored at index $idx from $ctx. Find your stuff by its little index number ๐Ÿ”
my $rv = Net::SSLeay::CTX_get_ex_data($ssl, $idx);
# $ssl - value corresponding to openssl's SSL_CTX structure
# $idx - (integer) index for application specific data
#
# returns: pointer to ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_ex_new_index.html>

  • CTX_get_ex_new_index โ€” registers a brand-new index for application specific data. Claim your slot, bestie, it's yours now โœจ
my $rv = Net::SSLeay::CTX_get_ex_new_index($argl, $argp, $new_func, $dup_func, $free_func);
# $argl - (long) ???
# $argp - (pointer) ???
# $new_func - function pointer ??? (CRYPTO_EX_new *)
# $dup_func - function pointer ??? (CRYPTO_EX_dup *)
# $free_func - function pointer ??? (CRYPTO_EX_free *)
#
# returns: (integer) ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_ex_new_index.html>

  • CTX_get_mode โ€” returns the mode that's set for ctx, as a bitmask. Decoding time, iykyk ๐Ÿ•ต๏ธโ€โ™€๏ธ
my $rv = Net::SSLeay::CTX_get_mode($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: mode (bitmask)

# to decode the return value (bitmask) use:
# 0x00000001 corresponds to SSL_MODE_ENABLE_PARTIAL_WRITE
# 0x00000002 corresponds to SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
# 0x00000004 corresponds to SSL_MODE_AUTO_RETRY
# 0x00000008 corresponds to SSL_MODE_NO_AUTO_CHAIN
# 0x00000010 corresponds to SSL_MODE_RELEASE_BUFFERS
# (note: some of the bits might not be supported by older openssl versions)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_mode.html>

  • CTX_set_mode โ€” adds the mode passed in as the $mode bitmask to $ctx. Important: options that were already set before do not get cleared, she just adds ๐ŸŒธ
my $rv = Net::SSLeay::CTX_set_mode($ctx, $mode);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $mode - mode bitmask
#
# returns: the new mode bitmask after adding $mode

For the bitmask details, scroll up to CTX_get_mode (above) ๐Ÿ’–

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_mode.html>

  • CTX_get_options โ€” returns the options (bitmask) that are set for $ctx.
my $rv = Net::SSLeay::CTX_get_options($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: options (bitmask)
BEWARE: โš ๏ธ the available constants and their values in the bitmask depend on the TLS library. For example, SSL_OP_NO_TLSv1_3 became available much later than SSL_OP_NO_COMPRESS, which is already deprecated by some libraries. Also, some previously used option values have been recycled and are now used for newer options. See the list of constants in this document for the options Net::SSLeay currently supports.

You are strongly encouraged to check your TLS library if you need to use numeric values directly. The following is a sample of historic values โ€” it may not be correct anymore, so do not come for me if it's off ๐Ÿ™ˆ

# to decode the return value (bitmask) use:
# 0x00000004 corresponds to SSL_OP_LEGACY_SERVER_CONNECT
# 0x00000800 corresponds to SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
# 0x00004000 corresponds to SSL_OP_NO_TICKET
# 0x00010000 corresponds to SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
# 0x00400000 corresponds to SSL_OP_CIPHER_SERVER_PREFERENCE
# 0x04000000 corresponds to SSL_OP_NO_TLSv1

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_options.html>

  • CTX_set_options โ€” this one adds the options in the $options bitmask to $ctx. Key word being adds bestie โ€” anything already set stays set, nothing gets cleared. It's giving "the more the merrier" energy ๐Ÿ’…
Net::SSLeay::CTX_set_options($ctx, $options);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $options - options bitmask
#
# returns: the new options bitmask after adding $options

For all the bitmask deets go peek at "CTX_get_options" up above โฌ†๏ธ it's literally right there.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html>

  • CTX_get_quiet_shutdown โ€” hands you back the 'quiet shutdown' setting of $ctx. That's the whole vibe check ๐Ÿฆ‹
my $rv = Net::SSLeay::CTX_get_quiet_shutdown($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: (integer) the current setting

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html>

  • CTX_get_read_ahead โ€” reads out the read_ahead value for $ctx, no thoughts just vibes โœจ
my $rv = Net::SSLeay::CTX_get_read_ahead($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: (integer) read_ahead value
  • CTX_get_session_cache_mode โ€” returns whichever cache mode is currently in use, as a bitmask ๐ŸŽ€
my $rv = Net::SSLeay::CTX_get_session_cache_mode($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: mode (bitmask)
BEWARE: SESS_CACHE_OFF and the other constants are not available in Net-SSLeay-1.82 and before. If the constants aren't there, the values below have historically been correct. You are strongly encouraged to check your TLS library for the current values. Like, actually check, bestie, don't just trust me on this one ๐Ÿ™ˆ
# to decode the return value (bitmask) use:
# 0x0000 corresponds to SSL_SESS_CACHE_OFF
# 0x0001 corresponds to SSL_SESS_CACHE_CLIENT
# 0x0002 corresponds to SSL_SESS_CACHE_SERVER
# 0x0080 corresponds to SSL_SESS_CACHE_NO_AUTO_CLEAR
# 0x0100 corresponds to SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
# 0x0200 corresponds to SSL_SESS_CACHE_NO_INTERNAL_STORE
# (note: some of the bits might not be supported by older openssl versions)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_cache_mode.html>

  • CTX_set_session_cache_mode โ€” turns session caching on/off by setting the operational mode for $ctx to $mode. Slay, caching enabled ๐Ÿ’–
my $rv = Net::SSLeay::CTX_set_session_cache_mode($ctx, $mode);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $mode - mode (bitmask)
#
# returns: previously set cache mode

For the bitmask goodies see "CTX_get_session_cache_mode" (above, literally the previous bullet, iykyk).

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_cache_mode.html>

  • CTX_get_timeout โ€” gives you back the timeout value that's currently set for $ctx โฐ
my $rv = Net::SSLeay::CTX_get_timeout($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: timeout in seconds

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_timeout.html>

  • CTX_get_verify_depth โ€” returns the verification depth limit currently set in $ctx. And if nobody ever explicitly set one? You get -1 back and the default value gets used instead. Sneaky but iconic ๐Ÿงš
my $rv = Net::SSLeay::CTX_get_verify_depth($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: depth limit currently set in $ctx, -1 if no limit has been explicitly set

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_verify_mode.html>

  • CTX_get_verify_mode โ€” returns the verification mode (bitmask, ofc) currently set in $ctx ๐ŸŒธ
my $rv = Net::SSLeay::CTX_get_verify_mode($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: mode (bitmask)

For bitmask details see "CTX_set_verify" โ€” it's the very next bullet, we love a forward reference ๐Ÿ’…

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_verify_mode.html>

  • CTX_set_verify โ€” sets the verification flags for $ctx to $mode and tells it which verify_callback function to use. Main character energy for your cert checking ๐Ÿ‘‘
Net::SSLeay::CTX_set_verify($ctx, $mode, $callback);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $mode - mode (bitmask), see OpenSSL manual
# $callback - [optional] reference to perl callback function
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html>

  • CTX_set_post_handshake_auth โ€” adds the Post-Handshake Authentication extension to the ClientHello so the server can request post-handshake authentication. Very "you may ask me for credentials later" of it ๐Ÿซถ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL โ€” check before you commit, bestie ๐Ÿ˜ญ
Net::SSLeay::CTX_set_posthandshake_auth($ctx, $val);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $val - 0 then the extension is not sent, otherwise it is
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_post_handshake_auth.html>

  • CTX_load_verify_locations โ€” tells $ctx where the CA certs for verification live. Anything findable via $CAfile and $CApath gets trusted ๐Ÿ”ฅ
my $rv = Net::SSLeay::CTX_load_verify_locations($ctx, $CAfile, $CApath);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $CAfile - (string) file of CA certificates in PEM format, the file can contain several CA certificates (or '')
# $CApath - (string) directory containing CA certificates in PEM format (or '')
#
# returns: 1 on success, 0 on failure (check the error stack to find out the reason)

Both of those can be '', bestie, in case you were wondering โœจ

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html>

  • CTX_need_tmp_RSA โ€” just returns the result of "SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)". That's the whole thing, no cap ๐Ÿ’€
my $rv = Net::SSLeay::CTX_need_tmp_RSA($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: result of SSL_CTRL_NEED_TMP_RSA command
Not available with OpenSSL 1.1 and later. Gone, retired, we don't talk about her anymore ๐Ÿ™ˆ
  • CTX_new โ€” literally the same as "CTX_v23_new". That's it, that's the function ๐Ÿฆ‹
my $rv = Net::SSLeay::CTX_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

Not available with OpenSSL 1.1 and later. ๐Ÿ˜ญ
  • CTX_v2_new โ€” creates a brand new SSL_CTX object, based on SSLv2_method(), as the framework for establishing TLS/SSL enabled connections โœจ
my $rv = Net::SSLeay::CTX_v2_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_v23_new โ€” creates a new SSL_CTX object, this time based on SSLv23_method(), as the framework for establishing TLS/SSL enabled connections. The flexible one, we stan ๐ŸŒˆ
my $rv = Net::SSLeay::CTX_v23_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_v3_new โ€” creates a new SSL_CTX object based on SSLv3_method(), as the framework for establishing TLS/SSL enabled connections ๐ŸŽ€
my $rv = Net::SSLeay::CTX_v3_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_tlsv1_new โ€” creates a new SSL_CTX object based on TLSv1_method(), as a framework for establishing connections using TLSv1 ๐Ÿ’œ
COMPATIBILITY: Requires OpenSSL or LibreSSL built with support for TLSv1.
my $rv = Net::SSLeay::CTX_tlsv1_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_tlsv1_1_new โ€” creates a new SSL_CTX object based on TLSv1_1_method(), as a framework for establishing connections using TLSv1.1 ๐ŸŒธ
COMPATIBILITY: Requires OpenSSL >= 1.0.1 or LibreSSL built with support for TLSv1.1.
my $rv = Net::SSLeay::CTX_tlsv1_1_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_tlsv1_2_new โ€” creates a new SSL_CTX object based on TLSv1_2_method(), as a framework for establishing connections using TLSv1.2. The people's champ tbh ๐Ÿ‘‘
COMPATIBILITY: Requires OpenSSL >= 1.0.1 or LibreSSL built with support for TLSv1.2.
my $rv = Net::SSLeay::CTX_tlsv1_2_new();
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
  • CTX_new_with_method โ€” creates a new SSL_CTX object based on whatever $meth method you hand it. Build-your-own-CTX energy ๐Ÿงš
my $rv = Net::SSLeay::CTX_new_with_method($meth);
# $meth - value corresponding to openssl's SSL_METHOD structure
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)
# example
my $ctx = Net::SSLeay::CTX_new_with_method(&Net::SSLeay::TLSv1_method);

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_new.html>

  • CTX_set_min_proto_version, CTX_set_max_proto_version, set_min_proto_version and set_max_proto_version โ€” sets the minimum and maximum supported protocol for $ctx or $ssl. Yes that's four functions in one bullet, they're a package deal ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0-pre2 or LibreSSL 2.6.0
my $rv = Net::SSLeay::CTX_set_min_proto_version($ctx, $version);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $version - (integer) constant version value or 0 for automatic lowest or highest value
#
# returns: 1 on success, 0 on failure
# example: allow only TLS 1.2 for a SSL_CTX
my $rv_min = Net::SSLeay::CTX_set_min_proto_version($ctx, Net::SSLeay::TLS1_2_VERSION());
my $rv_max = Net::SSLeay::CTX_set_max_proto_version($ctx, Net::SSLeay::TLS1_2_VERSION());

# example: allow only TLS 1.1 for a SSL
my $rv_min = Net::SSLeay::set_min_proto_version($ssl, Net::SSLeay::TLS1_1_VERSION());
my $rv_max = Net::SSLeay::set_max_proto_version($ssl, Net::SSLeay::TLS1_1_VERSION());

Pass 0 as the $version and it auto-picks the lowest or highest value for you โ€” the lazy girl's dream, fr fr ๐Ÿ“

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_min_proto_version.html>

  • CTX_get_min_proto_version, CTX_get_max_proto_version, get_min_proto_version and get_max_proto_version โ€” bestie these four are the vibe check for which protocol versions your $ctx or $ssl will actually allow ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0g

Grabs the minimum and maximum supported protocol for $ctx or $ssl.

my $version = Net::SSLeay::CTX_get_min_proto_version($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: 0 automatic lowest or highest value, configured value otherwise

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_min_proto_version.html>

  • CTX_remove_session โ€” literally evicts the session $ses out of the context $ctx, bye babe ๐Ÿ‘‹
my $rv = Net::SSLeay::CTX_remove_session($ctx, $ses);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_add_session.html>

  • CTX_sess_accept โ€” the counter for started SSL/TLS handshakes in server mode โœจ
my $rv = Net::SSLeay::CTX_sess_accept($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of started SSL/TLS handshakes in server mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_accept_good โ€” how many SSL/TLS sessions actually got successfully established in server mode, the ones that ate and left no crumbs ๐ŸŽ€
my $rv = Net::SSLeay::CTX_sess_accept_good($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of successfully established SSL/TLS sessions in server mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_accept_renegotiate โ€” number of start renegotiations in server mode, lowkey chaotic but we count them anyway ๐ŸŒ€
my $rv = Net::SSLeay::CTX_sess_accept_renegotiate($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of start renegotiations in server mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_cache_full โ€” the sad little tally of sessions that got yeeted because the maximum session cache size was exceeded ๐Ÿ˜ญ
my $rv = Net::SSLeay::CTX_sess_cache_full($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of sessions that were removed because the maximum session cache size was exceeded

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_cb_hits โ€” how many sessions were successfully retrieved from the external session cache in server mode, icon behaviour ๐Ÿซถ
my $rv = Net::SSLeay::CTX_sess_cb_hits($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of successfully retrieved sessions from the external session cache in server mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_connect โ€” same energy as CTX_sess_accept but for client mode: number of started SSL/TLS handshakes ๐Ÿ’ซ
my $rv = Net::SSLeay::CTX_sess_connect($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of started SSL/TLS handshakes in client mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_connect_good โ€” successfully established SSL/TLS sessions, client mode edition โœจ
my $rv = Net::SSLeay::CTX_sess_connect_good($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of successfully established SSL/TLS sessions in client mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_connect_renegotiate โ€” number of start renegotiations in client mode, we're keeping receipts ๐Ÿงพ
my $rv = Net::SSLeay::CTX_sess_connect_renegotiate($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of start renegotiations in client mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_get_cache_size โ€” tells you the currently valid session cache size, no guessing needed ๐Ÿ’–
my $rv = Net::SSLeay::CTX_sess_get_cache_size($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: current size

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_cache_size.html>

  • CTX_sess_hits โ€” how many sessions got successfully reused, slay ๐Ÿ”ฅ
my $rv = Net::SSLeay::CTX_sess_hits($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of successfully reused sessions

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_misses โ€” sessions proposed by clients that were not found in the internal session cache in server mode, flop era ๐Ÿ’€
my $rv = Net::SSLeay::CTX_sess_misses($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of sessions proposed by clients that were not found in the internal session cache in server mode

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_number โ€” the current count of sessions chilling in the internal session cache ๐Ÿฆ‹
my $rv = Net::SSLeay::CTX_sess_number($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: current number of sessions in the internal session cache

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_set_cache_size โ€” sets the size of the internal session cache of context $ctx to $size, and it hands you back the previously valid size as a lil souvenir ๐ŸŽ
Net::SSLeay::CTX_sess_set_cache_size($ctx, $size);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $size - cache size (0 = unlimited)
#
# returns: previously valid size

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_cache_size.html>

  • CTX_sess_timeouts โ€” returns the number of sessions proposed by clients and either found in the internal or external session cache in server mode, but that were invalid due to timeout. These sessions are not included in the SSL_CTX_sess_hits count ๐Ÿ‘€ (yes, that's important, don't double-count them bestie)
my $rv = Net::SSLeay::CTX_sess_timeouts($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: number of sessions

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html>

  • CTX_sess_set_new_cb โ€” sets the callback function, which is automatically called whenever a new session was negotiated. Very "notify me when it happens" of it ๐Ÿ›Ž๏ธ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before
Net::SSLeay::CTX_sess_set_new_cb($ctx, $func);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $func - perl reference to callback function
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html>

  • CTX_sess_set_remove_cb โ€” sets the callback function, which is automatically called whenever a session is removed by the SSL engine. So you always know when one leaves the chat ๐Ÿšช
COMPATIBILITY: not available in Net-SSLeay-1.85 and before
Net::SSLeay::CTX_sess_set_remove_cb($ctx, $func);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $func - perl reference to callback function
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_remove_cb.html>

  • CTX_sessions โ€” returns a pointer to the lhash databases containing the internal session cache for ctx ๐Ÿ—‚๏ธ
my $rv = Net::SSLeay::CTX_sessions($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's LHASH structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sessions.html>

  • CTX_set1_param โ€” applies X509 verification parameters $vpm on $ctx, like a little settings glow-up for your verification ๐Ÿ’…
COMPATIBILITY: requires at least OpenSSL 1.0.0-beta3
my $rv = Net::SSLeay::CTX_set1_param($ctx, $vpm);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $vpm - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get0_param.html>

  • CTX_set_cert_store โ€” sets/replaces the certificate verification storage of $ctx to/with $store. Out with the old, in with the new โœจ
Net::SSLeay::CTX_set_cert_store($ctx, $store);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $store - value corresponding to openssl's X509_STORE structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cert_store.html>

  • CTX_set_cert_verify_callback โ€” sets the verification callback function for $ctx. SSL objects that are created from $ctx inherit the setting valid at the time when Net::SSLeay::new($ctx) is called ๐Ÿงฌ (so like, it's inherited, fr fr)
Net::SSLeay::CTX_set_cert_verify_callback($ctx, $func, $data);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $func - perl reference to callback function
# $data - [optional] data that will be passed to callback function when invoked
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cert_verify_callback.html>

  • CTX_set_cipher_list โ€” sets the list of available ciphers for $ctx using the control string $str. The list of ciphers is inherited by all ssl objects created from $ctx ๐Ÿ”
my $rv = Net::SSLeay::CTX_set_cipher_list($s, $str);
# $s - value corresponding to openssl's SSL_CTX structure
# $str - (string) cipher list e.g. '3DES:+RSA'
#
# returns: 1 if any cipher could be selected and 0 on complete failure

The format of $str is described in <https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html>

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cipher_list.html>

  • CTX_set_ciphersuites โ€” configure the available TLSv1.3 ciphersuites ๐Ÿ‘‘
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.4.0 and Net-SSLeay-1.94
  • CTX_set_ciphersuites โ€” sets the TLSv1.3 ciphersuite list for $ctx. The string is colon (:) separated and the order is the preference order, so put your faves first bestie ๐Ÿ’…
my $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, $str);
# $ctx  - value corresponding to openssl's SSL_CTX structure
# $str  - colon (":") separated list of TLSv1.3 ciphersuite names in order of preference
#
# returns: (integer) 1 if the requested ciphersuite list was configured, and 0 otherwise

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html โœจ

  • CTX_set_client_CA_list โ€” sets the list of CAs that get sent to the client when a client certificate is being requested for $ctx. it's giving "here's who I trust, pick from this" ๐ŸŽ€
Net::SSLeay::CTX_set_client_CA_list($ctx, $list);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $list - value corresponding to openssl's X509_NAME_STACK structure
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_CA_list.html

  • CTX_set_default_passwd_cb โ€” sets the default password callback, which is the little function that gets called when you're loading or storing an encrypted PEM certificate. your "hey what's the password" guy ๐Ÿ”‘
Net::SSLeay::CTX_set_default_passwd_cb($ctx, $func);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $func - perl reference to callback function
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_default_passwd_cb.html

  • CTX_set_default_passwd_cb_userdata โ€” sets a pointer to userdata that gets handed to that password callback whenever it's invoked. basically a little care package for your callback ๐Ÿซถ
Net::SSLeay::CTX_set_default_passwd_cb_userdata($ctx, $userdata);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $userdata - data that will be passed to callback function when invoked
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_default_passwd_cb.html

  • CTX_set_default_verify_paths โ€” ngl the docs literally say ??? (more info needed) so that's what we're working with ๐Ÿ˜ญ here's the signature tho:
my $rv = Net::SSLeay::CTX_set_default_verify_paths($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: 1 on success, 0 on failure
  • CTX_set_ex_data โ€” stores your application data at $data for $idx into the $ctx object. like a little drawer with an index label ๐Ÿ—„๏ธ
my $rv = Net::SSLeay::CTX_set_ex_data($ssl, $idx, $data);
# $ssl - value corresponding to openssl's SSL_CTX structure
# $idx - (integer) ???
# $data - (pointer) ???
#
# returns: 1 on success, 0 on failure

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_ex_new_index.html

  • CTX_set_purpose โ€” sets the purpose for $s. lowkey underrated.
my $rv = Net::SSLeay::CTX_set_purpose($s, $purpose);
# $s - value corresponding to openssl's SSL_CTX structure
# $purpose - (integer) purpose identifier
#
# returns: 1 on success, 0 on failure

# available purpose identifier
# 1 - X509_PURPOSE_SSL_CLIENT
# 2 - X509_PURPOSE_SSL_SERVER
# 3 - X509_PURPOSE_NS_SSL_SERVER
# 4 - X509_PURPOSE_SMIME_SIGN
# 5 - X509_PURPOSE_SMIME_ENCRYPT
# 6 - X509_PURPOSE_CRL_SIGN
# 7 - X509_PURPOSE_ANY
# 8 - X509_PURPOSE_OCSP_HELPER
# 9 - X509_PURPOSE_TIMESTAMP_SIGN

# or use corresponding constants
$purpose = &Net::SSLeay::X509_PURPOSE_SSL_CLIENT;
# ...
$purpose = &Net::SSLeay::X509_PURPOSE_TIMESTAMP_SIGN;

like, just use the constants, bestie, your future self will thank you ๐Ÿ’–

  • CTX_set_quiet_shutdown โ€” sets the "quiet shutdown" flag for $ctx to mode. and heads up: SSL objects created from $ctx inherit whatever mode is valid at the time Net::SSLeay::new($ctx) is called, so timing matters โฐ
Net::SSLeay::CTX_set_quiet_shutdown($ctx, $mode);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $mode - 0 or 1
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html

  • CTX_set_read_ahead โ€” sets the read_ahead value. plot twist: it returns the original value, not the new one ๐ŸŒ€
my $rv = Net::SSLeay::CTX_set_read_ahead($ctx, $val);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $val - read_ahead value to be set
#
# returns: the original read_ahead value
  • CTX_set_session_id_context โ€” sets the context $sid_ctx of length $sid_ctx_len within which a session can be reused for the $ctx object. iykyk ๐Ÿฆ‹
my $rv = Net::SSLeay::CTX_set_session_id_context($ctx, $sid_ctx, $sid_ctx_len);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $sid_ctx - data buffer
# $sid_ctx_len - length of data in $sid_ctx
#
# returns: 1 on success, 0 on failure (the error is logged to the error stack)

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_id_context.html

  • CTX_set_ssl_version โ€” sets a new default TLS/SSL method for SSL objects newly created from this $ctx. important caveat incoming: SSL objects you already made with Net::SSLeay::new($ctx) are not affected โ€” except when Net::SSLeay:clear($ssl) is being called. so like, don't assume your existing ones got the memo ๐Ÿ’€
my $rv = Net::SSLeay::CTX_set_ssl_version($ctx, $meth);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $meth - value corresponding to openssl's SSL_METHOD structure
#
# returns: 1 on success, 0 on failure

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ssl_version.html

  • CTX_set_timeout โ€” sets the timeout for newly created sessions for $ctx to $t. and $t must be in seconds, no minutes, no "just vibes" โณ
my $rv = Net::SSLeay::CTX_set_timeout($ctx, $t);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $t - timeout in seconds
#
# returns: previously set timeout value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_timeout.html

  • CTX_set_tmp_dh โ€” sets the DH parameters to be $dh. and the key gets inherited by every ssl object created from $ctx, so it ripples out ๐ŸŒŠ
my $rv = Net::SSLeay::CTX_set_tmp_dh($ctx, $dh);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $dh - value corresponding to openssl's DH structure
#
# returns: 1 on success, 0 on failure

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tmp_dh_callback.html

  • CTX_set_tmp_dh_callback โ€” sets the callback function for $ctx to $tmp_dh_callback, to be used when DH parameters are required.
Net::SSLeay::CTX_set_tmp_dh_callback($ctx, $tmp_dh_callback);
# $ctx - value corresponding to openssl's SSL_CTX structure
# tmp_dh_callback - (function pointer) ???
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tmp_dh_callback.html

  • CTX_set_tmp_rsa โ€” sets the temporary/ephemeral RSA key to be $rsa.
my $rv = Net::SSLeay::CTX_set_tmp_rsa($ctx, $rsa);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $rsa - value corresponding to openssl's RSA structure
#
# returns: 1 on success, 0 on failure

check the openssl doc at https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_tmp_rsa_callback.html

๐Ÿšจ not available with OpenSSL 1.1 and later. so if you're on anything modern, this one's a museum piece.
  • CTX_set_tmp_rsa_callback โ€” sets the callback function for ctx to $tmp_rsa_callback, used when a temporary/ephemeral RSA key is required.

and the docs literally ask ??? (does this function really work?) soโ€ฆ good luck bestie ๐Ÿ˜ญ๐Ÿ™ˆ

Net::SSLeay::CTX_set_tmp_rsa_callback($ctx, $tmp_rsa_callback);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $tmp_rsa_callback - (function pointer) ???
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_tmp_rsa_callback.html

๐Ÿšจ also not available with OpenSSL 1.1 and later.
  • CTX_set_trust โ€” the vibe check for trust, honestly.
my $rv = Net::SSLeay::CTX_set_trust($s, $trust);
# $s - value corresponding to openssl's SSL_CTX structure
# $trust - (integer) trust identifier
#
# returns: the original value

# available trust identifiers
# 1 - X509_TRUST_COMPAT
# 2 - X509_TRUST_SSL_CLIENT
# 3 - X509_TRUST_SSL_SERVER
# 4 - X509_TRUST_EMAIL
# 5 - X509_TRUST_OBJECT_SIGN
# 6 - X509_TRUST_OCSP_SIGN
# 7 - X509_TRUST_OCSP_REQUEST
# 8 - X509_TRUST_TSA

# or use corresponding constants
$trust = &Net::SSLeay::X509_TRUST_COMPAT;
# ...
$trust = &Net::SSLeay::X509_TRUST_TSA;
  • CTX_set_verify_depth โ€” sets the max depth allowed for certificate chain verification for ctx. keep your chains from going full infinite scroll ๐Ÿงš
Net::SSLeay::CTX_set_verify_depth($ctx, $depth);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $depth - max. depth
#
# returns: no return value

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html

  • CTX_use_PKCS12_file โ€” adds the certificate and private key from the PKCS12 file $p12filename to $ctx. one file, both things, slay ๐ŸŽ
my $rv = Net::SSLeay::CTX_use_PKCS12_file($ctx, $p12filename, $password);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $p12filename - (string) filename
# $password - (string) password to decrypt private key
#
# returns: 1 on success, 0 on failure
๐Ÿ“Œ NOTE Net::SSLeay 1.92_01 and earlier: with some combinations of Windows, perl, compiler and compiler options, you may see a runtime error "no OPENSSL_Applink" when calling Net::SSLeay::CTX_use_PKCS12_file. see README.Win32 for more details.
  • CTX_use_PrivateKey โ€” adds the private key $pkey to $ctx.
my $rv = Net::SSLeay::CTX_use_PrivateKey($ctx, $pkey);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • CTX_use_PrivateKey_file โ€” adds the first private key found in $file to $ctx. โœจ
  • CTX_use_PrivateKey_file โ€” drops the private key from a file into $ctx ๐ŸŽ€
my $rv = Net::SSLeay::CTX_use_PrivateKey_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • CTX_use_RSAPrivateKey โ€” adds the RSA private key $rsa to $ctx ๐Ÿ”‘
my $rv = Net::SSLeay::CTX_use_RSAPrivateKey($ctx, $rsa);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $rsa - value corresponding to openssl's RSA structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • CTX_use_RSAPrivateKey_file โ€” grabs the first RSA private key it finds in $file and adds it to $ctx ๐Ÿ’–
my $rv = Net::SSLeay::CTX_use_RSAPrivateKey_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason
  • CTX_use_certificate โ€” loads the certificate $x into $ctx ๐Ÿ“œ
my $rv = Net::SSLeay::CTX_use_certificate($ctx, $x);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $x - value corresponding to openssl's X509 structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • CTX_use_certificate_chain_file โ€” loads a whole certificate chain from $file into $ctx ๐ŸŒˆ lowkey the glow-up version of the previous one
okay so the ordering here is not a vibe suggestion, it's a rule fr fr: the certs have to be in PEM format and sorted starting with the subject's certificate (like, the actual client or server certificate), then any intermediate CA certificates if they apply, and finishing at the highest level (root) CA. Get the order wrong and it's giving chaos. ๐Ÿ’€
my $rv = Net::SSLeay::CTX_use_certificate_chain_file($ctx, $file);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $file - (string) file name
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • CTX_use_certificate_file โ€” loads the first certificate stored in $file into $ctx โœจ
my $rv = Net::SSLeay::CTX_use_certificate_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • CTX_get_security_level โ€” tells you the security level chillin' on $ctx ๐Ÿ›ก๏ธ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.6.0 and Net-SSLeay-1.94 โ€” yeah, both conditions, sorry bestie ๐Ÿ˜ญ
my $level = Net::SSLeay::CTX_get_security_level($ctx);
# $ctx   - value corresponding to openssl's SSL_CTX structure
#
# returns: (integer) current security level

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_security_level.html>

  • CTX_set_security_level โ€” sets the security level on $ctx to $level, main character move ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.6.0 and Net-SSLeay-1.94
Net::SSLeay::CTX_set_security_level($ctx, $level);
# $ssl   - value corresponding to openssl's SSL_CTX structure
# $level - new security level
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.html>

  • CTX_set_num_tickets โ€” sets how many TLSv1.3 session tickets get sent to a client ๐ŸŽŸ๏ธ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
my $rv = Net::SSLeay::CTX_set_num_tickets($ctx, $number_of_tickets);
# $ctx  - value corresponding to openssl's SSL_CTX structure
# $number_of_tickets - number of tickets to send
#
# returns: 1 on success, 0 on failure

Set it to zero if you don't want to support a session resumption, k? ๐Ÿšซ

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_num_tickets.html>

  • CTX_get_num_tickets โ€” peeks at how many TLSv1.3 session tickets would get sent to a client ๐Ÿ‘€
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
my $number_of_tickets = Net::SSLeay::CTX_get_num_tickets($ctx);
# $ctx  - value corresponding to openssl's SSL_CTX structure
#
# returns: (integer) number of tickets to send

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_num_tickets.html>

  • CTX_set_keylog_callback โ€” sets the TLS key logging callback, aka the little spy that writes your key material out for debugging ๐Ÿ•ต๏ธโ€โ™€๏ธ
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 1.1.1pre1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
Net::SSLeay::CTX_set_keylog_callback($ctx, $cb);
# $ctx  - value corresponding to openssl's SSL_CTX structure
# $cb - reference to a perl callback function
#
# returns: no return value

The callback function will be called like this:

keylog_cb_func($ssl, $line);
# $ssl - value corresponding to OpenSSL's SSL object associated with the connection
# $line - a string containing the key material in the format used by NSS for its SSLKEYLOGFILE debugging output

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_keylog_callback.html>

  • CTX_get_keylog_callback โ€” retrieves whatever key logging callback you set earlier, no cap ๐Ÿ”
COMPATIBILITY: not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 1.1.1pre1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
my $cb = Net::SSLeay::CTX_get_keylog_callback($ctx);
# $ctx  - value corresponding to openssl's SSL_CTX structure
#
# returns: a reference to a perl callback function or undef if no callback is set

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_keylog_callback.html>

  • CTX_set_client_hello_cb โ€” sets a callback that fires during the early stages of ClientHello processing on the server side ๐ŸŒธ and when the callback is undef, the existing callback gets disabled, easy peasy
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL ๐Ÿšซ
Net::SSLeay::CTX_set_client_hello_cb($ctx, $f, [$arg]);
# $ctx  - value corresponding to openssl's SSL_CTX structure
# $f - sub { my ($ssl, $arg) = @_; ...; return ($ret, $al); }
# $arg - optional data passed to the callback function when invoked
#
# returns: no return value

The callback function will be called like this:

client_hello_cb_func($ssl, $arg);
# $ssl - value corresponding to OpenSSL's SSL object associated with the connection
# $arg - data to callback
#
# An alert code must be returned with SSL_CLIENT_HELLO_FAILURE.
# Return value examples:
# ok: return Net::SSLeay::CLIENT_HELLO_SUCCESS();
# suspend: return Net::SSLeay::CLIENT_HELLO_RETRY();
# error: return (Net::SSLeay::CLIENT_HELLO_FAILURE(), Net::SSLeay::AD_NO_APPLICATION_PROTOCOL());

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_hello_cb.html>


NOTE: Please note that the function described in this chapter have "SSL_" part stripped from their original openssl names. So like, don't go looking for SSL_new, it's just new here. iykyk ๐Ÿ’ซ
  • new โ€” creates a new SSL structure, which is literally what you need to hold the data for a TLS/SSL connection ๐Ÿ‘‘

The new structure inherits the settings of the underlying context $ctx: connection method (SSLv2/v3/TLSv1), options, verification settings, timeout settings. It's giving "child of $ctx" energy fr fr ๐Ÿงฌ

my $rv = Net::SSLeay::new($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's SSL structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_new.html>

  • accept โ€” waits for a TLS/SSL client to initiate the TLS/SSL handshake ๐Ÿค
heads up: the communication channel must already have been set and assigned to the ssl by setting an underlying BIO. Don't skip that step bestie, it will not work ๐Ÿ˜ญ
my $rv = Net::SSLeay::accept($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 = success, 0 = handshake not successful, <0 = fatal error during handshake

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_accept.html>

  • add_client_CA โ€” adds the CA name extracted from cacert to the list of CAs sent to the client when requesting a client certificate for the chosen ssl, overriding the setting valid for ssl's SSL_CTX object ๐ŸŽ€
my $rv = Net::SSLeay::add_client_CA($ssl, $x);
# $ssl - value corresponding to openssl's SSL structure
# $x - value corresponding to openssl's X509 structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_CA_list.html>

  • callback_ctrl โ€” ??? (more info needed) ๐Ÿ™ˆ literally the manpage itself is shrugging at you here
my $rv = Net::SSLeay::callback_ctrl($ssl, $cmd, $fp);
# $ssl - value corresponding to openssl's SSL structure
# $cmd - (integer) command id
# $fp - (function pointer) ???
#
# returns: ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_ctrl.html>

  • check_private_key

Checks that the private key is actually a match for the corresponding certificate loaded into $ssl โ€” like making sure the lock and key are literal soulmates ๐Ÿ’–

my $rv = Net::SSLeay::check_private_key($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • clear โ€” resets the SSL object so you can do another connection with it. Fresh start energy โœจ
Net::SSLeay::clear($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: no return value

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_clear.html

  • connect โ€” kicks off the TLS/SSL handshake with a TLS/SSL server, bestie ๐Ÿค
my $rv = Net::SSLeay::connect($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 = success, 0 = handshake not successful, <0 = fatal error during handshake

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_connect.html

  • copy_session_id โ€” copies the session structure from $from to $to, plus the private key and certificate that are associated with $from ๐ŸŽ€
Net::SSLeay::copy_session_id($to, $from);
# $to - value corresponding to openssl's SSL structure
# $from - value corresponding to openssl's SSL structure
#
# returns: no return value
  • ctrl โ€” internal handling function for SSL objects. BEWARE: the openssl doc literally says: This function should never be called directly! So likeโ€ฆ donโ€™t do it unless you know exactly what youโ€™re doing ๐Ÿ’€
my $rv = Net::SSLeay::ctrl($ssl, $cmd, $larg, $parg);
# $ssl - value corresponding to openssl's SSL structure
# $cmd - (integer) command id
# $larg - (integer) long ???
# $parg - (string/pointer) ???
#
# returns: (long) result of given command ???

For more details about valid $cmd values check CTX_ctrl.

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_ctrl.html

  • do_handshake โ€” waits for an SSL/TLS handshake to happen. If the connection is in client mode, the handshake gets started. The handshake routines may have to be explicitly set in advance using either SSL_set_connect_state or SSL_set_accept_state(3) ๐Ÿซถ
my $rv = Net::SSLeay::do_handshake($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 = success, 0 = handshake not successful, <0 = fatal error during handshake

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html

  • dup โ€” returns a duplicate of $ssl. Copy-paste but make it SSL โœจ
my $rv = Net::SSLeay::dup($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL structure (0 on failure)
  • free โ€” frees an allocated SSL structure. Let it go, let it gooo ๐Ÿงš
Net::SSLeay::free($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: no return value

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_free.html

  • get0_param โ€” returns the current verification parameters. COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 ๐ŸŒธ
my $vpm = Net::SSLeay::get0_param($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's X509_VERIFY_PARAM structure

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get0_param.html

  • get_SSL_CTX โ€” returns a pointer to the SSL_CTX object that $ssl was created from using Net::SSLeay::new. Found family ๐Ÿ˜ญ๐Ÿ’–
my $rv = Net::SSLeay::get_SSL_CTX($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL_CTX structure (0 on failure)

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_SSL_CTX.html

  • set_SSL_CTX โ€” sets the SSL_CTX that corresponds to an SSL session. COMPATIBILITY: requires at least OpenSSL 0.9.8f ๐Ÿ‘‘
my $the_ssl_ctx = Net::SSLeay::set_SSL_CTX($ssl, $ssl_ctx);
# $ssl - value corresponding to openssl's SSL structure
# $ssl_ctx - Change the ssl object to the given ssl_ctx
#
# returns - the ssl_ctx
  • get_app_data โ€” can be used to get application-defined value/data. Very โ€œyou put it there, now go get itโ€ ๐Ÿ’…
my $rv = Net::SSLeay::get_app_data($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: string/buffer/pointer ???
  • set_app_data โ€” can be used to set some application-defined value/data. Stash your little app data here ๐ŸŽ€
my $rv = Net::SSLeay::set_app_data($ssl, $arg);
# $ssl - value corresponding to openssl's SSL structure
# $arg - (string/buffer/pointer ???) data
#
# returns: ???
  • get_certificate โ€” gets the X509 certificate from an established SSL connection. Certificate reveal โœจ
my $rv = Net::SSLeay::get_certificate($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's X509 structure (0 on failure)
  • get_cipher โ€” obtains the name of the cipher currently being used. If no session has been established, you get ''. No session, no cipher name, bestie ๐Ÿ˜Œ
my $rv = Net::SSLeay::get_cipher($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (string) cipher name e.g. 'DHE-RSA-AES256-SHA' or '', when no session has been established.

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_current_cipher.html

  • get_cipher_bits โ€” gets the number of secret/algorithm bits used. Numbers girlies rise ๐Ÿ”ข๐Ÿ’…
my $rv = Net::SSLeay::get_cipher_bits($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: number of secret bits used by current cipher

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_current_cipher.html and https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html

  • get_ciphers โ€” returns a list of SSL_CIPHER structures available for $ssl, sorted by preference. COMPATIBILITY: not available in Net-SSLeay-1.88 and before ๐ŸŒˆ
my @ciphers = Net::SSLeay::get_ciphers($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (list) SSL_CIPHER structures or nothing when $ssl is undefined or no ciphers are available

Example:

my @ciphers = Net::SSLeay::get_ciphers($ssl);
foreach my $c (@ciphers) {
    print Net::SSLeay::CIPHER_get_name($c) . "\n";
}

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_ciphers.html

  • get_cipher_list โ€” returns the name (string) of the SSL_CIPHER listed for $ssl with priority $n. If thereโ€™s an error, you get undef ๐Ÿ˜ญ
my $rv = Net::SSLeay::get_cipher_list($ssl, $n);
# $ssl - value corresponding to openssl's SSL structure
# $n - (integer) priority
#
# returns: (string) cipher name e.g. 'EDH-DSS-DES-CBC3-SHA' or undef in case of error

Call Net::SSLeay::get_cipher_list with priority starting from 0 to obtain the sorted list of available ciphers, until undef is returned:

my $priority = 0;
while (my $c = Net::SSLeay::get_cipher_list($ssl, $priority)) {
    print "cipher[$priority] = $c\n";
    $priority++;
}

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_cipher_list.html

  • get_client_CA_list โ€” returns the list of client CAs explicitly set for $ssl using Net::SSLeay::set_client_CA_list, or $sslโ€™s SSL_CTX object with Net::SSLeay::CTX_set_client_CA_list, when in server mode. In client mode, it returns the list of client CAs sent from the server, if any ๐Ÿฆ‹
my $rv = Net::SSLeay::get_client_CA_list($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's STACK_OF(X509_NAME) structure (0 on failure)

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_client_CA_list.html

  • get_current_cipher โ€” returns the cipher thatโ€™s actually being used. No guesses, just facts ๐Ÿ’…
my $rv = Net::SSLeay::get_current_cipher($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL_CIPHER structure (0 on failure)

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_current_cipher.html

  • get_default_timeout โ€” returns the default timeout value assigned to SSL_SESSION objects negotiated for the protocol thatโ€™s valid for $ssl. Timeout era โณ
my $rv = Net::SSLeay::get_default_timeout($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (long) timeout in seconds

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_default_timeout.html

  • get_error โ€” returns a result code for a preceding call to connect, accept, do_handshake, read, peek or write on $ssl. This is the โ€œwhat just happenedโ€ check, bestie ๐Ÿ‘€
my $rv = Net::SSLeay::get_error($ssl, $ret);
# $ssl - value corresponding to openssl's SSL structure
# $ret - return value of preceding TLS/SSL I/O operation
#
# returns: result code, which is one of the following values:
#  0 - SSL_ERROR_NONE
#  1 - SSL_ERROR_SSL
#  2 - SSL_ERROR_WANT_READ
#  3 - SSL_ERROR_WANT_WRITE
#  4 - SSL_ERROR_WANT_X509_LOOKUP
#  5 - SSL_ERROR_SYSCALL
#  6 - SSL_ERROR_ZERO_RETURN
#  7 - SSL_ERROR_WANT_CONNECT
#  8 - SSL_ERROR_WANT_ACCEPT

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_error.html

  • get_ex_data โ€” is used to retrieve the information for $idx from $ssl. Application-specific data retrieval, slay ๐Ÿ’–
my $rv = Net::SSLeay::get_ex_data($ssl, $idx);
# $ssl - value corresponding to openssl's SSL structure
# $idx - (integer) index for application specific data
#
# returns: pointer to ???

OpenSSL doc: https://www.openssl.org/docs/manmaster/man3/SSL_get_ex_new_index.html

  • set_ex_data
  • set_ex_data โ€” stashes your app data, $data, at slot $idx inside the $ssl object. Like slapping a little name tag on it ๐Ÿ’…
my $rv = Net::SSLeay::set_ex_data($ssl, $idx, $data);
# $ssl - value corresponding to openssl's SSL structure
# $idx - (integer) ???
# $data - (pointer) ???
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_ex_new_index.html>

  • get_ex_new_index โ€” registers a brand-new index for application specific data. Yes bestie, you gotta grab a slot before you can use one ๐ŸŽŸ๏ธ
my $rv = Net::SSLeay::get_ex_new_index($argl, $argp, $new_func, $dup_func, $free_func);
# $argl - (long) ???
# $argp - (pointer) ???
# $new_func - function pointer ??? (CRYPTO_EX_new *)
# $dup_func - function pointer ??? (CRYPTO_EX_dup *)
# $free_func - function pointer ??? (CRYPTO_EX_free *)
#
# returns: (integer) ???

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_ex_new_index.html>

  • get_fd โ€” hands you the file descriptor that's linked to $ssl. Lowkey the most useful little number in this whole vibe ๐ŸŒธ
my $rv = Net::SSLeay::get_fd($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: file descriptor (>=0) or -1 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_fd.html>

  • get_finished โ€” grabs the most recent 'Finished' message that got sent to the peer. Return value is zero if there's been no Finished message yet. Default count is 2*EVP_MAX_MD_SIZE, which is long enough for all possible Finish messages. Heads up tho: if you supply a non-default count, the resulting return value may be longer than the returned buf's length ๐Ÿ˜ญ
my $rv = Net::SSLeay::get_finished($ssl, $buf, $count);
# $ssl - value corresponding to openssl's SSL structure
# $buf - buffer where the returned data will be stored
# $count - [optional] max size of return data - default is 2*EVP_MAX_MD_SIZE
#
# returns: length of latest Finished message
  • get_peer_finished โ€” same energy, different direction: gets the latest 'Finished' message we're expecting from the peer. Parameters and return value are similar to get_finished(). Twin energy fr fr ๐Ÿซถ
my $rv = Net::SSLeay::get_peer_finished($ssl, $buf, $count);
# $ssl - value corresponding to openssl's SSL structure
# $buf - buffer where the returned data will be stored
# $count - [optional] max size of return data - default is 2*EVP_MAX_MD_SIZE
#
# returns: length of latest Finished message
  • get_keyblock_size โ€” gets the length of the TLS keyblock. Look for 'key_block' in TLS 1.2 and earlier TLS RFCs. Honestly? Consider using the TLS exporter interface defined by RFC 5705 instead of creating your own keying material exporter, bestie โ€” it's the glow-up move โœจ
NOTE: does not exactly correspond to any low level API function. Intended for EAP-FAST.
my $rv = Net::SSLeay::get_keyblock_size($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: keyblock size, -1 on error
  • get_mode โ€” returns the mode (bitmask) set for $ssl. Bitmask meaning it's a whole little pile of flags smooshed into one number ๐Ÿ”ข
my $rv = Net::SSLeay::get_mode($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: mode (bitmask)

To decode the return value (bitmask) see documentation for "CTX_get_mode".

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_mode.html>

  • set_mode โ€” adds the mode set via bitmask in $mode to $ssl. Options you already set before are not cleared. It's additive, not a reset, iykyk ๐Ÿ’…
my $rv = Net::SSLeay::set_mode($ssl, $mode);
# $ssl - value corresponding to openssl's SSL structure
# $mode - mode (bitmask)
#
# returns: the new mode bitmask after adding $mode

For $mode bitmask details see "CTX_get_mode".

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_mode.html>

  • get_options โ€” returns the options (bitmask) set for $ssl. Same dealio as the mode one, just the other bitmask โœจ
my $rv = Net::SSLeay::get_options($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: options (bitmask)

To decode the return value (bitmask) see documentation for "CTX_get_options".

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html>

  • set_options โ€” adds the options set via bitmask in $options to $ssl. And bestie, options already set before are not cleared! (the exclamation mark is doing heavy lifting here ๐Ÿ˜ค)
Net::SSLeay::set_options($ssl, $options);
# $ssl - value corresponding to openssl's SSL structure
# $options - options (bitmask)
#
# returns: the new options bitmask after adding $options

For $options bitmask details see "CTX_get_options".

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html>

  • get_peer_certificate โ€” gets the X509 certificate of the peer, i.e. the other side's proof of identity ๐Ÿชช
my $rv = Net::SSLeay::get_peer_certificate($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's X509 structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_peer_certificate.html>

  • get_peer_certificate / get_peer_cert_chain โ€” this one gets the whole certificate chain of the peer, as an array of X509 structures. Not just one cert, the entire lineage, main character energy ๐Ÿ‘‘
my @chain = Net::SSLeay::get_peer_cert_chain($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: list of X509 structures

Example:

my @chain = Net::SSLeay::get_peer_cert_chain($ssl);
foreach my $x509 (@chain) {
    print Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)) . "\n";
}

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_peer_cert_chain.html>

  • get_quiet_shutdown โ€” returns the 'quiet shutdown' setting of ssl. No dramatic goodbye messages, just vibes ๐Ÿคซ
my $rv = Net::SSLeay::get_quiet_shutdown($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) current 'quiet shutdown' value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html>

  • get_rbio โ€” gets the 'read' BIO linked to an SSL object $ssl. That's the inbound pipe of the whole operation ๐ŸŽ€
my $rv = Net::SSLeay::get_rbio($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_rbio.html>

  • get_read_ahead โ€” reads back the read_ahead value. Short and sweet, we stan ๐Ÿ’–
my $rv = Net::SSLeay::get_read_ahead($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) read_ahead value
  • set_read_ahead โ€” sets the read_ahead value on $ssl, and spoiler: it gives you back the original value, like a little receipt ๐Ÿงพ
Net::SSLeay::set_read_ahead($ssl, $val);
# $ssl - value corresponding to openssl's SSL structure
# $val - read_ahead value to be set
#
# returns: the original read_ahead value
  • get_security_level โ€” returns the security level associated with $ssl. (See the compatibility note in "set_security_level" just below โ€” same tea โ˜•)
my $level = Net::SSLeay::get_security_level($ssl);
# $ssl   - value corresponding to openssl's SSL structure
#
# returns: (integer) current security level

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_security_level.html>

  • set_security_level โ€” sets the security level associated with $ssl to $level.
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.6.0 and Net-SSLeay-1.94
Net::SSLeay::set_security_level($ssl, $level);
# $ssl   - value corresponding to openssl's SSL structure
# $level - new security level
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_security_level.html>

  • set_num_tickets โ€” sets how many TLSv1.3 session tickets get sent to a client. Ticket spam, but make it intentional ๐ŸŽซ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
my $rv = Net::SSLeay::set_num_tickets($ssl, $number_of_tickets);
# $ssl  - value corresponding to openssl's SSL structure
# $number_of_tickets - number of tickets to send
#
# returns: 1 on success, 0 on failure

Set to zero if you do not want to support a session resumption.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_num_tickets.html>

  • get_num_tickets โ€” reads back how many TLSv1.3 session tickets will be sent to a client. Yes, the getter's example says $ctx โ€” that's exactly what's written, don't come for me ๐Ÿ™ˆ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.5.0 and Net-SSLeay-1.94
my $number_of_tickets = Net::SSLeay::get_num_tickets($ctx);
# $ctx  - value corresponding to openssl's SSL structure
#
# returns: number of tickets to send

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_num_tickets.html>

  • get_server_random โ€” returns the internal SSLv3 server_random value. Raw binary, don't try to print it like it's text ๐Ÿ’€
Net::SSLeay::get_server_random($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: server_random value (binary data)
  • get_client_random โ€” returns the internal SSLv3 client_random value. Same binary-data situation, same "handle with care" energy ๐Ÿฆ‹
NOTE: does not exactly correspond to any low level API function
Net::SSLeay::get_client_random($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: client_random value (binary data)
  • export_keying_material โ€” returns keying material based on the string $label and optional $context. And here's the tea you actually need: with TLSv1.2 and lower, an empty context (empty string) and an undefined context (no value or 'undef') will return different values. Not a typo, not a bug โ€” just how it is, so be intentional about which one you pass ๐Ÿ”ฅ
  • export_keying_material โ€” aww look, this one spills out keying material for you. ๐Ÿซถ
my $out = Net::SSLeay::export_keying_material($ssl, $olen, $label, $context);
# $ssl - value corresponding to openssl's SSL structure
# $olen - number of bytes to return
# $label - application specific label
# $context - [optional] context - default is undef for no context
#
# returns: keying material (binary data) or undef on error

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_export_keying_material.html>

  • get_session โ€” grabs the TLS/SSL session data being used in $ssl. Heads up bestie: the reference count of the SSL_SESSION is NOT incremented. Not even a little. ๐Ÿ’…
my $rv = Net::SSLeay::get_session($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL_SESSION structure (0 on failure)

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_session.html>

  • SSL_get0_session โ€” literally just an alias for get_session. And the name is SSL_get0_session, NOT get0_session. iykyk, it's giving sneaky lowercase trap energy ๐Ÿ™ˆ
my $rv = Net::SSLeay::SSL_get0_session();
  • get1_session โ€” this one hands you a pointer to the SSL_SESSION that's actually being used in $ssl, and โ€” plot twist โ€” this time the reference count is incremented by 1. โœจ
my $rv = Net::SSLeay::get1_session($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL_SESSION structure (0 on failure)

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_get_session.html>

  • get_shared_ciphers โ€” returns a string listing (colon ':' separated, iconic formatting) all the ciphers shared between client and server inside the SSL session $ssl. ๐ŸŽ€
my $rv = Net::SSLeay::get_shared_ciphers();
#
# returns: string like 'ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:...'
  • get_shutdown โ€” tells you the shutdown mode of $ssl. Very "are we still on speaking terms" energy. ๐Ÿ’€
my $rv = Net::SSLeay::get_shutdown($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: shutdown mode (bitmask) of ssl

# to decode the return value (bitmask) use:
# 0 - No shutdown setting, yet
# 1 - SSL_SENT_SHUTDOWN
# 2 - SSL_RECEIVED_SHUTDOWN

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_shutdown.html>

  • get_ssl_method โ€” returns a function pointer to the TLS/SSL method that's set in $ssl. ๐Ÿฆ‹
my $rv = Net::SSLeay::get_ssl_method($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's SSL_METHOD structure (0 on failure)

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ssl_version.html>

  • in_init, in_before, is_init_finished, in_connect_init, in_accept_init โ€” the handshake state machine gossip squad. ๐Ÿ’… COMPATIBILITY: not available in Net-SSLeay-1.85 and before. All of these take $ssl as their only argument and return 0 or 1. And fr fr, the docs recommend these over get_state() and state() โ€” they're the main characters here. ๐Ÿ‘‘
my $rv = Net::SSLeay::is_init_finished($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: All functions return 1 or 0

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_in_init.html>

  • get_state โ€” returns the SSL connection state. COMPATIBILITY: OpenSSL 1.1.0 and later use different constants which are not made available. So use is_init_finished() and its related functions instead, bestie, don't set yourself up. ๐Ÿ˜ญ
my $rv = Net::SSLeay::get_state($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) state value
#          to decode the returned state check:
#          SSL_ST_* constants in openssl/ssl.h
#          SSL2_ST_* constants in openssl/ssl2.h
#          SSL23_ST_* constants in openssl/ssl23.h
#          SSL3_ST_* + DTLS1_ST_* constants in openssl/ssl3.h
  • state โ€” exactly the same as get_state. Same vibes, different name. ๐Ÿชž
my $rv = Net::SSLeay::state($ssl);
  • set_state โ€” sets the SSL connection state.
Net::SSLeay::set_state($ssl,Net::SSLeay::SSL_ST_ACCEPT());
Not available with OpenSSL 1.1 and later. ๐Ÿšซ
  • get_verify_depth โ€” returns the verification depth limit currently set in $ssl.
my $rv = Net::SSLeay::get_verify_depth($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: current depth or -1 if no limit has been explicitly set

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_verify_mode.html>

  • set_verify_depth โ€” sets the maximum depth allowed for certificate chain verification on $ssl. Like a bouncer with a very specific guest list. ๐ŸŽ€
Net::SSLeay::set_verify_depth($ssl, $depth);
# $ssl - value corresponding to openssl's SSL structure
# $depth - (integer) depth
#
# returns: no return value

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html>

  • get_verify_mode โ€” returns the verification mode (bitmask) currently set in $ssl.
my $rv = Net::SSLeay::get_verify_mode($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: mode (bitmask)

Wanna decode that bitmask? Go read the docs for CTX_get_verify_mode. ๐Ÿซถ

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_get_verify_mode.html>

  • set_verify โ€” sets the verification flags for $ssl to $mode and specifies the $verify_callback function to be used. โœจ
Net::SSLeay::set_verify($ssl, $mode, $callback);
# $ssl - value corresponding to openssl's SSL structure
# $mode - mode (bitmask)
# $callback - [optional] reference to perl callback function
#
# returns: no return value

For the $mode bitmask deets, see CTX_get_verify_mode.

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html>

  • set_post_handshake_auth โ€” turns on the Post-Handshake Authentication extension so it gets added to the ClientHello, which means the server can then request post-handshake authentication. COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, and it's not in LibreSSL. ๐Ÿ‘€
Net::SSLeay::set_posthandshake_auth($ssl, $val);
# $ssl - value corresponding to openssl's SSL structure
# $val - 0 then the extension is not sent, otherwise it is
#
# returns: no return value

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_post_handshake_auth.html>

  • verify_client_post_handshake โ€” makes a server send a CertificateRequest message on the given ssl connection. Very "hey client, prove it" energy. ๐Ÿฆ‹ COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, and not in LibreSSL.
my $rv = Net::SSLeay::verify_client_post_handshake($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 if the request succeeded, and 0 if the request failed. The error stack can be examined to determine the failure reason.

Peep the openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_verify_client_post_handshake.html>

  • get_verify_result โ€” returns the result of verifying the X509 certificate the peer presented, if there even was one. ๐Ÿ‘‘
my $rv = Net::SSLeay::get_verify_result($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer)
#      0 - X509_V_OK: ok
#      2 - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate
#      3 - X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL
#      4 - X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature
#      5 - X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature
#      6 - X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key
#      7 - X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure
#      8 - X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure
#      9 - X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid
#     10 - X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired
#     11 - X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid
#     12 - X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired
#     13 - X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field
#     14 - X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field
#     15 - X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field
#     16 - X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field
#     17 - X509_V_ERR_OUT_OF_MEM: out of memory
#     18 - X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate
#     19 - X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain
#     20 - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate
#     21 - X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate
#     22 - X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long
#     23 - X509_V_ERR_CERT_REVOKED: certificate revoked
#     24 - X509_V_ERR_INVALID_CA: invalid CA certificate
#     25 - X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded
#     26 - X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose
#     27 - X509_V_ERR_CERT_UNTRUSTED: certificate not trusted
#     28 - X509_V_ERR_CERT_REJECTED: certificate rejected
#     29 - X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch
#     30 - X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch
#     31 - X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch
#     32 - X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing
#     50 - X509_V_ERR_APPLICATION_VERIFICATION: application verification failure

Check the openssl docs right here bestie: https://www.openssl.org/docs/manmaster/man3/SSL_get_verify_result.html

  • set_verify_result โ€” lowkey override the result of the peer certificate verification. Yes, you can justโ€ฆ do that. ๐Ÿ‘€
Net::SSLeay::set_verify_result($ssl, $v);
# $ssl - value corresponding to openssl's SSL structure
# $v - (integer) result value
#
# returns: no return value

Wanna know what values actually count as valid? Peep "get_verify_result" above, it's all there ๐Ÿ’–

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_set_verify_result.html

  • get_wbio โ€” grab the 'write' BIO that's linked to an SSL object $ssl. it's giving "which pipe do I shout into" energy โœจ
my $rv = Net::SSLeay::get_wbio($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_get_rbio.html

ngl that doc link says SSL_get_rbio and not SSL_get_wbio โ€” that's literally what the original says, so we're keeping it exactly as-is. no cap. ๐Ÿ™ˆ
  • load_client_CA_file โ€” load X509 certificates straight from a file (PEM formatted, obvi). ๐ŸŽ€
my $rv = Net::SSLeay::load_client_CA_file($file);
# $file - (string) file name
#
# returns: value corresponding to openssl's STACK_OF(X509_NAME) structure (0 on failure)

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_load_client_CA_file.html

  • clear_num_renegotiations โ€” runs the SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS command on $ssl. bye bye counter ๐Ÿ’…
my $rv = Net::SSLeay::clear_num_renegotiations($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: command result
  • need_tmp_RSA โ€” runs the SSL_CTRL_NEED_TMP_RSA command on $ssl.
my $rv = Net::SSLeay::need_tmp_RSA($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: command result
๐Ÿšจ heads up bestie: not available with OpenSSL 1.1 and later. it's giving deprecated era, so don't come for me if it's not there ๐Ÿ˜ญ
  • num_renegotiations โ€” runs the SSL_CTRL_GET_NUM_RENEGOTIATIONS command on $ssl. counting the renegotiation era ๐Ÿฆ‹
my $rv = Net::SSLeay::num_renegotiations($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: command result
  • total_renegotiations โ€” runs the SSL_CTRL_GET_TOTAL_RENEGOTIATIONS command on $ssl. the total total, not just the current ones ๐Ÿ‘‘
my $rv = Net::SSLeay::total_renegotiations($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: command result
  • peek โ€” copies $max bytes from the given $ssl into the returned value, but here's the iconic part: unlike Net::SSLeay::read(), the data in the SSL buffer is unmodified after the SSL_peek() operation. it's a look, not a take. ๐ŸŒธ
Net::SSLeay::peek($ssl, $max);
# $ssl - value corresponding to openssl's SSL structure
# $max - [optional] max bytes to peek (integer) - default is 32768
#
# in scalar context: data read from the TLS/SSL connection, undef on error
# in list context:   two-item array consisting of data read (undef on error),
#                      and return code from SSL_peek().
  • peek_ex โ€” COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, and it's not in LibreSSL. bestie check your versions first fr fr ๐Ÿซถ

Copies $max bytes from the given $ssl into the returned value. And again, unlike Net::SSLeay::read_ex(), the data in the SSL buffer stays unmodified after the SSL_peek_ex() operation.

my($got, $rv) = Net::SSLeay::peek_ex($ssl, $max);
# $ssl - value corresponding to openssl's SSL structure
# $max - [optional] max bytes to peek (integer) - default is 32768
#
# returns a list: two-item list consisting of data read (undef on error),
#                 and return code from SSL_peek_ex().

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_peek_ex.html

  • pending โ€” how many readable bytes are just chillin' in the $ssl object's buffer? this tells you. โœจ
my $rv = Net::SSLeay::pending($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: the number of bytes pending

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_pending.html

  • has_pending โ€” COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, and it's not in LibreSSL. ๐Ÿงš

Returns 1 if $ssl has buffered data (whether processed or unprocessed) and 0 otherwise. simple vibes only.

my $rv = Net::SSLeay::has_pending($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) 1 or 0

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_has_pending.html

  • read โ€” tries to read $max bytes from the given $ssl. the classic. the main character. ๐Ÿ”ฅ
my $got = Net::SSLeay::read($ssl, $max);
my($got, $rv) = Net::SSLeay::read($ssl, $max);
# $ssl - value corresponding to openssl's SSL structure
# $max - [optional] max bytes to read (integer) - default is 32768
#
# returns:
# in scalar context: data read from the TLS/SSL connection, undef on error
# in list context:   two-item array consisting of data read (undef on error),
#                      and return code from SSL_read().

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_read.html

  • read_ex โ€” COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, and it's not in LibreSSL. ๐Ÿ’œ

Tries to read $max bytes from the given $ssl.

my($got, $rv) = Net::SSLeay::read_ex($ssl, $max);
# $ssl - value corresponding to openssl's SSL structure
# $max - [optional] max bytes to read (integer) - default is 32768
#
# returns a list: two-item list consisting of data read (undef on error),
#                 and return code from SSL_read_ex().

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_read_ex.html

  • renegotiate โ€” turns on the flags for renegotiation so that renegotiation will actually happen. like, go bestie, negotiate again ๐Ÿ’…
my $rv = Net::SSLeay::renegotiate($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 on success, 0 on failure
  • rstate_string โ€” returns a 2 letter string telling you the current read state of the SSL object $ssl. two letters, so much lore. ๐ŸŽ€
my $rv = Net::SSLeay::rstate_string($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 2-letter string

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_rstate_string.html

  • rstate_string_long โ€” same vibe but a whole string, spelling out the current read state of the SSL object ssl. no abbreviations, we're being thorough โœจ
my $rv = Net::SSLeay::rstate_string_long($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: string with current state

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_rstate_string.html

  • session_reused โ€” asks the question: was a reused session negotiated during the handshake? ๐Ÿ‘€
my $rv = Net::SSLeay::session_reused($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 0 - new session was negotiated; 1 - session was reused.

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_session_reused.html

  • set1_param โ€” COMPATIBILITY: requires at least OpenSSL 1.0.0-beta3. ๐Ÿฆ‹

Applies the X509 verification parameters $vpm onto $ssl.

my $rv = Net::SSLeay::set1_param($ssl, $vpm);
# $ssl - value corresponding to openssl's SSL structure
# $vpm - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure
  • set_accept_state โ€” sets $ssl to work in server mode. welcome to the server side, we have cookies ๐Ÿ“
Net::SSLeay::set_accept_state($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: no return value

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html

  • set_bio โ€” connects the BIOs $rbio and $wbio for the read and write operations of the TLS/SSL (encrypted) side of $ssl. matching them up like the duo they are ๐Ÿซถ
Net::SSLeay::set_bio($ssl, $rbio, $wbio);
# $ssl - value corresponding to openssl's SSL structure
# $rbio - value corresponding to openssl's BIO structure
# $wbio - value corresponding to openssl's BIO structure
#
# returns: no return value

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_set_bio.html

  • set_cipher_list โ€” sets the list of ciphers, but only for $ssl. exclusive little list ๐Ÿ’…
my $rv = Net::SSLeay::set_cipher_list($ssl, $str);
# $ssl - value corresponding to openssl's SSL structure
# $str - (string) cipher list e.g. '3DES:+RSA'
#
# returns: 1 if any cipher could be selected and 0 on complete failure

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cipher_list.html

  • set_ciphersuites โ€” COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1 or at least LibreSSL 3.4.0 and Net-SSLeay-1.94. read that twice bestie ๐Ÿ“–

Configures the available TLSv1.3 ciphersuites.

my $rv = Net::SSLeay::set_ciphersuites($ssl, $str);
# $ssl  - value corresponding to openssl's SSL structure
# $str  - colon (":") separated list of TLSv1.3 ciphersuite names in order of preference
#
# returns: (integer) 1 if the requested ciphersuite list was configured, and 0 otherwise

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_set_ciphersuites.html

  • set_client_CA_list โ€” sets the list of CAs that get sent to the client when requesting a client certificate for the chosen $ssl โ€” and it overrides whatever setting is valid for $ssl's SSL_CTX object. the chosen one wins, periodt ๐Ÿ‘‘
my $rv = Net::SSLeay::set_client_CA_list($ssl, $list);
# $ssl - value corresponding to openssl's SSL structure
# $list - value corresponding to openssl's STACK_OF(X509_NAME) structure
#
# returns: no return value

Check the openssl docs: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_client_CA_list.html

  • set_connect_state โ€” sets $ssl to work in client mode. client-side era activated โœจ
Net::SSLeay::set_connect_state($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html>

(that was the tail end of the one above, bestie โ€” just making sure the link didn't get lost ๐Ÿ’–)


  • set_fd โ€” plugs file descriptor $fd in as the input/output facility for the TLS/SSL (encrypted) side of $ssl. And like, $fd is typically the socket file descriptor of a network connection, iykyk ๐Ÿ”Œ
my $rv = Net::SSLeay::set_fd($ssl, $fd);
# $ssl - value corresponding to openssl's SSL structure
# $fd - (integer) file handle (got via perl's fileno)
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_fd.html>

  • set_psk_client_callback โ€” sets the psk client callback. Pre-shared keys, we love a lowkey shortcut โœจ
Net::SSLeay::set_psk_client_callback($ssl, sub { my $hint = shift; return ($identity, $key) } );
# $ssl - value corresponding to openssl's SSL structure
# $hint - PSK identity hint send by the server
# $identity - PSK identity
# $key - PSK key, hex string without the leading '0x', e.g. 'deadbeef'
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_psk_client_callback.html>

  • set_rfd โ€” sets file descriptor $fd as the input (read) facility for the TLS/SSL (encrypted) side of $ssl. Just the reading half, she's selective ๐ŸŽ€
my $rv = Net::SSLeay::set_rfd($ssl, $fd);
# $ssl - value corresponding to openssl's SSL structure
# $fd - (integer) file handle (got via perl's fileno)
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_fd.html>

  • set_wfd โ€” and this one is the write half, fr fr ๐Ÿ–Š๏ธ
my $rv = Net::SSLeay::set_wfd($ssl, $fd);
# $ssl - value corresponding to openssl's SSL structure
# $fd - (integer) file handle (got via perl's fileno)
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_fd.html>

  • set_info_callback โ€” sets the callback function that lets you peep state information for $ssl during connection setup and use ๐Ÿ‘€. And when the callback is undef, the callback setting currently valid for ctx gets used instead. Vibes by inheritance, honestly iconic.
Net::SSLeay::set_info_callback($ssl, $cb, [$data]);
# $ssl - value corresponding to openssl's SSL structure
# $cb - sub { my ($ssl,$where,$ret,$data) = @_; ... }
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_info_callback.html>

  • CTX_set_info_callback โ€” same energy but on ctx this time: sets the callback function on ctx so you can get state information during ssl connection setup and use ๐Ÿ’ซ. And when the callback is undef, an existing callback gets disabled โ€” yeah, she'll just turn it off, no hesitation.
Net::SSLeay::CTX_set_info_callback($ssl, $cb, [$data]);
# $ssl - value corresponding to openssl's SSL structure
# $cb - sub { my ($ssl,$where,$ret,$data) = @_; ... }
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_info_callback.html>

  • set_msg_callback โ€” sets the callback function that lets you snag protocol messages information for $ssl during connection setup and use ๐Ÿ“จ. When the callback is undef, the callback setting currently valid for ctx is used. Also important bestie: set_msg_callback_arg is not provided โ€” there's literally no need to explicitly set $arg, because set_msg_callback handles all that for you. She's a self-sufficient queen ๐Ÿ‘‘.
Net::SSLeay::set_msg_callback($ssl, $cb, [$arg]);
# $ssl - value corresponding to openssl's SSL structure
# $cb - sub { my ($write_p,$version,$content_type,$buf,$len,$ssl,$arg) = @_; ... }
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_msg_callback.html>

  • CTX_set_msg_callback โ€” the ctx version of the whole protocol-messages-information situation for ssl connection setup and use ๐Ÿฆ‹. When the callback is undef, the existing callback gets disabled. And same deal as above: CTX_set_msg_callback_arg is not provided because there's no need to explicitly set $arg โ€” CTX_set_msg_callback has got it handled, periodt.
Net::SSLeay::CTX_set_msg_callback($ssl, $cb, [$arg]);
# $ssl - value corresponding to openssl's SSL structure
# $cb - sub { my ($write_p,$version,$content_type,$buf,$len,$ssl,$arg) = @_; ... }
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_msg_callback.html>

  • set_pref_cipher โ€” sets the list of available ciphers for $ssl using the control string $str. Choose your fighters, bestie โš”๏ธ
my $rv = Net::SSLeay::set_pref_cipher($ssl, $str);
# $ssl - value corresponding to openssl's SSL structure
# $str - (string) cipher list e.g. '3DES:+RSA'
#
# returns: 1 if any cipher could be selected and 0 on complete failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_cipher_list.html>

  • CTX_set_psk_client_callback โ€” sets the psk client callback, the ctx edition ๐Ÿ”‘ Same signature, same hex-string key energy:
Net::SSLeay::CTX_set_psk_client_callback($ssl, sub { my $hint = shift; return ($identity, $key) } );
# $ssl - value corresponding to openssl's SSL structure
# $hint - PSK identity hint send by the server
# $identity - PSK identity
# $key - PSK key, hex string without the leading '0x', e.g. 'deadbeef'
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_psk_client_callback.html>

  • set_purpose โ€” sets the purpose on $ssl ๐ŸŽฏ
my $rv = Net::SSLeay::set_purpose($ssl, $purpose);
# $ssl - value corresponding to openssl's SSL structure
# $purpose - (integer) purpose identifier
#
# returns: 1 on success, 0 on failure

For more info about the available $purpose identifiers, go look at "CTX_set_purpose" โ€” that's where the lore lives ๐Ÿ“–

  • set_quiet_shutdown โ€” sets the 'quiet shutdown' flag for $ssl to be $mode. Shhh, no drama, no close_notify announcements ๐Ÿคซ
Net::SSLeay::set_quiet_shutdown($ssl, $mode);
# $ssl - value corresponding to openssl's SSL structure
# $mode - 0 or 1
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html>

  • set_session โ€” sets a TLS/SSL session to be used during TLS/SSL connect. Recycling sessions is so sustainable of you โ™ป๏ธ๐Ÿ’…
my $rv = Net::SSLeay::set_session($to, $ses);
# $to - value corresponding to openssl's SSL structure
# $ses - value corresponding to openssl's SSL_SESSION structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_set_session.html>

  • set_session_id_context โ€” sets the context $sid_ctx of length $sid_ctx_len within which a session can be reused for the $ssl object. Boundaries, bestie โ€” sessions only get reused inside their own little context box ๐ŸŽ€
my $rv = Net::SSLeay::set_session_id_context($ssl, $sid_ctx, $sid_ctx_len);
# $ssl - value corresponding to openssl's SSL structure
# $sid_ctx - data buffer
# $sid_ctx_len - length of data in $sid_ctx
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_session_id_context.html>

  • set_session_secret_cb โ€” sets up the pre-shared secret session resumption function ๐Ÿ”
Net::SSLeay::set_session_secret_cb($ssl, $func, $data);
# $ssl - value corresponding to openssl's SSL structure
# $func - perl reference to callback function
# $data - [optional] data that will be passed to callback function when invoked
#
# returns: no return value

The callback function gets called like this:

callback_function($secret, $ciphers, $pref_cipher, $data);
# $secret is the current master session key, usually all 0s at the beginning of a session
# $ciphers is ref to an array of peer cipher names
# $pref_cipher is a ref to an index into the list of cipher names of
#  the preferred cipher. Set it if you want to specify a preferred cipher
# $data is the data passed to set_session_secret_cb

Your callback function should return 1 if it likes the suggested cipher (or has selected an alternative by setting pref_cipher), else it should return 0 โ€” in which case OpenSSL will select its own preferred cipher. Not her problem, she's got her own taste ๐Ÿ’โ€โ™€๏ธ

With OpenSSL 1.1 and later, callback_function can change the master key for the session by altering $secret and returning 1. Manifesting a whole new key, we love to see it โœจ

  • CTX_set_tlsext_ticket_getkey_cb โ€” sets up encryption for TLS session tickets (stateless session reuse) ๐ŸŽŸ๏ธ
Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx, $func, $data);
# $ctx  - value corresponding to openssl's SSL_CTX structure
# $func - perl reference to callback function
# $data - [optional] data that will be passed to callback function when invoked
#
# returns: no return value

The callback function gets called like this:

getkey($data,[$key_name]) -> ($key,$current_key_name)
# $data is the data passed to set_session_secret_cb
# $key_name is the name of the key OpenSSL has extracted from the session ticket
# $key is the requested key for ticket encryption + HMAC
# $current_key_name is the name for the currently valid key

OpenSSL will call the function without a key name if it generates a new ticket. In that case it needs the callback to return the encryption+HMAC key and an identifier (key name) for this key ๐Ÿ”‘

When OpenSSL gets a session ticket from the client, it extracts the key name and calls the callback with this name as the argument. It then expects the callback to return the encryption+HMAC key matching the requested key name, and also the key name which should be used at the moment. If the requested key name and the returned key name differ, that means the session ticket was created with an expired key and needs to be renewed. In that case OpenSSL will call the callback again with no key name, to create a new session ticket based on the old one ๐Ÿ”„

The key must be at least 32 byte of random data, which can be created with RAND_bytes. Internally the first 16 byte are used as key in AES-128 encryption while the next 16 byte are used for the SHA-256 HMAC. The key name are binary data and must be exactly 16 byte long. โš ๏ธ Like, exactly 16, bestie, do not freestyle that number.

Example:

               Net::SSLeay::RAND_bytes(my $oldkey,32);
               Net::SSLeay::RAND_bytes(my $newkey,32);
               my $oldkey_name = pack("a16",'oldsecret');
               my $newkey_name = pack("a16",'newsecret');

               my @keys = (
                   [ $newkey_name, $newkey ], # current active key
                   [ $oldkey_name, $oldkey ], # already expired
               );

               Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($server2->_ctx, sub {
                   my ($mykeys,$name) = @_;

                   # return (current_key, current_key_name) if no name given
                   return ($mykeys->[0][1],$mykeys->[0][0]) if ! $name;

                   # return (matching_key, current_key_name) if we find a key matching
                   # the given name
                   for(my $i = 0; $i<@$mykeys; $i++) {
                       next if $name ne $mykeys->[$i][0];
                       return ($mykeys->[$i][1],$mykeys->[0][0]);
                   }

                   # no matching key found
                   return;
               },\@keys);

So this function is basically OpenSSL's SSL_CTX_set_tlsext_ticket_key_cb but it gives you a way simpler interface to work with. Want the deep lore? It's all here: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tlsext_ticket_key_cb.html> โœจ


  • set_session_ticket_ext_cb โ€” sets up the callback for TLS session tickets (that's the stateless session reuse vibe, iykyk ๐ŸŽŸ๏ธ).
Net::SSLeay::set_session_ticket_ext_cb($ssl, $func, $data);
# $ssl  - value corresponding to openssl's SSL structure
# $func - perl reference to callback function
# $data - [optional] data that will be passed to callback function when invoked
#
# returns: no return value

Your callback gets invoked like this, bestie:

getticket($ssl,$ticket,$data) -> $return_value
# $ssl is a value corresponding to openssl's SSL structure
# $ticket is a value of received TLS session ticket (can also be empty)
# $data is the data passed to set_session_ticket_ext_cb
# $return_value is either 0 (failure) or 1 (success)

Built on top of OpenSSL's SSL_set_session_ticket_ext_cb. ๐Ÿ’…

  • set_session_ticket_ext โ€” sets the TLS session ticket (stateless session reuse, again โ€” it's giving ticket energy).
Net::SSLeay::set_session_ticket_ext($ssl, $ticket);
# $ssl    - value corresponding to openssl's SSL structure
# $ticket - is a value of TLS session ticket which client will send (can also be empty string)
#
# returns: no return value

And the callback function gets called like this:

getticket($ssl,$ticket,$data) -> $return_value
# $ssl is a value corresponding to openssl's SSL structure
# $ticket is a value of received TLS session ticket (can also be empty)
# $data is the data passed to set_session_ticket_ext_cb
# $return_value is either 0 (failure) or 1 (success)

This one is based on OpenSSL's SSL_set_session_ticket_ext_cb. ๐Ÿงš

  • set_shutdown โ€” sets the shutdown state of $ssl to $mode. Literally the vibe check for "are we closing this connection or what".
Net::SSLeay::set_shutdown($ssl, $mode);
# $ssl - value corresponding to openssl's SSL structure
# $mode - (integer) shutdown mode:
#         0 - No shutdown
#         1 - SSL_SENT_SHUTDOWN
#         2 - SSL_RECEIVED_SHUTDOWN
#         3 - SSL_RECEIVED_SHUTDOWN+SSL_SENT_SHUTDOWN
#
# returns: no return value

Docs if you wanna read more: <https://www.openssl.org/docs/manmaster/man3/SSL_set_shutdown.html> ๐ŸŒธ

  • set_ssl_method โ€” gives a particular $ssl object a whole new TLS/SSL method. Glow-up era โœจ
my $rv = Net::SSLeay::set_ssl_method($ssl, $method);
# $ssl - value corresponding to openssl's SSL structure
# $method - value corresponding to openssl's SSL_METHOD structure
#
# returns: 1 on success, 0 on failure

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ssl_version.html>

  • set_tmp_dh โ€” sets the DH parameters that'll be used to $dh.
my $rv = Net::SSLeay::set_tmp_dh($ssl, $dh);
# $ssl - value corresponding to openssl's SSL structure
# $dh - value corresponding to openssl's DH structure
#
# returns: 1 on success, 0 on failure

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tmp_dh_callback.html>

  • set_tmp_dh_callback โ€” sets the callback function for $ssl, which gets used whenever DH parameters are required, to $dh_cb.
??? (does this function really work?) โ€” yes, the manpage itself is out here asking the real questions ๐Ÿ’€ I'm just the messenger, no cap.
Net::SSLeay::set_tmp_dh_callback($ssl, $dh);
# $ssl - value corresponding to openssl's SSL structure
# $dh_cb - pointer to function ???
#
# returns: no return value

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tmp_dh_callback.html>

  • set_tmp_rsa โ€” sets the temporary/ephemeral RSA key used in $ssl to $rsa. ๐Ÿ—๏ธ
my $rv = Net::SSLeay::set_tmp_rsa($ssl, $rsa);
# $ssl - value corresponding to openssl's SSL structure
# $rsa - value corresponding to openssl's RSA structure
#
# returns: 1 on success, 0 on failure

Example, because seeing it is way easier than reading it:

$rsakey = Net::SSLeay::RSA_generate_key();
Net::SSLeay::set_tmp_rsa($ssl, $rsakey);
Net::SSLeay::RSA_free($rsakey);

OpenSSL doc: <https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_tmp_rsa_callback.html>

  • set_tmp_rsa_callback โ€” sets the callback function for $ssl, used whenever a temporary/ephemeral RSA key is required, to $tmp_rsa_callback.
??? (does this function really work?) โ€” again with the mystery ๐Ÿ™ˆ the source of truth is genuinely unsure here, so I'm not gonna pretend otherwise.
Net::SSLeay::set_tmp_rsa_callback($ssl, $tmp_rsa_callback);
# $ssl - value corresponding to openssl's SSL structure
# $tmp_rsa_callback - (function pointer) ???
#
# returns: no return value

OpenSSL doc: <https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_tmp_rsa_callback.html>

  • set_trust โ€” sets the trust on $ssl to $trust.
my $rv = Net::SSLeay::set_trust($ssl, $trust);
# $ssl - value corresponding to openssl's SSL structure
# $trust - (integer) trust identifier
#
# returns: the original value

Wanna know what the $trust values actually mean? Go peek at "CTX_set_trust" โ€” that's where the tea is. ๐Ÿ“

  • shutdown โ€” shuts down an active TLS/SSL connection and sends the 'close notify' shutdown alert to the peer. It's giving "we're done here, respectfully" ๐Ÿ‘‘
my $rv = Net::SSLeay::shutdown($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 1 - shutdown was successfully completed
#          0 - shutdown is not yet finished,
#         -1 - shutdown was not successful

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_shutdown.html>

  • state_string โ€” returns a 6 letter string telling you the current state of the $ssl object. Six whole letters. Iconic length, honestly.
my $rv = Net::SSLeay::state_string($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: 6-letter string

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_state_string.html>

  • state_string_long โ€” same state-of-the-$ssl-object energy, but as a string that actually reads like words instead of six cryptic letters.
my $rv = Net::SSLeay::state_string_long($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: state strings

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_state_string.html>

  • set_default_passwd_cb โ€” sets the default password callback that gets called when loading/storing a PEM certificate with encryption for $ssl. ๐Ÿ”
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0f. Not needed with LibreSSL. (Read that twice if you're on an old version, bestie, fr fr.)
Net::SSLeay::set_default_passwd_cb($ssl, $func);
# $ssl - value corresponding to openssl's SSL structure
# $func - perl reference to callback function
#
# returns: no return value

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_default_passwd_cb.html>

  • set_default_passwd_cb_userdata โ€” sets a pointer to userdata, and that userdata gets handed to the password callback of $ssl when it's invoked. Teamwork ๐Ÿ’–
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0f. Not needed with LibreSSL.
Net::SSLeay::set_default_passwd_cb_userdata($ssl, $userdata);
# $ssl - value corresponding to openssl's SSL structure
# $userdata - data that will be passed to callback function when invoked
#
# returns: no return value

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_default_passwd_cb.html>

  • use_PrivateKey โ€” adds $pkey as the private key to $ssl. ๐Ÿ’…
my $rv = Net::SSLeay::use_PrivateKey($ssl, $pkey);
# $ssl - value corresponding to openssl's SSL structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • use_PrivateKey_ASN1 โ€” adds a private key of type $pk, stored in $data, to $ssl.
my $rv = Net::SSLeay::use_PrivateKey_ASN1($pk, $ssl, $d, $len);
# $pk - (integer) key type, NID of corresponding algorithm
# $ssl - value corresponding to openssl's SSL structure
# $data - key data (binary)
# $len - length of $data
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • use_PrivateKey_file โ€” grabs the first private key it finds in $file and adds it to $ssl. First come, first served, periodt.
my $rv = Net::SSLeay::use_PrivateKey_file($ssl, $file, $type);
# $ssl - value corresponding to openssl's SSL structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

OpenSSL doc: <https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html>

  • use_RSAPrivateKey โ€” adds $rsa as the RSA private key to $ssl.
  • use_RSAPrivateKey โ€” drops an RSA private key straight into $ssl, like handing your bestie the keys to the group chat ๐Ÿ’…
my $rv = Net::SSLeay::use_RSAPrivateKey($ssl, $rsa);
# $ssl - value corresponding to openssl's SSL structure
# $rsa - value corresponding to openssl's RSA structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_RSAPrivateKey_ASN1 โ€” same energy, but the key is chilling in $data in raw binary and you hand over $len so it knows how much to read ๐Ÿซถ
my $rv = Net::SSLeay::use_RSAPrivateKey_ASN1($ssl, $data, $len);
# $ssl - value corresponding to openssl's SSL structure
# $data - key data (binary)
# $len - length of $data
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_RSAPrivateKey_file โ€” loads the first RSA private key it finds in $file into $ssl (first one, bestie, it does not go hunting for a second) ๐ŸŽ€
my $rv = Net::SSLeay::use_RSAPrivateKey_file($ssl, $file, $type);
# $ssl - value corresponding to openssl's SSL structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_certificate โ€” loads the certificate $x into $ssl. certificate girlies rise โœจ
my $rv = Net::SSLeay::use_certificate($ssl, $x);
# $ssl - value corresponding to openssl's SSL structure
# $x - value corresponding to openssl's X509 structure
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_certificate_ASN1 โ€” loads the ASN1-encoded certificate from $data into $ssl, with $len telling it how many bytes are actually real ๐Ÿ’–
my $rv = Net::SSLeay::use_certificate_ASN1($ssl, $data, $len);
# $ssl - value corresponding to openssl's SSL structure
# $data - certificate data (binary)
# $len - length of $data
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_certificate_chain_file โ€” loads a whole certificate chain from $file into $ssl. the certs HAVE to be PEM format and they HAVE to be sorted correctly, starting with the subject's certificate (the actual client or server cert, the main character ๐Ÿ‘‘), then intermediate CA certs if applicable, and ending at the highest level (root) CA. no cap, order really does matter here ๐Ÿ˜ญ
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.6.0 and Net-SSLeay-1.94
my $rv = Net::SSLeay::use_certificate_chain_file($ssl, $file);
# $ssl - value corresponding to openssl's SSL structure
# $file - (string) file name
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • use_certificate_file โ€” loads the first certificate stored in $file into $ssl, no scrolling past it ๐Ÿฆ‹
my $rv = Net::SSLeay::use_certificate_file($ssl, $file, $type);
# $ssl - value corresponding to openssl's SSL structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, otherwise check out the error stack to find out the reason

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_certificate.html

  • get_version โ€” hands you back the SSL/TLS protocol name as a string. it's giving name-drop ๐Ÿ’…
my $rv = Net::SSLeay::get_version($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (string) protocol name, see OpenSSL manual for the full list
#          TLSv1
#          TLSv1.3

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_get_version.html

  • version โ€” same idea but it's the numeric protocol version instead of the string. numbers > vibes, apparently ๐ŸŒธ
my $rv = Net::SSLeay::version($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) protocol version, see OpenSSL manual for the full list
#          0x0301 - TLS1_VERSION  (TLSv1)
#          0xFEFF - DTLS1_VERSION (DTLSv1)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_version.html

  • client_version โ€” tells you which TLS protocol version the client used when it kicked off the connection. main character behavior, honestly ๐Ÿ”ฅ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL
my $rv = Net::SSLeay::client_version($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) protocol version, see OpenSSL manual for the full list
#          0x0301 - TLS1_VERSION  (TLSv1)
#          0xFEFF - DTLS1_VERSION (DTLSv1)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_version.html

  • is_dtls โ€” vibe check: is this connection on DTLS or not? ๐Ÿงš
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0 or at least LibreSSL 3.3.1 and Net-SSLeay-1.94
my $rv = Net::SSLeay::is_dtls($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) zero or one
#          0 - connection is not using DTLS
#          1 - connection is using DTLS

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_is_dtls.html

  • want โ€” returns the state info for the SSL object $ssl, i.e. what it's currently craving ๐Ÿ’€
my $rv = Net::SSLeay::want($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: state
#          1 - SSL_NOTHING
#          2 - SSL_WRITING
#          3 - SSL_READING
#          4 - SSL_X509_LOOKUP

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_want.html

  • write โ€” pushes the data from buffer $data into the specified $ssl connection. go little data go โญ
my $rv = Net::SSLeay::write($ssl, $data);
# $ssl - value corresponding to openssl's SSL structure
# $data - data to be written
#
# returns: >0 - (success) number of bytes actually written to the TLS/SSL connection
#           0 - write not successful, probably the underlying connection was closed
#          <0 - error

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_write.html

  • write_ex โ€” same deal, writes $data into $ssl, but returns a whole two-item list instead of one number. extra info, extra slay ๐ŸŒˆ
COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL
my ($len, $rv) = Net::SSLeay::write_ex($ssl, $data);
# $ssl - value corresponding to openssl's SSL structure
# $data - data to be written
#
# returns a list: two-item list consisting of number of bytes written,
#                 and return code from SSL_write_ex()

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_write_ex.html

  • write_partial โ€” writes a fragment of the data in $data into the specified $ssl connection. it's a non-blocking function, just like Net::SSLeay::write(). little bites only, no stress ๐Ÿ“
NOTE: Does not exactly correspond to any low level API function
my $rv = Net::SSLeay::write_partial($ssl, $from, $count, $data);
# $ssl - value corresponding to openssl's SSL structure
# $from - (integer) offset from the beginning of $data
# $count - (integer) length of data to be written
# $data - data buffer
#
# returns: >0 - (success) number of bytes actually written to the TLS/SSL connection
#           0 - write not successful, probably the underlying connection was closed
#          <0 - error
  • set_tlsext_host_name โ€” sets the TLS servername extension on the SSL object $ssl to whatever $name you give it. SNI girlies, this one's for you ๐Ÿ’œ
COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 0.9.8f
my $rv = set_tlsext_host_name($ssl, $name);
# $ssl - value corresponding to openssl's SSL structure
# $name - (string) name to be set
#
# returns: 1 on success, 0 on failure
  • client_hello_isv2 โ€” tells you whether the ClientHello was carried in an SSLv2 record and is therefore in the SSLv2 format. ye olde format, lowkey vintage ๐Ÿ™ˆ
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL
NOTE: to be used only from a callback set with CTX_set_client_hello_cb.
my $rv = client_hello_isv2($s);
# $s - value corresponding to openssl's SSL structure
#
# returns: 1 for SSLv2-format ClientHellos and 0 otherwise

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_isv2.html

  • client_hello_get0_legacy_version โ€” pulls the legacy_version field out of the ClientHello โ€” you might also know it as the client_version field, iykyk ๐ŸŽ€
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL
NOTE: to be used only from a callback set with CTX_set_client_hello_cb.
my $rv = client_hello_get0_legacy_version($s);
# $s - value corresponding to openssl's SSL structure
#
# returns: unsigned integer, for example 0x0303 (TLS v1.2) with TLS 1.3

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_get0_legacy_version.html

  • client_hello_get0_random, client_hello_get0_session_id, client_hello_get0_ciphers and client_hello_get0_compression_methods โ€” the whole squad ๐Ÿ’– they return the random, session_id, cipher_suites and compression_methods fields from the ClientHello, respectively.
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL
NOTE: to be used only from a callback set with CTX_set_client_hello_cb.

These functions return random, session_id, cipher_suites and compression_methods fields from the ClientHello, respectively.

my $random = client_hello_get0_random($s);
my $session_id = client_hello_get0_session_id($s);
my $ciphers = client_hello_get0_ciphers($s);
my $compression_methods = client_hello_get0_compression_methods($s);
# $s - value corresponding to openssl's SSL structure
#
# returns: raw octet data where data length, zero or more, depends on the field definition

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_get0_random.html ๐Ÿฆ‹

  • client_hello_get1_extensions_present and client_hello_get_extension_order โ€” these two are your extension-list besties ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL

NOTE: to be used only from a callback set with CTX_set_client_hello_cb. Like, only there, bestie, don't get cute with it.

Returns a reference to an array holding the numerical value of the TLS extension types in the order they appear in the ClientHello. client_hello_get_extension_order is similar and requires at least OpenSSL 3.2.0, not in LibreSSL.

my $ref = client_hello_get1_extensions_present($s);
# $s - value corresponding to openssl's SSL structure
#
# returns: an array reference of zero or more extension types or undef on failure

Example from a TLS 1.3 ClientHello:

sub client_hello_cb {
    my ($ssl, $arg) = @_;
    my $ref = client_hello_get1_extensions_present($ssl);
    print join(' ', @$ref), "\n" if $ref;
}

Prints: "11 10 35 22 23 13 43 45 51" โœจ

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_get1_extensions_present.html

  • client_hello_get0_ext โ€” grab one single extension out of the ClientHello by its type number ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL

NOTE: to be used only from a callback set with CTX_set_client_hello_cb. Same rule as above, no exceptions.

Returns an extension by type number from the ClientHello.

my $ref = client_hello_get1_extensions_present($s, $type);
# $s - value corresponding to openssl's SSL structure
# $type - (integer) extension type number
#
# returns: zero or more octets of extension contents including extension length, undef if the extension is not present

Example: Get the value of TLS extension "supported_versions". You can use constant "TLSEXT_TYPE_supported_versions" or 43 directly. iykyk ๐ŸŒธ

sub client_hello_cb {
    my ($ssl, $arg) = @_;
    my $ext_ver = Net::SSLeay::client_hello_get0_ext($ssl, Net::SSLeay::TLSEXT_TYPE_supported_versions());
    print unpack('H*', $ext_ver), "\n" if defined $ext_ver;
}

Prints: 080304030303020301 where the first octet 0x08 is the extension length and the following four 16bit values correspond to TLS versions 1.3, 1.2, 1.1 and 1.0. Highkey satisfying to decode, ngl ๐Ÿ’–

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_get0_ext.html


Check openssl doc related to RAND stuff https://www.openssl.org/docs/manmaster/man3/rand.html โ€” literally the whole randomness vibe lives here, go read it ๐Ÿงš

  • RAND_add โ€” mixes the $num bytes at $buf into the PRNG state. Stirring the entropy soup ๐Ÿ“
Net::SSLeay::RAND_add($buf, $num, $entropy);
# $buf - buffer with data to be mixed into the PRNG state
# $num - number of bytes in $buf
# $entropy - estimate of how much randomness is contained in $buf (in bytes)
#
# returns: no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_add.html

  • RAND_seed โ€” equivalent to "RAND_add" when $num == $entropy. Same energy, shorter name, ghosted $num ๐Ÿ˜Œ
Net::SSLeay::RAND_seed($buf);   # Perlishly figures out buf size
# $buf - buffer with data to be mixed into the PRNG state
# $num - number of bytes in $buf
#
# returns: no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_add.html

  • RAND_status โ€” gives PRNG status (seeded enough or not). The vibe check for your random generator ๐Ÿซถ
my $rv = Net::SSLeay::RAND_status();
# returns: 1 if the PRNG has been seeded with enough data, 0 otherwise

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_add.html

  • RAND_bytes โ€” puts $num cryptographically strong pseudo-random bytes into $buf. This is the good stuff, the icon, the main character of randomness ๐Ÿ‘‘
my $rv = Net::SSLeay::RAND_bytes($buf, $num);
# $buf - buffer where the random data will be stored
# $num - the size (in bytes) of requested random data
#
# returns: 1 on success, -1 if not supported by the current RAND method, or 0 on other failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_bytes.html

  • RAND_priv_bytes โ€” also puts $num cryptographically strong pseudo-random bytes into $buf ๐Ÿ”ฅ

COMPATIBILITY: not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL

my $rv = Net::SSLeay::RAND_priv_bytes($buf, $num);
# $buf - buffer where the random data will be stored
# $num - the size (in bytes) of requested random data
#
# returns: 1 on success, -1 if not supported by the current RAND method, or 0 on other failure

RAND_priv_bytes has the same semantics as RAND_bytes, but see see the documentation for more information. (Yes it says "see see" โ€” the manpage is being extra ๐Ÿ’€)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_priv_bytes.html

  • RAND_pseudo_bytes โ€” puts $num pseudo-random (not necessarily unpredictable) bytes into $buf. Budget random, honestly ๐Ÿ™ˆ
my $rv = Net::SSLeay::RAND_pseudo_bytes($buf, $num);
# $buf - buffer where the random data will be stored
# $num - the size (in bytes) of requested random data
#
# returns: 1 if the bytes generated are cryptographically strong, 0 otherwise

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_bytes.html

  • RAND_cleanup โ€” erase the PRNG state. No thoughts, head empty ๐Ÿ’…
Net::SSLeay::RAND_cleanup();
# no args, no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_cleanup.html

  • RAND_egd_bytes โ€” queries the entropy gathering daemon EGD on socket $path for $bytes bytes ๐Ÿฆ‹
my $rv = Net::SSLeay::RAND_egd_bytes($path, $bytes);
# $path - path to a socket of entropy gathering daemon EGD
# $bytes - number of bytes we want from EGD
#
# returns: the number of bytes read from the daemon on success, and -1 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_egd.html

  • RAND_file_name โ€” generates a default path for the random seed file ๐Ÿ“
my $file = Net::SSLeay::RAND_file_name($num);
# $num - maximum size of returned file name
#
# returns: string with file name on success, '' (empty string) or undef on failure

LibreSSL and OpenSSL 1.1.0a and later return undef when, for example, $num is not large enough to hold the filename.

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_load_file.html

  • RAND_load_file โ€” reads $max_bytes of bytes from $file_name and adds them to the PRNG ๐ŸŒธ

COMPATIBILITY: Is no longer functional on LibreSSL

my $rv = Net::SSLeay::RAND_load_file($file_name, $max_bytes);
# $file_name - the name of file
# $max_bytes - bytes to read from $file_name; -1 => the complete file is read
#
# returns: the number of bytes read

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_load_file.html

  • RAND_write_file โ€” writes 1024 random bytes to $file_name which can be used to initialize the PRNG by calling "RAND_load_file" in a later session. Saving your random for later, very mindful ๐ŸŽ€
my $rv = Net::SSLeay::RAND_write_file($file_name);
# $file_name - the name of file
#
# returns: the number of bytes written, and -1 if the bytes written were generated without appropriate seed

Check openssl doc https://www.openssl.org/docs/manmaster/man3/RAND_load_file.html

  • RAND_poll โ€” collects some entropy from operating system and adds it to the PRNG ๐ŸŒฑ
my $rv = Net::SSLeay::RAND_poll();
# returns: 1 on success, 0 on failure (unable to gather reasonable entropy)

  • OBJ_cmp โ€” compares ASN1_OBJECT $a to ASN1_OBJECT $b. Are they twins or not ๐Ÿ’œ
my $rv = Net::SSLeay::OBJ_cmp($a, $b);
# $a - value corresponding to openssl's ASN1_OBJECT structure
# $b - value corresponding to openssl's ASN1_OBJECT structure
#
# returns: if the two are identical 0 is returned

Check openssl doc https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html

  • OBJ_dup โ€” returns a copy/duplicate of $o. Clone it, slay it, keep the original ๐Ÿซถ
my $rv = Net::SSLeay::OBJ_dup($o);
# $o - value corresponding to openssl's ASN1_OBJECT structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html

  • OBJ_nid2ln โ€” returns long name for given NID $n ๐Ÿฆ‹
my $rv = Net::SSLeay::OBJ_nid2ln($n);
# $n - (integer) NID
#
# returns: (string) long name e.g. 'commonName'

Check openssl doc https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html

  • OBJ_ln2nid โ€” returns NID corresponding to given long name $n. Reverse card, uno ๐ŸŽ€
my $rv = Net::SSLeay::OBJ_ln2nid($s);
# $s - (string) long name e.g. 'commonName'
#
# returns: (integer) NID
  • OBJ_nid2sn โ€” returns short name for given NID $n โœจ
my $rv = Net::SSLeay::OBJ_nid2sn($n);
# $n - (integer) NID
#
# returns: (string) short name e.g. 'CN'

Example:

print Net::SSLeay::OBJ_nid2sn(&Net::SSLeay::NID_commonName);
  • OBJ_sn2nid โ€” returns NID corresponding to given short name $s. The other direction, no cap ๐ŸŒˆ
my $rv = Net::SSLeay::OBJ_sn2nid($s);
# $s - (string) short name e.g. 'CN'
#
# returns: (integer) NID

Example:

print "NID_commonName constant=", &Net::SSLeay::NID_commonName;
print "OBJ_sn2nid('CN')=", Net::SSLeay::OBJ_sn2nid('CN');
  • OBJ_nid2obj โ€” returns ASN1_OBJECT for given NID $n ๐Ÿ‘‘
my $rv = Net::SSLeay::OBJ_nid2obj($n);
# $n - (integer) NID
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html

โ€ฆand yeah, the full tea on that one lives here: <https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html> ๐Ÿซถ

  • OBJ_obj2nid โ€” hands you back the NID that goes with the ASN1_OBJECT $o you gave it.
my $rv = Net::SSLeay::OBJ_obj2nid($o);
# $o - value corresponding to openssl's ASN1_OBJECT structure
#
# returns: (integer) NID

Doc drop: <https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html>

  • OBJ_txt2obj โ€” turns the text string s into an ASN1_OBJECT structure, slay. If $no_name is 0 it's super chill and will interpret long names (like 'commonName'), short names (like 'CN') and the numerical forms (like '2.5.4.3'). If $no_name is 1 then nope, only the numerical form is acceptable, that's the whole vibe check.
my $rv = Net::SSLeay::OBJ_txt2obj($s, $no_name);
# $s - text string to be converted
# $no_name - (integer) 0 or 1
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

Doc drop: <https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html>

  • OBJ_obj2txt โ€” the reverse glow-up: converts the ASN1_OBJECT a into a textual representation.
Net::SSLeay::OBJ_obj2txt($a, $no_name);
# $a - value corresponding to openssl's ASN1_OBJECT structure
# $no_name - (integer) 0 or 1
#
# returns: textual representation e.g. 'commonName' ($no_name=0), '2.5.4.3' ($no_name=1)

Doc drop: <https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html>

  • OBJ_txt2nid โ€” gives you the NID for text string $s, and $s can be a long name, a short name, or the numerical representation of an object. Versatile icon ๐Ÿ’…
my $rv = Net::SSLeay::OBJ_txt2nid($s);
# $s - (string) e.g. 'commonName' or 'CN' or '2.5.4.3'
#
# returns: (integer) NID

Example, because seeing it is believing:

my $nid = Net::SSLeay::OBJ_txt2nid('2.5.4.3');
Net::SSLeay::OBJ_nid2sn($n);

Doc drop: <https://www.openssl.org/docs/manmaster/man3/OBJ_nid2obj.html>


  • ASN1_INTEGER_new โ€” creates a brand new ASN1_INTEGER structure, fresh out the box โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::ASN1_INTEGER_new();
#
# returns: value corresponding to openssl's ASN1_INTEGER structure (0 on failure)
  • ASN1_INTEGER_free โ€” frees an allocated ASN1_INTEGER structure. Let it go, bestie ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::ASN1_INTEGER_free($i);
# $i - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: no return value
  • ASN1_INTEGER_get โ€” returns the integer value of the ASN1_INTEGER object you hand it.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

BEWARE: if the value stored in ASN1_INTEGER is bigger than the max integer that fits in the 'long' type (usually 32bit but it may vary by platform), this function returns -1. So if you're dealing with big ASN1_INTEGER values, consider using "P_ASN1_INTEGER_get_dec" or "P_ASN1_INTEGER_get_hex" instead. Like, actually consider it ๐Ÿ˜ญ
my $rv = Net::SSLeay::ASN1_INTEGER_get($a);
# $a - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: integer value of ASN1_INTEGER object in $a
  • ASN1_INTEGER_set โ€” sets the value of the ASN1_INTEGER object to $val.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

BEWARE: $val has a max limit (that's the max integer that fits in 'long' type). For setting large ASN1_INTEGER values, consider "P_ASN1_INTEGER_set_dec" or "P_ASN1_INTEGER_set_hex". Big numbers need the big-girl functions ๐Ÿ”ฅ
my $rv = Net::SSLeay::ASN1_INTEGER_set($i, $val);
# $i - value corresponding to openssl's ASN1_INTEGER structure
# $val - integer value
#
# returns: 1 on success, 0 on failure
  • P_ASN1_INTEGER_get_dec โ€” returns a string with the decimal representation of the integer value of the ASN1_INTEGER object. No -1 jumpscare here ๐Ÿ’€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_ASN1_INTEGER_get_dec($i);
# $i - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: string with decimal representation
  • P_ASN1_INTEGER_get_hex โ€” same energy, but hexadecimal. It returns a string with the hexadecimal representation of the integer value of the ASN1_INTEGER object.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_ASN1_INTEGER_get_hex($i);
# $i - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: string with hexadecimal representation
  • P_ASN1_INTEGER_set_dec โ€” sets the value of the ASN1_INTEGER object to $val (a decimal string, suitable for large integers). Big-number-friendly, we love to see it ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_ASN1_INTEGER_set_dec($i, $str);
# $i - value corresponding to openssl's ASN1_INTEGER structure
# $str - string with decimal representation
#
# returns: 1 on success, 0 on failure
  • P_ASN1_INTEGER_set_hex โ€” sets the value of the ASN1_INTEGER object to $val (a hexadecimal string, suitable for large integers). Same but in hex, periodt.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_ASN1_INTEGER_set_hex($i, $str);
# $i - value corresponding to openssl's ASN1_INTEGER structure
# $str - string with hexadecimal representation
#
# returns: 1 on success, 0 on failure

  • P_ASN1_STRING_get โ€” returns the string value of the ASN1_STRING object. There's an optional $utf8_decode situation: 0 or 1, deciding whether the returned value should be utf8 decoded (default is 0). Choose your fighter ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_ASN1_STRING_get($s, $utf8_decode);
# $s - value corresponding to openssl's ASN1_STRING structure
# $utf8_decode - [optional] 0 or 1 whether the returned value should be utf8 decoded (default=0)
#
# returns: string

And lowkey this:

$string = Net::SSLeay::P_ASN1_STRING_get($s);
# is the same as:
$string = Net::SSLeay::P_ASN1_STRING_get($s, 0);

  • ASN1_TIME_new โ€” spits out a value corresponding to openssl's ASN1_TIME structure.

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $time = ASN1_TIME_new();
# returns: value corresponding to openssl's ASN1_TIME structure
  • ASN1_TIME_free โ€” frees the ASN1_TIME structure. Bye bye ๐Ÿ‘‹

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

ASN1_TIME_free($time);
# $time - value corresponding to openssl's ASN1_TIME structure
  • ASN1_TIME_set โ€” sets the ASN1_TIME structure to $t, where $t is time in seconds since 1.1.1970.

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

ASN1_TIME_set($time, $t);
# $time - value corresponding to openssl's ASN1_TIME structure
# $t - time value in seconds since 1.1.1970
BEWARE: how this function handles dates after 2038 is platform dependent. Perl's integer is large enough, sure, but the internal implementation of this function depends on the size of the time_t structure (32bit time_t has a whole problem with 2038, not cute). If you want to safely set a date and time after 2038, use "P_ASN1_TIME_set_isotime". Future-proof yourself ๐Ÿ”ฎ
  • P_ASN1_TIME_get_isotime โ€” gives you the ISO-8601 string representation of an ASN1_TIME structure.

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

NOTE: does not exactly correspond to any low level API function

my $datetime_string = P_ASN1_TIME_get_isotime($time);
# $time - value corresponding to openssl's ASN1_TIME structure
#
# returns: datetime string like '2033-05-16T20:39:37Z' or '' on failure

The output format is compatible with module DateTime::Format::RFC3339 โ€” iykyk ๐Ÿงš

  • P_ASN1_TIME_set_isotime โ€” sets the time and date value of the ANS1_time structure. (Yes, the original really says ANS1_time, we're keeping it exactly as it is, don't come for me ๐Ÿ’€)

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

NOTE: does not exactly correspond to any low level API function

my $rv = P_ASN1_TIME_set_isotime($time, $string);
# $time - value corresponding to openssl's ASN1_TIME structure
# $string - ISO-8601 timedate string like '2033-05-16T20:39:37Z'
#
# returns: 1 on success, 0 on failure

The $string parameter has to be in full form like "2012-03-22T23:55:33" or "2012-03-22T23:55:33Z" or "2012-03-22T23:55:33CET". Short forms like "2012-03-22T23:55" or "2012-03-22" are not supported. Full form or nothing, bestie, no half-sends ๐Ÿšซ

  • P_ASN1_TIME_put2string โ€” gives you the string representation of an ASN1_TIME structure.

COMPATIBILITY: not available in Net-SSLeay-1.42 and before, has bugs with OpenSSL 0.9.8i

NOTE: does not exactly correspond to any low level API function

my $str = P_ASN1_TIME_put2string($time);
# $time - value corresponding to openssl's ASN1_TIME structure
#
# returns: datetime string like 'May 16 20:39:37 2033 GMT'
  • P_ASN1_UTCTIME_put2string โ€” deprecated function, only hanging around for backward compatibility. It's literally just an alias for "P_ASN1_TIME_put2string". Respectfully, use the other one ๐Ÿซถ

  • X509_new โ€” allocates and initializes an X509 structure. Main character behaviour โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_new();
#
# returns: value corresponding to openssl's X509 structure (0 on failure)

Doc drop: <https://www.openssl.org/docs/manmaster/man3/X509_new.html>

  • X509_free โ€” frees up the X509 structure. Closure, we love her ๐ŸŒธ
Net::SSLeay::X509_free($a);
# $a - value corresponding to openssl's X509 structure
#
# returns: no return value

Doc drop: <https://www.openssl.org/docs/manmaster/man3/X509_new.html>

  • X509_check_host โ€” checks if the certificate's Subject Alternative Name (SAN) or Subject CommonName (CN) matches the host name you specified. The ultimate "are you who you say you are" moment ๐Ÿ”

COMPATIBILITY: not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2. X509_CHECK_FLAG_NEVER_CHECK_SUBJECT requires OpenSSL 1.1.0.

my $rv = Net::SSLeay::X509_check_host($cert, $name, $flags, $peername);
# $cert - value corresponding to openssl's X509 structure
# $name - host name to check
# $flags (optional, default: 0) - can be the bitwise OR of:
#   &Net::SSLeay::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT
#   &Net::SSLeay::X509_CHECK_FLAG_NO_WILDCARDS
#   &Net::SSLeay::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
#   &Net::SSLeay::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS
#   &Net::SSLeay::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS
#   &Net::SSLeay::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT
# $peername (optional) - If not omitted and $host matches $cert,
#                        a copy of the matching SAN or CN from
#                        the peer certificate is stored in $peername.
#
# returns:
#   1 for a successful match
#   0 for a failed match
#  -1 for an internal error
#  -2 if the input is malformed

Peep the OpenSSL doc here: <https://www.openssl.org/docs/manmaster/man3/X509_check_host.html>.

  • X509_check_email โ€” ๐Ÿ’Œ checks whether the cert matches the email address you hand it.
COMPATIBILITY: not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2.
my $rv = Net::SSLeay::X509_check_email($cert, $address, $flags);
# $cert - value corresponding to openssl's X509 structure
# $address - email address to check
# $flags (optional, default: 0) - see X509_check_host()
#
# returns: see X509_check_host()

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_check_email.html>.

  • X509_check_ip โ€” ๐ŸŒ checks whether the cert matches the IPv4 or IPv6 address you give it.
COMPATIBILITY: not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2.
my $rv = Net::SSLeay::X509_check_ip($cert, $address, $flags);
# $cert - value corresponding to openssl's X509 structure
# $address - IP address to check in binary format, in network byte order
# $flags (optional, default: 0) - see X509_check_host()
#
# returns: see X509_check_host()

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_check_ip.html>.

  • X509_check_ip_asc โ€” ๐Ÿ›ฐ๏ธ same energy as X509_check_ip, but the address is in text representation instead of binary.
COMPATIBILITY: not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2.
my $rv = Net::SSLeay::X509_check_ip_asc($cert, $address, $flags);
# $cert - value corresponding to openssl's X509 structure
# $address - IP address to check in text representation
# $flags (optional, default: 0) - see X509_check_host()
#
# returns: see X509_check_host()

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_check_ip_asc.html>.

  • X509_certificate_type โ€” ๐Ÿงช returns a bitmask with the type of certificate $x.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_certificate_type($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: (integer) bitmask with certificate type

# to decode bitmask returned by this function use these constants:
# &Net::SSLeay::EVP_PKS_DSA
# &Net::SSLeay::EVP_PKS_EC
# &Net::SSLeay::EVP_PKS_RSA
# &Net::SSLeay::EVP_PKT_ENC
# &Net::SSLeay::EVP_PKT_EXCH
# &Net::SSLeay::EVP_PKT_EXP
# &Net::SSLeay::EVP_PKT_SIGN
# &Net::SSLeay::EVP_PK_DH
# &Net::SSLeay::EVP_PK_DSA
# &Net::SSLeay::EVP_PK_EC
# &Net::SSLeay::EVP_PK_RSA
  • X509_digest โ€” ๐Ÿ” computes the digest/fingerprint of X509 $data using the $type hash function.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $digest_value = Net::SSLeay::X509_digest($data, $type);
# $data - value corresponding to openssl's X509 structure
# $type - value corresponding to openssl's EVP_MD structure - e.g. got via EVP_get_digestbyname()
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
  • X509_issuer_and_serial_hash โ€” ๐Ÿงฎ sort of a checksum of the issuer name and serial number of X509 certificate $x. It is not a full hash (e.g. sha-1), it is kind-of-a-hash truncated to the size of 'unsigned long' (32 bits). The resulting value might differ across different openssl versions for the same X509 certificate.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_issuer_and_serial_hash($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: number representing checksum
  • X509_issuer_name_hash โ€” ๐Ÿงฎ sort of a checksum of the issuer name of X509 certificate $x. Again, it is not a full hash (e.g. sha-1), it is kind-of-a-hash truncated to the size of 'unsigned long' (32 bits). The resulting value might differ across different openssl versions for the same X509 certificate.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_issuer_name_hash($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: number representing checksum
  • X509_subject_name_hash โ€” ๐Ÿงฎ sort of a checksum of the subject name of X509 certificate $x. Not a full hash (e.g. sha-1), just kind-of-a-hash truncated to the size of 'unsigned long' (32 bits). The resulting value might differ across different openssl versions for the same X509 certificate.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_subject_name_hash($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: number representing checksum
  • X509_pubkey_digest โ€” ๐Ÿ”‘ computes the digest/fingerprint of the public key from X509 certificate $data using the $type hash function.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $digest_value = Net::SSLeay::X509_pubkey_digest($data, $type);
# $data - value corresponding to openssl's X509 structure
# $type - value corresponding to openssl's EVP_MD structure - e.g. got via EVP_get_digestbyname()
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
  • X509_set_issuer_name โ€” ๐Ÿท๏ธ sets the issuer of X509 certificate $x to $name.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_set_issuer_name($x, $name);
# $x - value corresponding to openssl's X509 structure
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: 1 on success, 0 on failure
  • X509_set_pubkey โ€” ๐Ÿ” sets the public key of X509 certificate $x to $pkey.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_set_pubkey($x, $pkey);
# $x - value corresponding to openssl's X509 structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: 1 on success, 0 on failure
  • X509_set_serialNumber โ€” ๐Ÿ”ข sets the serial number of X509 certificate $x to $serial.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_set_serialNumber($x, $serial);
# $x - value corresponding to openssl's X509 structure
# $serial - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: 1 on success, 0 on failure

# to create $serial value use one of these:
$serial = Net::SSLeay::P_ASN1_INTEGER_set_hex('45ad6f');
$serial = Net::SSLeay::P_ASN1_INTEGER_set_dec('7896541238529631478');
$serial = Net::SSLeay::ASN1_INTEGER_set(45896);
  • X509_set_subject_name โ€” ๐Ÿชช sets the subject of X509 certificate $x to $name.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_set_subject_name($x, $name);
# $x - value corresponding to openssl's X509 structure
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: 1 on success, 0 on failure
  • X509_set_version โ€” ๐Ÿท๏ธ set 'version' value for X509 certificate $ to $version.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_set_version($x, $version);
# $x - value corresponding to openssl's X509 structure
# $version - (integer) version number
#
# returns: 1 on success, 0 on failure
  • X509_sign โ€” โœ๏ธ signs X509 certificate $x with private key $pkey (using digest algorithm $md).
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_sign($x, $pkey, $md);
# $x - value corresponding to openssl's X509 structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: 1 on success, 0 on failure
  • X509_verify โ€” โœ… verifies X509 object $a using public key $r (pubkey of issuing CA).
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_verify($x, $r);
# $x - value corresponding to openssl's X509 structure
# $r - value corresponding to openssl's EVP_PKEY structure
#
# returns: 0 - verify failure, 1 - verify OK, <0 - error
  • X509_get_ext_count โ€” ๐Ÿ“ฆ returns the total number of extensions in X509 object $x.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_get_ext_count($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: count of extensions
  • X509_get_pubkey โ€” ๐Ÿ”‘ returns the public key corresponding to the given X509 object $x.
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::X509_get_pubkey($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's EVP_PKEY structure (0 on failure)
NOTE: this method gives you only the public key's key bits โ€” no algorithm, no parameters. If you want the whole public key (SPKI), use X509_get_X509_PUBKEY() instead. ๐Ÿ’…
  • X509_get_X509_PUBKEY โ€” ok so this one gives you the full public key (SPKI) of $x, the X509 certificate you handed it. The other one was giving you crumbs, this gives you the whole meal ๐Ÿ“

COMPATIBILITY: not available in Net-SSLeay-1.72 and before

Net::SSLeay::X509_get_X509_PUBKEY($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: public key data in DER format (binary)
  • X509_get_serialNumber โ€” returns the serial number of the X509 certificate $x. it's giving certificate ID card energy โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_get_serialNumber($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's ASN1_INTEGER structure (0 on failure)

And to actually decode that ASN1_INTEGER object, go see P_ASN1_INTEGER_get_dec, P_ASN1_INTEGER_get_hex or ASN1_INTEGER_get. iykyk ๐Ÿ”ฅ

  • X509_get0_serialNumber โ€” same vibe as X509_get_serialNumber(), the one difference being it takes a const parameter and hands back a const result. lowkey the polite version ๐Ÿ™ˆ

COMPATIBILITY: available in Net-SSLeay-1.86 onwards

  • X509_get_version โ€” returns the 'version' value of the X509 certificate $x. cute!

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_get_version($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: (integer) version
  • X509_get_ext โ€” grabs the X509_EXTENSION out of $x509, picked by position/index. it's a little extension vending machine ๐ŸŽ€
my $rv = Net::SSLeay::X509_get_ext($x509, $index);
# $x509 - value corresponding to openssl's X509 structure
# $index - (integer) position/index of extension within $x509
#
# returns: value corresponding to openssl's X509_EXTENSION structure (0 on failure)
  • X509_get_ext_by_NID โ€” same idea but you look the extension up by its NID, not its index. slay ๐Ÿ’…
my $rv = Net::SSLeay::X509_get_ext_by_NID($x509, $nid, $loc);
# $x509 - value corresponding to openssl's X509 structure
# $nid - (integer) NID value
# $loc - (integer) position to start lookup at
#
# returns: position/index of extension, negative value on error
#          call Net::SSLeay::X509_get_ext($x509, $rv) to get the actual extension
bestie, note the plot twist: this gives you the position, not the extension itself. you gotta follow up with Net::SSLeay::X509_get_ext($x509, $rv) to actually get it. two-step icon behavior ๐Ÿ‘‘
  • X509_get_fingerprint โ€” returns the fingerprint of certificate $cert. very main character forensic energy ๐Ÿ”

NOTE: this does not exactly correspond to any low level API function. The implementation is based on openssl's X509_digest().

Net::SSLeay::X509_get_fingerprint($x509, $type);
# $x509 - value corresponding to openssl's X509 structure
# $type - (string) digest type, currently supported values:
#         "md5"
#         "sha1"
#         "sha256"
#         "ripemd160"
#
# returns: certificate digest - hexadecimal string (NOT binary data!)
fr fr it's a hexadecimal string, NOT binary data. don't come for me when you try to treat it as bytes ๐Ÿ˜ญ
  • X509_get_issuer_name โ€” returns an X509_NAME object representing the issuer of the certificate $cert. it's giving "who even signed this" energy ๐Ÿงš
my $rv = Net::SSLeay::X509_get_issuer_name($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)
  • X509_get0_notAfter, X509_getm_notAfter and X509_get_notAfter โ€” these return an object telling you the time after which the certificate $cert is not valid. expiry check bestie, the vibe check of doom ๐Ÿ’€

COMPATIBILITY: X509_get0_notAfter and X509_getm_notAfter are not available in Net-SSLeay-1.92 and before

my $rv  = Net::SSLeay::X509_get0_notAfter($cert);
my $rvm = Net::SSLeay::X509_getm_notAfter($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: $rv  read-only value corresponding to openssl's ASN1_TIME structure
#          $rvm mutable   value corresponding to openssl's ASN1_TIME structure

To get it in human readable/printable form, you can do this:

my $time = Net::SSLeay::X509_get_notAfter($cert);
print "notAfter=", Net::SSLeay::P_ASN1_TIME_get_isotime($time), "\n";

NOTE: X509_get_notAfter is an alias and deprecated in OpenSSL 1.1.0 and later ๐Ÿซถ

Check the openssl doc: <https://www.openssl.org/docs/manmaster/man3/X509_get0_notAfter.html>

  • X509_get0_notBefore, X509_getm_notBefore and X509_get_notBefore โ€” and these give you the time before which the certificate $cert is not valid. the other end of the window, duality queen ๐ŸŒธ

COMPATIBILITY: X509_get0_notBefore and X509_getm_notBefore are not available in Net-SSLeay-1.92 and before

my $rv  = Net::SSLeay::X509_get0_notBefore($cert);
my $rvm = Net::SSLeay::X509_getm_notBefore($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: $rv  read-only value corresponding to openssl's ASN1_TIME structure
#          $rvm mutable   value corresponding to openssl's ASN1_TIME structure

Human readable/printable version, coming right up:

my $time = Net::SSLeay::X509_get_notBefore($cert);
print "notBefore=", Net::SSLeay::P_ASN1_TIME_get_isotime($time), "\n";

NOTE: X509_get_notBefore is an alias and deprecated in OpenSSL 1.1.0 and later ๐Ÿซถ

Check the openssl doc: <https://www.openssl.org/docs/manmaster/man3/X509_get0_notBefore.html>

  • X509_get_subjectAltNames โ€” returns the list of alternative subject names from the X509 certificate $cert. SANs, babes, the whole guest list ๐ŸŒˆ

NOTE: this does not exactly correspond to any low level API function.

my @rv = Net::SSLeay::X509_get_subjectAltNames($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: list containing pairs - name_type (integer), name_value (string)
#          where name_type can be:
#          0 - GEN_OTHERNAME
#          1 - GEN_EMAIL
#          2 - GEN_DNS
#          3 - GEN_X400
#          4 - GEN_DIRNAME
#          5 - GEN_EDIPARTY
#          6 - GEN_URI
#          7 - GEN_IPADD
#          8 - GEN_RID

Note: type 7 โ€” GEN_IPADD โ€” contains the IP address as a packed binary address. GEN_RID is available in Net-SSLeay-1.90 and later. Maximum length for the returned RID string is currently 2500. Invalid and overly long RID values get skipped and are not returned. GEN_X400 and GEN_EDIPARTY are not supported and will not be returned even when present in the certificate. not me being picky, it's just how it is ๐Ÿ™ˆ

  • X509_get_subject_name โ€” returns the subject of the certificate $cert. the "who even is this" of the certificate world ๐Ÿ’–
my $rv = Net::SSLeay::X509_get_subject_name($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)
  • X509_gmtime_adj โ€” adjusts the ASN1_TIME object to the timestamp (in GMT). time travel but make it ASN1 โฐ
my $rv = Net::SSLeay::X509_gmtime_adj($s, $adj);
# $s - value corresponding to openssl's ASN1_TIME structure
# $adj - timestamp (seconds since 1.1.1970)
#
# returns: value corresponding to openssl's ASN1_TIME structure (0 on failure)
BEWARE: this function may fail for dates after 2038 because it's dependent on time_t size on your system (32bit time_t does not work after 2038). Consider using P_ASN1_TIME_set_isotime instead. no cap, the year 2038 is coming for this one ๐Ÿ˜ญ
  • X509_load_cert_crl_file โ€” takes a PEM file and loads all the X509 certificates and X509 CRLs from that file into the X509_LOOKUP structure. bulk haul, we love a two-for-one ๐Ÿ›๏ธ
my $rv = Net::SSLeay::X509_load_cert_crl_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's X509_LOOKUP structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#                          if not FILETYPE_PEM then behaves as Net::SSLeay::X509_load_cert_file()
#
# returns: 1 on success, 0 on failure
heads up: if $type is not FILETYPE_PEM then it behaves as Net::SSLeay::X509_load_cert_file(). sneaky little plot twist ๐ŸŒ€
  • X509_load_cert_file โ€” loads/adds the X509 certificate from $file into the X509_LOOKUP structure. one cert, one mission โœจ
my $rv = Net::SSLeay::X509_load_cert_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's X509_LOOKUP structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, 0 on failure
  • X509_load_crl_file โ€” loads/adds the X509 CRL from $file into the X509_LOOKUP structure. revocation list bestie, the blocked list ๐Ÿ’…
my $rv = Net::SSLeay::X509_load_crl_file($ctx, $file, $type);
# $ctx - value corresponding to openssl's X509_LOOKUP structure
# $file - (string) file name
# $type - (integer) type - use constants &Net::SSLeay::FILETYPE_PEM or &Net::SSLeay::FILETYPE_ASN1
#
# returns: 1 on success, 0 on failure
  • X509_policy_level_get0_node โ€” honestly, ??? (more info needed). the docs are giving "we'll finish this later" ๐Ÿฆ‹

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

my $rv = Net::SSLeay::X509_policy_level_get0_node($level, $i);
# $level - value corresponding to openssl's X509_POLICY_LEVEL structure
# $i - (integer) index/position
#
# returns: value corresponding to openssl's X509_POLICY_NODE structure (0 on failure)
  • X509_policy_level_node_count โ€” also ??? (more info needed). yeah. same vibe ๐Ÿ˜ญ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

my $rv = Net::SSLeay::X509_policy_level_node_count($level);
# $level - value corresponding to openssl's X509_POLICY_LEVEL structure
#
# returns: (integer) node count
  • X509_policy_node_get0_parent โ€” ??? (more info needed) again, bestie ๐Ÿ™ˆ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

my $rv = Net::SSLeay::X509_policy_node_get0_parent($node);
# $node - value corresponding to openssl's X509_POLICY_NODE structure
#
# returns: value corresponding to openssl's X509_POLICY_NODE structure (0 on failure)
  • X509_policy_node_get0_policy โ€” ??? (more info needed), and yes it's still happening ๐Ÿซถ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

my $rv = Net::SSLeay::X509_policy_node_get0_policy($node);
# $node - value corresponding to openssl's X509_POLICY_NODE structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)
  • X509_policy_node_get0_qualifiers โ€” ??? (more info needed), the saga continues ๐Ÿ’€

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

okay so we're still in the function zone, continuing where we left off ๐Ÿ’…

my $rv = Net::SSLeay::X509_policy_node_get0_qualifiers($node);
# $node - value corresponding to openssl's X509_POLICY_NODE structure
#
# returns: value corresponding to openssl's STACK_OF(POLICYQUALINFO) structure (0 on failure)
  • X509_policy_tree_free โ€” frees the policy tree, that's it, that's the whole job ๐ŸŽ€

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

??? (more info needed)

Net::SSLeay::X509_policy_tree_free($tree);
# $tree - value corresponding to openssl's X509_POLICY_TREE structure
#
# returns: no return value
  • X509_policy_tree_get0_level โ€” grabs you the level at index $i out of the policy tree โœจ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

??? (more info needed)

my $rv = Net::SSLeay::X509_policy_tree_get0_level($tree, $i);
# $tree - value corresponding to openssl's X509_POLICY_TREE structure
# $i - (integer) level index
#
# returns: value corresponding to openssl's X509_POLICY_LEVEL structure (0 on failure)
  • X509_policy_tree_get0_policies โ€” pulls the policies stack out of the tree, lowkey straightforward ๐ŸŒธ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

??? (more info needed)

my $rv = Net::SSLeay::X509_policy_tree_get0_policies($tree);
# $tree - value corresponding to openssl's X509_POLICY_TREE structure
#
# returns: value corresponding to openssl's STACK_OF(X509_POLICY_NODE) structure (0 on failure)
  • X509_policy_tree_get0_user_policies โ€” same energy as above but it's the user policies bestie ๐Ÿซถ

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

??? (more info needed)

my $rv = Net::SSLeay::X509_policy_tree_get0_user_policies($tree);
# $tree - value corresponding to openssl's X509_POLICY_TREE structure
#
# returns: value corresponding to openssl's STACK_OF(X509_POLICY_NODE) structure (0 on failure)
  • X509_policy_tree_level_count โ€” literally just tells you how many levels the tree has ๐Ÿฆ‹

COMPATIBILITY: no longer available in LibreSSL 3.8.0 and later

??? (more info needed)

my $rv = Net::SSLeay::X509_policy_tree_level_count($tree);
# $tree - value corresponding to openssl's X509_POLICY_TREE structure
#
# returns: (integer) count
  • X509_verify_cert_error_string โ€” feed it a numeric verification error code and it hands you back a human readable error string ๐Ÿ’–
my $rv = Net::SSLeay::X509_verify_cert_error_string($n);
# $n - (long) numeric error code
#
# returns: error string

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html>

  • P_X509_add_extensions โ€” adds one or more X509 extensions onto X509 object $x โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_add_extensions($x, $ca_cert, $nid, $value);
# $x - value corresponding to openssl's X509 structure
# $ca_cert - value corresponding to openssl's X509 structure (issuer's cert - necessary for setting NID_authority_key_identifier)
# $nid - NID identifying extension to be set
# $value - extension value
#
# returns: 1 on success, 0 on failure

and bestie, you can set a whole bunch of extensions at once, it's giving efficiency ๐Ÿ’…

my $rv = Net::SSLeay::P_X509_add_extensions($x509, $ca_cert,
            &Net::SSLeay::NID_key_usage => 'digitalSignature,keyEncipherment',
            &Net::SSLeay::NID_subject_key_identifier => 'hash',
            &Net::SSLeay::NID_authority_key_identifier => 'keyid',
            &Net::SSLeay::NID_authority_key_identifier => 'issuer',
            &Net::SSLeay::NID_basic_constraints => 'CA:FALSE',
            &Net::SSLeay::NID_ext_key_usage => 'serverAuth,clientAuth',
            &Net::SSLeay::NID_netscape_cert_type => 'server',
            &Net::SSLeay::NID_subject_alt_name => 'DNS:s1.dom.com,DNS:s2.dom.com,DNS:s3.dom.com',
      );
  • P_X509_copy_extensions โ€” copies X509 extensions from an X509_REQ object over to an X509 object, which is honestly so handy when you need to turn an X509_REQ into an X509 certificate ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_X509_copy_extensions($x509_req, $x509, $override);
# $x509_req - value corresponding to openssl's X509_REQ structure
# $x509 - value corresponding to openssl's X509 structure
# $override - (integer) flag indication whether to override already existing items in $x509 (default 1)
#
# returns: 1 on success, 0 on failure
  • P_X509_get_crl_distribution_points โ€” gets you the list of CRL distribution points from an X509 certificate ๐ŸŒˆ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my @cdp = Net::SSLeay::P_X509_get_crl_distribution_points($x509);
# $x509 - value corresponding to openssl's X509 structure
#
# returns: list of distribution points (usually URLs)
  • P_X509_get_ext_key_usage โ€” gets the list of extended key usage of the given X509 certificate $cert ๐Ÿ”ฅ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my @ext_usage = Net::SSLeay::P_X509_get_ext_key_usage($cert, $format);
# $cert - value corresponding to openssl's X509 structure
# $format - choose type of return values: 0=OIDs, 1=NIDs, 2=shortnames, 3=longnames
#
# returns: list of values

Examples, because seeing it is believing ๐Ÿ‘‘

my @extkeyusage_oid = Net::SSLeay::P_X509_get_ext_key_usage($x509,0);
# returns for example: ("1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.2")

my @extkeyusage_nid = Net::SSLeay::P_X509_get_ext_key_usage($x509,1);
# returns for example: (129, 130)

my @extkeyusage_sn  = Net::SSLeay::P_X509_get_ext_key_usage($x509,2);
# returns for example: ("serverAuth", "clientAuth")

my @extkeyusage_ln  = Net::SSLeay::P_X509_get_ext_key_usage($x509,3);
# returns for example: ("TLS Web Server Authentication",  "TLS Web Client Authentication")
  • P_X509_get_key_usage โ€” gets the list of key usage of the given X509 certificate $cert ๐Ÿ’œ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my @keyusage = Net::SSLeay::P_X509_get_key_usage($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: list of key usage values which can be none, one or more from the following list:
#          "digitalSignature"
#          "nonRepudiation"
#          "keyEncipherment"
#          "dataEncipherment"
#          "keyAgreement"
#          "keyCertSign"
#          "cRLSign"
#          "encipherOnly"
#          "decipherOnly"
  • P_X509_get_netscape_cert_type โ€” gets the list of Netscape cert types of the given X509 certificate $cert ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_X509_get_netscape_cert_type($cert);
# $cert - value corresponding to openssl's X509 structure
#
# returns: list of Netscape type values which can be none, one or more from the following list:
#          "client"
#          "server"
#          "email"
#          "objsign"
#          "reserved"
#          "sslCA"
#          "emailCA"
#          "objCA"
  • P_X509_get_pubkey_alg โ€” returns the ASN1_OBJECT that corresponds to the X509 certificate's public key algorithm โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_get_pubkey_alg($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

want the textual representation? do this ๐ŸŽ€

my $alg = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_pubkey_alg($x509));
# returns for example: "rsaEncryption"
  • P_X509_get_signature_alg โ€” returns the ASN1_OBJECT that corresponds to the X509 signature key algorithm ๐ŸŒธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_get_signature_alg($x);
# $x - value corresponding to openssl's X509 structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

and again, for the textual version ๐Ÿ’–

my $alg = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_signature_alg($x509));
# returns for example: "sha1WithRSAEncryption"
  • sk_X509_new_null โ€” hands you a brand new, empty, STACK_OF(X509) structure, a fresh little baby stack ๐Ÿซถ
my $rv = Net::SSLeay::sk_X509_new_null();
#
# returns: value corresponding to openssl's STACK_OF(X509) structure
  • sk_X509_push โ€” pushes an X509 structure onto a STACK_OF(X509) structure ๐Ÿ”ฅ
my $rv = Net::SSLeay::sk_X509_push($sk_x509, $x509);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
# $x509 - value corresponding to openssl's X509 structure
#
# returns: total number of elements after the operation, 0 on failure
  • sk_X509_pop โ€” pops a single X509 structure off a STACK_OF(X509) structure ๐Ÿ’…
my $x509 = Net::SSLeay::sk_X509_pop($sk_x509);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
#
# returns: a pointer to an X509 structure, undef on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/sk_TYPE_pop.html>

  • sk_X509_shift โ€” shifts a single X509 structure onto a STACK_OF(X509) structure (yes bestie, that's what it says, we're just relaying the message) ๐Ÿ™ˆ
my $x509 = Net::SSLeay::sk_X509_shift($sk_x509, $x509);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
# $x509 - value corresponding to openssl's X509 structure
#
# returns: a pointer to an X509 structure, undef on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/sk_TYPE_shift.html>

  • sk_X509_unshift โ€” unshifts a single X509 structure from a STACK_OF(X509) structure โญ
my $rv = Net::SSLeay::sk_X509_unshift($sk_x509);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
#
# returns: total number of elements after the operation, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/sk_TYPE_unshift.html>

  • sk_X509_insert โ€” inserts a single X509 structure into a STACK_OF(X509) at the specified index ๐Ÿ‘‘
my $rv = Net::SSLeay::sk_X509_insert($sk_x509, $x509, $index);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
# $x509 - value corresponding to openssl's X509 structure
# $index - integer - 0 based index
#
# returns: total number of elements after the operation, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/sk_TYPE_insert.html

  • sk_X509_delete โ€” yeets one single X509 structure out of a STACK_OF(X509), right at the index you point at ๐Ÿ’…
my $x509 = Net::SSLeay::sk_X509_delete($sk_x509, $index);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
# $index - integer - 0 based index
#
# returns: a pointer to an X509 structure, undef on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/sk_TYPE_delete.html

  • sk_X509_value โ€” grabs you one single X509 structure from the STACK_OF(X509) sitting at that index ๐ŸŽ€
my $x509 = Net::SSLeay::sk_X509_value($sk_x509, $index);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
# $index - integer - 0 based index
#
# returns: a pointer to an X509 structure, undef on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/sk_TYPE_value.html

  • sk_X509_num โ€” how many X509 elements are vibing in this STACK_OF(X509)? it tells you ๐Ÿ”ข
my $num = Net::SSLeay::sk_X509_num($sk_x509);
# $sk_x509 - value corresponding to openssl's STACK_OF(X509) structure
#
# returns: the number of elements in the stack, -1 if the passed stack is NULL

Check openssl doc https://www.openssl.org/docs/manmaster/man3/sk_TYPE_num.html


  • X509_REQ_new โ€” births a brand new X509_REQ structure, no cap it's a fresh baby ๐Ÿ‘‘

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_new();
#
# returns: value corresponding to openssl's X509_REQ structure (0 on failure)
  • X509_REQ_free โ€” frees an allocated X509_REQ structure, releasing it back into the wild ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::X509_REQ_free($x);
# $x - value corresponding to openssl's X509_REQ structure
#
# returns: no return value
  • X509_REQ_add1_attr_by_NID โ€” adds an attribute whose name is defined by a NID $nid, and the field value you're adding lives in $bytes โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_add1_attr_by_NID($req, $nid, $type, $bytes);
# $req - value corresponding to openssl's X509_REQ structure
# $nid - (integer) NID value
# $type - (integer) type of data in $bytes (see below)
# $bytes - data to be set
#
# returns: 1 on success, 0 on failure

# values for $type - use constants:
# &Net::SSLeay::MBSTRING_UTF8     - $bytes contains utf8 encoded data
# &Net::SSLeay::MBSTRING_ASC      - $bytes contains ASCII data
  • X509_REQ_digest โ€” computes the digest/fingerprint of X509_REQ $data using the $type hash function, it's giving crypto glam ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $digest_value = Net::SSLeay::X509_REQ_digest($data, $type);
# $data - value corresponding to openssl's X509_REQ structure
# $type - value corresponding to openssl's EVP_MD structure - e.g. got via EVP_get_digestbyname()
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
  • X509_REQ_get_attr_by_NID โ€” retrieves the next index matching $nid after $lastpos (and bestie, $lastpos should initially be set to -1) ๐Ÿ”

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_attr_by_NID($req, $nid, $lastpos=-1);
# $req - value corresponding to openssl's X509_REQ structure
# $nid - (integer) NID value
# $lastpos - [optional] (integer) index where to start search (default -1)
#
# returns: index (-1 if there are no more entries)

Note: use P_X509_REQ_get_attr to get the actual attribute value โ€” e.g.

my $index = Net::SSLeay::X509_REQ_get_attr_by_NID($req, $nid);
my @attr_values = Net::SSLeay::P_X509_REQ_get_attr($req, $index);
  • X509_REQ_get_attr_by_OBJ โ€” retrieves the next index matching $obj after $lastpos ($lastpos should initially be set to -1 too, iykyk) ๐Ÿ”Ž

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_attr_by_OBJ($req, $obj, $lastpos=-1);
# $req - value corresponding to openssl's X509_REQ structure
# $obj - value corresponding to openssl's ASN1_OBJECT structure
# $lastpos - [optional] (integer) index where to start search (default -1)
#
# returns: index (-1 if there are no more entries)

Note: use P_X509_REQ_get_attr to get the actual attribute value โ€” e.g.

my $index = Net::SSLeay::X509_REQ_get_attr_by_NID($req, $nid);
my @attr_values = Net::SSLeay::P_X509_REQ_get_attr($req, $index);
  • X509_REQ_get_attr_count โ€” returns the total number of attributes in $req, just a lil headcount ๐Ÿงฎ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_attr_count($req);
# $req - value corresponding to openssl's X509_REQ structure
#
# returns: (integer) items count
  • X509_REQ_get_pubkey โ€” returns the public key corresponding to the given X509_REQ object $x ๐Ÿ”‘๐Ÿ’–

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_pubkey($x);
# $x - value corresponding to openssl's X509_REQ structure
#
# returns: value corresponding to openssl's EVP_PKEY structure (0 on failure)
  • X509_REQ_get_subject_name โ€” returns the X509_NAME object for the subject name of the given X509_REQ object $x, iconic behaviour honestly ๐Ÿ“›

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_subject_name($x);
# $x - value corresponding to openssl's X509_REQ structure
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)
  • X509_REQ_get_version โ€” returns the 'version' value for the given X509_REQ object $x ๐Ÿท๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_get_version($x);
# $x - value corresponding to openssl's X509_REQ structure
#
# returns: (integer) version e.g. 0 = "version 1"
  • X509_REQ_set_pubkey โ€” sets the public key of the given X509_REQ object $x to $pkey, glow-up incoming โœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_set_pubkey($x, $pkey);
# $x - value corresponding to openssl's X509_REQ structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
#
# returns: 1 on success, 0 on failure
  • X509_REQ_set_subject_name โ€” sets the subject name of the given X509_REQ object $x to the X509_NAME object $name ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_set_subject_name($x, $name);
# $x - value corresponding to openssl's X509_REQ structure
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: 1 on success, 0 on failure
  • X509_REQ_set_version โ€” sets the 'version' of the given X509_REQ object $x to $version ๐Ÿ”ข

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_set_version($x, $version);
# $x - value corresponding to openssl's X509_REQ structure
# $version - (integer) e.g. 0 = "version 1"
#
# returns: 1 on success, 0 on failure
  • X509_REQ_sign โ€” signs the X509_REQ object $x with the private key $pk (using digest algorithm $md), put your signature on it bestie โœ๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_sign($x, $pk, $md);
# $x - value corresponding to openssl's X509_REQ structure
# $pk - value corresponding to openssl's EVP_PKEY structure (requestor's private key)
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: 1 on success, 0 on failure
  • X509_REQ_verify โ€” verifies the X509_REQ object $x using public key $r (that's the pubkey of the requesting party, no cap) โœ…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_REQ_verify($x, $r);
# $x - value corresponding to openssl's X509_REQ structure
# $r - value corresponding to openssl's EVP_PKEY structure
#
# returns: 0 - verify failure, 1 - verify OK, <0 - error
  • P_X509_REQ_add_extensions โ€” adds one or more X509 extensions to the X509_REQ object $x, let's stack 'em ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_REQ_add_extensions($x, $nid, $value);
# $x - value corresponding to openssl's X509_REQ structure
# $nid - NID identifying extension to be set
# $value - extension value
#
# returns: 1 on success, 0 on failure

And you can set more extensions at once, look at her go:

my $rv = Net::SSLeay::P_X509_REQ_add_extensions($x509_req,
        &Net::SSLeay::NID_key_usage => 'digitalSignature,keyEncipherment',
        &Net::SSLeay::NID_basic_constraints => 'CA:FALSE',
        &Net::SSLeay::NID_ext_key_usage => 'serverAuth,clientAuth',
        &Net::SSLeay::NID_netscape_cert_type => 'server',
        &Net::SSLeay::NID_subject_alt_name => 'DNS:s1.com,DNS:s2.com',
        &Net::SSLeay::NID_crl_distribution_points => 'URI:http://pki.com/crl1,URI:http://pki.com/crl2',
      );
  • P_X509_REQ_get_attr โ€” returns the attribute value for X509_REQ's attribute sitting at index $n ๐Ÿ“

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_X509_REQ_get_attr($req, $n);
# $req - value corresponding to openssl's X509_REQ structure
# $n - (integer) attribute index
#
# returns: value corresponding to openssl's ASN1_STRING structure

  • X509_CRL_new โ€” creates a new X509_CRL structure, brand new CRL energy fr fr ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_new();
#
# returns: value corresponding to openssl's X509_CRL structure (0 on failure)
  • X509_CRL_free โ€” frees an allocated X509_CRL structure. bye bestie, go free yourself ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::X509_CRL_free($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: no return value
  • X509_CRL_digest โ€” computes the digest/fingerprint of X509_CRL $data using the $type hash function. it's giving "unique fingerprint energy" ๐Ÿ”ฅ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $digest_value = Net::SSLeay::X509_CRL_digest($data, $type);
# $data - value corresponding to openssl's X509_CRL structure
# $type - value corresponding to openssl's EVP_MD structure - e.g. got via EVP_get_digestbyname()
#
# returns: hash value (binary)

Example, because seeing it is believing โœจ

my $x509_crl;
my $md = Net::SSLeay::EVP_get_digestbyname("sha1");
my $digest_value = Net::SSLeay::X509_CRL_digest($x509_crl, $md);
# to get printable (hex) value of digest use:
print "digest=", unpack('H*', $digest_value), "\n";
  • X509_CRL_get_ext โ€” hands you the X509_EXTENSION from $x509 based on the position/index you ask for. it's like going "gimme the third one" ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.54 and before

my $rv = Net::SSLeay::X509_CRL_get_ext($x509, $index);
# $x509 - value corresponding to openssl's X509_CRL structure
# $index - (integer) position/index of extension within $x509
#
# returns: value corresponding to openssl's X509_EXTENSION structure (0 on failure)
  • X509_CRL_get_ext_by_NID โ€” same vibe but you look the extension up by its NID instead of its position. iykyk ๐ŸŒธ

COMPATIBILITY: not available in Net-SSLeay-1.54 and before

my $rv = Net::SSLeay::X509_CRL_get_ext_by_NID($x509, $nid, $loc);
# $x509 - value corresponding to openssl's X509_CRL structure
# $nid - (integer) NID value
# $loc - (integer) position to start lookup at
#
# returns: position/index of extension, negative value on error
#          call Net::SSLeay::X509_CRL_get_ext($x509, $rv) to get the actual extension
lowkey important: this one gives you the position, not the extension itself. so you gotta follow up with Net::SSLeay::X509_CRL_get_ext($x509, $rv) to actually grab it. no cap ๐Ÿ’€
  • X509_CRL_get_ext_count โ€” the total number of extensions sitting in the X509_CRL object $x. counting era ๐Ÿ‘‘

COMPATIBILITY: not available in Net-SSLeay-1.54 and before

my $rv = Net::SSLeay::X509_CRL_get_ext_count($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: count of extensions
  • X509_CRL_get_issuer โ€” returns the X509_NAME object that corresponds to the issuer of X509_CRL $x. who signed off on this, fr fr ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_get_issuer($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)

See the other X509_NAME_* functions if you want more info out of that X509_NAME structure. main character cross-referencing ๐Ÿ’–

  • X509_CRL_get0_lastUpdate and X509_CRL_get_lastUpdate โ€” returns the 'lastUpdate' date-time value of the X509_CRL object $x. when was this last touched, bestie ๐Ÿ•ฐ๏ธ

COMPATIBILITY: X509_CRL_get0_lastUpdate not available in Net-SSLeay-1.92 and before, X509_CRL_get_lastUpdate not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_get0_lastUpdate($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: read-only value corresponding to openssl's ASN1_TIME structure
NOTE: X509_CRL_get_lastUpdate is an alias and deprecated in OpenSSL 1.1.0 and later. so like... use the get0 one, bestie ๐Ÿ™ˆ

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_CRL_get0_lastUpdate.html

  • X509_CRL_get0_nextUpdate and X509_CRL_get_nextUpdate โ€” returns the 'nextUpdate' date-time value of the X509_CRL object $x. the "when's the next drop" of it all โญ

COMPATIBILITY: X509_CRL_get0_nextUpdate not available in Net-SSLeay-1.92 and before, X509_CRL_get_nextUpdate not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_get0_nextUpdate($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: read-only value corresponding to openssl's ASN1_TIME structure or 0 if 'nextUpdate' is not set
NOTE: X509_CRL_get_nextUpdate is an alias and deprecated in OpenSSL 1.1.0 and later. same deal, use the get0 version ๐Ÿ’€

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_CRL_get0_nextUpdate.html

  • X509_CRL_get_version โ€” returns the 'version' value of the given X509_CRL structure $x. integer moment ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_get_version($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: (integer) version
  • X509_CRL_set_issuer_name โ€” sets the issuer of X509_CRL object $x to the X509_NAME object $name. putting a name on it ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_set_issuer_name($x, $name);
# $x - value corresponding to openssl's X509_CRL structure
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: 1 on success, 0 on failure
  • X509_CRL_set1_lastUpdate and X509_CRL_set_lastUpdate โ€” sets the 'lastUpdate' value of X509_CRL object $x to $tm. stamping the time, slay ๐Ÿ•ฐ๏ธ

COMPATIBILITY: X509_CRL_set1_lastUpdate not available in Net-SSLeay-1.92 and before, X509_CRL_set_lastUpdate not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_set1_lastUpdate($x, $tm);
# $x - value corresponding to openssl's X509_CRL structure
# $tm - value corresponding to openssl's ASN1_TIME structure
#
# returns: 1 on success, 0 on failure
NOTE: X509_CRL_set_lastUpdate is an alias and deprecated in OpenSSL 1.1.0 and later. the set1 one is the moment ๐Ÿ™ˆ

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_CRL_set1_lastUpdate.html

  • X509_CRL_set1_nextUpdate and X509_CRL_set_nextUpdate โ€” sets the 'nextUpdate' value of X509_CRL object $x to $tm. scheduling the next chapter โœจ

COMPATIBILITY: X509_CRL_set1_nextUpdate not available in Net-SSLeay-1.92 and before, X509_CRL_set_nextUpdate not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_set1_nextUpdate($x, $tm);
# $x - value corresponding to openssl's X509_CRL structure
# $tm - value corresponding to openssl's ASN1_TIME structure
#
# returns: 1 on success, 0 on failure
NOTE: X509_CRL_set_nextUpdate is an alias and deprecated in OpenSSL 1.1.0 and later. again โ€” set1 girlies stay winning ๐Ÿ’…

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_CRL_set1_nextUpdate.html

  • X509_CRL_set_version โ€” sets the 'version' value of the given X509_CRL structure $x to $version. numbers, but make it official ๐Ÿ”ข

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_set_version($x, $version);
# $x - value corresponding to openssl's X509_CRL structure
# $version - (integer) version number (1 = version 2 CRL)
#
# returns: 1 on success, 0 on failure
Note: if you wanna use any X509_CRL extension you need to set "version 2 CRL" first โ€” like Net::SSLeay::X509_CRL_set_version($x, 1). no version 2, no extensions, periodt ๐Ÿซถ
  • X509_CRL_sign โ€” signs the X509_CRL object $x with the private key $pkey, using digest algorithm $md. signing it like it's a yearbook ๐Ÿ–Š๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_sign($x, $pkey, $md);
# $x - value corresponding to openssl's X509_CRL structure
# $pkey - value corresponding to openssl's EVP_PKEY structure
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: 1 on success, 0 on failure
  • X509_CRL_sort โ€” sorts the data of the X509_CRL object so it gets written in serial number order. organizing the group chat by serial, iconic ๐Ÿงš

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_sort($x);
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: 1 on success, 0 on failure
  • X509_CRL_verify โ€” verifies the X509_CRL object $a using public key $r (the pubkey of the issuing CA). vibe check on the signature ๐Ÿ”

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_CRL_verify($a, $r);
# $a - value corresponding to openssl's X509_CRL structure
# $r - value corresponding to openssl's EVP_PKEY structure
#
# returns: 0 - verify failure, 1 - verify OK, <0 - error
careful bestie: 0 means the verify failed and <0 means an error. don't get it twisted ๐Ÿ’€
  • P_X509_CRL_add_revoked_serial_hex โ€” adds the given serial number $serial_hex to the X509_CRL object $crl. adding someone to the revoked list, we been knew ๐Ÿ™ˆ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::P_X509_CRL_add_revoked_serial_hex($crl, $serial_hex, $rev_time, $reason_code, $comp_time);
# $crl - value corresponding to openssl's X509_CRL structure
# $serial_hex - string (hexadecimal) representation of serial number
# $rev_time - (revocation time) value corresponding to openssl's ASN1_TIME structure
# $reason_code - [optional] (integer) reason code (see below) - default 0
# $comp_time - [optional] (compromise time) value corresponding to openssl's ASN1_TIME structure
#
# returns: no return value
# reason codes:
# 0 - unspecified
# 1 - keyCompromise
# 2 - CACompromise
# 3 - affiliationChanged
# 4 - superseded
# 5 - cessationOfOperation
# 6 - certificateHold
# 7 - (value 7 is not used)
# 8 - removeFromCRL
# 9 - privilegeWithdrawn
# 10 - aACompromise
note that $reason_code defaults to 0 and both it and $comp_time are optional ๐ŸŽ€
  • P_X509_CRL_get_serial โ€” returns the serial number of the X509_CRL object. the ID of the whole situation ๐Ÿ”–

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_CRL_get_serial($crl);
# $crl - value corresponding to openssl's X509_CRL structure
#
# returns: value corresponding to openssl's ASN1_INTEGER structure (0 on failure)
  • P_X509_CRL_set_serial โ€” sets the serial number of the X509_CRL object to $crl_number. renaming the whole thing, honestly ๐ŸŒˆ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::P_X509_CRL_set_serial($crl, $crl_number);
# $crl - value corresponding to openssl's X509_CRL structure
# $crl_number - value corresponding to openssl's ASN1_INTEGER structure
#
# returns: 1 on success, 0 on failure
  • P_X509_CRL_add_extensions โ€” COMPATIBILITY: not available in Net-SSLeay-1.88 and before

Adds one or more X509 extensions to the X509 CRL object $x. Yes bestie, it's the CRL version of the extension-adding party ๐ŸŽ‰

my $rv = Net::SSLeay::P_X509_CRL_add_extensions($x, $ca_cert, $nid, $value);
# $x - value corresponding to openssl's X509 CRL structure
# $ca_cert - value corresponding to openssl's X509 structure (issuer's cert - necessary for setting NID_authority_key_identifier)
# $nid - NID identifying extension to be set
# $value - extension value
#
# returns: 1 on success, 0 on failure

For all the deets, go peek at "P_X509_add_extensions" โ€” it's literally the same energy โœจ

  • X509_EXTENSION_get_critical โ€” tells you whether this extension is marked critical or not ๐Ÿšฉ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Returns the 'critical' flag of the given X509_EXTENSION object $ex.

my $rv = Net::SSLeay::X509_EXTENSION_get_critical($ex);
# $ex - value corresponding to openssl's X509_EXTENSION structure
#
# returns: (integer) 1 - critical, 0 - noncritical
  • X509_EXTENSION_get_data โ€” hands you the raw value (the actual data) sitting inside the X509_EXTENSION object $ne ๐Ÿ“ฆ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_EXTENSION_get_data($ne);
# $ne - value corresponding to openssl's X509_EXTENSION structure
#
# returns: value corresponding to openssl's ASN1_OCTET_STRING structure (0 on failure)
Heads up: you can use "P_ASN1_STRING_get" to turn that ASN1_OCTET_STRING into a perl scalar variable ๐Ÿ’–
  • X509_EXTENSION_get_object โ€” gives you the OID (ASN1_OBJECT) of the X509_EXTENSION object $ne ๐Ÿท๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_EXTENSION_get_object($ex);
# $ex - value corresponding to openssl's X509_EXTENSION structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)
  • X509V3_EXT_print โ€” turns the given X509_EXTENSION object $ext into a string you can actually read ๐Ÿ‘€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Net::SSLeay::X509V3_EXT_print($ext, $flags, $utf8_decode);
# $ext - value corresponding to openssl's X509_EXTENSION structure
# $flags - [optional] (integer) Currently the flag argument is unused and should be set to 0
# $utf8_decode - [optional] 0 or 1 whether the returned value should be utf8 decoded (default=0)
#
# returns: no return value
ngl the $flags argument is lowkey doing nothing right now โ€” just pass 0 and move on ๐Ÿ’€
  • X509V3_EXT_d2i โ€” parses an extension and gives you back its internal structure ๐Ÿ”
my $rv = Net::SSLeay::X509V3_EXT_d2i($ext);
# $ext - value corresponding to openssl's X509_EXTENSION structure
#
# returns: pointer ???
fr fr the docs themselves say pointer ??? โ€” that's not me being vague, that's literally what it says ๐Ÿ˜ญ

  • X509_NAME_ENTRY_get_data โ€” grabs the field value of $ne, delivered as an ASN1_STRING structure ๐Ÿ’Œ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_NAME_ENTRY_get_data($ne);
# $ne - value corresponding to openssl's X509_NAME_ENTRY structure
#
# returns: value corresponding to openssl's ASN1_STRING structure (0 on failure)

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_ENTRY_get_object.html>

  • X509_NAME_ENTRY_get_object โ€” grabs the field name of $ne, as an ASN1_OBJECT structure ๐Ÿท๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

my $rv = Net::SSLeay::X509_NAME_ENTRY_get_object($ne);
# $ne - value corresponding to openssl's X509_NAME_ENTRY structure
#
# returns: value corresponding to openssl's ASN1_OBJECT structure (0 on failure)

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_ENTRY_get_object.html>

  • X509_NAME_new โ€” makes you a shiny brand-new X509_NAME structure โœจ

COMPATIBILITY: not available in Net-SSLeay-1.55 and before

Creates a new X509_NAME structure. Adds a field whose name is defined by a string $field. The field value to be added is in $bytes.

my $rv = Net::SSLeay::X509_NAME_new();
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)
  • X509_NAME_hash โ€” kind of a checksum of the issuer name $name ๐Ÿ”ข

COMPATIBILITY: not available in Net-SSLeay-1.55 and before

Sort of a checksum of issuer name $name. The result is not a full hash (e.g. sha-1), it is kind-of-a-hash truncated to the size of 'unsigned long' (32 bits). The resulting value might differ across different openssl versions for the same X509 certificate ๐Ÿ˜ฌ

my $rv = Net::SSLeay::X509_NAME_hash($name);
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: number representing checksum
Don't go comparing these across openssl versions, bestie โ€” they can legit not match ๐Ÿ™ˆ
  • X509_NAME_add_entry_by_txt โ€” adds a field whose name is defined by the string $field, with the value you pass in $bytes ๐ŸŒธ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Adds a field whose name is defined by a string $field. The field value to be added is in $bytes.

my $rv = Net::SSLeay::X509_NAME_add_entry_by_txt($name, $field, $type, $bytes, $len, $loc, $set);
# $name - value corresponding to openssl's X509_NAME structure
# $field - (string) field definition (name) - e.g. "organizationName"
# $type - (integer) type of data in $bytes (see below)
# $bytes - data to be set
# $loc - [optional] (integer) index where the new entry is inserted: if it is -1 (default) it is appended
# $set - [optional] (integer) determines how the new type is added. If it is 0 (default) a new RDN is created
#
# returns: 1 on success, 0 on failure

# values for $type - use constants:
# &Net::SSLeay::MBSTRING_UTF8     - $bytes contains utf8 encoded data
# &Net::SSLeay::MBSTRING_ASC      - $bytes contains ASCII data
Unicode note: when passing a non-ascii (unicode) string in $bytes do not forget to set $flags = &Net::SSLeay::MBSTRING_UTF8 and encode the perl $string via $bytes = encode('utf-8', $string) ๐Ÿงš

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_add_entry_by_txt.html>

  • X509_NAME_add_entry_by_NID โ€” same vibe, but the field name is defined by the NID $nid ๐Ÿ†”

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Adds a field whose name is defined by a NID $nid. The field value to be added is in $bytes.

my $rv = Net::SSLeay::X509_NAME_add_entry_by_NID($name, $nid, $type, $bytes, $len, $loc, $set);
# $name - value corresponding to openssl's X509_NAME structure
# $nid - (integer) field definition - NID value
# $type - (integer) type of data in $bytes (see below)
# $bytes - data to be set
# $loc - [optional] (integer) index where the new entry is inserted: if it is -1 (default) it is appended
# $set - [optional] (integer) determines how the new type is added. If it is 0 (default) a new RDN is created
#
# returns: 1 on success, 0 on failure

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_add_entry_by_txt.html>

  • X509_NAME_add_entry_by_OBJ โ€” and the third flavor: field name defined by an object (OID) $obj ๐ŸŽ€

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Adds a field whose name is defined by a object (OID) $obj . The field value to be added is in $bytes.

my $rv = Net::SSLeay::X509_NAME_add_entry_by_OBJ($name, $obj, $type, $bytes, $len, $loc, $set);
# $name - value corresponding to openssl's X509_NAME structure
# $obj - field definition - value corresponding to openssl's ASN1_OBJECT structure
# $type - (integer) type of data in $bytes (see below)
# $bytes - data to be set
# $loc - [optional] (integer) index where the new entry is inserted: if it is -1 (default) it is appended
# $set - [optional] (integer) determines how the new type is added. If it is 0 (default) a new RDN is created
#
# returns: 1 on success, 0 on failure

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_add_entry_by_txt.html>

  • X509_NAME_cmp โ€” compares two X509_NAME objects, head to head ๐ŸฅŠ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Compares two X509_NAME objects.

my $rv = Net::SSLeay::X509_NAME_cmp($a, $b);
# $a - value corresponding to openssl's X509_NAME structure
# $b - value corresponding to openssl's X509_NAME structure
#
# returns: 0 if $a matches $b; non zero otherwise
  • X509_NAME_digest โ€” computes the digest/fingerprint of the X509_NAME $data using the $type hash function ๐Ÿ”

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Computes digest/fingerprint of X509_NAME $data using $type hash function.

my $digest_value = Net::SSLeay::X509_NAME_digest($data, $type);
# $data - value corresponding to openssl's X509_NAME structure
# $type - value corresponding to openssl's EVP_MD structure - e.g. got via EVP_get_digestbyname()
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
That return value is binary, so if you try to print it raw you'll get chaos. Use the unpack('H*', ...) glow-up above ๐Ÿ’…
  • X509_NAME_entry_count โ€” how many entries total live inside $name ๐Ÿ”ข

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Returns the total number of entries in $name.

my $rv = Net::SSLeay::X509_NAME_entry_count($name);
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: (integer) entries count

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_get_index_by_NID.html>

  • X509_NAME_get_entry โ€” pulls out the X509_NAME_ENTRY from $name at index $loc ๐ŸŽฏ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Retrieves the X509_NAME_ENTRY from $name corresponding to index $loc. Acceptable values for $loc run from 0 to Net::SSLeay::X509_NAME_entry_count($name) - 1. The value returned is an internal pointer which must not be freed โš ๏ธ

my $rv = Net::SSLeay::X509_NAME_get_entry($name, $loc);
# $name - value corresponding to openssl's X509_NAME structure
# $loc - (integer) index of wanted entry
#
# returns: value corresponding to openssl's X509_NAME_ENTRY structure (0 on failure)

Check the openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_NAME_get_index_by_NID.html>

Do not free that pointer, bestie. It's not yours, it belongs to openssl ๐Ÿ‘‘๐Ÿ˜ค
  • X509_NAME_print_ex โ€” returns a string with a human readable version of $name ๐Ÿ–จ๏ธโœจ

COMPATIBILITY: not available in Net-SSLeay-1.45 and before

Returns a string with human readable version of $name.

Net::SSLeay::X509_NAME_print_ex($name, $flags, $utf8_decode);
# $name - value corresponding to openssl's X509_NAME structure
# $flags - [optional] conversion flags (default XN_FLAG_RFC2253) - see below
# $utf8_decode - [optional] 0 or 1 whether the returned value should be utf8 decoded (default=0)
#
# returns: string representation of $name
# available conversion flags - use constants:
# &Net::SSLeay::XN_FLAG_COMPAT
# &Net::SSLeay::XN_FLAG_DN_REV
# &Net::SSLeay::XN_FLAG_DUMP_UNKNOWN_FIELDS
# &Net::SSLeay::XN_FLAG_FN_ALIGN
# &Net::SSLeay::XN_FLAG_FN_LN
# &Net::SSLeay::XN_FLAG_FN_MASK
# &Net::SSLeay::XN_FLAG_FN_NONE
# &Net::SSLeay::XN_FLAG_FN_OID
# &Net::SSLeay::XN_FLAG_FN_SN
# &Net::SSLeay::XN_FLAG_MULTILINE
# &Net::SSLeay::XN_FLAG_ONELINE
# &Net::SSLeay::XN_FLAG_RFC2253
# &Net::SSLeay::XN_FLAG_SEP_COMMA_PLUS
# &Net::SSLeay::XN_FLAG_SEP_CPLUS_SPC
# &Net::SSLeay::XN_FLAG_SEP_MASK
# &Net::SSLeay::XN_FLAG_SEP_MULTILINE
# &Net::SSLeay::XN_FLAG_SEP_SPLUS_SPC
# &Net::SSLeay::XN_FLAG_SPC_EQ

Lowkey there are So Many flags, but ngl you're probably gonna be totally fine with the default ๐Ÿ’…

Net::SSLeay::X509_NAME_print_ex($name, &Net::SSLeay::XN_FLAG_RFC2253);

Orrrrr if you want that RFC2253-like output but without the utf8 chars escaping (iconic choice, honestly):

use Net::SSLeay qw/XN_FLAG_RFC2253 ASN1_STRFLGS_ESC_MSB/;
my $flag_rfc22536_utf8 = (XN_FLAG_RFC2253) & (~ ASN1_STRFLGS_ESC_MSB);
my $result = Net::SSLeay::X509_NAME_print_ex($name, $flag_rfc22536_utf8, 1);

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_NAME_print_ex.html


  • X509_NAME_get_text_by_NID โ€” pulls the text out of the first entry in the name that matches $nid. And if there's no such entry? You get -1, bestie. That's it. That's the vibe.
openssl note: this is a legacy function which has various limitations which makes it of minimal use in practice. It can only find the first matching entry and will copy the contents of the field verbatim: this can be highly confusing if the target is a multicharacter string type like a BMPString or a UTF8String.

So like... it works, but it's giving "legacy, minimal use in practice." Know what you're walking into ๐Ÿซถ

Net::SSLeay::X509_NAME_get_text_by_NID($name, $nid);
# $name - value corresponding to openssl's X509_NAME structure
# $nid - NID value (integer)
#
# returns: text value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_NAME_get_index_by_NID.html

  • X509_NAME_oneline โ€” hands you back an ASCII version of $name. Simple. Elegant. Slay.
Net::SSLeay::X509_NAME_oneline($name);
# $name - value corresponding to openssl's X509_NAME structure
#
# returns: (string) ASCII version of $name

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_NAME_print_ex.html

  • sk_X509_NAME_free โ€” frees an allocated STACK_OF(X509_NAME) structure. Cleanup era โœจ
Net::SSLeay::sk_X509_NAME_free($sk);
# $sk - value corresponding to openssl's STACK_OF(X509_NAME) structure
#
# returns: no return value
  • sk_X509_NAME_num โ€” tells you how many items are chilling in a STACK_OF(X509_NAME). Counting queen ๐Ÿ‘‘
my $rv = Net::SSLeay::sk_X509_NAME_num($sk);
# $sk - value corresponding to openssl's STACK_OF(X509_NAME) structure
#
# returns: number of items
  • sk_X509_NAME_value โ€” grabs the X509_NAME sitting at position $index in the STACK_OF(X509_NAME). Very "excuse me, this seat is taken" energy.
my $rv = Net::SSLeay::sk_X509_NAME_value($sk, $i);
# $sk - value corresponding to openssl's STACK_OF(X509_NAME) structure
# $i - (integer) index/position
#
# returns: value corresponding to openssl's X509_NAME structure (0 on failure)
  • add_file_cert_subjects_to_stack โ€” adds a file of certs to a stack. Every cert in $file that isn't already in $stackCAs gets added. No dupes, we don't do that here ๐Ÿ’…
my $rv = Net::SSLeay::add_file_cert_subjects_to_stack($stackCAs, $file);
# $stackCAs - value corresponding to openssl's STACK_OF(X509_NAME) structure
# $file - (string) filename
#
# returns: 1 on success, 0 on failure
  • add_dir_cert_subjects_to_stack โ€” same idea but for a whole directory of certs. Everything in $dir that isn't already in $stackCAs gets added. (Warning: it says dir, so it's a directory โ€” don't hand it a file and act surprised ๐Ÿ˜ญ)
my $rv = Net::SSLeay::add_dir_cert_subjects_to_stack($stackCAs, $dir);
# $stackCAs - value corresponding to openssl's STACK_OF(X509_NAME) structure
# $dir - (string) the directory to append from. All files in this directory will be examined as potential certs. Any that are acceptable to SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be included.
#
# returns: 1 on success, 0 on failure

Ok buckle up bestie, we're going low level. This is the basement of the certificate-verification house ๐Ÿ 

  • X509_STORE_CTX_new โ€” returns a newly initialised X509_STORE_CTX structure. Fresh out the box, no notes.
  • X509_STORE_CTX_init โ€” sets up an X509_STORE_CTX for a subsequent verification operation. And like, it must be called before each call to X509_verify_cert(). Every. Single. Time. No skipping, no cap.
my $rv = Net::SSLeay::X509_STORE_CTX_init($x509_store_ctx, $x509_store, $x509, $chain);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure (required)
# $x509_store - value corresponding to openssl's X509_STORE structure (optional)
# $x509 - value corresponding to openssl's X509 structure (optional)
# $chain - value corresponding to openssl's STACK_OF(X509) structure (optional)
#
# returns: 1 on success, 0 on failure
#
# Note: returns nothing with Net::SSLeay 1.90 and earlier.
Heads up: that last note is real โ€” on Net::SSLeay 1.90 and earlier this thing returns nothing. So don't go trusting $rv on ancient versions ๐Ÿ™ˆ

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_init.html

  • X509_STORE_CTX_free โ€” frees an X509_STORE_CTX structure. Bye bestie, you served ๐Ÿ’œ
Net::SSLeay::X509_STORE_CTX_free($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
  • X509_verify_cert โ€” attempts to discover and validate a certificate chain based on the parameters in ctx. The whole process is described over in the verify(1) manual page if you want the full lore ๐Ÿ“–

If this function returns 0, use X509_STORE_CTX_get_error to get the additional error info โ€” that's your "ok so what happened" function.

my $rv = Net::SSLeay::X509_verify_cert($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: 1 if a complete chain can be built and validated, otherwise 0

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_verify_cert.html

  • X509_STORE_CTX_get_current_cert โ€” returns the certificate in ctx that caused the error. Or 0 if no certificate is relevant. It's the culprit reveal moment ๐Ÿ’€
my $rv = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: value corresponding to openssl's X509 structure (0 on failure)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html

  • X509_STORE_CTX_get0_cert โ€” returns an internal pointer to the certificate being verified by the ctx. It's get0, so it's an internal pointer โ€” no copying, we're just peeking ๐Ÿ‘€
COMPATIBILITY: not available in Net-SSLeay-1.88 and before; requires at least OpenSSL 1.1.0pre6 or LibreSSL 2.7.0
my $x509 = Net::SSLeay::X509_STORE_CTX_get0_cert($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: value corresponding to openssl's X509 structure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get0_cert.html

  • X509_STORE_CTX_get1_chain โ€” returns a returns a complete validate chain if a previous call to X509_verify_cert() is successful. (Yes, the doc says "returns a returns a" and honestly? We respect the original's chaos. Keeping it fr fr.) So: no successful X509_verify_cert() first = no chain for you ๐Ÿ”—
my $rv = Net::SSLeay::X509_STORE_CTX_get1_chain($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: value corresponding to openssl's STACK_OF(X509) structure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get1_chain.html

  • X509_STORE_CTX_get_error โ€” returns the error code of $ctx. That's the tea โ˜•
my $rv = Net::SSLeay::X509_STORE_CTX_get_error($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: (integer) error code

For more info about error code values check function get_verify_result.

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html

  • X509_STORE_CTX_get_error_depth โ€” returns the depth of the error. It's a non-negative integer telling you where in the certificate chain the error happened. Zero = it happened in the end entity certificate, one = the certificate that signed the end entity certificate, and so on down the line. Like a little breadcrumb trail of what went wrong ๐Ÿž
my $rv = Net::SSLeay::X509_STORE_CTX_get_error_depth($x509_store_ctx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
#
# returns: (integer) depth

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html

  • X509_STORE_CTX_get_ex_data โ€” used to retrieve the information for $idx from $x509_store_ctx. Application-specific data retrieval, very "you left something in my locker" energy.
my $rv = Net::SSLeay::X509_STORE_CTX_get_ex_data($x509_store_ctx, $idx);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
# $idx - (integer) index for application specific data
#
# returns: pointer to ???

(Yeah, "pointer to ???" โ€” that's genuinely what the docs say. We're all just vibing here ๐Ÿซ )

  • X509_STORE_CTX_set_ex_data โ€” used to store application data at arg for idx into $x509_store_ctx. The storing half of the duo ๐Ÿ’พ
my $rv = Net::SSLeay::X509_STORE_CTX_set_ex_data($x509_store_ctx, $idx, $data);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
# $idx - (integer) ???
# $data - (pointer) ???
#
# returns: 1 on success, 0 on failure
  • X509_STORE_CTX_set_cert โ€” sets the certificate to be verified in $x509_store_ctx to $x. One cert in, one cert set ๐Ÿ“Œ
Net::SSLeay::X509_STORE_CTX_set_cert($x509_store_ctx, $x);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
# $x - value corresponding to openssl's X509 structure
#
# returns: no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_new.html

  • X509_STORE_new โ€” returns a newly initialized X509_STORE structure. Sparkly fresh โœจ
my $rv = Net::SSLeay::X509_STORE_new();
#
# returns: value corresponding to openssl's X509_STORE structure (0 on failure)
  • X509_STORE_free โ€” frees an X509_STORE structure.

...so like, the actual call looks like this, bestie:

Net::SSLeay::X509_STORE_free($x509_store);
# $x509_store - value corresponding to openssl's X509_STORE structure
  • X509_STORE_add_lookup โ€” attaches a lookup thingy to an X509_STORE, using whatever lookup method you hand it. Gotta tell it how to look stuff up, you know? โœจ
my $method = &Net::SSLeay::X509_LOOKUP_hash_dir;
my $rv = Net::SSLeay::X509_STORE_add_lookup($x509_store, $method);
# $method - value corresponding to openssl's X509_LOOKUP_METHOD structure
# $x509_store - value corresponding to openssl's X509_STORE structure
#
# returns: value corresponding to openssl's X509_LOOKUP structure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_STORE_add_lookup.html ๐Ÿฆ‹

  • X509_STORE_CTX_set_error โ€” sets the error code of $ctx to $s. Fr fr this one's handy inside a verification callback when you wanna flag an error based on extra checks you did yourself. ๐Ÿ’…
Net::SSLeay::X509_STORE_CTX_set_error($x509_store_ctx, $s);
# $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure
# $s - (integer) error id
#
# returns: no return value

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html ๐ŸŒธ

  • X509_STORE_add_cert โ€” drops X509 certificate $x into the X509_STORE $store. Like adding a lil certificate to the collection ๐ŸŽ€
my $rv = Net::SSLeay::X509_STORE_add_cert($store, $x);
# $store - value corresponding to openssl's X509_STORE structure
# $x - value corresponding to openssl's X509 structure
#
# returns: 1 on success, 0 on failure
  • X509_STORE_add_crl โ€” same energy but for a CRL: adds X509 CRL $x into the X509_STORE $store. ๐Ÿ˜Œ
my $rv = Net::SSLeay::X509_STORE_add_crl($store, $x);
# $store - value corresponding to openssl's X509_STORE structure
# $x - value corresponding to openssl's X509_CRL structure
#
# returns: 1 on success, 0 on failure
  • X509_STORE_set1_param โ€” ok so the manpage literally says "??? (more info needed)" for this one ๐Ÿ’€ iykyk, the docs are still cooking. Signature's below anyway:
my $rv = Net::SSLeay::X509_STORE_set1_param($store, $pm);
# $store - value corresponding to openssl's X509_STORE structure
# $pm - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure
  • X509_LOOKUP_hash_dir โ€” returns an X509_LOOKUP structure that tells an X509_STORE to go load files from a directory full of certificates named in the format hash.N, or CRLs named in the format hash.rN. The hashed-directory method, iconic โœจ
my $rv = Net::SSLeay::X509_LOOKUP_hash_dir();
#
# returns: value corresponding to openssl's X509_LOOKUP_METHOD structure, with the hashed directory method

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_load_crl_file.html ๐ŸŒˆ

  • X509_LOOKUP_add_dir โ€” adds a directory to an X509_LOOKUP structure, which you'd usually get from X509_STORE_add_lookup. Bestie, watch the $type โ€” it's a constant matching the file type in that directory: X509_FILETYPE_PEM, X509_FILETYPE_DEFAULT, or X509_FILETYPE_ASN1. ๐Ÿ‘‘
my $method = &Net::SSLeay::X509_LOOKUP_hash_dir;
my $lookup = Net::SSLeay::X509_STORE_add_lookup($x509_store, $method);
my $type = &Net::SSLeay::X509_FILETYPE_PEM;
Net::SSLeay::X509_LOOKUP_add_dir($lookup, $dir, $type);
# $lookup - value corresponding to openssl's X509_LOOKUP structure
# $dir - string path to a directory
# $type - constant corresponding to the type of file in the directory - can be X509_FILETYPE_PEM, X509_FILETYPE_DEFAULT, or X509_FILETYPE_ASN1
  • X509_STORE_set_flags โ€” sets flags on the store, and ngl there's no return value to obsess over. ๐Ÿ’€
Net::SSLeay::X509_STORE_set_flags($ctx, $flags);
# $ctx - value corresponding to openssl's X509_STORE structure
# $flags - (unsigned long) flags to be set (bitmask)
#
# returns: no return value

# to create $flags value use corresponding constants like
$flags = Net::SSLeay::X509_V_FLAG_CRL_CHECK();

For more deets about the $flags bitmask, see "X509_VERIFY_PARAM_set_flags". ๐Ÿ”ฅ

  • X509_STORE_set_purpose โ€” sets the purpose on the store. $purpose is an (integer) purpose identifier. No return value, sorry bestie ๐Ÿซถ
Net::SSLeay::X509_STORE_set_purpose($ctx, $purpose);
# $ctx - value corresponding to openssl's X509_STORE structure
# $purpose - (integer) purpose identifier
#
# returns: no return value

Moar about that $purpose identifier? Go check "CTX_set_purpose" ๐Ÿ’–

  • X509_STORE_set_trust โ€” sets the trust level. $trust is an (integer) trust identifier. Again: no return value. ๐ŸŽ€
Net::SSLeay::X509_STORE_set_trust($ctx, $trust);
# $ctx - value corresponding to openssl's X509_STORE structure
# $trust - (integer) trust identifier
#
# returns: no return value

Moar about that $trust identifier? Check "CTX_set_trust" ๐ŸŒธ


  • sk_X509_INFO_num โ€” tells you how many values are chillin' in a STACK_OF(X509_INFO) structure. A lil headcount, basically โœจ
my $rv = Net::SSLeay::sk_X509_INFO_num($sk_x509_info);
# $sk_x509_info - value corresponding to openssl's STACK_OF(X509_INFO) structure
#
# returns: number of values in $sk_x509_info
  • sk_X509_INFO_value โ€” grabs the value out of a STACK_OF(X509_INFO) structure at whatever index you point at. Main character retrieval ๐Ÿซถ
my $rv = Net::SSLeay::sk_X509_INFO_value($sk_x509_info, $index);
# $sk_x509_info - value corresponding to openssl's STACK_OF(X509_INFO) structure
# $index - index into the stack
#
# returns: value corresponding to openssl's X509_INFO structure at the given index
  • P_X509_INFO_get_x509 โ€” pulls the X509 structure out of an X509_INFO structure. Little nesting-doll moment ๐Ÿ’…
my $rv = Net::SSLeay::P_X509_INFO_get_x509($x509_info);
# $x509_info - value corresponding to openssl's X509_INFO structure
#
# returns: value corresponding to openssl's X509 structure

  • X509_VERIFY_PARAM_add0_policy โ€” turns policy checking ON (it's off by default, fyi) and adds $policy to the acceptable policy set. Turning up the strictness ๐Ÿ˜Œ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_add0_policy($param, $policy);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $policy - value corresponding to openssl's ASN1_OBJECT structure
#
# returns: 1 on success, 0 on failure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐ŸŒŸ

  • X509_VERIFY_PARAM_add0_table โ€” the manpage says "??? (more info needed)" for this one too, bestie ๐Ÿ’€ the vibes are inconclusive, but here's the shape of it:
my $rv = Net::SSLeay::X509_VERIFY_PARAM_add0_table($param);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure
  • X509_VERIFY_PARAM_add1_host โ€” adds another reference identifier that can match the peer's certificate. Extra vibes for matching, if you will ๐Ÿฆ‹
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta2 or LibreSSL 2.7.0 โ€” so check your version before you come for me ๐Ÿ™ˆ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_add1_host($param, $name);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $name - (string) name to be set
#
# returns: 1 on success, 0 on failure

Also peep the OpenSSL docs, "X509_VERIFY_PARAM_set1_host" and "X509_VERIFY_PARAM_set_hostflags", for more info โ€” wildcard matching included, periodt.

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐ŸŒธ

  • X509_VERIFY_PARAM_clear_flags โ€” clears the flags $flags in $param. Undoing, but make it certificate verification โœจ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_clear_flags($param, $flags);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $flags - (unsigned long) flags to be set (bitmask)
#
# returns: 1 on success, 0 on failure

For more deets about the $flags bitmask, see "X509_VERIFY_PARAM_set_flags" ๐Ÿ’–

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐ŸŽ€

  • X509_VERIFY_PARAM_free โ€” frees up the X509_VERIFY_PARAM structure. Cleanup era ๐Ÿงน
Net::SSLeay::X509_VERIFY_PARAM_free($param);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: no return value
  • X509_VERIFY_PARAM_get0_peername โ€” returns the DNS hostname or subject CommonName from the peer certificate that matched one of the reference identifiers. Literally who matched, we love a receipt ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta2 or LibreSSL 2.7.0 ๐ŸŒˆ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_get0_peername($param);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: (string) name e.g. '*.example.com' or undef

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html โญ

  • X509_VERIFY_PARAM_get_depth โ€” returns the current verification depth. How deep are we going? ๐Ÿ˜ญ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_get_depth($param);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: (integer) depth

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐Ÿ“

  • X509_VERIFY_PARAM_get_flags โ€” returns the current verification flags, as an (unsigned long) bitmask. Receipt for your settings ๐Ÿ‘‘
my $rv = Net::SSLeay::X509_VERIFY_PARAM_get_flags($param);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: (unsigned long) flags to be set (bitmask)

For more deets about that returned flags bitmask, see "X509_VERIFY_PARAM_set_flags" ๐Ÿ’œ

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐Ÿ”ฅ

  • X509_VERIFY_PARAM_set_flags โ€” sets the flags. Classic. And yes, you make $flags with constants like the one below ๐ŸŒŸ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set_flags($param, $flags);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $flags - (unsigned long) flags to be set (bitmask)
#
# returns: 1 on success, 0 on failure

# to create $flags value use corresponding constants like
$flags = Net::SSLeay::X509_V_FLAG_CRL_CHECK();

For more deets about the $flags bitmask, see the OpenSSL docs below ๐Ÿซถ

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html ๐Ÿงš

  • X509_VERIFY_PARAM_inherit โ€” again with the "??? (more info needed)" ๐Ÿ˜ญ it inherits stuff from one param into another, going off the signatures alone:
my $rv = Net::SSLeay::X509_VERIFY_PARAM_inherit($to, $from);
# $to - value corresponding to openssl's X509_VERIFY_PARAM structure
# $from - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure
  • X509_VERIFY_PARAM_lookup โ€” finds an X509_VERIFY_PARAM by name. Detector: engaged ๐Ÿ”
  • X509_VERIFY_PARAM_lookup โ€” (continued from the last part, here's the code)
my $rv = Net::SSLeay::X509_VERIFY_PARAM_lookup($name);
# $name - (string) name we want to find
#
# returns: value corresponding to openssl's X509_VERIFY_PARAM structure (0 on failure)
  • X509_VERIFY_PARAM_new โ€” bestie, this one literally just births a fresh X509_VERIFY_PARAM structure out of thin air. New param, who dis ๐Ÿ’…
my $rv = Net::SSLeay::X509_VERIFY_PARAM_new();
#
# returns: value corresponding to openssl's X509_VERIFY_PARAM structure (0 on failure)
  • X509_VERIFY_PARAM_set1 โ€” copies the name from one param over to another, so $to gets $from's whole name vibe. Matching energy, yk? ๐Ÿซถ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1($to, $from);
# $to - value corresponding to openssl's X509_VERIFY_PARAM structure
# $from - value corresponding to openssl's X509_VERIFY_PARAM structure
#
# returns: 1 on success, 0 on failure
  • X509_VERIFY_PARAM_set1_email โ€” sets the expected RFC822 email address to $email.
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_email($param, $email);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $email - (string) email to be set
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set1_host โ€” sets the expected DNS hostname to $name, and the way it does that is by clearing out any hostname(s) you'd set before. Fresh slate, periodt โœจ
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_host($param, $name);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $name - (string) name to be set
#
# returns: 1 on success, 0 on failure

See also OpenSSL docs, X509_VERIFY_PARAM_add1_host and X509_VERIFY_PARAM_set_hostflags for more info, wildcard matching included. ๐Ÿ‘€

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set1_ip โ€” sets the expected IP address to $ip.
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_ip($param, $ip);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $ip - (binary) 4 octet IPv4 or 16 octet IPv6 address
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set1_ip_asc โ€” sets the expected IP address to $ipasc.
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_asc($param, $ipasc);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $ip - (string) IPv4 or IPv6 address
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set1_name โ€” gives the X509_VERIFY_PARAM structure $param the name $name. Naming rights, iconic ๐ŸŒธ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_name($param, $name);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $name - (string) name to be set
#
# returns: 1 on success, 0 on failure
  • X509_VERIFY_PARAM_set1_policies โ€” turns policy checking on (it's off by default, no cap) and sets the acceptable policy set to $policies. Any existing policy set gets cleared โ€” like, gone. And plot twist: $policies can be 0 if you just wanna clear an existing policy set with no replacement. ๐Ÿงน
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set1_policies($param, $policies);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $policies - value corresponding to openssl's STACK_OF(ASN1_OBJECT) structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set_depth โ€” sets the maximum verification depth to $depth. Translation: the max number of untrusted CA certs that can show up in a chain. It's giving "you may bring this many plus-ones" ๐ŸŽŸ๏ธ
Net::SSLeay::X509_VERIFY_PARAM_set_depth($param, $depth);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $depth - (integer) depth to be set
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set_hostflags โ€” sets the host flags, as a bitmask. Slay.
COMPATIBILITY: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta2 or LibreSSL 2.7.0
Net::SSLeay::X509_VERIFY_PARAM_set_hostflags($param, $flags);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $flags - (unsigned int) flags to be set (bitmask)
#
# returns: no return value

See also OpenSSL docs, X509_VERIFY_PARAM_add1_host and X509_VERIFY_PARAM_set1_host for more info. The flags that control wildcard checks and other features are defined in the OpenSSL docs, so go read those, iykyk ๐Ÿ“–

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set_purpose โ€” sets the verification purpose in $param to $purpose. This is what decides the acceptable purpose of the cert chain โ€” like, SSL client or SSL server, bestie. Main character selection screen ๐ŸŽฎ
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set_purpose($param, $purpose);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $purpose - (integer) purpose identifier
#
# returns: 1 on success, 0 on failure

For more details about that $purpose identifier, check CTX_set_purpose.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set_time โ€” sets the verification time in $param to $t. Normally the current time is what gets used, but here you're clocking in whenever you want ๐Ÿ•ฐ๏ธ
Net::SSLeay::X509_VERIFY_PARAM_set_time($param, $t);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $t - (time_t) time in seconds since 1.1.1970
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_set_trust โ€” sets the trust setting in $param to $trust. Trust issues? Not anymore ๐Ÿ’–
my $rv = Net::SSLeay::X509_VERIFY_PARAM_set_trust($param, $trust);
# $param - value corresponding to openssl's X509_VERIFY_PARAM structure
# $trust - (integer) trust identifier
#
# returns: 1 on success, 0 on failure

For more details about that $trust identifier, check CTX_set_trust.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html>

  • X509_VERIFY_PARAM_table_cleanup โ€” ??? (more info needed) โ€” yeah that's literally what the docs say, bestie, we're all just guessing out here ๐Ÿ˜ญ
Net::SSLeay::X509_VERIFY_PARAM_table_cleanup();
#
# returns: no return value

  • EVP_get_cipherbyname โ€” hand it a cipher name, and it hands you back an EVP_CIPHER structure. Match made in heaven ๐Ÿ’ซ
COMPATIBILITY: not available in Net-SSLeay-1.45 and before
my $rv = Net::SSLeay::EVP_get_cipherbyname($name);
# $name - (string) cipher name e.g. 'aes-128-cbc', 'camellia-256-ecb', 'des-ede', ...
#
# returns: value corresponding to openssl's EVP_CIPHER structure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/EVP_EncryptInit.html>


  • OpenSSL_add_all_digests โ€” registers all the digests. No args, no return value, no notes. Just vibes โœจ
COMPATIBILITY: not available in Net-SSLeay-1.42 and before
Net::SSLeay::OpenSSL_add_all_digests();
# no args, no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/OpenSSL_add_all_algorithms.html>

  • P_EVP_MD_list_all โ€” gimme the whole digest lineup, bestie ๐Ÿ“‹
COMPATIBILITY: not available in Net-SSLeay-1.42 and before; requires at least OpenSSL 1.0.0
NOTE: Does not exactly correspond to any low level API function
my $rv = Net::SSLeay::P_EVP_MD_list_all();
#
# returns: arrayref - list of available digest names

Those returned digest names are the values EVP_get_digestbyname expects โ€” so like, that's the handshake between them.

Also important: some of these digests are available by default, and some only show up after you call OpenSSL_add_all_digests. So don't come for the list if your fave is missing ๐Ÿ™ˆ

  • EVP_get_digestbyname โ€” name in, EVP_MD structure out. Simple as that ๐Ÿ’…
COMPATIBILITY: not available in Net-SSLeay-1.42 and before
my $rv = Net::SSLeay::EVP_get_digestbyname($name);
# $name - string with digest name
#
# returns: value corresponding to openssl's EVP_MD structure

# The $name param can be:
# md2
# md4
# md5
# mdc2
# ripemd160
# sha
# sha1
# sha224
# sha256
# sha512
# whirlpool

Or, honestly better, check which digests are actually supported by calling P_EVP_MD_list_all. Fr fr, that's the safer move ๐Ÿซถ

  • EVP_MD_type โ€” gives you the NID (an integer) of the OBJECT IDENTIFIER that represents the given message digest.
COMPATIBILITY: not available in Net-SSLeay-1.42 and before
my $rv = Net::SSLeay::EVP_MD_type($md);
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: the NID (integer) of the OBJECT IDENTIFIER representing the given message digest

Fun fact: EVP_MD_type is a non-deprecated alias macro of EVP_MD_get_type since OpenSSL 3.0.0. Glow-up complete ๐Ÿ‘‘

  • EVP_MD_size โ€” how big is the message digest, in bytes? e.g. 20 for SHA1. Size matters, bestie ๐Ÿ“
COMPATIBILITY: not available in Net-SSLeay-1.42 and before
my $rv = Net::SSLeay::EVP_MD_size($md);
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: the size of the message digest in bytes (e.g. 20 for SHA1)
  • EVP_MD_get0_description โ€” returns the description of a message digest. Tell me about yourself, digest ๐Ÿ’ฌ
COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 3.0.0-beta1, not in LibreSSL
  • EVP_MD_get0_name โ€” bestie this one hands you one name for a message digest, that's it, one.

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 3.0.0-beta1, not in LibreSSL

my $rv = Net::SSLeay::EVP_MD_get0_description($md);
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: String, the name of the given message digest. For fetched message digests with multiple names, only one of them is returned; it's recommended to use EVP_MD_names_do_all() instead. (e.g. SHA2-256 or SHA256 for the same digest)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/EVP_MD_get0_name.html>

  • EVP_MD_get_type โ€” give it a digest, it gives you back the NID. cute little number-for-a-name trade ๐Ÿ˜Œ

COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 3.0.0-beta1, not in LibreSSL

my $rv = Net::SSLeay::EVP_MD_get_type($md);
# $md - value corresponding to openssl's EVP_MD structure
#
# returns: Integer, the NID of the OBJECT IDENTIFIER representing the given message digest when passed an EVP_MD structure.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/EVP_MD_get_type.html>

  • EVP_MD_CTX_md โ€” peeks at a digest context and tells you which EVP_MD it's riding with ๐Ÿ’…

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

Net::SSLeay::EVP_MD_CTX_md($ctx);
# $ctx - value corresponding to openssl's EVP_MD_CTX structure
#
# returns: value corresponding to openssl's EVP_MD structure
  • EVP_MD_CTX_create โ€” allocates, initializes and returns a digest context. it's giving "new blank canvas, come hash with me" โœจ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::EVP_MD_CTX_create();
#
# returns: value corresponding to openssl's EVP_MD_CTX structure

The complete idea behind EVP_MD_CTX looks like this example โ€” literally the whole vibe in one block, no cap:

Net::SSLeay::OpenSSL_add_all_digests();

my $md = Net::SSLeay::EVP_get_digestbyname("sha1");
my $ctx = Net::SSLeay::EVP_MD_CTX_create();
Net::SSLeay::EVP_DigestInit($ctx, $md);

while(my $chunk = get_piece_of_data()) {
    Net::SSLeay::EVP_DigestUpdate($ctx,$chunk);
}

my $result = Net::SSLeay::EVP_DigestFinal($ctx);
Net::SSLeay::EVP_MD_CTX_destroy($ctx);

print "digest=", unpack('H*', $result), "\n"; # print hex value
  • EVP_DigestInit_ex โ€” sets up digest context $ctx to use digest $type from ENGINE $impl. Important: $ctx must already be initialized before you call this, and $type will typically come from a function like "EVP_get_digestbyname". If $impl is 0 then the default implementation of digest $type is used ๐Ÿซถ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::EVP_DigestInit_ex($ctx, $type, $impl);
# $ctx  - value corresponding to openssl's EVP_MD_CTX structure
# $type - value corresponding to openssl's EVP_MD structure
# $impl - value corresponding to openssl's ENGINE structure
#
# returns: 1 for success and 0 for failure
  • EVP_DigestInit โ€” behaves in the same way as "EVP_DigestInit_ex" except the passed context $ctx does not have to be initialized, and it always uses the default digest implementation. lowkey the chill version ๐ŸŒธ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::EVP_DigestInit($ctx, $type);
# $ctx - value corresponding to openssl's EVP_MD_CTX structure
# $type - value corresponding to openssl's EVP_MD structure
#
# returns: 1 for success and 0 for failure
  • EVP_MD_CTX_destroy โ€” cleans up digest context $ctx and frees the space allocated to it. Only call this on a context you created using "EVP_MD_CTX_create" โ€” respect the origin story pls ๐Ÿ™

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

Net::SSLeay::EVP_MD_CTX_destroy($ctx);
# $ctx - value corresponding to openssl's EVP_MD_CTX structure
#
# returns: no return value
  • EVP_DigestUpdate โ€” feed it more data, keep hashing, keep slaying ๐Ÿ”ฅ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::EVP_DigestUpdate($ctx, $data);
# $ctx  - value corresponding to openssl's EVP_MD_CTX structure
# $data - data to be hashed
#
# returns: 1 for success and 0 for failure
  • EVP_DigestFinal_ex โ€” retrieves the digest value from $ctx. Heads up bestie: after calling "EVP_DigestFinal_ex" you can't make any more calls to "EVP_DigestUpdate", but you can call "EVP_DigestInit_ex" to start a whole new digest operation. it's giving "chapter closed, new chapter unlocked" ๐Ÿ“–

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $digest_value = Net::SSLeay::EVP_DigestFinal_ex($ctx);
# $ctx - value corresponding to openssl's EVP_MD_CTX structure
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
  • EVP_DigestFinal โ€” similar to "EVP_DigestFinal_ex" except the digest context ctx is automatically cleaned up for you. self-care built in ๐Ÿง–โ€โ™€๏ธ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::EVP_DigestFinal($ctx);
# $ctx - value corresponding to openssl's EVP_MD_CTX structure
#
# returns: hash value (binary)

# to get printable (hex) value of digest use:
print unpack('H*', $digest_value);
  • MD2 โ€” computes MD2 from the given $data. (all data needs to be loaded into memory โ€” no streaming here, she likes it all at once)

COMPATIBILITY: not supported by default in OpenSSL 1.0.0

my $digest = Net::SSLeay::MD2($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • MD4 โ€” computes MD4 from the given $data. (all data needs to be loaded into memory)
my $digest = Net::SSLeay::MD4($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • MD5 โ€” computes MD5 from the given $data. (all data needs to be loaded into memory)
my $digest = Net::SSLeay::MD5($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • RIPEMD160 โ€” computes RIPEMD160 from the given $data. (all data needs to be loaded into memory)
my $digest = Net::SSLeay::RIPEMD160($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • SHA1 โ€” computes SHA1 from the given $data. (all data needs to be loaded into memory)

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $digest = Net::SSLeay::SHA1($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • SHA256 โ€” computes SHA256 from the given $data. (all data needs to be loaded into memory)

COMPATIBILITY: not available in Net-SSLeay-1.42 and before; requires at least OpenSSL 0.9.8

my $digest = Net::SSLeay::SHA256($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • SHA512 โ€” computes SHA512 from the given $data. (all data needs to be loaded into memory)

COMPATIBILITY: not available in Net-SSLeay-1.42 and before; requires at least OpenSSL 0.9.8

my $digest = Net::SSLeay::SHA512($data);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • EVP_Digest โ€” computes "any" digest from the given $data. (all data needs to be loaded into memory) pick your fighter, this one does them all ๐Ÿ‘‘

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $md = Net::SSLeay::EVP_get_digestbyname("sha1"); # or any other algorithm
my $digest = Net::SSLeay::EVP_Digest($data, $md);
print "digest(hexadecimal)=", unpack('H*', $digest);
  • EVP_sha1 โ€” hands you the EVP_MD for sha1, no detective work required ๐Ÿ”

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $md = Net::SSLeay::EVP_sha1();
#
# returns: value corresponding to openssl's EVP_MD structure
  • EVP_sha256 โ€” same deal but sha256 flavoured ๐Ÿ“

COMPATIBILITY: requires at least OpenSSL 0.9.8

my $md = Net::SSLeay::EVP_sha256();
#
# returns: value corresponding to openssl's EVP_MD structure
  • EVP_sha512 โ€” and the big one, sha512 ๐Ÿฆ‹

COMPATIBILITY: not available in Net-SSLeay-1.42 and before; requires at least OpenSSL 0.9.8

my $md = Net::SSLeay::EVP_sha512();
#
# returns: value corresponding to openssl's EVP_MD structure
  • EVP_add_digest โ€” adds a digest to the table, returns 1 on success, 0 otherwise. simple as ๐Ÿ’…
my $rv = Net::SSLeay::EVP_add_digest($digest);
# $digest - value corresponding to openssl's EVP_MD structure
#
# returns: 1 on success, 0 otherwise

okay we're in cipher territory now, stay with me bestie, these ones are about which cipher is doing the work ๐Ÿ”

  • CIPHER_get_name โ€” returns the name of the cipher used. and if $cipher is undefined you get '(NONE)', so at least she tells you ๐Ÿ˜ญ

COMPATIBILITY: not available in Net-SSLeay-1.42 and before

my $rv = Net::SSLeay::CIPHER_get_name($cipher);
# $cipher - value corresponding to openssl's SSL_CIPHER structure
#
# returns: (string) cipher name e.g. 'DHE-RSA-AES256-SHA', '(NONE)' if $cipher is undefined.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html>

Example โ€” grab the current cipher off your $ssl, then ask her her name:

my $ssl_cipher = Net::SSLeay::get_current_cipher($ssl);
my $cipher_name = Net::SSLeay::CIPHER_get_name($ssl_cipher);
  • CIPHER_description โ€” returns a textual description of the cipher used, whole little paragraph about her ๐ŸŽ€

COMPATIBILITY: doesn't work correctly in Net-SSLeay-1.88 and before

my $rv = Net::SSLeay::CIPHER_description($cipher);
# $cipher - value corresponding to openssl's SSL_CIPHER structure
#
# returns: (string) cipher description e.g. 'DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1'

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_description.html>

  • CIPHER_get_bits โ€” returns the number of secret bits used for cipher. you also pass an optional $alg_bits empty scalar to stash an extra return value in ๐Ÿ‘€

COMPATIBILITY: $alg_bits doesn't work correctly in Net-SSLeay-1.88 and before

my $rv = Net::SSLeay::CIPHER_get_bits($cipher, $alg_bits);
# $cipher - value corresponding to openssl's SSL_CIPHER structure
# $alg_bits - [optional] empty scalar for storing additional return value
#
# returns: (integer) number of secret bits, 0 on error
#          (integer) in $alg_bits for bits processed by the chosen algorithm

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_bits.html> โ€” that's the link, bestie. Now the example:

# bits and alg_bits are not equal for e.g., TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
# RFC 8422 name TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
my $alg_bits;
my $bits = Net::SSLeay::CIPHER_get_bits($cipher, $alg_bits);
# my $bits = Net::SSLeay::CIPHER_get_bits($cipher);
print "bits: $bits, alg_bits: $alg_bits\n";
  • CIPHER_get_version โ€” COMPATIBILITY: not available in Net-SSLeay-1.88 and before.

Returns version of SSL/TLS protocol that first defined the cipher.

my $rv = Net::SSLeay::CIPHER_get_version($cipher);
# $cipher - value corresponding to openssl's SSL_CIPHER structure
#
# returns: (string) cipher name e.g. 'TLSv1/SSLv3' with some libraries, 'TLSv1.0' or 'TLSv1.3', '(NONE)' if $cipher is undefined.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_version.html>

  • CIPHER_get_handshake_digest โ€” COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.1.1-pre1, not in LibreSSL.

Returns version of SSL/TLS protocol that first defined the cipher.

my $rv = Net::SSLeay::CIPHER_get_handshake_digest($cipher);
# $cipher - value corresponding to openssl's SSL_CIPHER structure
#
# returns: A value corresponding to OpenSSL's EVP_MD structure for the digest used during the SSL/TLS handshake when using $cipher.

Check openssl doc <https://www.openssl.org/docs/ssl/SSL_CIPHER_get_handshake_digest.html>

  • CIPHER_find โ€” COMPATIBILITY: not available in Net-SSLeay-1.92 and before; requires at least OpenSSL 1.0.2 or LibreSSL 3.4.0.

Returns a SSL_CIPHER structure from the current SSL using a two octet cipher ID.

my $cipher = Net::SSLeay::CIPHER_find($ssl, $id);
# $ssl - value corresponding to OpenSSL SSL structure
# $id - two octet cipher ID.
#
# returns: A value corresponding to OpenSSL SSL_CIPHER structure or undef if cipher is not found or an error occurs.

Example that prints 'OpenSSL name is: TLS_AES_128_GCM_SHA256' with TLSv1.3 when the ciphersuite is enabled:

# TLS Cipher Suite 0x13, 0x01 is TLS_AES_128_GCM_SHA256
my $id = pack('n', 0x1301);
my $cipher =  Net::SSLeay::CIPHER_find($ssl, $id);
printf("OpenSSL name is: " . Net::SSLeay::CIPHER_get_name($cipher));

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_find.html>

  • BN_dup โ€” Creates and returns a new BIGNUM from an existing BIGNUM.
my $bn = Net::SSLeay::BN_dup($from);
# $from - value corresponding to BIGNUM structure
#
# returns: a new BIGNUM containing the value $from

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BN_dup.html>

  • BN_clear โ€” Clears BIGNUM data when it is no longer needed.
Net::SSLeay::BN_clear($bn);
# $bn - value corresponding to BIGNUM structure
#
# returns: nothing. $bn is set to 0.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BN_clear.html>

  • BN_clear_free โ€” Clears and frees a previously allocated BIGNUM.
Net::SSLeay::BN_clear_free($bn);
# $bn - value corresponding to BIGNUM structure
#
# returns: nothing. $bn is no longer usable.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BN_clear_free.html>

  • BN_free โ€” Frees a previously allocated BIGNUM.
Net::SSLeay::BN_free($bn);
# $bn - value corresponding to BIGNUM structure
#
# returns: nothing. $bn is no longer usable.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BN_free.html>

  • RSA_generate_key โ€” Generates a key pair and returns it in a newly allocated RSA structure. The pseudo-random number generator must be seeded prior to calling RSA_generate_key.
my $rv = Net::SSLeay::RSA_generate_key($bits, $e, $perl_cb, $perl_cb_arg);
# $bits - (integer) modulus size in bits e.g. 512, 1024, 2048
# $e - (integer) public exponent, an odd number, typically 3, 17 or 65537
# $perl_cb - [optional] reference to perl callback function
# $perl_cb_arg - [optional] data that will be passed to callback function when invoked
#
# returns: value corresponding to openssl's RSA structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/RSA_generate_key.html>

  • RSA_free โ€” Frees the RSA structure and its components. The key is erased before the memory is returned to the system.
Net::SSLeay::RSA_free($r);
# $r - value corresponding to openssl's RSA structure
#
# returns: no return value

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/RSA_new.html>

  • RSA_get_key_parameters โ€” COMPATIBILITY: not available when OpenSSL is 1.1.0 or later and Net-SSLeay is 1.92 or earlier.

Returns a list of pointers to BIGNUMs representing the parameters of the key in this order: (n, e, d, p, q, dmp1, dmq1, iqmp)

Caution: returned list consists of direct pointers to BIGNUMs. These must not be freed by the caller. These pointers can be used to duplicate a BIGNUM, which would need to be blessed as Crypt::OpenSSL::Bignum for further use. See Crypt::OpenSSL::Bignum and OpenSSL manual for more about "bless_pointer" to why BN_dup() is used.
my (@params) = RSA_get_key_parameters($r);

my $dup = Net::SSLeay::BN_dup($params[1]);
my $e = Crypt::OpenSSL::Bignum->bless_pointer($dup);
print "exponent: ", $e->to_decimal(), "\n";

This function has no equivalent in OpenSSL or LibreSSL but combines functions "RSA_get0_key", "RSA_get0_factors" and "RSA_get0_crt_params" for an easier interface.

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html>

  • BIO_eof โ€” Returns 1 if the BIO has read EOF, the precise meaning of 'EOF' varies according to the BIO type.
my $rv = Net::SSLeay::BIO_eof($s);
# $s - value corresponding to openssl's BIO structure
#
# returns: 1 if EOF has been reached 0 otherwise

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_ctrl.html>

  • BIO_f_ssl โ€” Returns the SSL BIO method. This is a filter BIO which is a wrapper round the OpenSSL SSL routines adding a BIO 'flavour' to SSL I/O.
my $rv = Net::SSLeay::BIO_f_ssl();
#
# returns: value corresponding to openssl's BIO_METHOD structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html>

  • BIO_free โ€” Frees up a single BIO.
my $rv = Net::SSLeay::BIO_free($bio);
# $bio; - value corresponding to openssl's BIO structure
#
# returns: 1 on success, 0 on failure

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_new.html>

  • BIO_new โ€” Returns a new BIO using method $type.
my $rv = Net::SSLeay::BIO_new($type);
# $type - value corresponding to openssl's BIO_METHOD structure
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_new.html>

  • BIO_new_buffer_ssl_connect โ€” Creates a new BIO chain consisting of a buffering BIO, an SSL BIO (using ctx) and a connect BIO.
my $rv = Net::SSLeay::BIO_new_buffer_ssl_connect($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html>

  • BIO_new_file โ€” Creates a new file BIO with mode $mode the meaning of mode is the same as the stdio function fopen(). The BIO_CLOSE flag is set on the returned BIO.
my $rv = Net::SSLeay::BIO_new_file($filename, $mode);
# $filename - (string) filename
# $mode - (string) opening mode (as mode by stdio function fopen)
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_s_file.html>

  • BIO_new_ssl โ€” Allocates an SSL BIO using SSL_CTX ctx and using client mode if client is non zero.
my $rv = Net::SSLeay::BIO_new_ssl($ctx, $client);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $client - (integer) 0 or 1 - indicates ssl client mode
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html>

  • BIO_new_ssl_connect โ€” Creates a new BIO chain consisting of an SSL BIO (using ctx) followed by a connect BIO.
my $rv = Net::SSLeay::BIO_new_ssl_connect($ctx);
# $ctx - value corresponding to openssl's SSL_CTX structure
#
# returns: value corresponding to openssl's BIO structure (0 on failure)

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html>

  • BIO_pending โ€” Return the number of pending characters in the BIOs read buffers.
my $rv = Net::SSLeay::BIO_pending($s);
# $s - value corresponding to openssl's BIO structure
#
# returns: the amount of pending data

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_ctrl.html>

  • BIO_wpending โ€” Return the number of pending characters in the BIOs write buffers.
my $rv = Net::SSLeay::BIO_wpending($s);
# $s - value corresponding to openssl's BIO structure
#
# returns: the amount of pending data

Check openssl doc <https://www.openssl.org/docs/manmaster/man3/BIO_ctrl.html>

  • BIO_read โ€” Reads the underlying descriptor.

and the actual invocation is this, bestie:

Net::SSLeay::BIO_read($s, $max);
# $s - value corresponding to openssl's BIO structure
# $max - [optional] max. bytes to read (if not specified, the value 32768 is used)
#
# returns: data

Check openssl doc https://www.openssl.org/docs/manmaster/man3/BIO_read.html

  • BIO_write โ€” tries to write the data sitting in $buffer out to BIO $b. That's it, that's the whole vibe ๐Ÿซถ
my $rv = Net::SSLeay::BIO_write($b, $buffer);
# $b - value corresponding to openssl's BIO structure
# $buffer - data
#
# returns: amount of data successfully written
#          or that no data was successfully read or written if the result is 0 or -1
#          or -2 when the operation is not implemented in the specific BIO type

Check openssl doc https://www.openssl.org/docs/manmaster/man3/BIO_read.html

  • BIO_s_mem โ€” hands you back the memory BIO method function. Very "here's the blueprint" of it all โœจ
my $rv = Net::SSLeay::BIO_s_mem();
#
# returns: value corresponding to openssl's BIO_METHOD structure (0 on failure)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/BIO_s_mem.html

  • BIO_ssl_copy_session_id โ€” copies an SSL session id between BIO chains, from $from to $to. It pulls this off by hunting down the SSL BIOs in each chain and calling SSL_copy_session_id() on the internal SSL pointer. Sneaky but iconic ๐Ÿ’…
my $rv = Net::SSLeay::BIO_ssl_copy_session_id($to, $from);
# $to - value corresponding to openssl's BIO structure
# $from - value corresponding to openssl's BIO structure
#
# returns: 1 on success, 0 on failure

Check openssl doc https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html

  • BIO_ssl_shutdown โ€” closes down an SSL connection on BIO chain bio. Same trick as above: it finds the SSL BIO in the chain and calls SSL_shutdown() on its internal SSL pointer. Goodbye bestie ๐Ÿ‘‹
Net::SSLeay::BIO_ssl_shutdown($ssl_bio);
# $ssl_bio - value corresponding to openssl's BIO structure
#
# returns: no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/BIO_f_ssl.html


๐ŸŒธ Low level API: Server side Server Name Indication (SNI) support ๐ŸŒธ

  • set_tlsext_host_name โ€” TBA
  • get_servername โ€” TBA
  • get_servername_type โ€” TBA
  • CTX_set_tlsext_servername_callback โ€” COMPATIBILITY: requires at least OpenSSL 0.9.8f

This one's the server-side glow-up for Server Name Indication (SNI). If you're the server and you're juggling multiple certs, this is your main character moment ๐Ÿ‘‘

Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, $code);
# $ctx - SSL context
# $code - reference to a subroutine that will be called when a new connection is being initiated
#
# returns: no return value

On the client side: use set_tlsext_host_name($ssl, $servername) before initiating the SSL connection.

On the server side: set up an additional SSL_CTX() for each different certificate.

Add a servername callback to each SSL_CTX() using CTX_set_tlsext_servername_callback().

The callback function is required to retrieve the client-supplied servername with get_servername(ssl). Figure out the right SSL_CTX to go with that host name, then switch the SSL object to that SSL_CTX with set_SSL_CTX().

Example:

# set callback
Net::SSLeay::CTX_set_tlsext_servername_callback($ctx,
    sub {
        my $ssl = shift;
        my $h = Net::SSLeay::get_servername($ssl);
        Net::SSLeay::set_SSL_CTX($ssl, $hostnames{$h}->{ctx}) if exists $hostnames{$h};
    } );

More complete example:

# ... initialize Net::SSLeay

my %hostnames = (
    'sni1' => { cert=>'sni1.pem', key=>'sni1.key' },
    'sni2' => { cert=>'sni2.pem', key=>'sni2.key' },
);

# create a new context for each certificate/key pair
for my $name (keys %hostnames) {
    $hostnames{$name}->{ctx} = Net::SSLeay::CTX_new or die;
    Net::SSLeay::CTX_set_cipher_list($hostnames{$name}->{ctx}, 'ALL');
    Net::SSLeay::set_cert_and_key($hostnames{$name}->{ctx},
    $hostnames{$name}->{cert}, $hostnames{$name}->{key}) or die;
}

# create default context
my $ctx = Net::SSLeay::CTX_new or die;
Net::SSLeay::CTX_set_cipher_list($ctx, 'ALL');
Net::SSLeay::set_cert_and_key($ctx, 'cert.pem','key.pem') or die;

# set callback
Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub {
    my $ssl = shift;
    my $h = Net::SSLeay::get_servername($ssl);
    Net::SSLeay::set_SSL_CTX($ssl, $hostnames{$h}->{ctx}) if exists $hostnames{$h};
} );

# ... later

$s = Net::SSLeay::new($ctx);
Net::SSLeay::set_fd($s, fileno($accepted_socket));
Net::SSLeay::accept($s);

Heads up bestie ๐Ÿ’€ NPN is being replaced with ALPN, a more recent TLS extension for application protocol negotiation that's in process of being adopted by IETF. Please look below for APLN API description.

Simple approach for using NPN support looks like this:

### client side
use Net::SSLeay;
use IO::Socket::INET;

Net::SSLeay::initialize();
my $sock = IO::Socket::INET->new(PeerAddr=>'encrypted.google.com:443') or die;
my $ctx = Net::SSLeay::CTX_tlsv1_new() or die;
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
Net::SSLeay::CTX_set_next_proto_select_cb($ctx, ['http1.1','spdy/2']);
my $ssl = Net::SSLeay::new($ctx) or die;
Net::SSLeay::set_fd($ssl, fileno($sock)) or die;
Net::SSLeay::connect($ssl);

warn "client:negotiated=",Net::SSLeay::P_next_proto_negotiated($ssl), "\n";
warn "client:last_status=", Net::SSLeay::P_next_proto_last_status($ssl), "\n";

### server side
use Net::SSLeay;
use IO::Socket::INET;

Net::SSLeay::initialize();
my $ctx = Net::SSLeay::CTX_tlsv1_new() or die;
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
Net::SSLeay::set_cert_and_key($ctx, "cert.pem", "key.pem");
Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, ['spdy/2','http1.1']);
my $sock = IO::Socket::INET->new(LocalAddr=>'localhost', LocalPort=>5443, Proto=>'tcp', Listen=>20) or die;

while (1) {
    my $ssl = Net::SSLeay::new($ctx);
    warn("server:waiting for incoming connection...\n");
    my $fd = $sock->accept();
    Net::SSLeay::set_fd($ssl, $fd->fileno);
    Net::SSLeay::accept($ssl);
    warn "server:negotiated=",Net::SSLeay::P_next_proto_negotiated($ssl),"\n";
    my $got = Net::SSLeay::read($ssl);
    Net::SSLeay::ssl_write_all($ssl, "length=".length($got));
    Net::SSLeay::free($ssl);
    $fd->close();
}
# check with: openssl s_client -connect localhost:5443 -nextprotoneg http/1.1,spdy/2

Please note that the selection (negotiation) is performed by client side, the server side simply advertise the list of supported protocols. The client picks, the server just vibes and hands over the menu ๐Ÿ“

Advanced approach allows you to implement your own negotiation algorithm.

# see below documentation for:
Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $perl_callback_function, $callback_data);
Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $perl_callback_function, $callback_data);

Detection of NPN support (works even in older Net::SSLeay versions):

use Net::SSLeay;

if (exists &Net::SSLeay::P_next_proto_negotiated) {
    # do NPN stuff
}
  • CTX_set_next_proto_select_cb โ€” COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 1.0.1

NOTE: You need CTX_set_next_proto_select_cb on client side of SSL connection.

Simple usage โ€” in this case a "common" negotiation algorithm (as implemented by openssl's function SSL_select_next_proto) is used.

$rv = Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $arrayref);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $arrayref - list of accepted protocols - e.g. ['http1.0', 'http1.1']
#
# returns: 0 on success, 1 on failure

Advanced usage (you probably do not need this):

$rv = Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $perl_callback_function, $callback_data);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $perl_callback_function - reference to perl function
# $callback_data - [optional] data to passed to callback function when invoked
#
# returns: 0 on success, 1 on failure

# where callback function looks like
sub npn_advertised_cb_invoke {
    my ($ssl, $arrayref_proto_list_advertised_by_server, $callback_data) = @_;
    my $status;
    # ...
    $status = 1;   # status can be:
                  # 0 - OPENSSL_NPN_UNSUPPORTED
                  # 1 - OPENSSL_NPN_NEGOTIATED
                  # 2 - OPENSSL_NPN_NO_OVERLAP
    return $status, ['http1.1','spdy/2']; # the callback has to return 2 values
}

To undefine/clear this callback use:

Net::SSLeay::CTX_set_next_proto_select_cb($ctx, undef);
  • CTX_set_next_protos_advertised_cb โ€” COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 1.0.1

NOTE: You need CTX_set_next_proto_select_cb on server side of SSL connection. (yep, that's literally what it says ๐Ÿ’€)

Simple usage:

$rv = Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $arrayref);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $arrayref - list of advertised protocols - e.g. ['http1.0', 'http1.1']
#
# returns: 0 on success, 1 on failure

Advanced usage (you probably do not need this):

$rv = Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $perl_callback_function, $callback_data);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $perl_callback_function - reference to perl function
# $callback_data - [optional] data to passed to callback function when invoked
#
# returns: 0 on success, 1 on failure

# where callback function looks like
sub npn_advertised_cb_invoke {
    my ($ssl, $callback_data) = @_;
    # ...
    return ['http1.1','spdy/2']; # the callback has to return arrayref
}

To undefine/clear this callback use:

Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, undef);
  • P_next_proto_negotiated โ€” ๐Ÿ’– ok so this one hands you back the name of the protocol that actually got negotiated on this SSL connection $ssl. That's it, that's the whole vibe.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 1.0.1

$rv = Net::SSLeay::P_next_proto_negotiated($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (string) negotiated protocol name (or undef if no negotiation was done or failed with fatal error)
  • P_next_proto_last_status โ€” ๐Ÿฆ‹ and this one tells you how the last negotiation went down on $ssl, like a little report card.

COMPATIBILITY: not available in Net-SSLeay-1.45 and before; requires at least OpenSSL 1.0.1

$rv = Net::SSLeay::P_next_proto_last_status($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (integer) negotiation status
#          0 - OPENSSL_NPN_UNSUPPORTED
#          1 - OPENSSL_NPN_NEGOTIATED
#          2 - OPENSSL_NPN_NO_OVERLAP

So bestie, here's the tea โ˜• โ€” you've got two different mechanisms for negotiating an application protocol, and they ride on two different TLS extensions: NPN (obsolete, grandmacore) and ALPN (recommended, main character energy).

The API's pretty similar between them, but with slight differences that just reflect how each protocol actually works. Specifically: with ALPN the protocol negotiation happens on the server, whereas with NPN it's the client doing the negotiation logic. Yeah, whole different job description ๐Ÿ’….

With ALPN, the most basic implementation looks exactly like this:

### client side
use Net::SSLeay;
use IO::Socket::INET;

Net::SSLeay::initialize();
my $sock = IO::Socket::INET->new(PeerAddr=>'encrypted.google.com:443') or die;
my $ctx = Net::SSLeay::CTX_tlsv1_new() or die;
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
Net::SSLeay::CTX_set_alpn_protos($ctx, ['http/1.1', 'http/2.0', 'spdy/3']);
my $ssl = Net::SSLeay::new($ctx) or die;
Net::SSLeay::set_fd($ssl, fileno($sock)) or die;
Net::SSLeay::connect($ssl);

warn "client:selected=",Net::SSLeay::P_alpn_selected($ssl), "\n";

### server side
use Net::SSLeay;
use IO::Socket::INET;

Net::SSLeay::initialize();
my $ctx = Net::SSLeay::CTX_tlsv1_new() or die;
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
Net::SSLeay::set_cert_and_key($ctx, "cert.pem", "key.pem");
Net::SSLeay::CTX_set_alpn_select_cb($ctx, ['http/1.1', 'http/2.0', 'spdy/3']);
my $sock = IO::Socket::INET->new(LocalAddr=>'localhost', LocalPort=>5443, Proto=>'tcp', Listen=>20) or die;

while (1) {
    my $ssl = Net::SSLeay::new($ctx);
    warn("server:waiting for incoming connection...\n");
    my $fd = $sock->accept();
    Net::SSLeay::set_fd($ssl, $fd->fileno);
    Net::SSLeay::accept($ssl);
    warn "server:selected=",Net::SSLeay::P_alpn_selected($ssl),"\n";
    my $got = Net::SSLeay::read($ssl);
    Net::SSLeay::ssl_write_all($ssl, "length=".length($got));
    Net::SSLeay::free($ssl);
    $fd->close();
}
# check with: openssl s_client -connect localhost:5443 -alpn spdy/3,http/1.1

โœจ And if you're feeling extra (advanced approach energy), you can implement your own negotiation algorithm:

# see below documentation for:
Net::SSLeay::CTX_set_alpn_select_cb($ctx, $perl_callback_function, $callback_data);

Detecting whether ALPN support is even there (and yes, this works even in older Net::SSLeay versions, iconic behaviour):

use Net::SSLeay;

if (exists &Net::SSLeay::P_alpn_selected) {
    # do ALPN stuff
}
  • CTX_set_alpn_select_cb โ€” ๐Ÿ‘‘ server-side bestie, this is the one you need.

COMPATIBILITY: not available in Net-SSLeay-1.55 and before; requires at least OpenSSL 1.0.2

NOTE: You need CTX_set_alpn_select_cb on server side of TLS connection.

Simple usage โ€” and in this case a "common" negotiation algorithm gets used (the one implemented by openssl's function SSL_select_next_proto, so you don't gotta cook):

$rv = Net::SSLeay::CTX_set_alpn_select_cb($ctx, $arrayref);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $arrayref - list of accepted protocols - e.g. ['http/2.0', 'http/1.1', 'spdy/3']
#
# returns: 0 on success, 1 on failure

Advanced usage (you probably do not need this, fr fr):

$rv = Net::SSLeay::CTX_set_alpn_select_cb($ctx, $perl_callback_function, $callback_data);
# $ctx - value corresponding to openssl's SSL_CTX structure
# $perl_callback_function - reference to perl function
# $callback_data - [optional] data to passed to callback function when invoked
#
# returns: 0 on success, 1 on failure

# where callback function looks like
sub alpn_select_cb_invoke {
    my ($ssl, $arrayref_proto_list_advertised_by_client, $callback_data) = @_;
    # ...
    if ($negotiated) {
        return 'http/2.0';
    } else {
        return undef;
    }
}

To undefine/clear this callback use:

Net::SSLeay::CTX_set_alpn_select_cb($ctx, undef);
  • set_alpn_protos โ€” ๐Ÿซถ client-side queen.

COMPATIBILITY: not available in Net-SSLeay-1.55 and before; requires at least OpenSSL 1.0.2

NOTE: You need set_alpn_protos on client side of TLS connection.

This adds a list of supported application layer protocols to the ClientHello message sent by a client. It advertises the enumeration of supported protocols:

Net::SSLeay::set_alpn_protos($ssl, ['http/1.1', 'http/2.0', 'spdy/3']);
# returns 0 on success
  • CTX_set_alpn_protos โ€” ๐Ÿ’… same energy, but at the CTX level.

COMPATIBILITY: not available in Net-SSLeay-1.55 and before; requires at least OpenSSL 1.0.2

NOTE: You need CTX_set_alpn_protos on client side of TLS connection.

This adds a list of supported application layer protocols to the ClientHello message sent by a client. It advertises the enumeration of supported protocols:

Net::SSLeay::CTX_set_alpn_protos($ctx, ['http/1.1', 'http/2.0', 'spdy/3']);
# returns 0 on success
  • P_alpn_selected โ€” ๐ŸŒธ the reveal ๐Ÿ’ซ โ€” tells you which protocol won on this TLS connection $ssl.

COMPATIBILITY: not available in Net-SSLeay-1.55 and before; requires at least OpenSSL 1.0.2

$rv = Net::SSLeay::P_alpn_selected($ssl);
# $ssl - value corresponding to openssl's SSL structure
#
# returns: (string) negotiated protocol name (or undef if no negotiation was done or failed with fatal error)

๐Ÿงš Low level API: DANE Support

OpenSSL version 1.0.2 adds preliminary support for RFC6698 Domain Authentication of Named Entities (DANE) Transport Layer Association within OpenSSL. Yes that's a lot of capital letters, breathe ๐Ÿซง.

  • SSL_get_tlsa_record_byname โ€” ๐Ÿ˜ญ and here's the sad part, bestie...

COMPATIBILITY: DELETED from net-ssleay, since it is not supported by OpenSSL

In order to facilitate DANE there is additional interface, SSL_get_tlsa_record_byname, accepting hostname, port and socket type that returns packed TLSA record. In order to make it even easier there is additional SSL_ctrl function that calls SSL_get_tlsa_record_byname for you. Latter is recommended for programmers that wish to maintain broader binary compatibility, e.g. make application work with both 1.0.2 and prior version (in which case call to SSL_ctrl with new code returning error would have to be ignored when running with prior version).

Net::SSLeay::get_tlsa_record_byname($name, $port, $type);

โญ Low level API: Other functions

  • COMP_add_compression_method โ€” ๐ŸŽ€ this adds the compression method $cm with the identifier $id to the list of available compression methods. And heads up: that list is globally maintained for all SSL operations within this application โ€” it cannot be set for specific SSL_CTX or SSL objects. So like, it's for everyone, no exclusivity ๐Ÿ’€.
my $rv = Net::SSLeay::COMP_add_compression_method($id, $cm);
# $id - (integer) compression method id
#       0 to 63:    methods defined by the IETF
#       64 to 192:  external party methods assigned by IANA
#       193 to 255: reserved for private use
#
# $cm - value corresponding to openssl's COMP_METHOD structure
#
# returns: 0 on success, 1 on failure (check the error queue to find out the reason)

Check openssl doc https://www.openssl.org/docs/manmaster/man3/SSL_COMP_add_compression_method.html

  • DH_free โ€” ๐Ÿฆ‹ frees the DH structure and all its components. And the values are erased before the memory goes back to the system โ€” clean girl behaviour โœจ.
Net::SSLeay::DH_free($dh);
# $dh - value corresponding to openssl's DH structure
#
# returns: no return value

Check openssl doc https://www.openssl.org/docs/manmaster/man3/DH_new.html

  • FIPS_mode_set โ€” ๐Ÿ”ฅ enables or disables FIPS mode in a FIPS capable OpenSSL.
Net::SSLeay::FIPS_mode_set($enable);
# $enable - (integer) 1 to enable, 0 to disable

  • CTX_set_tmp_ecdh โ€” TBA
  • EC_KEY_free โ€” TBA
  • EC_KEY_new_by_curve_name โ€” TBA
  • EC_KEY_generate_key โ€” ๐Ÿ“ generates an EC key and returns it in a newly allocated EC_KEY structure. That key can then be used to create a PKEY, which can be used in calls like X509_set_pubkey. Look at it being all useful and connected ๐Ÿ’œ.
my $key = Net::SSLeay::EVP_PKEY_new();
my $ec  = Net::SSLeay::EC_KEY_generate_key($curve);
Net::SSLeay::EVP_PKEY_assign_EC_KEY($key,$ec);

# $curve - curve name like 'secp521r1' or the matching Id (integer) of the curve
#
# returns: value corresponding to openssl's EC_KEY structure (0 on failure)

This function has no equivalent in OpenSSL but combines multiple OpenSSL functions for an easier interface. Glow-up behaviour ๐Ÿ’…โœจ.

  • CTX_set_ecdh_auto, set_ecdh_auto โ€” ๐ŸŒˆ these two enable or disable the automatic curve selection on the server side by calling SSL_CTX_set_ecdh_auto or SSL_set_ecdh_auto respectively. If enabled, the highest preference curve gets automatically used for ECDH temporary keys during key exchange. And no cap: this function is no longer available for OpenSSL 1.1.0 or higher ๐Ÿซ .
Net::SSLeay::CTX_set_ecdh_auto($ctx,1);
Net::SSLeay::set_ecdh_auto($ssl,1);
  • CTX_set1_curves_list, set1_curves_list
  • CTX_set1_curves_list, set1_curves_list โ€” these set the supported curves (in the order you like them best ๐Ÿ’…) by calling SSL_CTX_set1_curves_list or SSL_set1_curves_list respectively. On a TLS client these curves get offered to the server in the supported curves extension, and on the server side they're what determines the shared curve. Heads up bestie: these functions are only available since OpenSSL 1.1.0.
Net::SSLeay::CTX_set1_curves_list($ctx,"P-521:P-384:P-256");
Net::SSLeay::set1_curves_list($ssl,"P-521:P-384:P-256");
  • CTX_set1_groups_list, set1_groups_list โ€” these set the supported groups (again, in order of preference, main character first โœจ) by calling SSL_CTX_set1_groups_list or SSL_set1_groups_list respectively. Lowkey this is practically the same as CTX_set1_curves_list and set1_curves_list, except that all DH groups can be given as supported by TLS 1.3. These functions are only available since OpenSSL 1.1.1.
Net::SSLeay::CTX_set1_groups_list($ctx,"P-521:P-384:P-256");
Net::SSLeay::set1_groups_list($ssl,"P-521:P-384:P-256");
  • OSSL_LIB_CTX_get0_global_default โ€” returns a concrete (non-NULL) reference to the global default library context ๐Ÿซถ
my $libctx = Net::SSLeay::OSSL_LIB_CTX_get0_global_default();
# returns: a value corresponding to OSSL_LIB_CTX structure or false on failure

Typically it's simpler to just use undef with functions that take an OSSL_LIB_CTX argument when the global default library context is what you need โ€” honestly, iconic shortcut energy.

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_LIB_CTX_get0_global_default.html

  • OSSL_PROVIDER_load โ€” loads and initializes a provider โœจ
my $provider = Net::SSLeay::OSSL_PROVIDER_load($libctx, $name);
# $libctx - value corresponding to OSSL_LIB_CTX structure or undef
# $name - (string) provider name, e.g., 'legacy'
#
# returns: a value corresponding to OSSL_PROVIDER or false on failure

Passing undef loads the provider inside the global default library context, like so:

my $provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'legacy');

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_load.html

  • OSSL_PROVIDER_try_load โ€” loads and initializes a provider, kinda like OSSL_PROVIDER_load but with extra fallback control for when you're feeling cautious ๐Ÿ™ˆ
my $provider = Net::SSLeay::OSSL_PROVIDER_try_load($libctx, $name, $retain_fallbacks);
# $libctx - value corresponding to OSSL_LIB_CTX structure or undef
# $name - (string) provider name, e.g., 'legacy'
# $retain_fallbacks - (integer) 0 or 1
#
# returns: a value corresponding to OSSL_PROVIDER or false on failure

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_try_load.html

  • OSSL_PROVIDER_unload โ€” unloads the given provider. bye bestie ๐Ÿ‘‹
my $rv = Net::SSLeay::OSSL_PROVIDER_unload($provider);
# $provider - a value corresponding to OSSL_PROVIDER
#
# returns: (integer) 1 on success, 0 on error

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_unload.html

  • OSSL_PROVIDER_available โ€” checks if a named provider is available for use ๐Ÿ”
my $rv = Net::SSLeay::OSSL_PROVIDER_available($libctx, $name);
# $libctx - value corresponding to OSSL_LIB_CTX structure or undef
# $name - (string) provider name, e.g., 'legacy'
#
# returns: (integer) 1 if the named provider is available, otherwise 0.

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_available.html

  • OSSL_PROVIDER_do_all โ€” iterates over all loaded providers, calling a callback for each one ๐ŸŒˆ
my $rv = Net::SSLeay::OSSL_PROVIDER_do_all($libctx, $cb, $cbdata);
# $libctx - value corresponding to OSSL_LIB_CTX structure or undef
# $cb - reference to a perl callback function
# $cbdata - data that will be passed to callback function
#
# returns: (integer) 1 if all callbacks returned 1, 0 the first time a callback returns 0.

Example, because examples are everything ๐Ÿ’–:

sub do_all_cb {
    my ($provider, $cbdata) = @_;

    my $name = Net::SSLeay::OSSL_PROVIDER_get0_name($provider);
    print "Callback for provider: '$name', cbdata: '$cbdata'\n";
    return 1;
}
my $data_for_cb = 'Hello';

# Triggers default provider automatic loading.
Net::SSLeay::OSSL_PROVIDER_available(undef, 'default') || die 'default provider not available';
Net::SSLeay::OSSL_PROVIDER_load(undef, 'legacy') || die 'load legacy';
Net::SSLeay::OSSL_PROVIDER_load(undef, 'null')   || die 'load null';
Net::SSLeay::OSSL_PROVIDER_do_all(undef, \&do_all_cb, $data_for_cb) || die 'a callback failed';

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_do_all.html

  • OSSL_PROVIDER_get0_name โ€” returns the name of the given provider ๐ŸŽ€
my $name = Net::SSLeay::OSSL_PROVIDER_get0_name($provider);
# $provider - a value corresponding to OSSL_PROVIDER
#
# returns: (string) provider name, e.g., 'legacy'

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_get0_name.html

  • OSSL_PROVIDER_self_test โ€” runs the provider's self tests, like a little wellness check for your crypto ๐Ÿ”ฅ
my $rv = Net::SSLeay::OSSL_PROVIDER_self_test($provider);
# $libctx - value corresponding to OSSL_LIB_CTX structure or undef
# $provider - a value corresponding to OSSL_PROVIDER
#
# returns: (integer) returns 1 if the self tests pass, 0 on error

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/OSSL_PROVIDER_self_test.html


COMPATIBILITY: not available in Net-SSLeay-1.92 and before. The TLSv1.3 specific functions require at least OpenSSL 1.1.1 and the others require at least OpenSSL 1.0.0. Not available in LibreSSL. (Yeah, that's a whole lot of nope on the older stacks ๐Ÿ˜ญ)

  • CTX_use_psk_identity_hint โ€” sets the PSK identity hint for an SSL_CTX on a TLS server, for TLSv1.2 and earlier versions.
my $ret = Net::SSLeay::CTX_use_psk_identity_hint($ctx, $hint);
# $ctx - value corresponding to OpenSSL SSL_CTX structure
# $hint - string, a hint sent to the TLS clients
#
# returns: 1 on success, 0 on failure

Example:

my $ret = Net::SSLeay::CTX_use_psk_identity_hint($ctx, 'ctx server identity_hint');

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_use_psk_identity_hint.html

  • use_psk_identity_hint โ€” sets the PSK identity hint for an SSL on a TLS server, for TLSv1.2 and earlier versions.
my $ret = Net::SSLeay::use_psk_identity_hint($ssl, $hint);
# $ssl - value corresponding to OpenSSL SSL structure
# $hint - string, a hint sent to the TLS clients
#
# returns: 1 on success, 0 on failure

Example:

my $ret = Net::SSLeay::use_psk_identity_hint($ssl, 'ssl server identity_hint');

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_use_psk_identity_hint.html

  • CTX_set_psk_server_callback โ€” sets a callback for an SSL_CTX on a TLS server, for using PSKs with all TLS versions ๐Ÿ‘‘
NOTE: with TLSv1.3, Net::SSLeay::CTX_set_psk_find_session_callback or Net::SSLeay::set_psk_find_session_callback is recommended instead. iykyk ๐Ÿ’…
# First set up a callback function.
sub tls12_psk_cb {
    my ($ssl, $identity, $max_psk_len) = @_;

    # Note: $identity is potentially hostile user supplied data

    my $psk = pack('H*', 'deadbeef');
    return $psk if length $psk <= $max_psk_len;

    return undef;
}

my $cb = \&tls12_psk_cb;
Net::SSLeay::CTX_set_psk_server_callback($ctx, $cb);
# $ctx - value corresponding to OpenSSL SSL_CTX structure
# $cb - reference to callback function
#
# returns: no return value

The callback function must return a PSK in packed binary format, or undef to trigger the unknown_psk_identity alert and a TLS handshake failure. If you need a TLS handshake failure without the PSK specific alert, return packed random data instead. No cap, that's the trick ๐Ÿซก

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_psk_server_callback.html

  • set_psk_server_callback โ€” sets a callback for an SSL on a TLS server, for using PSKs with all TLS versions.
NOTE: with TLSv1.3, Net::SSLeay::CTX_set_psk_find_session_callback or Net::SSLeay::set_psk_find_session_callback is the recommended move โœจ
Net::SSLeay::set_psk_server_callback($ssl, $cb);
# $ssl - value corresponding to OpenSSL SSL structure
# $cb - reference to callback function
#
# returns: no return value

See the Net::SSLeay::CTX_set_psk_server_callback() documentation for a full example with a callback โ€” it's the same vibe, just SSL-flavoured.

Check the openssl doc at https://www.openssl.org/docs/manmaster/man3/SSL_set_psk_server_callback.html

  • CTX_set_psk_find_session_callback โ€” sets a callback for an SSL_CTX on a TLS server for using TLSv1.3 PSKs ๐Ÿฆ‹
# First set up a callback function.
sub tls13_psk_cb {
    my ($ssl, $identity) = @_;

    # Note: $identity is potentially hostile user supplied data

    my $sess = Net::SSLeay::SESSION_new();
    my $cipher = Net::SSLeay::CIPHER_find($ssl, pack('n', 0x1301));
    Net::SSLeay::SESSION_set1_master_key($sess, pack('H*', 'deadbeef'));
    Net::SSLeay::SESSION_set_cipher($sess, $cipher);
    Net::SSLeay::SESSION_set_protocol_version($sess, Net::SSLeay::version($ssl));

    return (1, $sess);
}

my $cb = \&tls13_psk_cb;
Net::SSLeay::CTX_set_psk_find_session_callback($ctx, $cb);
# $ctx - value corresponding to OpenSSL SSL_CTX structure
# $cb - reference to callback function
#
# returns: no return value

The callback function must return a two value list. When the first value is 0, the connection setup fails ๐Ÿ’€. When the first value is 1, the second value must be a valid SSL_SESSION or undef. When that second value is a valid SSL_SESSION, the TLS handshake proceeds with PSK authentication. When the second value is undef, PSK is not used and the TLS handshake proceeds with certificate authentication. Two paths, one callback โ€” periodt ๐ŸŒธ

  • set_psk_find_session_callback โ€” okay so this one sets a callback on an SSL for a TLS server, specifically for using TLSv1.3 PSKs. ๐Ÿ’…
Net::SSLeay::set_psk_find_session_callback($ssl, $cb);
# $ssl - value corresponding to OpenSSL SSL structure
# $cb - reference to callback function
#
# returns: no return value

Wanna see a full example with a callback? Peep the docs for Net::SSLeay::CTX_set_psk_find_session_callback(). ๐Ÿซถ

Check openssl doc: https://www.openssl.org/docs/manmaster/man3/SSL_set_psk_find_session_callback.html

  • CTX_set_psk_use_session_callback โ€” this sets a callback on an SSL_CTX for a TLS client, for TLSv1.3 PSKs. โœจ
# First set up a callback function.
sub tls13_use_psk_cb {
    my ($ssl, $md) = @_;

    my $psk_identity = "test-tls-psk";
    my $sess = Net::SSLeay::SESSION_new();
    my $cipher = Net::SSLeay::CIPHER_find($ssl, pack('n', 0x1301));
    Net::SSLeay::SESSION_set1_master_key($sess, pack('H*', 'deadbeef'));
    Net::SSLeay::SESSION_set_cipher($sess, $cipher);
    Net::SSLeay::SESSION_set_protocol_version($sess, Net::SSLeay::TLS1_3_VERSION());

    # Typically not defined, see OpenSSL manual
    if ($md) {
        my $sess_md = Net::SSLeay::CIPHER_get_handshake_digest($cipher);
        my $md_type; $md_type = Net::SSLeay::EVP_MD_type($md) if $md;
        my $sess_md_type = Net::SSLeay::EVP_MD_type($sess_md);

        if ($md_type != $sess_md_type) {
            # Example only: guess and try SHA384
            my $switched_cipher = Net::SSLeay::CIPHER_find($ssl, pack('n', 0x1302));
            my $switched_md = Net::SSLeay::CIPHER_get_handshake_digest($switched_cipher);
            my $switched_md_type = Net::SSLeay::EVP_MD_type($switched_md);
            if ($md_type != $switched_md_type) {
                # Guessed wrong, can't proceed with mismatched digest function
                Net::SSLeay::SESSION_free($sess);
                return (0, undef, undef);
            }
            Net::SSLeay::SESSION_set_cipher($sess, $switched_cipher);
        }
    }

    return (1, $psk_identity, $sess);
}

my $cb = \&tls13_use_psk_cb;
Net::SSLeay::CTX_set_psk_use_session_callback($ctx, $cb);
# $ctx - value corresponding to OpenSSL SSL_CTX structure
# $cb - reference to callback function
#
# returns: no return value

So the callback has to return a two value list. First value 0? Connection setup fails. First value 1? Then the second value has to be a valid SSL_SESSION or undef. If itโ€™s a valid SSL_SESSION, the TLS handshake proceeds with PSK authentication. If itโ€™s undef, PSK isnโ€™t used and the TLS handshake proceeds with certificate authentication. ๐Ÿ˜ญ

Check openssl doc: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_psk_find_session_callback.html

  • set_psk_use_session_callback โ€” sets a callback on an SSL for a TLS client, for TLSv1.3 PSKs. ๐ŸŒธ
# First set up a callback function.
sub tls13_psk_cb {
    my ($ssl, $identity) = @_;

    # Note: $identity is potentially hostile user supplied data

    my $sess = Net::SSLeay::SESSION_new();
    my $cipher = Net::SSLeay::CIPHER_find($ssl, pack('n', 0x1301));
    Net::SSLeay::SESSION_set1_master_key($sess, pack('H*', 'deadbeef'));
    Net::SSLeay::SESSION_set_cipher($sess, $cipher);
    Net::SSLeay::SESSION_set_protocol_version($sess, Net::SSLeay::version($ssl));

    return (1, $sess);
}

my $cb = \&tls13_psk_cb;
Net::SSLeay::CTX_set_psk_find_session_callback($ctx, $cb);
# $ctx - value corresponding to OpenSSL SSL_CTX structure
# $cb - reference to callback function
#
# returns: no return value

Same deal: callback returns a two value list. First value 0 โ†’ connection setup fails. First value 1 โ†’ second value must be a valid SSL_SESSION or undef. Valid SSL_SESSION โ†’ TLS handshake proceeds with PSK authentication. undef โ†’ PSK isnโ€™t used and the TLS handshake proceeds with certificate authentication. ๐Ÿ˜ญ

Check openssl doc: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_psk_find_session_callback.html

โœจ Constants โœจ

Bestie, Net::SSLeay has a ton of openssl constants available. You can use them like this:

use Net::SSLeay;
print &Net::SSLeay::NID_commonName;
# or
print Net::SSLeay::NID_commonName();

Or you can import them and go off:

use Net::SSLeay qw/NID_commonName/;
print &NID_commonName;
# or
print NID_commonName();
# or
print NID_commonName;

The constant names come from openssl constants, but constants that start with the SSL_ prefix get the SSL_ part stripped โ€” like opensslโ€™s SSL_OP_ALL is available as Net::SSLeay::OP_ALL. ๐Ÿงš

The list of all available constant names:

The list below is automatically generated - do not manually modify it. To add or remove a constant, edit helper_script/constants.txt, then run helper_script/update-exported-constants.

okay so we're still deep in the list and there's genuinely no way around it โ€” this is the part where you hit Ctrl+F and type the first four letters, periodt. ๐Ÿ’… Everything below is spelled exactly right, capitals and all, so copy it character-for-character. Do not get cute and "fix" anything. ๐Ÿ™ˆ

AD_ACCESS_DENIED                        OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS
AD_BAD_CERTIFICATE                      OPENSSL_INIT_NO_LOAD_SSL_STRINGS
AD_BAD_CERTIFICATE_HASH_VALUE           OPENSSL_MODULES_DIR
AD_BAD_CERTIFICATE_STATUS_RESPONSE      OPENSSL_PLATFORM
AD_BAD_RECORD_MAC                       OPENSSL_VERSION
AD_CERTIFICATE_EXPIRED                  OPENSSL_VERSION_MAJOR
AD_CERTIFICATE_REQUIRED                 OPENSSL_VERSION_MINOR
AD_CERTIFICATE_REVOKED                  OPENSSL_VERSION_NUMBER
AD_CERTIFICATE_UNKNOWN                  OPENSSL_VERSION_PATCH
AD_CERTIFICATE_UNOBTAINABLE             OPENSSL_VERSION_STRING
AD_CLOSE_NOTIFY                         OP_ALL
AD_DECODE_ERROR                         OP_ALLOW_CLIENT_RENEGOTIATION
AD_DECOMPRESSION_FAILURE                OP_ALLOW_NO_DHE_KEX
AD_DECRYPTION_FAILED                    OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
AD_DECRYPT_ERROR                        OP_CIPHER_SERVER_PREFERENCE
AD_EXPORT_RESTRICTION                   OP_CISCO_ANYCONNECT
AD_HANDSHAKE_FAILURE                    OP_CLEANSE_PLAINTEXT
AD_ILLEGAL_PARAMETER                    OP_COOKIE_EXCHANGE
AD_INAPPROPRIATE_FALLBACK               OP_CRYPTOPRO_TLSEXT_BUG
AD_INSUFFICIENT_SECURITY                OP_DISABLE_TLSEXT_CA_NAMES
AD_INTERNAL_ERROR                       OP_DONT_INSERT_EMPTY_FRAGMENTS
AD_MISSING_EXTENSION                    OP_ENABLE_KTLS
AD_NO_APPLICATION_PROTOCOL              OP_ENABLE_MIDDLEBOX_COMPAT
AD_NO_CERTIFICATE                       OP_EPHEMERAL_RSA
AD_NO_RENEGOTIATION                     OP_IGNORE_UNEXPECTED_EOF
AD_PROTOCOL_VERSION                     OP_LEGACY_SERVER_CONNECT
AD_RECORD_OVERFLOW                      OP_MICROSOFT_BIG_SSLV3_BUFFER
AD_UNEXPECTED_MESSAGE                   OP_MICROSOFT_SESS_ID_BUG
AD_UNKNOWN_CA                           OP_MSIE_SSLV2_RSA_PADDING
AD_UNKNOWN_PSK_IDENTITY                 OP_NETSCAPE_CA_DN_BUG
AD_UNRECOGNIZED_NAME                    OP_NETSCAPE_CHALLENGE_BUG
AD_UNSUPPORTED_CERTIFICATE              OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
AD_UNSUPPORTED_EXTENSION                OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
AD_USER_CANCELLED                       OP_NON_EXPORT_FIRST
ASN1_STRFLGS_ESC_CTRL                   OP_NO_ANTI_REPLAY
ASN1_STRFLGS_ESC_MSB                    OP_NO_CLIENT_RENEGOTIATION
ASN1_STRFLGS_ESC_QUOTE                  OP_NO_COMPRESSION
ASN1_STRFLGS_RFC2253                    OP_NO_ENCRYPT_THEN_MAC
ASYNC_NO_JOBS                           OP_NO_EXTENDED_MASTER_SECRET
ASYNC_PAUSED                            OP_NO_QUERY_MTU
CB_ACCEPT_EXIT                          OP_NO_RENEGOTIATION
CB_ACCEPT_LOOP                          OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
CB_ALERT                                OP_NO_SSL_MASK
CB_CONNECT_EXIT                         OP_NO_SSLv2
CB_CONNECT_LOOP                         OP_NO_SSLv3
CB_EXIT                                 OP_NO_TICKET
CB_HANDSHAKE_DONE                       OP_NO_TLSv1
CB_HANDSHAKE_START                      OP_NO_TLSv1_1
CB_LOOP                                 OP_NO_TLSv1_2
CB_READ                                 OP_NO_TLSv1_3
CB_READ_ALERT                           OP_PKCS1_CHECK_1
CB_WRITE                                OP_PKCS1_CHECK_2
CB_WRITE_ALERT                          OP_PRIORITIZE_CHACHA
CLIENT_HELLO_CB                         OP_SAFARI_ECDHE_ECDSA_BUG
CLIENT_HELLO_ERROR                      OP_SINGLE_DH_USE
CLIENT_HELLO_RETRY                      OP_SINGLE_ECDH_USE
CLIENT_HELLO_SUCCESS                    OP_SSLEAY_080_CLIENT_DH_BUG

okay pause โ€” vibe check. ๐Ÿซถ Notice how the names just tell you things? OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2, OP_NO_TLSv1_3 are sitting there in a little row like a matched set, and OP_SAFARI_ECDHE_ECDSA_BUG is fully calling out a whole browser by name. iconic. Also NID_OCSP_sign and NID_SMIMECapabilities are coming through with lowercase letters in the middle โ€” that is not a typo, that's how they're spelled, leave them alone bestie. ๐Ÿ˜ญ

Next chunk, keep scrolling:

CONF_MFLAGS_DEFAULT_SECTION             OP_SSLREF2_REUSE_CERT_TYPE_BUG
CONF_MFLAGS_IGNORE_ERRORS               OP_TLSEXT_PADDING
CONF_MFLAGS_IGNORE_MISSING_FILE         OP_TLS_BLOCK_PADDING_BUG
CONF_MFLAGS_IGNORE_RETURN_CODES         OP_TLS_D5_BUG
CONF_MFLAGS_NO_DSO                      OP_TLS_ROLLBACK_BUG
CONF_MFLAGS_SILENT                      READING
ERROR_NONE                              RECEIVED_SHUTDOWN
ERROR_SSL                               RETRY_VERIFY
ERROR_SYSCALL                           RSA_3
ERROR_WANT_ACCEPT                       RSA_F4
ERROR_WANT_ASYNC                        R_BAD_AUTHENTICATION_TYPE
ERROR_WANT_ASYNC_JOB                    R_BAD_CHECKSUM
ERROR_WANT_CLIENT_HELLO_CB              R_BAD_MAC_DECODE
ERROR_WANT_CONNECT                      R_BAD_RESPONSE_ARGUMENT
ERROR_WANT_READ                         R_BAD_SSL_FILETYPE
ERROR_WANT_RETRY_VERIFY                 R_BAD_SSL_SESSION_ID_LENGTH
ERROR_WANT_WRITE                        R_BAD_STATE
ERROR_WANT_X509_LOOKUP                  R_BAD_WRITE_RETRY
ERROR_ZERO_RETURN                       R_CHALLENGE_IS_DIFFERENT
EVP_PKS_DSA                             R_CIPHER_TABLE_SRC_ERROR
EVP_PKS_EC                              R_INVALID_CHALLENGE_LENGTH
EVP_PKS_RSA                             R_NO_CERTIFICATE_SET
EVP_PKT_ENC                             R_NO_CERTIFICATE_SPECIFIED
EVP_PKT_EXCH                            R_NO_CIPHER_LIST
EVP_PKT_EXP                             R_NO_CIPHER_MATCH
EVP_PKT_SIGN                            R_NO_PRIVATEKEY
EVP_PK_DH                               R_NO_PUBLICKEY
EVP_PK_DSA                              R_NULL_SSL_CTX
EVP_PK_EC                               R_PEER_DID_NOT_RETURN_A_CERTIFICATE
EVP_PK_RSA                              R_PEER_ERROR
FILETYPE_ASN1                           R_PEER_ERROR_CERTIFICATE
FILETYPE_PEM                            R_PEER_ERROR_NO_CIPHER
F_CLIENT_CERTIFICATE                    R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
F_CLIENT_HELLO                          R_PUBLIC_KEY_ENCRYPT_ERROR
F_CLIENT_MASTER_KEY                     R_PUBLIC_KEY_IS_NOT_RSA
F_D2I_SSL_SESSION                       R_READ_WRONG_PACKET_TYPE
F_GET_CLIENT_FINISHED                   R_SHORT_READ
F_GET_CLIENT_HELLO                      R_SSL_SESSION_ID_IS_DIFFERENT
F_GET_CLIENT_MASTER_KEY                 R_UNABLE_TO_EXTRACT_PUBLIC_KEY
F_GET_SERVER_FINISHED                   R_UNKNOWN_REMOTE_ERROR_TYPE
F_GET_SERVER_HELLO                      R_UNKNOWN_STATE
F_GET_SERVER_VERIFY                     R_X509_LIB
F_I2D_SSL_SESSION                       SENT_SHUTDOWN
F_READ_N                               SESSION_ASN1_VERSION
F_REQUEST_CERTIFICATE                   SESS_CACHE_BOTH
F_SERVER_HELLO                          SESS_CACHE_CLIENT
F_SSL_CERT_NEW                          SESS_CACHE_NO_AUTO_CLEAR
F_SSL_GET_NEW_SESSION                   SESS_CACHE_NO_INTERNAL
F_SSL_NEW                              SESS_CACHE_NO_INTERNAL_LOOKUP
F_SSL_READ                             SESS_CACHE_NO_INTERNAL_STORE
F_SSL_RSA_PRIVATE_DECRYPT              SESS_CACHE_OFF
F_SSL_RSA_PUBLIC_ENCRYPT               SESS_CACHE_SERVER
F_SSL_SESSION_NEW                      SESS_CACHE_UPDATE_TIME
F_SSL_SESSION_PRINT_FP                 SSL2_MT_CLIENT_CERTIFICATE
F_SSL_SET_FD                           SSL2_MT_CLIENT_FINISHED
F_SSL_SET_RFD                          SSL2_MT_CLIENT_HELLO
F_SSL_SET_WFD                          SSL2_MT_CLIENT_MASTER_KEY
F_SSL_USE_CERTIFICATE                  SSL2_MT_ERROR
F_SSL_USE_CERTIFICATE_ASN1             SSL2_MT_REQUEST_CERTIFICATE
F_SSL_USE_CERTIFICATE_FILE             SSL2_MT_SERVER_FINISHED
F_SSL_USE_PRIVATEKEY                   SSL2_MT_SERVER_HELLO
F_SSL_USE_PRIVATEKEY_ASN1              SSL2_MT_SERVER_VERIFY
F_SSL_USE_PRIVATEKEY_FILE              SSL2_VERSION
F_SSL_USE_RSAPRIVATEKEY                SSL3_MT_CCS
F_SSL_USE_RSAPRIVATEKEY_ASN1           SSL3_MT_CERTIFICATE
F_SSL_USE_RSAPRIVATEKEY_FILE           SSL3_MT_CERTIFICATE_REQUEST
F_WRITE_PENDING                        SSL3_MT_CERTIFICATE_STATUS

okay the F_ block ate, no notes. ๐Ÿ’€ And then R_PEER_DID_NOT_RETURN_A_CERTIFICATE and R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE are just full sentences wearing a constant costume โ€” the way those names go on and on is honestly so real of them. SENT_SHUTDOWN and RECEIVED_SHUTDOWN are sitting right there too, one for each direction, balanced, symmetrical, slay. โญ

And the last chunk of this batch:

GEN_DIRNAME                             SSL3_MT_CERTIFICATE_URL
GEN_DNS                                 SSL3_MT_CERTIFICATE_VERIFY
GEN_EDIPARTY                            SSL3_MT_CHANGE_CIPHER_SPEC
GEN_EMAIL                               SSL3_MT_CLIENT_HELLO
GEN_IPADD                               SSL3_MT_CLIENT_KEY_EXCHANGE
GEN_OTHERNAME                           SSL3_MT_ENCRYPTED_EXTENSIONS
GEN_RID                                 SSL3_MT_END_OF_EARLY_DATA
GEN_URI                                 SSL3_MT_FINISHED
GEN_X400                                SSL3_MT_HELLO_REQUEST
LIBRESSL_VERSION_NUMBER                 SSL3_MT_KEY_UPDATE
MBSTRING_ASC                            SSL3_MT_MESSAGE_HASH
MBSTRING_BMP                            SSL3_MT_NEWSESSION_TICKET
MBSTRING_FLAG                           SSL3_MT_NEXT_PROTO
MBSTRING_UNIV                           SSL3_MT_SERVER_DONE
MBSTRING_UTF8                           SSL3_MT_SERVER_HELLO
MIN_RSA_MODULUS_LENGTH_IN_BYTES         SSL3_MT_SERVER_KEY_EXCHANGE
MODE_ACCEPT_MOVING_WRITE_BUFFER         SSL3_MT_SUPPLEMENTAL_DATA
MODE_ASYNC                              SSL3_RT_ALERT
MODE_AUTO_RETRY                         SSL3_RT_APPLICATION_DATA
MODE_ENABLE_PARTIAL_WRITE               SSL3_RT_CHANGE_CIPHER_SPEC
MODE_NO_AUTO_CHAIN                      SSL3_RT_HANDSHAKE
MODE_RELEASE_BUFFERS                    SSL3_RT_HEADER
NID_OCSP_sign                           SSL3_RT_INNER_CONTENT_TYPE
NID_SMIMECapabilities                   SSL3_VERSION
NID_X500                                SSLEAY_BUILT_ON
NID_X509                                SSLEAY_CFLAGS
NID_ad_OCSP                             SSLEAY_DIR
NID_ad_ca_issuers                       SSLEAY_PLATFORM
NID_algorithm                           SSLEAY_VERSION
NID_authority_key_identifier            ST_ACCEPT
NID_basic_constraints                   ST_BEFORE
NID_bf_cbc                              ST_CONNECT
NID_bf_cfb64                            ST_INIT
NID_bf_ecb                              ST_OK
NID_bf_ofb64                            ST_READ_BODY
NID_cast5_cbc                           ST_READ_HEADER
NID_cast5_cfb64                         TLS1_1_VERSION
NID_cast5_ecb                           TLS1_2_VERSION
NID_cast5_ofb64                         TLS1_3_VERSION
NID_certBag                             TLS1_VERSION
NID_certificate_policies                TLSEXT_STATUSTYPE_ocsp
NID_client_auth                         TLSEXT_TYPE_application_layer_protocol_negotiation

look at TLSEXT_TYPE_application_layer_protocol_negotiation โ€” the longest constant in the room and it's not even lowercase, it's just running the whole width of the terminal like it pays rent here. ๐Ÿ‘‘ And NID_OCSP_sign and NID_SMIMECapabilities are back, still lowercase-ish, still doing their thing.

That's the batch, bestie โ€” don't try to memorise it, just know it's here and that the spelling is law. ๐ŸŒธ Next bit incoming. ๐Ÿฆ‹

okay bestie we are still deep in the big alphabetical constant soup and honestly? it's giving phone book but make it โœจcryptoโœจ. same deal as before โ€” these are constants that exist in Net::SSLeay, spelled exactly like this, and your job is just to recognize them when they show up. no cap, no notes, let's keep scrolling ๐Ÿซถ

  • NID_code_sign, NID_commonName, NID_countryName โ€” the classics, the cert-name girlies
  • NID_crlBag, NID_crl_distribution_points, NID_crl_number, NID_crl_reason, NID_delta_crl โ€” the whole CRL crew, all in one vibe
  • NID_des_cbc, NID_des_cfb64, NID_des_ecb, NID_des_ede, NID_des_ede3 โ€” DES family, vintage icon behavior
  • NID_des_ede3_cbc, NID_des_ede3_cfb64, NID_des_ede3_ofb64, NID_des_ede_cbc, NID_des_ede_cfb64, NID_des_ede_ofb64, NID_des_ofb64 โ€” every DES mode walked so you could run
  • NID_description, NID_desx_cbc, NID_dhKeyAgreement, NID_dnQualifier
  • NID_dsa, NID_dsaWithSHA, NID_dsaWithSHA1, NID_dsaWithSHA1_2, NID_dsa_2 โ€” the DSA quintet, we stan a complete set
  • NID_email_protect, NID_ext_key_usage, NID_ext_req
  • NID_friendlyName, NID_givenName, NID_hmacWithSHA1
  • NID_id_ad, NID_id_ce, NID_id_kp, NID_id_pbkdf2, NID_id_pe, NID_id_pkix, NID_id_qt_cps, NID_id_qt_unotice โ€” the lowercase id_ squad, iykyk
  • NID_idea_cbc, NID_idea_cfb64, NID_idea_ecb, NID_idea_ofb64
  • NID_info_access, NID_initials, NID_invalidity_date, NID_issuer_alt_name
  • NID_keyBag, NID_key_usage, NID_localKeyID, NID_localityName
  • NID_md2, NID_md2WithRSAEncryption, NID_md5, NID_md5WithRSA, NID_md5WithRSAEncryption, NID_md5_sha1, NID_mdc2, NID_mdc2WithRSA โ€” the hash girls, some of them VERY vintage, take it up with history not me ๐Ÿ’€
  • NID_ms_code_com, NID_ms_code_ind, NID_ms_ctl_sign, NID_ms_efs, NID_ms_ext_req, NID_ms_sgc โ€” the Microsoft corner ๐ŸชŸ
  • NID_name, NID_netscape, NID_netscape_base_url, NID_netscape_ca_policy_url, NID_netscape_ca_revocation_url, NID_netscape_cert_extension, NID_netscape_cert_sequence, NID_netscape_cert_type, NID_netscape_comment, NID_netscape_data_type, NID_netscape_renewal_url, NID_netscape_revocation_url, NID_netscape_ssl_server_name, NID_ns_sgc โ€” a full legacy era in fourteen constants, kind of iconic honestly
  • NID_organizationName, NID_organizationalUnitName
  • NID_pbeWithMD2AndDES_CBC, NID_pbeWithMD2AndRC2_CBC, NID_pbeWithMD5AndCast5_CBC, NID_pbeWithMD5AndDES_CBC, NID_pbeWithMD5AndRC2_CBC, NID_pbeWithSHA1AndDES_CBC, NID_pbeWithSHA1AndRC2_CBC
  • NID_pbe_WithSHA1And128BitRC2_CBC, NID_pbe_WithSHA1And128BitRC4, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_pbe_WithSHA1And40BitRC2_CBC, NID_pbe_WithSHA1And40BitRC4, NID_pbes2, NID_pbmac1 โ€” yes the underscores are different, yes you have to copy them exactly, i don't make the rules ๐Ÿ˜ญ
  • NID_pkcs, NID_pkcs3, NID_pkcs7, NID_pkcs7_data, NID_pkcs7_digest, NID_pkcs7_encrypted, NID_pkcs7_enveloped, NID_pkcs7_signed, NID_pkcs7_signedAndEnveloped
  • NID_pkcs8ShroudedKeyBag โ€” shrouded!! mysterious!! main character energy ๐Ÿ‘‘
  • NID_pkcs9, NID_pkcs9_challengePassword, NID_pkcs9_contentType, NID_pkcs9_countersignature, NID_pkcs9_emailAddress, NID_pkcs9_extCertAttributes, NID_pkcs9_messageDigest, NID_pkcs9_signingTime, NID_pkcs9_unstructuredAddress, NID_pkcs9_unstructuredName
  • NID_private_key_usage_period
  • NID_rc2_40_cbc, NID_rc2_64_cbc, NID_rc2_cbc, NID_rc2_cfb64, NID_rc2_ecb, NID_rc2_ofb64, NID_rc4, NID_rc4_40, NID_rc5_cbc, NID_rc5_cfb64, NID_rc5_ecb, NID_rc5_ofb64 โ€” RC everything, all the modes, slay
  • NID_ripemd160, NID_ripemd160WithRSA, NID_rle_compression, NID_rsa, NID_rsaEncryption, NID_rsadsi
  • NID_safeContentsBag, NID_sdsiCertificate, NID_secretBag, NID_serialNumber, NID_server_auth
  • NID_sha, NID_sha1, NID_sha1WithRSA, NID_sha1WithRSAEncryption, NID_sha224, NID_sha224WithRSAEncryption โ€” and that's where this column lands, right on the SHA girls ๐ŸŒธ

and over in the other lane, the TLS extension girlies are having their own little moment:

  • TLSEXT_TYPE_cert_type, TLSEXT_TYPE_certificate_authorities, TLSEXT_TYPE_client_authz, TLSEXT_TYPE_client_cert_type, TLSEXT_TYPE_client_certificate_url, TLSEXT_TYPE_compress_certificate, TLSEXT_TYPE_cookie, TLSEXT_TYPE_early_data โ€” cookie!! early data!! we love a shortcut bestie ๐Ÿ“
  • TLSEXT_TYPE_ec_point_formats, TLSEXT_TYPE_elliptic_curves, TLSEXT_TYPE_encrypt_then_mac, TLSEXT_TYPE_extended_master_secret
  • TLSEXT_TYPE_key_share, TLSEXT_TYPE_max_fragment_length
  • TLSEXT_TYPE_next_proto_neg, TLSEXT_TYPE_padding, TLSEXT_TYPE_post_handshake_auth, TLSEXT_TYPE_psk, TLSEXT_TYPE_psk_kex_modes
  • TLSEXT_TYPE_quic_transport_parameters, TLSEXT_TYPE_renegotiate
  • TLSEXT_TYPE_server_authz, TLSEXT_TYPE_server_cert_type, TLSEXT_TYPE_server_name, TLSEXT_TYPE_session_ticket
  • TLSEXT_TYPE_signature_algorithms, TLSEXT_TYPE_signature_algorithms_cert, TLSEXT_TYPE_signed_certificate_timestamp, TLSEXT_TYPE_srp, TLSEXT_TYPE_status_request, TLSEXT_TYPE_supported_groups, TLSEXT_TYPE_supported_versions
  • TLSEXT_TYPE_truncated_hmac, TLSEXT_TYPE_trusted_ca_keys, TLSEXT_TYPE_use_srtp, TLSEXT_TYPE_user_mapping

then the verify + OCSP status constants, small but mighty:

  • VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_NONE, VERIFY_PEER, VERIFY_POST_HANDSHAKE โ€” your peer-verification mood ring ๐Ÿ’…
  • V_OCSP_CERTSTATUS_GOOD, V_OCSP_CERTSTATUS_REVOKED, V_OCSP_CERTSTATUS_UNKNOWN โ€” good / revoked / unknown, the three OCSP feelings
  • WRITING โ€” literally just WRITING, one word, no prefix, standing there. periodt. โœจ

and now the X509_* family reunion, buckle up ๐ŸŽ€

  • X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, X509_CHECK_FLAG_NO_WILDCARDS, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS โ€” the hostname-checking flag set, very "rules are rules"
  • X509_CRL_VERSION_1, X509_CRL_VERSION_2
  • X509_FILETYPE_ASN1, X509_FILETYPE_DEFAULT, X509_FILETYPE_PEM, X509_LOOKUP
  • X509_PURPOSE_ANY, X509_PURPOSE_CRL_SIGN, X509_PURPOSE_NS_SSL_SERVER, X509_PURPOSE_OCSP_HELPER, X509_PURPOSE_SMIME_ENCRYPT, X509_PURPOSE_SMIME_SIGN, X509_PURPOSE_SSL_CLIENT, X509_PURPOSE_SSL_SERVER, X509_PURPOSE_TIMESTAMP_SIGN
  • X509_REQ_VERSION_1, X509_REQ_VERSION_2, X509_REQ_VERSION_3
  • X509_TRUST_COMPAT, X509_TRUST_DEFAULT, X509_TRUST_EMAIL, X509_TRUST_OBJECT_SIGN, X509_TRUST_OCSP_REQUEST, X509_TRUST_OCSP_SIGN, X509_TRUST_SSL_CLIENT, X509_TRUST_SSL_SERVER, X509_TRUST_TSA
  • X509_VERSION_1, X509_VERSION_2, X509_VERSION_3 โ€” one, two, three, that's the whole trilogy bestie

and finally the big one: the X509_V_ERR_* wall of feelings. every single one is a different way a certificate can disappoint you ๐Ÿ’€

  • X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH, X509_V_ERR_AKID_SKID_MISMATCH, X509_V_ERR_APPLICATION_VERIFICATION, X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL, X509_V_ERR_CA_BCONS_NOT_CRITICAL, X509_V_ERR_CA_CERT_MISSING_KEY_USAGE, X509_V_ERR_CA_KEY_TOO_SMALL, X509_V_ERR_CA_MD_TOO_WEAK
  • X509_V_ERR_CERT_CHAIN_TOO_LONG, X509_V_ERR_CERT_HAS_EXPIRED, X509_V_ERR_CERT_NOT_YET_VALID, X509_V_ERR_CERT_REJECTED, X509_V_ERR_CERT_REVOKED, X509_V_ERR_CERT_SIGNATURE_FAILURE, X509_V_ERR_CERT_UNTRUSTED โ€” expired and not-yet-valid are the two genders of "girl, timing" ๐Ÿ˜ญ
  • X509_V_ERR_CRL_HAS_EXPIRED, X509_V_ERR_CRL_NOT_YET_VALID, X509_V_ERR_CRL_PATH_VALIDATION_ERROR, X509_V_ERR_CRL_SIGNATURE_FAILURE
  • X509_V_ERR_DANE_NO_MATCH, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, X509_V_ERR_DIFFERENT_CRL_SCOPE
  • X509_V_ERR_EC_KEY_EXPLICIT_PARAMS, X509_V_ERR_EE_KEY_TOO_SMALL, X509_V_ERR_EMAIL_MISMATCH, X509_V_ERR_EMPTY_SUBJECT_ALT_NAME, X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL
  • X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD, X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
  • X509_V_ERR_EXCLUDED_VIOLATION, X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3
  • X509_V_ERR_HOSTNAME_MISMATCH, X509_V_ERR_INVALID_CA, X509_V_ERR_INVALID_CALL, X509_V_ERR_INVALID_EXTENSION, X509_V_ERR_INVALID_NON_CA, X509_V_ERR_INVALID_POLICY_EXTENSION, X509_V_ERR_INVALID_PURPOSE, X509_V_ERR_IP_ADDRESS_MISMATCH, X509_V_ERR_ISSUER_NAME_EMPTY
  • X509_V_ERR_KEYUSAGE_NO_CERTSIGN, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN, X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA
  • X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER, X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER
  • X509_V_ERR_NO_EXPLICIT_POLICY, X509_V_ERR_NO_ISSUER_PUBLIC_KEY, X509_V_ERR_NO_VALID_SCTS
  • X509_V_ERR_OCSP_CERT_UNKNOWN, X509_V_ERR_OCSP_VERIFY_FAILED, X509_V_ERR_OCSP_VERIFY_NEEDED, X509_V_ERR_OUT_OF_MEM โ€” out of memory has no business being on a cert-verification list but ok go off ๐Ÿ”ฅ
  • X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA, X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN, X509_V_ERR_PATH_LENGTH_EXCEEDED, X509_V_ERR_PATH_LOOP, X509_V_ERR_PERMITTED_VIOLATION
  • X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED, X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED, X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION
  • X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY, X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH, X509_V_ERR_STORE_LOOKUP, X509_V_ERR_SUBJECT_ISSUER_MISMATCH, X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL โ€” and that's the last one in this column, we made it bestie ๐Ÿ

okay that was a lot of names, but you survived, and ngl that's the whole energy of these lists: they're literally just exported constants, and now you know exactly what they're called. keep reading, there's more ๐Ÿ’–

  • NID_sha256, NID_sha256WithRSAEncryption
  • NID_sha384, NID_sha384WithRSAEncryption
  • NID_sha3_224, NID_sha3_256, NID_sha3_384, NID_sha3_512 โ€” the whole SHA-3 glow-up era, we love to see it โœจ
  • NID_sha512, NID_sha512WithRSAEncryption
  • NID_sha512_224, NID_sha512_224WithRSAEncryption
  • NID_sha512_256, NID_sha512_256WithRSAEncryption
  • NID_shaWithRSAEncryption โ€” yes bestie, that SHA. the ancestor. respect the elders ๐Ÿ™
  • NID_shake128, NID_shake256
  • NID_stateOrProvinceName, NID_subject_alt_name, NID_subject_key_identifier, NID_surname, NID_title โ€” all the X.509 name-field besties
  • NID_sxnet
  • NID_time_stamp
  • NID_undef โ€” the "no thoughts, head empty" NID ๐Ÿ’€
  • NID_uniqueIdentifier
  • NID_x509Certificate, NID_x509Crl
  • NID_zlib_compression
  • NOTHING โ€” literally the name of the constant. iconic. no notes ๐Ÿ‘‘

Now the OCSP response statuses, aka "how did the revocation check go" energy:

  • OCSP_RESPONSE_STATUS_INTERNALERROR
  • OCSP_RESPONSE_STATUS_MALFORMEDREQUEST
  • OCSP_RESPONSE_STATUS_SIGREQUIRED
  • OCSP_RESPONSE_STATUS_SUCCESSFUL โ€” the only one that's a slay ๐Ÿ’…
  • OCSP_RESPONSE_STATUS_TRYLATER
  • OCSP_RESPONSE_STATUS_UNAUTHORIZED

And the OPENSSL_* build/info/init constants, which are lowkey a whole personality:

  • OPENSSL_BUILT_ON, OPENSSL_CFLAGS, OPENSSL_CPU_INFO
  • OPENSSL_DIR, OPENSSL_ENGINES_DIR, OPENSSL_FULL_VERSION_STRING
  • OPENSSL_INFO_CONFIG_DIR, OPENSSL_INFO_CPU_SETTINGS, OPENSSL_INFO_DIR_FILENAME_SEPARATOR, OPENSSL_INFO_DSO_EXTENSION, OPENSSL_INFO_ENGINES_DIR, OPENSSL_INFO_LIST_SEPARATOR, OPENSSL_INFO_MODULES_DIR, OPENSSL_INFO_SEED_SOURCE
  • OPENSSL_INIT_ADD_ALL_CIPHERS, OPENSSL_INIT_ADD_ALL_DIGESTS
  • OPENSSL_INIT_ASYNC, OPENSSL_INIT_ATFORK
  • OPENSSL_INIT_ENGINE_AFALG, OPENSSL_INIT_ENGINE_CAPI, OPENSSL_INIT_ENGINE_CRYPTODEV, OPENSSL_INIT_ENGINE_DYNAMIC, OPENSSL_INIT_ENGINE_OPENSSL, OPENSSL_INIT_ENGINE_PADLOCK, OPENSSL_INIT_ENGINE_RDRAND
  • OPENSSL_INIT_LOAD_CONFIG, OPENSSL_INIT_LOAD_CRYPTO_STRINGS, OPENSSL_INIT_LOAD_SSL_STRINGS
  • OPENSSL_INIT_NO_ADD_ALL_CIPHERS, OPENSSL_INIT_NO_ADD_ALL_DIGESTS, OPENSSL_INIT_NO_ATEXIT, OPENSSL_INIT_NO_LOAD_CONFIG

Next up, the X509_V_* constants โ€” these are the verification tea โ˜• every error code is a different flavor of "something's wrong with this cert chain":

  • X509_V_ERR_SUBJECT_NAME_EMPTY
  • X509_V_ERR_SUBTREE_MINMAX
  • X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256
  • X509_V_ERR_SUITE_B_INVALID_ALGORITHM
  • X509_V_ERR_SUITE_B_INVALID_CURVE
  • X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
  • X509_V_ERR_SUITE_B_INVALID_VERSION
  • X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED
  • X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
  • X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
  • X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
  • X509_V_ERR_UNABLE_TO_GET_CRL
  • X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
  • X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
  • X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
  • X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
  • X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION
  • X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION
  • X509_V_ERR_UNNESTED_RESOURCE
  • X509_V_ERR_UNSPECIFIED
  • X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX
  • X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE
  • X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE
  • X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
  • X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM

And the flags you can flip to change how that check behaves:

  • X509_V_FLAG_ALLOW_PROXY_CERTS
  • X509_V_FLAG_CB_ISSUER_CHECK
  • X509_V_FLAG_CHECK_SS_SIGNATURE
  • X509_V_FLAG_CRL_CHECK, X509_V_FLAG_CRL_CHECK_ALL
  • X509_V_FLAG_EXPLICIT_POLICY
  • X509_V_FLAG_EXTENDED_CRL_SUPPORT
  • X509_V_FLAG_IGNORE_CRITICAL
  • X509_V_FLAG_INHIBIT_ANY, X509_V_FLAG_INHIBIT_MAP
  • X509_V_FLAG_LEGACY_VERIFY
  • X509_V_FLAG_NOTIFY_POLICY
  • X509_V_FLAG_NO_ALT_CHAINS
  • X509_V_FLAG_NO_CHECK_TIME
  • X509_V_FLAG_PARTIAL_CHAIN
  • X509_V_FLAG_POLICY_CHECK, X509_V_FLAG_POLICY_MASK
  • X509_V_FLAG_SUITEB_128_LOS, X509_V_FLAG_SUITEB_128_LOS_ONLY, X509_V_FLAG_SUITEB_192_LOS
  • X509_V_FLAG_TRUSTED_FIRST
  • X509_V_FLAG_USE_CHECK_TIME, X509_V_FLAG_USE_DELTAS
  • X509_V_FLAG_X509_STRICT
  • X509_V_OK โ€” the happy ending we're all manifesting ๐Ÿซถ

Finally the XN_FLAG_* set, which is all about how a name gets formatted when it's printed out:

  • XN_FLAG_COMPAT
  • XN_FLAG_DN_REV
  • XN_FLAG_DUMP_UNKNOWN_FIELDS
  • XN_FLAG_FN_ALIGN, XN_FLAG_FN_LN, XN_FLAG_FN_MASK, XN_FLAG_FN_NONE, XN_FLAG_FN_OID, XN_FLAG_FN_SN โ€” pick your fave way to label a field, no wrong answers (well, one of them is NONE, soโ€ฆ choices ๐Ÿ’€)
  • XN_FLAG_MULTILINE, XN_FLAG_ONELINE
  • XN_FLAG_RFC2253
  • XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK, XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_SPLUS_SPC โ€” separator drama, but make it punctuation
  • XN_FLAG_SPC_EQ

๐Ÿ’€ INTERNAL ONLY functions (do not use these) ๐Ÿ’€

Okay bestie, listen to me very carefully, this is the part where I grab your shoulders ๐Ÿซถ

The following functions are not intended for use from outside of Net::SSLeay module. They might be removed, renamed or changed without prior notice in future version.

So likeโ€ฆ they could ghost you at any release and not even leave a text. ๐Ÿ˜ญ

Simply DO NOT USE THEM!

  • hello
  • blength
  • constant

That's the whole list. Three little functions that are absolutely none of your business. I said what I said, periodt. ๐Ÿ‘‘

โœจ EXAMPLES โœจ

okay so the ultimate glow-up reference is literally the implementation of sslcat() sitting right there in the "SSLeay.pm" file โ€” go look at it, it's giving main character energy ๐Ÿ’…

What follows is a simple SSLeay client (with too little error checking :-(

#!/usr/bin/perl
use Socket;
use Net::SSLeay qw(die_now die_if_ssl_error) ;
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

($dest_serv, $port, $msg) = @ARGV;      # Read command line
$port = getservbyname ($port, 'tcp') unless $port =~ /^\d+$/;
$dest_ip = gethostbyname ($dest_serv);
$dest_serv_params  = sockaddr_in($port, $dest_ip);

socket  (S, &AF_INET, &SOCK_STREAM, 0)  or die "socket: $!";
connect (S, $dest_serv_params)          or die "connect: $!";
select  (S); $| = 1; select (STDOUT);   # Eliminate STDIO buffering

# The network connection is now open, lets fire up SSL

$ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!");
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL)
     or die_if_ssl_error("ssl ctx set options");
$ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!");
Net::SSLeay::set_fd($ssl, fileno(S));   # Must use fileno
$res = Net::SSLeay::connect($ssl) and die_if_ssl_error("ssl connect");
print "Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n";

# Exchange data

$res = Net::SSLeay::write($ssl, $msg);  # Perl knows how long $msg is
die_if_ssl_error("ssl write");
CORE::shutdown S, 1;  # Half close --> No more output, sends EOF to server
$got = Net::SSLeay::read($ssl);         # Perl returns undef on failure
die_if_ssl_error("ssl read");
print $got;

Net::SSLeay::free ($ssl);               # Tear down connection
Net::SSLeay::CTX_free ($ctx);
close S;

And here's a simple SSLeay echo server (non forking) ๐Ÿฆ‹

#!/usr/bin/perl -w
use Socket;
use Net::SSLeay qw(die_now die_if_ssl_error);
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

$our_ip = "\0\0\0\0"; # Bind to all interfaces
$port = 1235;
$sockaddr_template = 'S n a4 x8';
$our_serv_params = pack ($sockaddr_template, &AF_INET, $port, $our_ip);

socket (S, &AF_INET, &SOCK_STREAM, 0)  or die "socket: $!";
bind (S, $our_serv_params)             or die "bind:   $!";
listen (S, 5)                          or die "listen: $!";
$ctx = Net::SSLeay::CTX_new ()         or die_now("CTX_new ($ctx): $!");
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL)
     or die_if_ssl_error("ssl ctx set options");

# Following will ask password unless private key is not encrypted
Net::SSLeay::CTX_use_RSAPrivateKey_file ($ctx, 'plain-rsa.pem',
                                         &Net::SSLeay::FILETYPE_PEM);
die_if_ssl_error("private key");
Net::SSLeay::CTX_use_certificate_file ($ctx, 'plain-cert.pem',
                                        &Net::SSLeay::FILETYPE_PEM);
die_if_ssl_error("certificate");

while (1) {
    print "Accepting connections...\n";
    ($addr = accept (NS, S))           or die "accept: $!";
    select (NS); $| = 1; select (STDOUT);  # Piping hot!

    ($af,$client_port,$client_ip) = unpack($sockaddr_template,$addr);
    @inetaddr = unpack('C4',$client_ip);
    print "$af connection from " .
    join ('.', @inetaddr) . ":$client_port\n";

    # We now have a network connection, lets fire up SSLeay...

    $ssl = Net::SSLeay::new($ctx)      or die_now("SSL_new ($ssl): $!");
    Net::SSLeay::set_fd($ssl, fileno(NS));

    $err = Net::SSLeay::accept($ssl) and die_if_ssl_error('ssl accept');
    print "Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n";

    # Connected. Exchange some data.

    $got = Net::SSLeay::read($ssl);     # Returns undef on fail
    die_if_ssl_error("ssl read");
    print "Got `$got' (" . length ($got) . " chars)\n";

    Net::SSLeay::write ($ssl, uc ($got)) or die "write: $!";
    die_if_ssl_error("ssl write");

    Net::SSLeay::free ($ssl);           # Tear down connection
    close NS;
}

Yet another echo server, bestie ๐ŸŒธ This one runs straight from "/etc/inetd.conf" so it skips all the socket code overhead. Only caveat is opening an rsa key file โ€” it had better be without any encryption or else it will not know where to ask for the password. Note how "STDIN" and "STDOUT" are wired to SSL ๐Ÿ‘‘

#!/usr/bin/perl
# /etc/inetd.conf
#    ssltst stream tcp nowait root /path/to/server.pl server.pl
# /etc/services
#    ssltst        1234/tcp

use Net::SSLeay qw(die_now die_if_ssl_error);
Net::SSLeay::load_error_strings();
Net::SSLeay::SSLeay_add_ssl_algorithms();
Net::SSLeay::randomize();

chdir '/key/dir' or die "chdir: $!";
$| = 1;  # Piping hot!
open LOG, ">>/dev/console" or die "Can't open log file $!";
select LOG; print "server.pl started\n";

$ctx = Net::SSLeay::CTX_new()     or die_now "CTX_new ($ctx) ($!)";
$ssl = Net::SSLeay::new($ctx)     or die_now "new ($ssl) ($!)";
Net::SSLeay::set_options($ssl, &Net::SSLeay::OP_ALL)
    and die_if_ssl_error("ssl set options");

# We get already open network connection from inetd, now we just
# need to attach SSLeay to STDIN and STDOUT
Net::SSLeay::set_rfd($ssl, fileno(STDIN));
Net::SSLeay::set_wfd($ssl, fileno(STDOUT));

Net::SSLeay::use_RSAPrivateKey_file ($ssl, 'plain-rsa.pem',
                                     Net::SSLeay::FILETYPE_PEM);
die_if_ssl_error("private key");
Net::SSLeay::use_certificate_file ($ssl, 'plain-cert.pem',
                                   Net::SSLeay::FILETYPE_PEM);
die_if_ssl_error("certificate");

Net::SSLeay::accept($ssl) and die_if_ssl_err("ssl accept: $!");
print "Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n";

$got = Net::SSLeay::read($ssl);
die_if_ssl_error("ssl read");
print "Got `$got' (" . length ($got) . " chars)\n";

Net::SSLeay::write ($ssl, uc($got)) or die "write: $!";
die_if_ssl_error("ssl write");

Net::SSLeay::free ($ssl);         # Tear down the connection
Net::SSLeay::CTX_free ($ctx);
close LOG;

There are also a number of example/test programs chillin' in the examples directory ๐ŸŽ€

sslecho.pl   -  A simple server, not unlike the one above
minicli.pl   -  Implements a client using low level SSLeay routines
sslcat.pl    -  Demonstrates using high level sslcat utility function
get_page.pl  -  Is a utility for getting html pages from secure servers
callback.pl  -  Demonstrates certificate verification and callback usage
stdio_bulk.pl       - Does SSL over Unix pipes
ssl-inetd-serv.pl   - SSL server that can be invoked from inetd.conf
httpd-proxy-snif.pl - Utility that allows you to see how a browser
                      sends https request to given server and what reply
                      it gets back (very educative :-)
makecert.pl  -  Creates a self signed cert (does not use this module)

๐ŸŒˆ INSTALLATION ๐ŸŒˆ

Check out README and README.* in the distribution directory for installation guidance across a whole variety of platforms ๐Ÿ’–


๐Ÿ’€ LIMITATIONS ๐Ÿ’€

okay listen, this part actually matters so pay attention bestie ๐Ÿ™ˆ

Net::SSLeay::read() uses an internal buffer of 32KB, thus no single read will return more. In practice one read returns much less, usually as much as fits in one network packet. To work around this, you should use a loop like this:

$reply = '';
while ($got = Net::SSLeay::read($ssl)) {
    last if print_errs('SSL_read');
    $reply .= $got;
}

Although there is no built-in limit in Net::SSLeay::write(), the network packet size limitation applies here as well, thus use:

$written = 0;

while ($written < length($message)) {
    $written += Net::SSLeay::write($ssl, substr($message, $written));
    last if print_errs('SSL_write');
}

Or alternatively you can just use the following convenience functions, which are lowkey iconic for saving you from writing all that yourself โœจ

Net::SSLeay::ssl_write_all($ssl, $message) or die "ssl write failure";
$got = Net::SSLeay::ssl_read_all($ssl) or die "ssl read failure";

๐Ÿ’€ KNOWN BUGS AND CAVEATS ๐Ÿ’€

okay so LibreSSL versions in the 3.1 - 3.3 series have a whole TLS 1.3 situation going on: their TLS 1.3 implementation is not fully compatible with the libssl API, but it still gets advertised during protocol auto-negotiation. So if you hit problems or unexpected behaviour with SSL or SSL_CTX objects whose protocol version was automatically negotiated, and libssl is provided by any of these LibreSSL versions, it could be because the peers negotiated to use TLS 1.3. The move is to try setting the maximum protocol version to TLS 1.2 โ€” via Net::SSLeay::set_max_proto_version() or Net::SSLeay::CTX_set_max_proto_version() โ€” before establishing the connection. The first stable LibreSSL version with a fully libssl-compatible TLS 1.3 implementation is 3.4.1.

ngl, there's also an OpenSSL bug, CVE-2015-0290 "OpenSSL Multiblock Corrupted Pointer Issue", that can cause POST requests of over 90kB to fail or crash. It's reported to be fixed in OpenSSL 1.0.2a.

The Autoloader emits a warning that looks like this:

Argument "xxx" isn't numeric in entersub at blib/lib/Net/SSLeay.pm'

...if die_if_ssl_error is made autoloadable. If you figure out why, drop me a line. ๐Ÿซถ

A callback set using SSL_set_verify() does not appear to work. This may well be an openssl problem (e.g. see ssl/ssl_lib.c line 1029). Try using SSL_CTX_set_verify() instead, and do not be surprised if even this stops working in future versions. Callback and certificate verification stuff is generally too little tested. ๐Ÿงช

Random numbers are not initialized randomly enough, especially if you do not have /dev/random and/or /dev/urandom (such as in Solaris platforms โ€” but it's been suggested that the cryptorand daemon from the SUNski package solves this). In this case you should investigate third party software that can emulate these devices, e.g. by way of a named pipe to some program. ๐ŸŽฒ

Another gotcha with random number initialization is randomness depletion. This phenomenon, which has been extensively discussed in OpenSSL, Apache-SSL, and Apache-mod_ssl forums, can cause your script to block if you use /dev/random or to operate insecurely if you use /dev/urandom. What happens is that when too much randomness is drawn from the operating system's randomness pool, then randomness can temporarily be unavailable. /dev/random solves this problem by waiting until enough randomness can be gathered โ€” and this can take a long time since blocking reduces activity in the machine and less activity provides less random events: a vicious circle. /dev/urandom solves this dilemma more pragmatically by simply returning predictable "random" numbers. Some /dev/urandom emulation software however actually seems to implement /dev/random semantics. Caveat emptor. ๐Ÿ˜ญ

I've been pointed to two such daemons by Mik Firestone <mik@@speed.stdio._com> who has used them on Solaris 8:

  1. Entropy Gathering Daemon (EGD) at <https://egd.sourceforge.net/>
  2. Pseudo-random number generating daemon (PRNGD) at <https://prngd.sourceforge.net/>

If you are using the low level API functions to communicate with other SSL implementations, you would do well to call:

Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL)
    or die_if_ssl_error("ssl ctx set options");

...to cope with some well know bugs in some other SSL implementations. The high level API functions always set all known compatibility options. ๐Ÿ‘‘

Sometimes sslcat() (and the high level HTTPS functions that build on it) is too fast in signaling the EOF to legacy HTTPS servers. This causes the server to return an empty page. To work around this problem you can set the global variable:

$Net::SSLeay::slowly = 1;   # Add sleep so broken servers can keep up

HTTP/1.1 is not supported. Specifically this module does not know to issue or serve multiple http requests per connection. This is a serious shortcoming, but using the SSL session cache on your server helps to alleviate the CPU load somewhat.

As of version 1.09 many newer OpenSSL auxiliary functions were added (from REM_AUTOMATICALLY_GENERATED_1_09 onwards in SSLeay.xs). Unfortunately I have not had any opportunity to test these. Some of them are trivial enough that I believe they "just work", but others have rather complex interfaces with function pointers and all. In these cases you should proceed wit great caution. โš ๏ธ

This module defaults to using OpenSSL automatic protocol negotiation code for automatically detecting the version of the SSL/TLS protocol that the other end talks. With most web servers this works just fine, but once in a while I get complaints from people that the module does not work with some web servers. Usually this can be solved by explicitly setting the protocol version, e.g.:

$Net::SSLeay::ssl_version = 2;  # Insist on SSLv2
$Net::SSLeay::ssl_version = 3;  # Insist on SSLv3
$Net::SSLeay::ssl_version = 10; # Insist on TLSv1
$Net::SSLeay::ssl_version = 11; # Insist on TLSv1.1
$Net::SSLeay::ssl_version = 12; # Insist on TLSv1.2
$Net::SSLeay::ssl_version = 13; # Insist on TLSv1.3

Although the autonegotiation is nice to have, the SSL standards do not formally specify any such mechanism. Most of the world has accepted the SSLeay/OpenSSL way of doing it as the de facto standard. But for the few that think differently, you have to explicitly speak the correct version. This is not really a bug, but rather a deficiency in the standards. If a site refuses to respond or sends back some nonsensical error codes (at the SSL handshake level), try this option before mailing me. ๐Ÿ“จ

On some systems, OpenSSL may be compiled without support for SSLv2. If this is the case, Net::SSLeay will warn if ssl_version has been set to 2.

The high level API returns the certificate of the peer, thus allowing one to check what certificate was supplied. However, you will only be able to check the certificate after the fact, i.e. you already sent your form data by the time you find out that you did not trust them, oops. ๐Ÿ™ˆ

So, while being able to know the certificate after the fact is surely useful, the security minded would still choose to do the connection and certificate verification first and only then exchange data with the site. Currently none of the high level API functions do this, thus you would have to program it using the low level API. A good place to start is to see how the Net::SSLeay::http_cat() function is implemented.

The high level API functions use a global file handle SSLCAT_S internally. This really should not be a problem because there is no way to interleave the high level API functions, unless you use threads (but threads are not very well supported in perl anyway). However, you may run into problems if you call undocumented internal functions in an interleaved fashion. The best solution is to require Net::SSLeay in one thread after all the threads have been created. ๐Ÿงต


๐Ÿฉบ DIAGNOSTICS ๐Ÿฉบ

  • Random number generator not seeded!!! โ€” (W) This warning indicates that randomize() was not able to read /dev/random or /dev/urandom, possibly because your system does not have them or they are differently named. You can still use SSL, but the encryption will not be as strong. ๐Ÿ’”
  • open_tcp_connection: destination host not found:`server' (port 123) ($!) โ€” Name lookup for host named server failed.
  • open_tcp_connection: failed `server', 123 ($!) โ€” The name was resolved, but establishing the TCP connection failed.
  • msg 123: 1 - error:140770F8:SSL routines:SSL23_GET_SERVER_HELLO:unknown proto โ€” SSLeay error string. The first number (123) is the PID, the second number (1) indicates the position of the error message in SSLeay error stack. You often see a pile of these messages as errors cascade. ๐Ÿ“š
  • msg 123: 1 - error:02001002::lib(2) :func(1) :reason(2) โ€” The same as above, but you didn't call load_error_strings() so SSLeay couldn't verbosely explain the error. You can still find out what it means with this command:
/usr/local/ssl/bin/ssleay errstr 02001002
  • Password is being asked for private key โ€” This is normal behaviour if your private key is encrypted. Either you have to supply the password or you have to use an unencrypted private key. Scan OpenSSL.org for the FAQ that explains how to do this (or just study examples/makecert.pl which is used during make test to do just that). ๐Ÿ”

๐Ÿ›ก๏ธ SECURITY ๐Ÿ›ก๏ธ

You can mitigate some of the security vulnerabilities that might be present in your SSL/TLS application:

๐Ÿ BEAST Attack ๐Ÿ

The BEAST attack relies on a weakness in the way CBC mode is used in SSL/TLS. In OpenSSL versions 0.9.6d and later, the protocol-level mitigation is enabled by default, thus making it not vulnerable to the BEAST attack. ๐Ÿโœจ

Solutions:

  • Compile with OpenSSL versions 0.9.6d or later, which enables SSL_OP_ALL by default
  • Ensure SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is not enabled (its not enabled by default)
  • Don't support SSLv2, SSLv3
  • Actively control the ciphers your server supports with set_cipher_list:
Net::SSLeay::set_cipher_list($ssl, 'RC4-SHA:HIGH:!ADH');

๐Ÿ” Session Resumption ๐Ÿ”

The SSL Labs vulnerability test on your SSL server might report in red:

Session resumption      No (IDs assigned but not accepted)

This report is not really bug or a vulnerability, since the server will not accept session resumption requests. However, you can prevent this noise in the report by disabling the session cache altogether:

Net::SSLeay::CTX_set_session_cache_mode($ssl_ctx, Net::SSLeay::SESS_CACHE_OFF());
# Use 0 if you don't have SESS_CACHE_OFF constant.

๐Ÿ›ก๏ธ Secure Renegotiation and DoS Attack ๐Ÿ›ก๏ธ

This is not a "security flaw," it is more of a DoS vulnerability.

Solutions:

  • Do not support SSLv2
  • Do not set the SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION option
  • Compile with OpenSSL 0.9.8m or later

๐Ÿ› BUGS ๐Ÿ›

If you encounter a problem with this module that you believe is a bug, please create a new issue <https://github.com/radiator-software/p5-net-ssleay/issues/new> in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information:

  • the code you are trying to run;
  • your operating system name and version;
  • the output of perl -V;
  • the version of OpenSSL or LibreSSL you are using. ๐Ÿ’–

๐Ÿ‘‘ AUTHOR

Okay so the origin story: this whole thing was originally written by Sampo Kellomรคki. Iconic behavior, honestly.

Then the maintainer baton got passed around like the group chat aux cord:

  • Maintained by Florian Ragwitz between November 2005 and January 2010.
  • Maintained by Mike McCauley between November 2005 and June 2018.
  • Maintained by Tuure Vartiainen between June 2018 and July 2018.
  • Maintained by Chris Novakovic and Heikki Vatiainen since June 2018.

No cap, thatโ€™s a whole relay team and they kept it alive. ๐Ÿซถ


The legal receipts, exactly as they are, bestie:

Copyright (c) 1996-2003 Sampo Kellomรคki <sampo@iki.fi>

Copyright (c) 2005-2010 Florian Ragwitz <rafl@debian.org>

Copyright (c) 2005-2018 Mike McCauley <mikem@airspayce.com>

Copyright (c) 2018 Tuure Vartiainen <vartiait@radiatorsoftware.com>

Copyright (c) 2018- Chris Novakovic <chris@chrisn.me.uk>

Copyright (c) 2018- Heikki Vatiainen <hvn@radiatorsoftware.com>

All rights reserved.

Like, all of it. Every line. Keep it cute, keep it accurate. ๐Ÿ’…


๐Ÿ“œ LICENSE

This module is released under the terms of the Artistic License 2.0. For the full details, go look at the LICENSE file that ships with Net-SSLeayโ€™s source code. Thatโ€™s the one, bestie โ€” not a vibe-based guess, the actual file. โœจ


๐Ÿ‘€ SEE ALSO

The little โ€œgo touch grass and read these tooโ€ section:


And thatโ€™s the whole page, bestie. This little artifact is from perl v5.42.0, dated 2025-04-09, and itโ€™s the Net::SSLeay(3) manual page. Slay, read responsibly, and hydrate. ๐Ÿ’–โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from