Net-SSLeay-1.92/0000755000175000001440000000000014167654753012055 5ustar csnusersNet-SSLeay-1.92/lib/0000755000175000001440000000000014167654753012623 5ustar csnusersNet-SSLeay-1.92/lib/Net/0000755000175000001440000000000014167654753013351 5ustar csnusersNet-SSLeay-1.92/lib/Net/SSLeay/0000755000175000001440000000000014167654753014511 5ustar csnusersNet-SSLeay-1.92/lib/Net/SSLeay/Handle.pm0000644000175000001440000002451714167654427016251 0ustar csnuserspackage Net::SSLeay::Handle; use 5.8.1; use strict; use Socket; use Net::SSLeay; require Exporter; =encoding utf-8 =head1 NAME Net::SSLeay::Handle - Perl module that lets SSL (HTTPS) sockets be handled as standard file handles. =head1 SYNOPSIS use Net::SSLeay::Handle qw/shutdown/; my ($host, $port) = ("localhost", 443); tie(*SSL, "Net::SSLeay::Handle", $host, $port); print SSL "GET / HTTP/1.0\r\n"; shutdown(\*SSL, 1); print while (); close SSL; =head1 DESCRIPTION Net::SSLeay::Handle allows you to request and receive HTTPS web pages using "old-fashion" file handles as in: print SSL "GET / HTTP/1.0\r\n"; and print while (); If you export the shutdown routine, then the only extra code that you need to add to your program is the tie function as in: my $socket; if ($scheme eq "https") { tie(*S2, "Net::SSLeay::Handle", $host, $port); $socket = \*S2; else { $socket = Net::SSLeay::Handle->make_socket($host, $port); } print $socket $request_headers; ... =cut use vars qw(@ISA @EXPORT_OK $VERSION); @ISA = qw(Exporter); @EXPORT_OK = qw(shutdown); $VERSION = '1.92'; my $Initialized; #-- only _initialize() once my $Debug = 0; #-- pretty hokey #== Tie Handle Methods ======================================================== # # see perldoc perltie for details. # #============================================================================== sub TIEHANDLE { my ($class, $socket, $port) = @_; $Debug > 10 and print "TIEHANDLE(@{[join ', ', @_]})\n"; ref $socket eq "GLOB" or $socket = $class->make_socket($socket, $port); $class->_initialize(); my $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); my $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); my $fileno = fileno($socket); Net::SSLeay::set_fd($ssl, $fileno); # Must use fileno my $resp = Net::SSLeay::connect($ssl); $Debug and print "Cipher '" . Net::SSLeay::get_cipher($ssl) . "'\n"; my $self = bless { ssl => $ssl, ctx => $ctx, socket => $socket, fileno => $fileno, }, $class; return $self; } sub PRINT { my $self = shift; my $ssl = _get_ssl($self); my $resp = 0; for my $msg (@_) { defined $msg or last; $resp = Net::SSLeay::write($ssl, $msg) or last; } return $resp; } sub READLINE { my $self = shift; my $ssl = _get_ssl($self); if (wantarray) { my @lines; while (my $line = Net::SSLeay::ssl_read_until($ssl)) { push @lines, $line; } return @lines; } else { my $line = Net::SSLeay::ssl_read_until($ssl); return $line ? $line : undef; } } sub READ { my ($self, $buf, $len, $offset) = \ (@_); my $ssl = _get_ssl($$self); defined($$offset) or return length($$buf = Net::SSLeay::ssl_read_all($ssl, $$len)); defined(my $read = Net::SSLeay::ssl_read_all($ssl, $$len)) or return undef; my $buf_len = length($$buf); $$offset > $buf_len and $$buf .= chr(0) x ($$offset - $buf_len); substr($$buf, $$offset) = $read; return length($read); } sub WRITE { my $self = shift; my ($buf, $len, $offset) = @_; $offset = 0 unless defined $offset; # Return number of characters written. my $ssl = $self->_get_ssl(); return $len if Net::SSLeay::write($ssl, substr($buf, $offset, $len)); return undef; } sub CLOSE { my $self = shift; my $fileno = $self->{fileno}; $Debug > 10 and print "close($fileno)\n"; Net::SSLeay::free ($self->{ssl}); Net::SSLeay::CTX_free ($self->{ctx}); close $self->{socket}; } sub FILENO { $_[0]->{fileno} } =head1 FUNCTIONS =over =item shutdown shutdown(\*SOCKET, $mode) Calls to the main shutdown() don't work with tied sockets created with this module. This shutdown should be able to distinquish between tied and untied sockets and do the right thing. =cut sub shutdown { my ($obj, @params) = @_; my $socket = UNIVERSAL::isa($obj, 'Net::SSLeay::Handle') ? $obj->{socket} : $obj; return shutdown($socket, @params); } =item debug my $debug = Net::SSLeay::Handle->debug() Net::SSLeay::Handle->debug(1) Get/set debugging mode. Always returns the debug value before the function call. if an additional argument is given the debug option will be set to this value. =cut sub debug { my ($class, $debug) = @_; my $old_debug = $Debug; @_ >1 and $Debug = $debug || 0; return $old_debug; } #=== Internal Methods ========================================================= =item make_socket my $sock = Net::SSLeay::Handle->make_socket($host, $port); Creates a socket that is connected to $post using $port. It uses $Net::SSLeay::proxyhost and proxyport if set and authentificates itself against this proxy depending on $Net::SSLeay::proxyauth. It also turns autoflush on for the created socket. =cut sub make_socket { my ($class, $host, $port) = @_; $Debug > 10 and print "_make_socket(@{[join ', ', @_]})\n"; $host ||= 'localhost'; $port ||= 443; my $phost = $Net::SSLeay::proxyhost; my $pport = $Net::SSLeay::proxyhost ? $Net::SSLeay::proxyport : $port; my $dest_ip = gethostbyname($phost || $host); my $host_params = sockaddr_in($pport, $dest_ip); socket(my $socket, &PF_INET(), &SOCK_STREAM(), 0) or die "socket: $!"; connect($socket, $host_params) or die "connect: $!"; my $old_select = select($socket); $| = 1; select($old_select); $phost and do { my $auth = $Net::SSLeay::proxyauth; my $CRLF = $Net::SSLeay::CRLF; print $socket "CONNECT $host:$port HTTP/1.0$auth$CRLF$CRLF"; my $line = <$socket>; }; return $socket; } =back =cut sub _initialize { $Initialized++ and return; Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::randomize(); } sub __dummy { my $host = $Net::SSLeay::proxyhost; my $port = $Net::SSLeay::proxyport; my $auth = $Net::SSLeay::proxyauth; } #--- _get_self($socket) ------------------------------------------------------- # Returns a hash containing attributes for $socket (= \*SOMETHING) based # on fileno($socket). Will return undef if $socket was not created here. #------------------------------------------------------------------------------ sub _get_self { return $_[0]; } #--- _get_ssl($socket) -------------------------------------------------------- # Returns a the "ssl" attribute for $socket (= \*SOMETHING) based # on fileno($socket). Will cause a warning and return undef if $socket was not # created here. #------------------------------------------------------------------------------ sub _get_ssl { return $_[0]->{ssl}; } 1; __END__ =head2 USING EXISTING SOCKETS One of the motivations for writing this module was to avoid duplicating socket creation code (which is mostly error handling). The calls to tie() above where it is passed a $host and $port is provided for convenience testing. If you already have a socket connected to the right host and port, S1, then you can do something like: my $socket \*S1; if ($scheme eq "https") { tie(*S2, "Net::SSLeay::Handle", $socket); $socket = \*S2; } my $last_sel = select($socket); $| = 1; select($last_sel); print $socket $request_headers; ... Note: As far as I know you must be careful with the globs in the tie() function. The first parameter must be a glob (*SOMETHING) and the last parameter must be a reference to a glob (\*SOMETHING_ELSE) or a scaler that was assigned to a reference to a glob (as in the example above) Also, the two globs must be different. When I tried to use the same glob, I got a core dump. =head2 EXPORT None by default. You can export the shutdown() function. It is suggested that you do export shutdown() or use the fully qualified Net::SSLeay::Handle::shutdown() function to shutdown SSL sockets. It should be smart enough to distinguish between SSL and non-SSL sockets and do the right thing. =head1 EXAMPLES use Net::SSLeay::Handle qw/shutdown/; my ($host, $port) = ("localhost", 443); tie(*SSL, "Net::SSLeay::Handle", $host, $port); print SSL "GET / HTTP/1.0\r\n"; shutdown(\*SSL, 1); print while (); close SSL; =head1 TODO Better error handling. Callback routine? =head1 CAVEATS Tying to a file handle is a little tricky (for me at least). The first parameter to tie() must be a glob (*SOMETHING) and the last parameter must be a reference to a glob (\*SOMETHING_ELSE) or a scaler that was assigned to a reference to a glob ($s = \*SOMETHING_ELSE). Also, the two globs must be different. When I tried to use the same glob, I got a core dump. I was able to associate attributes to globs created by this module (like *SSL above) by making a hash of hashes keyed by the file head1. =head1 CHANGES Please see Net-SSLeay-Handle-0.50/Changes file. =head1 BUGS If you encounter a problem with this module that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the code you are trying to run; =item * your operating system name and version; =item * the output of C; =item * the version of OpenSSL or LibreSSL you are using. =back =head1 AUTHOR Originally written by Jim Bowlin. Maintained by Sampo Kellomäki between July 2001 and August 2003. Maintained by Florian Ragwitz between November 2005 and January 2010. Maintained by Mike McCauley between November 2005 and June 2018. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen since June 2018. =head1 COPYRIGHT Copyright (c) 2001 Jim Bowlin Copyright (c) 2001-2003 Sampo Kellomäki Copyright (c) 2005-2010 Florian Ragwitz Copyright (c) 2005-2018 Mike McCauley Copyright (c) 2018- Chris Novakovic Copyright (c) 2018- Tuure Vartiainen Copyright (c) 2018- Heikki Vatiainen All rights reserved. =head1 LICENSE This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =head1 SEE ALSO Net::SSLeay, perl(1), http://openssl.org/ =cut Net-SSLeay-1.92/lib/Net/SSLeay.pm0000644000175000001440000015434714167654427015063 0ustar csnusers# Net::SSLeay.pm - Perl module for using Eric Young's implementation of SSL # # Copyright (c) 1996-2003 Sampo Kellomäki # Copyright (c) 2005-2010 Florian Ragwitz # Copyright (c) 2005-2018 Mike McCauley # Copyright (c) 2018- Chris Novakovic # Copyright (c) 2018- Tuure Vartiainen # Copyright (c) 2018- Heikki Vatiainen # # All rights reserved. # # This module is released under the terms of the Artistic License 2.0. For # details, see the LICENSE file distributed with Net-SSLeay's source code. package Net::SSLeay; use 5.8.1; use strict; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD $CRLF); use Socket; use Errno; require Exporter; use AutoLoader; # 0=no warns, 1=only errors, 2=ciphers, 3=progress, 4=dump data $Net::SSLeay::trace = 0; # Do not change here, use # $Net::SSLeay::trace = [1-4] in caller # 2 = insist on v2 SSL protocol # 3 = insist on v3 SSL # 10 = insist on TLSv1 # 11 = insist on TLSv1.1 # 12 = insist on TLSv1.2 # 13 = insist on TLSv1.3 # 0 or undef = guess (v23) # $Net::SSLeay::ssl_version = 0; # don't change here, use # Net::SSLeay::version=[2,3,0] in caller #define to enable the "cat /proc/$$/stat" stuff $Net::SSLeay::linux_debug = 0; # Number of seconds to sleep after sending message and before half # closing connection. Useful with antiquated broken servers. $Net::SSLeay::slowly = 0; # RANDOM NUMBER INITIALIZATION # # Edit to your taste. Using /dev/random would be more secure, but may # block if randomness is not available, thus the default is # /dev/urandom. $how_random determines how many bits of randomness to take # from the device. You should take enough (read SSLeay/doc/rand), but # beware that randomness is limited resource so you should not waste # it either or you may end up with randomness depletion (situation where # /dev/random would block and /dev/urandom starts to return predictable # numbers). # # N.B. /dev/urandom does not exist on all systems, such as Solaris 2.6. In that # case you should get a third party package that emulates /dev/urandom # (e.g. via named pipe) or supply a random number file. Some such # packages are documented in Caveat section of the POD documentation. $Net::SSLeay::random_device = '/dev/urandom'; $Net::SSLeay::how_random = 512; # When updating this, also update $VERSION in the following files: # inc/Test/Net/SSLeay.pm # inc/Test/Net/SSLeay/Socket.pm # lib/Net/SSLeay/Handle.pm $VERSION = '1.92'; @ISA = qw(Exporter); # This array 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. my @constants = qw( ASN1_STRFLGS_ESC_CTRL ASN1_STRFLGS_ESC_MSB ASN1_STRFLGS_ESC_QUOTE ASN1_STRFLGS_RFC2253 CB_ACCEPT_EXIT CB_ACCEPT_LOOP CB_ALERT CB_CONNECT_EXIT CB_CONNECT_LOOP CB_EXIT CB_HANDSHAKE_DONE CB_HANDSHAKE_START CB_LOOP CB_READ CB_READ_ALERT CB_WRITE CB_WRITE_ALERT ERROR_NONE ERROR_SSL ERROR_SYSCALL ERROR_WANT_ACCEPT ERROR_WANT_CONNECT ERROR_WANT_READ ERROR_WANT_WRITE ERROR_WANT_X509_LOOKUP ERROR_ZERO_RETURN EVP_PKS_DSA EVP_PKS_EC EVP_PKS_RSA EVP_PKT_ENC EVP_PKT_EXCH EVP_PKT_EXP EVP_PKT_SIGN EVP_PK_DH EVP_PK_DSA EVP_PK_EC EVP_PK_RSA FILETYPE_ASN1 FILETYPE_PEM F_CLIENT_CERTIFICATE F_CLIENT_HELLO F_CLIENT_MASTER_KEY F_D2I_SSL_SESSION F_GET_CLIENT_FINISHED F_GET_CLIENT_HELLO F_GET_CLIENT_MASTER_KEY F_GET_SERVER_FINISHED F_GET_SERVER_HELLO F_GET_SERVER_VERIFY F_I2D_SSL_SESSION F_READ_N F_REQUEST_CERTIFICATE F_SERVER_HELLO F_SSL_CERT_NEW F_SSL_GET_NEW_SESSION F_SSL_NEW F_SSL_READ F_SSL_RSA_PRIVATE_DECRYPT F_SSL_RSA_PUBLIC_ENCRYPT F_SSL_SESSION_NEW F_SSL_SESSION_PRINT_FP F_SSL_SET_FD F_SSL_SET_RFD F_SSL_SET_WFD F_SSL_USE_CERTIFICATE F_SSL_USE_CERTIFICATE_ASN1 F_SSL_USE_CERTIFICATE_FILE F_SSL_USE_PRIVATEKEY F_SSL_USE_PRIVATEKEY_ASN1 F_SSL_USE_PRIVATEKEY_FILE F_SSL_USE_RSAPRIVATEKEY F_SSL_USE_RSAPRIVATEKEY_ASN1 F_SSL_USE_RSAPRIVATEKEY_FILE F_WRITE_PENDING GEN_DIRNAME GEN_DNS GEN_EDIPARTY GEN_EMAIL GEN_IPADD GEN_OTHERNAME GEN_RID GEN_URI GEN_X400 LIBRESSL_VERSION_NUMBER MBSTRING_ASC MBSTRING_BMP MBSTRING_FLAG MBSTRING_UNIV MBSTRING_UTF8 MIN_RSA_MODULUS_LENGTH_IN_BYTES MODE_ACCEPT_MOVING_WRITE_BUFFER MODE_AUTO_RETRY MODE_ENABLE_PARTIAL_WRITE MODE_RELEASE_BUFFERS NID_OCSP_sign NID_SMIMECapabilities NID_X500 NID_X509 NID_ad_OCSP NID_ad_ca_issuers NID_algorithm NID_authority_key_identifier NID_basic_constraints NID_bf_cbc NID_bf_cfb64 NID_bf_ecb NID_bf_ofb64 NID_cast5_cbc NID_cast5_cfb64 NID_cast5_ecb NID_cast5_ofb64 NID_certBag NID_certificate_policies NID_client_auth NID_code_sign NID_commonName NID_countryName NID_crlBag NID_crl_distribution_points NID_crl_number NID_crl_reason NID_delta_crl NID_des_cbc NID_des_cfb64 NID_des_ecb NID_des_ede NID_des_ede3 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 NID_description NID_desx_cbc NID_dhKeyAgreement NID_dnQualifier NID_dsa NID_dsaWithSHA NID_dsaWithSHA1 NID_dsaWithSHA1_2 NID_dsa_2 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 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 NID_ms_code_com NID_ms_code_ind NID_ms_ctl_sign NID_ms_efs NID_ms_ext_req NID_ms_sgc 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 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 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 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 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_shaWithRSAEncryption NID_stateOrProvinceName NID_subject_alt_name NID_subject_key_identifier NID_surname NID_sxnet NID_time_stamp NID_title NID_undef NID_uniqueIdentifier NID_x509Certificate NID_x509Crl NID_zlib_compression NOTHING OCSP_RESPONSE_STATUS_INTERNALERROR OCSP_RESPONSE_STATUS_MALFORMEDREQUEST OCSP_RESPONSE_STATUS_SIGREQUIRED OCSP_RESPONSE_STATUS_SUCCESSFUL OCSP_RESPONSE_STATUS_TRYLATER OCSP_RESPONSE_STATUS_UNAUTHORIZED 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_MODULES_DIR OPENSSL_PLATFORM OPENSSL_VERSION OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR OPENSSL_VERSION_NUMBER OPENSSL_VERSION_PATCH OPENSSL_VERSION_STRING OP_ALL OP_ALLOW_NO_DHE_KEX OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION OP_CIPHER_SERVER_PREFERENCE OP_CISCO_ANYCONNECT OP_COOKIE_EXCHANGE OP_CRYPTOPRO_TLSEXT_BUG OP_DONT_INSERT_EMPTY_FRAGMENTS OP_ENABLE_MIDDLEBOX_COMPAT OP_EPHEMERAL_RSA OP_LEGACY_SERVER_CONNECT OP_MICROSOFT_BIG_SSLV3_BUFFER OP_MICROSOFT_SESS_ID_BUG OP_MSIE_SSLV2_RSA_PADDING OP_NETSCAPE_CA_DN_BUG OP_NETSCAPE_CHALLENGE_BUG OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG OP_NON_EXPORT_FIRST OP_NO_ANTI_REPLAY OP_NO_CLIENT_RENEGOTIATION OP_NO_COMPRESSION OP_NO_ENCRYPT_THEN_MAC OP_NO_QUERY_MTU OP_NO_RENEGOTIATION OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION OP_NO_SSL_MASK OP_NO_SSLv2 OP_NO_SSLv3 OP_NO_TICKET OP_NO_TLSv1 OP_NO_TLSv1_1 OP_NO_TLSv1_2 OP_NO_TLSv1_3 OP_PKCS1_CHECK_1 OP_PKCS1_CHECK_2 OP_PRIORITIZE_CHACHA OP_SAFARI_ECDHE_ECDSA_BUG OP_SINGLE_DH_USE OP_SINGLE_ECDH_USE OP_SSLEAY_080_CLIENT_DH_BUG OP_SSLREF2_REUSE_CERT_TYPE_BUG OP_TLSEXT_PADDING OP_TLS_BLOCK_PADDING_BUG OP_TLS_D5_BUG OP_TLS_ROLLBACK_BUG READING RECEIVED_SHUTDOWN RSA_3 RSA_F4 R_BAD_AUTHENTICATION_TYPE R_BAD_CHECKSUM R_BAD_MAC_DECODE R_BAD_RESPONSE_ARGUMENT R_BAD_SSL_FILETYPE R_BAD_SSL_SESSION_ID_LENGTH R_BAD_STATE R_BAD_WRITE_RETRY R_CHALLENGE_IS_DIFFERENT R_CIPHER_TABLE_SRC_ERROR R_INVALID_CHALLENGE_LENGTH R_NO_CERTIFICATE_SET R_NO_CERTIFICATE_SPECIFIED R_NO_CIPHER_LIST R_NO_CIPHER_MATCH R_NO_PRIVATEKEY R_NO_PUBLICKEY R_NULL_SSL_CTX R_PEER_DID_NOT_RETURN_A_CERTIFICATE R_PEER_ERROR R_PEER_ERROR_CERTIFICATE R_PEER_ERROR_NO_CIPHER R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE R_PUBLIC_KEY_ENCRYPT_ERROR R_PUBLIC_KEY_IS_NOT_RSA R_READ_WRONG_PACKET_TYPE R_SHORT_READ R_SSL_SESSION_ID_IS_DIFFERENT R_UNABLE_TO_EXTRACT_PUBLIC_KEY R_UNKNOWN_REMOTE_ERROR_TYPE R_UNKNOWN_STATE R_X509_LIB SENT_SHUTDOWN SESSION_ASN1_VERSION SESS_CACHE_BOTH SESS_CACHE_CLIENT SESS_CACHE_NO_AUTO_CLEAR SESS_CACHE_NO_INTERNAL SESS_CACHE_NO_INTERNAL_LOOKUP SESS_CACHE_NO_INTERNAL_STORE SESS_CACHE_OFF SESS_CACHE_SERVER SSL2_MT_CLIENT_CERTIFICATE SSL2_MT_CLIENT_FINISHED SSL2_MT_CLIENT_HELLO SSL2_MT_CLIENT_MASTER_KEY SSL2_MT_ERROR SSL2_MT_REQUEST_CERTIFICATE SSL2_MT_SERVER_FINISHED SSL2_MT_SERVER_HELLO SSL2_MT_SERVER_VERIFY SSL2_VERSION SSL3_MT_CCS SSL3_MT_CERTIFICATE SSL3_MT_CERTIFICATE_REQUEST SSL3_MT_CERTIFICATE_STATUS SSL3_MT_CERTIFICATE_URL SSL3_MT_CERTIFICATE_VERIFY SSL3_MT_CHANGE_CIPHER_SPEC SSL3_MT_CLIENT_HELLO SSL3_MT_CLIENT_KEY_EXCHANGE SSL3_MT_ENCRYPTED_EXTENSIONS SSL3_MT_END_OF_EARLY_DATA SSL3_MT_FINISHED SSL3_MT_HELLO_REQUEST SSL3_MT_KEY_UPDATE SSL3_MT_MESSAGE_HASH SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEXT_PROTO SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO SSL3_MT_SERVER_KEY_EXCHANGE SSL3_MT_SUPPLEMENTAL_DATA SSL3_RT_ALERT SSL3_RT_APPLICATION_DATA SSL3_RT_CHANGE_CIPHER_SPEC SSL3_RT_HANDSHAKE SSL3_RT_HEADER SSL3_RT_INNER_CONTENT_TYPE SSL3_VERSION SSLEAY_BUILT_ON SSLEAY_CFLAGS SSLEAY_DIR SSLEAY_PLATFORM SSLEAY_VERSION ST_ACCEPT ST_BEFORE ST_CONNECT ST_INIT ST_OK ST_READ_BODY ST_READ_HEADER TLS1_1_VERSION TLS1_2_VERSION TLS1_3_VERSION TLS1_VERSION TLSEXT_STATUSTYPE_ocsp VERIFY_CLIENT_ONCE VERIFY_FAIL_IF_NO_PEER_CERT VERIFY_NONE VERIFY_PEER VERIFY_POST_HANDSHAKE V_OCSP_CERTSTATUS_GOOD V_OCSP_CERTSTATUS_REVOKED V_OCSP_CERTSTATUS_UNKNOWN WRITING 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 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_TRUST_COMPAT 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_V_ERR_AKID_ISSUER_SERIAL_MISMATCH X509_V_ERR_AKID_SKID_MISMATCH X509_V_ERR_APPLICATION_VERIFICATION 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 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_EE_KEY_TOO_SMALL X509_V_ERR_EMAIL_MISMATCH 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_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_KEYUSAGE_NO_CERTSIGN X509_V_ERR_KEYUSAGE_NO_CRL_SIGN X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE X509_V_ERR_NO_EXPLICIT_POLICY 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 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_STORE_LOOKUP X509_V_ERR_SUBJECT_ISSUER_MISMATCH 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_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 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 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 XN_FLAG_SPC_EQ ); my @functions = qw( BIO_eof BIO_f_ssl BIO_free BIO_new BIO_new_file BIO_pending BIO_read BIO_s_mem BIO_wpending BIO_write CTX_free CTX_get_cert_store CTX_new CTX_use_RSAPrivateKey_file CTX_use_certificate_file CTX_v23_new CTX_v2_new CTX_v3_new ERR_error_string ERR_get_error ERR_load_RAND_strings ERR_load_SSL_strings PEM_read_bio_X509_CRL RSA_free RSA_generate_key SESSION_free SESSION_get_master_key SESSION_new SESSION_print X509_NAME_get_text_by_NID X509_NAME_oneline X509_STORE_add_cert X509_STORE_add_crl X509_check_email X509_check_host X509_check_ip X509_check_ip_asc X509_free X509_get_issuer_name X509_get_subject_name X509_load_cert_crl_file X509_load_cert_file X509_load_crl_file accept clear connect copy_session_id d2i_SSL_SESSION die_if_ssl_error die_now do_https dump_peer_certificate free get_cipher get_cipher_list get_client_random get_fd get_http get_http4 get_https get_https3 get_https4 get_httpx get_httpx4 get_peer_certificate get_peer_cert_chain get_rbio get_read_ahead get_server_random get_shared_ciphers get_time get_timeout get_wbio i2d_SSL_SESSION load_error_strings make_form make_headers new peek pending post_http post_http4 post_https post_https3 post_https4 post_httpx post_httpx4 print_errs read rstate_string rstate_string_long set_bio set_cert_and_key set_cipher_list set_fd set_read_ahead set_rfd set_server_cert_and_key set_session set_time set_timeout set_verify set_wfd ssl_read_CRLF ssl_read_all ssl_read_until ssl_write_CRLF ssl_write_all sslcat state_string state_string_long tcp_read_CRLF tcp_read_all tcp_read_until tcp_write_CRLF tcp_write_all tcpcat tcpxcat use_PrivateKey use_PrivateKey_ASN1 use_PrivateKey_file use_RSAPrivateKey use_RSAPrivateKey_ASN1 use_RSAPrivateKey_file use_certificate use_certificate_ASN1 use_certificate_file write d2i_OCSP_RESPONSE i2d_OCSP_RESPONSE OCSP_RESPONSE_free d2i_OCSP_REQUEST i2d_OCSP_REQUEST OCSP_REQUEST_free OCSP_cert2ids OCSP_ids2req OCSP_response_status OCSP_response_status_str OCSP_response_verify OCSP_response_results ); @EXPORT_OK = ( @constants, @functions ); sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. If a constant is not found then control is passed # to the AUTOLOAD in AutoLoader. my $constname; ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname); if ($! != 0) { if ($! =~ /((Invalid)|(not valid))/i || $!{EINVAL}) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { croak "Your vendor has not defined SSLeay macro $constname"; } } eval "sub $AUTOLOAD { $val }"; goto &$AUTOLOAD; } eval { require XSLoader; XSLoader::load('Net::SSLeay', $VERSION); 1; } or do { require DynaLoader; push @ISA, 'DynaLoader'; bootstrap Net::SSLeay $VERSION; }; # Preloaded methods go here. $CRLF = "\x0d\x0a"; # because \r\n is not fully portable ### Print SSLeay error stack sub print_errs { my ($msg) = @_; my ($count, $err, $errs, $e) = (0,0,''); while ($err = ERR_get_error()) { $count ++; $e = "$msg $$: $count - " . ERR_error_string($err) . "\n"; $errs .= $e; warn $e if $Net::SSLeay::trace; } return $errs; } # Death is conditional to SSLeay errors existing, i.e. this function checks # for errors and only dies in affirmative. # usage: Net::SSLeay::write($ssl, "foo") or die_if_ssl_error("SSL write ($!)"); sub die_if_ssl_error { my ($msg) = @_; die "$$: $msg\n" if print_errs($msg); } # Unconditional death. Used to print SSLeay errors before dying. # usage: Net::SSLeay::connect($ssl) or die_now("Failed SSL connect ($!)"); sub die_now { my ($msg) = @_; print_errs($msg); die "$$: $msg\n"; } # Perl 5.6.* unicode support causes that length() no longer reliably # reflects the byte length of a string. This eval is to fix that. # Thanks to Sean Burke for the snippet. BEGIN{ eval 'use bytes; sub blength ($) { defined $_[0] ? length $_[0] : 0 }'; $@ and eval ' sub blength ($) { defined $_[0] ? length $_[0] : 0 }' ; } # Autoload methods go after __END__, and are processed by the autosplit program. 1; __END__ ### Some methods that are macros in C sub want_nothing { want(shift) == 1 } sub want_read { want(shift) == 2 } sub want_write { want(shift) == 3 } sub want_X509_lookup { want(shift) == 4 } ### ### Open TCP stream to given host and port, looking up the details ### from system databases or DNS. ### sub open_tcp_connection { my ($dest_serv, $port) = @_; my ($errs); $port = getservbyname($port, 'tcp') unless $port =~ /^\d+$/; my $dest_serv_ip = gethostbyname($dest_serv); unless (defined($dest_serv_ip)) { $errs = "$0 $$: open_tcp_connection: destination host not found:" . " `$dest_serv' (port $port) ($!)\n"; warn $errs if $trace; return wantarray ? (0, $errs) : 0; } my $sin = sockaddr_in($port, $dest_serv_ip); warn "Opening connection to $dest_serv:$port (" . inet_ntoa($dest_serv_ip) . ")" if $trace>2; my $proto = &Socket::IPPROTO_TCP; # getprotobyname('tcp') not available on android if (socket (SSLCAT_S, &PF_INET(), &SOCK_STREAM(), $proto)) { warn "next connect" if $trace>3; if (CORE::connect (SSLCAT_S, $sin)) { my $old_out = select (SSLCAT_S); $| = 1; select ($old_out); warn "connected to $dest_serv, $port" if $trace>3; return wantarray ? (1, undef) : 1; # Success } } $errs = "$0 $$: open_tcp_connection: failed `$dest_serv', $port ($!)\n"; warn $errs if $trace; close SSLCAT_S; return wantarray ? (0, $errs) : 0; # Fail } ### Open connection via standard web proxy, if one was defined ### using set_proxy(). sub open_proxy_tcp_connection { my ($dest_serv, $port) = @_; return open_tcp_connection($dest_serv, $port) if !$proxyhost; warn "Connect via proxy: $proxyhost:$proxyport" if $trace>2; my ($ret, $errs) = open_tcp_connection($proxyhost, $proxyport); return wantarray ? (0, $errs) : 0 if !$ret; # Connection fail warn "Asking proxy to connect to $dest_serv:$port" if $trace>2; #print SSLCAT_S "CONNECT $dest_serv:$port HTTP/1.0$proxyauth$CRLF$CRLF"; #my $line = ; # *** bug? Mixing stdio with syscall read? ($ret, $errs) = tcp_write_all("CONNECT $dest_serv:$port HTTP/1.0$proxyauth$CRLF$CRLF"); return wantarray ? (0,$errs) : 0 if $errs; ($line, $errs) = tcp_read_until($CRLF . $CRLF, 1024); warn "Proxy response: $line" if $trace>2; return wantarray ? (0,$errs) : 0 if $errs; return wantarray ? (1,'') : 1; # Success } ### ### read and write helpers that block ### sub debug_read { my ($replyr, $gotr) = @_; my $vm = $trace>2 && $linux_debug ? (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; warn " got " . blength($$gotr) . ':' . blength($$replyr) . " bytes (VM=$vm).\n" if $trace == 3; warn " got `$$gotr' (" . blength($$gotr) . ':' . blength($$replyr) . " bytes, VM=$vm)\n" if $trace>3; } sub ssl_read_all { my ($ssl,$how_much) = @_; $how_much = 2000000000 unless $how_much; my ($got, $rv, $errs); my $reply = ''; while ($how_much > 0) { ($got, $rv) = Net::SSLeay::read($ssl, ($how_much > 32768) ? 32768 : $how_much ); if (! defined $got) { my $err = Net::SSLeay::get_error($ssl, $rv); if ($err != Net::SSLeay::ERROR_WANT_READ() and $err != Net::SSLeay::ERROR_WANT_WRITE()) { $errs = print_errs('SSL_read'); last; } next; } $how_much -= blength($got); debug_read(\$reply, \$got) if $trace>1; last if $got eq ''; # EOF $reply .= $got; } return wantarray ? ($reply, $errs) : $reply; } sub tcp_read_all { my ($how_much) = @_; $how_much = 2000000000 unless $how_much; my ($n, $got, $errs); my $reply = ''; my $bsize = 0x10000; while ($how_much > 0) { $n = sysread(SSLCAT_S,$got, (($bsize < $how_much) ? $bsize : $how_much)); warn "Read error: $! ($n,$how_much)" unless defined $n; last if !$n; # EOF $how_much -= $n; debug_read(\$reply, \$got) if $trace>1; $reply .= $got; } return wantarray ? ($reply, $errs) : $reply; } sub ssl_write_all { my $ssl = $_[0]; my ($data_ref, $errs); if (ref $_[1]) { $data_ref = $_[1]; } else { $data_ref = \$_[1]; } my ($wrote, $written, $to_write) = (0,0, blength($$data_ref)); my $vm = $trace>2 && $linux_debug ? (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; warn " write_all VM at entry=$vm\n" if $trace>2; while ($to_write) { #sleep 1; # *** DEBUG warn "partial `$$data_ref'\n" if $trace>3; $wrote = write_partial($ssl, $written, $to_write, $$data_ref); if (defined $wrote && ($wrote > 0)) { # write_partial can return -1 $written += $wrote; $to_write -= $wrote; } else { if (defined $wrote) { # check error conditions via SSL_get_error per man page if ( my $sslerr = get_error($ssl, $wrote) ) { my $errstr = ERR_error_string($sslerr); my $errname = ''; SWITCH: { $sslerr == constant("ERROR_NONE") && do { # according to map page SSL_get_error(3ssl): # The TLS/SSL I/O operation completed. # This result code is returned if and only if ret > 0 # so if we received it here complain... warn "ERROR_NONE unexpected with invalid return value!" if $trace; $errname = "SSL_ERROR_NONE"; }; $sslerr == constant("ERROR_WANT_READ") && do { # operation did not complete, call again later, so do not # set errname and empty err_que since this is a known # error that is expected but, we should continue to try # writing the rest of our data with same io call and params. warn "ERROR_WANT_READ (TLS/SSL Handshake, will continue)\n" if $trace; print_errs('SSL_write(want read)'); last SWITCH; }; $sslerr == constant("ERROR_WANT_WRITE") && do { # operation did not complete, call again later, so do not # set errname and empty err_que since this is a known # error that is expected but, we should continue to try # writing the rest of our data with same io call and params. warn "ERROR_WANT_WRITE (TLS/SSL Handshake, will continue)\n" if $trace; print_errs('SSL_write(want write)'); last SWITCH; }; $sslerr == constant("ERROR_ZERO_RETURN") && do { # valid protocol closure from other side, no longer able to # write, since there is no longer a session... warn "ERROR_ZERO_RETURN($wrote): TLS/SSLv3 Closure alert\n" if $trace; $errname = "SSL_ERROR_ZERO_RETURN"; last SWITCH; }; $sslerr == constant("ERROR_SSL") && do { # library/protocol error warn "ERROR_SSL($wrote): Library/Protocol error occured\n" if $trace; $errname = "SSL_ERROR_SSL"; last SWITCH; }; $sslerr == constant("ERROR_WANT_CONNECT") && do { # according to man page, should never happen on call to # SSL_write, so complain, but handle as known error type warn "ERROR_WANT_CONNECT: Unexpected error for SSL_write\n" if $trace; $errname = "SSL_ERROR_WANT_CONNECT"; last SWITCH; }; $sslerr == constant("ERROR_WANT_ACCEPT") && do { # according to man page, should never happen on call to # SSL_write, so complain, but handle as known error type warn "ERROR_WANT_ACCEPT: Unexpected error for SSL_write\n" if $trace; $errname = "SSL_ERROR_WANT_ACCEPT"; last SWITCH; }; $sslerr == constant("ERROR_WANT_X509_LOOKUP") && do { # operation did not complete: waiting on call back, # call again later, so do not set errname and empty err_que # since this is a known error that is expected but, we should # continue to try writing the rest of our data with same io # call parameter. warn "ERROR_WANT_X509_LOOKUP: (Cert Callback asked for in ". "SSL_write will contine)\n" if $trace; print_errs('SSL_write(want x509'); last SWITCH; }; $sslerr == constant("ERROR_SYSCALL") && do { # some IO error occured. According to man page: # Check retval, ERR, fallback to errno if ($wrote==0) { # EOF warn "ERROR_SYSCALL($wrote): EOF violates protocol.\n" if $trace; $errname = "SSL_ERROR_SYSCALL(EOF)"; } else { # -1 underlying BIO error reported. # check error que for details, don't set errname since we # are directly appending to errs my $chkerrs = print_errs('SSL_write (syscall)'); if ($chkerrs) { warn "ERROR_SYSCALL($wrote): Have errors\n" if $trace; $errs .= "ssl_write_all $$: 1 - ERROR_SYSCALL($wrote,". "$sslerr,$errstr,$!)\n$chkerrs"; } else { # que was empty, use errno warn "ERROR_SYSCALL($wrote): errno($!)\n" if $trace; $errs .= "ssl_write_all $$: 1 - ERROR_SYSCALL($wrote,". "$sslerr) : $!\n"; } } last SWITCH; }; warn "Unhandled val $sslerr from SSL_get_error(SSL,$wrote)\n" if $trace; $errname = "SSL_ERROR_?($sslerr)"; } # end of SWITCH block if ($errname) { # if we had an errname set add the error $errs .= "ssl_write_all $$: 1 - $errname($wrote,$sslerr,". "$errstr,$!)\n"; } } # endif on have SSL_get_error val } # endif on $wrote defined } # endelse on $wrote > 0 $vm = $trace>2 && $linux_debug ? (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; warn " written so far $wrote:$written bytes (VM=$vm)\n" if $trace>2; # append remaining errors in que and report if errs exist $errs .= print_errs('SSL_write'); return (wantarray ? (undef, $errs) : undef) if $errs; } return wantarray ? ($written, $errs) : $written; } sub tcp_write_all { my ($data_ref, $errs); if (ref $_[0]) { $data_ref = $_[0]; } else { $data_ref = \$_[0]; } my ($wrote, $written, $to_write) = (0,0, blength($$data_ref)); my $vm = $trace>2 && $linux_debug ? (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; warn " write_all VM at entry=$vm to_write=$to_write\n" if $trace>2; while ($to_write) { warn "partial `$$data_ref'\n" if $trace>3; $wrote = syswrite(SSLCAT_S, $$data_ref, $to_write, $written); if (defined $wrote && ($wrote > 0)) { # write_partial can return -1 $written += $wrote; $to_write -= $wrote; } elsif (!defined($wrote)) { warn "tcp_write_all: $!"; return (wantarray ? (undef, "$!") : undef); } $vm = $trace>2 && $linux_debug ? (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; warn " written so far $wrote:$written bytes (VM=$vm)\n" if $trace>2; } return wantarray ? ($written, '') : $written; } ### from patch by Clinton Wong # ssl_read_until($ssl [, $delimit [, $max_length]]) # if $delimit missing, use $/ if it exists, otherwise use \n # read until delimiter reached, up to $max_length chars if defined sub ssl_read_until ($;$$) { my ($ssl,$delim, $max_length) = @_; # guess the delim string if missing if ( ! defined $delim ) { if ( defined $/ && length $/ ) { $delim = $/ } else { $delim = "\n" } # Note: \n,$/ value depends on the platform } my $len_delim = length $delim; my ($got); my $reply = ''; # If we have OpenSSL 0.9.6a or later, we can use SSL_peek to # speed things up. # N.B. 0.9.6a has security problems, so the support for # anything earlier than 0.9.6e will be dropped soon. if (&Net::SSLeay::OPENSSL_VERSION_NUMBER >= 0x0090601f) { $max_length = 2000000000 unless (defined $max_length); my ($pending, $peek_length, $found, $done); while (blength($reply) < $max_length and !$done) { #Block if necessary until we get some data $got = Net::SSLeay::peek($ssl,1); last if print_errs('SSL_peek'); $pending = Net::SSLeay::pending($ssl) + blength($reply); $peek_length = ($pending > $max_length) ? $max_length : $pending; $peek_length -= blength($reply); $got = Net::SSLeay::peek($ssl, $peek_length); last if print_errs('SSL_peek'); $peek_length = blength($got); #$found = index($got, $delim); # Old and broken # the delimiter may be split across two gets, so we prepend # a little from the last get onto this one before we check # for a match my $match; if(blength($reply) >= blength($delim) - 1) { #if what we've read so far is greater or equal #in length of what we need to prepatch $match = substr $reply, blength($reply) - blength($delim) + 1; } else { $match = $reply; } $match .= $got; $found = index($match, $delim); if ($found > -1) { #$got = Net::SSLeay::ssl_read_all($ssl, $found+$len_delim); #read up to the end of the delimiter $got = Net::SSLeay::ssl_read_all($ssl, $found + $len_delim - ((blength($match)) - (blength($got)))); $done = 1; } else { $got = Net::SSLeay::ssl_read_all($ssl, $peek_length); $done = 1 if ($peek_length == $max_length - blength($reply)); } last if print_errs('SSL_read'); debug_read(\$reply, \$got) if $trace>1; last if $got eq ''; $reply .= $got; } } else { while (!defined $max_length || length $reply < $max_length) { $got = Net::SSLeay::ssl_read_all($ssl,1); # one by one last if print_errs('SSL_read'); debug_read(\$reply, \$got) if $trace>1; last if $got eq ''; $reply .= $got; last if $len_delim && substr($reply, blength($reply)-$len_delim) eq $delim; } } return $reply; } sub tcp_read_until { my ($delim, $max_length) = @_; # guess the delim string if missing if ( ! defined $delim ) { if ( defined $/ && length $/ ) { $delim = $/ } else { $delim = "\n" } # Note: \n,$/ value depends on the platform } my $len_delim = length $delim; my ($n,$got); my $reply = ''; while (!defined $max_length || length $reply < $max_length) { $n = sysread(SSLCAT_S, $got, 1); # one by one warn "tcp_read_until: $!" if !defined $n; debug_read(\$reply, \$got) if $trace>1; last if !$n; # EOF $reply .= $got; last if $len_delim && substr($reply, blength($reply)-$len_delim) eq $delim; } return $reply; } # ssl_read_CRLF($ssl [, $max_length]) sub ssl_read_CRLF ($;$) { ssl_read_until($_[0], $CRLF, $_[1]) } sub tcp_read_CRLF { tcp_read_until($CRLF, $_[0]) } # ssl_write_CRLF($ssl, $message) writes $message and appends CRLF sub ssl_write_CRLF ($$) { # the next line uses less memory but might use more network packets return ssl_write_all($_[0], $_[1]) + ssl_write_all($_[0], $CRLF); # the next few lines do the same thing at the expense of memory, with # the chance that it will use less packets, since CRLF is in the original # message and won't be sent separately. #my $data_ref; #if (ref $_[1]) { $data_ref = $_[1] } # else { $data_ref = \$_[1] } #my $message = $$data_ref . $CRLF; #return ssl_write_all($_[0], \$message); } sub tcp_write_CRLF { # the next line uses less memory but might use more network packets return tcp_write_all($_[0]) + tcp_write_all($CRLF); # the next few lines do the same thing at the expense of memory, with # the chance that it will use less packets, since CRLF is in the original # message and won't be sent separately. #my $data_ref; #if (ref $_[1]) { $data_ref = $_[1] } # else { $data_ref = \$_[1] } #my $message = $$data_ref . $CRLF; #return tcp_write_all($_[0], \$message); } ### Quickly print out with whom we're talking sub dump_peer_certificate ($) { my ($ssl) = @_; my $cert = get_peer_certificate($ssl); return if print_errs('get_peer_certificate'); print "no cert defined\n" if !defined($cert); # Cipher=NONE with empty cert fix if (!defined($cert) || ($cert == 0)) { warn "cert = `$cert'\n" if $trace; return "Subject Name: undefined\nIssuer Name: undefined\n"; } else { my $x = 'Subject Name: ' . X509_NAME_oneline(X509_get_subject_name($cert)) . "\n" . 'Issuer Name: ' . X509_NAME_oneline(X509_get_issuer_name($cert)) . "\n"; Net::SSLeay::X509_free($cert); return $x; } } ### Arrange some randomness for eay PRNG sub randomize (;$$$) { my ($rn_seed_file, $seed, $egd_path) = @_; my $rnsf = defined($rn_seed_file) && -r $rn_seed_file; $egd_path = ''; $egd_path = $ENV{'EGD_PATH'} if $ENV{'EGD_PATH'}; RAND_seed(rand() + $$); # Stir it with time and pid unless ($rnsf || -r $Net::SSLeay::random_device || $seed || -S $egd_path) { my $poll_retval = Net::SSLeay::RAND_poll(); warn "Random number generator not seeded!!!" if $trace && !$poll_retval; } RAND_load_file($rn_seed_file, -s _) if $rnsf; RAND_seed($seed) if $seed; RAND_seed($ENV{RND_SEED}) if $ENV{RND_SEED}; RAND_load_file($Net::SSLeay::random_device, $Net::SSLeay::how_random/8) if -r $Net::SSLeay::random_device; } sub new_x_ctx { if ($ssl_version == 2) { unless (exists &Net::SSLeay::CTX_v2_new) { warn "ssl_version has been set to 2, but this version of OpenSSL has been compiled without SSLv2 support"; return undef; } $ctx = CTX_v2_new(); } elsif ($ssl_version == 3) { $ctx = CTX_v3_new(); } elsif ($ssl_version == 10) { $ctx = CTX_tlsv1_new(); } elsif ($ssl_version == 11) { unless (exists &Net::SSLeay::CTX_tlsv1_1_new) { warn "ssl_version has been set to 11, but this version of OpenSSL has been compiled without TLSv1.1 support"; return undef; } $ctx = CTX_tlsv1_1_new; } elsif ($ssl_version == 12) { unless (exists &Net::SSLeay::CTX_tlsv1_2_new) { warn "ssl_version has been set to 12, but this version of OpenSSL has been compiled without TLSv1.2 support"; return undef; } $ctx = CTX_tlsv1_2_new; } elsif ($ssl_version == 13) { unless (eval { Net::SSLeay::TLS1_3_VERSION(); } ) { warn "ssl_version has been set to 13, but this version of OpenSSL has been compiled without TLSv1.3 support"; return undef; } $ctx = CTX_new(); unless(Net::SSLeay::CTX_set_min_proto_version($ctx, Net::SSLeay::TLS1_3_VERSION())) { warn "CTX_set_min_proto failed for TLSv1.3"; return undef; } unless(Net::SSLeay::CTX_set_max_proto_version($ctx, Net::SSLeay::TLS1_3_VERSION())) { warn "CTX_set_max_proto failed for TLSv1.3"; return undef; } } else { $ctx = CTX_new(); } return $ctx; } ### ### Standard initialisation. Initialise the ssl library in the usual way ### at most once. Override this if you need differnet initialisation ### SSLeay_add_ssl_algorithms is also protected against multiple runs in SSLeay.xs ### and is also mutex protected in threading perls ### my $library_initialised; sub initialize { if (!$library_initialised) { load_error_strings(); # Some bloat, but I'm after ease of use SSLeay_add_ssl_algorithms(); # and debuggability. randomize(); $library_initialised++; } } ### ### Basic request - response primitive (don't use for https) ### sub sslcat { # address, port, message, $crt, $key --> reply / (reply,errs,cert) my ($dest_serv, $port, $out_message, $crt_path, $key_path) = @_; my ($ctx, $ssl, $got, $errs, $written); ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); return (wantarray ? (undef, $errs) : undef) unless $got; ### Do SSL negotiation stuff warn "Creating SSL $ssl_version context...\n" if $trace>2; initialize(); # Will init at most once $ctx = new_x_ctx(); goto cleanup2 if $errs = print_errs('CTX_new') or !$ctx; CTX_set_options($ctx, &OP_ALL); goto cleanup2 if $errs = print_errs('CTX_set_options'); warn "Cert `$crt_path' given without key" if $crt_path && !$key_path; set_cert_and_key($ctx, $crt_path, $key_path) if $crt_path; warn "Creating SSL connection (context was '$ctx')...\n" if $trace>2; $ssl = new($ctx); goto cleanup if $errs = print_errs('SSL_new') or !$ssl; warn "Setting fd (ctx $ctx, con $ssl)...\n" if $trace>2; set_fd($ssl, fileno(SSLCAT_S)); goto cleanup if $errs = print_errs('set_fd'); warn "Entering SSL negotiation phase...\n" if $trace>2; if ($trace>2) { my $i = 0; my $p = ''; my $cipher_list = 'Cipher list: '; $p=Net::SSLeay::get_cipher_list($ssl,$i); $cipher_list .= $p if $p; do { $i++; $cipher_list .= ', ' . $p if $p; $p=Net::SSLeay::get_cipher_list($ssl,$i); } while $p; $cipher_list .= '\n'; warn $cipher_list; } $got = Net::SSLeay::connect($ssl); warn "SSLeay connect returned $got\n" if $trace>2; goto cleanup if $errs = print_errs('SSL_connect'); my $server_cert = get_peer_certificate($ssl); print_errs('get_peer_certificate'); if ($trace>1) { warn "Cipher `" . get_cipher($ssl) . "'\n"; print_errs('get_ciper'); warn dump_peer_certificate($ssl); } ### Connected. Exchange some data (doing repeated tries if necessary). warn "sslcat $$: sending " . blength($out_message) . " bytes...\n" if $trace==3; warn "sslcat $$: sending `$out_message' (" . blength($out_message) . " bytes)...\n" if $trace>3; ($written, $errs) = ssl_write_all($ssl, $out_message); goto cleanup unless $written; sleep $slowly if $slowly; # Closing too soon can abort broken servers Net::SSLeay::shutdown($ssl); # Useful starting with OpenSSL 1.1.1e CORE::shutdown SSLCAT_S, 1; # Half close --> No more output, send EOF to server warn "waiting for reply...\n" if $trace>2; ($got, $errs) = ssl_read_all($ssl); warn "Got " . blength($got) . " bytes.\n" if $trace==3; warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; cleanup: free ($ssl); $errs .= print_errs('SSL_free'); cleanup2: CTX_free ($ctx); $errs .= print_errs('CTX_free'); close SSLCAT_S; return wantarray ? ($got, $errs, $server_cert) : $got; } sub tcpcat { # address, port, message, $crt, $key --> reply / (reply,errs,cert) my ($dest_serv, $port, $out_message) = @_; my ($got, $errs, $written); ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); return (wantarray ? (undef, $errs) : undef) unless $got; ### Connected. Exchange some data (doing repeated tries if necessary). warn "tcpcat $$: sending " . blength($out_message) . " bytes...\n" if $trace==3; warn "tcpcat $$: sending `$out_message' (" . blength($out_message) . " bytes)...\n" if $trace>3; ($written, $errs) = tcp_write_all($out_message); goto cleanup unless $written; sleep $slowly if $slowly; # Closing too soon can abort broken servers CORE::shutdown SSLCAT_S, 1; # Half close --> No more output, send EOF to server warn "waiting for reply...\n" if $trace>2; ($got, $errs) = tcp_read_all(); warn "Got " . blength($got) . " bytes.\n" if $trace==3; warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; cleanup: close SSLCAT_S; return wantarray ? ($got, $errs) : $got; } sub tcpxcat { my ($usessl, $site, $port, $req, $crt_path, $key_path) = @_; if ($usessl) { return sslcat($site, $port, $req, $crt_path, $key_path); } else { return tcpcat($site, $port, $req); } } ### ### Basic request - response primitive, this is different from sslcat ### because this does not shutdown the connection. ### sub https_cat { # address, port, message --> returns reply / (reply,errs,cert) my ($dest_serv, $port, $out_message, $crt_path, $key_path) = @_; my ($ctx, $ssl, $got, $errs, $written); ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); return (wantarray ? (undef, $errs) : undef) unless $got; ### Do SSL negotiation stuff warn "Creating SSL $ssl_version context...\n" if $trace>2; initialize(); $ctx = new_x_ctx(); goto cleanup2 if $errs = print_errs('CTX_new') or !$ctx; CTX_set_options($ctx, &OP_ALL); goto cleanup2 if $errs = print_errs('CTX_set_options'); warn "Cert `$crt_path' given without key" if $crt_path && !$key_path; set_cert_and_key($ctx, $crt_path, $key_path) if $crt_path; warn "Creating SSL connection (context was '$ctx')...\n" if $trace>2; $ssl = new($ctx); goto cleanup if $errs = print_errs('SSL_new') or !$ssl; warn "Setting fd (ctx $ctx, con $ssl)...\n" if $trace>2; set_fd($ssl, fileno(SSLCAT_S)); goto cleanup if $errs = print_errs('set_fd'); warn "Entering SSL negotiation phase...\n" if $trace>2; if ($trace>2) { my $i = 0; my $p = ''; my $cipher_list = 'Cipher list: '; $p=Net::SSLeay::get_cipher_list($ssl,$i); $cipher_list .= $p if $p; do { $i++; $cipher_list .= ', ' . $p if $p; $p=Net::SSLeay::get_cipher_list($ssl,$i); } while $p; $cipher_list .= '\n'; warn $cipher_list; } $got = Net::SSLeay::connect($ssl); warn "SSLeay connect failed" if $trace>2 && $got==0; goto cleanup if $errs = print_errs('SSL_connect'); my $server_cert = get_peer_certificate($ssl); print_errs('get_peer_certificate'); if ($trace>1) { warn "Cipher `" . get_cipher($ssl) . "'\n"; print_errs('get_ciper'); warn dump_peer_certificate($ssl); } ### Connected. Exchange some data (doing repeated tries if necessary). warn "https_cat $$: sending " . blength($out_message) . " bytes...\n" if $trace==3; warn "https_cat $$: sending `$out_message' (" . blength($out_message) . " bytes)...\n" if $trace>3; ($written, $errs) = ssl_write_all($ssl, $out_message); goto cleanup unless $written; warn "waiting for reply...\n" if $trace>2; ($got, $errs) = ssl_read_all($ssl); warn "Got " . blength($got) . " bytes.\n" if $trace==3; warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; cleanup: free ($ssl); $errs .= print_errs('SSL_free'); cleanup2: CTX_free ($ctx); $errs .= print_errs('CTX_free'); close SSLCAT_S; return wantarray ? ($got, $errs, $server_cert) : $got; } sub http_cat { # address, port, message --> returns reply / (reply,errs,cert) my ($dest_serv, $port, $out_message) = @_; my ($got, $errs, $written); ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); return (wantarray ? (undef, $errs) : undef) unless $got; ### Connected. Exchange some data (doing repeated tries if necessary). warn "http_cat $$: sending " . blength($out_message) . " bytes...\n" if $trace==3; warn "http_cat $$: sending `$out_message' (" . blength($out_message) . " bytes)...\n" if $trace>3; ($written, $errs) = tcp_write_all($out_message); goto cleanup unless $written; warn "waiting for reply...\n" if $trace>2; ($got, $errs) = tcp_read_all(); warn "Got " . blength($got) . " bytes.\n" if $trace==3; warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; cleanup: close SSLCAT_S; return wantarray ? ($got, $errs) : $got; } sub httpx_cat { my ($usessl, $site, $port, $req, $crt_path, $key_path) = @_; warn "httpx_cat: usessl=$usessl ($site:$port)" if $trace; if ($usessl) { return https_cat($site, $port, $req, $crt_path, $key_path); } else { return http_cat($site, $port, $req); } } ### ### Easy set up of private key and certificate ### sub set_cert_and_key ($$$) { my ($ctx, $cert_path, $key_path) = @_; my $errs = ''; # Following will ask password unless private key is not encrypted CTX_use_PrivateKey_file( $ctx, $key_path, &FILETYPE_PEM ) == 1 or $errs .= print_errs("private key `$key_path' ($!)"); CTX_use_certificate_file ($ctx, $cert_path, &FILETYPE_PEM) == 1 or $errs .= print_errs("certificate `$cert_path' ($!)"); return wantarray ? (undef, $errs) : ($errs eq ''); } ### Old deprecated API sub set_server_cert_and_key ($$$) { &set_cert_and_key } ### Set up to use web proxy sub set_proxy ($$;**) { ($proxyhost, $proxyport, $proxyuser, $proxypass) = @_; require MIME::Base64 if $proxyuser; $proxyauth = $proxyuser ? $CRLF . 'Proxy-authorization: Basic ' . MIME::Base64::encode("$proxyuser:$proxypass", '') : ''; } ### ### Easy https manipulation routines ### sub make_form { my (@fields) = @_; my $form; while (@fields) { my ($name, $data) = (shift(@fields), shift(@fields)); $data =~ s/([^\w\-.\@\$ ])/sprintf("%%%2.2x",ord($1))/gse; $data =~ tr[ ][+]; $form .= "$name=$data&"; } chop $form; return $form; } sub make_headers { my (@headers) = @_; my $headers; while (@headers) { my $header = shift(@headers); my $value = shift(@headers); $header =~ s/:$//; $value =~ s/\x0d?\x0a$//; # because we add it soon, see below $headers .= "$header: $value$CRLF"; } return $headers; } sub do_httpx3 { my ($method, $usessl, $site, $port, $path, $headers, $content, $mime_type, $crt_path, $key_path) = @_; my ($response, $page, $h,$v); my $len = blength($content); if ($len) { $mime_type = "application/x-www-form-urlencoded" unless $mime_type; $content = "Content-Type: $mime_type$CRLF" . "Content-Length: $len$CRLF$CRLF$content"; } else { $content = "$CRLF$CRLF"; } my $req = "$method $path HTTP/1.0$CRLF"; unless (defined $headers && $headers =~ /^Host:/m) { $req .= "Host: $site"; unless (($port == 80 && !$usessl) || ($port == 443 && $usessl)) { $req .= ":$port"; } $req .= $CRLF; } $req .= (defined $headers ? $headers : '') . "Accept: */*$CRLF$content"; warn "do_httpx3($method,$usessl,$site:$port)" if $trace; my ($http, $errs, $server_cert) = httpx_cat($usessl, $site, $port, $req, $crt_path, $key_path); return (undef, "HTTP/1.0 900 NET OR SSL ERROR$CRLF$CRLF$errs") if $errs; $http = '' if !defined $http; ($headers, $page) = split /\s?\n\s?\n/, $http, 2; warn "headers >$headers< page >>$page<< http >>>$http<<<" if $trace>1; ($response, $headers) = split /\s?\n/, $headers, 2; return ($page, $response, $headers, $server_cert); } sub do_https3 { splice(@_,1,0) = 1; do_httpx3; } # Legacy undocumented ### do_https2() is a legacy version in the sense that it is unable ### to return all instances of duplicate headers. sub do_httpx2 { my ($page, $response, $headers, $server_cert) = &do_httpx3; X509_free($server_cert) if defined $server_cert; return ($page, $response, defined $headers ? map( { ($h,$v)=/^(\S+)\:\s*(.*)$/; (uc($h),$v); } split(/\s?\n/, $headers) ) : () ); } sub do_https2 { splice(@_,1,0) = 1; do_httpx2; } # Legacy undocumented ### Returns headers as a hash where multiple instances of same header ### are handled correctly. sub do_httpx4 { my ($page, $response, $headers, $server_cert) = &do_httpx3; my %hr = (); for my $hh (split /\s?\n/, $headers) { my ($h,$v) = ($hh =~ /^(\S+)\:\s*(.*)$/); push @{$hr{uc($h)}}, $v; } return ($page, $response, \%hr, $server_cert); } sub do_https4 { splice(@_,1,0) = 1; do_httpx4; } # Legacy undocumented # https sub get_https { do_httpx2(GET => 1, @_) } sub post_https { do_httpx2(POST => 1, @_) } sub put_https { do_httpx2(PUT => 1, @_) } sub head_https { do_httpx2(HEAD => 1, @_) } sub get_https3 { do_httpx3(GET => 1, @_) } sub post_https3 { do_httpx3(POST => 1, @_) } sub put_https3 { do_httpx3(PUT => 1, @_) } sub head_https3 { do_httpx3(HEAD => 1, @_) } sub get_https4 { do_httpx4(GET => 1, @_) } sub post_https4 { do_httpx4(POST => 1, @_) } sub put_https4 { do_httpx4(PUT => 1, @_) } sub head_https4 { do_httpx4(HEAD => 1, @_) } # http sub get_http { do_httpx2(GET => 0, @_) } sub post_http { do_httpx2(POST => 0, @_) } sub put_http { do_httpx2(PUT => 0, @_) } sub head_http { do_httpx2(HEAD => 0, @_) } sub get_http3 { do_httpx3(GET => 0, @_) } sub post_http3 { do_httpx3(POST => 0, @_) } sub put_http3 { do_httpx3(PUT => 0, @_) } sub head_http3 { do_httpx3(HEAD => 0, @_) } sub get_http4 { do_httpx4(GET => 0, @_) } sub post_http4 { do_httpx4(POST => 0, @_) } sub put_http4 { do_httpx4(PUT => 0, @_) } sub head_http4 { do_httpx4(HEAD => 0, @_) } # Either https or http sub get_httpx { do_httpx2(GET => @_) } sub post_httpx { do_httpx2(POST => @_) } sub put_httpx { do_httpx2(PUT => @_) } sub head_httpx { do_httpx2(HEAD => @_) } sub get_httpx3 { do_httpx3(GET => @_) } sub post_httpx3 { do_httpx3(POST => @_) } sub put_httpx3 { do_httpx3(PUT => @_) } sub head_httpx3 { do_httpx3(HEAD => @_) } sub get_httpx4 { do_httpx4(GET => @_) } sub post_httpx4 { do_httpx4(POST => @_) } sub put_httpx4 { do_httpx4(PUT => @_) } sub head_httpx4 { do_httpx4(HEAD => @_) } ### Legacy, don't use # ($page, $respone_or_err, %headers) = do_https(...); sub do_https { my ($site, $port, $path, $method, $headers, $content, $mime_type, $crt_path, $key_path) = @_; do_https2($method, $site, $port, $path, $headers, $content, $mime_type, $crt_path, $key_path); } 1; __END__ Net-SSLeay-1.92/lib/Net/SSLeay.pod0000644000175000001440000135255514167653374015233 0ustar csnusers=encoding utf-8 =head1 NAME Net::SSLeay - Perl bindings for OpenSSL and LibreSSL =head1 SYNOPSIS 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 =head1 DESCRIPTION This module provides Perl bindings for libssl (an SSL/TLS API) and libcrypto (a cryptography API). =head1 COMPATIBILITY Net::SSLeay supports the following libssl implementations: =over =item * Any stable release of L in the 0.9.8 - 3.0 branches, except for OpenSSL 0.9.8 - 0.9.8b. =item * Any stable release of L in the 2.0 - 3.4 series, except for LibreSSL 3.2.2 and 3.2.3. =back Net::SSLeay may not function as expected with releases other than the ones listed above due to 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. Although Net::SSLeay maintains compatibility with old versions of OpenSSL and LibreSSL, it is B 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 L and L 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(...); } =head1 OVERVIEW L module basically comprise of: =over =item * High level functions for accessing web servers (by using HTTP/HTTPS) =item * Low level API (mostly mapped 1:1 to openssl's C functions) =item * Convenience functions (related to low level API but with more perl friendly interface) =back There is also a related module called L included in this distribution that you might want to use instead. It has its own pod documentation. =head2 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 C 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. For high level functions it is most convenient to import them into your main namespace as indicated in the synopsis. =head3 Basic set of functions =over =item * get_https =item * post_https =item * put_https =item * head_https =item * do_https =item * sslcat =item * https_cat =item * make_form =item * make_headers =back B 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 L. B demonstrates full fledged use of C. As can be seen, C 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 C is used to insert some additional headers in the request. C is a function that will convert a list or hash to such headers. By default C supplies C (to make virtual hosting easy) and C (reportedly needed by IIS) headers. B demonstrates how to get a password protected page. Refer to the HTTP protocol specifications for further details (e.g. RFC-2617). B invokes C to submit a HTML/CGI form to a secure server. The first four arguments are equal to C (note that the empty string (C<''>) 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 C is used to do the formatting, but you could pass any string. C automatically adds C and C headers to the request. B shows the fundamental C function (inspired in spirit by the C 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 - C is just a transport. B is a full invocation of C which allows the return of errors as well as the server (peer) certificate. The C<$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. =head3 Alternate versions of high-level API =over =item * get_https3 =item * post_https3 =item * put_https3 =item * get_https4 =item * post_https4 =item * put_https4 =back The above mentioned functions actually return the response headers as a list, which only gets converted to hash upon assignment (this assignment looses 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 L and L 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 'Subject Name: ' . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($server_cert)) . 'Issuer Name: ' . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($server_cert)); } Beware that this method only allows after the fact verification of the certificate: by the time C 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 C for guidance on how to do this. =head3 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 outlined above accept additional arguments that allow one to supply the client side certificate and key files. The format of these files is the same as used for server certificates and the caveat about encrypting private keys applies. ($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); B demonstrates getting a password protected page that also requires a client certificate, i.e. it is possible to use both authentication methods simultaneously. B is a full blown POST to a secure server that requires both password authentication and a client certificate, just like in case 2c. Note: The client will not send a certificate unless the server requests one. This is typically achieved by setting the verify mode to C on the server: Net::SSLeay::set_verify(ssl, Net::SSLeay::VERIFY_PEER, 0); See C for a full description. =head3 Working through a web proxy =over =item * set_proxy =back C can use a web proxy to make its connections. You need to first set the proxy host and port using C and then just use the normal API functions, e.g: Net::SSLeay::set_proxy('gateway.myorg.com', 8080); ($page) = get_https('www.bacus.pt', 443, '/'); If your proxy requires authentication, 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",'')) ); This example demonstrates the case where we authenticate to the proxy as C<"joe"> and to the final web server as C<"susie">. Proxy authentication requires the C module to work. =head3 HTTP (without S) API =over =item * get_http =item * post_http =item * tcpcat =item * get_httpx =item * post_httpx =item * tcpxcat =back Over the years it has become clear that it would be convenient to use the light-weight flavour API of C for normal HTTP as well (see C for the heavy-weight object-oriented approach). In fact it would be nice to be able to flip https on and off on the fly. Thus regular HTTP support was evolved. 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); As can be seen, the C<"x"> family of APIs takes as the first argument a flag which indicates whether SSL is used or not. =head2 Certificate verification and Certificate Revocation Lists (CRLs) OpenSSL supports the ability to verify peer certificates. It can also optionally check the peer certificate against a Certificate Revocation List (CRL) from the certificates issuer. A CRL is a file, created by the certificate issuer that lists all the certificates that it previously signed, but which it now revokes. CRLs are in PEM format. You can enable C checking like this: &Net::SSLeay::X509_STORE_set_flags (&Net::SSLeay::CTX_get_cert_store($ssl), &Net::SSLeay::X509_V_FLAG_CRL_CHECK); After setting this flag, if OpenSSL checks a peer's certificate, then it will attempt to find a CRL for the issuer. It does this 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 C<.r0>, C<.r1> etc. For example C, C. It will read all the .r files for the issuer, and then check for a revocation of the peer certificate in all of them. (You can also force it to look in a specific named CRL file., see below). You can find out the hash of the issuer subject name in a CRL with openssl crl -in crl.pem -hash -noout If the peer certificate does not pass the revocation list, or if no CRL is found, then the handshaking fails with an error. 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 is contained in the certificate itself and you can extract them with my @url = Net::SSLeay::P_X509_get_crl_distribution_points($cert) But there is no automatic downloading of the CRLs and often these CRLs are too huge to just download them to verify a single certificate. Also, these CRLs are often in DER format which you need to convert to PEM before you can use it: openssl crl -in crl.der -inform der -out crl.pem So as an alternative for faster and timely revocation checks you better use the Online Status Revocation Protocol (OCSP). =head2 Certificate verification and Online Status Revocation Protocol (OCSP) While checking for revoked certificates is possible and fast with Certificate Revocation Lists, you need to download the complete and often huge list before you can verify a single certificate. A faster way is to ask the CA to check the revocation of just a single or a few certificates using OCSP. Basically you generate for each certificate an OCSP_CERTID based on the certificate itself and its issuer, put the ids togetether into an OCSP_REQUEST and send the request to the URL given in the certificate. As a result you get back an OCSP_RESPONSE and need to check the status of the response, check that it is valid (e.g. signed by the CA) and finally extract the information about each OCSP_CERTID to find out if the certificate is still valid or got revoked. With Net::SSLeay this can be done like this: # 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: $@"; } # 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) } To further speed up certificate revocation checking one can use a TLS extension to instruct the server to staple the OCSP response: # 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 ... } =head2 Using Net::SSLeay in multi-threaded applications B Net::SSLeay module implements all necessary stuff to be ready for multi-threaded environment - it requires openssl-0.9.7 or newer. The implementation fully follows thread safety related requirements of openssl library(see L). If you are about to use Net::SSLeay (or any other module based on Net::SSLeay) in multi-threaded perl application it is recommended to follow this best-practice: =head3 Initialization Load and initialize 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 C function (which is also aliased as C, C and C) is not re-entrant and multiple calls can cause a crash in threaded application. Net::SSLeay implements flags preventing repeated calls to this function, therefore even multiple initialization via Net::SSLeay::SSLeay_add_ssl_algorithms() should work without trouble. =head3 Using callbacks Do not use callbacks across threads (the module blocks cross-thread callback operations and throws a warning). Always do the callback setup, callback use and callback destruction within the same thread. =head3 Using openssl elements All openssl elements (X509, SSL_CTX, ...) can be directly passed between threads. 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: 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); =head3 Using other perl modules based on Net::SSLeay It should be fine to use any other module based on L (like L) in multi-threaded applications. It is generally recommended to do any global initialization of such a module in the main thread before calling C<< threads->new(..) >> or C<< threads->create(..) >> but 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(); } =head3 Combining Net::SSLeay with other modules linked with openssl B There are many other (XS) modules linked directly to openssl library (like L). As it is expected that also "another" module will call C at some point we have again a trouble with multiple openssl initialization by Net::SSLeay and "another" module. As you can expect Net::SSLeay is not able to avoid multiple initialization of openssl library called by "another" module, thus you have to handle this on your own (in some cases it might not be possible at all to avoid this). =head3 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. You can call Net::SSLeay::initialize from your own code if you desire this conventional library initialization. =head2 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); =over =item * randomize seeds the openssl PRNG with C (see the top of C 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. The high level API functions automatically call C so it is not needed with them. See also caveats. =item * 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. =item * dump_peer_certificate allows you to get a plaintext description of the certificate the peer (usually the server) presented to us. =item * ssl_read_all see ssl_write_all (below) =item * ssl_write_all C and C provide true blocking semantics for these operations (see limitation, below, for explanation). These are much preferred to the low level API equivalents (which implement BSD blocking semantics). The message argument to C can be a reference. This is helpful to avoid unnecessary copying when writing something big, e.g: $data = 'A' x 1000000000; Net::SSLeay::ssl_write_all($ssl, \$data) or die "ssl write failed"; =item * ssl_read_CRLF uses C to read in a line terminated with a carriage return followed by a linefeed (CRLF). The CRLF is included in the returned scalar. =item * ssl_read_until uses C to read from the SSL input stream until it encounters a programmer specified delimiter. If the delimiter is undefined, C<$/> is used. If C<$/> is undefined, C<\n> is used. One can optionally set a maximum length of bytes to read from the SSL input stream. =item * ssl_write_CRLF writes C<$message> and appends CRLF to the SSL output stream. =back =head2 Initialization In order to use the low level API you should start your programs with the following incantation: 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(); =head2 Error handling functions I can not emphasize the need to check for error enough. Use these functions even in the most simple programs, they will reduce debugging time greatly. Do not ask questions on the mailing list without having first sprinkled these in your code. =over =item * die_now =item * die_if_ssl_error C and C are used to conveniently print the SSLeay error stack when something goes wrong: Net::SSLeay::connect($ssl) or die_now("Failed SSL connect ($!)"); Net::SSLeay::write($ssl, "foo") or die_if_ssl_error("SSL write ($!)"); =item * print_errs You can also use C to dump the error stack without exiting the program. As can be seen, your code becomes much more readable if you import the error reporting functions into your main name space. =back =head2 Sockets Perl uses file handles for all I/O. While SSLeay has a quite flexible BIO mechanism and perl has an evolved PerlIO mechanism, this module still sticks to using file descriptors. Thus to attach SSLeay to a socket you should use C to extract the underlying file descriptor: Net::SSLeay::set_fd($ssl, fileno(S)); # Must use fileno You should also set C<$|> to 1 to eliminate STDIO buffering so you do not get confused if you use perl I/O functions to manipulate your socket handle. If you need to C on the socket, go right ahead, but be warned that OpenSSL does some internal buffering so SSL_read does not always return data even if the socket selected for reading (just keep on selecting and trying to read). C is no different from the C language OpenSSL in this respect. =head2 Callbacks You can establish a per-context verify callback function something like this: sub verify { my ($ok, $x509_store_ctx) = @_; print "Verifying certificate...\n"; ... return $ok; } It is used like this: Net::SSLeay::set_verify ($ssl, Net::SSLeay::VERIFY_PEER, \&verify); Per-context callbacks for decrypting private keys are implemented. 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 Hello Extensions are supported by your OpenSSL, a session secret callback can be set up to be called when a session secret is set by openssl. Establish it like this: Net::SSLeay::set_session_secret_cb($ssl, \&session_secret_cb, $somedata); It will be called like this: sub session_secret_cb { my ($secret, \@cipherlist, \$preferredcipher, $somedata) = @_; } No other callbacks are implemented. You do not need to use any callback for simple (i.e. normal) cases where the SSLeay built-in verify mechanism satisfies your needs. It is required to reset these callbacks to undef immediately after use to prevent memory leaks, thread safety problems and crashes on exit that can occur if different threads set different callbacks. If you want to use callback stuff, see examples/callback.pl! It's the only one I am able to make work reliably. =head2 Low level API In addition to the high level functions outlined above, this module contains straight-forward access to CRYPTO and SSL parts of OpenSSL C API. See the C<*.h> headers from OpenSSL C distribution for a list of low level SSLeay functions to call (check SSLeay.xs to see if some function has been implemented). The module strips the initial C<"SSL_"> off of the SSLeay names. Generally you should use C in its place. Note that some functions are prefixed with C<"P_"> - these are very close to the original API however contain some kind of a wrapper making its interface more perl friendly. For example: In C: #include 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); If the function does not start with C you should use the full function name, e.g.: $err = Net::SSLeay::ERR_get_error; The following new functions behave in 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 =head3 Low level API: Version and library information related functions =over =item * OpenSSL_version_num and SSLeay B 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. B 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 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 # ... # 0x101010df => openssl-1.1.1m # 0x30000000 => openssl-3.0.0 # 0x30000010 => openssl-3.0.1 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.4.2 You can use the version number like this when you know that the underlying library is OpenSSL: if (Net::SSLeay::SSLeay() < 0x0090800f) { die "You need OpenSSL 0.9.8 or higher"; } LibresSSL 2.2.2 and later define constant LIBRESSL_VERSION_NUMBER that gives the LibreSSL version number. The format is the same that OpenSSL uses with OPENSSL_VERSION_NUMBER. You can do this if you need to check that the underlying library is LibreSSL and 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 openssl doc L See OpenSSL 1.1.1 and earlier documentation for the details of status nibble and the format interpretation. =item * SSLeay_version B 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() to an alias of OpenSSL_version(). To ensure correct functionality with LibreSSL, use SSLEAY_* constants with SSLeay_version() and OPENSSL_* constants with OpenSSL_version(). Check openssl doc L OpenSSL website no longer has a manual page for SSLeay_version(). =item * OpenSSL_version B 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. Available $t constants depend on the 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 L =item * OPENSSL_info B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1 Returns different strings depending on $t. Available $t constants depend on the library version. 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 L =item * OPENSSL_version_major, OPENSSL_version_minor and OPENSSL_version_patch B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL Return constants OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR and OPENSSL_VERSION_PATCH, respectively. 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. 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. Check openssl doc L =item * OPENSSL_version_pre_release B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL Return constant string defined by C macro OPENSSL_VERSION_PRE_RELEASE. 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. Check openssl doc L =item * OPENSSL_version_build_metadata() B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 3.0.0-alpha1, not in LibreSSL Return constant string defined by C macro OPENSSL_VERSION_BUILD_METADATA. 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. Check openssl doc L =back =head3 Low level API: Initialization related functions =over =item * library_init Initialize SSL library by registering algorithms. my $rv = Net::SSLeay::library_init(); Check openssl doc L 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. =item * add_ssl_algorithms The alias for L Net::SSLeay::add_ssl_algorithms(); =item * OpenSSL_add_ssl_algorithms The alias for L Net::SSLeay::OpenSSL_add_ssl_algorithms(); =item * SSLeay_add_ssl_algorithms The alias for L Net::SSLeay::SSLeay_add_ssl_algorithms(); =item * load_error_strings Registers the error strings for all libcrypto + libssl related functions. Net::SSLeay::load_error_strings(); # # returns: no return value Check openssl doc L =item * ERR_load_crypto_strings Registers the error strings for all libcrypto functions. No need to call this function if you have already called L. Net::SSLeay::ERR_load_crypto_strings(); # # returns: no return value Check openssl doc L =item * ERR_load_RAND_strings Registers the error strings for RAND related functions. No need to call this function if you have already called L. Net::SSLeay::ERR_load_RAND_strings(); # # returns: no return value =item * ERR_load_SSL_strings Registers the error strings for SSL related functions. No need to call this function if you have already called L. Net::SSLeay::ERR_load_SSL_strings(); # # returns: no return value =item * OpenSSL_add_all_algorithms B not available in Net-SSLeay-1.45 and before Add algorithms to internal table. Net::SSLeay::OpenSSL_add_all_algorithms(); # # returns: no return value Check openssl doc L =item * OPENSSL_add_all_algorithms_conf B not available in Net-SSLeay-1.45 and before Similar to L - will ALWAYS load the config file Net::SSLeay::OPENSSL_add_all_algorithms_conf(); # # returns: no return value =item * OPENSSL_add_all_algorithms_noconf B not available in Net-SSLeay-1.45 and before Similar to L - will NEVER load the config file Net::SSLeay::OPENSSL_add_all_algorithms_noconf(); # # returns: no return value =back =head3 Low level API: ERR_* and SSL_alert_* related functions B Please note that SSL_alert_* function have "SSL_" part stripped from their names. =over =item * ERR_clear_error Clear the error queue. Net::SSLeay::ERR_clear_error(); # # returns: no return value Check openssl doc L =item * ERR_error_string Generates a human-readable string representing the error code $error. my $rv = Net::SSLeay::ERR_error_string($error); # $error - (unsigned integer) error code # # returns: string Check openssl doc L =item * ERR_get_error Returns the earliest error code from the thread's error queue and removes the entry. This function can be called repeatedly until there are no more error codes to return. my $rv = Net::SSLeay::ERR_get_error(); # # returns: (unsigned integer) error code Check openssl doc L =item * ERR_peek_error Returns the earliest error code from the thread's error queue without modifying it. my $rv = Net::SSLeay::ERR_peek_error(); # # returns: (unsigned integer) error code Check openssl doc L =item * 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. 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 L and L =item * alert_desc_string Returns a two letter string as a short form describing the reason of the alert specified by value. my $rv = Net::SSLeay::alert_desc_string($value); # $value - (integer) allert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants) # # returns: description string (2 letters) Check openssl doc L =item * alert_desc_string_long Returns a string describing the reason of the alert specified by value. my $rv = Net::SSLeay::alert_desc_string_long($value); # $value - (integer) allert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants) # # returns: description string Check openssl doc L =item * alert_type_string Returns a one letter string indicating the type of the alert specified by value. my $rv = Net::SSLeay::alert_type_string($value); # $value - (integer) allert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants) # # returns: string (1 letter) Check openssl doc L =item * alert_type_string_long Returns a string indicating the type of the alert specified by value. my $rv = Net::SSLeay::alert_type_string_long($value); # $value - (integer) allert id (check openssl/ssl.h for SSL3_AD_* and TLS1_AD_* constants) # # returns: string Check openssl doc L =back =head3 Low level API: SSL_METHOD_* related functions =over =item * SSLv23_method, SSLv23_server_method and SSLv23_client_method B 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 L. B Consider using TLS_method, TLS_server_method or TLS_client_method with new code. my $rv = Net::SSLeay::SSLv2_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) =item * SSLv2_method Returns SSL_METHOD structure corresponding to SSLv2 method, the return value can be later used as a param of L. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::SSLv2_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) =item * SSLv3_method Returns SSL_METHOD structure corresponding to SSLv3 method, the return value can be later used as a param of L. my $rv = Net::SSLeay::SSLv3_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) Check openssl doc L =item * TLSv1_method, TLSv1_server_method and TLSv1_client_method B Server and client methods 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 L. my $rv = Net::SSLeay::TLSv1_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) Check openssl doc L =item * TLSv1_1_method, TLSv1_1_server_method and TLSv1_1_client_method B Server and client methods 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 L. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::TLSv1_1_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) Check openssl doc L =item * TLSv1_2_method, TLSv1_2_server_method and TLSv1_2_client_method B Server and client methods 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 L. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::TLSv1_2_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) Check openssl doc L =item * TLS_method, TLS_server_method and TLS_client_method B 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 L. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::TLS_method(); # # returns: value corresponding to openssl's SSL_METHOD structure (0 on failure) Check openssl doc L =back =head3 Low level API: ENGINE_* related functions =over =item * ENGINE_load_builtin_engines B Requires an OpenSSL build with dynamic engine loading support. Load all bundled ENGINEs into memory and make them visible. Net::SSLeay::ENGINE_load_builtin_engines(); # # returns: no return value Check openssl doc L =item * ENGINE_register_all_complete B Requires an OpenSSL build with dynamic engine loading support. Register all loaded ENGINEs for every algorithm they collectively implement. Net::SSLeay::ENGINE_register_all_complete(); # # returns: no return value Check openssl doc L =item * ENGINE_set_default B Requires an OpenSSL build with dynamic engine loading support. Set default engine to $e + set its flags to $flags. 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 L =item * ENGINE_by_id Get ENGINE by its identification $id. B Requires an OpenSSL build with dynamic engine loading support. 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 openssl doc L =back =head3 Low level API: EVP_PKEY_* related functions =over =item * EVP_PKEY_copy_parameters Copies the parameters from key $from to key $to. 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 openssl doc L =item * EVP_PKEY_new B not available in Net-SSLeay-1.45 and before Creates a new EVP_PKEY structure. my $rv = Net::SSLeay::EVP_PKEY_new(); # # returns: value corresponding to openssl's EVP_PKEY structure (0 on failure) Check openssl doc L =item * EVP_PKEY_free B not available in Net-SSLeay-1.45 and before Free an allocated EVP_PKEY structure. Net::SSLeay::EVP_PKEY_free($pkey); # $pkey - value corresponding to openssl's EVP_PKEY structure # # returns: no return value Check openssl doc L =item * EVP_PKEY_assign_RSA B not available in Net-SSLeay-1.45 and before Set the key referenced by $pkey to $key B No reference counter will be increased, i.e. $key will be freed if $pkey is freed. 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 openssl doc L =item * EVP_PKEY_assign_EC_KEY B not available in Net-SSLeay-1.74 and before Set the key referenced by $pkey to $key B No reference counter will be increased, i.e. $key will be freed if $pkey is freed. 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 openssl doc L =item * EVP_PKEY_bits B not available in Net-SSLeay-1.45 and before Returns the size of the key $pkey in bits. my $rv = Net::SSLeay::EVP_PKEY_bits($pkey); # $pkey - value corresponding to openssl's EVP_PKEY structure # # returns: size in bits =item * EVP_PKEY_size B not available in Net-SSLeay-1.45 and before Returns the maximum size of a signature in bytes. The actual signature may be smaller. my $rv = Net::SSLeay::EVP_PKEY_size($pkey); # $pkey - value corresponding to openssl's EVP_PKEY structure # # returns: the maximum size in bytes Check openssl doc L =item * EVP_PKEY_id B not available in Net-SSLeay-1.45 and before; requires at least openssl-1.0.0 Returns $pkey type (integer value of corresponding NID). my $rv = Net::SSLeay::EVP_PKEY_id($pkey); # $pkey - value corresponding to openssl's EVP_PKEY structure # # returns: (integer) key type Example: 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' =back =head3 Low level API: PEM_* related functions Check openssl doc L =over =item * PEM_read_bio_X509 B not available in Net-SSLeay-1.45 and before Loads PEM formatted X509 certificate via given BIO structure. 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); =item * PEM_read_bio_X509_REQ B not available in Net-SSLeay-1.45 and before Loads PEM formatted X509_REQ object via given BIO structure. 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); =item * PEM_read_bio_DHparams Reads DH structure from BIO. 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) =item * PEM_read_bio_X509_CRL Reads X509_CRL structure from BIO. 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) =item * PEM_read_bio_PrivateKey B not available in Net-SSLeay-1.45 and before Loads PEM formatted private key via given BIO structure. 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 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"; } =item * PEM_X509_INFO_read_bio Reads a BIO containing a PEM formatted file into a STACK_OF(X509_INFO) structure. 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); =item * PEM_get_string_X509 B Does not exactly correspond to any low level API function Converts/exports X509 certificate to string (PEM format). Net::SSLeay::PEM_get_string_X509($x509); # $x509 - value corresponding to openssl's X509 structure # # returns: string with $x509 in PEM format =item * PEM_get_string_PrivateKey B not available in Net-SSLeay-1.45 and before Converts public key $pk into PEM formatted string (optionally protected with password). 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")); =item * PEM_get_string_X509_CRL B not available in Net-SSLeay-1.45 and before Converts X509_CRL object $x509_crl into PEM formatted string. Net::SSLeay::PEM_get_string_X509_CRL($x509_crl); # $x509_crl - value corresponding to openssl's X509_CRL structure # # returns: no return value =item * PEM_get_string_X509_REQ B not available in Net-SSLeay-1.45 and before Converts X509_REQ object $x509_crl into PEM formatted string. Net::SSLeay::PEM_get_string_X509_REQ($x509_req); # $x509_req - value corresponding to openssl's X509_REQ structure # # returns: no return value =back =head3 Low level API: d2i_* (DER format) related functions =over =item * d2i_X509_bio B not available in Net-SSLeay-1.45 and before Loads DER formatted X509 certificate via given BIO structure. 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: 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 L =item * d2i_X509_CRL_bio B not available in Net-SSLeay-1.45 and before Loads DER formatted X509_CRL object via given BIO structure. 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); =item * d2i_X509_REQ_bio B not available in Net-SSLeay-1.45 and before Loads DER formatted X509_REQ object via given BIO structure. 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); =back =head3 Low level API: PKCS12 related functions =over =item * P_PKCS12_load_file B not available in Net-SSLeay-1.45 and before Loads X509 certificate + private key + certificates of CA chain (if present in PKCS12 file). 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) B after you do the job you need to call X509_free() on $privkey + all members of @cachain and EVP_PKEY_free() on $privkey. 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); B 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. =back =head3 Low level API: SESSION_* related functions =over =item * d2i_SSL_SESSION B 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. my $ses = Net::SSLeay::d2i_SSL_SESSION($data); # $data - the session as ASN1 representation string # # returns: $ses - the new SSL_SESSION Check openssl doc L =item * i2d_SSL_SESSION B 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. 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 L =item * SESSION_new Creates a new SSL_SESSION structure. my $rv = Net::SSLeay::SESSION_new(); # # returns: value corresponding to openssl's SSL_SESSION structure (0 on failure) =item * SESSION_free Free an allocated SSL_SESSION structure. Net::SSLeay::SESSION_free($ses); # $ses - value corresponding to openssl's SSL_SESSION structure # # returns: no return value Check openssl doc L =item * SESSION_up_ref B 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. Net::SSLeay::SESSION_up_ref($ses); # $ses - value corresponding to openssl's SSL_SESSION structure # # returns: 1 on success else 0 Check openssl doc L =item * SESSION_dup B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Duplicates a SSL_SESSION structure. Net::SSLeay::SESSION_dup($ses); # $ses - value corresponding to openssl's SSL_SESSION structure # # returns: the duplicated session Check openssl doc L =item * SESSION_is_resumable B 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. 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 L =item * SESSION_cmp Compare two SSL_SESSION structures. 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 B Not available in openssl 1.0 or later =item * 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 ??? =item * 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: ??? =item * 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 L =item * 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 L =item * 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 L =item * SESSION_get_master_key B Does not exactly correspond to any low level API function Returns 'master_key' value from SSL_SESSION structure $s Net::SSLeay::SESSION_get_master_key($s); # $s - value corresponding to openssl's SSL_SESSION structure # # returns: master key (binary data) =item * 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. =item * SESSION_get_time Returns the time at which the session s was established. The time is given in seconds since 1.1.1970. 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 L =item * get_time Technically the same functionality as L. my $rv = Net::SSLeay::get_time($s); =item * SESSION_get_timeout Returns the timeout value 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 L =item * get_timeout Technically the same functionality as L. my $rv = Net::SSLeay::get_timeout($s); =item * SESSION_print B Does not exactly correspond to any low level API function Prints session details (e.g. protocol version, cipher, session-id ...) to BIO. 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 You have to use necessary BIO functions 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); =item * SESSION_print_fp Prints session details (e.g. protocol version, cipher, session-id ...) to file handle. 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: # 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); =item * SESSION_set_time Replaces the creation time of the session s with the chosen value $t (seconds since 1.1.1970). 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 L =item * set_time Technically the same functionality as L. my $rv = Net::SSLeay::set_time($ses, $t); =item * SESSION_set_timeout Sets the timeout value for session s in seconds to $t. 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 L =item * set_timeout Technically the same functionality as L. my $rv = Net::SSLeay::set_timeout($ses, $t); =back =head3 Low level API: SSL_CTX_* related functions B Please note that the function described in this chapter have "SSL_" part stripped from their original openssl names. =over =item * CTX_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 $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 L =item * CTX_add_extra_chain_cert Adds the certificate $x509 to the certificate chain presented together with the certificate. Several certificates can be added 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 L =item * CTX_add_session Adds the session $ses to the context $ctx. 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 L =item * CTX_callback_ctrl ??? (more info needed) 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 L =item * CTX_check_private_key Checks the consistency of a private key with the corresponding certificate loaded into $ctx. 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 L =item * CTX_ctrl Internal handling function for SSL_CTX objects. B openssl doc says: This function should never be called directly! 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 ??? #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 L =item * CTX_flush_sessions Causes a run through the session cache of $ctx to remove sessions expired at time $tm. 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 L =item * CTX_free Free an allocated SSL_CTX object. Net::SSLeay::CTX_free($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: no return value Check openssl doc L =item * CTX_get_app_data Can be used to get application defined value/data. my $rv = Net::SSLeay::CTX_get_app_data($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: string/buffer/pointer ??? =item * CTX_set_app_data Can be used to set some application defined value/data. 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: ??? =item * CTX_get0_param B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Returns the current verification parameters. 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 L =item * CTX_get_cert_store Returns the current certificate verification storage. 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 L =item * CTX_get_client_CA_list Returns the list of client CAs explicitly set for $ctx using L. 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 L =item * CTX_get_ex_data Is used to retrieve the information for index $idx from $ctx. 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 L =item * CTX_get_ex_new_index Is used to register a new index for application specific data. 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 L =item * CTX_get_mode Returns the mode set for ctx. 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 L =item * CTX_set_mode Adds the mode set via bitmask in $mode to $ctx. Options already set before are not cleared. 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 bitmask details see L (above). Check openssl doc L =item * CTX_get_options Returns the options (bitmask) set for $ctx. my $rv = Net::SSLeay::CTX_get_options($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: options (bitmask) B The available constants and their values in 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 options Net::SSLeay currently supports. You are strongly encouraged to B if you need to use numeric values directly. The following is a sample of historic values. It may not be correct anymore. #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 L =item * CTX_set_options Adds the options set via bitmask in $options to ctx. Options already set before are not cleared. 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 bitmask details see L (above). Check openssl doc L =item * CTX_get_quiet_shutdown Returns the 'quiet shutdown' setting of $ctx. 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 L =item * CTX_get_read_ahead my $rv = Net::SSLeay::CTX_get_read_ahead($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: (integer) read_ahead value =item * CTX_get_session_cache_mode Returns the currently used cache mode (bitmask). my $rv = Net::SSLeay::CTX_get_session_cache_mode($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: mode (bitmask) B SESS_CACHE_OFF and other constants are not available in Net-SSLeay-1.82 and before. If the constants are not available, the following values have historically been correct. You are strongly encouraged to B for the current values. #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 L =item * CTX_set_session_cache_mode Enables/disables session caching by setting the operational mode for $ctx to $mode. 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 bitmask details see L (above). Check openssl doc L =item * CTX_get_timeout Returns the currently set timeout value 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 L =item * CTX_get_verify_depth Returns the verification depth limit currently set in $ctx. If no limit has been explicitly set, -1 is returned and the default value will be used. 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 L =item * CTX_get_verify_mode Returns the verification mode (bitmask) 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 L. Check openssl doc L =item * CTX_set_verify Sets the verification flags for $ctx to be $mode and specifies the verify_callback function to be used. 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 L =item * CTX_set_post_handshake_auth B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Enable the Post-Handshake Authentication extension to be added to the ClientHello such that post-handshake authentication can be requested by the server. 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 L =item * CTX_load_verify_locations Specifies the locations for $ctx, at which CA certificates for verification purposes are located. The certificates available via $CAfile and $CApath are 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) Check openssl doc L =item * CTX_need_tmp_RSA Return the result of C 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. =item * CTX_new The same as L my $rv = Net::SSLeay::CTX_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) Check openssl doc L Not available with OpenSSL 1.1 and later. =item * CTX_v2_new Creates a new SSL_CTX object - based on SSLv2_method() - as framework to establish TLS/SSL enabled connections. my $rv = Net::SSLeay::CTX_v2_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_v23_new Creates a new SSL_CTX object - based on SSLv23_method() - as framework to establish TLS/SSL enabled connections. my $rv = Net::SSLeay::CTX_v23_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_v3_new Creates a new SSL_CTX object - based on SSLv3_method() - as framework to establish TLS/SSL enabled connections. my $rv = Net::SSLeay::CTX_v3_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_tlsv1_new Creates a new SSL_CTX object - based on TLSv1_method() - as framework to establish TLS/SSL enabled connections. my $rv = Net::SSLeay::CTX_tlsv1_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_tlsv1_1_new Creates a new SSL_CTX object - based on TLSv1_1_method() - as framework to establish TLS/SSL enabled connections. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::CTX_tlsv1_1_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_tlsv1_2_new Creates a new SSL_CTX object - based on TLSv1_2_method() - as framework to establish TLS/SSL enabled connections. Only available where supported by the underlying openssl. my $rv = Net::SSLeay::CTX_tlsv1_2_new(); # # returns: value corresponding to openssl's SSL_CTX structure (0 on failure) =item * CTX_new_with_method Creates a new SSL_CTX object based on $meth method 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 L =item * CTX_set_min_proto_version, CTX_set_max_proto_version, set_min_proto_version and set_max_proto_version, B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0-pre2 or LibreSSL 2.6.0 Set the minimum and maximum supported protocol for $ctx or $ssl. my $rv = Net::SSLeay::CTX_set_min_proto_version($ctx, $version) # $ctx - value corresponding to openssl's SSL_CTX structure # $version - (integer) constat 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()); Check openssl doc L =item * CTX_get_min_proto_version, CTX_get_max_proto_version, get_min_proto_version and get_max_proto_version, B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0g Get 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 L =item * CTX_remove_session Removes the session $ses from the context $ctx. 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 L =item * CTX_sess_accept 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 L =item * CTX_sess_accept_good 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 L =item * CTX_sess_accept_renegotiate 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 L =item * CTX_sess_cache_full 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 L =item * CTX_sess_cb_hits 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 L =item * CTX_sess_connect 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 L =item * CTX_sess_connect_good 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 L =item * CTX_sess_connect_renegotiate 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 L =item * CTX_sess_get_cache_size Returns the currently valid session cache size. 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 L =item * CTX_sess_hits 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 L =item * CTX_sess_misses 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 L =item * CTX_sess_number 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 L =item * CTX_sess_set_cache_size Sets the size of the internal session cache of context $ctx to $size. 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 L =item * 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. my $rv = Net::SSLeay::CTX_sess_timeouts($ctx); # $ctx - value corresponding to openssl's SSL_CTX structure # # returns: number of sessions Check openssl doc L =item * CTX_sess_set_new_cb B not available in Net-SSLeay-1.85 and before Sets the callback function, which is automatically called whenever a new session was negotiated. 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 L =item * CTX_sess_set_remove_cb B not available in Net-SSLeay-1.85 and before Sets the callback function, which is automatically called whenever a session is removed by the SSL engine. 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 L =item * 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 L =item * CTX_set1_param B requires at least OpenSSL 1.0.0-beta3 Applies X509 verification parameters $vpm on $ctx 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 L =item * CTX_set_cert_store Sets/replaces the certificate verification storage of $ctx to/with $store. 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 L =item * 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 C is called. 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 L =item * 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 L Check openssl doc L =item * CTX_set_ciphersuites B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Configure the available TLSv1.3 ciphersuites. 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 openssl doc L =item * CTX_set_client_CA_list Sets the list of CAs sent to the client when requesting a client certificate for $ctx. 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 openssl doc L =item * CTX_set_default_passwd_cb Sets the default password callback called when loading/storing a PEM certificate with encryption. 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 openssl doc L =item * CTX_set_default_passwd_cb_userdata Sets a pointer to userdata which will be provided to the password callback on invocation. 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 openssl doc L =item * CTX_set_default_verify_paths ??? (more info needed) 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 =item * CTX_set_ex_data Is used to store application data at $data for $idx into the $ctx object. 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 openssl doc L =item * CTX_set_purpose 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 #avainable 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; =item * CTX_set_quiet_shutdown Sets the 'quiet shutdown' flag for $ctx to be mode. SSL objects created from $ctx inherit the mode valid at the time C is called. 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 openssl doc L =item * CTX_set_read_ahead 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 =item * 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. 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 openssl doc L =item * CTX_set_ssl_version Sets a new default TLS/SSL method for SSL objects newly created from this $ctx. SSL objects already created with C are not affected, except when C is being called. 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 openssl doc L =item * CTX_set_timeout Sets the timeout for newly created sessions for $ctx to $t. The timeout value $t must be given in seconds. 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 openssl doc L =item * CTX_set_tmp_dh Sets DH parameters to be used to be $dh. The key is inherited by all ssl objects created from $ctx. 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 openssl doc L =item * CTX_set_tmp_dh_callback Sets the callback function for $ctx to be used when a DH parameters are required to $tmp_dh_callback. 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 openssl doc L =item * CTX_set_tmp_rsa Sets the temporary/ephemeral RSA key to be used 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 openssl doc L Not available with OpenSSL 1.1 and later. =item * CTX_set_tmp_rsa_callback Sets the callback function for ctx to be used when a temporary/ephemeral RSA key is required to $tmp_rsa_callback. ??? (does this function really work?) 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 openssl doc L Not available with OpenSSL 1.1 and later. =item * CTX_set_trust 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; =item * CTX_set_verify_depth Sets the maximum depth for the certificate chain verification that shall be allowed for ctx. 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 openssl doc L =item * CTX_use_PKCS12_file Adds the certificate and private key from PKCS12 file $p12filename to $ctx. 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 =item * 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 openssl doc L =item * CTX_use_PrivateKey_file Adds the first private key found in $file to $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 L =item * 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 L =item * CTX_use_RSAPrivateKey_file Adds the first RSA private key found in $file 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 =item * 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 L =item * CTX_use_certificate_chain_file Loads a certificate chain from $file into $ctx. The certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA. 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 L =item * 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 L =item * CTX_get_security_level B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Returns the security level associated with $ctx. 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 L =item * CTX_set_security_level B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Sets the security level associated with $ctx to $level. 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 L =item * CTX_set_num_tickets B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Set number of TLSv1.3 session tickets that will be sent to a client. 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 to zero if you do not no want to support a session resumption. Check openssl doc L =item * CTX_get_num_tickets B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Get number of TLSv1.3 session tickets that will be sent to a client. 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 L =item * CTX_set_keylog_callback B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL Set the TLS key logging callback. 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 L =item * CTX_get_keylog_callback B not available in Net-SSLeay-1.90 and before; requires at least OpenSSL 1.1.1pre1, not in LibreSSL Retrieve the previously set TLS key logging callback. 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 L =back =head3 Low level API: SSL_* related functions B Please note that the function described in this chapter have "SSL_" part stripped from their original openssl names. =over =item * new Creates a new SSL structure which is needed 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. 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 L =item * accept Waits for a TLS/SSL client to initiate the TLS/SSL handshake. The communication channel must already have been set and assigned to the ssl by setting an underlying BIO. 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 L =item * 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 L =item * callback_ctrl ??? (more info needed) 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 L =item * check_private_key Checks the consistency of a private key with the corresponding certificate loaded into $ssl 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 Check openssl doc L =item * clear Reset SSL object to allow another connection. Net::SSLeay::clear($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: no return value Check openssl doc L =item * connect Initiate the TLS/SSL handshake with an TLS/SSL server. 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 Check openssl doc L =item * copy_session_id Copies the session structure fro $from to $to (+ also the private key and certificate 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 =item * ctrl Internal handling function for SSL objects. B openssl doc says: This function should never be called directly! 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 L. Check openssl doc L =item * do_handshake Will wait for a SSL/TLS handshake to take place. If the connection is in client mode, the handshake will be 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 Check openssl doc L =item * dup Returns a duplicate of $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) =item * free Free an allocated SSL structure. Net::SSLeay::free($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: no return value Check openssl doc L =item * get0_param B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Returns the current verification parameters. 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 Check openssl doc L =item * get_SSL_CTX Returns a pointer to the SSL_CTX object, from which $ssl was created with Net::SSLeay::new. 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) Check openssl doc L =item * set_SSL_CTX B requires at least OpenSSL 0.9.8f Sets the SSL_CTX the corresponds to an SSL session. 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 =item * get_app_data Can be used to get application defined value/data. my $rv = Net::SSLeay::get_app_data($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: string/buffer/pointer ??? =item * set_app_data Can be used to set some application defined value/data. my $rv = Net::SSLeay::set_app_data($ssl, $arg); # $ssl - value corresponding to openssl's SSL structure # $arg - (string/buffer/pointer ???) data # # returns: ??? =item * get_certificate Gets X509 certificate from an established SSL connection. 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) =item * get_cipher Obtains the name of the currently used cipher. 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. Check openssl doc L =item * get_cipher_bits Obtain the number of secret/algorithm bits used. 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 Check openssl doc L and L =item * get_ciphers B not available in Net-SSLeay-1.88 and before Returns a list of SSL_CIPHER structures available for $ssl sorted by preference 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"; } Check openssl doc L =item * get_cipher_list Returns the name (string) of the SSL_CIPHER listed for $ssl with priority $n. 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++; } Check openssl doc L =item * get_client_CA_list Returns the list of client CAs explicitly set for $ssl using C or $ssl's SSL_CTX object with C, when in server mode. In client mode, 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) Check openssl doc L =item * get_current_cipher Returns the cipher actually used. 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) Check openssl doc L =item * get_default_timeout Returns the default timeout value assigned to SSL_SESSION objects negotiated for the protocol valid for $ssl. my $rv = Net::SSLeay::get_default_timeout($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: (long) timeout in seconds Check openssl doc L =item * get_error Returns a result code for a preceding call to C, C, C, C, C or C on $ssl. 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 Check openssl doc L =item * get_ex_data Is used to retrieve the information for $idx from $ssl. 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 ??? Check openssl doc L =item * set_ex_data Is used to store application data at $data for $idx into the $ssl object. 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 L =item * get_ex_new_index Is used to register a new index for application specific data. 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 L =item * get_fd Returns the file descriptor which is linked to $ssl. 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 L =item * get_finished Obtains the latest 'Finished' message sent to the peer. Return value is zero if there's been no Finished message yet. Default count is 2*EVP_MAX_MD_SIZE that is long enough for all possible Finish messages. If you supply a non-default count, the resulting return value may be longer than 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 =item * get_peer_finished Obtains the latest 'Finished' message expected from the peer. Parameters and return value are similar to get_finished(). 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 =item * get_keyblock_size Gets the length of the TLS keyblock. B Does not exactly correspond to any low level API function. my $rv = Net::SSLeay::get_keyblock_size($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: keyblock size, -1 on error =item * get_mode Returns the mode (bitmask) set for $ssl. 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 L. Check openssl doc L =item * set_mode Adds the mode set via bitmask in $mode to $ssl. Options already set before are not cleared. 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 L. Check openssl doc L =item * get_options Returns the options (bitmask) set for $ssl. 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 L. Check openssl doc L =item * set_options Adds the options set via bitmask in $options to $ssl. Options already set before are not cleared! 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 L. Check openssl doc L =item * get_peer_certificate Get the X509 certificate of the peer. 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 L =item * get_peer_cert_chain Get the certificate chain of the peer as an array of X509 structures. my @rv = Net::SSLeay::get_peer_cert_chain($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: list of X509 structures Check openssl doc L =item * get_quiet_shutdown Returns the 'quiet shutdown' setting of ssl. 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 L =item * get_rbio Get 'read' BIO linked to an SSL object $ssl. 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 L =item * get_read_ahead my $rv = Net::SSLeay::get_read_ahead($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: (integer) read_ahead value =item * set_read_ahead 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 =item * get_security_level B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Returns the security level associated with $ssl. my $level = Net::SSLeay::get_security_level($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: (integer) current security level Check openssl doc L =item * set_security_level B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Sets the security level associated with $ssl to $level. 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 L =item * set_num_tickets B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Set number of TLSv1.3 session tickets that will be sent to a client. 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 no want to support a session resumption. Check openssl doc L =item * get_num_tickets B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Get number of TLSv1.3 session tickets that will be sent to a client. 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 L =item * get_server_random Returns internal SSLv3 server_random value. Net::SSLeay::get_server_random($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: server_random value (binary data) =item * get_client_random B Does not exactly correspond to any low level API function Returns internal SSLv3 client_random value. Net::SSLeay::get_client_random($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: client_random value (binary data) =item * export_keying_material Returns keying material based on the string $label and optional $context. Note that with TLSv1.2 and lower, empty context (empty string) and undefined context (no value or 'undef') will return different values. 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 Check openssl doc L =item * get_session Retrieve TLS/SSL session data used in $ssl. The reference count of the SSL_SESSION is NOT incremented. 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) Check openssl doc L =item * SSL_get0_session The alias for L (note that the name is C NOT C). my $rv = Net::SSLeay::SSL_get0_session(); =item * get1_session Returns a pointer to the SSL_SESSION actually used in $ssl. The reference count of the SSL_SESSION 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) Check openssl doc L =item * get_shared_ciphers Returns string with a list (colon ':' separated) of ciphers shared between client and server within 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:...' =item * get_shutdown Returns the shutdown mode of $ssl. 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 Check openssl doc L =item * get_ssl_method Returns a function pointer to the TLS/SSL method 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) Check openssl doc L =item * in_init, in_before, is_init_finished, in_connect_init, in_accept_init B not available in Net-SSLeay-1.85 and before. Retrieve information about the handshake state machine. All functions take $ssl as the only argument and return 0 or 1. These functions are recommended over get_state() and state(). my $rv = Net::SSLeay::is_init_finished($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: All functions return 1 or 0 Check openssl doc L =item * get_state B OpenSSL 1.1.0 and later use different constants which are not made available. Use is_init_finished() and related functions instead. Returns the SSL connection state. 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 =item * state Exactly the same as L. my $rv = Net::SSLeay::state($ssl); =item * 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. =item * 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 Check openssl doc L =item * set_verify_depth Sets the maximum depth for the certificate chain verification that shall be allowed for $ssl. Net::SSLeay::set_verify_depth($ssl, $depth); # $ssl - value corresponding to openssl's SSL structure # $depth - (integer) depth # # returns: no return value Check openssl doc L =item * 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) To decode the return value (bitmask) see documentation for L. Check openssl doc L =item * set_verify Sets the verification flags for $ssl to be $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 $mode bitmask details see L. Check openssl doc L =item * set_post_handshake_auth B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Enable the Post-Handshake Authentication extension to be added to the ClientHello such that post-handshake authentication can be requested by the server. 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 Check openssl doc L =item * verify_client_post_handshake B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL verify_client_post_handshake causes a CertificateRequest message to be sent by a server on the given ssl connection. 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. Check openssl doc L =item * get_verify_result Returns the result of the verification of the X509 certificate presented by the peer, if any. 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 openssl doc L =item * set_verify_result Override result of peer certificate verification. Net::SSLeay::set_verify_result($ssl, $v); # $ssl - value corresponding to openssl's SSL structure # $v - (integer) result value # # returns: no return value For more info about valid return values see L Check openssl doc L =item * get_wbio Get 'write' BIO linked to an SSL object $ssl. 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 openssl doc L =item * load_client_CA_file Load X509 certificates from file (PEM formatted). 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 openssl doc L =item * clear_num_renegotiations Executes SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS command on $ssl. my $rv = Net::SSLeay::clear_num_renegotiations($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: command result =item * need_tmp_RSA Executes 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 Not available with OpenSSL 1.1 and later. =item * num_renegotiations Executes SSL_CTRL_GET_NUM_RENEGOTIATIONS command on $ssl. my $rv = Net::SSLeay::num_renegotiations($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: command result =item * total_renegotiations Executes SSL_CTRL_GET_TOTAL_RENEGOTIATIONS command on $ssl. my $rv = Net::SSLeay::total_renegotiations($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: command result =item * peek Copies $max bytes from the specified $ssl into the returned value. In contrast to the C function, the data in the SSL buffer is unmodified after the SSL_peek() operation. 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(). =item * peek_ex B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Copies $max bytes from the specified $ssl into the returned value. In contrast to the C function, the data in the SSL buffer is 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 openssl doc L =item * pending Obtain number of readable bytes buffered in $ssl object. my $rv = Net::SSLeay::pending($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: the number of bytes pending Check openssl doc L =item * has_pending B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Returns 1 if $ssl has buffered data (whether processed or unprocessed) and 0 otherwise. my $rv = Net::SSLeay::has_pending($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: (integer) 1 or 0 Check openssl doc L =item * read Tries to read $max bytes from the specified $ssl. 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 openssl doc L =item * read_ex B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Tries to read $max bytes from the specified $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 openssl doc L =item * renegotiate Turn on flags for renegotiation so that renegotiation will happen my $rv = Net::SSLeay::renegotiate($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: 1 on success, 0 on failure =item * rstate_string Returns a 2 letter string indicating the current read state of the SSL object $ssl. my $rv = Net::SSLeay::rstate_string($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: 2-letter string Check openssl doc L =item * rstate_string_long Returns a string indicating the current read state of the SSL object ssl. my $rv = Net::SSLeay::rstate_string_long($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: string with current state Check openssl doc L =item * session_reused Query whether a reused session was negotiated during 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 openssl doc L =item * set1_param B requires at least OpenSSL 1.0.0-beta3 Applies X509 verification parameters $vpm on $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 =item * set_accept_state Sets $ssl to work in server mode. Net::SSLeay::set_accept_state($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: no return value Check openssl doc L =item * set_bio Connects the BIOs $rbio and $wbio for the read and write operations of the TLS/SSL (encrypted) side of $ssl. 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 openssl doc L =item * set_cipher_list Sets the list of ciphers only for ssl. 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 openssl doc L =item * set_ciphersuites B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Configure 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 openssl doc L =item * set_client_CA_list Sets 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::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 openssl doc L =item * set_connect_state Sets $ssl to work in client mode. Net::SSLeay::set_connect_state($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: no return value Check openssl doc L =item * set_fd Sets the file descriptor $fd as the input/output facility for the TLS/SSL (encrypted) side of $ssl, $fd will typically be the socket file descriptor of a network connection. 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 L =item * set_psk_client_callback Sets the psk client callback. 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 L =item * set_rfd Sets the file descriptor $fd as the input (read) facility for the TLS/SSL (encrypted) side of $ssl. 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 L =item * set_wfd 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 L =item * set_info_callback Sets the callback function, that can be used to obtain state information for $ssl during connection setup and use. When callback is undef, the callback setting currently valid for ctx is used. 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 L =item * CTX_set_info_callback Sets the callback function on ctx, that can be used to obtain state information during ssl connection setup and use. When callback is undef, an existing callback will be disabled. 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 L =item * set_msg_callback Sets the callback function, that can be used to obtain protocol messages information for $ssl during connection setup and use. When callback is undef, the callback setting currently valid for ctx is used. Note that set_msg_callback_arg is not provided as there is no need to explicitly set $arg, this is handled by set_msg_callback. 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 L =item * CTX_set_msg_callback Sets the callback function on ctx, that can be used to obtain protocol messages information for ssl connection setup and use. When callback is undef, the existing callback will be disabled. Note that CTX_set_msg_callback_arg is not provided as there is no need to explicitly set $arg, this is handled by CTX_set_msg_callback. 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 L =item * set_pref_cipher Sets the list of available ciphers for $ssl using the control string $str. 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 L =item * CTX_set_psk_client_callback Sets the psk client callback. 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 L =item * set_purpose 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 available $purpose identifiers see L. =item * set_quiet_shutdown Sets the 'quiet shutdown' flag for $ssl to be $mode. 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 L =item * set_session Set a TLS/SSL session to be used during TLS/SSL connect. 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 L =item * 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. 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 L =item * set_session_secret_cb Setup 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 will be called like: 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 The 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). With OpenSSL 1.1 and later, callback_function can change the master key for the session by altering $secret and returning 1. =item * CTX_set_tlsext_ticket_getkey_cb Setup 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 will be called like: 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. It then 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 argument. It then expects the callback to return the encryption+HMAC key matching the requested key name and and also the key name which should be used at the moment. If the requested key name and the returned key name differ it means that this session ticket was created with an expired key and need to be renewed. In this 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. 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); This function is based on the OpenSSL function SSL_CTX_set_tlsext_ticket_key_cb but provides a simpler to use interface. For more information see L =item * set_session_ticket_ext_cb Setup callback for TLS session tickets (stateless session reuse). 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 The callback function will be called like: 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 function is based on the OpenSSL function SSL_set_session_ticket_ext_cb. =item * set_session_ticket_ext Set TLS session ticket (stateless session reuse). 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 The callback function will be called like: 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 function is based on the OpenSSL function SSL_set_session_ticket_ext_cb. =item * set_shutdown Sets the shutdown state of $ssl to $mode. 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 Check openssl doc L =item * set_ssl_method Sets a new TLS/SSL method for a particular $ssl object. 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 Check openssl doc L =item * set_tmp_dh Sets DH parameters to be used to be $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 Check openssl doc L =item * set_tmp_dh_callback Sets the callback function for $ssl to be used when a DH parameters are required to $dh_cb. ??? (does this function really work?) 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 Check openssl doc L =item * set_tmp_rsa Sets the temporary/ephemeral RSA key to be used in $ssl to be $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: $rsakey = Net::SSLeay::RSA_generate_key(); Net::SSLeay::set_tmp_rsa($ssl, $rsakey); Net::SSLeay::RSA_free($rsakey); Check openssl doc L =item * set_tmp_rsa_callback Sets the callback function for $ssl to be used when a temporary/ephemeral RSA key is required to $tmp_rsa_callback. ??? (does this function really work?) 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 Check openssl doc L =item * set_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 For more details about $trust values see L. =item * shutdown Shuts down an active TLS/SSL connection. It sends the 'close notify' shutdown alert to the peer. 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 Check openssl doc L =item * state_string Returns a 6 letter string indicating the current state of the SSL object $ssl. my $rv = Net::SSLeay::state_string($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: 6-letter string Check openssl doc L =item * state_string_long Returns a string indicating the current state of the SSL object $ssl. my $rv = Net::SSLeay::state_string_long($ssl); # $ssl - value corresponding to openssl's SSL structure # # returns: state strings Check openssl doc L =item * set_default_passwd_cb B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0f. Not needed with LibreSSL. Sets the default password callback called when loading/storing a PEM certificate with encryption for $ssl. 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 Check openssl doc L =item * set_default_passwd_cb_userdata B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0f. Not needed with LibreSSL. Sets a pointer to userdata which will be provided to the password callback of $ssl on invocation. 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 Check openssl doc L =item * use_PrivateKey Adds $pkey as 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 Check openssl doc L =item * use_PrivateKey_ASN1 Adds the 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 Check openssl doc L =item * use_PrivateKey_file Adds the first private key found in $file to $ssl. 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 Check openssl doc L =item * use_RSAPrivateKey Adds $rsa as RSA private key to $ssl. 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 L =item * use_RSAPrivateKey_ASN1 Adds RSA private key stored in $data to $ssl. 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 L =item * use_RSAPrivateKey_file Adds the first RSA private key found in $file to $ssl. 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 L =item * use_certificate Loads the certificate $x into $ssl. 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 L =item * use_certificate_ASN1 Loads the ASN1 encoded certificate from $data to $ssl. 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 L =item * use_certificate_chain_file B: not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.1.0 Loads a certificate chain from $file into $ssl. The certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA. 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 L =item * use_certificate_file Loads the first certificate stored in $file into $ssl. 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 L =item * get_version Returns SSL/TLS protocol name 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 L =item * version Returns SSL/TLS protocol version 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 L =item * client_version B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL Returns TLS protocol version used by the client when initiating the connection 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 L =item * is_dtls B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.0, not in LibreSSL 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 L =item * want Returns state information for the SSL object $ssl. 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 L =item * write Writes data from the buffer $data into the specified $ssl connection. 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 L =item * write_ex B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Writes data from the buffer $data into the specified $ssl connection. 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 L =item * write_partial B Does not exactly correspond to any low level API function Writes a fragment of data in $data from the buffer $data into the specified $ssl connection. This is a non-blocking function like L. 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 =item * set_tlsext_host_name B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.8f Sets TLS servername extension on SLL object $ssl to value $name. 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 =back =head3 Low level API: RAND_* related functions Check openssl doc related to RAND stuff L =over =item * RAND_add Mixes the $num bytes at $buf into the PRNG state. 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 L =item * RAND_seed Equivalent to L when $num == $entropy. 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 L =item * RAND_status Gives PRNG status (seeded enough or not). my $rv = Net::SSLeay::RAND_status(); #returns: 1 if the PRNG has been seeded with enough data, 0 otherwise Check openssl doc L =item * RAND_bytes Puts $num cryptographically strong pseudo-random bytes into $buf. 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 L =item * RAND_priv_bytes B not available in Net-SSLeay-1.85 and before; requires at least OpenSSL 1.1.1, not in LibreSSL Puts $num cryptographically strong pseudo-random bytes into $buf. 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. Check openssl doc L =item * RAND_pseudo_bytes Puts $num pseudo-random (not necessarily unpredictable) bytes into $buf. 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 L =item * RAND_cleanup Erase the PRNG state. Net::SSLeay::RAND_cleanup(); # no args, no return value Check openssl doc L =item * 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 L =item * 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 L =item * RAND_load_file B Is no longer functional on LibreSSL Reads $max_bytes of bytes from $file_name and adds them to the PRNG. 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 L =item * RAND_write_file Writes 1024 random bytes to $file_name which can be used to initialize the PRNG by calling L in a later session. 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 L =item * 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) =back =head3 Low level API: OBJ_* related functions =over =item * OBJ_cmp Compares ASN1_OBJECT $a to ASN1_OBJECT $b. 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 L =item * OBJ_dup Returns a copy/duplicate of $o. 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 L =item * 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 L =item * OBJ_ln2nid Returns NID corresponding to given long name $n. my $rv = Net::SSLeay::OBJ_ln2nid($s); # $s - (string) long name e.g. 'commonName' # # returns: (integer) NID =item * 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); =item * OBJ_sn2nid Returns NID corresponding to given short name $s. 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'); =item * 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 L =item * OBJ_obj2nid Returns NID corresponding to given ASN1_OBJECT $o. my $rv = Net::SSLeay::OBJ_obj2nid($o); # $o - value corresponding to openssl's ASN1_OBJECT structure # # returns: (integer) NID Check openssl doc L =item * OBJ_txt2obj Converts the text string s into an ASN1_OBJECT structure. If $no_name is 0 then long names (e.g. 'commonName') and short names (e.g. 'CN') will be interpreted as well as numerical forms (e.g. '2.5.4.3'). If $no_name is 1 only the numerical form is acceptable. 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) Check openssl doc L =item * OBJ_obj2txt 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) Check openssl doc L =item * OBJ_txt2nid Returns NID corresponding to text string $s which can be a long name, a short name or the numerical representation of an object. my $rv = Net::SSLeay::OBJ_txt2nid($s); # $s - (string) e.g. 'commonName' or 'CN' or '2.5.4.3' # # returns: (integer) NID Example: my $nid = Net::SSLeay::OBJ_txt2nid('2.5.4.3'); Net::SSLeay::OBJ_nid2sn($n); Check openssl doc L =back =head3 Low level API: ASN1_INTEGER_* related functions =over =item * ASN1_INTEGER_new B not available in Net-SSLeay-1.45 and before Creates a new ASN1_INTEGER structure. my $rv = Net::SSLeay::ASN1_INTEGER_new(); # # returns: value corresponding to openssl's ASN1_INTEGER structure (0 on failure) =item * ASN1_INTEGER_free B not available in Net-SSLeay-1.45 and before Free an allocated ASN1_INTEGER structure. Net::SSLeay::ASN1_INTEGER_free($i); # $i - value corresponding to openssl's ASN1_INTEGER structure # # returns: no return value =item * ASN1_INTEGER_get B not available in Net-SSLeay-1.45 and before Returns integer value of given ASN1_INTEGER object. B If the value stored in ASN1_INTEGER is greater than max. integer that can be stored in 'long' type (usually 32bit but may vary according to platform) then this function will return -1. For getting large ASN1_INTEGER values consider using L or L. 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 =item * ASN1_INTEGER_set B not available in Net-SSLeay-1.45 and before Sets value of given ASN1_INTEGER object to value $val B $val has max. limit (= max. integer that can be stored in 'long' type). For setting large ASN1_INTEGER values consider using L or L. 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 =item * P_ASN1_INTEGER_get_dec B not available in Net-SSLeay-1.45 and before Returns string with decimal representation of integer value of given ASN1_INTEGER object. Net::SSLeay::P_ASN1_INTEGER_get_dec($i); # $i - value corresponding to openssl's ASN1_INTEGER structure # # returns: string with decimal representation =item * P_ASN1_INTEGER_get_hex B not available in Net-SSLeay-1.45 and before Returns string with hexadecimal representation of integer value of given ASN1_INTEGER object. Net::SSLeay::P_ASN1_INTEGER_get_hex($i); # $i - value corresponding to openssl's ASN1_INTEGER structure # # returns: string with hexadecimal representation =item * P_ASN1_INTEGER_set_dec B not available in Net-SSLeay-1.45 and before Sets value of given ASN1_INTEGER object to value $val (decimal string, suitable for large integers) 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 =item * P_ASN1_INTEGER_set_hex B not available in Net-SSLeay-1.45 and before Sets value of given ASN1_INTEGER object to value $val (hexadecimal string, suitable for large integers) 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 =back =head3 Low level API: ASN1_STRING_* related functions =over =item * P_ASN1_STRING_get B not available in Net-SSLeay-1.45 and before Returns string value of given ASN1_STRING object. 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 $string = Net::SSLeay::P_ASN1_STRING_get($s); #is the same as: $string = Net::SSLeay::P_ASN1_STRING_get($s, 0); =back =head3 Low level API: ASN1_TIME_* related functions =over =item * ASN1_TIME_new B not available in Net-SSLeay-1.42 and before my $time = ASN1_TIME_new(); # returns: value corresponding to openssl's ASN1_TIME structure =item * ASN1_TIME_free B not available in Net-SSLeay-1.42 and before ASN1_TIME_free($time); # $time - value corresponding to openssl's ASN1_TIME structure =item * ASN1_TIME_set B 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 B It is platform dependent how this function will handle dates after 2038. Although perl's integer is large enough the internal implementation of this function is dependent on the size of time_t structure (32bit time_t has problem with 2038). If you want to safely set date and time after 2038 use function L. =item * P_ASN1_TIME_get_isotime B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7e B Does not exactly correspond to any low level API function Gives ISO-8601 string representation of ASN1_TIME structure. 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 L =item * P_ASN1_TIME_set_isotime B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7e B Does not exactly correspond to any low level API function Sets time and date value of ANS1_time structure. 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 C<$string> parameter has to be in full form like C<"2012-03-22T23:55:33"> or C<"2012-03-22T23:55:33Z"> or C<"2012-03-22T23:55:33CET">. Short forms like C<"2012-03-22T23:55"> or C<"2012-03-22"> are not supported. =item * P_ASN1_TIME_put2string B not available in Net-SSLeay-1.42 and before, has bugs with openssl-0.9.8i B Does not exactly correspond to any low level API function Gives string representation of ASN1_TIME structure. 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' =item * P_ASN1_UTCTIME_put2string B deprecated function, only for backward compatibility, just an alias for L =back =head3 Low level API: X509_* related functions =over =item * X509_new B not available in Net-SSLeay-1.45 and before Allocates and initializes a X509 structure. my $rv = Net::SSLeay::X509_new(); # # returns: value corresponding to openssl's X509 structure (0 on failure) Check openssl doc L =item * X509_free Frees up the X509 structure. Net::SSLeay::X509_free($a); # $a - value corresponding to openssl's X509 structure # # returns: no return value Check openssl doc L =item * X509_check_host B 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. Checks if the certificate Subject Alternative Name (SAN) or Subject CommonName (CN) matches the specified host name. 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 Check openssl doc L. =item * X509_check_email B not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2. Checks if the certificate matches the specified email address. 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 L. =item * X509_check_ip B not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2. Checks if the certificate matches the specified IPv4 or IPv6 address. 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 L. =item * X509_check_ip_asc B not available in Net-SSLeay-1.68 and before; requires at least OpenSSL 1.0.2. Checks if the certificate matches the specified IPv4 or IPv6 address. 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 L. =item * X509_certificate_type B not available in Net-SSLeay-1.45 and before Returns bitmask with type of certificate $x. 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 =item * X509_digest B not available in Net-SSLeay-1.45 and before Computes digest/fingerprint of X509 $data using $type hash function. 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); =item * X509_issuer_and_serial_hash B not available in Net-SSLeay-1.45 and before Sort of a checksum of issuer name and serial number of X509 certificate $x. 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_issuer_and_serial_hash($x); # $x - value corresponding to openssl's X509 structure # # returns: number representing checksum =item * X509_issuer_name_hash B not available in Net-SSLeay-1.45 and before Sort of a checksum of issuer name of X509 certificate $x. 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_issuer_name_hash($x); # $x - value corresponding to openssl's X509 structure # # returns: number representing checksum =item * X509_subject_name_hash B not available in Net-SSLeay-1.45 and before Sort of a checksum of subject name of X509 certificate $x. 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_subject_name_hash($x); # $x - value corresponding to openssl's X509 structure # # returns: number representing checksum =item * X509_pubkey_digest B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Computes digest/fingerprint of public key from X509 certificate $data using $type hash function. 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); =item * X509_set_issuer_name B not available in Net-SSLeay-1.45 and before Sets issuer of X509 certificate $x to $name. 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 =item * X509_set_pubkey B not available in Net-SSLeay-1.45 and before Sets public key of X509 certificate $x to $pkey. 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 =item * X509_set_serialNumber B not available in Net-SSLeay-1.45 and before Sets serial number of X509 certificate $x to $serial. 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); =item * X509_set_subject_name B not available in Net-SSLeay-1.45 and before Sets subject of X509 certificate $x to $name. 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 =item * X509_set_version B not available in Net-SSLeay-1.45 and before Set 'version' value for X509 certificate $ to $version. 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 =item * X509_sign B not available in Net-SSLeay-1.45 and before Sign X509 certificate $x with private key $pkey (using digest algorithm $md). 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 =item * X509_verify B not available in Net-SSLeay-1.45 and before Verifies X509 object $a using public key $r (pubkey of issuing CA). 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 =item * X509_get_ext_count B not available in Net-SSLeay-1.45 and before Returns the total number of extensions in X509 object $x. my $rv = Net::SSLeay::X509_get_ext_count($x); # $x - value corresponding to openssl's X509 structure # # returns: count of extensions =item * X509_get_pubkey B not available in Net-SSLeay-1.45 and before Returns public key corresponding to given X509 object $x. 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) B This method returns only the public key's key bits, without the algorithm or parameters. Use C to return the full public key (SPKI) instead. =item * X509_get_X509_PUBKEY B not available in Net-SSLeay-1.72 and before Returns the full public key (SPKI) of given X509 certificate $x. Net::SSLeay::X509_get_X509_PUBKEY($x); # $x - value corresponding to openssl's X509 structure # # returns: public key data in DER format (binary) =item * X509_get_serialNumber B not available in Net-SSLeay-1.45 and before Returns serial number of X509 certificate $x. 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) See L, L or L to decode ASN1_INTEGER object. =item * X509_get0_serialNumber B available in Net-SSLeay-1.86 onwards X509_get0_serialNumber() is the same as X509_get_serialNumber() except it accepts a const parameter and returns a const result. =item * X509_get_version B not available in Net-SSLeay-1.45 and before Returns 'version' value of given X509 certificate $x. my $rv = Net::SSLeay::X509_get_version($x); # $x - value corresponding to openssl's X509 structure # # returns: (integer) version =item * X509_get_ext Returns X509_EXTENSION from $x509 based on given position/index. 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) =item * X509_get_ext_by_NID Returns X509_EXTENSION from $x509 based on given NID. 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 =item * X509_get_fingerprint Returns fingerprint of certificate $cert. B Does not exactly correspond to any low level API function. The implementation is based on openssl's C. 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!) =item * X509_get_issuer_name Return an X509_NAME object representing the issuer of the certificate $cert. 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) =item * X509_get_notAfter Return an object giving the time after which the certificate $cert is not valid. my $rv = Net::SSLeay::X509_get_notAfter($cert); # $cert - value corresponding to openssl's X509 structure # # returns: value corresponding to openssl's ASN1_TIME structure (0 on failure) To get human readable/printable form the return value you can use: my $time = Net::SSLeay::X509_get_notAfter($cert); print "notAfter=", Net::SSLeay::P_ASN1_TIME_get_isotime($time), "\n"; =item * X509_get_notBefore Return an object giving the time before which the certificate $cert is not valid my $rv = Net::SSLeay::X509_get_notBefore($cert); # $cert - value corresponding to openssl's X509 structure # # returns: value corresponding to openssl's ASN1_TIME structure (0 on failure) To get human readable/printable form the return value you can use: my $time = Net::SSLeay::X509_get_notBefore($cert); print "notBefore=", Net::SSLeay::P_ASN1_TIME_get_isotime($time), "\n"; =item * X509_get_subjectAltNames B Does not exactly correspond to any low level API function. Returns the list of alternative subject names from X509 certificate $cert. 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 returned RID string is currently 2500. Invalid and overly long RID values are skipped and not returned. GEN_X400 and GEN_EDIPARTY are not supported and will not be returned even when present in the certificate. =item * X509_get_subject_name Returns the subject of the certificate $cert. 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) =item * X509_gmtime_adj Adjust th ASN1_TIME object to the timestamp (in GMT). 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) B this function may fail for dates after 2038 as it is dependent on time_t size on your system (32bit time_t does not work after 2038). Consider using L instead). =item * X509_load_cert_crl_file Takes PEM file and loads all X509 certificates and X509 CRLs from that file into X509_LOOKUP structure. 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 =item * X509_load_cert_file Loads/adds X509 certificate from $file to X509_LOOKUP structure 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 =item * X509_load_crl_file Loads/adds X509 CRL from $file to X509_LOOKUP structure 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 =item * X509_policy_level_get0_node ??? (more info needed) 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) =item * X509_policy_level_node_count ??? (more info needed) my $rv = Net::SSLeay::X509_policy_level_node_count($level); # $level - value corresponding to openssl's X509_POLICY_LEVEL structure # # returns: (integer) node count =item * X509_policy_node_get0_parent ??? (more info needed) 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) =item * X509_policy_node_get0_policy ??? (more info needed) 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) =item * X509_policy_node_get0_qualifiers ??? (more info needed) 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) =item * X509_policy_tree_free ??? (more info needed) Net::SSLeay::X509_policy_tree_free($tree); # $tree - value corresponding to openssl's X509_POLICY_TREE structure # # returns: no return value =item * X509_policy_tree_get0_level ??? (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) =item * X509_policy_tree_get0_policies ??? (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 X509_POLICY_NODE structure (0 on failure) =item * X509_policy_tree_get0_user_policies ??? (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 X509_POLICY_NODE structure (0 on failure) =item * X509_policy_tree_level_count ??? (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 =item * X509_verify_cert_error_string Returns a human readable error string for verification error $n. my $rv = Net::SSLeay::X509_verify_cert_error_string($n); # $n - (long) numeric error code # # returns: error string Check openssl doc L =item * P_X509_add_extensions B not available in Net-SSLeay-1.45 and before Adds one or more X509 extensions to X509 object $x. 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 sertting NID_authority_key_identifier) # $nid - NID identifying extension to be set # $value - extension value # # returns: 1 on success, 0 on failure You can set more extensions at once: 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', ); =item * P_X509_copy_extensions B not available in Net-SSLeay-1.45 and before Copies X509 extensions from X509_REQ object to X509 object - handy when you need to turn X509_REQ into X509 certificate. 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 =item * P_X509_get_crl_distribution_points B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Get the list of CRL distribution points from X509 certificate. 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) =item * P_X509_get_ext_key_usage B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Gets the list of extended key usage of given X509 certificate $cert. 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: 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") =item * P_X509_get_key_usage B not available in Net-SSLeay-1.45 and before Gets the list of key usage of given X509 certificate $cert. 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" =item * P_X509_get_netscape_cert_type B not available in Net-SSLeay-1.45 and before Gets the list of Netscape cert types of given X509 certificate $cert. 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" =item * P_X509_get_pubkey_alg B not available in Net-SSLeay-1.45 and before Returns ASN1_OBJECT corresponding to X509 certificate public key algorithm. 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) To get textual representation use: my $alg = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_pubkey_alg($x509)); # returns for example: "rsaEncryption" =item * P_X509_get_signature_alg B not available in Net-SSLeay-1.45 and before Returns ASN1_OBJECT corresponding to X509 signarite key algorithm. 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) To get textual representation use: my $alg = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_signature_alg($x509)) # returns for example: "sha1WithRSAEncryption" =item * sk_X509_new_null Returns a new, empty, STACK_OF(X509) structure. my $rv = Net::SSLeay::sk_X509_new_null(); # # returns: value corresponding to openssl's STACK_OF(X509) structure =item * 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 =item * sk_X509_pop Pops an single X509 structure from a STACK_OF(X509) structure. my $x509 = NetSSLeay::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 L =item * sk_X509_shift Shifts an single X509 structure onto a STACK_OF(X509) structure. my $x509 = NetSSLeay::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 L =item * sk_X509_unshift Unshifts an single X509 structure from a STACK_OF(X509) structure. my $rv = NetSSLeay::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 L =item * 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 L =item * sk_X509_delete Delete a single X509 structure from a STACK_OF(X509) at the specified index. 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 L =item * sk_X509_value Return a single X509 structure from a STACK_OF(X509) at the specified 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 L =item * sk_X509_num Return the number of X509 elements in a STACK_OF(X509). 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 L =back =head3 Low level API: X509_REQ_* related functions =over =item * X509_REQ_new B not available in Net-SSLeay-1.45 and before Creates a new X509_REQ structure. my $rv = Net::SSLeay::X509_REQ_new(); # # returns: value corresponding to openssl's X509_REQ structure (0 on failure) =item * X509_REQ_free B not available in Net-SSLeay-1.45 and before Free an allocated X509_REQ structure. Net::SSLeay::X509_REQ_free($x); # $x - value corresponding to openssl's X509_REQ structure # # returns: no return value =item * X509_REQ_add1_attr_by_NID B not available in Net-SSLeay-1.45 and before Adds an attribute whose name is defined by a NID $nid. The field value to be added is in $bytes. 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 =item * X509_REQ_digest B not available in Net-SSLeay-1.45 and before Computes digest/fingerprint of X509_REQ $data using $type hash function. 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); =item * X509_REQ_get_attr_by_NID B not available in Net-SSLeay-1.45 and before Retrieve the next index matching $nid after $lastpos ($lastpos should initially be set to -1). 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 L 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); =item * X509_REQ_get_attr_by_OBJ B not available in Net-SSLeay-1.45 and before Retrieve the next index matching $obj after $lastpos ($lastpos should initially be set to -1). 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 L 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); =item * X509_REQ_get_attr_count B not available in Net-SSLeay-1.45 and before Returns the total number of attributes in $req. my $rv = Net::SSLeay::X509_REQ_get_attr_count($req); # $req - value corresponding to openssl's X509_REQ structure # # returns: (integer) items count =item * X509_REQ_get_pubkey B not available in Net-SSLeay-1.45 and before Returns public key corresponding to given X509_REQ object $x. 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) =item * X509_REQ_get_subject_name B not available in Net-SSLeay-1.45 and before Returns X509_NAME object corresponding to subject name of given X509_REQ object $x. 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) =item * X509_REQ_get_version B not available in Net-SSLeay-1.45 and before Returns 'version' value for given X509_REQ object $x. 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" =item * X509_REQ_set_pubkey B not available in Net-SSLeay-1.45 and before Sets public key of given X509_REQ object $x to $pkey. 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 =item * X509_REQ_set_subject_name B not available in Net-SSLeay-1.45 and before Sets subject name of given X509_REQ object $x to X509_NAME object $name. 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 =item * X509_REQ_set_version B not available in Net-SSLeay-1.45 and before Sets 'version' of given X509_REQ object $x to $version. 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 =item * X509_REQ_sign B not available in Net-SSLeay-1.45 and before Sign X509_REQ object $x with private key $pk (using digest algorithm $md). 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 =item * X509_REQ_verify B not available in Net-SSLeay-1.45 and before Verifies X509_REQ object $x using public key $r (pubkey of requesting party). 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 =item * P_X509_REQ_add_extensions B not available in Net-SSLeay-1.45 and before Adds one or more X509 extensions to X509_REQ object $x. 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 You can set more extensions at once: 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', ); =item * P_X509_REQ_get_attr B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Returns attribute value for X509_REQ's attribute at index $n. 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 =back =head3 Low level API: X509_CRL_* related functions =over =item * X509_CRL_new B not available in Net-SSLeay-1.45 and before Creates a new X509_CRL structure. my $rv = Net::SSLeay::X509_CRL_new(); # # returns: value corresponding to openssl's X509_CRL structure (0 on failure) =item * X509_CRL_free B not available in Net-SSLeay-1.45 and before Free an allocated X509_CRL structure. Net::SSLeay::X509_CRL_free($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: no return value =item * X509_CRL_digest B not available in Net-SSLeay-1.45 and before Computes digest/fingerprint of X509_CRL $data using $type hash function. 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: 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"; =item * X509_CRL_get_ext B not available in Net-SSLeay-1.54 and before Returns X509_EXTENSION from $x509 based on given position/index. 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) =item * X509_CRL_get_ext_by_NID B not available in Net-SSLeay-1.54 and before Returns X509_EXTENSION from $x509 based on given NID. 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 =item * X509_CRL_get_ext_count B not available in Net-SSLeay-1.54 and before Returns the total number of extensions in X509_CRL object $x. my $rv = Net::SSLeay::X509_CRL_get_ext_count($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: count of extensions =item * X509_CRL_get_issuer B not available in Net-SSLeay-1.45 and before Returns X509_NAME object corresponding to the issuer of X509_CRL $x. 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 other C functions to get more info from X509_NAME structure. =item * X509_CRL_get_lastUpdate B not available in Net-SSLeay-1.45 and before Returns 'lastUpdate' date-time value of X509_CRL object $x. my $rv = Net::SSLeay::X509_CRL_get_lastUpdate($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: value corresponding to openssl's ASN1_TIME structure (0 on failure) =item * X509_CRL_get_nextUpdate B not available in Net-SSLeay-1.45 and before Returns 'nextUpdate' date-time value of X509_CRL object $x. my $rv = Net::SSLeay::X509_CRL_get_nextUpdate($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: value corresponding to openssl's ASN1_TIME structure (0 on failure) =item * X509_CRL_get_version B not available in Net-SSLeay-1.45 and before Returns 'version' value of given X509_CRL structure $x. my $rv = Net::SSLeay::X509_CRL_get_version($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: (integer) version =item * X509_CRL_set_issuer_name B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sets the issuer of X509_CRL object $x to X509_NAME object $name. 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 =item * X509_CRL_set_lastUpdate B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sets 'lastUpdate' value of X509_CRL object $x to $tm. my $rv = Net::SSLeay::X509_CRL_set_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 =item * X509_CRL_set_nextUpdate B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sets 'nextUpdate' value of X509_CRL object $x to $tm. my $rv = Net::SSLeay::X509_CRL_set_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 =item * X509_CRL_set_version B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sets 'version' value of given X509_CRL structure $x to $version. 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 that if you want to use any X509_CRL extension you need to set "version 2 CRL" - C. =item * X509_CRL_sign B not available in Net-SSLeay-1.45 and before Sign X509_CRL object $x with private key $pkey (using digest algorithm $md). 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 =item * X509_CRL_sort B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sorts the data of X509_CRL object so it will be written in serial number order. my $rv = Net::SSLeay::X509_CRL_sort($x); # $x - value corresponding to openssl's X509_CRL structure # # returns: 1 on success, 0 on failure =item * X509_CRL_verify B not available in Net-SSLeay-1.45 and before Verifies X509_CRL object $a using public key $r (pubkey of issuing CA). 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 =item * P_X509_CRL_add_revoked_serial_hex B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Adds given serial number $serial_hex to X509_CRL object $crl. 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 - removeFromCRL =item * P_X509_CRL_get_serial B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Returns serial number of X509_CRL object. 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) =item * P_X509_CRL_set_serial B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.7 Sets serial number of X509_CRL object to $crl_number. 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 =item * P_X509_CRL_add_extensions B not available in Net-SSLeay-1.88 and before Adds one or more X509 extensions to X509 CRL object $x. 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 sertting NID_authority_key_identifier) # $nid - NID identifying extension to be set # $value - extension value # # returns: 1 on success, 0 on failure For more details see L. =back =head3 Low level API: X509_EXTENSION_* related functions =over =item * X509_EXTENSION_get_critical B not available in Net-SSLeay-1.45 and before Returns 'critical' flag of 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 =item * X509_EXTENSION_get_data B not available in Net-SSLeay-1.45 and before Returns value (raw data) of X509_EXTENSION object $ne. 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) Note: you can use L to convert ASN1_OCTET_STRING into perl scalar variable. =item * X509_EXTENSION_get_object B not available in Net-SSLeay-1.45 and before Returns OID (ASN1_OBJECT) of X509_EXTENSION object $ne. 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) =item * X509V3_EXT_print B not available in Net-SSLeay-1.45 and before Returns string representation of given X509_EXTENSION object $ext. 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 =item * X509V3_EXT_d2i Parses an extension and returns its internal structure. my $rv = Net::SSLeay::X509V3_EXT_d2i($ext); # $ext - value corresponding to openssl's X509_EXTENSION structure # # returns: pointer ??? =back =head3 Low level API: X509_NAME_* related functions =over =item * X509_NAME_ENTRY_get_data B not available in Net-SSLeay-1.45 and before Retrieves the field value of $ne in and ASN1_STRING structure. 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 openssl doc L =item * X509_NAME_ENTRY_get_object B not available in Net-SSLeay-1.45 and before Retrieves the field name of $ne in and ASN1_OBJECT structure. 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 openssl doc L =item * X509_NAME_new B not available in Net-SSLeay-1.55 and before; requires at least openssl-0.9.5 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) =item * X509_NAME_hash B not available in Net-SSLeay-1.55 and before; requires at least openssl-0.9.5 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 =item * X509_NAME_add_entry_by_txt B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.5 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 non-ascii (unicode) string in $bytes do not forget to set C<$flags = &Net::SSLeay::MBSTRING_UTF8> and encode the perl $string via C<$bytes = encode('utf-8', $string)>. Check openssl doc L =item * X509_NAME_add_entry_by_NID B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.5 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 openssl doc L =item * X509_NAME_add_entry_by_OBJ B not available in Net-SSLeay-1.45 and before; requires at least openssl-0.9.5 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 openssl doc L =item * X509_NAME_cmp B not available in Net-SSLeay-1.45 and before Compares two X509_NAME obejcts. 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 =item * X509_NAME_digest B 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); =item * X509_NAME_entry_count B 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 openssl doc L =item * X509_NAME_get_entry B 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 C. 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 openssl doc L =item * X509_NAME_print_ex B 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 Most likely you will be fine with default: Net::SSLeay::X509_NAME_print_ex($name, &Net::SSLeay::XN_FLAG_RFC2253); Or you might want RFC2253-like output without utf8 chars escaping: 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 L =item * X509_NAME_get_text_by_NID Retrieves the text from the first entry in name which matches $nid, if no such entry exists -1 is returned. B 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. 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 L =item * X509_NAME_oneline Return an ASCII version of $name. Net::SSLeay::X509_NAME_oneline($name); # $name - value corresponding to openssl's X509_NAME structure # # returns: (string) ASCII version of $name Check openssl doc L =item * sk_X509_NAME_free Free an allocated STACK_OF(X509_NAME) structure. Net::SSLeay::sk_X509_NAME_free($sk); # $sk - value corresponding to openssl's STACK_OF(X509_NAME) structure # # returns: no return value =item * sk_X509_NAME_num Return number of items in STACK_OF(X509_NAME) my $rv = Net::SSLeay::sk_X509_NAME_num($sk); # $sk - value corresponding to openssl's STACK_OF(X509_NAME) structure # # returns: number of items =item * sk_X509_NAME_value Returns X509_NAME from position $index in STACK_OF(X509_NAME) 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) =item * add_file_cert_subjects_to_stack Add a file of certs to a stack. All certs in $file that are not already in the $stackCAs will be added. 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 =item * add_dir_cert_subjects_to_stack Add a directory of certs to a stack. All certs in $dir that are not already in the $stackCAs will be added. 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 =back =head3 Low level API: X509_STORE_* related functions =over =item * X509_STORE_CTX_new returns a newly initialised X509_STORE_CTX structure. =item * X509_STORE_CTX_init X509_STORE_CTX_init() sets up an X509_STORE_CTX for a subsequent verification operation. It must be called before each call to X509_verify_cert(). 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. Check openssl doc L =item * X509_STORE_CTX_free Frees an X509_STORE_CTX structure. Net::SSLeay::X509_STORE_CTX_free($x509_store_ctx); # $x509_store_ctx - value corresponding to openssl's X509_STORE_CTX structure =item * X509_verify_cert The X509_verify_cert() function attempts to discover and validate a certificate chain based on parameters in ctx. A complete description of the process is contained in the verify(1) manual page. If this function returns 0, use X509_STORE_CTX_get_error to get additional error information. 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 L =item * X509_STORE_CTX_get_current_cert Returns the certificate in ctx which caused the error or 0 if no certificate is relevant. 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 L =item * X509_STORE_CTX_get0_cert B: not available in Net-SSLeay-1.88 and before; requires at least OpenSSL 1.1.0pre6 or LibreSSL 2.7.0 Returns an internal pointer to the certificate being verified by the ctx. 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 L =item * X509_STORE_CTX_get1_chain Returns a returns a complete validate chain if a previous call to X509_verify_cert() is successful. 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 L =item * X509_STORE_CTX_get_error Returns the error code of $ctx. 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 erro code values check function L. Check openssl doc L =item * X509_STORE_CTX_get_error_depth Returns the depth of the error. This is a non-negative integer representing where in the certificate chain the error occurred. If it is zero it occurred in the end entity certificate, one if it is the certificate which signed the end entity certificate and so on. 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 L =item * X509_STORE_CTX_get_ex_data Is used to retrieve the information for $idx from $x509_store_ctx. 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 ??? =item * X509_STORE_CTX_set_ex_data Is used to store application data at arg for idx into $x509_store_ctx. 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 =item * X509_STORE_CTX_set_cert Sets the certificate to be verified in $x509_store_ctx to $x. 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 L =item * X509_STORE_new Returns a newly initialized X509_STORE structure. my $rv = Net::SSLeay::X509_STORE_new(); # # returns: value corresponding to openssl's X509_STORE structure (0 on failure) =item * X509_STORE_free Frees an X509_STORE structure Net::SSLeay::X509_STORE_free($x509_store); # $x509_store - value corresponding to openssl's X509_STORE structure =item * X509_STORE_add_lookup Adds a lookup to an X509_STORE for a given lookup method. 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 openssl doc L =item * X509_STORE_CTX_set_error Sets the error code of $ctx to $s. For example it might be used in a verification callback to set an error based on additional checks. 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 openssl doc L =item * X509_STORE_add_cert Adds X509 certificate $x into the X509_STORE $store. 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 =item * X509_STORE_add_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 =item * X509_STORE_set1_param ??? (more info needed) 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 =item * X509_LOOKUP_hash_dir Returns an X509_LOOKUP structure that instructs an X509_STORE to load files from a directory containing certificates with filenames in the format I or crls with filenames in the format IBI my $rv = Net::SSLeay::X509_LOOKUP_hash_dir(); # # returns: value corresponding to openssl's X509_LOOKUP_METHOD structure, with the hashed directory method Check openssl doc L =item * X509_LOOKUP_add_dir Add a directory to an X509_LOOKUP structure, usually obtained from X509_STORE_add_lookup. 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 =item * X509_STORE_set_flags 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 details about $flags bitmask see L. =item * X509_STORE_set_purpose 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 For more details about $purpose identifier check L. =item * X509_STORE_set_trust 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 For more details about $trust identifier check L. =back =head3 Low Level API: X509_INFO related functions =over =item * sk_X509_INFO_num Returns the number of values in a STACK_OF(X509_INFO) structure. 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 =item * sk_X509_INFO_value Returns the value of a STACK_OF(X509_INFO) structure at a given index. 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 =item * P_X509_INFO_get_x509 Returns the X509 structure stored in an X509_INFO structure. 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 =back =head3 Low level API: X509_VERIFY_PARAM_* related functions =over =item * X509_VERIFY_PARAM_add0_policy Enables policy checking (it is disabled by default) and adds $policy to the acceptable policy set. 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 openssl doc L =item * X509_VERIFY_PARAM_add0_table ??? (more info needed) 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 =item * X509_VERIFY_PARAM_add1_host B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta2 or LibreSSL 2.7.0 Adds an additional reference identifier that can match the peer's certificate. 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 See also OpenSSL docs, L and L for more information, including wildcard matching. Check openssl doc L =item * X509_VERIFY_PARAM_clear_flags Clears the flags $flags in param. 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 details about $flags bitmask see L. Check openssl doc L =item * X509_VERIFY_PARAM_free Frees up the X509_VERIFY_PARAM structure. Net::SSLeay::X509_VERIFY_PARAM_free($param); # $param - value corresponding to openssl's X509_VERIFY_PARAM structure # # returns: no return value =item * X509_VERIFY_PARAM_get0_peername B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta2 or LibreSSL 2.7.0 Returns the DNS hostname or subject CommonName from the peer certificate that matched one of the reference identifiers. 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 openssl doc L =item * X509_VERIFY_PARAM_get_depth Returns the current verification depth. my $rv = Net::SSLeay::X509_VERIFY_PARAM_get_depth($param); # $param - value corresponding to openssl's X509_VERIFY_PARAM structure # # returns: (ineger) depth Check openssl doc L =item * X509_VERIFY_PARAM_get_flags Returns the current verification flags. 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 details about returned flags bitmask see L. Check openssl doc L =item * X509_VERIFY_PARAM_set_flags 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 details about $flags bitmask, see the OpenSSL docs below. Check openssl doc L =item * X509_VERIFY_PARAM_inherit ??? (more info needed) 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 =item * X509_VERIFY_PARAM_lookup Finds X509_VERIFY_PARAM by name. 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) =item * X509_VERIFY_PARAM_new Creates a new X509_VERIFY_PARAM structure. my $rv = Net::SSLeay::X509_VERIFY_PARAM_new(); # # returns: value corresponding to openssl's X509_VERIFY_PARAM structure (0 on failure) =item * X509_VERIFY_PARAM_set1 Sets the name of X509_VERIFY_PARAM structure $to to the same value as the name of X509_VERIFY_PARAM structure $from. 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 =item * X509_VERIFY_PARAM_set1_email B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Sets the expected RFC822 email address to email. 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 L =item * X509_VERIFY_PARAM_set1_host B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Sets the expected DNS hostname to name clearing any previously specified host name or names. 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, L and L for more information, including wildcard matching. Check openssl doc L =item * X509_VERIFY_PARAM_set1_ip B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Sets the expected IP address to ip. 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 L =item * X509_VERIFY_PARAM_set1_ip_asc B not available in Net-SSLeay-1.82 and before; requires at least OpenSSL 1.0.2-beta1 or LibreSSL 2.7.0 Sets the expected IP address to ipasc. 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 L =item * X509_VERIFY_PARAM_set1_name Sets the name of X509_VERIFY_PARAM structure $param to $name. 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 =item * X509_VERIFY_PARAM_set1_policies Enables policy checking (it is disabled by default) and sets the acceptable policy set to policies. Any existing policy set is cleared. The policies parameter can be 0 to clear an existing policy set. 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 L =item * X509_VERIFY_PARAM_set_depth Sets the maximum verification depth to depth. That is the maximum number of untrusted CA certificates that can appear in a chain. 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 L =item * X509_VERIFY_PARAM_set_hostflags B 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, L and L for more information. The flags for controlling wildcard checks and other features are defined in OpenSSL docs. Check openssl doc L =item * X509_VERIFY_PARAM_set_purpose Sets the verification purpose in $param to $purpose. This determines the acceptable purpose of the certificate chain, for example SSL client or SSL server. 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 $purpose identifier check L. Check openssl doc L =item * X509_VERIFY_PARAM_set_time Sets the verification time in $param to $t. Normally the current time is used. 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 L =item * X509_VERIFY_PARAM_set_trust Sets the trust setting in $param to $trust. 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 $trust identifier check L. Check openssl doc L =item * X509_VERIFY_PARAM_table_cleanup ??? (more info needed) Net::SSLeay::X509_VERIFY_PARAM_table_cleanup(); # # returns: no return value =back =head3 Low level API: Cipher (EVP_CIPHER_*) related functions =over =item * EVP_get_cipherbyname B not available in Net-SSLeay-1.45 and before Returns an EVP_CIPHER structure when passed a cipher name. 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 L =back =head3 Low level API: Digest (EVP_MD_*) related functions =over =item * OpenSSL_add_all_digests B not available in Net-SSLeay-1.42 and before Net::SSLeay::OpenSSL_add_all_digests(); # no args, no return value http://www.openssl.org/docs/crypto/OpenSSL_add_all_algorithms.html =item * P_EVP_MD_list_all B not available in Net-SSLeay-1.42 and before; requires at least openssl-1.0.0 B 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 The returned digest names correspond to values expected by L. Note that some of the digests are available by default and some only after calling L. =item * EVP_get_digestbyname B 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 better check the supported digests by calling L. =item * EVP_MD_type B 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 =item * EVP_MD_size B 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) =item * EVP_MD_CTX_md B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 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 =item * EVP_MD_CTX_create B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Allocates, initializes and returns a digest context. 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: 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 =item * EVP_DigestInit_ex B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Sets up digest context $ctx to use a digest $type from ENGINE $impl, $ctx must be initialized before calling this function, type will typically be supplied by a function such as L. If $impl is 0 then the default implementation of digest $type is used. 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 =item * EVP_DigestInit B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Behaves in the same way as L except the passed context $ctx does not have to be initialized, and it always uses the default digest implementation. 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 =item * EVP_MD_CTX_destroy B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Cleans up digest context $ctx and frees up the space allocated to it, it should be called only on a context created using L. Net::SSLeay::EVP_MD_CTX_destroy($ctx); # $ctx - value corresponding to openssl's EVP_MD_CTX structure # # returns: no return value =item * EVP_DigestUpdate B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 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 =item * EVP_DigestFinal_ex B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Retrieves the digest value from $ctx. After calling L no additional calls to L can be made, but L can be called to initialize a new digest operation. 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); =item * EVP_DigestFinal B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Similar to L except the digest context ctx is automatically cleaned up. 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); =item * MD2 B no supported by default in openssl-1.0.0 Computes MD2 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::MD2($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * MD4 Computes MD4 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::MD4($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * MD5 Computes MD5 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::MD5($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * RIPEMD160 Computes RIPEMD160 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::RIPEMD160($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * SHA1 B not available in Net-SSLeay-1.42 and before Computes SHA1 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::SHA1($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * SHA256 B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.8 Computes SHA256 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::SHA256($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * SHA512 B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.8 Computes SHA512 from given $data (all data needs to be loaded into memory) my $digest = Net::SSLeay::SHA512($data); print "digest(hexadecimal)=", unpack('H*', $digest); =item * EVP_Digest B not available in Net-SSLeay-1.42 and before; requires at least openssl-0.9.7 Computes "any" digest from given $data (all data needs to be loaded into memory) 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); =item * EVP_sha1 B not available in Net-SSLeay-1.42 and before my $md = Net::SSLeay::EVP_sha1(); # # returns: value corresponding to openssl's EVP_MD structure =item * EVP_sha256 B requires at least openssl-0.9.8 my $md = Net::SSLeay::EVP_sha256(); # # returns: value corresponding to openssl's EVP_MD structure =item * EVP_sha512 B 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 =item * EVP_add_digest my $rv = Net::SSLeay::EVP_add_digest($digest); # $digest - value corresponding to openssl's EVP_MD structure # # returns: 1 on success, 0 otherwise =back =head3 Low level API: CIPHER_* related functions =over =item * CIPHER_get_name B not available in Net-SSLeay-1.42 and before Returns name of the cipher used. 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 L Example: my $ssl_cipher = Net::SSLeay::get_current_cipher($ssl); my $cipher_name = Net::SSLeay::CIPHER_get_name($ssl_cipher); =item * CIPHER_description B doesn't work correctly in Net-SSLeay-1.88 and before Returns a textual description of the cipher used. 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 L =item * CIPHER_get_bits B $alg_bits doesn't work correctly in Net-SSLeay-1.88 and before Returns the number of secret bits used for cipher. 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 L 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"; =item * CIPHER_get_version B 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 L =back =head3 Low level API: RSA_* related functions =over =item * 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 L =item * 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 L =item * RSA_get_key_parameters 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 SV pointers to BIGNUMs, which would need to be blessed as Crypt::OpenSSL::Bignum for further use my (@params) = RSA_get_key_parameters($r); =back =head3 Low level API: BIO_* related functions =over =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * 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 L =item * BIO_read Read the underlying descriptor. 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 L =item * BIO_write Attempts to write data from $buffer to BIO $b. 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 L =item * BIO_s_mem Return the memory BIO method function. my $rv = Net::SSLeay::BIO_s_mem(); # # returns: value corresponding to openssl's BIO_METHOD structure (0 on failure) Check openssl doc L =item * BIO_ssl_copy_session_id Copies an SSL session id between BIO chains from and to. It does this by locating the SSL BIOs in each chain and calling SSL_copy_session_id() on the internal SSL pointer. 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 L =item * BIO_ssl_shutdown Closes down an SSL connection on BIO chain bio. It does this by locating the SSL BIO in the chain and calling SSL_shutdown() on its internal SSL pointer. Net::SSLeay::BIO_ssl_shutdown($ssl_bio); # $ssl_bio - value corresponding to openssl's BIO structure # # returns: no return value Check openssl doc L =back =head3 Low level API: Server side Server Name Indication (SNI) support =over =item * set_tlsext_host_name TBA =item * get_servername TBA =item * get_servername_type TBA =item * CTX_set_tlsext_servername_callback B requires at least OpenSSL 0.9.8f This function is used in a server to support Server side Server Name Indication (SNI). 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); =back =head3 Low level API: NPN (next protocol negotiation) related functions 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. 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 } =over =item * CTX_set_next_proto_select_cb B not available in Net-SSLeay-1.45 and before; requires at least openssl-1.0.1 B You need CTX_set_next_proto_select_cb on B 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); =item * CTX_set_next_protos_advertised_cb B not available in Net-SSLeay-1.45 and before; requires at least openssl-1.0.1 B You need CTX_set_next_proto_select_cb on B of SSL connection. 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); =item * P_next_proto_negotiated B not available in Net-SSLeay-1.45 and before; requires at least openssl-1.0.1 Returns the name of negotiated protocol for given SSL connection $ssl. $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) =item * P_next_proto_last_status B not available in Net-SSLeay-1.45 and before; requires at least openssl-1.0.1 Returns the result of the last negotiation for given SSL connection $ssl. $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 =back =head3 Low level API: ALPN (application layer protocol negotiation) related functions Application protocol can be negotiated via two different mechanisms employing two different TLS extensions: NPN (obsolete) and ALPN (recommended). The API is rather similar, with slight differences reflecting protocol specifics. In particular, with ALPN the protocol negotiation takes place on server, while with NPN the client implements the protocol negotiation logic. With ALPN, the most basic implementation 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_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 Advanced approach allows you to implement your own negotiation algorithm. #see below documentation for: Net::SSleay::CTX_set_alpn_select_cb($ctx, $perl_callback_function, $callback_data); Detection of ALPN support (works even in older Net::SSLeay versions): use Net::SSLeay; if (exists &Net::SSLeay::P_alpn_selected) { # do ALPN stuff } =over =item * CTX_set_alpn_select_cb B not available in Net-SSLeay-1.55 and before; requires at least openssl-1.0.2 B You need CTX_set_alpn_select_cb on B of TLS 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_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): $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); =item * set_alpn_protos B not available in Net-SSLeay-1.55 and before; requires at least openssl-1.0.2 B You need set_alpn_protos on B of TLS connection. This adds list of supported application layer protocols to 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 =item * CTX_set_alpn_protos B not available in Net-SSLeay-1.55 and before; requires at least openssl-1.0.2 B You need CTX_set_alpn_protos on B of TLS connection. This adds list of supported application layer protocols to 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 =item * P_alpn_selected B not available in Net-SSLeay-1.55 and before; requires at least openssl-1.0.2 Returns the name of negotiated protocol for given TLS connection $ssl. $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) =back =head3 Low level API: DANE Support OpenSSL version 1.0.2 adds preliminary support RFC6698 Domain Authentication of Named Entities (DANE) Transport Layer Association within OpenSSL =over =item * SSL_get_tlsa_record_byname B 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); =back =head3 Low level API: Other functions =over =item * COMP_add_compression_method Adds the compression method cm with the identifier id to the list of available compression methods. This list is globally maintained for all SSL operations within this application. It cannot be set for specific SSL_CTX or SSL objects. 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 L =item * DH_free Frees the DH structure and its components. The values are erased before the memory is returned to the system. Net::SSLeay::DH_free($dh); # $dh - value corresponding to openssl's DH structure # # returns: no return value Check openssl doc L =item * FIPS_mode_set Enable or disable FIPS mode in a FIPS capable OpenSSL. Net::SSLeay:: FIPS_mode_set($enable); # $enable - (integer) 1 to enable, 0 to disable =back =head3 Low level API: EC related functions =over =item * CTX_set_tmp_ecdh TBA =item * EC_KEY_free TBA =item * EC_KEY_new_by_curve_name TBA =item * EC_KEY_generate_key Generates a EC key and returns it in a newly allocated EC_KEY structure. The EC key then can be used to create a PKEY which can be used in calls like X509_set_pubkey. 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. =item * CTX_set_ecdh_auto, set_ecdh_auto These functions 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 is automatically used for ECDH temporary keys used during key exchange. 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); =item * CTX_set1_curves_list, set1_curves_list These functions set the supported curves (in order of preference) by calling SSL_CTX_set1_curves_list or SSL_set1_curves_list respectively. For a TLS client these curves are offered to the server in the supported curves extension while on the server side these are used to determine the shared curve. 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"); =item * CTX_set1_groups_list, set1_groups_list These functions set the supported groups (in order of preference) by calling SSL_CTX_set1_groups_list or SSL_set1_groups_list respectively. 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"); =back =head3 Low level API: OSSL_LIB_CTX and OSSL_PROVIDER related functions =over =item * 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 use undef with functions that take an OSSL_LIB_CTX argument when global default library context is needed. Check openssl doc L =item * 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 Using undef loads the provider within the global default library context. my $provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'legacy'); Check openssl doc L =item * OSSL_PROVIDER_try_load Loads and initializes a provider similar to OSSL_PROVIDER_load with additional fallback control. 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 openssl doc L =item * OSSL_PROVIDER_unload Unloads the given provider. my $rv = Net::SSLeay::OSSL_PROVIDER_unload($provider); # $provider - a value corresponding to OSSL_PROVIDER # # returns: (integer) 1 on success, 0 on error Check openssl doc L =item * 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 openssl doc L =item * OSSL_PROVIDER_do_all Iterates over all loaded providers. A callback is called for each provider. 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: 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 openssl doc L =item * 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 openssl doc L =item * OSSL_PROVIDER_self_test Runs the provider's self tests. 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 openssl doc L =back =head2 Constants There are many openssl constants available in L. 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 use: use Net::SSLeay qw/NID_commonName/; print &NID_commonName; #or print NID_commonName(); #or print NID_commonName; The constants names are derived from openssl constants, however constants starting with C prefix have name with C part stripped - e.g. openssl's constant C is available as C The list of all available constant names: =for comment 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. =for start_constants ASN1_STRFLGS_ESC_CTRL OPENSSL_VERSION_STRING ASN1_STRFLGS_ESC_MSB OP_ALL ASN1_STRFLGS_ESC_QUOTE OP_ALLOW_NO_DHE_KEX ASN1_STRFLGS_RFC2253 OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION CB_ACCEPT_EXIT OP_CIPHER_SERVER_PREFERENCE CB_ACCEPT_LOOP OP_CISCO_ANYCONNECT CB_ALERT OP_COOKIE_EXCHANGE CB_CONNECT_EXIT OP_CRYPTOPRO_TLSEXT_BUG CB_CONNECT_LOOP OP_DONT_INSERT_EMPTY_FRAGMENTS CB_EXIT OP_ENABLE_MIDDLEBOX_COMPAT CB_HANDSHAKE_DONE OP_EPHEMERAL_RSA CB_HANDSHAKE_START OP_LEGACY_SERVER_CONNECT CB_LOOP OP_MICROSOFT_BIG_SSLV3_BUFFER CB_READ OP_MICROSOFT_SESS_ID_BUG CB_READ_ALERT OP_MSIE_SSLV2_RSA_PADDING CB_WRITE OP_NETSCAPE_CA_DN_BUG CB_WRITE_ALERT OP_NETSCAPE_CHALLENGE_BUG ERROR_NONE OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG ERROR_SSL OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG ERROR_SYSCALL OP_NON_EXPORT_FIRST ERROR_WANT_ACCEPT OP_NO_ANTI_REPLAY ERROR_WANT_CONNECT OP_NO_CLIENT_RENEGOTIATION ERROR_WANT_READ OP_NO_COMPRESSION ERROR_WANT_WRITE OP_NO_ENCRYPT_THEN_MAC ERROR_WANT_X509_LOOKUP OP_NO_QUERY_MTU ERROR_ZERO_RETURN OP_NO_RENEGOTIATION EVP_PKS_DSA OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION EVP_PKS_EC OP_NO_SSL_MASK EVP_PKS_RSA OP_NO_SSLv2 EVP_PKT_ENC OP_NO_SSLv3 EVP_PKT_EXCH OP_NO_TICKET EVP_PKT_EXP OP_NO_TLSv1 EVP_PKT_SIGN OP_NO_TLSv1_1 EVP_PK_DH OP_NO_TLSv1_2 EVP_PK_DSA OP_NO_TLSv1_3 EVP_PK_EC OP_PKCS1_CHECK_1 EVP_PK_RSA OP_PKCS1_CHECK_2 FILETYPE_ASN1 OP_PRIORITIZE_CHACHA FILETYPE_PEM OP_SAFARI_ECDHE_ECDSA_BUG F_CLIENT_CERTIFICATE OP_SINGLE_DH_USE F_CLIENT_HELLO OP_SINGLE_ECDH_USE F_CLIENT_MASTER_KEY OP_SSLEAY_080_CLIENT_DH_BUG F_D2I_SSL_SESSION OP_SSLREF2_REUSE_CERT_TYPE_BUG F_GET_CLIENT_FINISHED OP_TLSEXT_PADDING F_GET_CLIENT_HELLO OP_TLS_BLOCK_PADDING_BUG F_GET_CLIENT_MASTER_KEY OP_TLS_D5_BUG F_GET_SERVER_FINISHED OP_TLS_ROLLBACK_BUG F_GET_SERVER_HELLO READING F_GET_SERVER_VERIFY RECEIVED_SHUTDOWN F_I2D_SSL_SESSION RSA_3 F_READ_N RSA_F4 F_REQUEST_CERTIFICATE R_BAD_AUTHENTICATION_TYPE F_SERVER_HELLO R_BAD_CHECKSUM F_SSL_CERT_NEW R_BAD_MAC_DECODE F_SSL_GET_NEW_SESSION R_BAD_RESPONSE_ARGUMENT F_SSL_NEW R_BAD_SSL_FILETYPE F_SSL_READ R_BAD_SSL_SESSION_ID_LENGTH F_SSL_RSA_PRIVATE_DECRYPT R_BAD_STATE F_SSL_RSA_PUBLIC_ENCRYPT R_BAD_WRITE_RETRY F_SSL_SESSION_NEW R_CHALLENGE_IS_DIFFERENT F_SSL_SESSION_PRINT_FP R_CIPHER_TABLE_SRC_ERROR F_SSL_SET_FD R_INVALID_CHALLENGE_LENGTH F_SSL_SET_RFD R_NO_CERTIFICATE_SET F_SSL_SET_WFD R_NO_CERTIFICATE_SPECIFIED F_SSL_USE_CERTIFICATE R_NO_CIPHER_LIST F_SSL_USE_CERTIFICATE_ASN1 R_NO_CIPHER_MATCH F_SSL_USE_CERTIFICATE_FILE R_NO_PRIVATEKEY F_SSL_USE_PRIVATEKEY R_NO_PUBLICKEY F_SSL_USE_PRIVATEKEY_ASN1 R_NULL_SSL_CTX F_SSL_USE_PRIVATEKEY_FILE R_PEER_DID_NOT_RETURN_A_CERTIFICATE F_SSL_USE_RSAPRIVATEKEY R_PEER_ERROR F_SSL_USE_RSAPRIVATEKEY_ASN1 R_PEER_ERROR_CERTIFICATE F_SSL_USE_RSAPRIVATEKEY_FILE R_PEER_ERROR_NO_CIPHER F_WRITE_PENDING R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE GEN_DIRNAME R_PUBLIC_KEY_ENCRYPT_ERROR GEN_DNS R_PUBLIC_KEY_IS_NOT_RSA GEN_EDIPARTY R_READ_WRONG_PACKET_TYPE GEN_EMAIL R_SHORT_READ GEN_IPADD R_SSL_SESSION_ID_IS_DIFFERENT GEN_OTHERNAME R_UNABLE_TO_EXTRACT_PUBLIC_KEY GEN_RID R_UNKNOWN_REMOTE_ERROR_TYPE GEN_URI R_UNKNOWN_STATE GEN_X400 R_X509_LIB LIBRESSL_VERSION_NUMBER SENT_SHUTDOWN MBSTRING_ASC SESSION_ASN1_VERSION MBSTRING_BMP SESS_CACHE_BOTH MBSTRING_FLAG SESS_CACHE_CLIENT MBSTRING_UNIV SESS_CACHE_NO_AUTO_CLEAR MBSTRING_UTF8 SESS_CACHE_NO_INTERNAL MIN_RSA_MODULUS_LENGTH_IN_BYTES SESS_CACHE_NO_INTERNAL_LOOKUP MODE_ACCEPT_MOVING_WRITE_BUFFER SESS_CACHE_NO_INTERNAL_STORE MODE_AUTO_RETRY SESS_CACHE_OFF MODE_ENABLE_PARTIAL_WRITE SESS_CACHE_SERVER MODE_RELEASE_BUFFERS SSL2_MT_CLIENT_CERTIFICATE NID_OCSP_sign SSL2_MT_CLIENT_FINISHED NID_SMIMECapabilities SSL2_MT_CLIENT_HELLO NID_X500 SSL2_MT_CLIENT_MASTER_KEY NID_X509 SSL2_MT_ERROR NID_ad_OCSP SSL2_MT_REQUEST_CERTIFICATE NID_ad_ca_issuers SSL2_MT_SERVER_FINISHED NID_algorithm SSL2_MT_SERVER_HELLO NID_authority_key_identifier SSL2_MT_SERVER_VERIFY NID_basic_constraints SSL2_VERSION NID_bf_cbc SSL3_MT_CCS NID_bf_cfb64 SSL3_MT_CERTIFICATE NID_bf_ecb SSL3_MT_CERTIFICATE_REQUEST NID_bf_ofb64 SSL3_MT_CERTIFICATE_STATUS NID_cast5_cbc SSL3_MT_CERTIFICATE_URL NID_cast5_cfb64 SSL3_MT_CERTIFICATE_VERIFY NID_cast5_ecb SSL3_MT_CHANGE_CIPHER_SPEC NID_cast5_ofb64 SSL3_MT_CLIENT_HELLO NID_certBag SSL3_MT_CLIENT_KEY_EXCHANGE NID_certificate_policies SSL3_MT_ENCRYPTED_EXTENSIONS NID_client_auth SSL3_MT_END_OF_EARLY_DATA NID_code_sign SSL3_MT_FINISHED NID_commonName SSL3_MT_HELLO_REQUEST NID_countryName SSL3_MT_KEY_UPDATE NID_crlBag SSL3_MT_MESSAGE_HASH NID_crl_distribution_points SSL3_MT_NEWSESSION_TICKET NID_crl_number SSL3_MT_NEXT_PROTO NID_crl_reason SSL3_MT_SERVER_DONE NID_delta_crl SSL3_MT_SERVER_HELLO NID_des_cbc SSL3_MT_SERVER_KEY_EXCHANGE NID_des_cfb64 SSL3_MT_SUPPLEMENTAL_DATA NID_des_ecb SSL3_RT_ALERT NID_des_ede SSL3_RT_APPLICATION_DATA NID_des_ede3 SSL3_RT_CHANGE_CIPHER_SPEC NID_des_ede3_cbc SSL3_RT_HANDSHAKE NID_des_ede3_cfb64 SSL3_RT_HEADER NID_des_ede3_ofb64 SSL3_RT_INNER_CONTENT_TYPE NID_des_ede_cbc SSL3_VERSION NID_des_ede_cfb64 SSLEAY_BUILT_ON NID_des_ede_ofb64 SSLEAY_CFLAGS NID_des_ofb64 SSLEAY_DIR NID_description SSLEAY_PLATFORM NID_desx_cbc SSLEAY_VERSION NID_dhKeyAgreement ST_ACCEPT NID_dnQualifier ST_BEFORE NID_dsa ST_CONNECT NID_dsaWithSHA ST_INIT NID_dsaWithSHA1 ST_OK NID_dsaWithSHA1_2 ST_READ_BODY NID_dsa_2 ST_READ_HEADER NID_email_protect TLS1_1_VERSION NID_ext_key_usage TLS1_2_VERSION NID_ext_req TLS1_3_VERSION NID_friendlyName TLS1_VERSION NID_givenName TLSEXT_STATUSTYPE_ocsp NID_hmacWithSHA1 VERIFY_CLIENT_ONCE NID_id_ad VERIFY_FAIL_IF_NO_PEER_CERT NID_id_ce VERIFY_NONE NID_id_kp VERIFY_PEER NID_id_pbkdf2 VERIFY_POST_HANDSHAKE NID_id_pe V_OCSP_CERTSTATUS_GOOD NID_id_pkix V_OCSP_CERTSTATUS_REVOKED NID_id_qt_cps V_OCSP_CERTSTATUS_UNKNOWN NID_id_qt_unotice WRITING NID_idea_cbc X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT NID_idea_cfb64 X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS NID_idea_ecb X509_CHECK_FLAG_NEVER_CHECK_SUBJECT NID_idea_ofb64 X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS NID_info_access X509_CHECK_FLAG_NO_WILDCARDS NID_initials X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS NID_invalidity_date X509_FILETYPE_ASN1 NID_issuer_alt_name X509_FILETYPE_DEFAULT NID_keyBag X509_FILETYPE_PEM NID_key_usage X509_LOOKUP NID_localKeyID X509_PURPOSE_ANY NID_localityName X509_PURPOSE_CRL_SIGN NID_md2 X509_PURPOSE_NS_SSL_SERVER NID_md2WithRSAEncryption X509_PURPOSE_OCSP_HELPER NID_md5 X509_PURPOSE_SMIME_ENCRYPT NID_md5WithRSA X509_PURPOSE_SMIME_SIGN NID_md5WithRSAEncryption X509_PURPOSE_SSL_CLIENT NID_md5_sha1 X509_PURPOSE_SSL_SERVER NID_mdc2 X509_PURPOSE_TIMESTAMP_SIGN NID_mdc2WithRSA X509_TRUST_COMPAT NID_ms_code_com X509_TRUST_EMAIL NID_ms_code_ind X509_TRUST_OBJECT_SIGN NID_ms_ctl_sign X509_TRUST_OCSP_REQUEST NID_ms_efs X509_TRUST_OCSP_SIGN NID_ms_ext_req X509_TRUST_SSL_CLIENT NID_ms_sgc X509_TRUST_SSL_SERVER NID_name X509_TRUST_TSA NID_netscape X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH NID_netscape_base_url X509_V_ERR_AKID_SKID_MISMATCH NID_netscape_ca_policy_url X509_V_ERR_APPLICATION_VERIFICATION NID_netscape_ca_revocation_url X509_V_ERR_CA_KEY_TOO_SMALL NID_netscape_cert_extension X509_V_ERR_CA_MD_TOO_WEAK NID_netscape_cert_sequence X509_V_ERR_CERT_CHAIN_TOO_LONG NID_netscape_cert_type X509_V_ERR_CERT_HAS_EXPIRED NID_netscape_comment X509_V_ERR_CERT_NOT_YET_VALID NID_netscape_data_type X509_V_ERR_CERT_REJECTED NID_netscape_renewal_url X509_V_ERR_CERT_REVOKED NID_netscape_revocation_url X509_V_ERR_CERT_SIGNATURE_FAILURE NID_netscape_ssl_server_name X509_V_ERR_CERT_UNTRUSTED NID_ns_sgc X509_V_ERR_CRL_HAS_EXPIRED NID_organizationName X509_V_ERR_CRL_NOT_YET_VALID NID_organizationalUnitName X509_V_ERR_CRL_PATH_VALIDATION_ERROR NID_pbeWithMD2AndDES_CBC X509_V_ERR_CRL_SIGNATURE_FAILURE NID_pbeWithMD2AndRC2_CBC X509_V_ERR_DANE_NO_MATCH NID_pbeWithMD5AndCast5_CBC X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT NID_pbeWithMD5AndDES_CBC X509_V_ERR_DIFFERENT_CRL_SCOPE NID_pbeWithMD5AndRC2_CBC X509_V_ERR_EE_KEY_TOO_SMALL NID_pbeWithSHA1AndDES_CBC X509_V_ERR_EMAIL_MISMATCH NID_pbeWithSHA1AndRC2_CBC X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD NID_pbe_WithSHA1And128BitRC2_CBC X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD NID_pbe_WithSHA1And128BitRC4 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD NID_pbe_WithSHA1And2_Key_TripleDES_CBC X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD NID_pbe_WithSHA1And3_Key_TripleDES_CBC X509_V_ERR_EXCLUDED_VIOLATION NID_pbe_WithSHA1And40BitRC2_CBC X509_V_ERR_HOSTNAME_MISMATCH NID_pbe_WithSHA1And40BitRC4 X509_V_ERR_INVALID_CA NID_pbes2 X509_V_ERR_INVALID_CALL NID_pbmac1 X509_V_ERR_INVALID_EXTENSION NID_pkcs X509_V_ERR_INVALID_NON_CA NID_pkcs3 X509_V_ERR_INVALID_POLICY_EXTENSION NID_pkcs7 X509_V_ERR_INVALID_PURPOSE NID_pkcs7_data X509_V_ERR_IP_ADDRESS_MISMATCH NID_pkcs7_digest X509_V_ERR_KEYUSAGE_NO_CERTSIGN NID_pkcs7_encrypted X509_V_ERR_KEYUSAGE_NO_CRL_SIGN NID_pkcs7_enveloped X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE NID_pkcs7_signed X509_V_ERR_NO_EXPLICIT_POLICY NID_pkcs7_signedAndEnveloped X509_V_ERR_NO_VALID_SCTS NID_pkcs8ShroudedKeyBag X509_V_ERR_OCSP_CERT_UNKNOWN NID_pkcs9 X509_V_ERR_OCSP_VERIFY_FAILED NID_pkcs9_challengePassword X509_V_ERR_OCSP_VERIFY_NEEDED NID_pkcs9_contentType X509_V_ERR_OUT_OF_MEM NID_pkcs9_countersignature X509_V_ERR_PATH_LENGTH_EXCEEDED NID_pkcs9_emailAddress X509_V_ERR_PATH_LOOP NID_pkcs9_extCertAttributes X509_V_ERR_PERMITTED_VIOLATION NID_pkcs9_messageDigest X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED NID_pkcs9_signingTime X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED NID_pkcs9_unstructuredAddress X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION NID_pkcs9_unstructuredName X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN NID_private_key_usage_period X509_V_ERR_STORE_LOOKUP NID_rc2_40_cbc X509_V_ERR_SUBJECT_ISSUER_MISMATCH NID_rc2_64_cbc X509_V_ERR_SUBTREE_MINMAX NID_rc2_cbc X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 NID_rc2_cfb64 X509_V_ERR_SUITE_B_INVALID_ALGORITHM NID_rc2_ecb X509_V_ERR_SUITE_B_INVALID_CURVE NID_rc2_ofb64 X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM NID_rc4 X509_V_ERR_SUITE_B_INVALID_VERSION NID_rc4_40 X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED NID_rc5_cbc X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY NID_rc5_cfb64 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE NID_rc5_ecb X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE NID_rc5_ofb64 X509_V_ERR_UNABLE_TO_GET_CRL NID_ripemd160 X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER NID_ripemd160WithRSA X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT NID_rle_compression X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY NID_rsa X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE NID_rsaEncryption X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION NID_rsadsi X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION NID_safeContentsBag X509_V_ERR_UNNESTED_RESOURCE NID_sdsiCertificate X509_V_ERR_UNSPECIFIED NID_secretBag X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX NID_serialNumber X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE NID_server_auth X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE NID_sha X509_V_ERR_UNSUPPORTED_NAME_SYNTAX NID_sha1 X509_V_FLAG_ALLOW_PROXY_CERTS NID_sha1WithRSA X509_V_FLAG_CB_ISSUER_CHECK NID_sha1WithRSAEncryption X509_V_FLAG_CHECK_SS_SIGNATURE NID_shaWithRSAEncryption X509_V_FLAG_CRL_CHECK NID_stateOrProvinceName X509_V_FLAG_CRL_CHECK_ALL NID_subject_alt_name X509_V_FLAG_EXPLICIT_POLICY NID_subject_key_identifier X509_V_FLAG_EXTENDED_CRL_SUPPORT NID_surname X509_V_FLAG_IGNORE_CRITICAL NID_sxnet X509_V_FLAG_INHIBIT_ANY NID_time_stamp X509_V_FLAG_INHIBIT_MAP NID_title X509_V_FLAG_LEGACY_VERIFY NID_undef X509_V_FLAG_NOTIFY_POLICY NID_uniqueIdentifier X509_V_FLAG_NO_ALT_CHAINS NID_x509Certificate X509_V_FLAG_NO_CHECK_TIME NID_x509Crl X509_V_FLAG_PARTIAL_CHAIN NID_zlib_compression X509_V_FLAG_POLICY_CHECK NOTHING X509_V_FLAG_POLICY_MASK OCSP_RESPONSE_STATUS_INTERNALERROR X509_V_FLAG_SUITEB_128_LOS OCSP_RESPONSE_STATUS_MALFORMEDREQUEST X509_V_FLAG_SUITEB_128_LOS_ONLY OCSP_RESPONSE_STATUS_SIGREQUIRED X509_V_FLAG_SUITEB_192_LOS OCSP_RESPONSE_STATUS_SUCCESSFUL X509_V_FLAG_TRUSTED_FIRST OCSP_RESPONSE_STATUS_TRYLATER X509_V_FLAG_USE_CHECK_TIME OCSP_RESPONSE_STATUS_UNAUTHORIZED X509_V_FLAG_USE_DELTAS OPENSSL_BUILT_ON X509_V_FLAG_X509_STRICT OPENSSL_CFLAGS X509_V_OK OPENSSL_CPU_INFO XN_FLAG_COMPAT OPENSSL_DIR XN_FLAG_DN_REV OPENSSL_ENGINES_DIR XN_FLAG_DUMP_UNKNOWN_FIELDS OPENSSL_FULL_VERSION_STRING XN_FLAG_FN_ALIGN OPENSSL_INFO_CONFIG_DIR XN_FLAG_FN_LN OPENSSL_INFO_CPU_SETTINGS XN_FLAG_FN_MASK OPENSSL_INFO_DIR_FILENAME_SEPARATOR XN_FLAG_FN_NONE OPENSSL_INFO_DSO_EXTENSION XN_FLAG_FN_OID OPENSSL_INFO_ENGINES_DIR XN_FLAG_FN_SN OPENSSL_INFO_LIST_SEPARATOR XN_FLAG_MULTILINE OPENSSL_INFO_MODULES_DIR XN_FLAG_ONELINE OPENSSL_INFO_SEED_SOURCE XN_FLAG_RFC2253 OPENSSL_MODULES_DIR XN_FLAG_SEP_COMMA_PLUS OPENSSL_PLATFORM XN_FLAG_SEP_CPLUS_SPC OPENSSL_VERSION XN_FLAG_SEP_MASK OPENSSL_VERSION_MAJOR XN_FLAG_SEP_MULTILINE OPENSSL_VERSION_MINOR XN_FLAG_SEP_SPLUS_SPC OPENSSL_VERSION_NUMBER XN_FLAG_SPC_EQ OPENSSL_VERSION_PATCH =for end_constants =head2 INTERNAL ONLY functions (do not use these) The following functions are not intended for use from outside of L module. They might be removed, renamed or changed without prior notice in future version. Simply B! =over =item * hello =item * blength =item * constant =back =head1 EXAMPLES One very good example to look at is the implementation of C in the C file. The following 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; The following is 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. This one runs from C so it avoids 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 C and C 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 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) =head1 INSTALLATION See README and README.* in the distribution directory for installation guidance on a variety of platforms. =head1 LIMITATIONS C 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 C, 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: Net::SSLeay::ssl_write_all($ssl, $message) or die "ssl write failure"; $got = Net::SSLeay::ssl_read_all($ssl) or die "ssl read failure"; =head1 KNOWN BUGS AND CAVEATS LibreSSL versions in the 3.1 - 3.3 series contain a TLS 1.3 implementation that is not fully compatible with the libssl API, but is still advertised during protocol auto-negotiation. If you encounter problems or unexpected behaviour with SSL or SSL_CTX objects whose protocol version was automatically negotiated and libssl is provided by any of these versions of LibreSSL, it could be because the peers negotiated to use TLS 1.3 - try setting the maximum protocol version to TLS 1.2 (via C or C) before establishing the connection. The first stable LibreSSL version with a fully libssl-compatible TLS 1.3 implementation is 3.4.1. An OpenSSL bug CVE-2015-0290 "OpenSSL Multiblock Corrupted Pointer Issue" can cause POST requests of over 90kB to fail or crash. This bug is reported to be fixed in OpenSSL 1.0.2a. Autoloader emits a Argument "xxx" isn't numeric in entersub at blib/lib/Net/SSLeay.pm' warning if die_if_ssl_error is made autoloadable. If you figure out why, drop me a line. Callback set using C does not appear to work. This may well be an openssl problem (e.g. see C line 1029). Try using C 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 C and/or C (such as in Solaris platforms - but it's been suggested that 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 C or to operate insecurely if you use C. What happens is that when too much randomness is drawn from the operating system's randomness pool then randomness can temporarily be unavailable. C 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. C solves this dilemma more pragmatically by simply returning predictable "random" numbers. SomeC< /dev/urandom> emulation software however actually seems to implement C semantics. Caveat emptor. I've been pointed to two such daemons by Mik Firestone who has used them on Solaris 8: =over =item 1 Entropy Gathering Daemon (EGD) at L =item 2 Pseudo-random number generating daemon (PRNGD) at L =back 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 C (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 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 C onwards in C). 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 C function is implemented. The high level API functions use a global file handle C 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. =head1 DIAGNOSTICS =over =item Random number generator not seeded!!! B<(W)> This warning indicates that C was not able to read C or C, 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. =item open_tcp_connection: destination host not found:`server' (port 123) ($!) Name lookup for host named C failed. =item open_tcp_connection: failed `server', 123 ($!) The name was resolved, but establishing the TCP connection failed. =item 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. =item 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 =item 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 C to do just that). =back =head1 SECURITY You can mitigate some of the security vulnerabilities that might be present in your SSL/TLS application: =head2 BEAST Attack http://blogs.cisco.com/security/beat-the-beast-with-tls/ https://community.qualys.com/blogs/securitylabs/2011/10/17/mitigating-the-beast-attack-on-tls http://blog.zoller.lu/2011/09/beast-summary-tls-cbc-countermeasures.html 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: =over =item * Compile with OpenSSL versions 0.9.6d or later, which enables SSL_OP_ALL by default =item * Ensure SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is not enabled (its not enabled by default) =item * Don't support SSLv2, SSLv3 =item * Actively control the ciphers your server supports with set_cipher_list: =back Net::SSLeay::set_cipher_list($ssl, 'RC4-SHA:HIGH:!ADH'); =head2 Session Resumption http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html 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. =head2 Secure Renegotiation and DoS Attack https://community.qualys.com/blogs/securitylabs/2011/10/31/tls-renegotiation-and-denial-of-service-attacks This is not a "security flaw," it is more of a DoS vulnerability. Solutions: =over =item * Do not support SSLv2 =item * Do not set the SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION option =item * Compile with OpenSSL 0.9.8m or later =back =head1 BUGS If you encounter a problem with this module that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the code you are trying to run; =item * your operating system name and version; =item * the output of C; =item * the version of OpenSSL or LibreSSL you are using. =back =head1 AUTHOR Originally written by Sampo Kellomäki. Maintained by Florian Ragwitz between November 2005 and January 2010. Maintained by Mike McCauley between November 2005 and June 2018. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen since June 2018. =head1 COPYRIGHT Copyright (c) 1996-2003 Sampo Kellomäki Copyright (c) 2005-2010 Florian Ragwitz Copyright (c) 2005-2018 Mike McCauley Copyright (c) 2018- Chris Novakovic Copyright (c) 2018- Tuure Vartiainen Copyright (c) 2018- Heikki Vatiainen All rights reserved. =head1 LICENSE This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =head1 SEE ALSO Net::SSLeay::Handle - File handle interface ./examples - Example servers and a clients - OpenSSL source, documentation, etc openssl-users-request@openssl.org - General OpenSSL mailing list - TLS 1.0 specification - HTTP specifications - How to send password - Entropy Gathering Daemon (EGD) - pseudo-random number generating daemon (PRNGD) perl(1) perlref(1) perllol(1) perldoc ~openssl/doc/ssl/SSL_CTX_set_verify.pod Net-SSLeay-1.92/LICENSE0000644000175000001440000002127613653663747013074 0ustar csnusers The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Net-SSLeay-1.92/README.VMS0000644000175000001440000000220113326717663013370 0ustar csnusersBuilding on OpenVMS ====================== You'll need to either build and install OpenSSL from source using the authoritative sources from openssl.org or install a PCSI kit from HPE or VSI. Building against your own from-source installation currently uses SSL object libraries that will be statically linked into the Net::SSLeay shareable image. That means no updates to SSL without updating Net::SSLeay. Building against a vendor installation gives you the possibility of SSL updates without rebuilding Net::SSLeay, assuming the upgrade is binary compatible, and also gets you the possibility of vendor support if you encounter a problem that is within the SSL libraries. If you don't know what any of this means, just use whatever is already on your system (if anything) or install whatever is easiest. Once you've got a working installation of the SSL libraries, the steps to build Net::SSLeay on VMS are really the same as building any other package,and should look something like: $ gzip -d Net-SSLeay-xx.xx.tar.gz $ vmstar -xvf Net-SSLeay-xx.xx.tar $ set default [.Net-SSLeay-xx_xx] $ perl Makefile.PL $ mmk $ mmk test $ mmk install Net-SSLeay-1.92/README.OSX0000644000175000001440000000427014012250042013354 0ustar csnusersAs of 15 Jun 2015, Apply no longer ships OpenSSL with OS X: (http://lists.apple.com/archives/macnetworkprog/2015/Jun/msg00025.html) Some OS X packages and bundles install OpenSSL, typically in /opt/local if that is the case it is sufficient for you to unpack and build Net-SSLeay in the usual way: #cd to a working directory cd /Users/mikem/tmp/ # unpack net-ssleay from wherever you got it: tar zxvf /Volumes/projects/net-ssleay/trunk/Net-SSLeay-1.72.tar.gz cd Net-SSLeay-1.72 # Build it for 64 bits (default) perl Makefile.PL make make test # as root, install the compiled Net-SSLeay: make install If a working openssl is not installed already the above will fail, but you can still build your own OpenSSL to link against: (https://wiki.openssl.org/index.php/Compilation_and_Installation), and build Net-SSLeay against it: Test compilation etc in a private directory eg: #cd to a working directory cd /Users/mikem/tmp/ wd=`pwd` # unpack openssl from wherever you got it: tar zxvf /Volumes/src/openssl-1.0.2c.tar.gz cd openssl-1.0.2c # Build for 64 bits and install it in a local directory darwin64-x86_64-cc shared enable-ec_nistp_64_gcc_128 no-ssl2 no-ssl3 no-comp --prefix=$wd/openssl make make install_sw cd $wd # unpack net-ssleay from wherever you got it: tar zxvf /Volumes/projects/net-ssleay/trunk/Net-SSLeay-1.72.tar.gz cd Net-SSLeay-1.72 # Build it for 64 bits (default) OPENSSL_PREFIX=$wd/openssl perl Makefile.PL make test # You should see successful test run data and "Result: PASS" Real installation of OpenSSL and Net-SSLeay to public areas eg: #cd to a working directory cd /Users/mikem/tmp/ wd=`pwd` # unpack openssl from wherever you got it: tar zxvf /Volumes/src/openssl-1.0.2c.tar.gz cd openssl-1.0.2c # Build for 64 bits and install it in a local directory darwin64-x86_64-cc shared enable-ec_nistp_64_gcc_128 no-ssl2 no-ssl3 no-comp make sudo make install_sw cd $wd # unpack net-ssleay from wherever you got it: tar zxvf /Volumes/projects/net-ssleay/trunk/Net-SSLeay-1.72.tar.gz cd Net-SSLeay-1.72 # Build it for 64 bits (default) perl Makefile.PL make test # You should see successful test run data and "Result: PASS" # Install it, typically to /Library/Perl/5.18 or whereever sudo make install Net-SSLeay-1.92/META.yml0000644000175000001440000000243614167654753013333 0ustar csnusers--- abstract: 'Perl bindings for OpenSSL and LibreSSL' author: - 'Sampo Kellomäki ' - 'Florian Ragwitz ' - 'Mike McCauley ' - 'Chris Novakovic ' - 'Tuure Vartiainen ' - 'Heikki Vatiainen ' build_requires: Carp: '0' Config: '0' Cwd: '0' English: '0' ExtUtils::MakeMaker: '0' File::Basename: '0' File::Spec::Functions: '0' Scalar::Util: '0' SelectSaver: '0' Socket: '0' Storable: '0' Test::Builder: '0' Test::More: 0.60_01 base: '0' configure_requires: English: '0' ExtUtils::MakeMaker: '0' File::Spec::Functions: '0' Text::Wrap: '0' constant: '0' dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-SSLeay no_index: directory: - t - inc - helper_script - examples requires: MIME::Base64: '0' perl: '5.008001' resources: bugtracker: https://github.com/radiator-software/p5-net-ssleay/issues repository: git://github.com/radiator-software/p5-net-ssleay.git version: '1.92' x_serialization_backend: 'CPAN::Meta::YAML version 0.012' Net-SSLeay-1.92/typemap0000644000175000001440000000451314163136013013436 0ustar csnusersTYPEMAP SSL_METHOD * T_PTR const SSL_METHOD * T_PTR SSL_CTX * T_PTR const SSL_CTX * T_PTR SSL_SESSION * T_PTR SSL * T_PTR RSA * T_PTR DH * T_PTR EC_KEY * T_PTR const X509 * T_PTR const X509_CRL * T_PTR const X509_REQ * T_PTR const X509_NAME * T_PTR const EVP_CIPHER * T_PTR const EVP_PKEY * T_PTR const SSL * T_PTR X509 * T_PTR X509_CRL * T_PTR X509_LOOKUP * T_PTR X509_LOOKUP_METHOD * T_PTR X509_NAME * T_PTR X509_NAME_ENTRY * T_PTR X509_EXTENSION * T_PTR X509_REQ * T_PTR X509_PUBKEY * T_PTR BIGNUM * T_PTR BIO * T_PTR const BIO_METHOD * T_PTR BIO_METHOD * T_PTR EVP_PKEY * T_PTR const EVP_MD * T_PTR EVP_MD * T_PTR EVP_MD_CTX * T_PTR const EVP_MD_CTX * T_PTR CERT * T_PTR LHASH * T_PTR struct lhash_st_SSL_SESSION * T_PTR struct cert_st * T_PTR X509_STORE_CTX * T_PTR ASN1_TIME * T_PTR ASN1_OCTET_STRING * T_PTR const ASN1_INTEGER * T_PTR ASN1_INTEGER * T_PTR ASN1_STRING * T_PTR EVP_PKEY * T_PTR const char * T_PV const unsigned char * T_PV CRYPTO_EX_new * T_PTR CRYPTO_EX_dup * T_PTR CRYPTO_EX_free * T_PTR SSL_CIPHER * T_PTR const SSL_CIPHER * T_PTR int * T_PTR COMP_METHOD * T_PTR X509_INFO * T_PTR X509_STORE * T_PTR X509_NAME_STACK * T_PTR X509_VERIFY_PARAM * T_PTR const X509_VERIFY_PARAM * T_PTR X509_POLICY_LEVEL * T_PTR X509_POLICY_TREE * T_PTR X509_POLICY_NODE * T_PTR const X509_POLICY_NODE * T_PTR STACK_OF(X509) * T_PTR const STACK_OF(X509) * T_PTR STACK_OF(X509_INFO) * T_PTR const STACK_OF(X509_INFO) * T_PTR STACK_OF(X509_POLICY_NODE) * T_PTR STACK_OF(POLICYQUALINFO) * T_PTR ASN1_OBJECT * T_PTR const ASN1_OBJECT * T_PTR STACK_OF(ASN1_OBJECT) * T_PTR ENGINE * T_PTR OCSP_RESPONSE * T_PTR OCSP_REQUEST * T_PTR pem_password_cb * T_PTR generate_key_cb * T_PTR callback_ret_int * T_PTR callback_no_ret * T_PTR cb_ssl_int_int_ret_void * T_PTR cb_ssl_int_int_ret_RSA * T_PTR cb_ssl_int_int_ret_DH * T_PTR perl_filehandle_t T_PERL_IO_HANDLE OSSL_LIB_CTX * T_PTR OSSL_PROVIDER * T_PTR const OSSL_PROVIDER * T_PTR uint64_t T_UINT64 OUTPUT T_UINT64 sv_setuv($arg, (UV)$var); INPUT T_UINT64 $var = (uint64_t)SvUV($arg) T_PERL_IO_HANDLE if ($arg && SvOK($arg) && SvROK($arg)) { $var = ($type)PerlIO_fileno( IoIFP( sv_2io(SvRV($arg)) ) ); } else { $var = ($type)SvIV($arg); } Net-SSLeay-1.92/ppport.h0000644000175000001440000052540614124733135013547 0ustar csnusers#if 0 <<'SKIP'; #endif /* ---------------------------------------------------------------------- ppport.h -- Perl/Pollution/Portability Version 3.19 Automatically created by Devel::PPPort running under perl 5.014002. Do NOT edit this file directly! -- Edit PPPort_pm.PL and the includes in parts/inc/ instead. Use 'perldoc ppport.h' to view the documentation below. ---------------------------------------------------------------------- SKIP =pod =head1 NAME ppport.h - Perl/Pollution/Portability version 3.19 =head1 SYNOPSIS perl ppport.h [options] [source files] Searches current directory for files if no [source files] are given --help show short help --version show version --patch=file write one patch file with changes --copy=suffix write changed copies with suffix --diff=program use diff program and options --compat-version=version provide compatibility with Perl version --cplusplus accept C++ comments --quiet don't output anything except fatal errors --nodiag don't show diagnostics --nohints don't show hints --nochanges don't suggest changes --nofilter don't filter input files --strip strip all script and doc functionality from ppport.h --list-provided list provided API --list-unsupported list unsupported API --api-info=name show Perl API portability information =head1 COMPATIBILITY This version of F is designed to support operation with Perl installations back to 5.003, and has been tested up to 5.10.0. =head1 OPTIONS =head2 --help Display a brief usage summary. =head2 --version Display the version of F. =head2 --patch=I If this option is given, a single patch file will be created if any changes are suggested. This requires a working diff program to be installed on your system. =head2 --copy=I If this option is given, a copy of each file will be saved with the given suffix that contains the suggested changes. This does not require any external programs. Note that this does not automagially add a dot between the original filename and the suffix. If you want the dot, you have to include it in the option argument. If neither C<--patch> or C<--copy> are given, the default is to simply print the diffs for each file. This requires either C or a C program to be installed. =head2 --diff=I Manually set the diff program and options to use. The default is to use C, when installed, and output unified context diffs. =head2 --compat-version=I Tell F to check for compatibility with the given Perl version. The default is to check for compatibility with Perl version 5.003. You can use this option to reduce the output of F if you intend to be backward compatible only down to a certain Perl version. =head2 --cplusplus Usually, F will detect C++ style comments and replace them with C style comments for portability reasons. Using this option instructs F to leave C++ comments untouched. =head2 --quiet Be quiet. Don't print anything except fatal errors. =head2 --nodiag Don't output any diagnostic messages. Only portability alerts will be printed. =head2 --nohints Don't output any hints. Hints often contain useful portability notes. Warnings will still be displayed. =head2 --nochanges Don't suggest any changes. Only give diagnostic output and hints unless these are also deactivated. =head2 --nofilter Don't filter the list of input files. By default, files not looking like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped. =head2 --strip Strip all script and documentation functionality from F. This reduces the size of F dramatically and may be useful if you want to include F in smaller modules without increasing their distribution size too much. The stripped F will have a C<--unstrip> option that allows you to undo the stripping, but only if an appropriate C module is installed. =head2 --list-provided Lists the API elements for which compatibility is provided by F. Also lists if it must be explicitly requested, if it has dependencies, and if there are hints or warnings for it. =head2 --list-unsupported Lists the API elements that are known not to be supported by F and below which version of Perl they probably won't be available or work. =head2 --api-info=I Show portability information for API elements matching I. If I is surrounded by slashes, it is interpreted as a regular expression. =head1 DESCRIPTION In order for a Perl extension (XS) module to be as portable as possible across differing versions of Perl itself, certain steps need to be taken. =over 4 =item * Including this header is the first major one. This alone will give you access to a large part of the Perl API that hasn't been available in earlier Perl releases. Use perl ppport.h --list-provided to see which API elements are provided by ppport.h. =item * You should avoid using deprecated parts of the API. For example, using global Perl variables without the C prefix is deprecated. Also, some API functions used to have a C prefix. Using this form is also deprecated. You can safely use the supported API, as F will provide wrappers for older Perl versions. =item * If you use one of a few functions or variables that were not present in earlier versions of Perl, and that can't be provided using a macro, you have to explicitly request support for these functions by adding one or more C<#define>s in your source code before the inclusion of F. These functions or variables will be marked C in the list shown by C<--list-provided>. Depending on whether you module has a single or multiple files that use such functions or variables, you want either C or global variants. For a C function or variable (used only in a single source file), use: #define NEED_function #define NEED_variable For a global function or variable (used in multiple source files), use: #define NEED_function_GLOBAL #define NEED_variable_GLOBAL Note that you mustn't have more than one global request for the same function or variable in your project. Function / Variable Static Request Global Request ----------------------------------------------------------------------------------------- PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL grok_number() NEED_grok_number NEED_grok_number_GLOBAL grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL load_module() NEED_load_module NEED_load_module_GLOBAL my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL pv_display() NEED_pv_display NEED_pv_display_GLOBAL pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL vload_module() NEED_vload_module NEED_vload_module_GLOBAL vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL warner() NEED_warner NEED_warner_GLOBAL To avoid namespace conflicts, you can change the namespace of the explicitly exported functions / variables using the C macro. Just C<#define> the macro before including C: #define DPPP_NAMESPACE MyOwnNamespace_ #include "ppport.h" The default namespace is C. =back The good thing is that most of the above can be checked by running F on your source code. See the next section for details. =head1 EXAMPLES To verify whether F is needed for your module, whether you should make any changes to your code, and whether any special defines should be used, F can be run as a Perl script to check your source code. Simply say: perl ppport.h The result will usually be a list of patches suggesting changes that should at least be acceptable, if not necessarily the most efficient solution, or a fix for all possible problems. If you know that your XS module uses features only available in newer Perl releases, if you're aware that it uses C++ comments, and if you want all suggestions as a single patch file, you could use something like this: perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff If you only want your code to be scanned without any suggestions for changes, use: perl ppport.h --nochanges You can specify a different C program or options, using the C<--diff> option: perl ppport.h --diff='diff -C 10' This would output context diffs with 10 lines of context. If you want to create patched copies of your files instead, use: perl ppport.h --copy=.new To display portability information for the C function, use: perl ppport.h --api-info=newSVpvn Since the argument to C<--api-info> can be a regular expression, you can use perl ppport.h --api-info=/_nomg$/ to display portability information for all C<_nomg> functions or perl ppport.h --api-info=/./ to display information for all known API elements. =head1 BUGS If this version of F is causing failure during the compilation of this module, please check if newer versions of either this module or C are available on CPAN before sending a bug report. If F was generated using the latest version of C and is causing failure of this module, please file a bug report using the CPAN Request Tracker at L. Please include the following information: =over 4 =item 1. The complete output from running "perl -V" =item 2. This file. =item 3. The name and version of the module you were trying to build. =item 4. A full log of the build that failed. =item 5. Any other information that you think could be relevant. =back For the latest version of this code, please get the C module from CPAN. =head1 COPYRIGHT Version 3.x, Copyright (c) 2004-2009, Marcus Holland-Moritz. Version 2.x, Copyright (C) 2001, Paul Marquess. Version 1.x, Copyright (C) 1999, Kenneth Albanowski. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO See L. =cut use strict; # Disable broken TRIE-optimization BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } my $VERSION = 3.19; my %opt = ( quiet => 0, diag => 1, hints => 1, changes => 1, cplusplus => 0, filter => 1, strip => 0, version => 0, ); my($ppport) = $0 =~ /([\w.]+)$/; my $LF = '(?:\r\n|[\r\n])'; # line feed my $HS = "[ \t]"; # horizontal whitespace # Never use C comments in this file! my $ccs = '/'.'*'; my $cce = '*'.'/'; my $rccs = quotemeta $ccs; my $rcce = quotemeta $cce; eval { require Getopt::Long; Getopt::Long::GetOptions(\%opt, qw( help quiet diag! filter! hints! changes! cplusplus strip version patch=s copy=s diff=s compat-version=s list-provided list-unsupported api-info=s )) or usage(); }; if ($@ and grep /^-/, @ARGV) { usage() if "@ARGV" =~ /^--?h(?:elp)?$/; die "Getopt::Long not found. Please don't use any options.\n"; } if ($opt{version}) { print "This is $0 $VERSION.\n"; exit 0; } usage() if $opt{help}; strip() if $opt{strip}; if (exists $opt{'compat-version'}) { my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) }; if ($@) { die "Invalid version number format: '$opt{'compat-version'}'\n"; } die "Only Perl 5 is supported\n" if $r != 5; die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000; $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s; } else { $opt{'compat-version'} = 5; } my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/ ? ( $1 => { ($2 ? ( base => $2 ) : ()), ($3 ? ( todo => $3 ) : ()), (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()), (index($4, 'p') >= 0 ? ( provided => 1 ) : ()), (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()), } ) : die "invalid spec: $_" } qw( AvFILLp|5.004050||p AvFILL||| CLASS|||n CPERLscope|5.005000||p CX_CURPAD_SAVE||| CX_CURPAD_SV||| CopFILEAV|5.006000||p CopFILEGV_set|5.006000||p CopFILEGV|5.006000||p CopFILESV|5.006000||p CopFILE_set|5.006000||p CopFILE|5.006000||p CopSTASHPV_set|5.006000||p CopSTASHPV|5.006000||p CopSTASH_eq|5.006000||p CopSTASH_set|5.006000||p CopSTASH|5.006000||p CopyD|5.009002||p Copy||| CvPADLIST||| CvSTASH||| CvWEAKOUTSIDE||| DEFSV_set|5.011000||p DEFSV|5.004050||p END_EXTERN_C|5.005000||p ENTER||| ERRSV|5.004050||p EXTEND||| EXTERN_C|5.005000||p F0convert|||n FREETMPS||| GIMME_V||5.004000|n GIMME|||n GROK_NUMERIC_RADIX|5.007002||p G_ARRAY||| G_DISCARD||| G_EVAL||| G_METHOD|5.006001||p G_NOARGS||| G_SCALAR||| G_VOID||5.004000| GetVars||| GvSVn|5.009003||p GvSV||| Gv_AMupdate||| HEf_SVKEY||5.004000| HeHASH||5.004000| HeKEY||5.004000| HeKLEN||5.004000| HePV||5.004000| HeSVKEY_force||5.004000| HeSVKEY_set||5.004000| HeSVKEY||5.004000| HeUTF8||5.011000| HeVAL||5.004000| HvNAMELEN_get|5.009003||p HvNAME_get|5.009003||p HvNAME||| INT2PTR|5.006000||p IN_LOCALE_COMPILETIME|5.007002||p IN_LOCALE_RUNTIME|5.007002||p IN_LOCALE|5.007002||p IN_PERL_COMPILETIME|5.008001||p IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p IS_NUMBER_INFINITY|5.007002||p IS_NUMBER_IN_UV|5.007002||p IS_NUMBER_NAN|5.007003||p IS_NUMBER_NEG|5.007002||p IS_NUMBER_NOT_INT|5.007002||p IVSIZE|5.006000||p IVTYPE|5.006000||p IVdf|5.006000||p LEAVE||| LVRET||| MARK||| MULTICALL||5.011000| MY_CXT_CLONE|5.009002||p MY_CXT_INIT|5.007003||p MY_CXT|5.007003||p MoveD|5.009002||p Move||| NOOP|5.005000||p NUM2PTR|5.006000||p NVTYPE|5.006000||p NVef|5.006001||p NVff|5.006001||p NVgf|5.006001||p Newxc|5.009003||p Newxz|5.009003||p Newx|5.009003||p Nullav||| Nullch||| Nullcv||| Nullhv||| Nullsv||| ORIGMARK||| PAD_BASE_SV||| PAD_CLONE_VARS||| PAD_COMPNAME_FLAGS||| PAD_COMPNAME_GEN_set||| PAD_COMPNAME_GEN||| PAD_COMPNAME_OURSTASH||| PAD_COMPNAME_PV||| PAD_COMPNAME_TYPE||| PAD_DUP||| PAD_RESTORE_LOCAL||| PAD_SAVE_LOCAL||| PAD_SAVE_SETNULLPAD||| PAD_SETSV||| PAD_SET_CUR_NOSAVE||| PAD_SET_CUR||| PAD_SVl||| PAD_SV||| PERLIO_FUNCS_CAST|5.009003||p PERLIO_FUNCS_DECL|5.009003||p PERL_ABS|5.008001||p PERL_BCDVERSION|5.011000||p PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p PERL_HASH|5.004000||p PERL_INT_MAX|5.004000||p PERL_INT_MIN|5.004000||p PERL_LONG_MAX|5.004000||p PERL_LONG_MIN|5.004000||p PERL_MAGIC_arylen|5.007002||p PERL_MAGIC_backref|5.007002||p PERL_MAGIC_bm|5.007002||p PERL_MAGIC_collxfrm|5.007002||p PERL_MAGIC_dbfile|5.007002||p PERL_MAGIC_dbline|5.007002||p PERL_MAGIC_defelem|5.007002||p PERL_MAGIC_envelem|5.007002||p PERL_MAGIC_env|5.007002||p PERL_MAGIC_ext|5.007002||p PERL_MAGIC_fm|5.007002||p PERL_MAGIC_glob|5.011000||p PERL_MAGIC_isaelem|5.007002||p PERL_MAGIC_isa|5.007002||p PERL_MAGIC_mutex|5.011000||p PERL_MAGIC_nkeys|5.007002||p PERL_MAGIC_overload_elem|5.007002||p PERL_MAGIC_overload_table|5.007002||p PERL_MAGIC_overload|5.007002||p PERL_MAGIC_pos|5.007002||p PERL_MAGIC_qr|5.007002||p PERL_MAGIC_regdata|5.007002||p PERL_MAGIC_regdatum|5.007002||p PERL_MAGIC_regex_global|5.007002||p PERL_MAGIC_shared_scalar|5.007003||p PERL_MAGIC_shared|5.007003||p PERL_MAGIC_sigelem|5.007002||p PERL_MAGIC_sig|5.007002||p PERL_MAGIC_substr|5.007002||p PERL_MAGIC_sv|5.007002||p PERL_MAGIC_taint|5.007002||p PERL_MAGIC_tiedelem|5.007002||p PERL_MAGIC_tiedscalar|5.007002||p PERL_MAGIC_tied|5.007002||p PERL_MAGIC_utf8|5.008001||p PERL_MAGIC_uvar_elem|5.007003||p PERL_MAGIC_uvar|5.007002||p PERL_MAGIC_vec|5.007002||p PERL_MAGIC_vstring|5.008001||p PERL_PV_ESCAPE_ALL|5.009004||p PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p PERL_PV_ESCAPE_NOCLEAR|5.009004||p PERL_PV_ESCAPE_QUOTE|5.009004||p PERL_PV_ESCAPE_RE|5.009005||p PERL_PV_ESCAPE_UNI_DETECT|5.009004||p PERL_PV_ESCAPE_UNI|5.009004||p PERL_PV_PRETTY_DUMP|5.009004||p PERL_PV_PRETTY_ELLIPSES|5.010000||p PERL_PV_PRETTY_LTGT|5.009004||p PERL_PV_PRETTY_NOCLEAR|5.010000||p PERL_PV_PRETTY_QUOTE|5.009004||p PERL_PV_PRETTY_REGPROP|5.009004||p PERL_QUAD_MAX|5.004000||p PERL_QUAD_MIN|5.004000||p PERL_REVISION|5.006000||p PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p PERL_SCAN_DISALLOW_PREFIX|5.007003||p PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p PERL_SCAN_SILENT_ILLDIGIT|5.008001||p PERL_SHORT_MAX|5.004000||p PERL_SHORT_MIN|5.004000||p PERL_SIGNALS_UNSAFE_FLAG|5.008001||p PERL_SUBVERSION|5.006000||p PERL_SYS_INIT3||5.006000| PERL_SYS_INIT||| PERL_SYS_TERM||5.011000| PERL_UCHAR_MAX|5.004000||p PERL_UCHAR_MIN|5.004000||p PERL_UINT_MAX|5.004000||p PERL_UINT_MIN|5.004000||p PERL_ULONG_MAX|5.004000||p PERL_ULONG_MIN|5.004000||p PERL_UNUSED_ARG|5.009003||p PERL_UNUSED_CONTEXT|5.009004||p PERL_UNUSED_DECL|5.007002||p PERL_UNUSED_VAR|5.007002||p PERL_UQUAD_MAX|5.004000||p PERL_UQUAD_MIN|5.004000||p PERL_USE_GCC_BRACE_GROUPS|5.009004||p PERL_USHORT_MAX|5.004000||p PERL_USHORT_MIN|5.004000||p PERL_VERSION|5.006000||p PL_DBsignal|5.005000||p PL_DBsingle|||pn PL_DBsub|||pn PL_DBtrace|||pn PL_Sv|5.005000||p PL_bufend|5.011000||p PL_bufptr|5.011000||p PL_compiling|5.004050||p PL_copline|5.011000||p PL_curcop|5.004050||p PL_curstash|5.004050||p PL_debstash|5.004050||p PL_defgv|5.004050||p PL_diehook|5.004050||p PL_dirty|5.004050||p PL_dowarn|||pn PL_errgv|5.004050||p PL_error_count|5.011000||p PL_expect|5.011000||p PL_hexdigit|5.005000||p PL_hints|5.005000||p PL_in_my_stash|5.011000||p PL_in_my|5.011000||p PL_last_in_gv|||n PL_laststatval|5.005000||p PL_lex_state|5.011000||p PL_lex_stuff|5.011000||p PL_linestr|5.011000||p PL_modglobal||5.005000|n PL_na|5.004050||pn PL_no_modify|5.006000||p PL_ofsgv|||n PL_parser|5.009005||p PL_perl_destruct_level|5.004050||p PL_perldb|5.004050||p PL_ppaddr|5.006000||p PL_rsfp_filters|5.004050||p PL_rsfp|5.004050||p PL_rs|||n PL_signals|5.008001||p PL_stack_base|5.004050||p PL_stack_sp|5.004050||p PL_statcache|5.005000||p PL_stdingv|5.004050||p PL_sv_arenaroot|5.004050||p PL_sv_no|5.004050||pn PL_sv_undef|5.004050||pn PL_sv_yes|5.004050||pn PL_tainted|5.004050||p PL_tainting|5.004050||p PL_tokenbuf|5.011000||p POP_MULTICALL||5.011000| POPi|||n POPl|||n POPn|||n POPpbytex||5.007001|n POPpx||5.005030|n POPp|||n POPs|||n PTR2IV|5.006000||p PTR2NV|5.006000||p PTR2UV|5.006000||p PTR2nat|5.009003||p PTR2ul|5.007001||p PTRV|5.006000||p PUSHMARK||| PUSH_MULTICALL||5.011000| PUSHi||| PUSHmortal|5.009002||p PUSHn||| PUSHp||| PUSHs||| PUSHu|5.004000||p PUTBACK||| PerlIO_clearerr||5.007003| PerlIO_close||5.007003| PerlIO_context_layers||5.009004| PerlIO_eof||5.007003| PerlIO_error||5.007003| PerlIO_fileno||5.007003| PerlIO_fill||5.007003| PerlIO_flush||5.007003| PerlIO_get_base||5.007003| PerlIO_get_bufsiz||5.007003| PerlIO_get_cnt||5.007003| PerlIO_get_ptr||5.007003| PerlIO_read||5.007003| PerlIO_seek||5.007003| PerlIO_set_cnt||5.007003| PerlIO_set_ptrcnt||5.007003| PerlIO_setlinebuf||5.007003| PerlIO_stderr||5.007003| PerlIO_stdin||5.007003| PerlIO_stdout||5.007003| PerlIO_tell||5.007003| PerlIO_unread||5.007003| PerlIO_write||5.007003| Perl_signbit||5.009005|n PoisonFree|5.009004||p PoisonNew|5.009004||p PoisonWith|5.009004||p Poison|5.008000||p RETVAL|||n Renewc||| Renew||| SAVECLEARSV||| SAVECOMPPAD||| SAVEPADSV||| SAVETMPS||| SAVE_DEFSV|5.004050||p SPAGAIN||| SP||| START_EXTERN_C|5.005000||p START_MY_CXT|5.007003||p STMT_END|||p STMT_START|||p STR_WITH_LEN|5.009003||p ST||| SV_CONST_RETURN|5.009003||p SV_COW_DROP_PV|5.008001||p SV_COW_SHARED_HASH_KEYS|5.009005||p SV_GMAGIC|5.007002||p SV_HAS_TRAILING_NUL|5.009004||p SV_IMMEDIATE_UNREF|5.007001||p SV_MUTABLE_RETURN|5.009003||p SV_NOSTEAL|5.009002||p SV_SMAGIC|5.009003||p SV_UTF8_NO_ENCODING|5.008001||p SVfARG|5.009005||p SVf_UTF8|5.006000||p SVf|5.006000||p SVt_IV||| SVt_NV||| SVt_PVAV||| SVt_PVCV||| SVt_PVHV||| SVt_PVMG||| SVt_PV||| Safefree||| Slab_Alloc||| Slab_Free||| Slab_to_rw||| StructCopy||| SvCUR_set||| SvCUR||| SvEND||| SvGAMAGIC||5.006001| SvGETMAGIC|5.004050||p SvGROW||| SvIOK_UV||5.006000| SvIOK_notUV||5.006000| SvIOK_off||| SvIOK_only_UV||5.006000| SvIOK_only||| SvIOK_on||| SvIOKp||| SvIOK||| SvIVX||| SvIV_nomg|5.009001||p SvIV_set||| SvIVx||| SvIV||| SvIsCOW_shared_hash||5.008003| SvIsCOW||5.008003| SvLEN_set||| SvLEN||| SvLOCK||5.007003| SvMAGIC_set|5.009003||p SvNIOK_off||| SvNIOKp||| SvNIOK||| SvNOK_off||| SvNOK_only||| SvNOK_on||| SvNOKp||| SvNOK||| SvNVX||| SvNV_set||| SvNVx||| SvNV||| SvOK||| SvOOK_offset||5.011000| SvOOK||| SvPOK_off||| SvPOK_only_UTF8||5.006000| SvPOK_only||| SvPOK_on||| SvPOKp||| SvPOK||| SvPVX_const|5.009003||p SvPVX_mutable|5.009003||p SvPVX||| SvPV_const|5.009003||p SvPV_flags_const_nolen|5.009003||p SvPV_flags_const|5.009003||p SvPV_flags_mutable|5.009003||p SvPV_flags|5.007002||p SvPV_force_flags_mutable|5.009003||p SvPV_force_flags_nolen|5.009003||p SvPV_force_flags|5.007002||p SvPV_force_mutable|5.009003||p SvPV_force_nolen|5.009003||p SvPV_force_nomg_nolen|5.009003||p SvPV_force_nomg|5.007002||p SvPV_force|||p SvPV_mutable|5.009003||p SvPV_nolen_const|5.009003||p SvPV_nolen|5.006000||p SvPV_nomg_const_nolen|5.009003||p SvPV_nomg_const|5.009003||p SvPV_nomg|5.007002||p SvPV_renew|5.009003||p SvPV_set||| SvPVbyte_force||5.009002| SvPVbyte_nolen||5.006000| SvPVbytex_force||5.006000| SvPVbytex||5.006000| SvPVbyte|5.006000||p SvPVutf8_force||5.006000| SvPVutf8_nolen||5.006000| SvPVutf8x_force||5.006000| SvPVutf8x||5.006000| SvPVutf8||5.006000| SvPVx||| SvPV||| SvREFCNT_dec||| SvREFCNT_inc_NN|5.009004||p SvREFCNT_inc_simple_NN|5.009004||p SvREFCNT_inc_simple_void_NN|5.009004||p SvREFCNT_inc_simple_void|5.009004||p SvREFCNT_inc_simple|5.009004||p SvREFCNT_inc_void_NN|5.009004||p SvREFCNT_inc_void|5.009004||p SvREFCNT_inc|||p SvREFCNT||| SvROK_off||| SvROK_on||| SvROK||| SvRV_set|5.009003||p SvRV||| SvRXOK||5.009005| SvRX||5.009005| SvSETMAGIC||| SvSHARED_HASH|5.009003||p SvSHARE||5.007003| SvSTASH_set|5.009003||p SvSTASH||| SvSetMagicSV_nosteal||5.004000| SvSetMagicSV||5.004000| SvSetSV_nosteal||5.004000| SvSetSV||| SvTAINTED_off||5.004000| SvTAINTED_on||5.004000| SvTAINTED||5.004000| SvTAINT||| SvTRUE||| SvTYPE||| SvUNLOCK||5.007003| SvUOK|5.007001|5.006000|p SvUPGRADE||| SvUTF8_off||5.006000| SvUTF8_on||5.006000| SvUTF8||5.006000| SvUVXx|5.004000||p SvUVX|5.004000||p SvUV_nomg|5.009001||p SvUV_set|5.009003||p SvUVx|5.004000||p SvUV|5.004000||p SvVOK||5.008001| SvVSTRING_mg|5.009004||p THIS|||n UNDERBAR|5.009002||p UTF8_MAXBYTES|5.009002||p UVSIZE|5.006000||p UVTYPE|5.006000||p UVXf|5.007001||p UVof|5.006000||p UVuf|5.006000||p UVxf|5.006000||p WARN_ALL|5.006000||p WARN_AMBIGUOUS|5.006000||p WARN_ASSERTIONS|5.011000||p WARN_BAREWORD|5.006000||p WARN_CLOSED|5.006000||p WARN_CLOSURE|5.006000||p WARN_DEBUGGING|5.006000||p WARN_DEPRECATED|5.006000||p WARN_DIGIT|5.006000||p WARN_EXEC|5.006000||p WARN_EXITING|5.006000||p WARN_GLOB|5.006000||p WARN_INPLACE|5.006000||p WARN_INTERNAL|5.006000||p WARN_IO|5.006000||p WARN_LAYER|5.008000||p WARN_MALLOC|5.006000||p WARN_MISC|5.006000||p WARN_NEWLINE|5.006000||p WARN_NUMERIC|5.006000||p WARN_ONCE|5.006000||p WARN_OVERFLOW|5.006000||p WARN_PACK|5.006000||p WARN_PARENTHESIS|5.006000||p WARN_PIPE|5.006000||p WARN_PORTABLE|5.006000||p WARN_PRECEDENCE|5.006000||p WARN_PRINTF|5.006000||p WARN_PROTOTYPE|5.006000||p WARN_QW|5.006000||p WARN_RECURSION|5.006000||p WARN_REDEFINE|5.006000||p WARN_REGEXP|5.006000||p WARN_RESERVED|5.006000||p WARN_SEMICOLON|5.006000||p WARN_SEVERE|5.006000||p WARN_SIGNAL|5.006000||p WARN_SUBSTR|5.006000||p WARN_SYNTAX|5.006000||p WARN_TAINT|5.006000||p WARN_THREADS|5.008000||p WARN_UNINITIALIZED|5.006000||p WARN_UNOPENED|5.006000||p WARN_UNPACK|5.006000||p WARN_UNTIE|5.006000||p WARN_UTF8|5.006000||p WARN_VOID|5.006000||p XCPT_CATCH|5.009002||p XCPT_RETHROW|5.009002||p XCPT_TRY_END|5.009002||p XCPT_TRY_START|5.009002||p XPUSHi||| XPUSHmortal|5.009002||p XPUSHn||| XPUSHp||| XPUSHs||| XPUSHu|5.004000||p XSPROTO|5.010000||p XSRETURN_EMPTY||| XSRETURN_IV||| XSRETURN_NO||| XSRETURN_NV||| XSRETURN_PV||| XSRETURN_UNDEF||| XSRETURN_UV|5.008001||p XSRETURN_YES||| XSRETURN|||p XST_mIV||| XST_mNO||| XST_mNV||| XST_mPV||| XST_mUNDEF||| XST_mUV|5.008001||p XST_mYES||| XS_VERSION_BOOTCHECK||| XS_VERSION||| XSprePUSH|5.006000||p XS||| ZeroD|5.009002||p Zero||| _aMY_CXT|5.007003||p _pMY_CXT|5.007003||p aMY_CXT_|5.007003||p aMY_CXT|5.007003||p aTHXR_|5.011000||p aTHXR|5.011000||p aTHX_|5.006000||p aTHX|5.006000||p add_data|||n addmad||| allocmy||| amagic_call||| amagic_cmp_locale||| amagic_cmp||| amagic_i_ncmp||| amagic_ncmp||| any_dup||| ao||| append_elem||| append_list||| append_madprops||| apply_attrs_my||| apply_attrs_string||5.006001| apply_attrs||| apply||| atfork_lock||5.007003|n atfork_unlock||5.007003|n av_arylen_p||5.009003| av_clear||| av_create_and_push||5.009005| av_create_and_unshift_one||5.009005| av_delete||5.006000| av_exists||5.006000| av_extend||| av_fetch||| av_fill||| av_iter_p||5.011000| av_len||| av_make||| av_pop||| av_push||| av_reify||| av_shift||| av_store||| av_undef||| av_unshift||| ax|||n bad_type||| bind_match||| block_end||| block_gimme||5.004000| block_start||| boolSV|5.004000||p boot_core_PerlIO||| boot_core_UNIVERSAL||| boot_core_mro||| bytes_from_utf8||5.007001| bytes_to_uni|||n bytes_to_utf8||5.006001| call_argv|5.006000||p call_atexit||5.006000| call_list||5.004000| call_method|5.006000||p call_pv|5.006000||p call_sv|5.006000||p calloc||5.007002|n cando||| cast_i32||5.006000| cast_iv||5.006000| cast_ulong||5.006000| cast_uv||5.006000| check_type_and_open||| check_uni||| checkcomma||| checkposixcc||| ckWARN|5.006000||p ck_anoncode||| ck_bitop||| ck_concat||| ck_defined||| ck_delete||| ck_die||| ck_each||| ck_eof||| ck_eval||| ck_exec||| ck_exists||| ck_exit||| ck_ftst||| ck_fun||| ck_glob||| ck_grep||| ck_index||| ck_join||| ck_lfun||| ck_listiob||| ck_match||| ck_method||| ck_null||| ck_open||| ck_readline||| ck_repeat||| ck_require||| ck_return||| ck_rfun||| ck_rvconst||| ck_sassign||| ck_select||| ck_shift||| ck_sort||| ck_spair||| ck_split||| ck_subr||| ck_substr||| ck_svconst||| ck_trunc||| ck_unpack||| ckwarn_d||5.009003| ckwarn||5.009003| cl_and|||n cl_anything|||n cl_init_zero|||n cl_init|||n cl_is_anything|||n cl_or|||n clear_placeholders||| closest_cop||| convert||| cop_free||| cr_textfilter||| create_eval_scope||| croak_nocontext|||vn croak_xs_usage||5.011000| croak|||v csighandler||5.009003|n curmad||| custom_op_desc||5.007003| custom_op_name||5.007003| cv_ckproto_len||| cv_clone||| cv_const_sv||5.004000| cv_dump||| cv_undef||| cx_dump||5.005000| cx_dup||| cxinc||| dAXMARK|5.009003||p dAX|5.007002||p dITEMS|5.007002||p dMARK||| dMULTICALL||5.009003| dMY_CXT_SV|5.007003||p dMY_CXT|5.007003||p dNOOP|5.006000||p dORIGMARK||| dSP||| dTHR|5.004050||p dTHXR|5.011000||p dTHXa|5.006000||p dTHXoa|5.006000||p dTHX|5.006000||p dUNDERBAR|5.009002||p dVAR|5.009003||p dXCPT|5.009002||p dXSARGS||| dXSI32||| dXSTARG|5.006000||p deb_curcv||| deb_nocontext|||vn deb_stack_all||| deb_stack_n||| debop||5.005000| debprofdump||5.005000| debprof||| debstackptrs||5.007003| debstack||5.007003| debug_start_match||| deb||5.007003|v del_sv||| delete_eval_scope||| delimcpy||5.004000| deprecate_old||| deprecate||| despatch_signals||5.007001| destroy_matcher||| die_nocontext|||vn die_where||| die|||v dirp_dup||| div128||| djSP||| do_aexec5||| do_aexec||| do_aspawn||| do_binmode||5.004050| do_chomp||| do_chop||| do_close||| do_dump_pad||| do_eof||| do_exec3||| do_execfree||| do_exec||| do_gv_dump||5.006000| do_gvgv_dump||5.006000| do_hv_dump||5.006000| do_ipcctl||| do_ipcget||| do_join||| do_kv||| do_magic_dump||5.006000| do_msgrcv||| do_msgsnd||| do_oddball||| do_op_dump||5.006000| do_op_xmldump||| do_open9||5.006000| do_openn||5.007001| do_open||5.004000| do_pmop_dump||5.006000| do_pmop_xmldump||| do_print||| do_readline||| do_seek||| do_semop||| do_shmio||| do_smartmatch||| do_spawn_nowait||| do_spawn||| do_sprintf||| do_sv_dump||5.006000| do_sysseek||| do_tell||| do_trans_complex_utf8||| do_trans_complex||| do_trans_count_utf8||| do_trans_count||| do_trans_simple_utf8||| do_trans_simple||| do_trans||| do_vecget||| do_vecset||| do_vop||| docatch||| doeval||| dofile||| dofindlabel||| doform||| doing_taint||5.008001|n dooneliner||| doopen_pm||| doparseform||| dopoptoeval||| dopoptogiven||| dopoptolabel||| dopoptoloop||| dopoptosub_at||| dopoptowhen||| doref||5.009003| dounwind||| dowantarray||| dump_all||5.006000| dump_eval||5.006000| dump_exec_pos||| dump_fds||| dump_form||5.006000| dump_indent||5.006000|v dump_mstats||| dump_packsubs||5.006000| dump_sub||5.006000| dump_sv_child||| dump_trie_interim_list||| dump_trie_interim_table||| dump_trie||| dump_vindent||5.006000| dumpuntil||| dup_attrlist||| emulate_cop_io||| eval_pv|5.006000||p eval_sv|5.006000||p exec_failed||| expect_number||| fbm_compile||5.005000| fbm_instr||5.005000| feature_is_enabled||| fetch_cop_label||5.011000| filter_add||| filter_del||| filter_gets||| filter_read||| find_and_forget_pmops||| find_array_subscript||| find_beginning||| find_byclass||| find_hash_subscript||| find_in_my_stash||| find_runcv||5.008001| find_rundefsvoffset||5.009002| find_script||| find_uninit_var||| first_symbol|||n fold_constants||| forbid_setid||| force_ident||| force_list||| force_next||| force_version||| force_word||| forget_pmop||| form_nocontext|||vn form||5.004000|v fp_dup||| fprintf_nocontext|||vn free_global_struct||| free_tied_hv_pool||| free_tmps||| gen_constant_list||| get_arena||| get_aux_mg||| get_av|5.006000||p get_context||5.006000|n get_cvn_flags||5.009005| get_cv|5.006000||p get_db_sub||| get_debug_opts||| get_hash_seed||| get_hv|5.006000||p get_isa_hash||| get_mstats||| get_no_modify||| get_num||| get_op_descs||5.005000| get_op_names||5.005000| get_opargs||| get_ppaddr||5.006000| get_re_arg||| get_sv|5.006000||p get_vtbl||5.005030| getcwd_sv||5.007002| getenv_len||| glob_2number||| glob_assign_glob||| glob_assign_ref||| gp_dup||| gp_free||| gp_ref||| grok_bin|5.007003||p grok_hex|5.007003||p grok_number|5.007002||p grok_numeric_radix|5.007002||p grok_oct|5.007003||p group_end||| gv_AVadd||| gv_HVadd||| gv_IOadd||| gv_SVadd||| gv_autoload4||5.004000| gv_check||| gv_const_sv||5.009003| gv_dump||5.006000| gv_efullname3||5.004000| gv_efullname4||5.006001| gv_efullname||| gv_ename||| gv_fetchfile_flags||5.009005| gv_fetchfile||| gv_fetchmeth_autoload||5.007003| gv_fetchmethod_autoload||5.004000| gv_fetchmethod_flags||5.011000| gv_fetchmethod||| gv_fetchmeth||| gv_fetchpvn_flags|5.009002||p gv_fetchpvs|5.009004||p gv_fetchpv||| gv_fetchsv||5.009002| gv_fullname3||5.004000| gv_fullname4||5.006001| gv_fullname||| gv_get_super_pkg||| gv_handler||5.007001| gv_init_sv||| gv_init||| gv_name_set||5.009004| gv_stashpvn|5.004000||p gv_stashpvs|5.009003||p gv_stashpv||| gv_stashsv||| he_dup||| hek_dup||| hfreeentries||| hsplit||| hv_assert||5.011000| hv_auxinit|||n hv_backreferences_p||| hv_clear_placeholders||5.009001| hv_clear||| hv_common_key_len||5.010000| hv_common||5.010000| hv_copy_hints_hv||| hv_delayfree_ent||5.004000| hv_delete_common||| hv_delete_ent||5.004000| hv_delete||| hv_eiter_p||5.009003| hv_eiter_set||5.009003| hv_exists_ent||5.004000| hv_exists||| hv_fetch_ent||5.004000| hv_fetchs|5.009003||p hv_fetch||| hv_free_ent||5.004000| hv_iterinit||| hv_iterkeysv||5.004000| hv_iterkey||| hv_iternext_flags||5.008000| hv_iternextsv||| hv_iternext||| hv_iterval||| hv_kill_backrefs||| hv_ksplit||5.004000| hv_magic_check|||n hv_magic||| hv_name_set||5.009003| hv_notallowed||| hv_placeholders_get||5.009003| hv_placeholders_p||5.009003| hv_placeholders_set||5.009003| hv_riter_p||5.009003| hv_riter_set||5.009003| hv_scalar||5.009001| hv_store_ent||5.004000| hv_store_flags||5.008000| hv_stores|5.009004||p hv_store||| hv_undef||| ibcmp_locale||5.004000| ibcmp_utf8||5.007003| ibcmp||| incline||| incpush_if_exists||| incpush_use_sep||| incpush||| ingroup||| init_argv_symbols||| init_debugger||| init_global_struct||| init_i18nl10n||5.006000| init_i18nl14n||5.006000| init_ids||| init_interp||| init_main_stash||| init_perllib||| init_postdump_symbols||| init_predump_symbols||| init_stacks||5.005000| init_tm||5.007002| instr||| intro_my||| intuit_method||| intuit_more||| invert||| io_close||| isALNUMC|5.006000||p isALNUM||| isALPHA||| isASCII|5.006000||p isBLANK|5.006001||p isCNTRL|5.006000||p isDIGIT||| isGRAPH|5.006000||p isGV_with_GP|5.009004||p isLOWER||| isPRINT|5.004000||p isPSXSPC|5.006001||p isPUNCT|5.006000||p isSPACE||| isUPPER||| isXDIGIT|5.006000||p is_an_int||| is_gv_magical_sv||| is_handle_constructor|||n is_list_assignment||| is_lvalue_sub||5.007001| is_uni_alnum_lc||5.006000| is_uni_alnumc_lc||5.006000| is_uni_alnumc||5.006000| is_uni_alnum||5.006000| is_uni_alpha_lc||5.006000| is_uni_alpha||5.006000| is_uni_ascii_lc||5.006000| is_uni_ascii||5.006000| is_uni_cntrl_lc||5.006000| is_uni_cntrl||5.006000| is_uni_digit_lc||5.006000| is_uni_digit||5.006000| is_uni_graph_lc||5.006000| is_uni_graph||5.006000| is_uni_idfirst_lc||5.006000| is_uni_idfirst||5.006000| is_uni_lower_lc||5.006000| is_uni_lower||5.006000| is_uni_print_lc||5.006000| is_uni_print||5.006000| is_uni_punct_lc||5.006000| is_uni_punct||5.006000| is_uni_space_lc||5.006000| is_uni_space||5.006000| is_uni_upper_lc||5.006000| is_uni_upper||5.006000| is_uni_xdigit_lc||5.006000| is_uni_xdigit||5.006000| is_utf8_alnumc||5.006000| is_utf8_alnum||5.006000| is_utf8_alpha||5.006000| is_utf8_ascii||5.006000| is_utf8_char_slow|||n is_utf8_char||5.006000| is_utf8_cntrl||5.006000| is_utf8_common||| is_utf8_digit||5.006000| is_utf8_graph||5.006000| is_utf8_idcont||5.008000| is_utf8_idfirst||5.006000| is_utf8_lower||5.006000| is_utf8_mark||5.006000| is_utf8_print||5.006000| is_utf8_punct||5.006000| is_utf8_space||5.006000| is_utf8_string_loclen||5.009003| is_utf8_string_loc||5.008001| is_utf8_string||5.006001| is_utf8_upper||5.006000| is_utf8_xdigit||5.006000| isa_lookup||| items|||n ix|||n jmaybe||| join_exact||| keyword||| leave_scope||| lex_end||| lex_start||| linklist||| listkids||| list||| load_module_nocontext|||vn load_module|5.006000||pv localize||| looks_like_bool||| looks_like_number||| lop||| mPUSHi|5.009002||p mPUSHn|5.009002||p mPUSHp|5.009002||p mPUSHs|5.011000||p mPUSHu|5.009002||p mXPUSHi|5.009002||p mXPUSHn|5.009002||p mXPUSHp|5.009002||p mXPUSHs|5.011000||p mXPUSHu|5.009002||p mad_free||| madlex||| madparse||| magic_clear_all_env||| magic_clearenv||| magic_clearhint||| magic_clearisa||| magic_clearpack||| magic_clearsig||| magic_dump||5.006000| magic_existspack||| magic_freearylen_p||| magic_freeovrld||| magic_getarylen||| magic_getdefelem||| magic_getnkeys||| magic_getpack||| magic_getpos||| magic_getsig||| magic_getsubstr||| magic_gettaint||| magic_getuvar||| magic_getvec||| magic_get||| magic_killbackrefs||| magic_len||| magic_methcall||| magic_methpack||| magic_nextpack||| magic_regdata_cnt||| magic_regdatum_get||| magic_regdatum_set||| magic_scalarpack||| magic_set_all_env||| magic_setamagic||| magic_setarylen||| magic_setcollxfrm||| magic_setdbline||| magic_setdefelem||| magic_setenv||| magic_sethint||| magic_setisa||| magic_setmglob||| magic_setnkeys||| magic_setpack||| magic_setpos||| magic_setregexp||| magic_setsig||| magic_setsubstr||| magic_settaint||| magic_setutf8||| magic_setuvar||| magic_setvec||| magic_set||| magic_sizepack||| magic_wipepack||| make_matcher||| make_trie_failtable||| make_trie||| malloc_good_size|||n malloced_size|||n malloc||5.007002|n markstack_grow||| matcher_matches_sv||| measure_struct||| memEQ|5.004000||p memNE|5.004000||p mem_collxfrm||| mem_log_common|||n mess_alloc||| mess_nocontext|||vn mess||5.006000|v method_common||| mfree||5.007002|n mg_clear||| mg_copy||| mg_dup||| mg_find||| mg_free||| mg_get||| mg_length||5.005000| mg_localize||| mg_magical||| mg_set||| mg_size||5.005000| mini_mktime||5.007002| missingterm||| mode_from_discipline||| modkids||| mod||| more_bodies||| more_sv||| moreswitches||| mro_get_from_name||5.011000| mro_get_linear_isa_dfs||| mro_get_linear_isa||5.009005| mro_get_private_data||5.011000| mro_isa_changed_in||| mro_meta_dup||| mro_meta_init||| mro_method_changed_in||5.009005| mro_register||5.011000| mro_set_mro||5.011000| mro_set_private_data||5.011000| mul128||| mulexp10|||n my_atof2||5.007002| my_atof||5.006000| my_attrs||| my_bcopy|||n my_betoh16|||n my_betoh32|||n my_betoh64|||n my_betohi|||n my_betohl|||n my_betohs|||n my_bzero|||n my_chsize||| my_clearenv||| my_cxt_index||| my_cxt_init||| my_dirfd||5.009005| my_exit_jump||| my_exit||| my_failure_exit||5.004000| my_fflush_all||5.006000| my_fork||5.007003|n my_htobe16|||n my_htobe32|||n my_htobe64|||n my_htobei|||n my_htobel|||n my_htobes|||n my_htole16|||n my_htole32|||n my_htole64|||n my_htolei|||n my_htolel|||n my_htoles|||n my_htonl||| my_kid||| my_letoh16|||n my_letoh32|||n my_letoh64|||n my_letohi|||n my_letohl|||n my_letohs|||n my_lstat||| my_memcmp||5.004000|n my_memset|||n my_ntohl||| my_pclose||5.004000| my_popen_list||5.007001| my_popen||5.004000| my_setenv||| my_snprintf|5.009004||pvn my_socketpair||5.007003|n my_sprintf|5.009003||pvn my_stat||| my_strftime||5.007002| my_strlcat|5.009004||pn my_strlcpy|5.009004||pn my_swabn|||n my_swap||| my_unexec||| my_vsnprintf||5.009004|n need_utf8|||n newANONATTRSUB||5.006000| newANONHASH||| newANONLIST||| newANONSUB||| newASSIGNOP||| newATTRSUB||5.006000| newAVREF||| newAV||| newBINOP||| newCONDOP||| newCONSTSUB|5.004050||p newCVREF||| newDEFSVOP||| newFORM||| newFOROP||| newGIVENOP||5.009003| newGIVWHENOP||| newGP||| newGVOP||| newGVREF||| newGVgen||| newHVREF||| newHVhv||5.005000| newHV||| newIO||| newLISTOP||| newLOGOP||| newLOOPEX||| newLOOPOP||| newMADPROP||| newMADsv||| newMYSUB||| newNULLLIST||| newOP||| newPADOP||| newPMOP||| newPROG||| newPVOP||| newRANGE||| newRV_inc|5.004000||p newRV_noinc|5.004000||p newRV||| newSLICEOP||| newSTATEOP||| newSUB||| newSVOP||| newSVREF||| newSV_type|5.009005||p newSVhek||5.009003| newSViv||| newSVnv||| newSVpvf_nocontext|||vn newSVpvf||5.004000|v newSVpvn_flags|5.011000||p newSVpvn_share|5.007001||p newSVpvn_utf8|5.011000||p newSVpvn|5.004050||p newSVpvs_flags|5.011000||p newSVpvs_share||5.009003| newSVpvs|5.009003||p newSVpv||| newSVrv||| newSVsv||| newSVuv|5.006000||p newSV||| newTOKEN||| newUNOP||| newWHENOP||5.009003| newWHILEOP||5.009003| newXS_flags||5.009004| newXSproto||5.006000| newXS||5.006000| new_collate||5.006000| new_constant||| new_ctype||5.006000| new_he||| new_logop||| new_numeric||5.006000| new_stackinfo||5.005000| new_version||5.009000| new_warnings_bitfield||| next_symbol||| nextargv||| nextchar||| ninstr||| no_bareword_allowed||| no_fh_allowed||| no_op||| not_a_number||| nothreadhook||5.008000| nuke_stacks||| num_overflow|||n offer_nice_chunk||| oopsAV||| oopsHV||| op_clear||| op_const_sv||| op_dump||5.006000| op_free||| op_getmad_weak||| op_getmad||| op_null||5.007002| op_refcnt_dec||| op_refcnt_inc||| op_refcnt_lock||5.009002| op_refcnt_unlock||5.009002| op_xmldump||| open_script||| pMY_CXT_|5.007003||p pMY_CXT|5.007003||p pTHX_|5.006000||p pTHX|5.006000||p packWARN|5.007003||p pack_cat||5.007003| pack_rec||| package||| packlist||5.008001| pad_add_anon||| pad_add_name||| pad_alloc||| pad_block_start||| pad_check_dup||| pad_compname_type||| pad_findlex||| pad_findmy||| pad_fixup_inner_anons||| pad_free||| pad_leavemy||| pad_new||| pad_peg|||n pad_push||| pad_reset||| pad_setsv||| pad_sv||5.011000| pad_swipe||| pad_tidy||| pad_undef||| parse_body||| parse_unicode_opts||| parser_dup||| parser_free||| path_is_absolute|||n peep||| pending_Slabs_to_ro||| perl_alloc_using|||n perl_alloc|||n perl_clone_using|||n perl_clone|||n perl_construct|||n perl_destruct||5.007003|n perl_free|||n perl_parse||5.006000|n perl_run|||n pidgone||| pm_description||| pmflag||| pmop_dump||5.006000| pmop_xmldump||| pmruntime||| pmtrans||| pop_scope||| pregcomp||5.009005| pregexec||| pregfree2||5.011000| pregfree||| prepend_elem||| prepend_madprops||| printbuf||| printf_nocontext|||vn process_special_blocks||| ptr_table_clear||5.009005| ptr_table_fetch||5.009005| ptr_table_find|||n ptr_table_free||5.009005| ptr_table_new||5.009005| ptr_table_split||5.009005| ptr_table_store||5.009005| push_scope||| put_byte||| pv_display|5.006000||p pv_escape|5.009004||p pv_pretty|5.009004||p pv_uni_display||5.007003| qerror||| qsortsvu||| re_compile||5.009005| re_croak2||| re_dup_guts||| re_intuit_start||5.009005| re_intuit_string||5.006000| readpipe_override||| realloc||5.007002|n reentrant_free||| reentrant_init||| reentrant_retry|||vn reentrant_size||| ref_array_or_hash||| refcounted_he_chain_2hv||| refcounted_he_fetch||| refcounted_he_free||| refcounted_he_new_common||| refcounted_he_new||| refcounted_he_value||| refkids||| refto||| ref||5.011000| reg_check_named_buff_matched||| reg_named_buff_all||5.009005| reg_named_buff_exists||5.009005| reg_named_buff_fetch||5.009005| reg_named_buff_firstkey||5.009005| reg_named_buff_iter||| reg_named_buff_nextkey||5.009005| reg_named_buff_scalar||5.009005| reg_named_buff||| reg_namedseq||| reg_node||| reg_numbered_buff_fetch||| reg_numbered_buff_length||| reg_numbered_buff_store||| reg_qr_package||| reg_recode||| reg_scan_name||| reg_skipcomment||| reg_temp_copy||| reganode||| regatom||| regbranch||| regclass_swash||5.009004| regclass||| regcppop||| regcppush||| regcurly|||n regdump_extflags||| regdump||5.005000| regdupe_internal||| regexec_flags||5.005000| regfree_internal||5.009005| reghop3|||n reghop4|||n reghopmaybe3|||n reginclass||| reginitcolors||5.006000| reginsert||| regmatch||| regnext||5.005000| regpiece||| regpposixcc||| regprop||| regrepeat||| regtail_study||| regtail||| regtry||| reguni||| regwhite|||n reg||| repeatcpy||| report_evil_fh||| report_uninit||| require_pv||5.006000| require_tie_mod||| restore_magic||| rninstr||| rsignal_restore||| rsignal_save||| rsignal_state||5.004000| rsignal||5.004000| run_body||| run_user_filter||| runops_debug||5.005000| runops_standard||5.005000| rvpv_dup||| rxres_free||| rxres_restore||| rxres_save||| safesyscalloc||5.006000|n safesysfree||5.006000|n safesysmalloc||5.006000|n safesysrealloc||5.006000|n same_dirent||| save_I16||5.004000| save_I32||| save_I8||5.006000| save_adelete||5.011000| save_aelem||5.004050| save_alloc||5.006000| save_aptr||| save_ary||| save_bool||5.008001| save_clearsv||| save_delete||| save_destructor_x||5.006000| save_destructor||5.006000| save_freeop||| save_freepv||| save_freesv||| save_generic_pvref||5.006001| save_generic_svref||5.005030| save_gp||5.004000| save_hash||| save_hek_flags|||n save_helem_flags||5.011000| save_helem||5.004050| save_hints||| save_hptr||| save_int||| save_item||| save_iv||5.005000| save_lines||| save_list||| save_long||| save_magic||| save_mortalizesv||5.007001| save_nogv||| save_op||| save_padsv_and_mortalize||5.011000| save_pptr||| save_pushi32ptr||| save_pushptri32ptr||| save_pushptrptr||| save_pushptr||5.011000| save_re_context||5.006000| save_scalar_at||| save_scalar||| save_set_svflags||5.009000| save_shared_pvref||5.007003| save_sptr||| save_svref||| save_vptr||5.006000| savepvn||| savepvs||5.009003| savepv||| savesharedpvn||5.009005| savesharedpv||5.007003| savestack_grow_cnt||5.008001| savestack_grow||| savesvpv||5.009002| sawparens||| scalar_mod_type|||n scalarboolean||| scalarkids||| scalarseq||| scalarvoid||| scalar||| scan_bin||5.006000| scan_commit||| scan_const||| scan_formline||| scan_heredoc||| scan_hex||| scan_ident||| scan_inputsymbol||| scan_num||5.007001| scan_oct||| scan_pat||| scan_str||| scan_subst||| scan_trans||| scan_version||5.009001| scan_vstring||5.009005| scan_word||| scope||| screaminstr||5.005000| search_const||| seed||5.008001| sequence_num||| sequence_tail||| sequence||| set_context||5.006000|n set_numeric_local||5.006000| set_numeric_radix||5.006000| set_numeric_standard||5.006000| setdefout||| share_hek_flags||| share_hek||5.004000| si_dup||| sighandler|||n simplify_sort||| skipspace0||| skipspace1||| skipspace2||| skipspace||| softref2xv||| sortcv_stacked||| sortcv_xsub||| sortcv||| sortsv_flags||5.009003| sortsv||5.007003| space_join_names_mortal||| ss_dup||| stack_grow||| start_force||| start_glob||| start_subparse||5.004000| stashpv_hvname_match||5.011000| stdize_locale||| store_cop_label||| strEQ||| strGE||| strGT||| strLE||| strLT||| strNE||| str_to_version||5.006000| strip_return||| strnEQ||| strnNE||| study_chunk||| sub_crush_depth||| sublex_done||| sublex_push||| sublex_start||| sv_2bool||| sv_2cv||| sv_2io||| sv_2iuv_common||| sv_2iuv_non_preserve||| sv_2iv_flags||5.009001| sv_2iv||| sv_2mortal||| sv_2num||| sv_2nv||| sv_2pv_flags|5.007002||p sv_2pv_nolen|5.006000||p sv_2pvbyte_nolen|5.006000||p sv_2pvbyte|5.006000||p sv_2pvutf8_nolen||5.006000| sv_2pvutf8||5.006000| sv_2pv||| sv_2uv_flags||5.009001| sv_2uv|5.004000||p sv_add_arena||| sv_add_backref||| sv_backoff||| sv_bless||| sv_cat_decode||5.008001| sv_catpv_mg|5.004050||p sv_catpvf_mg_nocontext|||pvn sv_catpvf_mg|5.006000|5.004000|pv sv_catpvf_nocontext|||vn sv_catpvf||5.004000|v sv_catpvn_flags||5.007002| sv_catpvn_mg|5.004050||p sv_catpvn_nomg|5.007002||p sv_catpvn||| sv_catpvs|5.009003||p sv_catpv||| sv_catsv_flags||5.007002| sv_catsv_mg|5.004050||p sv_catsv_nomg|5.007002||p sv_catsv||| sv_catxmlpvn||| sv_catxmlsv||| sv_chop||| sv_clean_all||| sv_clean_objs||| sv_clear||| sv_cmp_locale||5.004000| sv_cmp||| sv_collxfrm||| sv_compile_2op||5.008001| sv_copypv||5.007003| sv_dec||| sv_del_backref||| sv_derived_from||5.004000| sv_destroyable||5.010000| sv_does||5.009004| sv_dump||| sv_dup_inc_multiple||| sv_dup||| sv_eq||| sv_exp_grow||| sv_force_normal_flags||5.007001| sv_force_normal||5.006000| sv_free2||| sv_free_arenas||| sv_free||| sv_gets||5.004000| sv_grow||| sv_i_ncmp||| sv_inc||| sv_insert_flags||5.011000| sv_insert||| sv_isa||| sv_isobject||| sv_iv||5.005000| sv_kill_backrefs||| sv_len_utf8||5.006000| sv_len||| sv_magic_portable|5.011000|5.004000|p sv_magicext||5.007003| sv_magic||| sv_mortalcopy||| sv_ncmp||| sv_newmortal||| sv_newref||| sv_nolocking||5.007003| sv_nosharing||5.007003| sv_nounlocking||| sv_nv||5.005000| sv_peek||5.005000| sv_pos_b2u_midway||| sv_pos_b2u||5.006000| sv_pos_u2b_cached||| sv_pos_u2b_forwards|||n sv_pos_u2b_midway|||n sv_pos_u2b||5.006000| sv_pvbyten_force||5.006000| sv_pvbyten||5.006000| sv_pvbyte||5.006000| sv_pvn_force_flags|5.007002||p sv_pvn_force||| sv_pvn_nomg|5.007003|5.005000|p sv_pvn||5.005000| sv_pvutf8n_force||5.006000| sv_pvutf8n||5.006000| sv_pvutf8||5.006000| sv_pv||5.006000| sv_recode_to_utf8||5.007003| sv_reftype||| sv_release_COW||| sv_replace||| sv_report_used||| sv_reset||| sv_rvweaken||5.006000| sv_setiv_mg|5.004050||p sv_setiv||| sv_setnv_mg|5.006000||p sv_setnv||| sv_setpv_mg|5.004050||p sv_setpvf_mg_nocontext|||pvn sv_setpvf_mg|5.006000|5.004000|pv sv_setpvf_nocontext|||vn sv_setpvf||5.004000|v sv_setpviv_mg||5.008001| sv_setpviv||5.008001| sv_setpvn_mg|5.004050||p sv_setpvn||| sv_setpvs|5.009004||p sv_setpv||| sv_setref_iv||| sv_setref_nv||| sv_setref_pvn||| sv_setref_pv||| sv_setref_uv||5.007001| sv_setsv_cow||| sv_setsv_flags||5.007002| sv_setsv_mg|5.004050||p sv_setsv_nomg|5.007002||p sv_setsv||| sv_setuv_mg|5.004050||p sv_setuv|5.004000||p sv_tainted||5.004000| sv_taint||5.004000| sv_true||5.005000| sv_unglob||| sv_uni_display||5.007003| sv_unmagic||| sv_unref_flags||5.007001| sv_unref||| sv_untaint||5.004000| sv_upgrade||| sv_usepvn_flags||5.009004| sv_usepvn_mg|5.004050||p sv_usepvn||| sv_utf8_decode||5.006000| sv_utf8_downgrade||5.006000| sv_utf8_encode||5.006000| sv_utf8_upgrade_flags_grow||5.011000| sv_utf8_upgrade_flags||5.007002| sv_utf8_upgrade_nomg||5.007002| sv_utf8_upgrade||5.007001| sv_uv|5.005000||p sv_vcatpvf_mg|5.006000|5.004000|p sv_vcatpvfn||5.004000| sv_vcatpvf|5.006000|5.004000|p sv_vsetpvf_mg|5.006000|5.004000|p sv_vsetpvfn||5.004000| sv_vsetpvf|5.006000|5.004000|p sv_xmlpeek||| svtype||| swallow_bom||| swap_match_buff||| swash_fetch||5.007002| swash_get||| swash_init||5.006000| sys_init3||5.010000|n sys_init||5.010000|n sys_intern_clear||| sys_intern_dup||| sys_intern_init||| sys_term||5.010000|n taint_env||| taint_proper||| tmps_grow||5.006000| toLOWER||| toUPPER||| to_byte_substr||| to_uni_fold||5.007003| to_uni_lower_lc||5.006000| to_uni_lower||5.007003| to_uni_title_lc||5.006000| to_uni_title||5.007003| to_uni_upper_lc||5.006000| to_uni_upper||5.007003| to_utf8_case||5.007003| to_utf8_fold||5.007003| to_utf8_lower||5.007003| to_utf8_substr||| to_utf8_title||5.007003| to_utf8_upper||5.007003| token_free||| token_getmad||| tokenize_use||| tokeq||| tokereport||| too_few_arguments||| too_many_arguments||| uiv_2buf|||n unlnk||| unpack_rec||| unpack_str||5.007003| unpackstring||5.008001| unshare_hek_or_pvn||| unshare_hek||| unsharepvn||5.004000| unwind_handler_stack||| update_debugger_info||| upg_version||5.009005| usage||| utf16_to_utf8_reversed||5.006001| utf16_to_utf8||5.006001| utf8_distance||5.006000| utf8_hop||5.006000| utf8_length||5.007001| utf8_mg_pos_cache_update||| utf8_to_bytes||5.006001| utf8_to_uvchr||5.007001| utf8_to_uvuni||5.007001| utf8n_to_uvchr||| utf8n_to_uvuni||5.007001| utilize||| uvchr_to_utf8_flags||5.007003| uvchr_to_utf8||| uvuni_to_utf8_flags||5.007003| uvuni_to_utf8||5.007001| validate_suid||| varname||| vcmp||5.009000| vcroak||5.006000| vdeb||5.007003| vdie_common||| vdie_croak_common||| vdie||| vform||5.006000| visit||| vivify_defelem||| vivify_ref||| vload_module|5.006000||p vmess||5.006000| vnewSVpvf|5.006000|5.004000|p vnormal||5.009002| vnumify||5.009000| vstringify||5.009000| vverify||5.009003| vwarner||5.006000| vwarn||5.006000| wait4pid||| warn_nocontext|||vn warner_nocontext|||vn warner|5.006000|5.004000|pv warn|||v watch||| whichsig||| write_no_mem||| write_to_stderr||| xmldump_all||| xmldump_attr||| xmldump_eval||| xmldump_form||| xmldump_indent|||v xmldump_packsubs||| xmldump_sub||| xmldump_vindent||| yyerror||| yylex||| yyparse||| yywarn||| ); if (exists $opt{'list-unsupported'}) { my $f; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $API{$f}{todo}; print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; } exit 0; } # Scan for possible replacement candidates my(%replace, %need, %hints, %warnings, %depends); my $replace = 0; my($hint, $define, $function); sub find_api { my $code = shift; $code =~ s{ / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*) | "[^"\\]*(?:\\.[^"\\]*)*" | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx; grep { exists $API{$_} } $code =~ /(\w+)/mg; } while () { if ($hint) { my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings; if (m{^\s*\*\s(.*?)\s*$}) { for (@{$hint->[1]}) { $h->{$_} ||= ''; # suppress warning with older perls $h->{$_} .= "$1\n"; } } else { undef $hint } } $hint = [$1, [split /,?\s+/, $2]] if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$}; if ($define) { if ($define->[1] =~ /\\$/) { $define->[1] .= $_; } else { if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) { my @n = find_api($define->[1]); push @{$depends{$define->[0]}}, @n if @n } undef $define; } } $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)}; if ($function) { if (/^}/) { if (exists $API{$function->[0]}) { my @n = find_api($function->[1]); push @{$depends{$function->[0]}}, @n if @n } undef $function; } else { $function->[1] .= $_; } } $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)}; $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; if (m{^\s*$rccs\s+(\w+(\s*,\s*\w+)*)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { my @deps = map { s/\s+//g; $_ } split /,/, $3; my $d; for $d (map { s/\s+//g; $_ } split /,/, $1) { push @{$depends{$d}}, @deps; } } $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)}; } for (values %depends) { my %s; $_ = [sort grep !$s{$_}++, @$_]; } if (exists $opt{'api-info'}) { my $f; my $count = 0; my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $f =~ /$match/; print "\n=== $f ===\n\n"; my $info = 0; if ($API{$f}{base} || $API{$f}{todo}) { my $base = format_version($API{$f}{base} || $API{$f}{todo}); print "Supported at least starting from perl-$base.\n"; $info++; } if ($API{$f}{provided}) { my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; print "Support by $ppport provided back to perl-$todo.\n"; print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; print "\n$hints{$f}" if exists $hints{$f}; print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f}; $info++; } print "No portability information available.\n" unless $info; $count++; } $count or print "Found no API matching '$opt{'api-info'}'."; print "\n"; exit 0; } if (exists $opt{'list-provided'}) { my $f; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $API{$f}{provided}; my @flags; push @flags, 'explicit' if exists $need{$f}; push @flags, 'depend' if exists $depends{$f}; push @flags, 'hint' if exists $hints{$f}; push @flags, 'warning' if exists $warnings{$f}; my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; print "$f$flags\n"; } exit 0; } my @files; my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc ); my $srcext = join '|', map { quotemeta $_ } @srcext; if (@ARGV) { my %seen; for (@ARGV) { if (-e) { if (-f) { push @files, $_ unless $seen{$_}++; } else { warn "'$_' is not a file.\n" } } else { my @new = grep { -f } glob $_ or warn "'$_' does not exist.\n"; push @files, grep { !$seen{$_}++ } @new; } } } else { eval { require File::Find; File::Find::find(sub { $File::Find::name =~ /($srcext)$/i and push @files, $File::Find::name; }, '.'); }; if ($@) { @files = map { glob "*$_" } @srcext; } } if (!@ARGV || $opt{filter}) { my(@in, @out); my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; for (@files) { my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i; push @{ $out ? \@out : \@in }, $_; } if (@ARGV && @out) { warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); } @files = @in; } die "No input files given!\n" unless @files; my(%files, %global, %revreplace); %revreplace = reverse %replace; my $filename; my $patch_opened = 0; for $filename (@files) { unless (open IN, "<$filename") { warn "Unable to read from $filename: $!\n"; next; } info("Scanning $filename ..."); my $c = do { local $/; }; close IN; my %file = (orig => $c, changes => 0); # Temporarily remove C/XS comments and strings from the code my @ccom; $c =~ s{ ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]* | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* ) | ( ^$HS*\#[^\r\n]* | "[^"\\]*(?:\\.[^"\\]*)*" | '[^'\\]*(?:\\.[^'\\]*)*' | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) ) }{ defined $2 and push @ccom, $2; defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex; $file{ccom} = \@ccom; $file{code} = $c; $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m; my $func; for $func (keys %API) { my $match = $func; $match .= "|$revreplace{$func}" if exists $revreplace{$func}; if ($c =~ /\b(?:Perl_)?($match)\b/) { $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; if (exists $API{$func}{provided}) { $file{uses_provided}{$func}++; if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { $file{uses}{$func}++; my @deps = rec_depend($func); if (@deps) { $file{uses_deps}{$func} = \@deps; for (@deps) { $file{uses}{$_} = 0 unless exists $file{uses}{$_}; } } for ($func, @deps) { $file{needs}{$_} = 'static' if exists $need{$_}; } } } if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { if ($c =~ /\b$func\b/) { $file{uses_todo}{$func}++; } } } } while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { if (exists $need{$2}) { $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; } else { warning("Possibly wrong #define $1 in $filename") } } for (qw(uses needs uses_todo needed_global needed_static)) { for $func (keys %{$file{$_}}) { push @{$global{$_}{$func}}, $filename; } } $files{$filename} = \%file; } # Globally resolve NEED_'s my $need; for $need (keys %{$global{needs}}) { if (@{$global{needs}{$need}} > 1) { my @targets = @{$global{needs}{$need}}; my @t = grep $files{$_}{needed_global}{$need}, @targets; @targets = @t if @t; @t = grep /\.xs$/i, @targets; @targets = @t if @t; my $target = shift @targets; $files{$target}{needs}{$need} = 'global'; for (@{$global{needs}{$need}}) { $files{$_}{needs}{$need} = 'extern' if $_ ne $target; } } } for $filename (@files) { exists $files{$filename} or next; info("=== Analyzing $filename ==="); my %file = %{$files{$filename}}; my $func; my $c = $file{code}; my $warnings = 0; for $func (sort keys %{$file{uses_Perl}}) { if ($API{$func}{varargs}) { unless ($API{$func}{nothxarg}) { my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); if ($changes) { warning("Doesn't pass interpreter argument aTHX to Perl_$func"); $file{changes} += $changes; } } } else { warning("Uses Perl_$func instead of $func"); $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} {$func$1(}g); } } for $func (sort keys %{$file{uses_replace}}) { warning("Uses $func instead of $replace{$func}"); $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); } for $func (sort keys %{$file{uses_provided}}) { if ($file{uses}{$func}) { if (exists $file{uses_deps}{$func}) { diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); } else { diag("Uses $func"); } } $warnings += hint($func); } unless ($opt{quiet}) { for $func (sort keys %{$file{uses_todo}}) { print "*** WARNING: Uses $func, which may not be portable below perl ", format_version($API{$func}{todo}), ", even with '$ppport'\n"; $warnings++; } } for $func (sort keys %{$file{needed_static}}) { my $message = ''; if (not exists $file{uses}{$func}) { $message = "No need to define NEED_$func if $func is never used"; } elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { $message = "No need to define NEED_$func when already needed globally"; } if ($message) { diag($message); $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); } } for $func (sort keys %{$file{needed_global}}) { my $message = ''; if (not exists $global{uses}{$func}) { $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; } elsif (exists $file{needs}{$func}) { if ($file{needs}{$func} eq 'extern') { $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; } elsif ($file{needs}{$func} eq 'static') { $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; } } if ($message) { diag($message); $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); } } $file{needs_inc_ppport} = keys %{$file{uses}}; if ($file{needs_inc_ppport}) { my $pp = ''; for $func (sort keys %{$file{needs}}) { my $type = $file{needs}{$func}; next if $type eq 'extern'; my $suffix = $type eq 'global' ? '_GLOBAL' : ''; unless (exists $file{"needed_$type"}{$func}) { if ($type eq 'global') { diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); } else { diag("File needs $func, adding static request"); } $pp .= "#define NEED_$func$suffix\n"; } } if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { $pp = ''; $file{changes}++; } unless ($file{has_inc_ppport}) { diag("Needs to include '$ppport'"); $pp .= qq(#include "$ppport"\n) } if ($pp) { $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) || ($c =~ s/^/$pp/); } } else { if ($file{has_inc_ppport}) { diag("No need to include '$ppport'"); $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); } } # put back in our C comments my $ix; my $cppc = 0; my @ccom = @{$file{ccom}}; for $ix (0 .. $#ccom) { if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { $cppc++; $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; } else { $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; } } if ($cppc) { my $s = $cppc != 1 ? 's' : ''; warning("Uses $cppc C++ style comment$s, which is not portable"); } my $s = $warnings != 1 ? 's' : ''; my $warn = $warnings ? " ($warnings warning$s)" : ''; info("Analysis completed$warn"); if ($file{changes}) { if (exists $opt{copy}) { my $newfile = "$filename$opt{copy}"; if (-e $newfile) { error("'$newfile' already exists, refusing to write copy of '$filename'"); } else { local *F; if (open F, ">$newfile") { info("Writing copy of '$filename' with changes to '$newfile'"); print F $c; close F; } else { error("Cannot open '$newfile' for writing: $!"); } } } elsif (exists $opt{patch} || $opt{changes}) { if (exists $opt{patch}) { unless ($patch_opened) { if (open PATCH, ">$opt{patch}") { $patch_opened = 1; } else { error("Cannot open '$opt{patch}' for writing: $!"); delete $opt{patch}; $opt{changes} = 1; goto fallback; } } mydiff(\*PATCH, $filename, $c); } else { fallback: info("Suggested changes:"); mydiff(\*STDOUT, $filename, $c); } } else { my $s = $file{changes} == 1 ? '' : 's'; info("$file{changes} potentially required change$s detected"); } } else { info("Looks good"); } } close PATCH if $patch_opened; exit 0; sub try_use { eval "use @_;"; return $@ eq '' } sub mydiff { local *F = shift; my($file, $str) = @_; my $diff; if (exists $opt{diff}) { $diff = run_diff($opt{diff}, $file, $str); } if (!defined $diff and try_use('Text::Diff')) { $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); $diff = <
$tmp") { print F $str; close F; if (open F, "$prog $file $tmp |") { while () { s/\Q$tmp\E/$file.patched/; $diff .= $_; } close F; unlink $tmp; return $diff; } unlink $tmp; } else { error("Cannot open '$tmp' for writing: $!"); } return undef; } sub rec_depend { my($func, $seen) = @_; return () unless exists $depends{$func}; $seen = {%{$seen||{}}}; return () if $seen->{$func}++; my %s; grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}}; } sub parse_version { my $ver = shift; if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) { return ($1, $2, $3); } elsif ($ver !~ /^\d+\.[\d_]+$/) { die "cannot parse version '$ver'\n"; } $ver =~ s/_//g; $ver =~ s/$/000000/; my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; $v = int $v; $s = int $s; if ($r < 5 || ($r == 5 && $v < 6)) { if ($s % 10) { die "cannot parse version '$ver'\n"; } } return ($r, $v, $s); } sub format_version { my $ver = shift; $ver =~ s/$/000000/; my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; $v = int $v; $s = int $s; if ($r < 5 || ($r == 5 && $v < 6)) { if ($s % 10) { die "invalid version '$ver'\n"; } $s /= 10; $ver = sprintf "%d.%03d", $r, $v; $s > 0 and $ver .= sprintf "_%02d", $s; return $ver; } return sprintf "%d.%d.%d", $r, $v, $s; } sub info { $opt{quiet} and return; print @_, "\n"; } sub diag { $opt{quiet} and return; $opt{diag} and print @_, "\n"; } sub warning { $opt{quiet} and return; print "*** ", @_, "\n"; } sub error { print "*** ERROR: ", @_, "\n"; } my %given_hints; my %given_warnings; sub hint { $opt{quiet} and return; my $func = shift; my $rv = 0; if (exists $warnings{$func} && !$given_warnings{$func}++) { my $warn = $warnings{$func}; $warn =~ s!^!*** !mg; print "*** WARNING: $func\n", $warn; $rv++; } if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) { my $hint = $hints{$func}; $hint =~ s/^/ /mg; print " --- hint for $func ---\n", $hint; } $rv; } sub usage { my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms; my %M = ( 'I' => '*' ); $usage =~ s/^\s*perl\s+\S+/$^X $0/; $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g; print < }; my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms; $copy =~ s/^(?=\S+)/ /gms; $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms; $self =~ s/^SKIP.*(?=^__DATA__)/SKIP if (\@ARGV && \$ARGV[0] eq '--unstrip') { eval { require Devel::PPPort }; \$@ and die "Cannot require Devel::PPPort, please install.\\n"; if (eval \$Devel::PPPort::VERSION < $VERSION) { die "$0 was originally generated with Devel::PPPort $VERSION.\\n" . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n" . "Please install a newer version, or --unstrip will not work.\\n"; } Devel::PPPort::WriteFile(\$0); exit 0; } print <$0" or die "cannot strip $0: $!\n"; print OUT "$pl$c\n"; exit 0; } __DATA__ */ #ifndef _P_P_PORTABILITY_H_ #define _P_P_PORTABILITY_H_ #ifndef DPPP_NAMESPACE # define DPPP_NAMESPACE DPPP_ #endif #define DPPP_CAT2(x,y) CAT2(x,y) #define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name) #ifndef PERL_REVISION # if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION)) # define PERL_PATCHLEVEL_H_IMPLICIT # include # endif # if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) # include # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10)) #define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION)) /* It is very unlikely that anyone will try to use this with Perl 6 (or greater), but who knows. */ #if PERL_REVISION != 5 # error ppport.h only works with Perl version 5 #endif /* PERL_REVISION != 5 */ #ifndef dTHR # define dTHR dNOOP #endif #ifndef dTHX # define dTHX dNOOP #endif #ifndef dTHXa # define dTHXa(x) dNOOP #endif #ifndef pTHX # define pTHX void #endif #ifndef pTHX_ # define pTHX_ #endif #ifndef aTHX # define aTHX #endif #ifndef aTHX_ # define aTHX_ #endif #if (PERL_BCDVERSION < 0x5006000) # ifdef USE_THREADS # define aTHXR thr # define aTHXR_ thr, # else # define aTHXR # define aTHXR_ # endif # define dTHXR dTHR #else # define aTHXR aTHX # define aTHXR_ aTHX_ # define dTHXR dTHX #endif #ifndef dTHXoa # define dTHXoa(x) dTHXa(x) #endif #ifdef I_LIMITS # include #endif #ifndef PERL_UCHAR_MIN # define PERL_UCHAR_MIN ((unsigned char)0) #endif #ifndef PERL_UCHAR_MAX # ifdef UCHAR_MAX # define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) # else # ifdef MAXUCHAR # define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) # else # define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) # endif # endif #endif #ifndef PERL_USHORT_MIN # define PERL_USHORT_MIN ((unsigned short)0) #endif #ifndef PERL_USHORT_MAX # ifdef USHORT_MAX # define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) # else # ifdef MAXUSHORT # define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) # else # ifdef USHRT_MAX # define PERL_USHORT_MAX ((unsigned short)USHRT_MAX) # else # define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) # endif # endif # endif #endif #ifndef PERL_SHORT_MAX # ifdef SHORT_MAX # define PERL_SHORT_MAX ((short)SHORT_MAX) # else # ifdef MAXSHORT /* Often used in */ # define PERL_SHORT_MAX ((short)MAXSHORT) # else # ifdef SHRT_MAX # define PERL_SHORT_MAX ((short)SHRT_MAX) # else # define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) # endif # endif # endif #endif #ifndef PERL_SHORT_MIN # ifdef SHORT_MIN # define PERL_SHORT_MIN ((short)SHORT_MIN) # else # ifdef MINSHORT # define PERL_SHORT_MIN ((short)MINSHORT) # else # ifdef SHRT_MIN # define PERL_SHORT_MIN ((short)SHRT_MIN) # else # define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) # endif # endif # endif #endif #ifndef PERL_UINT_MAX # ifdef UINT_MAX # define PERL_UINT_MAX ((unsigned int)UINT_MAX) # else # ifdef MAXUINT # define PERL_UINT_MAX ((unsigned int)MAXUINT) # else # define PERL_UINT_MAX (~(unsigned int)0) # endif # endif #endif #ifndef PERL_UINT_MIN # define PERL_UINT_MIN ((unsigned int)0) #endif #ifndef PERL_INT_MAX # ifdef INT_MAX # define PERL_INT_MAX ((int)INT_MAX) # else # ifdef MAXINT /* Often used in */ # define PERL_INT_MAX ((int)MAXINT) # else # define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) # endif # endif #endif #ifndef PERL_INT_MIN # ifdef INT_MIN # define PERL_INT_MIN ((int)INT_MIN) # else # ifdef MININT # define PERL_INT_MIN ((int)MININT) # else # define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) # endif # endif #endif #ifndef PERL_ULONG_MAX # ifdef ULONG_MAX # define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) # else # ifdef MAXULONG # define PERL_ULONG_MAX ((unsigned long)MAXULONG) # else # define PERL_ULONG_MAX (~(unsigned long)0) # endif # endif #endif #ifndef PERL_ULONG_MIN # define PERL_ULONG_MIN ((unsigned long)0L) #endif #ifndef PERL_LONG_MAX # ifdef LONG_MAX # define PERL_LONG_MAX ((long)LONG_MAX) # else # ifdef MAXLONG # define PERL_LONG_MAX ((long)MAXLONG) # else # define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) # endif # endif #endif #ifndef PERL_LONG_MIN # ifdef LONG_MIN # define PERL_LONG_MIN ((long)LONG_MIN) # else # ifdef MINLONG # define PERL_LONG_MIN ((long)MINLONG) # else # define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) # endif # endif #endif #if defined(HAS_QUAD) && (defined(convex) || defined(uts)) # ifndef PERL_UQUAD_MAX # ifdef ULONGLONG_MAX # define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX) # else # ifdef MAXULONGLONG # define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG) # else # define PERL_UQUAD_MAX (~(unsigned long long)0) # endif # endif # endif # ifndef PERL_UQUAD_MIN # define PERL_UQUAD_MIN ((unsigned long long)0L) # endif # ifndef PERL_QUAD_MAX # ifdef LONGLONG_MAX # define PERL_QUAD_MAX ((long long)LONGLONG_MAX) # else # ifdef MAXLONGLONG # define PERL_QUAD_MAX ((long long)MAXLONGLONG) # else # define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1)) # endif # endif # endif # ifndef PERL_QUAD_MIN # ifdef LONGLONG_MIN # define PERL_QUAD_MIN ((long long)LONGLONG_MIN) # else # ifdef MINLONGLONG # define PERL_QUAD_MIN ((long long)MINLONGLONG) # else # define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) # endif # endif # endif #endif /* This is based on code from 5.003 perl.h */ #ifdef HAS_QUAD # ifdef cray #ifndef IVTYPE # define IVTYPE int #endif #ifndef IV_MIN # define IV_MIN PERL_INT_MIN #endif #ifndef IV_MAX # define IV_MAX PERL_INT_MAX #endif #ifndef UV_MIN # define UV_MIN PERL_UINT_MIN #endif #ifndef UV_MAX # define UV_MAX PERL_UINT_MAX #endif # ifdef INTSIZE #ifndef IVSIZE # define IVSIZE INTSIZE #endif # endif # else # if defined(convex) || defined(uts) #ifndef IVTYPE # define IVTYPE long long #endif #ifndef IV_MIN # define IV_MIN PERL_QUAD_MIN #endif #ifndef IV_MAX # define IV_MAX PERL_QUAD_MAX #endif #ifndef UV_MIN # define UV_MIN PERL_UQUAD_MIN #endif #ifndef UV_MAX # define UV_MAX PERL_UQUAD_MAX #endif # ifdef LONGLONGSIZE #ifndef IVSIZE # define IVSIZE LONGLONGSIZE #endif # endif # else #ifndef IVTYPE # define IVTYPE long #endif #ifndef IV_MIN # define IV_MIN PERL_LONG_MIN #endif #ifndef IV_MAX # define IV_MAX PERL_LONG_MAX #endif #ifndef UV_MIN # define UV_MIN PERL_ULONG_MIN #endif #ifndef UV_MAX # define UV_MAX PERL_ULONG_MAX #endif # ifdef LONGSIZE #ifndef IVSIZE # define IVSIZE LONGSIZE #endif # endif # endif # endif #ifndef IVSIZE # define IVSIZE 8 #endif #ifndef PERL_QUAD_MIN # define PERL_QUAD_MIN IV_MIN #endif #ifndef PERL_QUAD_MAX # define PERL_QUAD_MAX IV_MAX #endif #ifndef PERL_UQUAD_MIN # define PERL_UQUAD_MIN UV_MIN #endif #ifndef PERL_UQUAD_MAX # define PERL_UQUAD_MAX UV_MAX #endif #else #ifndef IVTYPE # define IVTYPE long #endif #ifndef IV_MIN # define IV_MIN PERL_LONG_MIN #endif #ifndef IV_MAX # define IV_MAX PERL_LONG_MAX #endif #ifndef UV_MIN # define UV_MIN PERL_ULONG_MIN #endif #ifndef UV_MAX # define UV_MAX PERL_ULONG_MAX #endif #endif #ifndef IVSIZE # ifdef LONGSIZE # define IVSIZE LONGSIZE # else # define IVSIZE 4 /* A bold guess, but the best we can make. */ # endif #endif #ifndef UVTYPE # define UVTYPE unsigned IVTYPE #endif #ifndef UVSIZE # define UVSIZE IVSIZE #endif #ifndef sv_setuv # define sv_setuv(sv, uv) \ STMT_START { \ UV TeMpUv = uv; \ if (TeMpUv <= IV_MAX) \ sv_setiv(sv, TeMpUv); \ else \ sv_setnv(sv, (double)TeMpUv); \ } STMT_END #endif #ifndef newSVuv # define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv)) #endif #ifndef sv_2uv # define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv))) #endif #ifndef SvUVX # define SvUVX(sv) ((UV)SvIVX(sv)) #endif #ifndef SvUVXx # define SvUVXx(sv) SvUVX(sv) #endif #ifndef SvUV # define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) #endif #ifndef SvUVx # define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) #endif /* Hint: sv_uv * Always use the SvUVx() macro instead of sv_uv(). */ #ifndef sv_uv # define sv_uv(sv) SvUVx(sv) #endif #if !defined(SvUOK) && defined(SvIOK_UV) # define SvUOK(sv) SvIOK_UV(sv) #endif #ifndef XST_mUV # define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) ) #endif #ifndef XSRETURN_UV # define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END #endif #ifndef PUSHu # define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END #endif #ifndef XPUSHu # define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END #endif #ifdef HAS_MEMCMP #ifndef memNE # define memNE(s1,s2,l) (memcmp(s1,s2,l)) #endif #ifndef memEQ # define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) #endif #else #ifndef memNE # define memNE(s1,s2,l) (bcmp(s1,s2,l)) #endif #ifndef memEQ # define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) #endif #endif #ifndef MoveD # define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) #endif #ifndef CopyD # define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) #endif #ifdef HAS_MEMSET #ifndef ZeroD # define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) #endif #else #ifndef ZeroD # define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d) #endif #endif #ifndef PoisonWith # define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)) #endif #ifndef PoisonNew # define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB) #endif #ifndef PoisonFree # define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF) #endif #ifndef Poison # define Poison(d,n,t) PoisonFree(d,n,t) #endif #ifndef Newx # define Newx(v,n,t) New(0,v,n,t) #endif #ifndef Newxc # define Newxc(v,n,t,c) Newc(0,v,n,t,c) #endif #ifndef Newxz # define Newxz(v,n,t) Newz(0,v,n,t) #endif #ifndef PERL_UNUSED_DECL # ifdef HASATTRIBUTE # if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) # define PERL_UNUSED_DECL # else # define PERL_UNUSED_DECL __attribute__((unused)) # endif # else # define PERL_UNUSED_DECL # endif #endif #ifndef PERL_UNUSED_ARG # if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */ # include # define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x)) # else # define PERL_UNUSED_ARG(x) ((void)x) # endif #endif #ifndef PERL_UNUSED_VAR # define PERL_UNUSED_VAR(x) ((void)x) #endif #ifndef PERL_UNUSED_CONTEXT # ifdef USE_ITHREADS # define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl) # else # define PERL_UNUSED_CONTEXT # endif #endif #ifndef NOOP # define NOOP /*EMPTY*/(void)0 #endif #ifndef dNOOP # define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL #endif #ifndef NVTYPE # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) # define NVTYPE long double # else # define NVTYPE double # endif typedef NVTYPE NV; #endif #ifndef INT2PTR # if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) # define PTRV UV # define INT2PTR(any,d) (any)(d) # else # if PTRSIZE == LONGSIZE # define PTRV unsigned long # else # define PTRV unsigned # endif # define INT2PTR(any,d) (any)(PTRV)(d) # endif #endif #ifndef PTR2ul # if PTRSIZE == LONGSIZE # define PTR2ul(p) (unsigned long)(p) # else # define PTR2ul(p) INT2PTR(unsigned long,p) # endif #endif #ifndef PTR2nat # define PTR2nat(p) (PTRV)(p) #endif #ifndef NUM2PTR # define NUM2PTR(any,d) (any)PTR2nat(d) #endif #ifndef PTR2IV # define PTR2IV(p) INT2PTR(IV,p) #endif #ifndef PTR2UV # define PTR2UV(p) INT2PTR(UV,p) #endif #ifndef PTR2NV # define PTR2NV(p) NUM2PTR(NV,p) #endif #undef START_EXTERN_C #undef END_EXTERN_C #undef EXTERN_C #ifdef __cplusplus # define START_EXTERN_C extern "C" { # define END_EXTERN_C } # define EXTERN_C extern "C" #else # define START_EXTERN_C # define END_EXTERN_C # define EXTERN_C extern #endif #if defined(PERL_GCC_PEDANTIC) # ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN # define PERL_GCC_BRACE_GROUPS_FORBIDDEN # endif #endif #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus) # ifndef PERL_USE_GCC_BRACE_GROUPS # define PERL_USE_GCC_BRACE_GROUPS # endif #endif #undef STMT_START #undef STMT_END #ifdef PERL_USE_GCC_BRACE_GROUPS # define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ # define STMT_END ) #else # if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__) # define STMT_START if (1) # define STMT_END else (void)0 # else # define STMT_START do # define STMT_END while (0) # endif #endif #ifndef boolSV # define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif /* DEFSV appears first in 5.004_56 */ #ifndef DEFSV # define DEFSV GvSV(PL_defgv) #endif #ifndef SAVE_DEFSV # define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) #endif #ifndef DEFSV_set # define DEFSV_set(sv) (DEFSV = (sv)) #endif /* Older perls (<=5.003) lack AvFILLp */ #ifndef AvFILLp # define AvFILLp AvFILL #endif #ifndef ERRSV # define ERRSV get_sv("@",FALSE) #endif /* Hint: gv_stashpvn * This function's backport doesn't support the length parameter, but * rather ignores it. Portability can only be ensured if the length * parameter is used for speed reasons, but the length can always be * correctly computed from the string argument. */ #ifndef gv_stashpvn # define gv_stashpvn(str,len,create) gv_stashpv(str,create) #endif /* Replace: 1 */ #ifndef get_cv # define get_cv perl_get_cv #endif #ifndef get_sv # define get_sv perl_get_sv #endif #ifndef get_av # define get_av perl_get_av #endif #ifndef get_hv # define get_hv perl_get_hv #endif /* Replace: 0 */ #ifndef dUNDERBAR # define dUNDERBAR dNOOP #endif #ifndef UNDERBAR # define UNDERBAR DEFSV #endif #ifndef dAX # define dAX I32 ax = MARK - PL_stack_base + 1 #endif #ifndef dITEMS # define dITEMS I32 items = SP - MARK #endif #ifndef dXSTARG # define dXSTARG SV * targ = sv_newmortal() #endif #ifndef dAXMARK # define dAXMARK I32 ax = POPMARK; \ register SV ** const mark = PL_stack_base + ax++ #endif #ifndef XSprePUSH # define XSprePUSH (sp = PL_stack_base + ax - 1) #endif #if (PERL_BCDVERSION < 0x5005000) # undef XSRETURN # define XSRETURN(off) \ STMT_START { \ PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ return; \ } STMT_END #endif #ifndef XSPROTO # define XSPROTO(name) void name(pTHX_ CV* cv) #endif #ifndef SVfARG # define SVfARG(p) ((void*)(p)) #endif #ifndef PERL_ABS # define PERL_ABS(x) ((x) < 0 ? -(x) : (x)) #endif #ifndef dVAR # define dVAR dNOOP #endif #ifndef SVf # define SVf "_" #endif #ifndef UTF8_MAXBYTES # define UTF8_MAXBYTES UTF8_MAXLEN #endif #ifndef CPERLscope # define CPERLscope(x) x #endif #ifndef PERL_HASH # define PERL_HASH(hash,str,len) \ STMT_START { \ const char *s_PeRlHaSh = str; \ I32 i_PeRlHaSh = len; \ U32 hash_PeRlHaSh = 0; \ while (i_PeRlHaSh--) \ hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ (hash) = hash_PeRlHaSh; \ } STMT_END #endif #ifndef PERLIO_FUNCS_DECL # ifdef PERLIO_FUNCS_CONST # define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs # define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) # else # define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs # define PERLIO_FUNCS_CAST(funcs) (funcs) # endif #endif /* provide these typedefs for older perls */ #if (PERL_BCDVERSION < 0x5009003) # ifdef ARGSproto typedef OP* (CPERLscope(*Perl_ppaddr_t))(ARGSproto); # else typedef OP* (CPERLscope(*Perl_ppaddr_t))(pTHX); # endif typedef OP* (CPERLscope(*Perl_check_t)) (pTHX_ OP*); #endif #ifndef isPSXSPC # define isPSXSPC(c) (isSPACE(c) || (c) == '\v') #endif #ifndef isBLANK # define isBLANK(c) ((c) == ' ' || (c) == '\t') #endif #ifdef EBCDIC #ifndef isALNUMC # define isALNUMC(c) isalnum(c) #endif #ifndef isASCII # define isASCII(c) isascii(c) #endif #ifndef isCNTRL # define isCNTRL(c) iscntrl(c) #endif #ifndef isGRAPH # define isGRAPH(c) isgraph(c) #endif #ifndef isPRINT # define isPRINT(c) isprint(c) #endif #ifndef isPUNCT # define isPUNCT(c) ispunct(c) #endif #ifndef isXDIGIT # define isXDIGIT(c) isxdigit(c) #endif #else # if (PERL_BCDVERSION < 0x5010000) /* Hint: isPRINT * The implementation in older perl versions includes all of the * isSPACE() characters, which is wrong. The version provided by * Devel::PPPort always overrides a present buggy version. */ # undef isPRINT # endif #ifndef isALNUMC # define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) #endif #ifndef isASCII # define isASCII(c) ((c) <= 127) #endif #ifndef isCNTRL # define isCNTRL(c) ((c) < ' ' || (c) == 127) #endif #ifndef isGRAPH # define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) #endif #ifndef isPRINT # define isPRINT(c) (((c) >= 32 && (c) < 127)) #endif #ifndef isPUNCT # define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) #endif #ifndef isXDIGIT # define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) #endif #endif #ifndef PERL_SIGNALS_UNSAFE_FLAG #define PERL_SIGNALS_UNSAFE_FLAG 0x0001 #if (PERL_BCDVERSION < 0x5008000) # define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG #else # define D_PPP_PERL_SIGNALS_INIT 0 #endif #if defined(NEED_PL_signals) static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; #elif defined(NEED_PL_signals_GLOBAL) U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; #else extern U32 DPPP_(my_PL_signals); #endif #define PL_signals DPPP_(my_PL_signals) #endif /* Hint: PL_ppaddr * Calling an op via PL_ppaddr requires passing a context argument * for threaded builds. Since the context argument is different for * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will * automatically be defined as the correct argument. */ #if (PERL_BCDVERSION <= 0x5005005) /* Replace: 1 */ # define PL_ppaddr ppaddr # define PL_no_modify no_modify /* Replace: 0 */ #endif #if (PERL_BCDVERSION <= 0x5004005) /* Replace: 1 */ # define PL_DBsignal DBsignal # define PL_DBsingle DBsingle # define PL_DBsub DBsub # define PL_DBtrace DBtrace # define PL_Sv Sv # define PL_bufend bufend # define PL_bufptr bufptr # define PL_compiling compiling # define PL_copline copline # define PL_curcop curcop # define PL_curstash curstash # define PL_debstash debstash # define PL_defgv defgv # define PL_diehook diehook # define PL_dirty dirty # define PL_dowarn dowarn # define PL_errgv errgv # define PL_error_count error_count # define PL_expect expect # define PL_hexdigit hexdigit # define PL_hints hints # define PL_in_my in_my # define PL_laststatval laststatval # define PL_lex_state lex_state # define PL_lex_stuff lex_stuff # define PL_linestr linestr # define PL_na na # define PL_perl_destruct_level perl_destruct_level # define PL_perldb perldb # define PL_rsfp_filters rsfp_filters # define PL_rsfp rsfp # define PL_stack_base stack_base # define PL_stack_sp stack_sp # define PL_statcache statcache # define PL_stdingv stdingv # define PL_sv_arenaroot sv_arenaroot # define PL_sv_no sv_no # define PL_sv_undef sv_undef # define PL_sv_yes sv_yes # define PL_tainted tainted # define PL_tainting tainting # define PL_tokenbuf tokenbuf /* Replace: 0 */ #endif /* Warning: PL_parser * For perl versions earlier than 5.9.5, this is an always * non-NULL dummy. Also, it cannot be dereferenced. Don't * use it if you can avoid is and unless you absolutely know * what you're doing. * If you always check that PL_parser is non-NULL, you can * define DPPP_PL_parser_NO_DUMMY to avoid the creation of * a dummy parser structure. */ #if (PERL_BCDVERSION >= 0x5009005) # ifdef DPPP_PL_parser_NO_DUMMY # define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ (croak("panic: PL_parser == NULL in %s:%d", \ __FILE__, __LINE__), (yy_parser *) NULL))->var) # else # ifdef DPPP_PL_parser_NO_DUMMY_WARNING # define D_PPP_parser_dummy_warning(var) # else # define D_PPP_parser_dummy_warning(var) \ warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__), # endif # define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var) #if defined(NEED_PL_parser) static yy_parser DPPP_(dummy_PL_parser); #elif defined(NEED_PL_parser_GLOBAL) yy_parser DPPP_(dummy_PL_parser); #else extern yy_parser DPPP_(dummy_PL_parser); #endif # endif /* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */ /* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf * Do not use this variable unless you know exactly what you're * doint. It is internal to the perl parser and may change or even * be removed in the future. As of perl 5.9.5, you have to check * for (PL_parser != NULL) for this variable to have any effect. * An always non-NULL PL_parser dummy is provided for earlier * perl versions. * If PL_parser is NULL when you try to access this variable, a * dummy is being accessed instead and a warning is issued unless * you define DPPP_PL_parser_NO_DUMMY_WARNING. * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access * this variable will croak with a panic message. */ # define PL_expect D_PPP_my_PL_parser_var(expect) # define PL_copline D_PPP_my_PL_parser_var(copline) # define PL_rsfp D_PPP_my_PL_parser_var(rsfp) # define PL_rsfp_filters D_PPP_my_PL_parser_var(rsfp_filters) # define PL_linestr D_PPP_my_PL_parser_var(linestr) # define PL_bufptr D_PPP_my_PL_parser_var(bufptr) # define PL_bufend D_PPP_my_PL_parser_var(bufend) # define PL_lex_state D_PPP_my_PL_parser_var(lex_state) # define PL_lex_stuff D_PPP_my_PL_parser_var(lex_stuff) # define PL_tokenbuf D_PPP_my_PL_parser_var(tokenbuf) # define PL_in_my D_PPP_my_PL_parser_var(in_my) # define PL_in_my_stash D_PPP_my_PL_parser_var(in_my_stash) # define PL_error_count D_PPP_my_PL_parser_var(error_count) #else /* ensure that PL_parser != NULL and cannot be dereferenced */ # define PL_parser ((void *) 1) #endif #ifndef mPUSHs # define mPUSHs(s) PUSHs(sv_2mortal(s)) #endif #ifndef PUSHmortal # define PUSHmortal PUSHs(sv_newmortal()) #endif #ifndef mPUSHp # define mPUSHp(p,l) sv_setpvn(PUSHmortal, (p), (l)) #endif #ifndef mPUSHn # define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) #endif #ifndef mPUSHi # define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) #endif #ifndef mPUSHu # define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) #endif #ifndef mXPUSHs # define mXPUSHs(s) XPUSHs(sv_2mortal(s)) #endif #ifndef XPUSHmortal # define XPUSHmortal XPUSHs(sv_newmortal()) #endif #ifndef mXPUSHp # define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn(PUSHmortal, (p), (l)); } STMT_END #endif #ifndef mXPUSHn # define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv(PUSHmortal, (NV)(n)); } STMT_END #endif #ifndef mXPUSHi # define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv(PUSHmortal, (IV)(i)); } STMT_END #endif #ifndef mXPUSHu # define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv(PUSHmortal, (UV)(u)); } STMT_END #endif /* Replace: 1 */ #ifndef call_sv # define call_sv perl_call_sv #endif #ifndef call_pv # define call_pv perl_call_pv #endif #ifndef call_argv # define call_argv perl_call_argv #endif #ifndef call_method # define call_method perl_call_method #endif #ifndef eval_sv # define eval_sv perl_eval_sv #endif /* Replace: 0 */ #ifndef PERL_LOADMOD_DENY # define PERL_LOADMOD_DENY 0x1 #endif #ifndef PERL_LOADMOD_NOIMPORT # define PERL_LOADMOD_NOIMPORT 0x2 #endif #ifndef PERL_LOADMOD_IMPORT_OPS # define PERL_LOADMOD_IMPORT_OPS 0x4 #endif #ifndef G_METHOD # define G_METHOD 64 # ifdef call_sv # undef call_sv # endif # if (PERL_BCDVERSION < 0x5006000) # define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \ (flags) & ~G_METHOD) : perl_call_sv(sv, flags)) # else # define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \ (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags)) # endif #endif /* Replace perl_eval_pv with eval_pv */ #ifndef eval_pv #if defined(NEED_eval_pv) static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); static #else extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); #endif #ifdef eval_pv # undef eval_pv #endif #define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b) #define Perl_eval_pv DPPP_(my_eval_pv) #if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL) SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error) { dSP; SV* sv = newSVpv(p, 0); PUSHMARK(sp); eval_sv(sv, G_SCALAR); SvREFCNT_dec(sv); SPAGAIN; sv = POPs; PUTBACK; if (croak_on_error && SvTRUE(GvSV(errgv))) croak(SvPVx(GvSV(errgv), na)); return sv; } #endif #endif #ifndef vload_module #if defined(NEED_vload_module) static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); static #else extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); #endif #ifdef vload_module # undef vload_module #endif #define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d) #define Perl_vload_module DPPP_(my_vload_module) #if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL) void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args) { dTHR; dVAR; OP *veop, *imop; OP * const modname = newSVOP(OP_CONST, 0, name); /* 5.005 has a somewhat hacky force_normal that doesn't croak on SvREADONLY() if PL_compling is true. Current perls take care in ck_require() to correctly turn off SvREADONLY before calling force_normal_flags(). This seems a better fix than fudging PL_compling */ SvREADONLY_off(((SVOP*)modname)->op_sv); modname->op_private |= OPpCONST_BARE; if (ver) { veop = newSVOP(OP_CONST, 0, ver); } else veop = NULL; if (flags & PERL_LOADMOD_NOIMPORT) { imop = sawparens(newNULLLIST()); } else if (flags & PERL_LOADMOD_IMPORT_OPS) { imop = va_arg(*args, OP*); } else { SV *sv; imop = NULL; sv = va_arg(*args, SV*); while (sv) { imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv)); sv = va_arg(*args, SV*); } } { const line_t ocopline = PL_copline; COP * const ocurcop = PL_curcop; const int oexpect = PL_expect; #if (PERL_BCDVERSION >= 0x5004000) utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), veop, modname, imop); #else utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), modname, imop); #endif PL_expect = oexpect; PL_copline = ocopline; PL_curcop = ocurcop; } } #endif #endif #ifndef load_module #if defined(NEED_load_module) static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); static #else extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); #endif #ifdef load_module # undef load_module #endif #define load_module DPPP_(my_load_module) #define Perl_load_module DPPP_(my_load_module) #if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL) void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...) { va_list args; va_start(args, ver); vload_module(flags, name, ver, &args); va_end(args); } #endif #endif #ifndef newRV_inc # define newRV_inc(sv) newRV(sv) /* Replace */ #endif #ifndef newRV_noinc #if defined(NEED_newRV_noinc) static SV * DPPP_(my_newRV_noinc)(SV *sv); static #else extern SV * DPPP_(my_newRV_noinc)(SV *sv); #endif #ifdef newRV_noinc # undef newRV_noinc #endif #define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a) #define Perl_newRV_noinc DPPP_(my_newRV_noinc) #if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL) SV * DPPP_(my_newRV_noinc)(SV *sv) { SV *rv = (SV *)newRV(sv); SvREFCNT_dec(sv); return rv; } #endif #endif /* Hint: newCONSTSUB * Returns a CV* as of perl-5.7.1. This return value is not supported * by Devel::PPPort. */ /* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ #if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005) #if defined(NEED_newCONSTSUB) static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); static #else extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); #endif #ifdef newCONSTSUB # undef newCONSTSUB #endif #define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c) #define Perl_newCONSTSUB DPPP_(my_newCONSTSUB) #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) /* This is just a trick to avoid a dependency of newCONSTSUB on PL_parser */ /* (There's no PL_parser in perl < 5.005, so this is completely safe) */ #define D_PPP_PL_copline PL_copline void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv) { U32 oldhints = PL_hints; HV *old_cop_stash = PL_curcop->cop_stash; HV *old_curstash = PL_curstash; line_t oldline = PL_curcop->cop_line; PL_curcop->cop_line = D_PPP_PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; if (stash) PL_curstash = PL_curcop->cop_stash = stash; newSUB( #if (PERL_BCDVERSION < 0x5003022) start_subparse(), #elif (PERL_BCDVERSION == 0x5003022) start_subparse(0), #else /* 5.003_23 onwards */ start_subparse(FALSE, 0), #endif newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)), newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; PL_curstash = old_curstash; PL_curcop->cop_line = oldline; } #endif #endif /* * Boilerplate macros for initializing and accessing interpreter-local * data from C. All statics in extensions should be reworked to use * this, if you want to make the extension thread-safe. See ext/re/re.xs * for an example of the use of these macros. * * Code that uses these macros is responsible for the following: * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" * 2. Declare a typedef named my_cxt_t that is a structure that contains * all the data that needs to be interpreter-local. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once * (typically put in the BOOT: section). * 5. Use the members of the my_cxt_t structure everywhere as * MY_CXT.member. * 6. Use the dMY_CXT macro (a declaration) in all the functions that * access MY_CXT. */ #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) #ifndef START_MY_CXT /* This must appear in all extensions that define a my_cxt_t structure, * right after the definition (i.e. at file scope). The non-threads * case below uses it to declare the data as static. */ #define START_MY_CXT #if (PERL_BCDVERSION < 0x5004068) /* Fetches the SV that keeps the per-interpreter data. */ #define dMY_CXT_SV \ SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) #else /* >= perl5.004_68 */ #define dMY_CXT_SV \ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ sizeof(MY_CXT_KEY)-1, TRUE) #endif /* < perl5.004_68 */ /* This declaration should be used within all functions that use the * interpreter-local data. */ #define dMY_CXT \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) /* Creates and zeroes the per-interpreter data. * (We allocate my_cxtp in a Perl SV so that it will be released when * the interpreter goes away.) */ #define MY_CXT_INIT \ dMY_CXT_SV; \ /* newSV() allocates one more than needed */ \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Zero(my_cxtp, 1, my_cxt_t); \ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) /* This macro must be used to access members of the my_cxt_t structure. * e.g. MYCXT.some_data */ #define MY_CXT (*my_cxtp) /* Judicious use of these macros can reduce the number of times dMY_CXT * is used. Use is similar to pTHX, aTHX etc. */ #define pMY_CXT my_cxt_t *my_cxtp #define pMY_CXT_ pMY_CXT, #define _pMY_CXT ,pMY_CXT #define aMY_CXT my_cxtp #define aMY_CXT_ aMY_CXT, #define _aMY_CXT ,aMY_CXT #endif /* START_MY_CXT */ #ifndef MY_CXT_CLONE /* Clones the per-interpreter data. */ #define MY_CXT_CLONE \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) #endif #else /* single interpreter */ #ifndef START_MY_CXT #define START_MY_CXT static my_cxt_t my_cxt; #define dMY_CXT_SV dNOOP #define dMY_CXT dNOOP #define MY_CXT_INIT NOOP #define MY_CXT my_cxt #define pMY_CXT void #define pMY_CXT_ #define _pMY_CXT #define aMY_CXT #define aMY_CXT_ #define _aMY_CXT #endif /* START_MY_CXT */ #ifndef MY_CXT_CLONE #define MY_CXT_CLONE NOOP #endif #endif #ifndef IVdf # if IVSIZE == LONGSIZE # define IVdf "ld" # define UVuf "lu" # define UVof "lo" # define UVxf "lx" # define UVXf "lX" # else # if IVSIZE == INTSIZE # define IVdf "d" # define UVuf "u" # define UVof "o" # define UVxf "x" # define UVXf "X" # endif # endif #endif #ifndef NVef # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ defined(PERL_PRIfldbl) && (PERL_BCDVERSION != 0x5006000) /* Not very likely, but let's try anyway. */ # define NVef PERL_PRIeldbl # define NVff PERL_PRIfldbl # define NVgf PERL_PRIgldbl # else # define NVef "e" # define NVff "f" # define NVgf "g" # endif #endif #ifndef SvREFCNT_inc # ifdef PERL_USE_GCC_BRACE_GROUPS # define SvREFCNT_inc(sv) \ ({ \ SV * const _sv = (SV*)(sv); \ if (_sv) \ (SvREFCNT(_sv))++; \ _sv; \ }) # else # define SvREFCNT_inc(sv) \ ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL) # endif #endif #ifndef SvREFCNT_inc_simple # ifdef PERL_USE_GCC_BRACE_GROUPS # define SvREFCNT_inc_simple(sv) \ ({ \ if (sv) \ (SvREFCNT(sv))++; \ (SV *)(sv); \ }) # else # define SvREFCNT_inc_simple(sv) \ ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL) # endif #endif #ifndef SvREFCNT_inc_NN # ifdef PERL_USE_GCC_BRACE_GROUPS # define SvREFCNT_inc_NN(sv) \ ({ \ SV * const _sv = (SV*)(sv); \ SvREFCNT(_sv)++; \ _sv; \ }) # else # define SvREFCNT_inc_NN(sv) \ (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv) # endif #endif #ifndef SvREFCNT_inc_void # ifdef PERL_USE_GCC_BRACE_GROUPS # define SvREFCNT_inc_void(sv) \ ({ \ SV * const _sv = (SV*)(sv); \ if (_sv) \ (void)(SvREFCNT(_sv)++); \ }) # else # define SvREFCNT_inc_void(sv) \ (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0) # endif #endif #ifndef SvREFCNT_inc_simple_void # define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END #endif #ifndef SvREFCNT_inc_simple_NN # define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) #endif #ifndef SvREFCNT_inc_void_NN # define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) #endif #ifndef SvREFCNT_inc_simple_void_NN # define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) #endif #ifndef newSV_type #if defined(NEED_newSV_type) static SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); static #else extern SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); #endif #ifdef newSV_type # undef newSV_type #endif #define newSV_type(a) DPPP_(my_newSV_type)(aTHX_ a) #define Perl_newSV_type DPPP_(my_newSV_type) #if defined(NEED_newSV_type) || defined(NEED_newSV_type_GLOBAL) SV* DPPP_(my_newSV_type)(pTHX_ svtype const t) { SV* const sv = newSV(0); sv_upgrade(sv, t); return sv; } #endif #endif #if (PERL_BCDVERSION < 0x5006000) # define D_PPP_CONSTPV_ARG(x) ((char *) (x)) #else # define D_PPP_CONSTPV_ARG(x) (x) #endif #ifndef newSVpvn # define newSVpvn(data,len) ((data) \ ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \ : newSV(0)) #endif #ifndef newSVpvn_utf8 # define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) #endif #ifndef SVf_UTF8 # define SVf_UTF8 0 #endif #ifndef newSVpvn_flags #if defined(NEED_newSVpvn_flags) static SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); static #else extern SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); #endif #ifdef newSVpvn_flags # undef newSVpvn_flags #endif #define newSVpvn_flags(a,b,c) DPPP_(my_newSVpvn_flags)(aTHX_ a,b,c) #define Perl_newSVpvn_flags DPPP_(my_newSVpvn_flags) #if defined(NEED_newSVpvn_flags) || defined(NEED_newSVpvn_flags_GLOBAL) SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags) { SV *sv = newSVpvn(D_PPP_CONSTPV_ARG(s), len); SvFLAGS(sv) |= (flags & SVf_UTF8); return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; } #endif #endif /* Backwards compatibility stuff... :-( */ #if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen) # define NEED_sv_2pv_flags #endif #if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL) # define NEED_sv_2pv_flags_GLOBAL #endif /* Hint: sv_2pv_nolen * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen(). */ #ifndef sv_2pv_nolen # define sv_2pv_nolen(sv) SvPV_nolen(sv) #endif #ifdef SvPVbyte /* Hint: SvPVbyte * Does not work in perl-5.6.1, ppport.h implements a version * borrowed from perl-5.7.3. */ #if (PERL_BCDVERSION < 0x5007000) #if defined(NEED_sv_2pvbyte) static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); static #else extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); #endif #ifdef sv_2pvbyte # undef sv_2pvbyte #endif #define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b) #define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte) #if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL) char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp) { sv_utf8_downgrade(sv,0); return SvPV(sv,*lp); } #endif /* Hint: sv_2pvbyte * Use the SvPVbyte() macro instead of sv_2pvbyte(). */ #undef SvPVbyte #define SvPVbyte(sv, lp) \ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) #endif #else # define SvPVbyte SvPV # define sv_2pvbyte sv_2pv #endif #ifndef sv_2pvbyte_nolen # define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv) #endif /* Hint: sv_pvn * Always use the SvPV() macro instead of sv_pvn(). */ /* Hint: sv_pvn_force * Always use the SvPV_force() macro instead of sv_pvn_force(). */ /* If these are undefined, they're not handled by the core anyway */ #ifndef SV_IMMEDIATE_UNREF # define SV_IMMEDIATE_UNREF 0 #endif #ifndef SV_GMAGIC # define SV_GMAGIC 0 #endif #ifndef SV_COW_DROP_PV # define SV_COW_DROP_PV 0 #endif #ifndef SV_UTF8_NO_ENCODING # define SV_UTF8_NO_ENCODING 0 #endif #ifndef SV_NOSTEAL # define SV_NOSTEAL 0 #endif #ifndef SV_CONST_RETURN # define SV_CONST_RETURN 0 #endif #ifndef SV_MUTABLE_RETURN # define SV_MUTABLE_RETURN 0 #endif #ifndef SV_SMAGIC # define SV_SMAGIC 0 #endif #ifndef SV_HAS_TRAILING_NUL # define SV_HAS_TRAILING_NUL 0 #endif #ifndef SV_COW_SHARED_HASH_KEYS # define SV_COW_SHARED_HASH_KEYS 0 #endif #if (PERL_BCDVERSION < 0x5007002) #if defined(NEED_sv_2pv_flags) static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); static #else extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); #endif #ifdef sv_2pv_flags # undef sv_2pv_flags #endif #define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c) #define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags) #if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL) char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) { STRLEN n_a = (STRLEN) flags; return sv_2pv(sv, lp ? lp : &n_a); } #endif #if defined(NEED_sv_pvn_force_flags) static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); static #else extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); #endif #ifdef sv_pvn_force_flags # undef sv_pvn_force_flags #endif #define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c) #define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags) #if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL) char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) { STRLEN n_a = (STRLEN) flags; return sv_pvn_force(sv, lp ? lp : &n_a); } #endif #endif #if (PERL_BCDVERSION < 0x5008008) || ( (PERL_BCDVERSION >= 0x5009000) && (PERL_BCDVERSION < 0x5009003) ) # define DPPP_SVPV_NOLEN_LP_ARG &PL_na #else # define DPPP_SVPV_NOLEN_LP_ARG 0 #endif #ifndef SvPV_const # define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) #endif #ifndef SvPV_mutable # define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) #endif #ifndef SvPV_flags # define SvPV_flags(sv, lp, flags) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) #endif #ifndef SvPV_flags_const # define SvPV_flags_const(sv, lp, flags) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) #endif #ifndef SvPV_flags_const_nolen # define SvPV_flags_const_nolen(sv, flags) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? SvPVX_const(sv) : \ (const char*) sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN)) #endif #ifndef SvPV_flags_mutable # define SvPV_flags_mutable(sv, lp, flags) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) #endif #ifndef SvPV_force # define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC) #endif #ifndef SvPV_force_nolen # define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC) #endif #ifndef SvPV_force_mutable # define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) #endif #ifndef SvPV_force_nomg # define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) #endif #ifndef SvPV_force_nomg_nolen # define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) #endif #ifndef SvPV_force_flags # define SvPV_force_flags(sv, lp, flags) \ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) #endif #ifndef SvPV_force_flags_nolen # define SvPV_force_flags_nolen(sv, flags) \ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ ? SvPVX(sv) : sv_pvn_force_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags)) #endif #ifndef SvPV_force_flags_mutable # define SvPV_force_flags_mutable(sv, lp, flags) \ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) #endif #ifndef SvPV_nolen # define SvPV_nolen(sv) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC)) #endif #ifndef SvPV_nolen_const # define SvPV_nolen_const(sv) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? SvPVX_const(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN)) #endif #ifndef SvPV_nomg # define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) #endif #ifndef SvPV_nomg_const # define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) #endif #ifndef SvPV_nomg_const_nolen # define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) #endif #ifndef SvPV_renew # define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \ SvPV_set((sv), (char *) saferealloc( \ (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \ } STMT_END #endif #ifndef SvMAGIC_set # define SvMAGIC_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END #endif #if (PERL_BCDVERSION < 0x5009003) #ifndef SvPVX_const # define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) #endif #ifndef SvPVX_mutable # define SvPVX_mutable(sv) (0 + SvPVX(sv)) #endif #ifndef SvRV_set # define SvRV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END #endif #else #ifndef SvPVX_const # define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) #endif #ifndef SvPVX_mutable # define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) #endif #ifndef SvRV_set # define SvRV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ ((sv)->sv_u.svu_rv = (val)); } STMT_END #endif #endif #ifndef SvSTASH_set # define SvSTASH_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END #endif #if (PERL_BCDVERSION < 0x5004000) #ifndef SvUV_set # define SvUV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END #endif #else #ifndef SvUV_set # define SvUV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END #endif #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf) #if defined(NEED_vnewSVpvf) static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); static #else extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); #endif #ifdef vnewSVpvf # undef vnewSVpvf #endif #define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b) #define Perl_vnewSVpvf DPPP_(my_vnewSVpvf) #if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL) SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args) { register SV *sv = newSV(0); sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); return sv; } #endif #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf) # define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf) # define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg) #if defined(NEED_sv_catpvf_mg) static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); static #else extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); #endif #define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg) #if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL) void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...) { va_list args; va_start(args, pat); sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); SvSETMAGIC(sv); va_end(args); } #endif #endif #ifdef PERL_IMPLICIT_CONTEXT #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext) #if defined(NEED_sv_catpvf_mg_nocontext) static void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); static #else extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); #endif #define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) #define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) #if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL) void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...) { dTHX; va_list args; va_start(args, pat); sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); SvSETMAGIC(sv); va_end(args); } #endif #endif #endif /* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */ #ifndef sv_catpvf_mg # ifdef PERL_IMPLICIT_CONTEXT # define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext # else # define sv_catpvf_mg Perl_sv_catpvf_mg # endif #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg) # define sv_vcatpvf_mg(sv, pat, args) \ STMT_START { \ sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ SvSETMAGIC(sv); \ } STMT_END #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg) #if defined(NEED_sv_setpvf_mg) static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); static #else extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); #endif #define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg) #if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL) void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...) { va_list args; va_start(args, pat); sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); SvSETMAGIC(sv); va_end(args); } #endif #endif #ifdef PERL_IMPLICIT_CONTEXT #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext) #if defined(NEED_sv_setpvf_mg_nocontext) static void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); static #else extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); #endif #define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) #define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) #if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL) void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...) { dTHX; va_list args; va_start(args, pat); sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); SvSETMAGIC(sv); va_end(args); } #endif #endif #endif /* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */ #ifndef sv_setpvf_mg # ifdef PERL_IMPLICIT_CONTEXT # define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext # else # define sv_setpvf_mg Perl_sv_setpvf_mg # endif #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg) # define sv_vsetpvf_mg(sv, pat, args) \ STMT_START { \ sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ SvSETMAGIC(sv); \ } STMT_END #endif #ifndef newSVpvn_share #if defined(NEED_newSVpvn_share) static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); static #else extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); #endif #ifdef newSVpvn_share # undef newSVpvn_share #endif #define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c) #define Perl_newSVpvn_share DPPP_(my_newSVpvn_share) #if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL) SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash) { SV *sv; if (len < 0) len = -len; if (!hash) PERL_HASH(hash, (char*) src, len); sv = newSVpvn((char *) src, len); sv_upgrade(sv, SVt_PVIV); SvIVX(sv) = hash; SvREADONLY_on(sv); SvPOK_on(sv); return sv; } #endif #endif #ifndef SvSHARED_HASH # define SvSHARED_HASH(sv) (0 + SvUVX(sv)) #endif #ifndef HvNAME_get # define HvNAME_get(hv) HvNAME(hv) #endif #ifndef HvNAMELEN_get # define HvNAMELEN_get(hv) (HvNAME_get(hv) ? (I32)strlen(HvNAME_get(hv)) : 0) #endif #ifndef GvSVn # define GvSVn(gv) GvSV(gv) #endif #ifndef isGV_with_GP # define isGV_with_GP(gv) isGV(gv) #endif #ifndef WARN_ALL # define WARN_ALL 0 #endif #ifndef WARN_CLOSURE # define WARN_CLOSURE 1 #endif #ifndef WARN_DEPRECATED # define WARN_DEPRECATED 2 #endif #ifndef WARN_EXITING # define WARN_EXITING 3 #endif #ifndef WARN_GLOB # define WARN_GLOB 4 #endif #ifndef WARN_IO # define WARN_IO 5 #endif #ifndef WARN_CLOSED # define WARN_CLOSED 6 #endif #ifndef WARN_EXEC # define WARN_EXEC 7 #endif #ifndef WARN_LAYER # define WARN_LAYER 8 #endif #ifndef WARN_NEWLINE # define WARN_NEWLINE 9 #endif #ifndef WARN_PIPE # define WARN_PIPE 10 #endif #ifndef WARN_UNOPENED # define WARN_UNOPENED 11 #endif #ifndef WARN_MISC # define WARN_MISC 12 #endif #ifndef WARN_NUMERIC # define WARN_NUMERIC 13 #endif #ifndef WARN_ONCE # define WARN_ONCE 14 #endif #ifndef WARN_OVERFLOW # define WARN_OVERFLOW 15 #endif #ifndef WARN_PACK # define WARN_PACK 16 #endif #ifndef WARN_PORTABLE # define WARN_PORTABLE 17 #endif #ifndef WARN_RECURSION # define WARN_RECURSION 18 #endif #ifndef WARN_REDEFINE # define WARN_REDEFINE 19 #endif #ifndef WARN_REGEXP # define WARN_REGEXP 20 #endif #ifndef WARN_SEVERE # define WARN_SEVERE 21 #endif #ifndef WARN_DEBUGGING # define WARN_DEBUGGING 22 #endif #ifndef WARN_INPLACE # define WARN_INPLACE 23 #endif #ifndef WARN_INTERNAL # define WARN_INTERNAL 24 #endif #ifndef WARN_MALLOC # define WARN_MALLOC 25 #endif #ifndef WARN_SIGNAL # define WARN_SIGNAL 26 #endif #ifndef WARN_SUBSTR # define WARN_SUBSTR 27 #endif #ifndef WARN_SYNTAX # define WARN_SYNTAX 28 #endif #ifndef WARN_AMBIGUOUS # define WARN_AMBIGUOUS 29 #endif #ifndef WARN_BAREWORD # define WARN_BAREWORD 30 #endif #ifndef WARN_DIGIT # define WARN_DIGIT 31 #endif #ifndef WARN_PARENTHESIS # define WARN_PARENTHESIS 32 #endif #ifndef WARN_PRECEDENCE # define WARN_PRECEDENCE 33 #endif #ifndef WARN_PRINTF # define WARN_PRINTF 34 #endif #ifndef WARN_PROTOTYPE # define WARN_PROTOTYPE 35 #endif #ifndef WARN_QW # define WARN_QW 36 #endif #ifndef WARN_RESERVED # define WARN_RESERVED 37 #endif #ifndef WARN_SEMICOLON # define WARN_SEMICOLON 38 #endif #ifndef WARN_TAINT # define WARN_TAINT 39 #endif #ifndef WARN_THREADS # define WARN_THREADS 40 #endif #ifndef WARN_UNINITIALIZED # define WARN_UNINITIALIZED 41 #endif #ifndef WARN_UNPACK # define WARN_UNPACK 42 #endif #ifndef WARN_UNTIE # define WARN_UNTIE 43 #endif #ifndef WARN_UTF8 # define WARN_UTF8 44 #endif #ifndef WARN_VOID # define WARN_VOID 45 #endif #ifndef WARN_ASSERTIONS # define WARN_ASSERTIONS 46 #endif #ifndef packWARN # define packWARN(a) (a) #endif #ifndef ckWARN # ifdef G_WARN_ON # define ckWARN(a) (PL_dowarn & G_WARN_ON) # else # define ckWARN(a) PL_dowarn # endif #endif #if (PERL_BCDVERSION >= 0x5004000) && !defined(warner) #if defined(NEED_warner) static void DPPP_(my_warner)(U32 err, const char *pat, ...); static #else extern void DPPP_(my_warner)(U32 err, const char *pat, ...); #endif #define Perl_warner DPPP_(my_warner) #if defined(NEED_warner) || defined(NEED_warner_GLOBAL) void DPPP_(my_warner)(U32 err, const char *pat, ...) { SV *sv; va_list args; PERL_UNUSED_ARG(err); va_start(args, pat); sv = vnewSVpvf(pat, &args); va_end(args); sv_2mortal(sv); warn("%s", SvPV_nolen(sv)); } #define warner Perl_warner #define Perl_warner_nocontext Perl_warner #endif #endif /* concatenating with "" ensures that only literal strings are accepted as argument * note that STR_WITH_LEN() can't be used as argument to macros or functions that * under some configurations might be macros */ #ifndef STR_WITH_LEN # define STR_WITH_LEN(s) (s ""), (sizeof(s)-1) #endif #ifndef newSVpvs # define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1) #endif #ifndef newSVpvs_flags # define newSVpvs_flags(str, flags) newSVpvn_flags(str "", sizeof(str) - 1, flags) #endif #ifndef sv_catpvs # define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1) #endif #ifndef sv_setpvs # define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1) #endif #ifndef hv_fetchs # define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval) #endif #ifndef hv_stores # define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0) #endif #ifndef gv_fetchpvn_flags # define gv_fetchpvn_flags(name, len, flags, svt) gv_fetchpv(name, flags, svt) #endif #ifndef gv_fetchpvs # define gv_fetchpvs(name, flags, svt) gv_fetchpvn_flags(name "", sizeof(name) - 1, flags, svt) #endif #ifndef gv_stashpvs # define gv_stashpvs(name, flags) gv_stashpvn(name "", sizeof(name) - 1, flags) #endif #ifndef SvGETMAGIC # define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END #endif #ifndef PERL_MAGIC_sv # define PERL_MAGIC_sv '\0' #endif #ifndef PERL_MAGIC_overload # define PERL_MAGIC_overload 'A' #endif #ifndef PERL_MAGIC_overload_elem # define PERL_MAGIC_overload_elem 'a' #endif #ifndef PERL_MAGIC_overload_table # define PERL_MAGIC_overload_table 'c' #endif #ifndef PERL_MAGIC_bm # define PERL_MAGIC_bm 'B' #endif #ifndef PERL_MAGIC_regdata # define PERL_MAGIC_regdata 'D' #endif #ifndef PERL_MAGIC_regdatum # define PERL_MAGIC_regdatum 'd' #endif #ifndef PERL_MAGIC_env # define PERL_MAGIC_env 'E' #endif #ifndef PERL_MAGIC_envelem # define PERL_MAGIC_envelem 'e' #endif #ifndef PERL_MAGIC_fm # define PERL_MAGIC_fm 'f' #endif #ifndef PERL_MAGIC_regex_global # define PERL_MAGIC_regex_global 'g' #endif #ifndef PERL_MAGIC_isa # define PERL_MAGIC_isa 'I' #endif #ifndef PERL_MAGIC_isaelem # define PERL_MAGIC_isaelem 'i' #endif #ifndef PERL_MAGIC_nkeys # define PERL_MAGIC_nkeys 'k' #endif #ifndef PERL_MAGIC_dbfile # define PERL_MAGIC_dbfile 'L' #endif #ifndef PERL_MAGIC_dbline # define PERL_MAGIC_dbline 'l' #endif #ifndef PERL_MAGIC_mutex # define PERL_MAGIC_mutex 'm' #endif #ifndef PERL_MAGIC_shared # define PERL_MAGIC_shared 'N' #endif #ifndef PERL_MAGIC_shared_scalar # define PERL_MAGIC_shared_scalar 'n' #endif #ifndef PERL_MAGIC_collxfrm # define PERL_MAGIC_collxfrm 'o' #endif #ifndef PERL_MAGIC_tied # define PERL_MAGIC_tied 'P' #endif #ifndef PERL_MAGIC_tiedelem # define PERL_MAGIC_tiedelem 'p' #endif #ifndef PERL_MAGIC_tiedscalar # define PERL_MAGIC_tiedscalar 'q' #endif #ifndef PERL_MAGIC_qr # define PERL_MAGIC_qr 'r' #endif #ifndef PERL_MAGIC_sig # define PERL_MAGIC_sig 'S' #endif #ifndef PERL_MAGIC_sigelem # define PERL_MAGIC_sigelem 's' #endif #ifndef PERL_MAGIC_taint # define PERL_MAGIC_taint 't' #endif #ifndef PERL_MAGIC_uvar # define PERL_MAGIC_uvar 'U' #endif #ifndef PERL_MAGIC_uvar_elem # define PERL_MAGIC_uvar_elem 'u' #endif #ifndef PERL_MAGIC_vstring # define PERL_MAGIC_vstring 'V' #endif #ifndef PERL_MAGIC_vec # define PERL_MAGIC_vec 'v' #endif #ifndef PERL_MAGIC_utf8 # define PERL_MAGIC_utf8 'w' #endif #ifndef PERL_MAGIC_substr # define PERL_MAGIC_substr 'x' #endif #ifndef PERL_MAGIC_defelem # define PERL_MAGIC_defelem 'y' #endif #ifndef PERL_MAGIC_glob # define PERL_MAGIC_glob '*' #endif #ifndef PERL_MAGIC_arylen # define PERL_MAGIC_arylen '#' #endif #ifndef PERL_MAGIC_pos # define PERL_MAGIC_pos '.' #endif #ifndef PERL_MAGIC_backref # define PERL_MAGIC_backref '<' #endif #ifndef PERL_MAGIC_ext # define PERL_MAGIC_ext '~' #endif /* That's the best we can do... */ #ifndef sv_catpvn_nomg # define sv_catpvn_nomg sv_catpvn #endif #ifndef sv_catsv_nomg # define sv_catsv_nomg sv_catsv #endif #ifndef sv_setsv_nomg # define sv_setsv_nomg sv_setsv #endif #ifndef sv_pvn_nomg # define sv_pvn_nomg sv_pvn #endif #ifndef SvIV_nomg # define SvIV_nomg SvIV #endif #ifndef SvUV_nomg # define SvUV_nomg SvUV #endif #ifndef sv_catpv_mg # define sv_catpv_mg(sv, ptr) \ STMT_START { \ SV *TeMpSv = sv; \ sv_catpv(TeMpSv,ptr); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_catpvn_mg # define sv_catpvn_mg(sv, ptr, len) \ STMT_START { \ SV *TeMpSv = sv; \ sv_catpvn(TeMpSv,ptr,len); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_catsv_mg # define sv_catsv_mg(dsv, ssv) \ STMT_START { \ SV *TeMpSv = dsv; \ sv_catsv(TeMpSv,ssv); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setiv_mg # define sv_setiv_mg(sv, i) \ STMT_START { \ SV *TeMpSv = sv; \ sv_setiv(TeMpSv,i); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setnv_mg # define sv_setnv_mg(sv, num) \ STMT_START { \ SV *TeMpSv = sv; \ sv_setnv(TeMpSv,num); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setpv_mg # define sv_setpv_mg(sv, ptr) \ STMT_START { \ SV *TeMpSv = sv; \ sv_setpv(TeMpSv,ptr); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setpvn_mg # define sv_setpvn_mg(sv, ptr, len) \ STMT_START { \ SV *TeMpSv = sv; \ sv_setpvn(TeMpSv,ptr,len); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setsv_mg # define sv_setsv_mg(dsv, ssv) \ STMT_START { \ SV *TeMpSv = dsv; \ sv_setsv(TeMpSv,ssv); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_setuv_mg # define sv_setuv_mg(sv, i) \ STMT_START { \ SV *TeMpSv = sv; \ sv_setuv(TeMpSv,i); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef sv_usepvn_mg # define sv_usepvn_mg(sv, ptr, len) \ STMT_START { \ SV *TeMpSv = sv; \ sv_usepvn(TeMpSv,ptr,len); \ SvSETMAGIC(TeMpSv); \ } STMT_END #endif #ifndef SvVSTRING_mg # define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL) #endif /* Hint: sv_magic_portable * This is a compatibility function that is only available with * Devel::PPPort. It is NOT in the perl core. * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when * it is being passed a name pointer with namlen == 0. In that * case, perl 5.8.0 and later store the pointer, not a copy of it. * The compatibility can be provided back to perl 5.004. With * earlier versions, the code will not compile. */ #if (PERL_BCDVERSION < 0x5004000) /* code that uses sv_magic_portable will not compile */ #elif (PERL_BCDVERSION < 0x5008000) # define sv_magic_portable(sv, obj, how, name, namlen) \ STMT_START { \ SV *SvMp_sv = (sv); \ char *SvMp_name = (char *) (name); \ I32 SvMp_namlen = (namlen); \ if (SvMp_name && SvMp_namlen == 0) \ { \ MAGIC *mg; \ sv_magic(SvMp_sv, obj, how, 0, 0); \ mg = SvMAGIC(SvMp_sv); \ mg->mg_len = -42; /* XXX: this is the tricky part */ \ mg->mg_ptr = SvMp_name; \ } \ else \ { \ sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \ } \ } STMT_END #else # define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e) #endif #ifdef USE_ITHREADS #ifndef CopFILE # define CopFILE(c) ((c)->cop_file) #endif #ifndef CopFILEGV # define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv) #endif #ifndef CopFILE_set # define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) #endif #ifndef CopFILESV # define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) #endif #ifndef CopFILEAV # define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) #endif #ifndef CopSTASHPV # define CopSTASHPV(c) ((c)->cop_stashpv) #endif #ifndef CopSTASHPV_set # define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) #endif #ifndef CopSTASH # define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) #endif #ifndef CopSTASH_set # define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch) #endif #ifndef CopSTASH_eq # define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \ || (CopSTASHPV(c) && HvNAME(hv) \ && strEQ(CopSTASHPV(c), HvNAME(hv))))) #endif #else #ifndef CopFILEGV # define CopFILEGV(c) ((c)->cop_filegv) #endif #ifndef CopFILEGV_set # define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) #endif #ifndef CopFILE_set # define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) #endif #ifndef CopFILESV # define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) #endif #ifndef CopFILEAV # define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) #endif #ifndef CopFILE # define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) #endif #ifndef CopSTASH # define CopSTASH(c) ((c)->cop_stash) #endif #ifndef CopSTASH_set # define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) #endif #ifndef CopSTASHPV # define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) #endif #ifndef CopSTASHPV_set # define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) #endif #ifndef CopSTASH_eq # define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) #endif #endif /* USE_ITHREADS */ #ifndef IN_PERL_COMPILETIME # define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling) #endif #ifndef IN_LOCALE_RUNTIME # define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) #endif #ifndef IN_LOCALE_COMPILETIME # define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) #endif #ifndef IN_LOCALE # define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) #endif #ifndef IS_NUMBER_IN_UV # define IS_NUMBER_IN_UV 0x01 #endif #ifndef IS_NUMBER_GREATER_THAN_UV_MAX # define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 #endif #ifndef IS_NUMBER_NOT_INT # define IS_NUMBER_NOT_INT 0x04 #endif #ifndef IS_NUMBER_NEG # define IS_NUMBER_NEG 0x08 #endif #ifndef IS_NUMBER_INFINITY # define IS_NUMBER_INFINITY 0x10 #endif #ifndef IS_NUMBER_NAN # define IS_NUMBER_NAN 0x20 #endif #ifndef GROK_NUMERIC_RADIX # define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) #endif #ifndef PERL_SCAN_GREATER_THAN_UV_MAX # define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 #endif #ifndef PERL_SCAN_SILENT_ILLDIGIT # define PERL_SCAN_SILENT_ILLDIGIT 0x04 #endif #ifndef PERL_SCAN_ALLOW_UNDERSCORES # define PERL_SCAN_ALLOW_UNDERSCORES 0x01 #endif #ifndef PERL_SCAN_DISALLOW_PREFIX # define PERL_SCAN_DISALLOW_PREFIX 0x02 #endif #ifndef grok_numeric_radix #if defined(NEED_grok_numeric_radix) static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); static #else extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); #endif #ifdef grok_numeric_radix # undef grok_numeric_radix #endif #define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b) #define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix) #if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL) bool DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send) { #ifdef USE_LOCALE_NUMERIC #ifdef PL_numeric_radix_sv if (PL_numeric_radix_sv && IN_LOCALE) { STRLEN len; char* radix = SvPV(PL_numeric_radix_sv, len); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #else /* older perls don't have PL_numeric_radix_sv so the radix * must manually be requested from locale.h */ #include dTHR; /* needed for older threaded perls */ struct lconv *lc = localeconv(); char *radix = lc->decimal_point; if (radix && IN_LOCALE) { STRLEN len = strlen(radix); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #endif #endif /* USE_LOCALE_NUMERIC */ /* always try "." if numeric radix didn't match because * we may have data from different locales mixed */ if (*sp < send && **sp == '.') { ++*sp; return TRUE; } return FALSE; } #endif #endif #ifndef grok_number #if defined(NEED_grok_number) static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); static #else extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); #endif #ifdef grok_number # undef grok_number #endif #define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c) #define Perl_grok_number DPPP_(my_grok_number) #if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL) int DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep) { const char *s = pv; const char *send = pv + len; const UV max_div_10 = UV_MAX / 10; const char max_mod_10 = UV_MAX % 10; int numtype = 0; int sawinf = 0; int sawnan = 0; while (s < send && isSPACE(*s)) s++; if (s == send) { return 0; } else if (*s == '-') { s++; numtype = IS_NUMBER_NEG; } else if (*s == '+') s++; if (s == send) return 0; /* next must be digit or the radix separator or beginning of infinity */ if (isDIGIT(*s)) { /* UVs are at least 32 bits, so the first 9 decimal digits cannot overflow. */ UV value = *s - '0'; /* This construction seems to be more optimiser friendly. (without it gcc does the isDIGIT test and the *s - '0' separately) With it gcc on arm is managing 6 instructions (6 cycles) per digit. In theory the optimiser could deduce how far to unroll the loop before checking for overflow. */ if (++s < send) { int digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { /* Now got 9 digits, so need to check each time for overflow. */ digit = *s - '0'; while (digit >= 0 && digit <= 9 && (value < max_div_10 || (value == max_div_10 && digit <= max_mod_10))) { value = value * 10 + digit; if (++s < send) digit = *s - '0'; else break; } if (digit >= 0 && digit <= 9 && (s < send)) { /* value overflowed. skip the remaining digits, don't worry about setting *valuep. */ do { s++; } while (s < send && isDIGIT(*s)); numtype |= IS_NUMBER_GREATER_THAN_UV_MAX; goto skip_value; } } } } } } } } } } } } } } } } } } numtype |= IS_NUMBER_IN_UV; if (valuep) *valuep = value; skip_value: if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT; while (s < send && isDIGIT(*s)) /* optional digits after the radix */ s++; } } else if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ /* no digits before the radix means we need digits after it */ if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); if (valuep) { /* integer approximation is valid - it's 0. */ *valuep = 0; } } else return 0; } else if (*s == 'I' || *s == 'i') { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; s++; if (s < send && (*s == 'I' || *s == 'i')) { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; s++; if (s == send || (*s != 'T' && *s != 't')) return 0; s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; s++; } sawinf = 1; } else if (*s == 'N' || *s == 'n') { /* XXX TODO: There are signaling NaNs and quiet NaNs. */ s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; sawnan = 1; } else return 0; if (sawinf) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; } else if (sawnan) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; } else if (s < send) { /* we can have an optional exponent part */ if (*s == 'e' || *s == 'E') { /* The only flag we keep is sign. Blow away any "it's UV" */ numtype &= IS_NUMBER_NEG; numtype |= IS_NUMBER_NOT_INT; s++; if (s < send && (*s == '-' || *s == '+')) s++; if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); } else return 0; } } while (s < send && isSPACE(*s)) s++; if (s >= send) return numtype; if (len == 10 && memEQ(pv, "0 but true", 10)) { if (valuep) *valuep = 0; return IS_NUMBER_IN_UV; } return 0; } #endif #endif /* * The grok_* routines have been modified to use warn() instead of * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit, * which is why the stack variable has been renamed to 'xdigit'. */ #ifndef grok_bin #if defined(NEED_grok_bin) static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); static #else extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); #endif #ifdef grok_bin # undef grok_bin #endif #define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d) #define Perl_grok_bin DPPP_(my_grok_bin) #if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL) UV DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) { const char *s = start; STRLEN len = *len_p; UV value = 0; NV value_nv = 0; const UV max_div_2 = UV_MAX / 2; bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; bool overflowed = FALSE; if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { /* strip off leading b or 0b. for compatibility silently suffer "b" and "0b" as valid binary numbers. */ if (len >= 1) { if (s[0] == 'b') { s++; len--; } else if (len >= 2 && s[0] == '0' && s[1] == 'b') { s+=2; len-=2; } } } for (; len-- && *s; s++) { char bit = *s; if (bit == '0' || bit == '1') { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. With gcc seems to be much straighter code than old scan_bin. */ redo: if (!overflowed) { if (value <= max_div_2) { value = (value << 1) | (bit - '0'); continue; } /* Bah. We're just overflowed. */ warn("Integer overflow in binary number"); overflowed = TRUE; value_nv = (NV) value; } value_nv *= 2.0; /* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount. */ value_nv += (NV)(bit - '0'); continue; } if (bit == '_' && len && allow_underscores && (bit = s[1]) && (bit == '0' || bit == '1')) { --len; ++s; goto redo; } if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal binary digit '%c' ignored", *s); break; } if ( ( overflowed && value_nv > 4294967295.0) #if UVSIZE > 4 || (!overflowed && value > 0xffffffff ) #endif ) { warn("Binary number > 0b11111111111111111111111111111111 non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX; } #endif #endif #ifndef grok_hex #if defined(NEED_grok_hex) static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); static #else extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); #endif #ifdef grok_hex # undef grok_hex #endif #define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d) #define Perl_grok_hex DPPP_(my_grok_hex) #if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL) UV DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) { const char *s = start; STRLEN len = *len_p; UV value = 0; NV value_nv = 0; const UV max_div_16 = UV_MAX / 16; bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; bool overflowed = FALSE; const char *xdigit; if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { /* strip off leading x or 0x. for compatibility silently suffer "x" and "0x" as valid hex numbers. */ if (len >= 1) { if (s[0] == 'x') { s++; len--; } else if (len >= 2 && s[0] == '0' && s[1] == 'x') { s+=2; len-=2; } } } for (; len-- && *s; s++) { xdigit = strchr((char *) PL_hexdigit, *s); if (xdigit) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. With gcc seems to be much straighter code than old scan_hex. */ redo: if (!overflowed) { if (value <= max_div_16) { value = (value << 4) | ((xdigit - PL_hexdigit) & 15); continue; } warn("Integer overflow in hexadecimal number"); overflowed = TRUE; value_nv = (NV) value; } value_nv *= 16.0; /* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 16-tuples. */ value_nv += (NV)((xdigit - PL_hexdigit) & 15); continue; } if (*s == '_' && len && allow_underscores && s[1] && (xdigit = strchr((char *) PL_hexdigit, s[1]))) { --len; ++s; goto redo; } if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal hexadecimal digit '%c' ignored", *s); break; } if ( ( overflowed && value_nv > 4294967295.0) #if UVSIZE > 4 || (!overflowed && value > 0xffffffff ) #endif ) { warn("Hexadecimal number > 0xffffffff non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX; } #endif #endif #ifndef grok_oct #if defined(NEED_grok_oct) static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); static #else extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); #endif #ifdef grok_oct # undef grok_oct #endif #define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d) #define Perl_grok_oct DPPP_(my_grok_oct) #if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL) UV DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) { const char *s = start; STRLEN len = *len_p; UV value = 0; NV value_nv = 0; const UV max_div_8 = UV_MAX / 8; bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; bool overflowed = FALSE; for (; len-- && *s; s++) { /* gcc 2.95 optimiser not smart enough to figure that this subtraction out front allows slicker code. */ int digit = *s - '0'; if (digit >= 0 && digit <= 7) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. */ redo: if (!overflowed) { if (value <= max_div_8) { value = (value << 3) | digit; continue; } /* Bah. We're just overflowed. */ warn("Integer overflow in octal number"); overflowed = TRUE; value_nv = (NV) value; } value_nv *= 8.0; /* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 8-tuples. */ value_nv += (NV)digit; continue; } if (digit == ('_' - '0') && len && allow_underscores && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) { --len; ++s; goto redo; } /* Allow \octal to work the DWIM way (that is, stop scanning * as soon as non-octal characters are seen, complain only iff * someone seems to want to use the digits eight and nine). */ if (digit == 8 || digit == 9) { if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal octal digit '%c' ignored", *s); } break; } if ( ( overflowed && value_nv > 4294967295.0) #if UVSIZE > 4 || (!overflowed && value > 0xffffffff ) #endif ) { warn("Octal number > 037777777777 non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX; } #endif #endif #if !defined(my_snprintf) #if defined(NEED_my_snprintf) static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); static #else extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); #endif #define my_snprintf DPPP_(my_my_snprintf) #define Perl_my_snprintf DPPP_(my_my_snprintf) #if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL) int DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...) { dTHX; int retval; va_list ap; va_start(ap, format); #ifdef HAS_VSNPRINTF retval = vsnprintf(buffer, len, format, ap); #else retval = vsprintf(buffer, format, ap); #endif va_end(ap); if (retval < 0 || (len > 0 && (Size_t)retval >= len)) Perl_croak(aTHX_ "panic: my_snprintf buffer overflow"); return retval; } #endif #endif #if !defined(my_sprintf) #if defined(NEED_my_sprintf) static int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); static #else extern int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); #endif #define my_sprintf DPPP_(my_my_sprintf) #define Perl_my_sprintf DPPP_(my_my_sprintf) #if defined(NEED_my_sprintf) || defined(NEED_my_sprintf_GLOBAL) int DPPP_(my_my_sprintf)(char *buffer, const char* pat, ...) { va_list args; va_start(args, pat); vsprintf(buffer, pat, args); va_end(args); return strlen(buffer); } #endif #endif #ifdef NO_XSLOCKS # ifdef dJMPENV # define dXCPT dJMPENV; int rEtV = 0 # define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0) # define XCPT_TRY_END JMPENV_POP; # define XCPT_CATCH if (rEtV != 0) # define XCPT_RETHROW JMPENV_JUMP(rEtV) # else # define dXCPT Sigjmp_buf oldTOP; int rEtV = 0 # define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0) # define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf); # define XCPT_CATCH if (rEtV != 0) # define XCPT_RETHROW Siglongjmp(top_env, rEtV) # endif #endif #if !defined(my_strlcat) #if defined(NEED_my_strlcat) static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); static #else extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); #endif #define my_strlcat DPPP_(my_my_strlcat) #define Perl_my_strlcat DPPP_(my_my_strlcat) #if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL) Size_t DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size) { Size_t used, length, copy; used = strlen(dst); length = strlen(src); if (size > 0 && used < size - 1) { copy = (length >= size - used) ? size - used - 1 : length; memcpy(dst + used, src, copy); dst[used + copy] = '\0'; } return used + length; } #endif #endif #if !defined(my_strlcpy) #if defined(NEED_my_strlcpy) static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); static #else extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); #endif #define my_strlcpy DPPP_(my_my_strlcpy) #define Perl_my_strlcpy DPPP_(my_my_strlcpy) #if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL) Size_t DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size) { Size_t length, copy; length = strlen(src); if (size > 0) { copy = (length >= size) ? size - 1 : length; memcpy(dst, src, copy); dst[copy] = '\0'; } return length; } #endif #endif #ifndef PERL_PV_ESCAPE_QUOTE # define PERL_PV_ESCAPE_QUOTE 0x0001 #endif #ifndef PERL_PV_PRETTY_QUOTE # define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE #endif #ifndef PERL_PV_PRETTY_ELLIPSES # define PERL_PV_PRETTY_ELLIPSES 0x0002 #endif #ifndef PERL_PV_PRETTY_LTGT # define PERL_PV_PRETTY_LTGT 0x0004 #endif #ifndef PERL_PV_ESCAPE_FIRSTCHAR # define PERL_PV_ESCAPE_FIRSTCHAR 0x0008 #endif #ifndef PERL_PV_ESCAPE_UNI # define PERL_PV_ESCAPE_UNI 0x0100 #endif #ifndef PERL_PV_ESCAPE_UNI_DETECT # define PERL_PV_ESCAPE_UNI_DETECT 0x0200 #endif #ifndef PERL_PV_ESCAPE_ALL # define PERL_PV_ESCAPE_ALL 0x1000 #endif #ifndef PERL_PV_ESCAPE_NOBACKSLASH # define PERL_PV_ESCAPE_NOBACKSLASH 0x2000 #endif #ifndef PERL_PV_ESCAPE_NOCLEAR # define PERL_PV_ESCAPE_NOCLEAR 0x4000 #endif #ifndef PERL_PV_ESCAPE_RE # define PERL_PV_ESCAPE_RE 0x8000 #endif #ifndef PERL_PV_PRETTY_NOCLEAR # define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR #endif #ifndef PERL_PV_PRETTY_DUMP # define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE #endif #ifndef PERL_PV_PRETTY_REGPROP # define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE #endif /* Hint: pv_escape * Note that unicode functionality is only backported to * those perl versions that support it. For older perl * versions, the implementation will fall back to bytes. */ #ifndef pv_escape #if defined(NEED_pv_escape) static char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); static #else extern char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); #endif #ifdef pv_escape # undef pv_escape #endif #define pv_escape(a,b,c,d,e,f) DPPP_(my_pv_escape)(aTHX_ a,b,c,d,e,f) #define Perl_pv_escape DPPP_(my_pv_escape) #if defined(NEED_pv_escape) || defined(NEED_pv_escape_GLOBAL) char * DPPP_(my_pv_escape)(pTHX_ SV *dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags) { const char esc = flags & PERL_PV_ESCAPE_RE ? '%' : '\\'; const char dq = flags & PERL_PV_ESCAPE_QUOTE ? '"' : esc; char octbuf[32] = "%123456789ABCDF"; STRLEN wrote = 0; STRLEN chsize = 0; STRLEN readsize = 1; #if defined(is_utf8_string) && defined(utf8_to_uvchr) bool isuni = flags & PERL_PV_ESCAPE_UNI ? 1 : 0; #endif const char *pv = str; const char * const end = pv + count; octbuf[0] = esc; if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) sv_setpvs(dsv, ""); #if defined(is_utf8_string) && defined(utf8_to_uvchr) if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) isuni = 1; #endif for (; pv < end && (!max || wrote < max) ; pv += readsize) { const UV u = #if defined(is_utf8_string) && defined(utf8_to_uvchr) isuni ? utf8_to_uvchr((U8*)pv, &readsize) : #endif (U8)*pv; const U8 c = (U8)u & 0xFF; if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) { if (flags & PERL_PV_ESCAPE_FIRSTCHAR) chsize = my_snprintf(octbuf, sizeof octbuf, "%"UVxf, u); else chsize = my_snprintf(octbuf, sizeof octbuf, "%cx{%"UVxf"}", esc, u); } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { chsize = 1; } else { if (c == dq || c == esc || !isPRINT(c)) { chsize = 2; switch (c) { case '\\' : /* fallthrough */ case '%' : if (c == esc) octbuf[1] = esc; else chsize = 1; break; case '\v' : octbuf[1] = 'v'; break; case '\t' : octbuf[1] = 't'; break; case '\r' : octbuf[1] = 'r'; break; case '\n' : octbuf[1] = 'n'; break; case '\f' : octbuf[1] = 'f'; break; case '"' : if (dq == '"') octbuf[1] = '"'; else chsize = 1; break; default: chsize = my_snprintf(octbuf, sizeof octbuf, pv < end && isDIGIT((U8)*(pv+readsize)) ? "%c%03o" : "%c%o", esc, c); } } else { chsize = 1; } } if (max && wrote + chsize > max) { break; } else if (chsize > 1) { sv_catpvn(dsv, octbuf, chsize); wrote += chsize; } else { char tmp[2]; my_snprintf(tmp, sizeof tmp, "%c", c); sv_catpvn(dsv, tmp, 1); wrote++; } if (flags & PERL_PV_ESCAPE_FIRSTCHAR) break; } if (escaped != NULL) *escaped= pv - str; return SvPVX(dsv); } #endif #endif #ifndef pv_pretty #if defined(NEED_pv_pretty) static char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); static #else extern char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); #endif #ifdef pv_pretty # undef pv_pretty #endif #define pv_pretty(a,b,c,d,e,f,g) DPPP_(my_pv_pretty)(aTHX_ a,b,c,d,e,f,g) #define Perl_pv_pretty DPPP_(my_pv_pretty) #if defined(NEED_pv_pretty) || defined(NEED_pv_pretty_GLOBAL) char * DPPP_(my_pv_pretty)(pTHX_ SV *dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags) { const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; STRLEN escaped; if (!(flags & PERL_PV_PRETTY_NOCLEAR)) sv_setpvs(dsv, ""); if (dq == '"') sv_catpvs(dsv, "\""); else if (flags & PERL_PV_PRETTY_LTGT) sv_catpvs(dsv, "<"); if (start_color != NULL) sv_catpv(dsv, D_PPP_CONSTPV_ARG(start_color)); pv_escape(dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR); if (end_color != NULL) sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color)); if (dq == '"') sv_catpvs(dsv, "\""); else if (flags & PERL_PV_PRETTY_LTGT) sv_catpvs(dsv, ">"); if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count) sv_catpvs(dsv, "..."); return SvPVX(dsv); } #endif #endif #ifndef pv_display #if defined(NEED_pv_display) static char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); static #else extern char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); #endif #ifdef pv_display # undef pv_display #endif #define pv_display(a,b,c,d,e) DPPP_(my_pv_display)(aTHX_ a,b,c,d,e) #define Perl_pv_display DPPP_(my_pv_display) #if defined(NEED_pv_display) || defined(NEED_pv_display_GLOBAL) char * DPPP_(my_pv_display)(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) { pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); if (len > cur && pv[cur] == '\0') sv_catpvs(dsv, "\\0"); return SvPVX(dsv); } #endif #endif #endif /* _P_P_PORTABILITY_H_ */ /* End of File ppport.h */ Net-SSLeay-1.92/README0000644000175000001440000003061114167653374012734 0ustar csnusersNet-SSLeay - Perl bindings for OpenSSL and LibreSSL By popular demand... -------------------- perl -MNet::SSLeay -e '($p)=Net::SSLeay::get_https("www.openssl.org", 443, "/"); print $p' for the released versions: https://metacpan.org/release/Net-SSLeay for the latest and possibly unstable version from git: https://github.com/radiator-software/p5-net-ssleay Prerequisites ------------- Perl 5.8.1 or higher. One of the following libssl implementations: * Any stable release of OpenSSL (https://www.openssl.org) in the 0.9.8 - 3.0 branches, except for OpenSSL 0.9.8 - 0.9.8b. * Any stable release of LibreSSL (https://www.libressl.org) in the 2.0 - 3.4 series, except for LibreSSL 3.2.2 and 3.2.3. Net-SSLeay may not compile or pass its tests against releases other than the ones listed above due to libssl API incompatibilities, or, in the case of LibreSSL, because of deviations from the libssl API. If you are using a version of OpenSSL or LibreSSL distributed by your operating system vendor, you may also need to install a "development" package containing the header files that correspond to the OpenSSL or LibreSSL library package. Examples include: * libssl-dev for OpenSSL on Debian and Ubuntu; * openssl-devel for OpenSSL on Red Hat Enterprise Linux and Fedora. On Linux, zlib is also required, even when libssl is built without support for TLS compression. zlib is probably also available via your Linux distribution's package manager, e.g.: * zlib1g-dev on Debian and Ubuntu; * zlib-devel on Red Hat Enterprise Linux and Fedora. A future version of Net-SSLeay will remove this requirement when building against a libssl without support for TLS compression. The same C compiler and options should be used to compile all of Perl, OpenSSL/LibreSSL, and Net-SSLeay. Mixing compilers and options often leads to build errors or run-time malfunctions that are difficult to debug. Installing ---------- Unix: # build or install OpenSSL as per instructions in that package gunzip bt # show stack trace gdb perl # run live with debugging # set break point in SSLeay.xs or in suspect function of OpenSSL > br XS_Net__SSLeay_connect > run yourscript.pl arg arg For gdb'ing make sure gdb finds all the relevant source code. This may mean that you must run perl and OpenSSL from the directories where the respective makefiles build them. You can also enable PR and PRN macros in SSLeay.xs and sprinkle even some more around the code to figure out what's happening. Some exotic configurations of perl may cause unstability: make sure OpenSSL uses the same malloc as perl. Recompile perl without threads. Try not using the PerlIO abstraction. If you need to tweak build for some platform, please let me know so I can fix it. Patches and gdb session dumps are also welcome. Copyright --------- Copyright (c) 1996-2003 Sampo Kellomäki Copyright (c) 2005-2010 Florian Ragwitz Copyright (c) 2005-2018 Mike McCauley Copyright (c) 2018- Chris Novakovic Copyright (c) 2018- Tuure Vartiainen Copyright (c) 2018- Heikki Vatiainen All rights reserved. License ------- Net-SSLeay is released under the terms of the Artistic License 2.0. For details, see the LICENSE file. Recommended reading ------------------- ===> HTTP protocol specification. It applies 100% to HTTPS too and doing password authentication is explained there. <=== If you are newbie interested in grabbing web pages from https servers, please read HTTP documentation from http://www.w3c.org/ before asking trivial questions. That document also covers the basic-auth FAQ (URLs like http://user:pass@host). Do not ask questions about authentication before consulting the HTTP specification. HTTPS is just HTTP in SSL transport. If you are doing advanced stuff, and don't find documentation you need, please try to extrapolate from OpenSSL documentation (which unfortunately is quite sparse) and the source code. If you run into build problems, especially regarding shared libraries, check your perl documentation, especially the perlxtut(1) man page, which gives excellent tutorial of the build process of XSUBs. perlxtut(1) perlxs(1) perlguts(1) perlcall(1) Say `perldoc Net::SSLeay' _NOW_! To download OpenSSL, see https://www.openssl.org/ Bug reports, patch submission, feature requests and git access to the latest source code etc., can be obtained at https://github.com/radiator-software/p5-net-ssleay Net-SSLeay-1.92/QuickRef0000644000175000001440000002157013320746140013474 0ustar csnusers(This quick reference list was contributed by anton@genua.de. Thanks, --Sampo) Net::SSLeay - useful function prototypes #---------------------------------- # Import frequently used functions #---------------------------------- use Net::SSLeay qw(die_now die_if_ssl_error); $errs = die_if_ssl_error($msg); Program dies with $msg if print_errs() was able to find and print some errors. $errs is 0 if no error occurred. die_now($msg); Program dies unconditionally! print_errs($msg) is used to print out errors before dying. #-------------------------- # Unsorted prototypes #-------------------------- $count = Net::SSLeay::print_errs($msg); Prints SSLeay-error stack with included $msg via 'warn'. Number of printed errors is returned (->$count). void Net::SSLeay::randomize($seed_file,$seed_string); void Net::SSLeay::randomize(); Load random bytes from $seed_file and from string $seed_string. Also uses $Net::SSLeay::random_device and $Net::SSLeay::how_random (Bits!) if used without parameters. void Net::SSLeay::RAND_seed($seed_string); Seeds randomgenerator with $seed_string. $bytes_read = Net::SSLeay::RAND_load_file($file_name, $how_much); Loads $how_much bytes randomness from file $file_name. $bytes_written = Net::SSLeay::RAND_write_file($file_name); Writes randomness to $file_name. void Net::SSLeay::load_error_strings(); Load SSL error messages to make error output more informative. void Net::SSLeay::ERR_load_crypto_strings(); Load crypto-API related error messages. void Net::SSLeay::SSLeay_add_ssl_algorithms(); Add support for supported ciphers. void Net::SSLeay::ENGINE_load_builtin_engines Load any built-in SSL engines suported by the underlybing OpenSSL void Net::SSLeay::ENGINE_register_all_complete Register any built-in SSL engines $ctx = Net::SSLeay::CTX_new(); Creates SSL-context. int Net::SSLeay::CTX_set_default_verify_paths($ctx); Load default location where to find certificates to verify remote certificates. This value is precompiled in SSLeay-Toolkit. int Net::SSLeay::CTX_load_verify_locations($ctx, $cert_file, $cert_dir); Set verify location. File with certificates or hashed directory. void Net::SSLeay::CTX_set_verify($ctx, $mode , \&verify_cb); Set mode and callback what to do with remote certificates. $mode: &Net::SSLeay::VERIFY_NONE &Net::SSLeay::VERIFY_PEER &Net::SSLeay::VERIFY_FAIL_IF_NO_PEER_CERT &Net::SSLeay::VERIFY_CLIENT_ONCE \&verify_cb: $ok = verify_cb($ok,$x509_store_ctx); Callback gets info if SSL-toolkit verified certificate ($ok) and certificate store location. void Net::SSLeay::CTX_set_default_passwd_cb($ctx,\&passwd_cb); If our RSA private key is passphrase protected and this callback is defined, then do not ask on the terminal but call the function. \&passwd_cb: $passwd = verify_cb($verify); If $verify is true, then the callback is supposed to make sure the returned password has been verified. $bool = Net::SSLeay::CTX_use_certificate_file($ctx,$cert,$type); $bool = Net::SSLeay::CTX_use_PrivateKey_file($ctx,$key,$type); Functions to load cert/key from filename ($cert/$key) with filetype $type into SSL-context. Filetypes are: &Net::SSLeay::FILETYPE_PEM $ssl = Net::SSLeay::new($ctx) Creates a SSL-session in context $ctx. Returns 0 on failure. $bool = Net::SSLeay::use_certificate_file($ssl,$cert,$type); $bool = Net::SSLeay::use_RSAPrivateKey_file($ssl,$key,$type); Functions to load cert/key from filename ($cert/$key) with filetype $type into SSL-session. Filetypes are: &Net::SSLeay::FILETYPE_PEM $bool = Net::SSLeay::set_fd($ssl, fileno(S)); Connect SSL-Toolkit with TCP-connection. $ssl SSL-Session S open socket $bool 0-failure 1-success $bool = Net::SSLeay::accept($ssl); Make SSL-handshake on hot connection. I am server! $ssl SSL-session $bool 0-failure 1-success $bool = Net::SSLeay::connect($ssl); Make SSL-handshake on hot connection. I am client! $ssl SSL-session $bool 0-failure 1-success $x509 = Net::SSLeay::get_peer_certificate($ssl); Get X509 certificate from SSL_session. $x509 = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx) Extract current certificate from cert-store. Cert-store is used in callbacks! $asn1_utctime = Net::SSLeay::X509_get_notBefore($x509); $asn1_utctime = Net::SSLeay::X509_get_notAfter($x509); $x509_name = Net::SSLeay::X509_get_subject_name($x509); $x509_name = Net::SSLeay::X509_get_issuer_name($x509); ($type1, $subject1, $type2, $subject2, ...) = Net::SSLeay::X509_get_subjectAltNames($x509) subjectAltName types as per x509v3.h GEN_* for example: GEN_DNS == 2 GEN_IPADD == 7 Return information from a certificate. $string = Net::SSLeay::P_ASN1_UTCTIME_put2string($asn1_utctime); Convert a asn1_utctime structure to a printable string. $string = Net::SSLeay::X509_NAME_oneline($x509_name); Convert a x509_name structure to a printable string. $string = Net::SSLeay::get_cipher($ssl) Return the active cipher from SSL-session $ssl. $string = Net::SSLeay::dump_peer_certificate($ssl) Return Subject/Issuer from peer-certificate in printable string. $string = Net::SSLeay::PEM_get_string_X509($x509); Returns a printable string containing the X509 certificate PEM encoded from $x509. $mode = Net::SSLeay::CTX_get_verify_mode($ctx) Return verify-mode previously set with CTX_set_verify in SSL-context. $mode = Net::SSLeay::get_verify_mode($ssl) Return verify-mode in SSL-session. $written_bytes = Net::SSLeay::ssl_write_all($ssl,$string); Write $string to SSL-session. This call returns undef if write failed. The whole string gets written! $written_bytes = $Net::SSLeay::write($ssl,$string); Write $string to SSL-session. This call returns immediately. SSL maybe wrote the string not completely - check yourself or use ssl_write_all! $string = Net::SSLeay::ssl_read_all($ssl,$how_much); Read everything available from the SSL-session and return it. Read a maximum of $how_much Bytes (default: 2000000000). $string = Net::SSLeay::read($ssl); Read one bunch of data from the SSL-session and return. void Net::SSLeay::free ($ssl); Free ressources from the SSL-session. void Net::SSLeay::CTX_free ($ctx); Free ressources from the SSL-context. #---------------------- # Hash functions #---------------------- # Several cryptographic digests (hash functions) are supported, possibly # including MD2, MD4, MD5, and RIPEMD160. $hash = Net::SSLeay:MD5($data); Computes md5 hash over $data. $hash is a binary string! Convert it to a printable with $string = unpack("H32",Net::SSLeay::MD5($data)); $hash = Net::SSLeay:RIPEMD160($data); Computes RIPEMD160 hash over $data. $hash is a binary string! Convert it to a printable with $string = unpack("H40",Net::SSLeay::RIPEMD160($data)); Note that some digests may not be available, depending on the version of OpenSSL used. #---------------------- # TCP-Connection hints #---------------------- # Make socket unbuffered after connect succeeded. # select(S); $| = 1; select(STDOUT); # Close connection by half... from client to server. This signals EOF to # server. (Clear some buffers, too...??) # Use this if finished with sending data to remote side. shutdown S, 1; # Finally close connection. Do this after reading everything availlable! # close S; #------------------ # TCP Client #------------------ # #!/usr/bin/perl -w use strict; use Socket; my ($remote,$port, $iaddr, $paddr, $proto, $line); $remote = shift || 'localhost'; $port = shift || 3000; # random port if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') } die "No port" unless $port; $iaddr = inet_aton($remote) || die "no host: $remote"; $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; connect(SOCK, $paddr) || die "connect: $!"; while (defined($line = )) { print $line; } close (SOCK) || die "close: $!"; exit; #-------------------- # TCP Server #-------------------- # #!/usr/bin/perl -Tw use strict; BEGIN { $ENV{PATH} = '/usr/ucb:/bin' } use Socket; use Carp; sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } my $EOL = "\015\012"; my $port = shift || 3000; my $proto = getprotobyname('tcp'); $port = $1 if $port =~ /(\d+)/; # untaint port number socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!"; listen(Server,SOMAXCONN) || die "listen: $!"; logmsg "server started on port $port"; my $paddr; for ( ; $paddr = accept(Client,Server); close Client) { my($port,$iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr,AF_INET); logmsg "connection from $name [", inet_ntoa($iaddr), "] at port $port"; print Client "Hello there, $name, it's now ", scalar localtime, $EOL; } Net-SSLeay-1.92/helper_script/0000755000175000001440000000000014167654753014720 5ustar csnusersNet-SSLeay-1.92/helper_script/generate-test-pki0000755000175000001440000017301414167654427020202 0ustar csnusers#!/usr/bin/env perl use 5.008001; use strict; use warnings; use English qw( $EVAL_ERROR $EXCEPTIONS_BEING_CAUGHT $EXECUTABLE_NAME $OS_ERROR $RS -no_match_vars ); use File::Basename qw(dirname); use File::Spec::Functions qw( catfile splitpath ); use File::Temp; use Getopt::Long qw(GetOptionsFromArray); use IPC::Run qw( start finish timeout ); our $VERSION = '1.92'; local $SIG{__DIE__} = sub { my ($cause) = @_; if ($EXCEPTIONS_BEING_CAUGHT) { return; } print STDERR $cause, "\n"; exit 1; }; my ( $args, $entities ) = eval { parse_options( \@ARGV ) } or fatal( 'Error while parsing command line options', $EVAL_ERROR ); eval { check_openssl_version( { min_version => '3.0.0-alpha7', min_version_match => qr{^3\.(?!0\.0-alpha[1-6])}, } ); } or fatal( 'OpenSSL minimum version check failed', $EVAL_ERROR ); my $tmp = eval { File::Temp->newdir( TEMPLATE => 'test-pki-XXXXXXXX', TMPDIR => 1, CLEANUP => 1, ); } or fatal( 'Could not create temporary working directory', $EVAL_ERROR ); my $pki_config = eval { pki_config() } or fatal( 'Could not load PKI configuration file', $EVAL_ERROR ); my $pki_tree = eval { pki_tree() } or fatal( 'Error while building PKI tree', $EVAL_ERROR ); generate_tree( $pki_tree, @{ $entities } ? { map { $_ => 1 } @{ $entities } } : undef ); sub parse_options { my ($argv) = @_; my $opts = { 'config' => catfile( dirname(__FILE__), 'pki.cfg' ), 'openssl-binary' => 'openssl', 'output' => undef, 'verbose' => 0, }; GetOptionsFromArray( $argv, $opts, 'config|c=s', 'openssl-binary|b=s', 'output|o=s', 'verbose|v', ); if ( !-e $opts->{config} ) { fatal("PKI configuration file $opts->{config} does not exist"); } if ( !defined $opts->{output} ) { fatal("an output directory must be given"); } if ( !-d $opts->{output} ) { fatal("output directory $opts->{output} does not exist"); } return wantarray ? ( $opts, $argv ) : $opts; } sub pki_config { open my $fh, '<:encoding(UTF-8)', $args->{config} or fatal( $args->{config}, $OS_ERROR ); my $config = do { local $RS = undef; eval <$fh> or do { ( my $error = $EVAL_ERROR ) =~ s{ at \(eval .+?\) }{ at $args->{config} }g; fatal( 'syntax error', $error ); }; }; close $fh; return $config; } sub pki_tree { my $children = {}; my $tree = {}; for my $entity ( keys %{$pki_config} ) { my $issuer = $pki_config->{$entity}->{cert}->{issuer}; if ( !exists $children->{$entity} ) { $children->{$entity} = {}; } if ( defined $issuer ) { if ( !exists $pki_config->{$issuer} ) { fatal("entity '$entity': issuer '$issuer' is not defined"); } $children->{$issuer}->{$entity} = $children->{$entity}; } else { $tree->{$entity} = $children->{$entity}; } } return $tree; } sub openssl_config { my (%tmpl) = @_; my $start = tell DATA; my $config = do { local $RS = undef; }; $config =~ s/\{\{ \s* (\w+) \s* \}\}/defined $tmpl{$1} ? $tmpl{$1} : ''/xeg; seek DATA, $start, 0; return $config; } sub subject_string { my (@rdns) = @_; my $string = q{}; while (@rdns) { my ( $key, $value ) = ( shift @rdns, shift @rdns ); if ( !defined $key || !defined $value ) { fatal('invalid key/value pair given in subject'); } # Certain characters in an RDN value must be escaped $value =~ s{([,\#+<>;"=/])}{\\$1}g; # Any leading space in an RDN value must be escaped $value =~ s{^ }{\\ }; $string .= "/$key=$value"; } return $string; } sub time_string { my ($time) = @_; if ( $time !~ m{^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$} ) { fatal('invalid timestamp'); } $time =~ s/[^\d]//g; $time =~ s/Z$//; return $time . 'Z'; } sub short_time_string { my ($time) = @_; ( $time = time_string($time) ) =~ s/^\d{2}//; return $time; } sub extensions_section { my ($exts) = @_; my @section; for my $ext ( sort keys %{$exts} ) { push @section, sprintf '%s = %s', $ext, ref $exts->{$ext} eq 'ARRAY' ? join ',', @{ $exts->{$ext} } : $exts->{$ext}; } return join "\n", @section; } sub issuer_chain { my ( $entity, $opts ) = @_; my @chain = ($entity); while ( defined $pki_config->{$entity}->{cert}->{issuer} ) { push @chain, $pki_config->{$entity}->{cert}->{issuer}; $entity = $pki_config->{$entity}->{cert}->{issuer}; } return \@chain; } sub generate_tree { my ( $tree, $entities ) = @_; for my $root ( sort keys %{$tree} ) { if ( defined $entities ) { if ( exists $entities->{$root} ) { for my $child ( keys %{ $tree->{$root} } ) { $entities->{$child} = 1; } generate_entity( $root, $entities ) or return 0; } generate_tree( $tree->{$root}, $entities ) or return 0; } else { generate_entity($root) or return 0; generate_tree( $tree->{$root} ) or return 0; } } return 1; } sub generate_entity { my ($entity) = @_; print "Generating PKI for entity '$entity'\n"; my $entity_cfg = $pki_config->{$entity}; my $entity_root = catfile( $args->{output}, $entity ); if ( !-e "$entity_root.key.pem" ) { print "\tPEM key: $entity_root.key.pem\n"; eval { generate_key( "$entity_root.key.pem", { algorithm => $entity_cfg->{key}->{algorithm}, size => $entity_cfg->{key}->{size}, } ) } or fatal( "Could not generate '$entity_root.key.pem'", $EVAL_ERROR ); print "\tEncrypted PEM key: $entity_root.key.enc.pem\n"; eval { convert_key( "$entity_root.key.pem", "$entity_root.key.enc.pem", { ( exists $entity_cfg->{key}->{passphrase} ? ( passphrase => $entity_cfg->{key}->{passphrase} ) : () ) } ) } or fatal( "Could not generate '$entity_root.key.enc.pem'", $EVAL_ERROR ); print "\tDER key: $entity_root.key.der\n"; eval { convert_key( "$entity_root.key.pem", "$entity_root.key.der", { format => 'der', } ); } or fatal( "Could not generate '$entity_root.key.der'", $EVAL_ERROR ); print "\tEncrypted DER key: $entity_root.key.enc.der\n"; eval { convert_key( "$entity_root.key.pem", "$entity_root.key.enc.der", { format => 'der', passphrase => 'test', } ); } or fatal( "Could not generate '$entity_root.key.enc.der'", $EVAL_ERROR ); } print "\tPEM CSR: $entity_root.csr.pem\n"; eval { generate_csr( "$entity_root.key.pem", "$entity_root.csr.pem", { md_algorithm => $entity_cfg->{csr}->{md_algorithm}, subject => $entity_cfg->{cert}->{subject}, } ); } or fatal( "Could not generate '$entity_root.csr.pem'", $EVAL_ERROR ); print "\tDER CSR: $entity_root.csr.der\n"; eval { convert_csr( "$entity_root.csr.pem", "$entity_root.csr.der", { format => 'der', } ); } or fatal( "Could not generate '$entity_root.csr.der'", $EVAL_ERROR ); print "\tPEM certificate: $entity_root.cert.pem\n"; my $issuer_root = defined $entity_cfg->{cert}->{issuer} ? catfile( $args->{output}, $entity_cfg->{cert}->{issuer} ) : $entity_root; my $issuer_cfg = defined $entity_cfg->{cert}->{issuer} ? $pki_config->{ $entity_cfg->{cert}->{issuer} } : undef; my @issuer_opts = defined $entity_cfg->{cert}->{issuer} ? ( issuer_cert_path => "$issuer_root.cert.pem", ) : (); eval { my $valid_from = time_string( $entity_cfg->{cert}->{valid_from} ) or fatal( 'valid_from', $EVAL_ERROR ); my $valid_until = time_string( $entity_cfg->{cert}->{valid_until} ) or fatal( 'valid_until', $EVAL_ERROR ); generate_cert( "$entity_root.csr.pem", "$issuer_root.key.pem", "$entity_root.cert.pem", { extensions => $entity_cfg->{cert}->{extensions}, md_algorithm => $entity_cfg->{cert}->{md_algorithm}, purpose => $entity_cfg->{cert}->{purpose}, serial => $entity_cfg->{cert}->{serial}, valid_from => $valid_from, valid_until => $valid_until, @issuer_opts, } ); } or fatal( "Could not generate '$entity_root.cert.pem'", $EVAL_ERROR ); print "\tDER certificate: $entity_root.cert.der\n"; eval { convert_cert( "$entity_root.cert.pem", "$entity_root.cert.der", { format => 'der', } ); } or fatal( "Could not generate '$entity_root.cert.der'", $EVAL_ERROR ); print "\tCertificate info: $entity_root.cert.dump\n"; eval { dump_cert_info( "$entity_root.cert.pem", "$entity_root.cert.dump" ); } or fatal( "Could not generate '$entity_root.cert.dump'", $EVAL_ERROR ); print "\tPEM certificate chain: $entity_root.certchain.pem\n"; eval { generate_cert_chain( [ map { catfile( $args->{output}, "$_.cert.pem" ) } @{ issuer_chain( $entity ) } ], "$entity_root.certchain.pem" ); } or fatal( "Could not generate '$entity_root.certchain.pem'", $EVAL_ERROR ); print "\tDER certificate chain: $entity_root.certchain.der\n"; eval { generate_cert_chain( [ map { catfile( $args->{output}, "$_.cert.der" ) } @{ issuer_chain( $entity ) } ], "$entity_root.certchain.der" ) } or fatal( "Could not generate '$entity_root.certchain.der'", $EVAL_ERROR ); if ( exists $entity_cfg->{cert}->{revoke_reason} ) { print "\tPEM CRL for signing entity: $issuer_root.crl.pem\n"; eval { revoke_cert( "$entity_root.cert.pem", "$issuer_root.key.pem", "$issuer_root.cert.pem", "$issuer_root.crl.pem", { crl_last_update => $issuer_cfg->{crl}->{last_update}, crl_md_algorithm => $issuer_cfg->{crl}->{md_algorithm}, crl_next_update => $issuer_cfg->{crl}->{next_update}, crl_number => $issuer_cfg->{crl}->{number}, reason => $entity_cfg->{cert}->{revoke_reason}, time => $entity_cfg->{cert}->{revoke_time}, } ); } or fatal( "Could not generate '$issuer_root.crl.pem'", $EVAL_ERROR ); print "\tDER CRL for signing entity: $issuer_root.crl.der\n"; eval { convert_crl( "$issuer_root.crl.pem", "$issuer_root.crl.der", { format => 'der', } ); } or fatal( "Could not generate '$issuer_root.crl.der'", $EVAL_ERROR ); } my @extra_certs = map { catfile( $args->{output}, "$_.cert.pem" ) } @{ issuer_chain( $entity ) }; # The certificate for this entity is at the start of the chain, but we just # want the certificates in the issuer chain shift @extra_certs; my @extra_certs_opts = @extra_certs ? ( extra_certs => \@extra_certs, ) : (); print "\tPKCS#12 archive: $entity_root.p12\n"; eval { generate_pkcs12( "$entity_root.key.pem", "$entity_root.cert.pem", "$entity_root.p12", { name => "$entity: unencrypted, no certificate chain", } ); } or fatal( "Could not generate '$entity_root.p12'", $EVAL_ERROR ); print "\tPKCS#12 archive with certificate chain: ", "$entity_root.certchain.p12\n"; eval { generate_pkcs12( "$entity_root.key.pem", "$entity_root.cert.pem", "$entity_root.certchain.p12", { name => "$entity: unencrypted, certificate chain", @extra_certs_opts, } ); } or fatal( "Could not generate '$entity_root.certchain.p12'", $EVAL_ERROR ); print "\tEncrypted PKCS#12 archive: $entity_root.enc.p12\n"; eval { generate_pkcs12( "$entity_root.key.pem", "$entity_root.cert.pem", "$entity_root.enc.p12", { name => "$entity: encrypted, no certificate chain", passphrase => $entity_cfg->{pkcs12}->{passphrase}, } ); } or fatal( "Could not generate '$entity_root.enc.p12'", $EVAL_ERROR ); print "\tEncrypted PKCS#12 archive with certificate chain: ", "$entity_root.certchain.enc.p12\n"; eval { generate_pkcs12( "$entity_root.key.pem", "$entity_root.cert.pem", "$entity_root.certchain.enc.p12", { name => "$entity: encrypted, certificate chain", passphrase => $entity_cfg->{pkcs12}->{passphrase}, @extra_certs_opts, } ); } or fatal( "Could not generate '$entity_root.certchain.enc.p12'", $EVAL_ERROR ); return 1; } sub generate_key { my ( $out_key_path, $params ) = @_; my $algorithms = { 'ec' => { openssl_name => 'EC', }, 'ed25519' => { openssl_name => 'ED25519', }, 'ed448' => { openssl_name => 'ED448', }, 'rsa' => { openssl_name => 'RSA', size_param => 'rsa_keygen_bits', }, 'rsa-pss' => { openssl_name => 'RSA-PSS', size_param => 'rsa_keygen_bits', }, 'x25519' => { openssl_name => 'X25519', }, 'x448' => { openssl_name => 'X448', }, }; if ( !exists $params->{algorithm} ) { fatal('missing key algorithm'); } if ( !exists $algorithms->{ $params->{algorithm} } ) { fatal("unknown key algorithm '$params->{algorithm}'"); } my $algorithm = $algorithms->{ $params->{algorithm} }; my @genpkey_opts; if ( exists $algorithm->{size_param} ) { if ( !exists $params->{size} ) { fatal("key algorithm '$params->{algorithm}' requires a key size"); } @genpkey_opts = ( '-pkeyopt', "$algorithm->{size_param}:$params->{size}" ); } # "openssl genpkey" exports keys in PKCS#8 format (which isn't recognised by # OpenSSL 0.9.8), and there's no way to export in traditional SSLeay format # directly - write the PKCS#8-formatted key to a temporary file, and then # use "openssl pkey" to convert it to SSLeay format my $out_key_name = ( splitpath($out_key_path) )[2]; my $tmp_key_path = catfile( $tmp->dirname(), $out_key_name ); openssl_cmd( [ 'genpkey', '-out', $tmp_key_path, '-algorithm', $algorithm->{openssl_name}, @genpkey_opts, ] ); return openssl_cmd( [ 'pkey', '-in', $tmp_key_path, '-out', $out_key_path, '-traditional', ] ); } sub convert_key { my ( $in_key_path, $out_key_path, $params ) = @_; my $formats = { pem => 'PEM', der => 'DER', }; ( my $in_format = $in_key_path ) =~ s{.*\.}{}; my $out_format = delete $params->{format} || 'pem'; if ( !exists $formats->{$in_format} ) { fatal("unknown key input format '$in_format'"); } if ( !exists $formats->{$out_format} ) { fatal("unknown key output format '$out_format'"); } my @encrypt_opts = exists $params->{passphrase} ? ( '-aes128', '-passout', 'stdin', ) : (); return openssl_cmd( [ 'pkey', '-in', $in_key_path, '-inform', $formats->{$in_format}, '-out', $out_key_path, '-outform', $formats->{$out_format}, '-traditional', @encrypt_opts, ], $params->{passphrase} ); } sub generate_csr { my ( $in_key_path, $out_csr_path, $params ) = @_; my $formats = { pem => 'PEM', der => 'DER', }; my $format = delete $params->{format} || 'pem'; if ( !exists $formats->{$format} ) { fatal("unknown CSR output format '$format'"); } if ( !exists $params->{md_algorithm} ) { fatal('missing message digest algorithm'); } my $digest_opt = '-' . $params->{md_algorithm}; return openssl_cmd( [ 'req', '-config', '-', '-new', '-key', $in_key_path, '-out', $out_csr_path, '-outform', $formats->{$format}, '-subj', subject_string( @{ $params->{subject} } ), '-multivalue-rdn', $digest_opt, ], openssl_config() ); } sub convert_csr { my ( $in_csr_path, $out_csr_path, $params ) = @_; my $formats = { pem => 'PEM', der => 'DER', }; ( my $in_format = $in_csr_path ) =~ s{.*\.}{}; my $out_format = delete $params->{format} || 'pem'; if ( !exists $formats->{$in_format} ) { fatal("unknown CSR input format '$in_format'"); } if ( !exists $formats->{$out_format} ) { fatal("unknown CSR output format '$out_format'"); } return openssl_cmd( [ 'req', '-in', $in_csr_path, '-inform', $formats->{$in_format}, '-out', $out_csr_path, '-outform', $formats->{$out_format}, ] ); } sub generate_cert { my ( $in_csr_path, $issuer_key_path, $out_cert_path, $params ) = @_; if ( !exists $params->{md_algorithm} ) { fatal('missing message digest algorithm'); } my @signing_opts = exists $params->{issuer_cert_path} ? ( '-cert', $params->{issuer_cert_path}, ) : ( '-selfsign', '-cert', 'ignored', ); my $tmp_root = do { my $file = ( splitpath($issuer_key_path) )[2]; $file =~ s/(?:\.key)?\.(?:pem|der)$//; my $dir = catfile( $tmp->dirname(), $file ); if ( !-d $dir ) { mkdir $dir or fatal( "could not create directory $dir", $OS_ERROR ); } $dir; }; my $serial_file = catfile( $tmp_root, 'serial' ); open my $serial_fh, '>', $serial_file or fatal( "could not write serial file $serial_file", $OS_ERROR ); printf {$serial_fh} '%02x', $params->{serial}; close $serial_fh; my $db_file = catfile( $tmp_root, 'db' ); open my $db_fh, '>>', $db_file or fatal( "could not touch database file $db_file", $OS_ERROR ); close $db_fh; return openssl_cmd( [ 'ca', '-verbose', '-batch', '-config', '-', '-name', 'ca_conf', '-in', $in_csr_path, '-out', $out_cert_path, '-keyfile', $issuer_key_path, '-startdate', $params->{valid_from}, '-enddate', $params->{valid_until}, '-md', $params->{md_algorithm}, '-extensions', 'exts_' . $params->{purpose}, '-notext', '-utf8', '-multivalue-rdn', @signing_opts, ], openssl_config( extensions => ( exists $params->{extensions} ? extensions_section( $params->{extensions} ) : q{} ), certs_path => $tmp_root, database_path => $db_file, serial_path => $serial_file, ) ); } sub convert_cert { my ( $in_cert_path, $out_cert_path, $params ) = @_; my $formats = { pem => 'PEM', der => 'DER', }; ( my $in_format = $in_cert_path ) =~ s{.*\.}{}; my $out_format = delete $params->{format} || 'pem'; if ( !exists $formats->{$in_format} ) { fatal("unknown certificate input format '$in_format'"); } if ( !exists $formats->{$out_format} ) { fatal("unknown certificate output format '$out_format'"); } return openssl_cmd( [ 'x509', '-in', $in_cert_path, '-inform', $formats->{$in_format}, '-out', $out_cert_path, '-outform', $formats->{$out_format}, ] ); } sub dump_cert_info { my ( $in_cert_path, $out_dump_path ) = @_; my $cwd = dirname(__FILE__); open my $out_fh, '>', $out_dump_path or fatal( "could not write $out_dump_path", $OS_ERROR ); my $run = eval { start( [ $EXECUTABLE_NAME, catfile( $cwd, '..', 'examples', 'x509_cert_details.pl' ), '-dump', '-pem', $in_cert_path ], '>', sub { print {$out_fh} $_[0]; }, '2>', sub { if ( $args->{verbose} ) { printf "[x509_cert_details.pl stderr] %s\n", $_[0]; } } ); } or fatal( 'could not run examples/x509_cert_details.pl', $EVAL_ERROR ); $run->finish(); close $out_fh; if ( $run->result() != 0 ) { fatal( 'examples/x509_cert_details.pl exited with exit code ' . $run->result() ); } return 1; } sub generate_cert_chain { my ( $in_cert_paths, $out_cert_path ) = @_; open my $out_fh, '>', $out_cert_path or fatal( "could not write certificate chain file $out_cert_path", $OS_ERROR ); for my $in ( @{$in_cert_paths} ) { open my $in_fh, '<', $in or fatal( "could not read certificate file $in", $OS_ERROR ); my $cert = do { local $RS = undef; <$in_fh> }; print {$out_fh} $cert; close $in_fh; } close $out_fh; return 1; } sub revoke_cert { my ( $in_cert_path, $issuer_key_path, $issuer_cert_path, $out_crl_path, $params ) = @_; my $tmp_root = do { my ( undef, undef, $file ) = splitpath($issuer_key_path); $file =~ s/(?:\.key)?\.(?:pem|der)$//; my $dir = catfile( $tmp->dirname(), $file ); if ( !-d $dir ) { mkdir $dir or fatal( "could not create directory $dir", $OS_ERROR ); } $dir; }; my $serial_file = catfile( $tmp_root, 'serial' ); my ( $stdout, $stderr ) = openssl_cmd( [ 'x509', '-in', $in_cert_path, '-noout', '-serial', ] ); ( my $in_cert_serial = join "\n", @{$stdout} ) =~ s/^serial=//; if ( $in_cert_serial !~ /^[\da-f]+$/i ) { fatal('could not get serial number for revoked certificate'); } my $db_file = catfile( $tmp_root, 'db' ); open my $db_fh, '<', $db_file or fatal( "could not read database file $db_file", $OS_ERROR ); my @entries; while ( defined( my $entry = <$db_fh> ) ) { chomp $entry; my @fields = split /\t/, $entry; if ( $fields[3] eq $in_cert_serial ) { $fields[0] = 'R'; $fields[2] = short_time_string( $params->{time} ); if ( defined $params->{reason} ) { $fields[2] .= ',' . $params->{reason}; } } push @entries, join "\t", @fields; } close $db_fh; open $db_fh, '>', $db_file or fatal( "could not write database file $db_file", $OS_ERROR ); for my $entry (@entries) { print {$db_fh} $entry, "\n"; } close $db_fh; my $crl_number_file = catfile( $tmp_root, 'crl_number' ); open my $crl_number_fh, '>', $crl_number_file or fatal( "could not write CRL number file $crl_number_file", $OS_ERROR ); printf {$crl_number_fh} '%02x', $params->{crl_number}; close $crl_number_fh; return openssl_cmd( [ 'ca', '-verbose', '-batch', '-gencrl', '-config', '-', '-name', 'ca_conf', '-keyfile', $issuer_key_path, '-cert', $issuer_cert_path, '-out', $out_crl_path, '-crl_lastupdate', time_string( $params->{crl_last_update} ), '-crl_nextupdate', time_string( $params->{crl_next_update} ), '-md', $params->{crl_md_algorithm}, ], openssl_config( certs_path => $tmp_root, crl_number_path => $crl_number_file, database_path => $db_file, serial_path => $serial_file, ) ); } sub convert_crl { my ( $in_crl_path, $out_crl_path, $params ) = @_; my $formats = { pem => 'PEM', der => 'DER', }; ( my $in_format = $in_crl_path ) =~ s{.*\.}{}; my $out_format = delete $params->{format} || 'pem'; if ( !exists $formats->{$in_format} ) { fatal("unknown CRL input format '$in_format'"); } if ( !exists $formats->{$out_format} ) { fatal("unknown CRL output format '$out_format'"); } return openssl_cmd( [ 'crl', '-in', $in_crl_path, '-inform', $formats->{$in_format}, '-out', $out_crl_path, '-outform', $formats->{$out_format}, ] ); } sub generate_pkcs12 { my ( $in_key_path, $in_cert_path, $out_p12_path, $params ) = @_; my $cert_chain_path; if ( exists $params->{extra_certs} ) { my ( undef, undef, $file ) = splitpath($in_key_path); $file =~ s/(?:\.key)?\.(?:pem|der)$//; my $dir = catfile( $tmp->dirname(), $file ); if ( !-d $dir ) { mkdir $dir or fatal( 'could not create directory $dir', $OS_ERROR ); } $cert_chain_path = catfile( $dir, 'pkcs12_cert_chain.pem' ); generate_cert_chain( $params->{extra_certs}, $cert_chain_path ); } my @name_opt = exists $params->{name} ? ( '-name', $params->{name}, ) : (); my @cert_opt = exists $params->{extra_certs} ? ( '-certfile', $cert_chain_path, ) : (); my @encrypt_opts = exists $params->{passphrase} ? ( '-passout', 'stdin', '-keypbe', 'pbeWithSHA1And3-KeyTripleDES-CBC', '-certpbe', 'pbeWithSHA1And3-KeyTripleDES-CBC', ) : ( '-passout', 'pass:', '-keypbe', 'NONE', '-certpbe', 'NONE', '-nomaciter', ); return openssl_cmd( [ 'pkcs12', '-export', '-inkey', $in_key_path, '-in', $in_cert_path, '-out', $out_p12_path, '-rand', $in_key_path, '-no-CAfile', '-no-CApath', @name_opt, @cert_opt, @encrypt_opts, ], $params->{passphrase} ); } sub check_openssl_version { my ($params) = @_; my $min_version = delete $params->{min_version} or fatal('missing minimum OpenSSL version'); my $min_version_match = delete $params->{min_version_match} or fatal('missing minimum OpenSSL version regex'); my ( $stdout, $stderr ); my $run = eval { start( [ 'openssl', 'version' ], \undef, \$stdout, \$stderr, timeout( 3 ) ); } or fatal( "could not run `openssl version`", $EVAL_ERROR ); $run->finish(); if ( $run->result() != 0 ) { fatal( "`openssl version` exited with exit code " . $run->result() ); } my ($openssl_version) = $stdout =~ m{^OpenSSL (.+?) } or fatal("`openssl` is not the OpenSSL command line utility"); if ( $openssl_version !~ $min_version_match ) { fatal( "OpenSSL >= $min_version required, but `openssl` is version " . $openssl_version ); } my $net_ssleay_version = eval { use Net::SSLeay; Net::SSLeay::SSLeay_version( Net::SSLeay::SSLEAY_VERSION() ); } or fatal( 'could not load Net::SSLeay', $EVAL_ERROR ); ($net_ssleay_version) = $net_ssleay_version =~ m{^OpenSSL (.+?) } or fatal('Net::SSLeay was not built against OpenSSL'); if ( $net_ssleay_version !~ $min_version_match ) { fatal( "Net::SSLeay must be built against OpenSSL >= $min_version, but " . "it is built against version $net_ssleay_version" ); } return 1; } sub openssl_cmd { my ( $opts, $stdin ) = @_; my $wantarray = wantarray; my $stdout = []; my $stderr = []; my $print = sub { my ( $prefix, $data ) = @_; for my $line ( split /\r?\n/, $data ) { printf "[OpenSSL %s] %s\n", $prefix, $line; } }; if ( $args->{verbose} ) { print "Running `openssl ", join( q{ }, @{$opts} ), "`\n"; } my $cmd = [ 'openssl', @{$opts} ]; my $cmd_string = join ' ', @{$cmd}; my $run = eval { start( $cmd, \$stdin, sub { if ($wantarray) { chomp $_[0]; push @{$stdout}, $_[0]; } elsif ( $args->{verbose} ) { $print->( 'stdout', $_[0] ); } }, sub { if ($wantarray) { chomp $_[0]; push @{$stderr}, $_[0]; } elsif ( $args->{verbose} ) { $print->( 'stderr', $_[0] ); } } ); } or fatal( "failed to run `$cmd_string`", $EVAL_ERROR ); $run->finish(); if ( $run->result() != 0 ) { fatal( "`$cmd_string` exited with exit code " . $run->result() ); } return $wantarray ? ( $stdout, $stderr ) : 1; } sub fatal { my ( $message, $cause ) = @_; die Error->new( $message, $cause ); } package Error; use overload ( q{""} => sub { my ($self) = @_; return defined $self->{cause} ? "$self->{message}: $self->{cause}" : $self->{message}; }, fallback => 1, ); sub new { my ( $class, $message, $cause ) = @_; return bless { message => $message, cause => $cause, }, $class; } package main; =pod =encoding utf-8 =head1 NAME C - Generate a PKI for the Net-SSLeay test suite =head1 VERSION This document describes version 1.92 of C. =head1 USAGE # With openssl >= 3.0.0-alpha7 in PATH, and a version of Net::SSLeay built # against OpenSSL >= 3.0.0-alpha7 in PERL5LIB: generate-test-pki \ -c pki.cfg \ -o pki-output-dir =head1 DESCRIPTION The Net-SSLeay test suite relies on a dummy X.509 public key infrastructure (PKI). Occasionally, this PKI needs to be modified - for example, to add a certificate with certain properties when writing a new test - but maintaining it by hand is time-consuming, difficult, and error-prone. C simplifies maintenance of the PKI by generating it from scratch using the OpenSSL command line utility, based on the structure defined in a simple configuration file. The files it generates can then be used in Net-SSLeay test scripts. =head1 DEPENDENCIES C requires at least version 3.0.0-alpha7 of the OpenSSL command line utility to be present either in I as C or at the path given by the B<-b> option (see L). Additionally, the first occurrance of Net::SSLeay in I must be built against at least version 3.0.0-alpha7 of OpenSSL. LibreSSL is not supported, since its command line utility lacks some of the functionality relied on by this program. =head1 OPTIONS C accepts the following command line options: =over 4 =item * B<-b I>, B<--openssl-binary=I>: the path to the OpenSSL binary to invoke when performing PKI generation operations. Defaults to C (i.e. the first occurrence of C in I). =item * B<-c I>, B<--config=I>: the path to the configuration file defining the PKI to generate. See L for a description of the expected format. =item * B<-o I>, B<--output=I>: the path to the directory to which the PKI's files (see L) will be written. The directory must already exist. Existing files whose names collide with files written by this program will be overwritten without warning; other existing files will be left alone. =item * B<-v>, B<--verbose>: show the output of C and C when they are invoked. =back =head1 CONFIGURATION The configuration file is an anonymous Perl hash whose keys define the names of the PKI's entities and whose values define each entity's properties: { 'entity-name' => { 'key' => { ... }, # Private key properties 'csr' => { ... }, # Certificate signing request (CSR) properties 'cert' => { ... }, # Certificate properties 'pkcs12' => { ... }, # PKCS#12 archive properties 'crl' => { ... }, # Certificate revocation list (CRL) properties # (optional; for CA entities only) }, ... } =head2 key An anonymous hash defining properties relating to the entity's private key. Valid keys: =over 4 =item * B: the public key algorithm to use when generating the private key. Must be one of C, C, C, C, C, C, or C. =item * B: the passphrase under which to encrypt the private key. Used only when generating encrypted forms of the key. =item * B: the size of the public key to generate, in bits. Used only when B is C, C, or C. =back =head2 csr An anonymous hash defining properties relating to the entity's PKCS#10 certificate signing request (CSR). The value of the B key in L will be used to generate a subject name for the CSR. Valid keys: =over 4 =item * B: the message digest algorithm used to sign the CSR. May be any value supported by C; commonly-supported values include C, C, and C. =back =head2 cert An anonymous hash defining properties relating to the entity's X.509 v3 certificate. Valid keys: =over 4 =item * B: optional; an anonymous hash defining the X.509 v3 extensions that should be specified in the certificate. Keys are expected to be extension field names as they appear in L, and values are expected to be either strings or anonymous arrays of strings (whose elements will be concatenated and delimited with commas), e.g.: { basicConstraints => 'critical,CA:false', certificatePolicies => [ '1.2.3', '4.5.6' ], # Becomes '1.2.3,4.5.6' } =item * B: a top-level key denoting the entity that should sign this certificate. If undefined, the entity's certificate will be self-signed. =item * B: the message digest algorithm used to sign the certificate. May be any value supported by C; commonly-supported values include C, C, and C. =item * B: a string describing the purpose of the certificate. The value given here will define reasonable values for the I, I, I, and/or I X.509 v3 extension fields. Must be one of C, C, C, C, or C (in which case no default values will be defined for any of the aforementioned fields, allowing for complete control of the fields that appear in the certificate via the B key). =item * B: optional; the reason for revoking the certificate. Must be one of C, C, C, C, C, C, or C. =item * B: optional; a timestamp string in I format denoting the time at which the certificate was revoked, in the UTC time zone. Must be specified if B is specified. =item * B: a decimal integer denoting the certificate's serial number. Must be unique among the serial numbers of all certificates issued by the entity given in B. =item * B: an anonymous array denoting the certificate's subject name; elements are expected to alternate between field names in either short or long format and values for those fields, e.g.: [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', commonName => 'test.net-ssleay.example', ] The order of the fields is preserved when generating the Distinguished Name string. =item * B: a timestamp string in I format denoting the time from which the certificate is valid, in the UTC time zone. =item * B: a timestamp string in I format denoting the time until which the certificate is valid, in the UTC time zone. =back =head2 pkcs12 An anonymous hash defining properties relating to the entity's PKCS#12 archives. Valid keys: =over 4 =item * B: the passphrase under which to encrypt the private key stored in the archive. Used only when generating archives that contain encrypted forms of the private key. =back =head2 crl An anonymous hash defining properties relating to the entity's certificate revocation list (CRL). Only used when the entity is a certificate authority and at least one of the certificates it issues requires revocation. Valid keys: =over 4 =item * B: a timestamp string in I format denoting the time at which the CRL was last updated, in the UTC time zone. =item * B: the message digest algorithm used to sign the CRL. May be any value supported by C; commonly-supported values include C, C, and C. =item * B: a timestamp string in I format denoting the time at which the CRL is next expected to be updated, in the UTC time zone. =item * B: a decimal integer denoting the CRL number. =back =head1 OUTPUT For each entity I declared in the configuration file, C ensures the following set of files exists: =over 4 =item * B: a private key in PEM format. Will not be generated if it already exists; the key in the existing file will be used instead. =item * B: the file above, encrypted with AES-128 using the passphrase given in the configuration file (see L). =item * B: B in DER format. =item * B: the file above, encrypted with AES-128 using the passphrase given in the configuration file (see L). =item * B: a certificate signing request in PEM format. =item * B: the file above in DER format. =item * B: a certificate in PEM format, signed by the entity given in the configuration file (see L). =item * B: the file above in DER format. =item * B: the output of C. C is a Net-SSLeay example script whose output is used by the test suite to verify the correct operation of various libssl certificate information functions. =item * B: the certificate chain in PEM format, starting with I's certificate and ending with the root CA certificate. =item * B: the file above, with certificates in DER format. =item * B: a PKCS#12 archive containing a private key and a certificate. =item * B: the file above, with the private key encrypted with AES-128 using the passphrase given in the configuration file (see L). =item * B: a PKCS#12 archive containing a private key and a certificate chain starting with I's certificate and ending with the root CA certificate. =item * B: the file above, with the private key encrypted with AES-128 using the passphrase given in the configuration file (see L). =back Additionally, for entities that sign and then revoke at least one certificate, C outputs the following files: =over 4 =item * B: a certificate revocation list (version 2) in PEM format. =item * B: the file above in DER format. =back =head1 DIAGNOSTICS C outputs a diagnostic message to stderr and immediately exits with exit code 1 if an error occurs. Error messages listed below indicate invalid input or a problem with the state of the system that can usually be fixed. Error messages not listed below are internal and should never be encountered under normal operation; please report any occurrences of such errors as bugs (see L). =over =item B does not exist> The PKI configuration file at I, as specified by the B<-c> command line option (or C in the same directory as C if a value for B<-c> was not specified), does not exist. Ensure C exists, or speicify an alternative path with B<-c I>. =item B The B<-o> option is compulsory, and has no default value. Pass the path to a directory in which the output files described in L should be written with B<-o I>. =item B does not exist> C does not attempt to create the directory at the path given by the B<-o> option; it must already exist and be writable. =item B: I> The configuration file at I could not be loaded because of I, which is probably an OS-level error. Ensure the file at I is readable. =item B> The configuration file could not be parsed because of I, which is likely a Perl syntax error. Ensure the configuration file is valid Perl and meets the specification given in L. =item B> C attempted to check the version of the OpenSSL command line utility currently in use by invoking C, and expected it to exit with exit code 0 (indicating success) but it actually exited with exit code I (indicating failure). Check that the first occurrence of C in I is in fact the OpenSSL command line utility, then run C with the B<-v> option to see the full output from C, which may help diagnose the problem further. =item B C attempted to check the version of the OpenSSL command line utility currently in use by invoking C, but its output was inconsistent with the output format known to be used by OpenSSL. Check that the first occurrence of C in I is in fact the OpenSSL command line utility (and not the LibreSSL command line utility), then run C with the B<-v> option to see the full output from C, which may help diagnose the problem further. =item B= I required, but `openssl` is version I> C relies on features of the OpenSSL command line utility that were added in version I, but the first occurrence of C in I is version I, which is insufficient. It may be necessary to compile a newer version of OpenSSL from the source code and prepend the directory containing the command line utility to I in order to solve this problem. =item B> C attempted to check the version of OpenSSL that Net::SSLeay is built against, but was unable to import Net::SSLeay because of I. Ensure the first occurrence of Net::SSLeay in I can be imported by Perl. =item B C relies on features of Net::SSLeay that are only available when it is built against OpenSSL, but the first occurrence of Net::SSLeay in I is built against LibreSSL. Rebuild Net::SSLeay against OpenSSL and ensure the rebuilt version is the first occurrence of Net::SSLeay in I. =item B= I, but it is built against version I> C relies on features of Net::SSLeay that are only available when it is built against OpenSSL version I, but the first occurrence of Net::SSLeay in I is built against OpenSSL I. Rebuild Net::SSLeay against a newer version OpenSSL - ideally the same version as the OpenSSL command line utility - and ensure the rebuilt version is the first occurrence of Net::SSLeay in I. =item B> C attempted to create a directory to store some temporary files that are necessary to generate the output files, but was unable to create the directory because of I (which is probably an OS-level error). Ensure the system's temporary directory is writable. =item B': issuer 'I' is not defined> The configuration file defines an entity I whose issuer (per the the value of its C<{cert}-E{issuer}> key) does not exist. Check that I is not misnamed and that the value of C<{cert}-E{issuer}> for I is correct. =item B.key.pem': missing key algorithm> The configuration file defines an entity I with no value for C<{key}-E{algorithm}>. See L for a list of acceptable values. =item B.key.pem': unknown key algorithm 'I'> The configuration file defines an entity I with the value I for C<{key}-E{algorithm}>, but this is not a known public key algorithm. See L for a list of acceptable values. =item B.key.pem': key algorithm 'I' requires a key size> The configuration file defines an entity I with the value I for C<{key}-E{algorithm}>, but I requires a key size to be defined in C<{key}-E{size}>. Define a valid key size for this entity's private key. See L for more information. =item B.csr.pem': invalid key/value pair given in subject> The configuration file defines an entity I with at least one undefined element in its value for C<{cert}-E{subject}>. Undefined elements cannot be stringified, so the subject could not be transformed into a Distinguished Name string. See L for more information of the expected format for C<{cert}-E{subject}>. =item B.csr.pem': missing message digest algorithm> The configuration file defines an entity I with no value for C<{csr}-E{md_algorithm}>. See L for possible values. =item B.cert.pem': valid_from: invalid timestamp> The configuration file defines an entity I with an invalid timestamp for its value of C<{cert}-E{valid_from}>. See L for more information on the expected timestamp format. =item B.cert.pem': valid_until: invalid timestamp> The configuration file defines an entity I with an invalid timestamp for its value of C<{cert}-E{valid_to}>. See L for more information on the expected timestamp format. =item B.cert.pem': missing message digest algorithm> The configuration file defines an entity I with no value for C<{cert}-E{md_algorithm}>. See L for possible values. =item B.cert.pem': could not create directory I: I> C attempted to create a temporary directory at I to store intermediate files that are necessary to generate I's certificate, but was unable to do so because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B.cert.pem': could not write serial file I: I> C attempted to write an intermediate file to I (a subdirectory of a temporary directory it created earlier) that is necessary to generate I's certificate, but was unable to do so because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B.cert.dump': could not write I: I> C attempted to write information about I's certificate to the file at I, but was unable to do so because of I, which is probably an OS-level error. Ensure the file at I is writable. =item B.cert.dump': could not run examples/x509_cert_details.pl: I> C attempted to invoke the Perl script C (part of the Net-SSLeay source distribution) to produce an output file containing information about I's certificate, but was unable to invoke the script because of I. Ensure that the script is located at C<../examples/x509_cert_details.pl> relative to the path to C, that it can be executed given the values of I and I that are inherited by C, and that a suitable version of Net::SSLeay is present in I (see L for more information). =item B.cert.dump': examples/x509_cert_details.pl exited with exit code I> C invoked the Perl script C (part of the Net-SSLeay source distribution) to produce an output file containing information about I's certificate, and expected it to exit with exit code 0 (indicating success) but it actually exited with exit code I (indicating failure). Run C with the B<-v> option to see the full output from C, which may help diagnose the problem further. =item B.certchain.pem': could not write certificate chain file I: I> =item B.certchain.der': could not write certificate chain file I: I> C attempted to concatenate the certificates in I's issuer chain (in either format) and write them to I, but was unable to do so because of I, which is probably an OS-level error. Ensure the file at I is writable. =item B.certchain.pem': could not read certificate file I: I> =item B.certchain.der': could not read certificate file I: I> C attempted to read a certificate in I's issuer chain (in either format) at I, but was unable to do so because of I, which is probably an OS-level error. Ensure the file at I is readable. =item B.crl.pem': could not create directory I: I> C attempted to create a temporary directory at I to store intermediate files that are necessary to generate I's CRL, but was unable to do so because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B.crl.pem': could not read database file I: I> When revoking a certificate, C looks up the certificate's serial number in its issuing entity's database file, which is created by OpenSSL in a temporary directory created earlier by C. It was unable to read this file on this occasion because of I, which is probably an OS-level error. Ensure the system's temporary directory is readable. =item B.crl.pem': could not write database file I: I> To revoke a certificate, C updates the certificate's entry in its issuing entity's database file, which is created by OpenSSL in a temporary directory created earlier by C. It was unable to update the file on this occasion because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B.crl.pem': could not write CRL number file I: I> When revoking a certificate, C stores the CRL number for the CRL it outputs in a file in a temporary directory it created earlier. It was unable to write this file on this occasion because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B.certchain.p12': could not create directory I: I> =item B.certchain.enc.p12': could not create directory I: I> When generating a PKCS#12 archive containing multiple certificates, C concatenates the certificates and writes them to a file in a temporary directory it creates before passing the path to that file in a command line option to C. It was unable to create the temporary directory on this occasion because of I, which is probably an OS-level error. Ensure the system's temporary directory is writable. =item B> =item B': failed to run `openssl I`: I> C attempted to invoke the OpenSSL command line utility, but failed to spawn a new process because of I, which is probably an OS-level error. =item B': `openssl I` failed with exit code I> C attempted to generate an output file by invoking the OpenSSL command line utility, and expected it to exit with exit code 0 (indicating success) but it actually exited with exit code I (indicating failure). Check that the PKI defined in the configuration file is sensible, then run C with the B<-v> option to see the full output from C. =back =head1 LIMITATIONS Although its interface is almost identical to the OpenSSL command line utility, C is incompatible with the LibreSSL command line utility, since it relies on features currently only found in the OpenSSL command line utility. Only limited error checking is performed on the configuration file; in particular, C will not always complain if required keys are missing. It is recommended to run the program with the B<-v> option after editing the configuration file to ensure C is being invoked as expected. Entities can have their certificates issued by one and only one entity; cross-signed certificates cannot currently be generated. The uniqueness of serial numbers among the certificates signed by any given issuer is not enforced, and duplication will likely cause odd output from C and breakage when certificates are revoked. Care should be taken when editing serial numbers in the configuration file. While as much effort as possible has been put into generating output files deterministically, C will still generate different private keys and PKCS#12 archives on every invocation, even when the PKI configuration file has not changed between invocations. C will avoid overwriting the private key for an entity if one already exists, but cannot recreate a private key that has been deleted. PKCS#12 archives cannot be generated deterministically because the PKCS#12 file format uses salts and IVs that the OpenSSL command line utiltity randomly generates on each invocation. =head1 SEE ALSO The man pages for the OpenSSL command line utility subcommands invoked by C: L, L, L, L, L, and L. =head1 BUGS If you encounter a problem with this program that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the list of command line options passed to C; =item * the full configuration file given by the C<-c> command line option; =item * the full output of C; =item * your operating system name and version; =item * the output of C; =item * the version of Net-SSLeay you are using; =item * the version of OpenSSL you are using. =back =head1 AUTHORS Originally written by Chris Novakovic. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen. =head1 COPYRIGHT AND LICENSE Copyright 2020- Chris Novakovic . Copyright 2020- Tuure Vartiainen . Copyright 2020- Heikki Vatiainen . This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =cut __DATA__ #----------------------------------------------------------------------- # openssl req #----------------------------------------------------------------------- [ req ] utf8 = yes string_mask = utf8only prompt = no distinguished_name = req_dn [ req_dn ] # This section is intentionally left blank - distinguished_name must be # defined in the [ req ] section, but the distinguished name is actually # specified in the -subj option to `openssl req` #----------------------------------------------------------------------- # openssl ca #----------------------------------------------------------------------- [ ca_conf ] database = {{ database_path }} serial = {{ serial_path }} new_certs_dir = {{ certs_path }} unique_subject = no email_in_dn = yes default_days = 3650 policy = ca_policy crlnumber = {{ crl_number_path }} crl_extensions = crlexts [ ca_policy ] domainComponent = optional countryName = optional organizationName = optional organizationalUnitName = optional dnQualifier = optional stateOrProvinceName = optional commonName = optional serialNumber = optional localityName = optional title = optional name = optional givenName = optional initials = optional pseudonym = optional generationQualifier = optional emailAddress = optional [ exts_ca ] keyUsage = critical,keyCertSign,cRLSign basicConstraints = critical,CA:true subjectKeyIdentifier = hash {{ extensions }} [ exts_server ] keyUsage = critical,digitalSignature,keyEncipherment extendedKeyUsage = serverAuth,clientAuth subjectKeyIdentifier = hash {{ extensions }} [ exts_client ] keyUsage = critical,digitalSignature extendedKeyUsage = clientAuth subjectKeyIdentifier = hash {{ extensions }} [ exts_email ] keyUsage = critical,digitalSignature,keyEncipherment extendedKeyUsage = emailProtection,clientAuth subjectKeyIdentifier = hash {{ extensions }} [ exts_custom ] {{ extensions }} [ crlexts ] # This section is intentionally left blank - if crl_extensions is # defined in the [ ca_conf ] section (even if it is empty), OpenSSL # writes a V2 CRL instead of a V1 CRL Net-SSLeay-1.92/helper_script/constants.txt0000644000175000001440000003342014167101614017456 0ustar csnusers# These libssl/libcrypto constants will be exported by Net::SSLeay. Constants # whose names begin with "SSL_" will have this prefix removed when they are # exported; for example, SSL_CB_EXIT will become Net::SSLeay::CB_EXIT(). # # Constants should be listed on separate lines and in lexicographical order. # # After changing the list below, run helper_script/update-exported-constants. # This script will: # - generate a new version of constants.c; # - generate a new test file at t/local/21_constants.t; # - update the list of exported constants in lib/Net/SSLeay.pm; # - update the constants list in the "Constants" section of lib/Net/SSLeay.pod. ASN1_STRFLGS_ESC_CTRL ASN1_STRFLGS_ESC_MSB ASN1_STRFLGS_ESC_QUOTE ASN1_STRFLGS_RFC2253 EVP_PKS_DSA EVP_PKS_EC EVP_PKS_RSA EVP_PKT_ENC EVP_PKT_EXCH EVP_PKT_EXP EVP_PKT_SIGN EVP_PK_DH EVP_PK_DSA EVP_PK_EC EVP_PK_RSA GEN_DIRNAME GEN_DNS GEN_EDIPARTY GEN_EMAIL GEN_IPADD GEN_OTHERNAME GEN_RID GEN_URI GEN_X400 LIBRESSL_VERSION_NUMBER MBSTRING_ASC MBSTRING_BMP MBSTRING_FLAG MBSTRING_UNIV MBSTRING_UTF8 NID_OCSP_sign NID_SMIMECapabilities NID_X500 NID_X509 NID_ad_OCSP NID_ad_ca_issuers NID_algorithm NID_authority_key_identifier NID_basic_constraints NID_bf_cbc NID_bf_cfb64 NID_bf_ecb NID_bf_ofb64 NID_cast5_cbc NID_cast5_cfb64 NID_cast5_ecb NID_cast5_ofb64 NID_certBag NID_certificate_policies NID_client_auth NID_code_sign NID_commonName NID_countryName NID_crlBag NID_crl_distribution_points NID_crl_number NID_crl_reason NID_delta_crl NID_des_cbc NID_des_cfb64 NID_des_ecb NID_des_ede NID_des_ede3 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 NID_description NID_desx_cbc NID_dhKeyAgreement NID_dnQualifier NID_dsa NID_dsaWithSHA NID_dsaWithSHA1 NID_dsaWithSHA1_2 NID_dsa_2 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 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 NID_ms_code_com NID_ms_code_ind NID_ms_ctl_sign NID_ms_efs NID_ms_ext_req NID_ms_sgc 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 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 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 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 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_shaWithRSAEncryption NID_stateOrProvinceName NID_subject_alt_name NID_subject_key_identifier NID_surname NID_sxnet NID_time_stamp NID_title NID_undef NID_uniqueIdentifier NID_x509Certificate NID_x509Crl NID_zlib_compression OCSP_RESPONSE_STATUS_INTERNALERROR OCSP_RESPONSE_STATUS_MALFORMEDREQUEST OCSP_RESPONSE_STATUS_SIGREQUIRED OCSP_RESPONSE_STATUS_SUCCESSFUL OCSP_RESPONSE_STATUS_TRYLATER OCSP_RESPONSE_STATUS_UNAUTHORIZED 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_MODULES_DIR OPENSSL_PLATFORM OPENSSL_VERSION OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR OPENSSL_VERSION_NUMBER OPENSSL_VERSION_PATCH OPENSSL_VERSION_STRING RSA_3 RSA_F4 SSL2_MT_CLIENT_CERTIFICATE SSL2_MT_CLIENT_FINISHED SSL2_MT_CLIENT_HELLO SSL2_MT_CLIENT_MASTER_KEY SSL2_MT_ERROR SSL2_MT_REQUEST_CERTIFICATE SSL2_MT_SERVER_FINISHED SSL2_MT_SERVER_HELLO SSL2_MT_SERVER_VERIFY SSL2_VERSION SSL3_MT_CCS SSL3_MT_CERTIFICATE SSL3_MT_CERTIFICATE_REQUEST SSL3_MT_CERTIFICATE_STATUS SSL3_MT_CERTIFICATE_URL SSL3_MT_CERTIFICATE_VERIFY SSL3_MT_CHANGE_CIPHER_SPEC SSL3_MT_CLIENT_HELLO SSL3_MT_CLIENT_KEY_EXCHANGE SSL3_MT_ENCRYPTED_EXTENSIONS SSL3_MT_END_OF_EARLY_DATA SSL3_MT_FINISHED SSL3_MT_HELLO_REQUEST SSL3_MT_KEY_UPDATE SSL3_MT_MESSAGE_HASH SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEXT_PROTO SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO SSL3_MT_SERVER_KEY_EXCHANGE SSL3_MT_SUPPLEMENTAL_DATA SSL3_RT_ALERT SSL3_RT_APPLICATION_DATA SSL3_RT_CHANGE_CIPHER_SPEC SSL3_RT_HANDSHAKE SSL3_RT_HEADER SSL3_RT_INNER_CONTENT_TYPE SSL3_VERSION SSLEAY_BUILT_ON SSLEAY_CFLAGS SSLEAY_DIR SSLEAY_PLATFORM SSLEAY_VERSION SSL_CB_ACCEPT_EXIT SSL_CB_ACCEPT_LOOP SSL_CB_ALERT SSL_CB_CONNECT_EXIT SSL_CB_CONNECT_LOOP SSL_CB_EXIT SSL_CB_HANDSHAKE_DONE SSL_CB_HANDSHAKE_START SSL_CB_LOOP SSL_CB_READ SSL_CB_READ_ALERT SSL_CB_WRITE SSL_CB_WRITE_ALERT SSL_ERROR_NONE SSL_ERROR_SSL SSL_ERROR_SYSCALL SSL_ERROR_WANT_ACCEPT SSL_ERROR_WANT_CONNECT SSL_ERROR_WANT_READ SSL_ERROR_WANT_WRITE SSL_ERROR_WANT_X509_LOOKUP SSL_ERROR_ZERO_RETURN SSL_FILETYPE_ASN1 SSL_FILETYPE_PEM SSL_F_CLIENT_CERTIFICATE SSL_F_CLIENT_HELLO SSL_F_CLIENT_MASTER_KEY SSL_F_D2I_SSL_SESSION SSL_F_GET_CLIENT_FINISHED SSL_F_GET_CLIENT_HELLO SSL_F_GET_CLIENT_MASTER_KEY SSL_F_GET_SERVER_FINISHED SSL_F_GET_SERVER_HELLO SSL_F_GET_SERVER_VERIFY SSL_F_I2D_SSL_SESSION SSL_F_READ_N SSL_F_REQUEST_CERTIFICATE SSL_F_SERVER_HELLO SSL_F_SSL_CERT_NEW SSL_F_SSL_GET_NEW_SESSION SSL_F_SSL_NEW SSL_F_SSL_READ SSL_F_SSL_RSA_PRIVATE_DECRYPT SSL_F_SSL_RSA_PUBLIC_ENCRYPT SSL_F_SSL_SESSION_NEW SSL_F_SSL_SESSION_PRINT_FP SSL_F_SSL_SET_FD SSL_F_SSL_SET_RFD SSL_F_SSL_SET_WFD SSL_F_SSL_USE_CERTIFICATE SSL_F_SSL_USE_CERTIFICATE_ASN1 SSL_F_SSL_USE_CERTIFICATE_FILE SSL_F_SSL_USE_PRIVATEKEY SSL_F_SSL_USE_PRIVATEKEY_ASN1 SSL_F_SSL_USE_PRIVATEKEY_FILE SSL_F_SSL_USE_RSAPRIVATEKEY SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 SSL_F_SSL_USE_RSAPRIVATEKEY_FILE SSL_F_WRITE_PENDING SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER SSL_MODE_AUTO_RETRY SSL_MODE_ENABLE_PARTIAL_WRITE SSL_MODE_RELEASE_BUFFERS SSL_NOTHING SSL_OP_ALL SSL_OP_ALLOW_NO_DHE_KEX SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION SSL_OP_CIPHER_SERVER_PREFERENCE SSL_OP_CISCO_ANYCONNECT SSL_OP_COOKIE_EXCHANGE SSL_OP_CRYPTOPRO_TLSEXT_BUG SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS SSL_OP_ENABLE_MIDDLEBOX_COMPAT SSL_OP_EPHEMERAL_RSA SSL_OP_LEGACY_SERVER_CONNECT SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER SSL_OP_MICROSOFT_SESS_ID_BUG SSL_OP_MSIE_SSLV2_RSA_PADDING SSL_OP_NETSCAPE_CA_DN_BUG SSL_OP_NETSCAPE_CHALLENGE_BUG SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG SSL_OP_NON_EXPORT_FIRST SSL_OP_NO_ANTI_REPLAY SSL_OP_NO_CLIENT_RENEGOTIATION SSL_OP_NO_COMPRESSION SSL_OP_NO_ENCRYPT_THEN_MAC SSL_OP_NO_QUERY_MTU SSL_OP_NO_RENEGOTIATION SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION SSL_OP_NO_SSL_MASK SSL_OP_NO_SSLv2 SSL_OP_NO_SSLv3 SSL_OP_NO_TICKET SSL_OP_NO_TLSv1 SSL_OP_NO_TLSv1_1 SSL_OP_NO_TLSv1_2 SSL_OP_NO_TLSv1_3 SSL_OP_PKCS1_CHECK_1 SSL_OP_PKCS1_CHECK_2 SSL_OP_PRIORITIZE_CHACHA SSL_OP_SAFARI_ECDHE_ECDSA_BUG SSL_OP_SINGLE_DH_USE SSL_OP_SINGLE_ECDH_USE SSL_OP_SSLEAY_080_CLIENT_DH_BUG SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG SSL_OP_TLSEXT_PADDING SSL_OP_TLS_BLOCK_PADDING_BUG SSL_OP_TLS_D5_BUG SSL_OP_TLS_ROLLBACK_BUG SSL_READING SSL_RECEIVED_SHUTDOWN SSL_R_BAD_AUTHENTICATION_TYPE SSL_R_BAD_CHECKSUM SSL_R_BAD_MAC_DECODE SSL_R_BAD_RESPONSE_ARGUMENT SSL_R_BAD_SSL_FILETYPE SSL_R_BAD_SSL_SESSION_ID_LENGTH SSL_R_BAD_STATE SSL_R_BAD_WRITE_RETRY SSL_R_CHALLENGE_IS_DIFFERENT SSL_R_CIPHER_TABLE_SRC_ERROR SSL_R_INVALID_CHALLENGE_LENGTH SSL_R_NO_CERTIFICATE_SET SSL_R_NO_CERTIFICATE_SPECIFIED SSL_R_NO_CIPHER_LIST SSL_R_NO_CIPHER_MATCH SSL_R_NO_PRIVATEKEY SSL_R_NO_PUBLICKEY SSL_R_NULL_SSL_CTX SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE SSL_R_PEER_ERROR SSL_R_PEER_ERROR_CERTIFICATE SSL_R_PEER_ERROR_NO_CIPHER SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE SSL_R_PUBLIC_KEY_ENCRYPT_ERROR SSL_R_PUBLIC_KEY_IS_NOT_RSA SSL_R_READ_WRONG_PACKET_TYPE SSL_R_SHORT_READ SSL_R_SSL_SESSION_ID_IS_DIFFERENT SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY SSL_R_UNKNOWN_REMOTE_ERROR_TYPE SSL_R_UNKNOWN_STATE SSL_R_X509_LIB SSL_SENT_SHUTDOWN SSL_SESSION_ASN1_VERSION SSL_SESS_CACHE_BOTH SSL_SESS_CACHE_CLIENT SSL_SESS_CACHE_NO_AUTO_CLEAR SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP SSL_SESS_CACHE_NO_INTERNAL_STORE SSL_SESS_CACHE_OFF SSL_SESS_CACHE_SERVER SSL_ST_ACCEPT SSL_ST_BEFORE SSL_ST_CONNECT SSL_ST_INIT SSL_ST_OK SSL_ST_READ_BODY SSL_ST_READ_HEADER SSL_VERIFY_CLIENT_ONCE SSL_VERIFY_FAIL_IF_NO_PEER_CERT SSL_VERIFY_NONE SSL_VERIFY_PEER SSL_VERIFY_POST_HANDSHAKE SSL_WRITING SSL_X509_LOOKUP TLS1_1_VERSION TLS1_2_VERSION TLS1_3_VERSION TLS1_VERSION TLSEXT_STATUSTYPE_ocsp V_OCSP_CERTSTATUS_GOOD V_OCSP_CERTSTATUS_REVOKED V_OCSP_CERTSTATUS_UNKNOWN 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 X509_FILETYPE_ASN1 X509_FILETYPE_DEFAULT X509_FILETYPE_PEM 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_TRUST_COMPAT 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_V_ERR_AKID_ISSUER_SERIAL_MISMATCH X509_V_ERR_AKID_SKID_MISMATCH X509_V_ERR_APPLICATION_VERIFICATION 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 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_EE_KEY_TOO_SMALL X509_V_ERR_EMAIL_MISMATCH 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_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_KEYUSAGE_NO_CERTSIGN X509_V_ERR_KEYUSAGE_NO_CRL_SIGN X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE X509_V_ERR_NO_EXPLICIT_POLICY 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 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_STORE_LOOKUP X509_V_ERR_SUBJECT_ISSUER_MISMATCH 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_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 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 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 XN_FLAG_SPC_EQ Net-SSLeay-1.92/helper_script/update-exported-constants0000755000175000001440000005425214167654427022000 0ustar csnusers#!/usr/bin/env perl use 5.008001; use strict; use warnings; use Cwd qw(abs_path); use English qw( $EVAL_ERROR $EXCEPTIONS_BEING_CAUGHT $OS_ERROR $RS -no_match_vars ); use Fcntl qw(SEEK_SET); use File::Basename qw(dirname); use File::Spec::Functions qw(catfile); use Getopt::Long qw(GetOptionsFromArray); use POSIX qw(ceil); our $VERSION = '1.92'; local $SIG{__DIE__} = sub { my ($cause) = @_; if ($EXCEPTIONS_BEING_CAUGHT) { return; } print STDERR $cause, "\n"; exit 1; }; my ($args) = eval { parse_options(\@ARGV) } or fatal( 'Failed to parse command line options', $EVAL_ERROR ); my @constants = eval { load_config( $args->{config} ) } or fatal( 'Failed to load configuration file', $EVAL_ERROR ); my @perl_constants = sort map { $_->{exported_name} } @constants; eval { generate_constants_c( $args->{'constants-file'}, @constants ) } or fatal( 'Failed to generate constants file', $EVAL_ERROR ); eval { generate_constants_test( $args->{'test-file'}, @perl_constants ) } or fatal( 'Failed to generate constants test script', $EVAL_ERROR ); eval { update_module( $args->{'module-file'}, @perl_constants ) } or fatal( 'Failed to update Net::SSLeay module file', $EVAL_ERROR ); eval { update_pod( $args->{'pod-file'}, @perl_constants ) } or fatal( 'Failed to update Pod file', $EVAL_ERROR ); sub dist_file { my @path = @_; return abs_path( catfile( dirname(__FILE__), '..', @path ) ); } sub parse_options { my ($argv) = @_; my $opts = { 'config' => dist_file( qw( helper_script constants.txt ) ), 'constants-file' => dist_file( qw( constants.c ) ), 'module-file' => dist_file( qw( lib Net SSLeay.pm ) ), 'pod-file' => dist_file( qw( lib Net SSLeay.pod ) ), 'test-file' => dist_file( qw( t local 21_constants.t ) ), }; GetOptionsFromArray( $argv, $opts, 'config|C=s', 'constants-file|c=s', 'module-file|m=s', 'pod-file|p=s', 'test-file|t=s', ); if ( !-e $opts->{'config'} ) { fatal("configuration file $opts->{config} does not exist"); } if ( !-e $opts->{'module-file'} ) { fatal("Net::SSLeay module file $opts->{'module-file'} does not exist"); } if ( !-e $opts->{'pod-file'} ) { fatal("Pod file $opts->{'pod-file'} does not exist"); } return wantarray ? ( $opts, $argv ) : $opts; } sub load_config { my ($config_file) = @_; open my $fh, '<', $config_file or fatal( $config_file, $OS_ERROR ); my @constants; my $line_number = 0; while (<$fh>) { $line_number++; # Trim leading and trailing space s{^\s+|\s+$}{}g; # Skip empty lines and comments next if m{^(?:\#.*)?$}; # Check whether the given constant name is likely to be a valid # OpenSSL/LibreSSL constant name if ( $_ !~ m{^[A-Za-z_][A-Za-z0-9_]*$} ) { printf STDERR "%s:%d: badly-formatted constant name; skipping\n", $config_file, $line_number; next; } # Remove "SSL_" prefix from constant name, if present ( my $exported_name = $_ ) =~ s{^SSL_}{}; push @constants, { exported_name => $exported_name, name => $_, }; } close $fh; return @constants; } sub generate_constants_c { my ( $file, @constants ) = @_; open my $fh, '>', $file or fatal($OS_ERROR); print $fh data_section('constants_c_header'); print $fh Net::SSLeay::ConstantsGenerator->C_constant( { breakout => ~0, indent => 20, }, map { { name => $_->{exported_name}, value => $_->{name}, } } ( # This constant name isn't defined by any libssl implementation - it # is only intended to be used by the test script generated by this # script to ensure that Net::SSLeay behaves as expected when a # caller attempts to refer to an undefined constant { exported_name => '_NET_SSLEAY_TEST_UNDEFINED_CONSTANT', name => '_NET_SSLEAY_TEST_UNDEFINED_CONSTANT', }, @constants, ) ); close $fh; printf "%s: generated\n", $file; return 1; } sub generate_constants_test { my ( $file, @constants ) = @_; open my $fh, '>', $file or fatal($OS_ERROR); print $fh data_section( 'constants_test', { constants => join( "\n", map { q{ } x 4 . $_ } @constants ), # 1 dies_like() test for each constant # 1 is() test for @EXPORT_OK # 1 dies_like() test for undefined constant tests => @constants + 2, } ); close $fh; printf "%s: generated\n", $file; return 1; } sub update_content { my ( $file, $start_match, $end_match, @replacement ) = @_; open my $fh, '<', $file or fatal($OS_ERROR); my ( @file, $start, $end ); my $pos = 0; while (<$fh>) { push @file, $_; if ( !defined $start && $_ =~ $start_match ) { $start = $pos; } elsif ( defined $start && !defined $end && $_ =~ $end_match ) { $end = $pos; } $pos++; } close $fh; if ( !defined $start || !defined $end ) { fatal('could not find start/end markers'); } splice @file, $start + 1, max( 0, $end - $start - 1 ), @replacement; open $fh, '>', $file or fatal($OS_ERROR); for (@file) { print $fh $_; } close $fh; return 1; } sub update_module { my ( $file, @constants ) = @_; eval { update_content( $file, qr{^my \@constants = qw\(}, qr{^\);}, map { q{ } x 4 . "$_\n" } @constants ) } or do { ( my $err = $EVAL_ERROR ) =~ s{start/end markers$}{\@constants declaration}; fatal( $file, $err ); }; printf "%s: updated\n", $file; return 1; } sub format_constants { my ( $list, $indent, $columns, $separator ) = @_; my $per_column = ceil( @$list / $columns ); my @columns = map { [ splice @$list, 0, $per_column ] } ( 0 .. $columns - 1 ); my @max_length = map { max( map { length } @$_ ) } @columns; my @formatted; for my $row ( 0 .. $per_column - 1 ) { my @row; for ( 0 .. $columns - 1 ) { my $this = $columns[$_]->[$row]; my $left = $columns[ $_ - 1 ]->[$row]; next if !defined $this; my $gap = $_ == 0 ? $indent : $max_length[ $_ - 1 ] - length($left) + $separator; push @row, q{ } x $gap . $this; } push @formatted, join( '', @row ) . "\n"; } return @formatted; } sub update_pod { my ( $file, @constants ) = @_; eval { update_content( $file, qr{^=for start_constants$}, qr{^=for end_constants$}, ( "\n", format_constants( \@constants, 4, 2, 2 ), "\n" ) ) } or do { ( my $err = $EVAL_ERROR ) =~ s{start/end markers$}{constants block}; fatal( $file, $err ); }; printf "%s: updated\n", $file; return 1; } sub max { my @numbers = @_; my $max = shift @numbers; while ( defined( my $number = shift @numbers ) ) { $max = $number if $number > $max; } return $max; } sub data_section { my ( $section, $tmpl ) = @_; seek DATA, 0, SEEK_SET; my @content = (); my $in_section; for () { if ( my ($name) = $_ =~ m{^\[section:(\w+)\]\n} ) { if ( $name eq $section ) { $in_section = 1; next; } elsif ($in_section) { # Reached the section following the requested section last; } } if ($in_section) { s/\{\{\s*(\w+)\s*\}\}/defined $tmpl->{$1} ? $tmpl->{$1} : ''/eg; push @content, $_; } } fatal("__DATA__ section '$section' not found") if !$in_section; return join '', @content; } sub fatal { my ( $message, $cause ) = @_; die Error->new( $message, $cause ); } package Net::SSLeay::ConstantsGenerator; use base 'ExtUtils::Constant::Base'; sub assignment_clause_for_type { my ( $self, $args, $value ) = @_; return main::data_section( 'assignment_clause_for_type', { value => $value, } ); } sub C_constant_return_type { my $ret = <<'END'; #ifdef NET_SSLEAY_32BIT_CONSTANTS static double #else static uint64_t #endif END # Newline is automatically added, remove ours. chomp($ret); return $ret; } sub return_statement_for_notfound { return main::data_section('return_statement_for_notfound'); } package Error; use overload ( q{""} => sub { my ($self) = @_; return defined $self->{cause} ? "$self->{message}: $self->{cause}" : $self->{message}; }, fallback => 1, ); sub new { my ( $class, $message, $cause ) = @_; return bless { message => $message, cause => $cause, }, $class; } package main; =pod =encoding utf-8 =head1 NAME C - Manage constants exported by Net::SSLeay =head1 VERSION This document describes version 1.92 of C. =head1 USAGE # Edit constants.txt to add or remove a libssl/libcrypto constant # Export the new list of constants in Net::SSLeay, document them, and test # for their availability in the test suite: update-exported-constants =head1 DESCRIPTION Net::SSLeay exports a number of constants defined by libssl and libcrypto. Several time-consuming and error-prone steps must be performed whenever this set of constants changes: each one must be recognised as a valid constant name by Net::SSLeay's XS code, defined as an exportable symbol in Net::SSLeay's Perl code, documented in Net::SSLeay's user documentation, and tested in the Net::SSLeay test suite to ensure that referencing it either returns a defined value or raises an exception depending on whether it is defined in the version of OpenSSL or LibreSSL being used. C simplifies the process of changing the set of exportable constants by automating it: it consumes a configuration file containing a list of constants, and performs each of the steps above for each of the constants listed in the file. =head1 DEPENDENCIES C requires Perl 5.8.1 or higher. =head1 OPTIONS C accepts the following command line options: =over 4 =item * B<-C I>, B<--config=I>: the path to a file defining the libssl and libcrypto constants that Net::SSLeay should attempt to export. See L for a description of the expected format. Defaults to C, relative to the path to C. =item * B<-c I>, B<--constants-file=I>: the path at which to write the C source file defining the C function; this file should be included by C. If a file exists at the given path, it will be overwritten. Defaults to C<../constants.c>, relative to the path to C. =item * B<-m I>, B<--module-file=I>: the path to Net::SSLeay's source code; the value of the C<@constants> array defined in this file will be overwritten. Defaults to C<../lib/Net/SSLeay.pm>, relative to the path to C. =item * B<-p I>, B<--pod-file=I>: the path to et::SSLeay's documentation; the list of constants given in the L section of this file will be overwritten. Defaults to C<../lib/Net/SSLeay.pod>, relative to the path to C. =item * B<-t I>, B<--test-file=I>: the path at which to write the constant autoloading test script. If a file exists at the given path, it will be overwritten. Defaults to C<../t/local/21_constants.t>, relative to the path to C. =back The above defaults ensure that C can be executed from a directory containing the Net-SSLeay source code without needing to specify any options. =head1 CONFIGURATION The configuration file is a plain text file containing libssl and libcrypto constant names, one per line. Empty lines and lines beginning with C<#> are ignored. libssl and libcrypto constants are C preprocessor macro names. C checks that constant names given in the configuration file appear to be valid macro names, and will output a I warning on stderr whenever it encounters a line in the configuration file that does not appear to be a valid macro name. Since the set of valid constant names differs between versions of OpenSSL and LibreSSL, it is not possible to validate that constant names listed in the configuration file are in fact valid constant names for a particular libssl or libcrypto version. =head1 OUTPUT C generates the following files (overwriting any file that already exists at that path): =over 4 =item * A C source file defining a function with the prototype C. For a given constant name and length, this function returns the value of the constant with the given name if it is recognised as exportable by Net::SSLeay and exists in libssl/libcrypto, returns C<0> and sets L to C if the constant is exportable but does not exist in libssl/libcrypto, or returns C<0> and sets L to C if the constant is not recognised as exportable by Net::SSLeay. This file is expected to be Cd by C. =item * A Net::SSLeay test script that ensures each constant is exportable if it is defined, or raises a specific exception if it is not. This test script is expected to run as part of the standard Net::SSLeay test suite. =back C updates the following files (which therefore must already exist and be writable): =over 4 =item * The source file for the Net::SSLeay module - the value of the C<@constants> array defined in this file is overwritten with the new list of constants that the module can export. =item * The Pod file documenting the Net::SSLeay module - the list of exportable constants given in the L section of this file is overwritten with the new list of constants that the module can export. =back =head1 DIAGNOSTICS C outputs a diagnostic message to stderr and immediately exits with exit code 1 if an error occurs. Error messages listed below indicate invalid input or a problem with the state of the system that can usually be fixed. Error messages not listed below are internal and should never be encountered under normal operation; please report any occurrences of such errors as bugs (see L). =over =item B does not exist> The configuration file listing the constants to export, as specified by the B<-C> command line option (or C in the same directory as C if a value for B<-C> was not specified), does not exist. Ensure C exists, or specify an alternative path with B<-C I>. =item B does not exist> C updates and overwrites the Net::SSLeay module file specified by the B<-m> command line option (or C<../lib/Net/SSLeay.pm> relative to the path to C if a value for B<-m> was not specified), but a file could not be found at this path. Ensure C<../lib/Net/SSLeay.pm> exists, or specify an alternative path with B<-m I>. =item B does not exist> C updates and overwrites the Pod file containing the Net::SSLeay documentation at the path specified by the B<-p> command line option (or C<../lib/Net/SSLeay.pod> relative to the path to C if a value for B<-p> was not specified), but a file could not be found at this path. Ensure C<../lib/Net/SSLeay.pod> exists, or specify an alternative path with B<-p I>. =item B> The configuration file could not be loaded because of I, which is probably an OS-level error. Ensure the path given by the B<-C> option, or the default path if B<-C> was not specified, is readable. =item B> The constants C source file could not be written because of I, which is probably an OS-level error. Ensure that the path given by the B<-c> option, or the default path if B<-c> was not specified, is writable. =item B> The constants test script could not be written because of I, which is probably an OS-level error. Ensure that the path given by the B<-t> option, or the default path if B<-t> was not specified, is writable. =item B The Net::SSLeay module file was read, but an updated constants list could not be written to it because the definition of the C<@constants> array could not be found. C expects this array to be defined with the following syntax: my @constants = qw( # ); Ensure the C<@constants> array is defined in this way in the Net::SSLeay module. =item B> The Net::SSLeay module file could not be either read or written because of I, which is probably an OS-level error. Ensure that the path given by the B<-m> option, or the default path if B<-m> was not specified, is both readable and writable. =item B The Net::SSLeay documentation file was read, but an updated constants list could not be written to it because the Pod code block listing the constants could not be found. C expects this block to be surrounded by the following Pod commands: =for start_constants =for end_constants Ensure the constants list is defined in this way in the documentation. =item B> The Net::SSLeay documentation file could not be either read or written because of I, which is probably an OS-level error. Ensure that the path given by the B<-p> option, or the default path if B<-p> was not specified, is both readable and writable. =back =head1 LIMITATIONS Net::SSLeay currently returns the values of libssl and libcrypto constants as double-precision floating-point numbers, regardless of the data type of the underlying constant as it is defined by OpenSSL and/or LibreSSL; the C source file generated by C therefore defines a function C with the return type C. While all constants currently exported by Net::SSLeay can be stored in this way without loss of precision, this may not necessarily be the case for all constants defined by libssl and libcrypto, either now or in the future. =head1 SEE ALSO The man pages for OpenSSL and LibreSSL, which describe the constants they define (and therefore the constants that may be exported by Net::SSLeay). =head1 BUGS If you encounter a problem with this program that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the list of command line options passed to C; =item * the full configuration file given by the B<-C> command line option (or the default configuration file if B<-C> was not specified); =item * the full output of C; =item * your operating system name and version; =item * the output of C; =item * the version of Net-SSLeay you are using. =back =head1 AUTHORS Originally written by Chris Novakovic. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen. =head1 COPYRIGHT AND LICENSE Copyright 2021- Chris Novakovic . Copyright 2021- Tuure Vartiainen . Copyright 2021- Heikki Vatiainen . This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =cut __DATA__ [section:constants_c_header] /* * This file 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. */ [section:assignment_clause_for_type] #ifdef {{ value }} return {{ value }}; #else goto not_there; #endif [section:return_statement_for_notfound] errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; [section:constants_test] # This file 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. use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(dies_like); # We rely on symbolic references in the dies_like() tests: no strict 'refs'; plan tests => {{ tests }}; my @constants = qw( {{ constants }} ); my %exported = map { $_ => 1 } @Net::SSLeay::EXPORT_OK; my @missing; for my $c (@constants) { dies_like( sub { "Net::SSLeay::$c"->(); die "ok\n"; }, qr/^(?:ok\n$|Your vendor has not defined SSLeay macro )/, "constant is exported or not defined: $c" ); push @missing, $c if !exists $exported{$c}; } is( join( q{,}, sort @missing ), '', 'no constants missing from @EXPORT_OK (total missing: ' . scalar(@missing) . ')' ); dies_like( sub { Net::SSLeay::_NET_SSLEAY_TEST_UNDEFINED_CONSTANT() }, qr/^Your vendor has not defined SSLeay macro _NET_SSLEAY_TEST_UNDEFINED_CONSTANT/, 'referencing an undefined constant raises an exception' ); Net-SSLeay-1.92/helper_script/pki.cfg0000644000175000001440000002731114000430120016126 0ustar csnusers{ 'extended-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'intermediate-ca', md_algorithm => 'sha256', purpose => 'custom', serial => 2, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ # RFC 5280 section 4.1.2.4 "MUST recognise" RDN attribute types: C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', dnQualifier => 'net-ssleay.example', ST => 'State', CN => 'John Doe', serialNumber => 1234, # RFC 5280 section 4.1.2.4 "SHOULD recognise" RDN attribute types: L => 'Locality', title => 'Mr.', SN => 'Doe', GN => 'John', initials => 'JD', pseudonym => 'John Q. Public', generationQualifier => 'Sr.', # Recommended by RFC 2985 section 3; deprecated, but still used emailAddress => 'john.doe@net-ssleay.example', ], extensions => { authorityInfoAccess => [ 'OCSP;URI:http://ocsp.intermediate-ca.net-ssleay.example', 'caIssuers;URI:http://issuers.intermediate-ca.net-ssleay.example', ], authorityKeyIdentifier => 'keyid,issuer', basicConstraints => 'critical,CA:false', certificatePolicies => [ # These OIDs are deliberately invalid '1.2.3.4.5', '2.3.4.5.6', ], crlDistributionPoints => [ 'URI:http://intermediate-ca.net-ssleay.example/crl1.crl', 'URI:http://intermediate-ca.net-ssleay.example/crl2.crl', ], extendedKeyUsage => [ 'critical', 'serverAuth', 'clientAuth', 'codeSigning', 'emailProtection', 'timeStamping', 'OCSPSigning', 'ipsecIKE', 'msCodeInd', 'msCodeCom', 'msCTLSign', 'msEFS', # 1.3.6.1.5.5.7.3.13 = id-kp-eapOverPPP '1.3.6.1.5.5.7.3.13', # 1.3.6.1.5.5.7.3.14 = id-kp-eapOverLAN '1.3.6.1.5.5.7.3.14', ], issuerAltName => [ 'email:intermediate-ca@net-ssleay.example', 'URI:http://intermediate-ca.net-ssleay.example', 'DNS:intermediate-ca.net-ssleay.example', 'RID:1.2.0.0', 'IP:192.168.0.1', 'IP:fd25:f814:afb5:9873::1', # 1.2.840.113549.1.9.1 = emailAddress 'otherName:1.2.840.113549.1.9.1;UTF8:ica@net-ssleay.example', ], keyUsage => [ 'digitalSignature', 'nonRepudiation', 'keyEncipherment', 'dataEncipherment', 'keyAgreement', 'keyCertSign', 'cRLSign', 'decipherOnly', ], subjectAltName => [ 'email:john.doe@net-ssleay.example', 'URI:http://johndoe.net-ssleay.example', 'DNS:johndoe.net-ssleay.example', 'RID:1.2.3.4', 'IP:192.168.0.2', 'IP:fd25:f814:afb5:9873::2', # 1.2.840.113549.1.9.1 = emailAddress 'otherName:1.2.840.113549.1.9.1;UTF8:jd@net-ssleay.example', ], subjectKeyIdentifier => 'hash', }, }, pkcs12 => { passphrase => 'test', }, }, 'intermediate-ca' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'root-ca', md_algorithm => 'sha256', purpose => 'ca', serial => 2, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => 'Intermediate CA', ], }, pkcs12 => { passphrase => 'test', }, crl => { last_update => '2020-07-01 00:00:00', md_algorithm => 'sha256', next_update => '2020-07-08 00:00:00', number => 1, }, }, 'revoked-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'intermediate-ca', md_algorithm => 'sha256', purpose => 'server', revoke_reason => 'keyCompromise', revoke_time => '2020-06-06 06:06:06', serial => 5, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => 'revoked-cert.net-ssleay.example', ], }, pkcs12 => { passphrase => 'test', }, }, 'root-ca' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { md_algorithm => 'sha256', purpose => 'ca', serial => 1, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => 'Root CA', ], }, pkcs12 => { passphrase => 'test', }, }, 'simple-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'intermediate-ca', md_algorithm => 'sha256', purpose => 'server', serial => 1, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => 'simple-cert.net-ssleay.example', ], }, pkcs12 => { passphrase => 'test', }, }, 'strange-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'intermediate-ca', md_algorithm => 'sha256', purpose => 'server', serial => 4, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'UA', ST => 'Львівська область', O => 'abc D.E.F', OU => q{START ! @ # $ % ^ & * ( ) , . - ? : _ / [ ] " ' | \ = + END}, CN => 'strange-cert.net-ssleay.example', ], }, pkcs12 => { passphrase => 'test', }, }, 'verify-ca' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'root-ca', md_algorithm => 'sha256', purpose => 'ca', serial => 3, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => 'Verification CA', ], extensions => { certificatePolicies => [ # This OID is deliberately invalid '1.2.3.4.5', ], }, }, pkcs12 => { passphrase => 'test', }, crl => { last_update => '2020-07-01 00:00:00', md_algorithm => 'sha256', next_update => '2020-07-08 00:00:00', number => 1, }, }, 'verify-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'verify-ca', md_algorithm => 'sha256', purpose => 'server', serial => 1, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => '*.johndoe.net-ssleay.example', emailAddress => 'john.doe@net-ssleay.example', ], extensions => { certificatePolicies => [ # This OID is deliberately invalid '1.2.3.4.5', ], subjectAltName => [ 'email:john.doe@net-ssleay.example', 'DNS:*.johndoe.net-ssleay.example', 'IP:192.168.0.3', ], }, }, pkcs12 => { passphrase => 'test', }, }, 'wildcard-cert' => { key => { algorithm => 'rsa', passphrase => 'test', size => 2048, }, csr => { md_algorithm => 'sha256', }, cert => { issuer => 'intermediate-ca', md_algorithm => 'sha256', purpose => 'server', serial => 3, valid_from => '2020-01-01 00:00:00', valid_until => '2038-01-01 00:00:00', subject => [ C => 'PL', O => 'Net-SSLeay', OU => 'Test Suite', CN => '*.net-ssleay.example', ], extensions => { subjectAltName => [ 'DNS:*.net-ssleay.example', ], }, }, pkcs12 => { passphrase => 'test', }, }, } Net-SSLeay-1.92/Credits0000644000175000001440000000056713320746140013363 0ustar csnusersanton@genua.de Win32 Clinton Wong Jim Bowlin for contributing Net::SSLeay::Handle Eric A Selber for Windows fixes and testing Marko Asplund for many suggestions and fixes Sébastien Aperghis-Tramoni for many fixes and cleanups See Changes file for other contributions. Net-SSLeay-1.92/MANIFEST0000644000175000001440000001433714167654753013216 0ustar csnusersChanges constants.c CONTRIBUTING.md Credits examples/bio.pl examples/bulk.pl examples/callback.pl examples/cb-testi.pl examples/cli-cert.pl examples/ephemeral.pl examples/get_authenticated_page.pl examples/get_page.pl examples/get_page_cert.pl examples/https-proxy-snif.pl examples/makecert.pl examples/minicli.pl examples/passwd-cb.pl examples/req.conf examples/server_key.pem examples/ssl-inetd-serv.pl examples/ssl_diff.pl examples/sslcat.pl examples/sslecho.pl examples/stdio_bulk.pl examples/tcpcat.pl examples/tcpecho.pl examples/x509_cert_details.pl helper_script/constants.txt helper_script/generate-test-pki helper_script/pki.cfg helper_script/update-exported-constants inc/Test/Net/SSLeay.pm inc/Test/Net/SSLeay/Socket.pm lib/Net/SSLeay.pm lib/Net/SSLeay.pod lib/Net/SSLeay/Handle.pm LICENSE Makefile.PL MANIFEST This list of files ppport.h QuickRef README README.OSX README.VMS README.Win32 SSLeay.xs t/data/binary-test.file t/data/extended-cert.cert.der t/data/extended-cert.cert.dump t/data/extended-cert.cert.pem t/data/extended-cert.certchain.der t/data/extended-cert.certchain.enc.p12 t/data/extended-cert.certchain.p12 t/data/extended-cert.certchain.pem t/data/extended-cert.csr.der t/data/extended-cert.csr.pem t/data/extended-cert.enc.p12 t/data/extended-cert.key.der t/data/extended-cert.key.enc.der t/data/extended-cert.key.enc.pem t/data/extended-cert.key.pem t/data/extended-cert.p12 t/data/intermediate-ca.cert.der t/data/intermediate-ca.cert.dump t/data/intermediate-ca.cert.pem t/data/intermediate-ca.certchain.der t/data/intermediate-ca.certchain.enc.p12 t/data/intermediate-ca.certchain.p12 t/data/intermediate-ca.certchain.pem t/data/intermediate-ca.crl.der t/data/intermediate-ca.crl.pem t/data/intermediate-ca.csr.der t/data/intermediate-ca.csr.pem t/data/intermediate-ca.enc.p12 t/data/intermediate-ca.key.der t/data/intermediate-ca.key.enc.der t/data/intermediate-ca.key.enc.pem t/data/intermediate-ca.key.pem t/data/intermediate-ca.p12 t/data/revoked-cert.cert.der t/data/revoked-cert.cert.dump t/data/revoked-cert.cert.pem t/data/revoked-cert.certchain.der t/data/revoked-cert.certchain.enc.p12 t/data/revoked-cert.certchain.p12 t/data/revoked-cert.certchain.pem t/data/revoked-cert.csr.der t/data/revoked-cert.csr.pem t/data/revoked-cert.enc.p12 t/data/revoked-cert.key.der t/data/revoked-cert.key.enc.der t/data/revoked-cert.key.enc.pem t/data/revoked-cert.key.pem t/data/revoked-cert.p12 t/data/root-ca.cert.der t/data/root-ca.cert.dump t/data/root-ca.cert.pem t/data/root-ca.certchain.der t/data/root-ca.certchain.enc.p12 t/data/root-ca.certchain.p12 t/data/root-ca.certchain.pem t/data/root-ca.csr.der t/data/root-ca.csr.pem t/data/root-ca.enc.p12 t/data/root-ca.key.der t/data/root-ca.key.enc.der t/data/root-ca.key.enc.pem t/data/root-ca.key.pem t/data/root-ca.p12 t/data/simple-cert.cert.der t/data/simple-cert.cert.dump t/data/simple-cert.cert.pem t/data/simple-cert.certchain.der t/data/simple-cert.certchain.enc.p12 t/data/simple-cert.certchain.p12 t/data/simple-cert.certchain.pem t/data/simple-cert.csr.der t/data/simple-cert.csr.pem t/data/simple-cert.enc.p12 t/data/simple-cert.key.der t/data/simple-cert.key.enc.der t/data/simple-cert.key.enc.pem t/data/simple-cert.key.pem t/data/simple-cert.p12 t/data/strange-cert.cert.der t/data/strange-cert.cert.dump t/data/strange-cert.cert.pem t/data/strange-cert.certchain.der t/data/strange-cert.certchain.enc.p12 t/data/strange-cert.certchain.p12 t/data/strange-cert.certchain.pem t/data/strange-cert.csr.der t/data/strange-cert.csr.pem t/data/strange-cert.enc.p12 t/data/strange-cert.key.der t/data/strange-cert.key.enc.der t/data/strange-cert.key.enc.pem t/data/strange-cert.key.pem t/data/strange-cert.p12 t/data/verify-ca.cert.der t/data/verify-ca.cert.dump t/data/verify-ca.cert.pem t/data/verify-ca.certchain.der t/data/verify-ca.certchain.enc.p12 t/data/verify-ca.certchain.p12 t/data/verify-ca.certchain.pem t/data/verify-ca.csr.der t/data/verify-ca.csr.pem t/data/verify-ca.enc.p12 t/data/verify-ca.key.der t/data/verify-ca.key.enc.der t/data/verify-ca.key.enc.pem t/data/verify-ca.key.pem t/data/verify-ca.p12 t/data/verify-cert.cert.der t/data/verify-cert.cert.dump t/data/verify-cert.cert.pem t/data/verify-cert.certchain.der t/data/verify-cert.certchain.enc.p12 t/data/verify-cert.certchain.p12 t/data/verify-cert.certchain.pem t/data/verify-cert.csr.der t/data/verify-cert.csr.pem t/data/verify-cert.enc.p12 t/data/verify-cert.key.der t/data/verify-cert.key.enc.der t/data/verify-cert.key.enc.pem t/data/verify-cert.key.pem t/data/verify-cert.p12 t/data/wildcard-cert.cert.der t/data/wildcard-cert.cert.dump t/data/wildcard-cert.cert.pem t/data/wildcard-cert.certchain.der t/data/wildcard-cert.certchain.enc.p12 t/data/wildcard-cert.certchain.p12 t/data/wildcard-cert.certchain.pem t/data/wildcard-cert.csr.der t/data/wildcard-cert.csr.pem t/data/wildcard-cert.enc.p12 t/data/wildcard-cert.key.der t/data/wildcard-cert.key.enc.der t/data/wildcard-cert.key.enc.pem t/data/wildcard-cert.key.pem t/data/wildcard-cert.p12 t/external/ocsp.t t/handle/external/10_destroy.t t/handle/external/50_external.t t/handle/local/05_use.t t/local/01_pod.t t/local/02_pod_coverage.t t/local/03_use.t t/local/04_basic.t t/local/05_passwd_cb.t t/local/06_tcpecho.t t/local/07_sslecho.t t/local/08_pipe.t t/local/09_ctx_new.t t/local/10_rand.t t/local/11_read.t t/local/15_bio.t t/local/20_functions.t t/local/21_constants.t t/local/22_provider.t t/local/22_provider_try_load.t t/local/22_provider_try_load_zero_retain.t t/local/30_error.t t/local/31_rsa_generate_key.t t/local/32_x509_get_cert_info.t t/local/33_x509_create_cert.t t/local/34_x509_crl.t t/local/35_ephemeral.t t/local/36_verify.t t/local/37_asn1_time.t t/local/38_priv-key.t t/local/39_pkcs12.t t/local/40_npn_support.t t/local/41_alpn_support.t t/local/42_info_callback.t t/local/43_misc_functions.t t/local/44_sess.t t/local/45_exporter.t t/local/46_msg_callback.t t/local/47_keylog.t t/local/50_digest.t t/local/61_threads-cb-crash.t t/local/62_threads-ctx_new-deadlock.t t/local/63_ec_key_generate_key.t t/local/64_ticket_sharing.t t/local/65_security_level.t t/local/65_ticket_sharing_2.t t/local/66_curves.t t/local/kwalitee.t typemap META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-SSLeay-1.92/inc/0000755000175000001440000000000014167654753012626 5ustar csnusersNet-SSLeay-1.92/inc/Test/0000755000175000001440000000000014167654753013545 5ustar csnusersNet-SSLeay-1.92/inc/Test/Net/0000755000175000001440000000000014167654753014273 5ustar csnusersNet-SSLeay-1.92/inc/Test/Net/SSLeay/0000755000175000001440000000000014167654753015433 5ustar csnusersNet-SSLeay-1.92/inc/Test/Net/SSLeay/Socket.pm0000644000175000001440000002021314167654427017215 0ustar csnuserspackage Test::Net::SSLeay::Socket; use 5.008001; use strict; use warnings; use Carp qw(croak); use English qw( $EVAL_ERROR $OS_ERROR $OUTPUT_AUTOFLUSH -no_match_vars ); use Scalar::Util qw(refaddr reftype); use SelectSaver; use Socket qw( AF_INET SOCK_DGRAM SOCK_STREAM inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); our $VERSION = '1.92'; my %PROTOS = ( tcp => SOCK_STREAM, udp => SOCK_DGRAM, ); sub new { my ( $class, %args ) = @_; my $self = bless { addr => delete $args{addr} || '127.0.0.1', port => delete $args{port} || 0, proto => delete $args{proto} || 'tcp', queue => delete $args{queue} || 5, }, $class; if ( !exists $PROTOS{ $self->{proto} } ) { croak "Unknown protocol '$self->{proto}'"; } $self->_init_server(); return $self; } sub _init_server { my ($self) = @_; my $addr = eval { inet_aton( $self->{addr} ) } or croak 'Could not pack IP address' . ( $EVAL_ERROR ? ": $EVAL_ERROR" : q{} ); my $sockaddr = eval { pack_sockaddr_in( $self->{port}, $addr ) } or croak 'Could not create sockaddr_in structure' . ( $EVAL_ERROR ? ": $EVAL_ERROR" : q{} ); socket $self->{sock}, AF_INET, $PROTOS{ $self->{proto} }, 0 or croak "Could not open server socket: $OS_ERROR"; if ( $self->{proto} eq 'tcp' ) { bind $self->{sock}, $sockaddr or croak "Could not bind server socket: $OS_ERROR"; listen $self->{sock}, $self->{queue} or croak "Could not listen on server socket: $OS_ERROR"; } my $sockname = getsockname $self->{sock}; ( $self->{sport}, $self->{saddr} ) = unpack_sockaddr_in($sockname); $self->{saddr} = inet_ntoa( $self->{saddr} ); return 1; } sub get_addr { my ($self) = @_; return $self->{saddr}; } sub get_port { my ($self) = @_; return $self->{sport}; } sub accept { my ( $self, $sock ) = @_; if ( defined $sock && reftype($sock) ne 'GLOB' ) { croak 'Argument #1 to accept() must be a typeglob reference'; } accept $sock, $self->{sock} or croak "Could not accept connection: $OS_ERROR"; my $saver = SelectSaver->new($sock); local $OUTPUT_AUTOFLUSH = 1; return $sock; } sub connect { my ($self) = @_; my $addr = eval { inet_aton( $self->{saddr} ) } or croak 'Could not pack IP address' . ( $EVAL_ERROR ? ": $EVAL_ERROR" : q{} ); my $sockaddr = eval { pack_sockaddr_in( $self->{sport}, $addr ) } or croak 'Could not create sockaddr_in structure' . ( $EVAL_ERROR ? ": $EVAL_ERROR" : q{} ); socket my $sock, AF_INET, $PROTOS{ $self->{proto} }, 0 or croak "Could not open server socket: $OS_ERROR"; connect $sock, $sockaddr or croak "Could not connect to server socket: $OS_ERROR"; my $saver = SelectSaver->new($sock); local $OUTPUT_AUTOFLUSH = 1; return $sock; } sub close { my ($self) = @_; return close $self->{sock}; } 1; __END__ =head1 NAME Test::Net::SSLeay::Socket - Socket class for the Net-SSLeay test suite =head1 VERSION This document describes version 1.92 of Test::Net::SSLeay::Socket. =head1 SYNOPSIS use Test::Net::SSLeay::Socket; # Create TCP server socket listening on localhost on a random unused port my $server = Test::Net::SSLeay::Socket->new( protocol => 'tcp' ); # To wait for a connection to the server socket: my $sock = $server->accept(); # Open a connection to the server socket: my $client_sock = $server->connect(); # Or do so using Net::SSLeay's high-level API: use Net::SSLeay qw(tcpcat); my ( $response, $err ) = tcpcat( $server->get_addr(), $server->get_port(), 'request' ); =head1 DESCRIPTION Test scripts in the Net-SSLeay test suite commonly need to establish server and client sockets over which TLS communication can be tested. This module simplifies the process of creating server sockets and client sockets that know how to connect to them. This module is not intended to be used directly by test scripts; use the helper functions in L instead. =head1 CONSTRUCTOR =head2 new # TCP server socket listening on localhost on a random unused port: my $server = Test::Net::SSLeay::Socket->new(); # TCP server socket listening on a private IP address on the standard HTTP # port: my $server = Test::Net::SSLeay::Socket->new( addr => '10.0.0.1', port => 80, proto => 'tcp', ); Creates a new C object. A server socket is created that binds to a given (or the default) address and port number. Supported options: =over 4 =item * C (optional): the IPv4 address that the server socket should bind to. Defaults to C<'127.0.0.1'>. =item * C (optional): the port number that the server socket should bind to. Defaults to the number of a random unused port chosen by the operating system. =item * C (optional): the transport protocol that the server socket should use; C<'tcp'> for TCP, C<'udp'> for UDP. Defaults to C<'tcp'>. =item * C (optional): the maximum number of pending connections to allow for the server socket. Defaults to 5. =back Dies on failure. =head1 METHODS =head2 get_addr my $address = $server->get_addr(); Returns the address on which the server socket is listening. Useful when manually creating a connection to the server socket (e.g. via one of Net::SSLeay's high-level API functions) and an address was not specified in the constructor. =head2 get_port my $port = $server->get_port(); Returns the port number on which the server socket is listening. Useful when manually creating a client socket to connect to the server socket (e.g. via one of Net::SSLeay's high-level API functions) and a port number was not specified in the constructor. =head2 accept # Communicate with the client, creating a new file handle: my $sock = $server->accept(); # Communicate with the client using an existing typeglob as the file # handle: $server->accept(*Net::SSLeay::SSLCAT_S); Accepts an incoming connection request to the server socket, and enables autoflush on the resulting file handle. If a typeglob is passed as the first argument, it becomes the socket's file handle. This is useful when creating sockets for testing Net::SSLeay's high-level API functions, which perform their operations on the C typeglob. Returns the file handle for the new socket. Dies on failure. =head2 connect my $sock = $server->connect(); Creates a new connection to the server socket, and enables autoflush on the resulting file handle. Returns the file handle for the new socket. Dies on failure. =head2 close $server->close(); Closes the file handle for the server socket. Returns true on success, or false on failure (just like Perl's L builtin). =head1 SEE ALSO L, for an easier way to use this module from Net-SSLeay test scripts. =head1 BUGS If you encounter a problem with this module that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the code you are trying to run (ideally a minimum working example that reproduces the problem), or the full output of the Net-SSLeay test suite if the problem relates to a test failure; =item * your operating system name and version; =item * the output of C; =item * the version of Net-SSLeay you are using; =item * the version of OpenSSL or LibreSSL you are using. =back =head1 AUTHORS Originally written by Chris Novakovic. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen. =head1 COPYRIGHT AND LICENSE Copyright 2020- Chris Novakovic . Copyright 2020- Tuure Vartiainen . Copyright 2020- Heikki Vatiainen . This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =cut Net-SSLeay-1.92/inc/Test/Net/SSLeay.pm0000644000175000001440000005661414167654427016003 0ustar csnuserspackage Test::Net::SSLeay; use 5.008001; use strict; use warnings; use base qw(Exporter); use Carp qw(croak); use Config; use Cwd qw(abs_path); use English qw( $EVAL_ERROR $OSNAME $PERL_VERSION -no_match_vars ); use File::Basename qw(dirname); use File::Spec::Functions qw( abs2rel catfile ); use Test::Builder; use Test::Net::SSLeay::Socket; our $VERSION = '1.92'; our @EXPORT_OK = qw( can_fork can_really_fork can_thread data_file_path dies_like dies_ok doesnt_warn initialise_libssl is_libressl is_openssl is_protocol_usable lives_ok new_ctx protocols tcp_socket warns_like ); my $tester = Test::Builder->new(); my $data_path = catfile( dirname(__FILE__), '..', '..', '..', 't', 'data' ); my $initialised = 0; my %protos = ( 'TLSv1.3' => { constant => \&Net::SSLeay::TLS1_3_VERSION, constant_type => 'version', priority => 6, }, 'TLSv1.2' => { constant => \&Net::SSLeay::TLSv1_2_method, constant_type => 'method', priority => 5, }, 'TLSv1.1' => { constant => \&Net::SSLeay::TLSv1_1_method, constant_type => 'method', priority => 4, }, 'TLSv1' => { constant => \&Net::SSLeay::TLSv1_method, constant_type => 'method', priority => 3, }, 'SSLv3' => { constant => \&Net::SSLeay::SSLv3_method, constant_type => 'method', priority => 2, }, 'SSLv2' => { constant => \&Net::SSLeay::SSLv2_method, constant_type => 'method', priority => 1, }, ); my ( $test_no_warnings, $test_no_warnings_name, @warnings ); END { _test_no_warnings() if $test_no_warnings; } sub _all { my ( $sub, @list ) = @_; for (@list) { $sub->() or return 0; } return 1; } sub _diag { my (%args) = @_; $tester->diag( ' ' x 9, 'got: ', $args{got} ); $tester->diag( ' ' x 4, 'expected: ', $args{expected} ); } sub _libssl_fatal { my ($context) = @_; croak "$context: " . Net::SSLeay::ERR_error_string( Net::SSLeay::ERR_get_error() ); } sub _load_net_ssleay { eval { require Net::SSLeay; 1; } or croak $EVAL_ERROR; return 1; } sub _test_no_warnings { my $got_str = join q{, }, map { qq{'$_'} } @warnings; my $got_type = @warnings == 1 ? 'warning' : 'warnings'; $tester->ok( @warnings == 0, $test_no_warnings_name ) or _diag( got => "$got_type $got_str", expected => 'no warnings', ); } sub import { my ( $class, @imports ) = @_; # Enable strict and warnings in the caller strict->import; warnings->import; # Import common modules into the caller's namespace my $caller = caller; for (qw(Test::More)) { eval "package $caller; use $_; 1;" or croak $EVAL_ERROR; } # Import requested Test::Net::SSLeay symbols into the caller's namespace __PACKAGE__->export_to_level( 1, $class, @imports ); return 1; } sub can_fork { return 1 if can_really_fork(); # Some platforms provide fork emulation using ithreads return 1 if $Config{d_pseudofork}; # d_pseudofork was added in Perl 5.10.0 - this is an approximation for # older Perls if ( ( $OSNAME eq 'Win32' or $OSNAME eq 'NetWare' ) and $Config{useithreads} and $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/ ) { return 1; } return can_thread(); } sub can_really_fork { return 1 if $Config{d_fork}; return 0; } sub can_thread { return 0 if not $Config{useithreads}; # Threads are broken in Perl 5.10.0 when compiled with GCC 4.8 or above # (see GH #175) if ( $PERL_VERSION == 5.010000 and $Config{ccname} eq 'gcc' and defined $Config{gccversion} # gccversion is sometimes defined for non-GCC compilers (see GH-350); # compilers that are truly GCC are identified with a version number in # gccversion and $Config{gccversion} =~ /^\d+\.\d+/ ) { my ( $gcc_major, $gcc_minor ) = split /[.\s]+/, $Config{gccversion}; return 0 if ( $gcc_major > 4 or ( $gcc_major == 4 and $gcc_minor >= 8 ) ); } # Devel::Cover doesn't (currently) work with threads return 0 if $INC{'Devel/Cover.pm'}; return 1; } sub data_file_path { my ($data_file) = @_; my $abs_path = catfile( abs_path($data_path), $data_file ); my $rel_path = abs2rel($abs_path); croak "$rel_path: data file does not exist" if not -e $abs_path; return $rel_path; } sub dies_like { my ( $sub, $expected, $name ) = @_; my ( $got, $ok ); if ( eval { $sub->(); 1 } ) { $ok = $tester->ok ( 0, $name ); _diag( got => 'subroutine lived', expected => "subroutine died with exception matching $expected", ); } else { $got = $EVAL_ERROR; my $test = $got =~ $expected; $ok = $tester->ok( $test, $name ) or _diag( got => qq{subroutine died with exception '$got'}, expected => "subroutine died with exception matching $expected", ); } $EVAL_ERROR = $got; return $ok; } sub dies_ok { my ( $sub, $name ) = @_; my ( $got, $ok ); if ( eval { $sub->(); 1 } ) { $got = $EVAL_ERROR; $ok = $tester->ok ( 0, $name ); _diag( got => 'subroutine lived', expected => 'subroutine died', ); } else { $got = $EVAL_ERROR; $ok = $tester->ok( 1, $name ); } $EVAL_ERROR = $got; return $ok; } sub doesnt_warn { $test_no_warnings = 1; $test_no_warnings_name = shift; $SIG{__WARN__} = sub { push @warnings, shift }; } sub initialise_libssl { return 1 if $initialised; _load_net_ssleay(); Net::SSLeay::randomize(); # Error strings aren't loaded by default until OpenSSL 1.1.0, but it's safe # to load them unconditionally because these functions are simply no-ops in # later OpenSSL versions Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::library_init(); # The test suite makes heavy use of SHA-256, but SHA-256 isn't registered by # default in all OpenSSL versions - register it manually when Net::SSLeay is # built against the following OpenSSL versions: # OpenSSL 0.9.8 series < 0.9.8o Net::SSLeay::OpenSSL_add_all_digests() if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') < 0x009080ff; # OpenSSL 1.0.0 series < 1.0.0a Net::SSLeay::OpenSSL_add_all_digests() if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') >= 0x10000000 && Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') < 0x1000001f; $initialised = 1; return 1; } sub is_libressl { _load_net_ssleay(); # The most foolproof method of checking whether libssl is provided by # LibreSSL is by checking OPENSSL_VERSION_NUMBER: every version of # LibreSSL identifies itself as OpenSSL 2.0.0, which is a version number # that OpenSSL itself will never use (version 3.0.0 follows 1.1.1) return 0 if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') != 0x20000000; return 1; } sub is_openssl { _load_net_ssleay(); # "OpenSSL 2.0.0" is actually LibreSSL return 0 if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') == 0x20000000; return 1; } sub is_protocol_usable { my ($proto) = @_; _load_net_ssleay(); initialise_libssl(); my $proto_data = $protos{$proto}; # If libssl does not support this protocol version, or if it was disabled at # compile-time, the appropriate method for that version will be missing if ( $proto_data->{constant_type} eq 'version' ? !eval { &{ $proto_data->{constant} }; 1 } : !defined &{ $proto_data->{constant} } ) { return 0; } # If libssl was built with support for this protocol version, the only # reliable way to test whether its use is permitted by the security policy # is to attempt to create a connection that uses it - if it is permitted, # the state machine enters the following states: # # SSL_CB_HANDSHAKE_START (ret=1) # SSL_CB_CONNECT_LOOP (ret=1) # SSL_CB_CONNECT_EXIT (ret=-1) # # If it is not permitted, the state machine instead enters the following # states: # # SSL_CB_HANDSHAKE_START (ret=1) # SSL_CB_CONNECT_EXIT (ret=-1) # # Additionally, ERR_get_error() returns the error code 0x14161044, although # this might not necessarily be guaranteed for all libssl versions, so # testing for it may be unreliable my $constant = $proto_data->{constant}->(); my $ctx; if ( $proto_data->{constant_type} eq 'version' ) { $ctx = Net::SSLeay::CTX_new_with_method( Net::SSLeay::TLS_method() ) or _libssl_fatal('Failed to create libssl SSL_CTX object'); Net::SSLeay::CTX_set_min_proto_version( $ctx, $constant ); Net::SSLeay::CTX_set_max_proto_version( $ctx, $constant ); } else { $ctx = Net::SSLeay::CTX_new_with_method($constant) or _libssl_fatal('Failed to create SSL_CTX object'); } my $ssl = Net::SSLeay::new($ctx) or _libssl_fatal('Failed to create SSL structure'); # For the purposes of this test, it isn't necessary to link the SSL # structure to a file descriptor, since no data actually needs to be sent or # received Net::SSLeay::set_fd( $ssl, -1 ) or _libssl_fatal('Failed to set file descriptor for SSL structure'); my @states; Net::SSLeay::CTX_set_info_callback( $ctx, sub { my ( $ssl, $where, $ret, $data ) = @_; push @states, $where; } ); Net::SSLeay::connect($ssl) or _libssl_fatal('Failed to initiate connection'); my $disabled = Net::SSLeay::CB_HANDSHAKE_START() + Net::SSLeay::CB_CONNECT_EXIT(); my $enabled = Net::SSLeay::CB_HANDSHAKE_START() + Net::SSLeay::CB_CONNECT_LOOP() + Net::SSLeay::CB_CONNECT_EXIT(); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); my $observed = 0; for my $state (@states) { $observed += $state; } return 0 if $observed == $disabled; return 1 if $observed == $enabled; croak 'Unexpected TLS state machine sequence: ' . join( ', ', @states ); } sub lives_ok { my ( $sub, $name ) = @_; my ( $got, $ok ); if ( !eval { $sub->(); 1 } ) { $got = $EVAL_ERROR; $ok = $tester->ok ( 0, $name ); _diag( got => qq{subroutine died with exception '$got'}, expected => 'subroutine lived', ); } else { $got = $EVAL_ERROR; $ok = $tester->ok( 1, $name ); } $EVAL_ERROR = $got; return $ok; } sub new_ctx { my ( $min_proto, $max_proto ) = @_; my @usable_protos = # Exclude protocol versions not supported by this libssl: grep { is_protocol_usable($_) } # Exclude protocol versions outside the desired range: grep { ( defined $min_proto ? $protos{$_}->{priority} >= $protos{$min_proto}->{priority} : 1 ) && ( defined $max_proto ? $protos{$_}->{priority} <= $protos{$max_proto}->{priority} : 1 ) } protocols(); croak 'Failed to create libssl SSL_CTX object: no usable protocol versions' if !@usable_protos; my $proto = shift @usable_protos; my $constant = $protos{$proto}->{constant}->(); my $ctx; if ( $protos{$proto}->{constant_type} eq 'version' ) { $ctx = Net::SSLeay::CTX_new_with_method( Net::SSLeay::TLS_method() ) or _libssl_fatal('Failed to create libssl SSL_CTX object'); Net::SSLeay::CTX_set_min_proto_version( $ctx, $constant ); Net::SSLeay::CTX_set_max_proto_version( $ctx, $constant ); } else { $ctx = Net::SSLeay::CTX_new_with_method($constant) or _libssl_fatal('Failed to create SSL_CTX object'); } return wantarray ? ( $ctx, $proto ) : $ctx; } sub protocols { return sort { $protos{$b}->{priority} <=> $protos{$a}->{priority} } keys %protos; } sub tcp_socket { return Test::Net::SSLeay::Socket->new( proto => 'tcp' ); } sub warns_like { my ( $sub, $expected, $name ) = @_; my @expected = ref $expected eq 'ARRAY' ? @$expected : ($expected); my @got; local $SIG{__WARN__} = sub { push @got, shift }; $sub->(); $SIG{__WARN__} = 'DEFAULT'; my $test = scalar @got == scalar @expected && _all( sub { $got[$_] =~ $expected[$_] }, 0 .. $#got ); my $ok = $tester->ok( $test, $name ) or do { my $got_str = join q{, }, map { qq{'$_'} } @got; my $expected_str = join q{, }, map { qq{'$_'} } @expected; my $got_plural = @got == 1 ? '' : 's'; my $expected_plural = @expected == 1 ? '' : 's'; _diag( got => "warning$got_plural $got_str", expected => "warning$expected_plural matching $expected_str", ); }; return $ok; } 1; __END__ =head1 NAME Test::Net::SSLeay - Helper module for the Net-SSLeay test suite =head1 VERSION This document describes version 1.92 of Test::Net::SSLeay. =head1 SYNOPSIS In a Net-SSLeay test script: # Optional summary of the purpose of the tests in this script use lib 'inc'; use Net::SSLeay; # if required by the tests use Test::Net::SSLeay qw(initialise_libssl); # import other helper # functions if required # Imports of other modules specific to this test script # Plan tests, or skip them altogether if certain preconditions aren't met if (disqualifying_condition) { plan skip_all => ...; } else { plan tests => ...; } # If this script tests Net::SSLeay functionality: initialise_libssl(); # Perform one or more Test::More-based tests =head1 DESCRIPTION This is a helper module that makes it easier (or, at least, less repetitive) to write test scripts for the Net-SSLeay test suite. For consistency, all test scripts should import this module and follow the preamble structure given in L. Importing this module has the following effects on the caller, regardless of whether any exports are requested: =over 4 =item * C and C are enabled; =item * L, the test framework used by the Net-SSLeay test suite, is imported. =back No symbols are exported by default. If desired, individual helper functions may be imported into the caller's namespace by specifying their name in the import list; see L for a list of available helper functions. =head1 HELPER FUNCTIONS =head2 can_fork if (can_fork()) { # Run tests that rely on a working fork() implementation } Returns true if this system natively supports the C system call, or if Perl can emulate C on this system using interpreter-level threads. Otherwise, returns false. =head2 can_really_fork if (can_really_fork()) { # Run tests that rely on a native fork() implementation } Returns true if this system natively supports the C system call, or false if not. =head2 can_thread if (can_thread()) { # Run tests that rely on working threads support } Returns true if reliable interpreter-level threads support is available in this Perl, or false if not. =head2 data_file_path my $cert_path = data_file_path('wildcard-cert.cert.pem'); my $key_path = data_file_path('wildcard-cert.key.pem'); Returns the relative path to a given file in the test suite data directory (C). Dies if the file does not exist. =head2 dies_like dies_like( sub { die 'This subroutine always dies' }, qr/always/, 'A test that always passes' ); Similar to L in Test::Exception|Test::Exception/throws_ok>: performs a L test that passes if a given subroutine dies with an exception string that matches a given pattern, or fails if the subroutine does not die or dies with an exception string that does not match the given pattern. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 dies_ok dies_ok( sub { my $x = 1 }, 'A test that always fails' ); Similar to L in Test::Exception|Test::Exception/dies_ok>: performs a L test that passes if a given subroutine dies, or fails if it does not. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 doesnt_warn doesnt_warn('Test script outputs no unexpected warnings'); Offers similar functionality to L: performs a L test at the end of the test script that passes if the test script executes from this point onwards without emitting any unexpected warnings, or fails if warnings are emitted before the test script ends. Warnings omitted by subroutines that are executed as part of a L test are not considered to be unexpected (even if the L test fails), and will therefore not cause this test to fail. =head2 initialise_libssl initialise_libssl(); # Run tests that call Net::SSLeay functions Initialises libssl (and libcrypto) by seeding the pseudorandom number generator, loading error strings, and registering the default TLS ciphers and digest functions. All digest functions are explicitly registered when Net::SSLeay is built against a libssl version that does not register SHA-256 by default, since SHA-256 is used heavily in the test suite PKI. libssl will only be initialised the first time this function is called, so it is safe for it to be called multiple times in the same test script. =head2 is_libressl if (is_libressl()) { # Run LibreSSL-specific tests } Returns true if libssl is provided by LibreSSL, or false if not. =head2 is_openssl if (is_openssl()) { # Run OpenSSL-specific tests } Returns true if libssl is provided by OpenSSL, or false if not. =head2 is_protocol_usable if ( is_protocol_usable('TLSv1.1') ) { # Run TLSv1.1 tests } Returns true if libssl can communicate using the given SSL/TLS protocol version (represented as a string of the format returned by L), or false if not. Note that the availability of a particular SSL/TLS protocol version may vary based on the version of OpenSSL or LibreSSL in use, the options chosen when it was compiled (e.g., OpenSSL will not support SSLv3 if it was built with C), or run-time configuration (e.g., the use of TLSv1.0 will be forbidden if the OpenSSL configuration sets the default security level to 3 or higher; see L). =head2 lives_ok lives_ok( sub { die 'Whoops' }, 'A test that always fails' ); Similar to L in Test::Exception|Test::Exception/lives_ok>: performs a L test that passes if a given subroutine executes without dying, or fails if it dies during execution. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 new_ctx my $ctx = new_ctx(); # $ctx is an SSL_CTX that uses the highest available protocol version my ( $ctx, $version ) = new_ctx( 'TLSv1', 'TLSv1.2' ); # $ctx is an SSL_CTX that uses the highest available protocol version # between TLSv1 and TLSv1.2 inclusive; $version contains the protocol # version chosen Creates a libssl SSL_CTX object that uses the most recent SSL/TLS protocol version supported by libssl, optionally bounded by the given minimum and maximum protocol versions (represented as strings of the format returned by L). If called in scalar context, returns the SSL_CTX object that was created. If called in array context, returns the SSL_CTX object and a string containing the protocol version used by the SSL_CTX object. Dies if libssl does not support any of the protocol versions in the given range, or if an SSL_CTX object that uses the chosen protocol version could not be created. =head2 protocols my @protos = protocols(); Returns an array containing strings that describe the SSL/TLS protocol versions supported by L: C<'TLSv1.3'>, C<'TLSv1.2'>, C<'TLSv1.1'>, C<'TLSv1'>, C<'SSLv3'>, and C<'SSLv2'>. The protocol versions are sorted in reverse order of age (i.e. in the order shown here). Note that it may not be possible to communicate using some of these protocol versions, depending on how libssl was compiled and is configured. These strings can be given as parameters to L to discover whether the protocol version is actually usable by libssl. =head2 tcp_socket my $server = tcp_socket(); # Accept connection from client: my $sock_in = $server->accept(); # Create connection to server: my $sock_out = $server->connect(); Creates a TCP server socket that listens on localhost on an arbitrarily-chosen free port. Convenience methods are provided for accepting, establishing and closing connections. Returns a L object. Dies on failure. =head2 warns_like warns_like( sub { warn 'First warning'; warn 'Second warning'; }, [ qr/First/, qr/Second/, ], 'A test that always passes' ); Similar to L in Test::Warn|Test::Warn/warnings_like>: performs a L test that passes if a given subroutine emits a series of warnings that match the given sequence of patterns, or fails if the subroutine emits any other sequence of warnings (or no warnings at all). If a pattern is given instead of an array reference, the subroutine will be expected to emit a single warning matching the pattern. =head1 BUGS If you encounter a problem with this module that you believe is a bug, please L in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the code you are trying to run (ideally a minimum working example that reproduces the problem), or the full output of the Net-SSLeay test suite if the problem relates to a test failure; =item * your operating system name and version; =item * the output of C; =item * the version of Net-SSLeay you are using; =item * the version of OpenSSL or LibreSSL you are using. =back =head1 AUTHORS Originally written by Chris Novakovic. Maintained by Chris Novakovic, Tuure Vartiainen and Heikki Vatiainen. =head1 COPYRIGHT AND LICENSE Copyright 2020- Chris Novakovic . Copyright 2020- Tuure Vartiainen . Copyright 2020- Heikki Vatiainen . This module is released under the terms of the Artistic License 2.0. For details, see the C file distributed with Net-SSLeay's source code. =cut Net-SSLeay-1.92/examples/0000755000175000001440000000000014167654753013673 5ustar csnusersNet-SSLeay-1.92/examples/cb-testi.pl0000644000175000001440000000104413320746140015717 0ustar csnusers#!/usr/bin/perl require Net::SSLeay; sub provide_password { # ($buf,$siz,$rwflag,$pwd)=@_; $_[0]="1234"; return 4; } Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::randomize(); $ctx=Net::SSLeay::CTX_new(); Net::SSLeay::CTX_set_options($ctx,&Net::SSLeay::OP_ALL); Net::SSLeay::CTX_set_default_passwd_cb($ctx,\&provide_password); $r=Net::SSLeay::CTX_use_PrivateKey_file($ctx,"server_key.pem",&Net::SSLeay::FILETYPE_PEM()); if($r==0) { print "vr avain\n"; } else { print "OK\n"; } Net-SSLeay-1.92/examples/callback.pl0000755000175000001440000000617213320746140015753 0ustar csnusers#!/usr/bin/perl -w # callback.pl - 8.6.1998, Sampo Kellomaki # 31.7.1999, fixed callback args, --Sampo # 7.4.2001, adapted to 0.9.6a and numerous bug reports --Sampo # # Test and demonstrate verify call back # # WARNING! Although this code works, it is by no means stable. Expect # that this stuff may break with newer than 0.9.3a --Sampo use Socket; use Net::SSLeay qw(die_now die_if_ssl_error); $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); ($dest_serv, $port, $cert_dir) = @ARGV; # Read command line my $callback_called = 0; $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); #Net::SSLeay::CTX_set_default_verify_paths($ctx); Net::SSLeay::CTX_load_verify_locations($ctx, '', $cert_dir) or die_now("CTX load verify loc=`$cert_dir' $!"); Net::SSLeay::CTX_set_verify($ctx, &Net::SSLeay::VERIFY_PEER, \&verify2); die_if_ssl_error('callback: ctx set verify'); $port = getservbyname ($port, 'tcp') unless $port =~ /^\d+$/; $dest_ip = gethostbyname ($dest_serv); $dest_serv_params = pack ('S n a4 x8', &AF_INET, $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); # The network connection is now open, lets fire up SSL $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); #Net::SSLeay::set_verify ($ssl, &Net::SSLeay::VERIFY_PEER, \&verify); Net::SSLeay::set_fd($ssl, fileno(S)); print "callback: starting ssl connect...\n"; Net::SSLeay::connect($ssl); die_if_ssl_error('callback: ssl connect'); print "Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; print Net::SSLeay::dump_peer_certificate($ssl); Net::SSLeay::ssl_write_all($ssl,"\tcallback ok\n"); shutdown S, 1; my $ra; print defined($ra = Net::SSLeay::ssl_read_all($ssl)) ? $ra : ''; Net::SSLeay::free ($ssl); Net::SSLeay::CTX_free ($ctx); close S; print $callback_called ? "OK\n" : "ERROR\n"; exit; sub verify2 { my ($ok, $x509_store_ctx) = @_; print "**** Verify 2 called ($ok)\n"; my $x = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx); if ($x) { print "Certificate:\n"; print " Subject Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($x)) . "\n"; print " Issuer Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($x)) . "\n"; } $callback_called++; return 1; } sub verify { my ($ok, $x509_store_ctx) = @_; print "**** Verify called ($ok)\n"; my $x = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx); if ($x) { print "Certificate:\n"; print " Subject Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($x)) . "\n"; print " Issuer Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($x)) . "\n"; } $callback_called++; return 1; #$ok; # 1=accept cert, 0=reject } __END__ Net-SSLeay-1.92/examples/ssl_diff.pl0000755000175000001440000000116713320746140016007 0ustar csnusers#!/usr/bin/perl # 18.6.1998, Sampo Kellomaki # Tool used to sync SSLeay.xs with ssl.h. Prints what .h has that .xs doesn't. # Usage: examples/ssl_diff.pl *pat* SSLeay.xs /usr/local/ssl/include/ssl.h # E.g: examples/ssl_diff.pl SSL_CTX_ SSLeay.xs /usr/local/ssl/include/ssl.h ($pat, $xs, $h) = @ARGV; open XS, $xs or die "Cant open .xs `$xs' ($!)\n"; foreach $_ () { next unless ($name) = /^($pat.*?)\(/o; $xs{$name} = 1; } close XS; open H, $h or die "Cant open .h `$h' ($!)\n"; foreach $_ () { next unless ($name) = /($pat.*?)\(/o; print "$name\n" unless $xs{$name}; } close H; __END__ Net-SSLeay-1.92/examples/sslcat.pl0000755000175000001440000000101613320746140015500 0ustar csnusers#!/usr/bin/perl # sslcat.pl - Send a message and receive a reply from SSL server. # # Copyright (c) 1996-2001 Sampo Kellomaki , All Rights Reserved. # $Id: sslcat.pl,v 1.3 2003/08/17 07:07:28 sampo Exp $ # Date: 7.6.1996 $host = 'localhost' unless $host = shift; $port = 443 unless $port = shift; $msg = "get \n\r\n" unless $msg = shift; $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; print "$host $port $msg\n"; use Net::SSLeay qw(sslcat); print sslcat($host, $port, $msg); __END__ Net-SSLeay-1.92/examples/https-proxy-snif.pl0000755000175000001440000001070013320746140017465 0ustar csnusers#!/usr/bin/perl # 5.6.1998, Sampo Kellomaki $usage = <foo

Bar Cool

HTTP ; &Net::SSLeay::free ($ssl); # Tear down connection close NS; } __END__ Net-SSLeay-1.92/examples/get_page_cert.pl0000644000175000001440000000170613320746140017002 0ustar csnusers#!/usr/bin/perl # 8.6.1998, Sampo Kellomaki # 25.3.2002, added certificate display --Sampo # $Id: get_page_cert.pl,v 1.1 2002/03/25 23:47:15 sampo Exp $ # Get a page via HTTP and print some info about it. use Net::SSLeay; ($site, $port, $path) = @ARGV; die "Usage: ./get_page.pl www.cryptsoft.com 443 /\n" unless $path; ($page, $result, $headers, $server_cert) = &Net::SSLeay::get_https3($site, $port, $path); if (!defined($server_cert) || ($server_cert == 0)) { print "Subject Name: undefined, Issuer Name: undefined\n"; } else { print 'Subject Name: ' . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($server_cert)) . 'Issuer Name: ' . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($server_cert)) . "\n"; } print "Headers were `$headers'\n"; print "Result was `$result'\n"; print "=================== Page follows =================\n"; print $page; __END__ Net-SSLeay-1.92/examples/passwd-cb.pl0000644000175000001440000000145113320746140016072 0ustar csnusers#!/usr/bin/perl # passwd-cb.pl # # Check using password callbacks to decrypt private keys # $Id: passwd-cb.pl,v 1.2 2002/06/05 18:25:47 sampo Exp $ use Socket; use Net::SSLeay qw(die_now die_if_ssl_error); Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); my ($key_pem, $password) = @ARGV; print "Keyfile: `$key_pem', pw: `$password'\n"; $calls = 0; sub callback { $calls++; print "Callback `$password'\n"; return $password; } my $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); if (1) { Net::SSLeay::CTX_set_default_passwd_cb($ctx, \&callback); } Net::SSLeay::CTX_use_PrivateKey_file($ctx, $key_pem, &Net::SSLeay::FILETYPE_PEM()) or print "CTX_use_PrivateKey_file failed\n"; print "calls=$calls\n"; #EOF Net-SSLeay-1.92/examples/minicli.pl0000755000175000001440000000247413320746140015644 0ustar csnusers#!/usr/bin/perl # minicli.pl - Sampo Kellomaki use Socket; use Net::SSLeay; Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; 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); # The network connection is now open, lets fire up SSL $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); $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); print "Cipher '" . Net::SSLeay::get_cipher($ssl) . "'\n"; # Exchange data $res = Net::SSLeay::write($ssl, $msg); # Perl knows how long $msg is shutdown S, 1; # Half close --> No more output, sends EOF to server $got = Net::SSLeay::read($ssl); # Perl returns undef on failure print $got; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); close S; __END__ Net-SSLeay-1.92/examples/sslecho.pl0000755000175000001440000000610713320746140015655 0ustar csnusers#!/usr/bin/perl -w # sslecho.pl - Echo server using SSL # # Copyright (c) 1996,1998 Sampo Kellomaki , All Rights Reserved. # Date: 27.6.1996, 8.6.1998 # 7.12.2001, added more support for client side certificate testing --Sampo # $Id: sslecho.pl,v 1.2 2001/12/08 17:43:14 sampo Exp $ # # Usage: ./sslecho.pl *port* *cert.pem* *key.pem* # # This server always binds to localhost as this is all that is needed # for tests. die "Usage: ./sslecho.pl *port* *cert.pem* *key.pem*\n" unless $#ARGV == 2; ($port, $cert_pem, $key_pem) = @ARGV; $our_ip = "\x7F\0\0\x01"; $trace = 2; use Socket; use Net::SSLeay qw(sslcat die_now die_if_ssl_error); $Net::SSLeay::trace = 3; # Super verbose debugging # # Create the socket and open a connection # $our_serv_params = pack ('S n a4 x8', &AF_INET, $port, $our_ip); socket (S, &AF_INET, &SOCK_STREAM, 0) or die "socket: $!"; bind (S, $our_serv_params) or die "bind: $! (port=$port)"; listen (S, 5) or die "listen: $!"; # # Prepare SSLeay # Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::randomize(); print "sslecho: Creating SSL context...\n" if $trace>1; $ctx = Net::SSLeay::CTX_new () or die_now("CTX_new ($ctx): $!\n"); print "sslecho: Setting cert and RSA key...\n" if $trace>1; Net::SSLeay::CTX_set_cipher_list($ctx,'ALL'); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem) or die "key"; while (1) { print "sslecho $$: Accepting connections...\n" if $trace>1; ($addr = accept (NS, S)) or die "accept: $!"; $old_out = select (NS); $| = 1; select ($old_out); # Piping hot! if ($trace) { ($af,$client_port,$client_ip) = unpack('S n a4 x8',$addr); @inetaddr = unpack('C4',$client_ip); print "$af connection from " . join ('.', @inetaddr) . ":$client_port\n" if $trace;; } # # Do SSL negotiation stuff # print "sslecho: Creating SSL session (cxt=`$ctx')...\n" if $trace>1; $ssl = Net::SSLeay::new($ctx) or die_now("ssl new ($ssl): $!"); print "sslecho: Setting fd (ctx $ctx, con $ssl)...\n" if $trace>1; Net::SSLeay::set_fd($ssl, fileno(NS)); print "sslecho: Entering SSL negotiation phase...\n" if $trace>1; Net::SSLeay::accept($ssl); die_if_ssl_error("ssl_echo: ssl accept: ($!)"); print "sslecho: Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n" if $trace; # # Connected. Exchange some data. # $got = Net::SSLeay::ssl_read_all($ssl) or die "$$: ssl read failed"; print "sslecho $$: got " . length($got) . " bytes\n" if $trace==2; print "sslecho: Got `$got' (" . length ($got) . " chars)\n" if $trace>2; $got = uc $got; if ($got eq 'CLIENT-CERT-TEST') { $got .= Net::SSLeay::dump_peer_certificate($ssl) . "END CERT\n"; } Net::SSLeay::ssl_write_all($ssl, $got) or die "$$: ssl write failed"; $got = ''; # in case it was huge print "sslecho: Tearing down the connection.\n\n" if $trace>1; Net::SSLeay::free ($ssl); close NS; } Net::SSLeay::CTX_free ($ctx); close S; __END__ Net-SSLeay-1.92/examples/makecert.pl0000755000175000001440000000277313320746140016015 0ustar csnusers#!/usr/bin/perl # 19.6.1998, Sampo Kellomaki # 31.3.1999, Upgraded to OpenSSL-0.9.2b, --Sampo # 31.7.1999, Upgraded to OpenSSL-0.9.3a, fixed depending on symlinks # (thanks to schinder@@pobox_.com) --Sampo # 7.4.2001, Upgraded to OpenSSL-0.9.6a --Sampo # 9.11.2001, EGD patch from Mik Firestone --Sampo # # Make a self signed cert use strict; use warnings; use File::Copy; use File::Spec::Functions qw(catfile); my $dir = shift || usage(); my $exe_path = shift || '/usr/local/ssl/bin/openssl'; my $egd = defined( $ENV{EGD_POOL} ) ? "-rand $ENV{EGD_POOL}" : ''; my $conf = catfile($dir, 'req.conf'); my $key = catfile($dir, 'key.pem' ); my $cert = catfile($dir, 'cert.pem'); open (REQ, "|$exe_path req -config $conf " . "-x509 -days 3650 -new -keyout $key $egd >$cert") or die "cant open req. check your path ($!)"; print REQ <, All Rights Reserved. # $Id: tcpecho.pl,v 1.2 2003/08/17 07:44:47 sampo Exp $ # 17.8.2003, created --Sampo # # Usage: ./tcpecho.pl *port* # # This server always binds to localhost as this is all that is needed # for tests. die "Usage: ./tcpecho.pl *port*\n" unless $#ARGV == 0; ($port) = @ARGV; $our_ip = "\x7F\0\0\x01"; $trace = 2; use Socket; use Net::SSLeay; # # Create the socket and open a connection # $our_serv_params = pack ('S n a4 x8', &AF_INET, $port, $our_ip); socket (S, &AF_INET, &SOCK_STREAM, 0) or die "socket: $!"; bind (S, $our_serv_params) or die "bind: $! (port=$port)"; listen (S, 5) or die "listen: $!"; #while (1) { # uncomment to turn off "one shot" behaviour print "tcpecho $$: Accepting connections on port $port...\n" if $trace>1; ($addr = accept(Net::SSLeay::SSLCAT_S, S)) or die "accept: $!"; $old_out = select(Net::SSLeay::SSLCAT_S); $| = 1; select ($old_out); # Piping hot! if ($trace) { ($af,$client_port,$client_ip) = unpack('S n a4 x8',$addr); @inetaddr = unpack('C4',$client_ip); print "$af connection from " . join ('.', @inetaddr) . ":$client_port\n" if $trace;; } # # Connected. Exchange some data. # $got = Net::SSLeay::tcp_read_all() or die "$$: read failed"; print "tcpecho $$: got " . length($got) . " bytes\n" if $trace==2; print "tcpecho: Got `$got' (" . length ($got) . " chars)\n" if $trace>2; $got = uc $got; Net::SSLeay::tcp_write_all($got) or die "$$: write failed"; $got = ''; # in case it was huge print "tcpecho: Tearing down the connection.\n\n" if $trace>1; close Net::SSLeay::SSLCAT_S; #} close S; __END__ Net-SSLeay-1.92/examples/x509_cert_details.pl0000755000175000001440000002450213740421545017450 0ustar csnusers#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use Data::Dumper; use IO::Socket::INET; use Net::SSLeay qw/XN_FLAG_RFC2253 ASN1_STRFLGS_ESC_MSB/; # Sorting keys helps keeping diffs at minimum between dumps. # # Quotekeys and Trailingcomma were set to match format used to # generate t/data/testcert_extended.crt.pem_dump when it was initially # imported to version control. They can likely be dropped in a future # release. $Data::Dumper::Sortkeys = 1; $Data::Dumper::Useqq = 1; $Data::Dumper::Quotekeys = 0; $Data::Dumper::Trailingcomma = 1; Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); # --- commandline options and global variables my ($g_host, $g_pem, $g_dump, $g_showusage); GetOptions( 'help|?' => \$g_showusage, 'dump' => \$g_dump, 'host=s@' => \$g_host, 'pem=s@' => \$g_pem, ) or $g_showusage = 1; # --- subroutines sub show_usage { die < -help -? show this help -pem process X509 certificate from file (PEM format) -host : process X509 certificate presented by SSL server -dump full dump of X509 certificate info Example: $0 -pem file1.pem $0 -pem file1.pem -pem file2.pem $0 -host twitter.com:443 -dump EOL } sub get_cert_details { my $x509 = shift; my $rv = {}; my $flag_rfc22536_utf8 = (XN_FLAG_RFC2253) & (~ ASN1_STRFLGS_ESC_MSB); die 'ERROR: $x509 is NULL, gonna quit' unless $x509; warn "Info: dumping subject\n"; my $subj_name = Net::SSLeay::X509_get_subject_name($x509); my $subj_count = Net::SSLeay::X509_NAME_entry_count($subj_name); $rv->{subject}->{count} = $subj_count; $rv->{subject}->{oneline} = Net::SSLeay::X509_NAME_oneline($subj_name); $rv->{subject}->{print_rfc2253} = Net::SSLeay::X509_NAME_print_ex($subj_name); $rv->{subject}->{print_rfc2253_utf8} = Net::SSLeay::X509_NAME_print_ex($subj_name, $flag_rfc22536_utf8); $rv->{subject}->{print_rfc2253_utf8_decoded} = Net::SSLeay::X509_NAME_print_ex($subj_name, $flag_rfc22536_utf8, 1); for my $i (0..$subj_count-1) { my $entry = Net::SSLeay::X509_NAME_get_entry($subj_name, $i); my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry); my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry); my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); $rv->{subject}->{entries}->[$i] = { oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), data => Net::SSLeay::P_ASN1_STRING_get($asn1_string), data_utf8_decoded => Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), nid => ($nid>0) ? $nid : undef, ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, }; } warn "Info: dumping issuer\n"; my $issuer_name = Net::SSLeay::X509_get_issuer_name($x509); my $issuer_count = Net::SSLeay::X509_NAME_entry_count($issuer_name); $rv->{issuer}->{count} = $issuer_count; $rv->{issuer}->{oneline} = Net::SSLeay::X509_NAME_oneline($issuer_name); $rv->{issuer}->{print_rfc2253} = Net::SSLeay::X509_NAME_print_ex($issuer_name); $rv->{issuer}->{print_rfc2253_utf8} = Net::SSLeay::X509_NAME_print_ex($issuer_name, $flag_rfc22536_utf8); $rv->{issuer}->{print_rfc2253_utf8_decoded} = Net::SSLeay::X509_NAME_print_ex($issuer_name, $flag_rfc22536_utf8, 1); for my $i (0..$issuer_count-1) { my $entry = Net::SSLeay::X509_NAME_get_entry($issuer_name, $i); my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry); my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry); my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); $rv->{issuer}->{entries}->[$i] = { oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), data => Net::SSLeay::P_ASN1_STRING_get($asn1_string), data_utf8_decoded => Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), nid => ($nid>0) ? $nid : undef, ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, }; } warn "Info: dumping alternative names\n"; $rv->{subject}->{altnames} = [ Net::SSLeay::X509_get_subjectAltNames($x509) ]; #XXX-TODO maybe add a function for dumping issuerAltNames #$rv->{issuer}->{altnames} = [ Net::SSLeay::X509_get_issuerAltNames($x509) ]; warn "Info: dumping hashes/fingerprints\n"; $rv->{hash}->{subject} = { dec=>Net::SSLeay::X509_subject_name_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_subject_name_hash($x509)) }; $rv->{hash}->{issuer} = { dec=>Net::SSLeay::X509_issuer_name_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_issuer_name_hash($x509)) }; $rv->{hash}->{issuer_and_serial} = { dec=>Net::SSLeay::X509_issuer_and_serial_hash($x509), hex=>sprintf("%X",Net::SSLeay::X509_issuer_and_serial_hash($x509)) }; $rv->{fingerprint}->{md5} = Net::SSLeay::X509_get_fingerprint($x509, "md5"); $rv->{fingerprint}->{sha1} = Net::SSLeay::X509_get_fingerprint($x509, "sha1"); my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"); $rv->{digest_sha1}->{pubkey} = Net::SSLeay::X509_pubkey_digest($x509, $sha1_digest); $rv->{digest_sha1}->{x509} = Net::SSLeay::X509_digest($x509, $sha1_digest); warn "Info: dumping expiration\n"; $rv->{not_before} = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($x509)); $rv->{not_after} = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($x509)); warn "Info: dumping serial number\n"; my $ai = Net::SSLeay::X509_get_serialNumber($x509); $rv->{serial} = { hex => Net::SSLeay::P_ASN1_INTEGER_get_hex($ai), dec => Net::SSLeay::P_ASN1_INTEGER_get_dec($ai), long => Net::SSLeay::ASN1_INTEGER_get($ai), }; $rv->{version} = Net::SSLeay::X509_get_version($x509); warn "Info: dumping extensions\n"; my $ext_count = Net::SSLeay::X509_get_ext_count($x509); $rv->{extensions}->{count} = $ext_count; for my $i (0..$ext_count-1) { my $ext = Net::SSLeay::X509_get_ext($x509,$i); my $asn1_string = Net::SSLeay::X509_EXTENSION_get_data($ext); my $asn1_object = Net::SSLeay::X509_EXTENSION_get_object($ext); my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object); $rv->{extensions}->{entries}->[$i] = { critical => Net::SSLeay::X509_EXTENSION_get_critical($ext), oid => Net::SSLeay::OBJ_obj2txt($asn1_object,1), nid => ($nid>0) ? $nid : undef, ln => ($nid>0) ? Net::SSLeay::OBJ_nid2ln($nid) : undef, sn => ($nid>0) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, data => Net::SSLeay::X509V3_EXT_print($ext), }; } warn "Info: dumping CDP\n"; $rv->{cdp} = [ Net::SSLeay::P_X509_get_crl_distribution_points($x509) ]; warn "Info: dumping extended key usage\n"; $rv->{extkeyusage} = { oid => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,0) ], nid => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,1) ], sn => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,2) ], ln => [ Net::SSLeay::P_X509_get_ext_key_usage($x509,3) ], }; warn "Info: dumping key usage\n"; $rv->{keyusage} = [ Net::SSLeay::P_X509_get_key_usage($x509) ]; warn "Info: dumping netscape cert type\n"; $rv->{ns_cert_type} = [ Net::SSLeay::P_X509_get_netscape_cert_type($x509) ]; warn "Info: dumping other info\n"; $rv->{certificate_type} = Net::SSLeay::X509_certificate_type($x509); $rv->{signature_alg} = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_signature_alg($x509)); $rv->{pubkey_alg} = Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_pubkey_alg($x509)); $rv->{pubkey_size} = Net::SSLeay::EVP_PKEY_size(Net::SSLeay::X509_get_pubkey($x509)); $rv->{pubkey_bits} = Net::SSLeay::EVP_PKEY_bits(Net::SSLeay::X509_get_pubkey($x509)); if (Net::SSLeay::SSLeay >= 0x1000000f) { $rv->{pubkey_id} = Net::SSLeay::EVP_PKEY_id(Net::SSLeay::X509_get_pubkey($x509)); } return $rv; } sub dump_details { my ($data, $comment) = @_; print "\n"; eval { require Data::Dump }; if (!$@) { # Data::Dump creates nicer output print "# $comment\n"; print "# hashref dumped via Data::Dump\n"; $Data::Dump::TRY_BASE64 = 0 if $Data::Dump::TRY_BASE64; print Data::Dump::pp($data); } else { print "# $comment\n"; print "# hashref dumped via Data::Dumper\n"; print Dumper($data); } print "\n"; } sub print_basic_info { my ($data) = @_; print "\n"; print "Subject: ", $data->{subject}->{print_rfc2253}, "\n"; print "Issuer: ", $data->{issuer}->{print_rfc2253}, "\n"; print "NotBefore: ", $data->{not_before}, "\n"; print "NotAfter: ", $data->{not_after}, "\n"; print "SHA1: ", $data->{fingerprint}->{sha1}, "\n"; print "MD5: ", $data->{fingerprint}->{md5}, "\n"; print "\n"; } # --- main show_usage() if $g_showusage || (!$g_host && !$g_pem); if ($g_pem) { for my $f(@$g_pem) { die "ERROR: non existing file '$f'" unless -f $f; warn "#### Going to load PEM file '$f'\n"; my $bio = Net::SSLeay::BIO_new_file($f, 'rb') or die "ERROR: BIO_new_file failed"; my $x509 = Net::SSLeay::PEM_read_bio_X509($bio) or die "ERROR: PEM_read_bio_X509 failed"; my $cert_details = get_cert_details($x509); warn "#### Certificate info\n"; if ($g_dump) { dump_details($cert_details, "exported via command: perl examples/x509_cert_details.pl -dump -pem $f > $f\_dump"); } else { print_basic_info($cert_details); } warn "#### DONE\n"; } } if ($g_host) { for my $h (@$g_host) { my ($host, $port) = split /:/, $h; die "ERROR: invalid host '$h'" unless $host && $port =~ /\d+/; warn "#### Going to connect to host=$host, port=$port\n"; my $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp') or die "ERROR: cannot create socket"; my $ctx = Net::SSLeay::CTX_new() or die "ERROR: CTX_new failed"; Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL); my $ssl = Net::SSLeay::new($ctx) or die "ERROR: new failed"; Net::SSLeay::set_fd($ssl, fileno($sock)) or die "ERROR: set_fd failed"; Net::SSLeay::connect($ssl) or die "ERROR: connect failed"; my $x509 = Net::SSLeay::get_peer_certificate($ssl); my $cert_details = get_cert_details($x509); warn "#### Certificate info\n"; if ($g_dump) { dump_details($cert_details, "host: $h\n"); } else { print_basic_info($cert_details); } warn "#### DONE\n"; } } Net-SSLeay-1.92/examples/get_page.pl0000755000175000001440000000077313320746140015773 0ustar csnusers#!/usr/bin/perl # 8.6.1998, Sampo Kellomaki # Get a page via HTTP and print some info about it. use Net::SSLeay; ($site, $port, $path) = @ARGV; die "Usage: ./get_page.pl www.cryptsoft.com 443 /\n" unless $path; ($page, $result, %headers) = &Net::SSLeay::get_https($site, $port, $path); print "Result was `$result'\n"; foreach $h (sort keys %headers) { print "Header `$h'\tvalue `$headers{$h}'\n"; } print "=================== Page follows =================\n"; print $page; __END__ Net-SSLeay-1.92/examples/stdio_bulk.pl0000755000175000001440000000503613320746140016354 0ustar csnusers#!/usr/bin/perl # stdio_bulk.pl - 8.6.1998, Sampo Kellomaki # Send tons of stuff over SSL connected by STDIO pipe. # This also demonstrates how you can communicate via arbitrary stream, not # just a TCP one. # $Id: stdio_bulk.pl,v 1.3 2003/06/13 21:14:41 sampo Exp $ use Socket; use Net::SSLeay qw(die_now die_if_ssl_error); $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); #$Net::SSLeay::trace = 2; ($cert_pem, $key_pem, $how_much) = @ARGV; # Read command line $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); Net::SSLeay::set_server_cert_and_key($ctx, $cert_pem, $key_pem) or die "key"; pipe RS, WC or die "pipe 1 ($!)"; pipe RC, WS or die "pipe 2 ($!)"; select WC; $| = 1; select WS; $| = 1; select STDOUT; $| = 1; if ($child_pid = fork) { print "$$: I'm the server for child $child_pid\n"; $ssl = Net::SSLeay::new($ctx) or die_now "$$: new ($ssl) ($!)"; Net::SSLeay::set_rfd($ssl, fileno(RS)); Net::SSLeay::set_wfd($ssl, fileno(WS)); Net::SSLeay::accept($ssl) and die_if_ssl_error("$$: ssl accept: $!"); print "$$: Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; #print "$$: " . Net::SSLeay::dump_peer_certificate($ssl); $got = Net::SSLeay::ssl_read_all($ssl,$how_much) or die "$$: ssl read failed"; print "$$: got " . length($got) . " bytes\n"; Net::SSLeay::ssl_write_all($ssl, \$got) or die "$$: ssl write failed"; $got = ''; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); wait; # wait for child to read the stuff close WS; close RS; print "$$: server done ($?).\n" . (($? >> 8) ? "ERROR\n" : "OK\n"); exit; } print "$$: I'm the child.\n"; sleep 1; # Give server time to get its act together $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); Net::SSLeay::set_rfd($ssl, fileno(RC)); Net::SSLeay::set_wfd($ssl, fileno(WC)); Net::SSLeay::connect($ssl); die_if_ssl_error("ssl connect"); print "$$: Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; print "$$: " . Net::SSLeay::dump_peer_certificate($ssl); # Exchange data $data = 'B' x $how_much; Net::SSLeay::ssl_write_all($ssl, \$data) or die "$$: ssl write failed"; $got = Net::SSLeay::ssl_read_all($ssl, $how_much) or die "$$: ssl read failed"; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); close WC; close RC; exit ($data ne $got); __END__ Net-SSLeay-1.92/examples/req.conf0000644000175000001440000000232013320746140015304 0ustar csnusers# SSLeay config file for generating self signed certificate # for testing Net::SSLeay.pm (see `make test' alias test.pl) # # 8.6.1998, Sampo Kellomaki #################################################################### [ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attr encrypt_rsa_key = no [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 countryName_default = PT stateOrProvinceName = State or Province Name (optional) localityName = Locality Name (eg, city) localityName_default = Lisboa organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (the name of your machine) commonName_max = 64 emailAddress = Email Address emailAddress_max = 40 # Challenge password is used for delievering the cert (or what)??? [ req_attr ] challengePassword = A challenge password challengePassword_min = 0 challengePassword_max = 80 #EOF Net-SSLeay-1.92/examples/cli-cert.pl0000644000175000001440000000733513320746140015720 0ustar csnusers#!/usr/bin/perl # cli-cert.pl # 8.6.1998, originally written as stdio_bulk.pl Sampo Kellomaki # 8.12.2001, adapted to test client certificates # # Contact server using client side certificate. Demonstrates how to # set up the client and how to make the server request the certificate. # This also demonstrates how you can communicate via arbitrary stream, not # just a TCP one. # $Id: cli-cert.pl,v 1.2 2003/06/13 21:14:41 sampo Exp $ use Socket; use Net::SSLeay qw(die_now die_if_ssl_error); $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); #$Net::SSLeay::trace = 2; ($cert_pem, $key_pem, $cert_dir) = @ARGV; # Read command line $how_much = 10000; ### Note: the following initialization is common for both client ### and the server. In particular, it is important that VERIFY_PEER ### is sent on the server as well, because otherwise the client ### certificate will never be requested. $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem) or die "key"; Net::SSLeay::CTX_load_verify_locations($ctx, '', $cert_dir) or die_now("CTX load verify loc=`$cert_dir' $!"); Net::SSLeay::CTX_set_verify($ctx, &Net::SSLeay::VERIFY_PEER, \&verify); die_if_ssl_error('callback: ctx set verify'); pipe RS, WC or die "pipe 1 ($!)"; pipe RC, WS or die "pipe 2 ($!)"; select WC; $| = 1; select WS; $| = 1; select STDOUT; $| = 1; if ($child_pid = fork) { print "$$: I'm the server for child $child_pid\n"; $ssl = Net::SSLeay::new($ctx) or die_now "$$: new ($ssl) ($!)"; Net::SSLeay::set_rfd($ssl, fileno(RS)); Net::SSLeay::set_wfd($ssl, fileno(WS)); Net::SSLeay::accept($ssl) and die_if_ssl_error("$$: ssl accept: $!"); print "$$: Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; print "$$: client cert: " . Net::SSLeay::dump_peer_certificate($ssl); $got = Net::SSLeay::ssl_read_all($ssl,$how_much) or die "$$: ssl read failed"; print "$$: got " . length($got) . " bytes\n"; Net::SSLeay::ssl_write_all($ssl, \$got) or die "$$: ssl write failed"; $got = ''; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); wait; # wait for child to read the stuff close WS; close RS; print "$$: server done ($?).\n" . (($? >> 8) ? "ERROR\n" : "OK\n"); exit; } print "$$: I'm the child.\n"; sleep 1; # Give server time to get its act together $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); Net::SSLeay::set_rfd($ssl, fileno(RC)); Net::SSLeay::set_wfd($ssl, fileno(WC)); Net::SSLeay::connect($ssl); die_if_ssl_error("ssl connect"); print "$$: Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; print "$$: server cert: " . Net::SSLeay::dump_peer_certificate($ssl); # Exchange data $data = 'B' x $how_much; Net::SSLeay::ssl_write_all($ssl, \$data) or die "$$: ssl write failed"; $got = Net::SSLeay::ssl_read_all($ssl, $how_much) or die "$$: ssl read failed"; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); close WC; close RC; exit ($data ne $got); sub verify { return 1; my ($ok, $x509_store_ctx) = @_; print "$$: **** Verify 2 called ($ok)\n"; my $x = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx); if ($x) { print "$$: Certificate:\n"; print " Subject Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($x)) . "\n"; print " Issuer Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($x)) . "\n"; } $callback_called++; return 1; } __END__ Net-SSLeay-1.92/examples/tcpcat.pl0000755000175000001440000000064613320746140015475 0ustar csnusers#!/usr/bin/perl # tcpcat.pl - Send a message and receive a reply from TCP server. # # Copyright (c) 2003 Sampo Kellomaki , All Rights Reserved. # $Id$ # 17.8.2003, created --Sampo $host = 'localhost' unless $host = shift; $port = 443 unless $port = shift; $msg = "get \n\r\n" unless $msg = shift; print "$host $port $msg\n"; use Net::SSLeay qw(tcpcat); print tcpcat($host, $port, $msg); __END__ Net-SSLeay-1.92/examples/bulk.pl0000755000175000001440000000364213320746140015153 0ustar csnusers#!/usr/bin/perl -w # bulk.pl - 8.6.1998, Sampo Kellomaki # Send tons of stuff over SSL (just for testing). # There's also an example about using the call back. use Socket; use Net::SSLeay qw(die_now die_if_ssl_error); $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); ($dest_serv, $port, $how_much) = @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); # The network connection is now open, lets fire up SSL $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!"); Net::SSLeay::set_fd($ssl, fileno(S)); # Must use fileno Net::SSLeay::connect($ssl); die_if_ssl_error('bulk: ssl connect'); print "Cipher `" . Net::SSLeay::get_cipher($ssl) . "'\n"; $cert = Net::SSLeay::get_peer_certificate($ssl); die_if_ssl_error('get_peer_certificate'); print "Subject Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($cert)) . "\n"; print "Issuer Name: " . Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($cert)) . "\n"; # Exchange data $data = 'A' x $how_much; Net::SSLeay::ssl_write_all($ssl, \$data) or die "ssl write failed"; shutdown S, 1; # Half close --> No more output, sends EOF to server $got = Net::SSLeay::ssl_read_all($ssl) or die "ssl read failed"; Net::SSLeay::free ($ssl); # Tear down connection Net::SSLeay::CTX_free ($ctx); close S; print $data eq $got ? "OK\n" : "ERROR\n"; exit; __END__ Net-SSLeay-1.92/examples/get_authenticated_page.pl0000755000175000001440000000133213320746140020665 0ustar csnusers#!/usr/bin/perl # 8.6.1998, Sampo Kellomaki # Get a page via HTTP and print some info about it. # Demonstrates how to generate password header use Net::SSLeay qw(get_https make_headers); use MIME::Base64; ($user, $pass, $site, $port, $path) = @ARGV; die "Usage: ./get_authenticated_page.pl user pass www.bacus.com 443 /\n" unless $path; ($page, $result, %headers) = get_https($site, $port, $path, make_headers('Authorization' => 'Basic ' . MIME::Base64::encode("$user:$pass")) ); print "Result was `$result'\n"; foreach $h (sort keys %headers) { print "Header `$h'\tvalue `$headers{$h}'\n"; } print "=================== Page follows =================\n"; print $page; __END__ Net-SSLeay-1.92/examples/ephemeral.pl0000644000175000001440000000105113320746140016145 0ustar csnusers#!/usr/bin/perl -w # ephemeral.pl mikem@open.com.au # # Test and demonstrate setting ephemeral RSA key use Net::SSLeay qw(die_now); Net::SSLeay::randomize(); Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!"); $rsa = &Net::SSLeay::RSA_generate_key(512, 0x10001); # 0x10001 = RSA_F4 die_now("Failed to set ephemeral RSA key $!") if (&Net::SSLeay::CTX_set_tmp_rsa($ctx, $rsa) < 0); print "OK\n"; exit; Net-SSLeay-1.92/examples/bio.pl0000644000175000001440000000226413320746140014763 0ustar csnusers#!/usr/bin/perl -w # bio.pl mikem@open.com.au # # Test and demonstrate BIO interface use Net::SSLeay qw(die_now); $data = '0123456789' x 100; $len = length($data); $b = &Net::SSLeay::BIO_new(&Net::SSLeay::BIO_s_mem()) or die_now("Could not create memory BIO $!"); &Net::SSLeay::BIO_write($b, $data) or die_now("Could not write memory BIO $!"); # Should now have 1000 bytes in BIO $pending = &Net::SSLeay::BIO_pending($b); die("Incorrect result from BIO_pending: $pending. Should be $len") unless $pending == $len; # Partial read of 9 bytes $len = 9; $part = &Net::SSLeay::BIO_read($b, $len); $nlen = length($part); die("Incorrect result from BIO_read: $len. Should be 9") unless $nlen == $len; die("Incorrect data from BIO_read: $len. Should be 012345678") unless $part eq '012345678'; # Should be 991 bytes left $len = 991; $pending = &Net::SSLeay::BIO_pending($b); die("Incorrect result from BIO_pending: $pending. Should be $len") unless $pending == $len; # Read the rest $part = &Net::SSLeay::BIO_read($b); $nlen = length($part); die("Incorrect result from BIO_read: $len. Should be 991") unless $len == $nlen; &Net::SSLeay::BIO_free($b); print "OK\n"; exit; Net-SSLeay-1.92/examples/ssl-inetd-serv.pl0000755000175000001440000000315213320746140017071 0ustar csnusers#!/usr/bin/perl # ssl-inetd-serv.pl - SSL echo server run from inetd # # Copyright (c) 1996,1998 Sampo Kellomaki . All Rights Reserved. # Date: 27.6.1996, 19.6.1998 # # /etc/inetd.conf: # ssltst stream tcp nowait root /usr/sampo/ssl-inetd-serv.pl ssl-inetd # # /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(); chdir '/usr/sampo' or die "chdir: $!"; $| = 1; # STDOUT Piping hot! open LOG, ">>log" or die "Can't open log file $!"; select LOG; $| = 1; print "ssl-inetd-serv.pl started\n"; print "Creating SSL context...\n"; $ctx = Net::SSLeay::CTX_new or die_now("CTX_new ($ctx) ($!)"); print "Setting private key and certificate...\n"; Net::SSLeay::set_server_cert_and_key($ctx, 'cert.pem', 'key.pem') or die "key"; print "Creating SSL connection (context was '$ctx')...\n"; $ssl = Net::SSLeay::new($ctx) or die_now("new ($ssl) ($!)"); print "Setting fds (ctx $ctx, con $ssl)...\n"; Net::SSLeay::set_rfd($ssl, fileno(STDIN)); Net::SSLeay::set_wfd($ssl, fileno(STDOUT)); print "Entering SSL negotiation phase...\n"; Net::SSLeay::accept($ssl); die_if_ssl_error("accept: $!"); print "Cipher '" . Net::SSLeay::get_cipher($ssl) . "'\n"; # # Connected. Exchange some data. # $got = Net::SSLeay::ssl_read_all($ssl) or die "$$: ssl read failed"; print "Got `$got' (" . length ($got) . " chars)\n"; $got = uc $got; Net::SSLeay::ssl_write_all($ssl, $got) or die "$$: ssl write failed"; print "Tearing down the connection.\n"; Net::SSLeay::free ($ssl); Net::SSLeay::CTX_free ($ctx); close LOG; __END__ Net-SSLeay-1.92/README.Win320000644000175000001440000001655113320761522013625 0ustar csnusersBuilding on Win 32 platforms ============================ 31.7.1999, Sampo Kellomaki 7.6.2002, reviewed and added comments, --Sampo 16.8.2002, added comments by Marcel Bucher --Sampo 10.7.2007. Complete rewrite to agree with latest version 1.31. References to ancient versions and untested procedures removed --mikem 22.4.2010 Updated info for 64 bit versions --mikem Notes: 1. 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. This appears to be due to incompatible compile options between the openssl libraries and Net::SSLeay. In particular it has been observed with Shining Light OpenSSL See https://www.openssl.org/support/faq.html for more details. Alas, the apparently simple and receommended solution of adding applink.c to the SSLeay library does not work, since applink.c need to be in the .exe file, not the .dll for this to work. Best workaround is to build and install OpenSSL for windows yourself. 2. If your OpenSSL is installed in an unusual place, you can tell Net-SSLeay where to find it with the OPENSSL_PREFIX environment variable: set OPENSSL_PREFIX=c:\OpenSSL-1.0.1c perl Makefile.PL make ..... 1. Windows Server 2003 ActivePerl 5.8.8.820 VC++ 6.0 Microsoft Platform SDK SVR2003R2 Shining Light Win32 OpenSSL 0.9.7L http://www.shininglightpro.com/products/Win32OpenSSL.html Dynamic linking to SSL DLLs Install all packages in the order listed above Unpack and install the Net-SSLeay package cd Net-SSLeay-xxxx perl Makefile.PL nmake nmake test nmake install Caution. There is an issue with Shining Light Win32 OpenSSL 0.9.7m and 0.9.8e on Server 2003: These versions were built with VC 7.1 and the packages are missing the 7.1 runtime DLL. This means that the openssl binaries from those versions will not run on a standard Server 2003 platform, and this prevents Net-SSLeay being built. Shining Light say this problem will be fixed in later versions, where they will revert to the earlier build procedures. 2. Windows Server 2003 ActivePerl 5.8.8.820 VC++ 6.0 Microsoft Platform SDK SVR2003R2 OpenSSL 0.9.8e source openssl-0.9.8e.tar.gz Dynamic linking to SSL DLLs Install all packages in the order listed above Unpack and build OpenSSL: cd openssl-0.9.8e perl Configure VC-WIN32 --prefix=c:/OpenSSL ms\do_ms nmake -f ms\ntdll.mak nmake -f ms\ntdll.mak install (if you have trouble getting to this stage, consult INSTALL.W32) copy c:\OpenSSL\bin\*.dll c:\windows\system32 Unpack and install the Net-SSLeay package cd Net-SSLeay-xxxx perl Makefile.PL nmake copy c:\OpenSSL\bin\*.dll blib\arch\auto\Net\SSLeay\ nmake test nmake install 3. Windows XP SP2 CAUTION: this is not working yet ActivePerl 5.8.8.820 Visual Studio Express 2005 Microsoft Platform SDK SVR2003R2 OpenSSL 0.9.8e source openssl-0.9.8e.tar.gz Dynamic linking to SSL DLLs - Install all packages in the order listed above (make sure you follow the instructions on the download page about adding the appropriate paths to the Projects and Solutions section of the Options dialog box, and updating corewin_express.vsprops file) - Start a build shell with Start->All Programs->Microsoft Windows SDK->CMD Shell - cd openssl-0.9.8e - perl Configure VC-WIN32 --prefix=c:/OpenSSL - ms\do_masm - nmake -f ms\ntdll.mak - nmake -f ms\ntdll.mak install (if you have trouble getting to this stage, consult INSTALL.W32) - cd Net-SSLeay-xxxx - perl Makefile.PL - nmake - copy c:\OpenSSL\bin\*.dll blib\arch\auto\Net\SSLeay\ - nmake test CAUTION: nmake test fails at this stage. Any suggestions?? This may be relevant: http://www.itwriting.com/blog/?postid=261&replyto=2542 - nmake install 4. Windows XP SP2 Strawberry Perl 5.8.8-alpha-2 OpenSSL 0.9.8e source openssl-0.9.8e.tar.gz - Install Strawberry Perl by running the installer (strawberry-perl-5.8.8-alpha-2.exe in this example) - Unpack openssl-0.9.8e.tar.gz - cd openssl-0.9.8e - ms\mingw32 - cd out - ..\ms\test (if you have trouble getting to this stage, consult INSTALL.W32) - md c:\openssl - md c:\openssl\bin - md c:\openssl\lib - md c:\openssl\include - md c:\openssl\include\openssl - copy /b inc32\openssl\* c:\openssl\include\openssl - copy /b out\libssl32.a c:\openssl\lib - copy /b out\libeay32.a c:\openssl\lib - copy /b libssl32.dll c:\openssl\bin - copy /b libeay32.dll c:\openssl\bin - copy /b out\openssl.exe c:\openssl\bin - cd Net-SSLeay-xxxx - c:\strawberry-perl\perl\bin\perl Makefile.PL - dmake - copy c:\openssl\bin\*.dll blib/arch/auto/Net/SSLeay - dmake install 4. Windows XP SP2 Perl CamelPack perl-camelpack-5.8.7.exe Shining Light Win32 OpenSSL 0.9.7L http://www.shininglightpro.com/products/Win32OpenSSL.html Install all packages in the order listed above Unpack and install the Net-SSLeay package cd Net-SSLeay-xxxx perl Makefile.PL (accept external tests and extra CPAN installs) nmake nmake install (Note that 'nmake test' does not seem to work with CamelPack 5.8.7) 5. Windows Server 2003 ActivePerl 5.8.8.820 VC++ 6.0 Microsoft Platform SDK SVR2003R2 OpenSSL 0.9.8e source openssl-0.9.8e.tar.gz + tls extensions patch from Radiator/goodies/openssl-0.9.8e-session-ticket-osc.patch Dynamic linking to SSL DLLs Install all packages in the order listed above Unpack, patch and and build OpenSSL, patch with cd openssl-0.9.8e+extensions patch -p1 < Radiator/goodies/openssl-0.9.8e-session-ticket-osc.patch perl Configure VC-WIN32 --prefix=c:/OpenSSL enable-tlsext ms\do_ms nmake -f ms\ntdll.mak nmake -f ms\ntdll.mak install (if you have trouble getting to this stage, consult INSTALL.W32) copy c:\OpenSSL\bin\*.dll c:\windows\system32 Unpack and install the Net-SSLeay package cd Net-SSLeay-xxxx perl Makefile.PL nmake copy c:\OpenSSL\bin\*.dll blib\arch\auto\Net\SSLeay\ nmake test nmake install 6. Windows Server 2003 ActivePerl 5.10.1 Microsoft Platform SDK 2003 SP1 OpenSSL 0.9.8i source including TLS extensions Dynamic linking to SSL DLLs Build OpenSSL S: cd \openssl-0.9.8i+extensions nmake -f ms\ntdll.mak clean perl Configure VC-WIN64A --prefix=c:/OpenSSL enable-tlsext ms\do_win64a nmake -f ms\ntdll.mak cd out32dll ..\ms\test nmake -f ms\ntdll.mak install Now build Net-SSLeay nmake clean R: cd \net-ssleay\trunk perl Makefile.PL nmake copy c:\OpenSSL\bin\*.dll blib\arch\auto\Net\SSLeay nmake test nmake install 7. Windows XP Professional SP3 ActivePerl 5.16.1 OpenSSL 1.0.1j binary from http://slproweb.com/download/Win32OpenSSL-1_0_1j.exe Visual C++ 2008 Redistributables from http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF Microsoft Visual Studio 2010 Express with Visual Studio Command Prompt shell: R: cd \net-ssleay\trunk perl Makefile.PL nmake nmake test (some warnings will be reported) 8. Windows XP Professional SP3 on VMWare ActivePerl 5.16.1 OpenSSL 1.0.1 source code Microsoft Visual Studio 2010 Express with Visual Studio Command Prompt shell: Build OpenSSL S: cd \openssl-1.0.1e perl Configure VC-WIN32 no-asm --prefix=c:/OpenSSL ms\do_ms nmake -f ms\ntdll.mak nmake -f ms\ntdll.mak install Now build Net-SSLeay R: cd \net-ssleay\trunk nmake clean perl Makefile.PL nmake nmake test (some warnings will be reported) Net-SSLeay-1.92/SSLeay.xs0000644000175000001440000057535014167101614013567 0ustar csnusers/* SSLeay.xs - Perl module for using Eric Young's implementation of SSL * * Copyright (c) 1996-2003 Sampo Kellomäki * Copyright (c) 2005-2010 Florian Ragwitz * Copyright (c) 2005-2018 Mike McCauley * Copyright (c) 2018- Chris Novakovic * Copyright (c) 2018- Tuure Vartiainen * Copyright (c) 2018- Heikki Vatiainen * * All rights reserved. * * Change data removed. See Changes * * This module is released under the terms of the Artistic License 2.0. For * details, see the LICENSE file. */ /* #### * #### PLEASE READ THE FOLLOWING RULES BEFORE YOU START EDITING THIS FILE! #### * #### * * Function naming conventions: * * 1/ never change the already existing function names (all calling convention) in a way * that may cause backward incompatibility (e.g. add ALIAS with old name if necessary) * * 2/ it is recommended to keep the original openssl function names for functions that are: * * 1:1 wrappers to the original openssl functions * see for example: X509_get_issuer_name(cert) >> Net::SSLeay::X509_get_issuer_name($cert) * * nearly 1:1 wrappers implementing only necessary "glue" e.g. buffer handling * see for example: RAND_seed(buf,len) >> Net::SSLeay::RAND_seed($buf) * * 3/ OpenSSL functions starting with "SSL_" are added into SSLeay.xs with "SLL_" prefix * (e.g. SSL_CTX_new) but keep in mind that they will be available in Net::SSLeay without * "SSL_" prefix (e.g. Net::SSLeay::CTX_new) - keep this for all new functions * * 4/ The names of functions which do not fit rule 2/ (which means they implement some non * trivial code around original openssl function or do more complex tasks) should be * prefixed with "P_" - see for example: P_ASN1_TIME_set_isotime * * 5/ Exceptions from rules above: * functions that are part or wider set of already existing function not following this rule * for example: there already exists: PEM_get_string_X509_CRL + PEM_get_string_X509_REQ and you want * to add PEM_get_string_SOMETHING - then no need to follow 3/ (do not prefix with "P_") * * Support for different Perl versions, libssl implementations, platforms, and compilers: * * 1/ Net-SSLeay has a version support policy for Perl and OpenSSL/LibreSSL (described in the * "Prerequisites" section in the README file). The test suite must pass when run on any * of those version combinations. * * 2/ Fix all compiler warnings - we expect 100% clean build * * 3/ If you add a function which is available since certain openssl version * use proper #ifdefs to assure that SSLeay.xs will compile also with older versions * which are missing this function * * 4/ Even warnings arising from different use of "const" in different openssl versions * needs to be hanled with #ifdefs - see for example: X509_NAME_add_entry_by_txt * * 5/ avoid using global C variables (it is very likely to break thread-safetyness) * use rather global MY_CXT structure * * 6/ avoid using any UNIX/POSIX specific functions, keep in mind that SSLeay.xs must * compile also on non-UNIX platforms like MS Windows and others * * 7/ avoid using c++ comments "//" (or other c++ features accepted by some c compiler) * even if your compiler can handle them without warnings * * Passing test suite: * * 1/ any changes to SSLeay.xs must not introduce a failure of existing test suite * * 2/ it is strongly recommended to create test(s) for newly added function(s), especially * when the new function is not only a 1:1 wrapper but contains a complex code * * 3/ it is mandatory to add a documentation for all newly added functions into SSLeay.pod * otherwise t/local/02_pod_coverage.t fail (and you will be asked to add some doc into * your patch) * * Preferred code layout: * * 1/ for simple 1:1 XS wrappers use: * * a/ functions with short "signature" (short list of args): * * long * SSL_set_tmp_dh(SSL *ssl,DH *dh) * * b/ functions with long "signature" (long list of args): * simply when approach a/ does not fit to 120 columns * * void * SSL_any_functions(library_flag,function_name,reason,file_name,line) * int library_flag * int function_name * int reason * char *file_name * int line * * 2/ for XS functions with full implementation use identation like this: * * int * RAND_bytes(buf, num) * SV *buf * int num * PREINIT: * int rc; * unsigned char *random; * CODE: * / * some code here * / * RETVAL = rc; * OUTPUT: * RETVAL * * * Runtime debugging: * * with TRACE(level,fmt,...) you can output debug messages. * it behaves the same as * warn sprintf($msg,...) if $Net::SSLeay::trace>=$level * would do in Perl (e.g. it is using also the $Net::SSLeay::trace variable) * * * THE LAST RULE: * * The fact that some parts of SSLeay.xs do not follow the rules above is not * a reason why any new code can also break these rules in the same way * */ /* Prevent warnings about strncpy from Windows compilers */ #define _CRT_SECURE_NO_DEPRECATE #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #define NEED_newRV_noinc #define NEED_sv_2pv_flags #define NEED_my_snprintf #include "ppport.h" #ifdef __cplusplus } #endif /* OpenSSL-0.9.3a has some strange warning about this in * openssl/des.h */ #undef _ /* Sigh: openssl 1.0 has typedef void *BLOCK; which conflicts with perls typedef struct block BLOCK; */ #define BLOCK OPENSSL_BLOCK #include #include #include #include #include #include #ifndef OPENSSL_NO_COMP #include /* openssl-0.9.6a forgets to include this */ #endif #ifndef OPENSSL_NO_MD2 #include #endif #ifndef OPENSSL_NO_MD4 #include #endif #ifndef OPENSSL_NO_MD5 #include /* openssl-SNAP-20020227 does not automatically include this */ #endif #if OPENSSL_VERSION_NUMBER >= 0x00905000L #include #endif #include #include #if OPENSSL_VERSION_NUMBER >= 0x0090700fL /* requires 0.9.7+ */ #ifndef OPENSSL_NO_ENGINE #include #endif #endif #ifdef OPENSSL_FIPS #include #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #endif #undef BLOCK /* Beginning with OpenSSL 3.0.0-alpha17, SSL_CTX_get_options() and * related functions return uint64_t instead of long. For this reason * constant() in constant.c and Net::SSLeay must also be able to * return 64bit constants. However, this creates a problem with Perls * that have only 32 bit integers. The define below helps with * handling this API change. */ #if (OPENSSL_VERSION_NUMBER < 0x30000000L) || defined(NET_SSLEAY_32BIT_INT_PERL) #define NET_SSLEAY_32BIT_CONSTANTS #endif /* Debugging output - to enable use: * * perl Makefile.PL DEFINE=-DSHOW_XS_DEBUG * make * */ #ifdef SHOW_XS_DEBUG #define PR1(s) fprintf(stderr,s); #define PR2(s,t) fprintf(stderr,s,t); #define PR3(s,t,u) fprintf(stderr,s,t,u); #define PR4(s,t,u,v) fprintf(stderr,s,t,u,v); #else #define PR1(s) #define PR2(s,t) #define PR3(s,t,u) #define PR4(s,t,u,v) #endif static void TRACE(int level,char *msg,...) { va_list args; SV *trace = get_sv("Net::SSLeay::trace",0); if (trace && SvIOK(trace) && SvIV(trace)>=level) { char buf[4096]; va_start(args,msg); vsnprintf(buf,4095,msg,args); warn("%s",buf); va_end(args); } } #include "constants.c" /* ============= thread-safety related stuff ============== */ #define MY_CXT_KEY "Net::SSLeay::_guts" XS_VERSION typedef struct { HV* global_cb_data; UV tid; } my_cxt_t; START_MY_CXT #ifdef USE_ITHREADS static perl_mutex LIB_init_mutex; #if OPENSSL_VERSION_NUMBER < 0x10100000L static perl_mutex *GLOBAL_openssl_mutex = NULL; #endif #endif static int LIB_initialized; UV get_my_thread_id(void) /* returns threads->tid() value */ { dSP; UV tid = 0; #ifdef USE_ITHREADS int count = 0; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv("threads", 0))); PUTBACK; count = call_method("tid", G_SCALAR|G_EVAL); SPAGAIN; /* Caution: recent perls do not appear support threads->tid() */ if (SvTRUE(ERRSV) || count != 1) { /* if compatible threads not loaded or an error occurs return 0 */ tid = 0; } else tid = (UV)POPi; PUTBACK; FREETMPS; LEAVE; #endif return tid; } /* IMPORTANT NOTE: * openssl locking was implemented according to http://www.openssl.org/docs/crypto/threads.html * we implement both static and dynamic locking as described on URL above * locking is supported when OPENSSL_THREADS macro is defined which means openssl-0.9.7 or newer * we intentionally do not implement cleanup of openssl's threading as it causes troubles * with apache-mpm-worker+mod_perl+mod_ssl+net-ssleay */ #if defined(USE_ITHREADS) && defined(OPENSSL_THREADS) #if OPENSSL_VERSION_NUMBER < 0x10100000L static void openssl_locking_function(int mode, int type, const char *file, int line) { PR3("openssl_locking_function %d %d\n", mode, type); if (!GLOBAL_openssl_mutex) return; if (mode & CRYPTO_LOCK) MUTEX_LOCK(&GLOBAL_openssl_mutex[type]); else MUTEX_UNLOCK(&GLOBAL_openssl_mutex[type]); } #if OPENSSL_VERSION_NUMBER < 0x10000000L static unsigned long openssl_threadid_func(void) { dMY_CXT; return (unsigned long)(MY_CXT.tid); } #else void openssl_threadid_func(CRYPTO_THREADID *id) { dMY_CXT; CRYPTO_THREADID_set_numeric(id, (unsigned long)(MY_CXT.tid)); } #endif struct CRYPTO_dynlock_value { perl_mutex mutex; }; struct CRYPTO_dynlock_value * openssl_dynlocking_create_function (const char *file, int line) { struct CRYPTO_dynlock_value *retval; New(0, retval, 1, struct CRYPTO_dynlock_value); if (!retval) return NULL; MUTEX_INIT(&retval->mutex); return retval; } void openssl_dynlocking_lock_function (int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) { if (!l) return; if (mode & CRYPTO_LOCK) MUTEX_LOCK(&l->mutex); else MUTEX_UNLOCK(&l->mutex); } void openssl_dynlocking_destroy_function (struct CRYPTO_dynlock_value *l, const char *file, int line) { if (!l) return; MUTEX_DESTROY(&l->mutex); Safefree(l); } #endif void openssl_threads_init(void) { int i; PR1("STARTED: openssl_threads_init\n"); #if OPENSSL_VERSION_NUMBER < 0x10100000L /* initialize static locking */ if ( !CRYPTO_get_locking_callback() ) { #if OPENSSL_VERSION_NUMBER < 0x10000000L if ( !CRYPTO_get_id_callback() ) { #else if ( !CRYPTO_THREADID_get_callback() ) { #endif PR2("openssl_threads_init static locking %d\n", CRYPTO_num_locks()); New(0, GLOBAL_openssl_mutex, CRYPTO_num_locks(), perl_mutex); if (!GLOBAL_openssl_mutex) return; for (i=0; i= 0x1000000fL static void handler_list_md_fn(const EVP_MD *m, const char *from, const char *to, void *arg) { /* taken from apps/dgst.c */ const char *mname; if (!m) return; /* Skip aliases */ mname = OBJ_nid2ln(EVP_MD_type(m)); if (strcmp(from, mname)) return; /* Skip shortnames */ #if OPENSSL_VERSION_NUMBER < 0x10100000L if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) return; /* Skip clones */ #endif if (strchr(mname, ' ')) mname= EVP_MD_name(m); av_push(arg, newSVpv(mname,0)); } #endif /* ============= callbacks - basic info ============= * * PLEASE READ THIS BEFORE YOU ADD ANY NEW CALLBACK!! * * There are basically 2 types of callbacks used in SSLeay: * * 1/ "one-time" callbacks - these are created+used+destroyed within one perl function implemented in XS. * These callbacks use a special C structure simple_cb_data_t to pass necessary data. * There are 2 related helper functions: simple_cb_data_new() + simple_cb_data_free() * For example see implementation of these functions: * - RSA_generate_key * - PEM_read_bio_PrivateKey * * 2/ "advanced" callbacks - these are setup/destroyed by one function but used by another function. These * callbacks use global hash MY_CXT.global_cb_data to store perl functions + data to be uset at callback time. * There are 2 related helper functions: cb_data_advanced_put() + cb_data_advanced_get() for manipulating * global hash MY_CXT.global_cb_data which work like this: * cb_data_advanced_put(, "data_name", dataSV) * >>> * global_cb_data->{"ptr_"}->{"data_name"} = dataSV) * or * data = cb_data_advanced_get(, "data_name") * >>> * my $data = global_cb_data->{"ptr_"}->{"data_name"} * For example see implementation of these functions: * - SSL_CTX_set_verify * - SSL_set_verify * - SSL_CTX_set_cert_verify_callback * - SSL_CTX_set_default_passwd_cb * - SSL_CTX_set_default_passwd_cb_userdata * - SSL_set_session_secret_cb * * If you want to add a new callback: * - you very likely need a new function "your_callback_name_invoke()" * - decide whether your case fits case 1/ or 2/ (and implement likewise existing functions) * - try to avoid adding a new style of callback implementation (or ask Net::SSLeay maintainers before) * */ /* ============= callback stuff - generic functions============== */ struct _ssleay_cb_t { SV* func; SV* data; }; typedef struct _ssleay_cb_t simple_cb_data_t; simple_cb_data_t* simple_cb_data_new(SV* func, SV* data) { simple_cb_data_t* cb; New(0, cb, 1, simple_cb_data_t); if (cb) { SvREFCNT_inc(func); SvREFCNT_inc(data); cb->func = func; cb->data = (data == &PL_sv_undef) ? NULL : data; } return cb; } void simple_cb_data_free(simple_cb_data_t* cb) { if (cb) { if (cb->func) { SvREFCNT_dec(cb->func); cb->func = NULL; } if (cb->data) { SvREFCNT_dec(cb->data); cb->data = NULL; } } Safefree(cb); } int cb_data_advanced_put(const void *ptr, const char* data_name, SV* data) { HV * L2HV; SV ** svtmp; int len; char key_name[500]; dMY_CXT; len = my_snprintf(key_name, sizeof(key_name), "ptr_%p", ptr); if (len == sizeof(key_name)) return 0; /* error - key_name too short*/ /* get or create level-2 hash */ svtmp = hv_fetch(MY_CXT.global_cb_data, key_name, strlen(key_name), 0); if (svtmp == NULL) { L2HV = newHV(); hv_store(MY_CXT.global_cb_data, key_name, strlen(key_name), newRV_noinc((SV*)L2HV), 0); } else { if (!SvOK(*svtmp) || !SvROK(*svtmp)) return 0; #if defined(MUTABLE_PTR) L2HV = (HV*)MUTABLE_PTR(SvRV(*svtmp)); #else L2HV = (HV*)(SvRV(*svtmp)); #endif } /* first delete already stored value */ hv_delete(L2HV, data_name, strlen(data_name), G_DISCARD); if (data!=NULL) { if (SvOK(data)) hv_store(L2HV, data_name, strlen(data_name), data, 0); else /* we're not storing data so discard it */ SvREFCNT_dec(data); } return 1; } SV* cb_data_advanced_get(const void *ptr, const char* data_name) { HV * L2HV; SV ** svtmp; int len; char key_name[500]; dMY_CXT; len = my_snprintf(key_name, sizeof(key_name), "ptr_%p", ptr); if (len == sizeof(key_name)) return &PL_sv_undef; /* return undef on error - key_name too short*/ /* get level-2 hash */ svtmp = hv_fetch(MY_CXT.global_cb_data, key_name, strlen(key_name), 0); if (svtmp == NULL) return &PL_sv_undef; if (!SvOK(*svtmp)) return &PL_sv_undef; if (!SvROK(*svtmp)) return &PL_sv_undef; #if defined(MUTABLE_PTR) L2HV = (HV*)MUTABLE_PTR(SvRV(*svtmp)); #else L2HV = (HV*)(SvRV(*svtmp)); #endif /* get stored data */ svtmp = hv_fetch(L2HV, data_name, strlen(data_name), 0); if (svtmp == NULL) return &PL_sv_undef; if (!SvOK(*svtmp)) return &PL_sv_undef; return *svtmp; } int cb_data_advanced_drop(const void *ptr) { int len; char key_name[500]; dMY_CXT; len = my_snprintf(key_name, sizeof(key_name), "ptr_%p", ptr); if (len == sizeof(key_name)) return 0; /* error - key_name too short*/ hv_delete(MY_CXT.global_cb_data, key_name, strlen(key_name), G_DISCARD); return 1; } /* ============= callback stuff - invoke functions ============== */ static int ssleay_verify_callback_invoke (int ok, X509_STORE_CTX* x509_store) { dSP; SSL* ssl; int count = -1, res; SV *cb_func; PR1("STARTED: ssleay_verify_callback_invoke\n"); ssl = X509_STORE_CTX_get_ex_data(x509_store, SSL_get_ex_data_X509_STORE_CTX_idx()); cb_func = cb_data_advanced_get(ssl, "ssleay_verify_callback!!func"); if (!SvOK(cb_func)) { SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl); cb_func = cb_data_advanced_get(ssl_ctx, "ssleay_verify_callback!!func"); } if (!SvOK(cb_func)) croak("Net::SSLeay: verify_callback called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PR2("verify callback glue ok=%d\n", ok); PUSHMARK(sp); EXTEND( sp, 2 ); PUSHs( sv_2mortal(newSViv(ok)) ); PUSHs( sv_2mortal(newSViv(PTR2IV(x509_store))) ); PUTBACK; PR1("About to call verify callback.\n"); count = call_sv(cb_func, G_SCALAR); PR1("Returned from verify callback.\n"); SPAGAIN; if (count != 1) croak ( "Net::SSLeay: verify_callback perl function did not return a scalar.\n"); res = POPi; PUTBACK; FREETMPS; LEAVE; return res; } static int ssleay_ctx_passwd_cb_invoke(char *buf, int size, int rwflag, void *userdata) { dSP; int count = -1; char *res; SV *cb_func, *cb_data; PR1("STARTED: ssleay_ctx_passwd_cb_invoke\n"); cb_func = cb_data_advanced_get(userdata, "ssleay_ctx_passwd_cb!!func"); cb_data = cb_data_advanced_get(userdata, "ssleay_ctx_passwd_cb!!data"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ctx_passwd_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(rwflag))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv( cb_func, G_SCALAR ); SPAGAIN; if (count != 1) croak("Net::SSLeay: ssleay_ctx_passwd_cb_invoke perl function did not return a scalar.\n"); res = POPp; if (res == NULL) { *buf = '\0'; } else { strncpy(buf, res, size); buf[size - 1] = '\0'; } PUTBACK; FREETMPS; LEAVE; return strlen(buf); } #if OPENSSL_VERSION_NUMBER >= 0x1010006fL /* In OpenSSL 1.1.0 but actually called for $ssl from 1.1.0f */ #ifndef LIBRESSL_VERSION_NUMBER #ifndef OPENSSL_IS_BORINGSSL static int ssleay_ssl_passwd_cb_invoke(char *buf, int size, int rwflag, void *userdata) { dSP; int count = -1; char *res; SV *cb_func, *cb_data; PR1("STARTED: ssleay_ssl_passwd_cb_invoke\n"); cb_func = cb_data_advanced_get(userdata, "ssleay_ssl_passwd_cb!!func"); cb_data = cb_data_advanced_get(userdata, "ssleay_ssl_passwd_cb!!data"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ssl_passwd_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(rwflag))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv( cb_func, G_SCALAR ); SPAGAIN; if (count != 1) croak("Net::SSLeay: ssleay_ssl_passwd_cb_invoke perl function did not return a scalar.\n"); res = POPp; if (res == NULL) { *buf = '\0'; } else { strncpy(buf, res, size); buf[size - 1] = '\0'; } PUTBACK; FREETMPS; LEAVE; return strlen(buf); } #endif /* !BoringSSL */ #endif /* !LibreSSL */ #endif /* >= 1.1.0f */ int ssleay_ctx_cert_verify_cb_invoke(X509_STORE_CTX* x509_store_ctx, void* data) { dSP; int count = -1; int res; SV * cb_func, *cb_data; void *ptr; SSL *ssl; PR1("STARTED: ssleay_ctx_cert_verify_cb_invoke\n"); #if OPENSSL_VERSION_NUMBER < 0x0090700fL ssl = X509_STORE_CTX_get_ex_data(x509_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ptr = (void*) SSL_get_SSL_CTX(ssl); #else ssl = NULL; ptr = (void*) data; #endif cb_func = cb_data_advanced_get(ptr, "ssleay_ctx_cert_verify_cb!!func"); cb_data = cb_data_advanced_get(ptr, "ssleay_ctx_cert_verify_cb!!data"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ctx_cert_verify_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(x509_store_ctx)))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv(cb_func, G_SCALAR); SPAGAIN; if (count != 1) croak("Net::SSLeay: ssleay_ctx_cert_verify_cb_invoke perl function did not return a scalar.\n"); res = POPi; PUTBACK; FREETMPS; LEAVE; return res; } #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) int tlsext_servername_callback_invoke(SSL *ssl, int *ad, void *arg) { dSP; int count = -1; int res; SV * cb_func, *cb_data; PR1("STARTED: tlsext_servername_callback_invoke\n"); cb_func = cb_data_advanced_get(arg, "tlsext_servername_callback!!func"); cb_data = cb_data_advanced_get(arg, "tlsext_servername_callback!!data"); if(!SvOK(cb_func)) croak ("Net::SSLeay: tlsext_servername_callback_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv(cb_func, G_SCALAR); SPAGAIN; if (count != 1) croak("Net::SSLeay: tlsext_servername_callback_invoke perl function did not return a scalar.\n"); res = POPi; PUTBACK; FREETMPS; LEAVE; return res; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_TLSEXT) int tlsext_status_cb_invoke(SSL *ssl, void *arg) { dSP; SV *cb_func, *cb_data; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); int len,res,nres = -1; const unsigned char *p = NULL; OCSP_RESPONSE *ocsp_response = NULL; cb_func = cb_data_advanced_get(ctx, "tlsext_status_cb!!func"); cb_data = cb_data_advanced_get(ctx, "tlsext_status_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: tlsext_status_cb_invoke called, but not set to point to any perl function.\n"); len = SSL_get_tlsext_status_ocsp_resp(ssl, &p); if (p) ocsp_response = d2i_OCSP_RESPONSE(NULL, &p, len); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); PUSHs( sv_2mortal(newSViv(PTR2IV(ocsp_response))) ); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; nres = call_sv(cb_func, G_SCALAR); if (ocsp_response) OCSP_RESPONSE_free(ocsp_response); SPAGAIN; if (nres != 1) croak("Net::SSLeay: tlsext_status_cb_invoke perl function did not return a scalar.\n"); res = POPi; PUTBACK; FREETMPS; LEAVE; return res; } int session_ticket_ext_cb_invoke(SSL *ssl, const unsigned char *data, int len, void *arg) { dSP; SV *cb_func, *cb_data; int res,nres = -1; cb_func = cb_data_advanced_get(arg, "session_ticket_ext_cb!!func"); cb_data = cb_data_advanced_get(arg, "session_ticket_ext_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: session_ticket_ext_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVpvn((const char *)data, len))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; nres = call_sv(cb_func, G_SCALAR); SPAGAIN; if (nres != 1) croak("Net::SSLeay: session_ticket_ext_cb_invoke perl function did not return a scalar.\n"); res = POPi; PUTBACK; FREETMPS; LEAVE; return res; } #endif #if defined(SSL_F_SSL_SET_HELLO_EXTENSION) || defined(SSL_F_SSL_SET_SESSION_TICKET_EXT) int ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, const SSL_CIPHER **cipher, void *arg) { dSP; int count = -1, res, i; AV *ciphers = newAV(); SV *pref_cipher = sv_newmortal(); SV * cb_func, *cb_data; SV * secretsv; PR1("STARTED: ssleay_session_secret_cb_invoke\n"); cb_func = cb_data_advanced_get(arg, "ssleay_session_secret_cb!!func"); cb_data = cb_data_advanced_get(arg, "ssleay_session_secret_cb!!data"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ctx_passwd_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); secretsv = sv_2mortal( newSVpv(secret, *secret_len)); XPUSHs(secretsv); for (i=0; i= 0x10100000L { /* Use any new master secret set by the callback function in secret */ STRLEN newsecretlen; char* newsecretdata = SvPV(secretsv, newsecretlen); memcpy(secret, newsecretdata, newsecretlen); } #endif } PUTBACK; FREETMPS; LEAVE; return res; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_PSK) #define NET_SSLEAY_CAN_PSK_CLIENT_CALLBACK unsigned int ssleay_set_psk_client_callback_invoke(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) { dSP; int count = -1; char *identity_val, *psk_val; unsigned int psk_len = 0; BIGNUM *psk_bn = NULL; SV * cb_func; SV * hintsv; /* this n_a is required for building with old perls: */ STRLEN n_a; PR1("STARTED: ssleay_set_psk_client_callback_invoke\n"); cb_func = cb_data_advanced_get(ssl, "ssleay_set_psk_client_callback!!func"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_set_psk_client_callback_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); if (hint != NULL) { hintsv = sv_2mortal( newSVpv(hint, strlen(hint))); XPUSHs(hintsv); } PUTBACK; count = call_sv( cb_func, G_ARRAY ); SPAGAIN; if (count != 2) croak ("Net::SSLeay: ssleay_set_psk_client_callback_invoke perl function did not return 2 values.\n"); psk_val = POPpx; identity_val = POPpx; my_snprintf(identity, max_identity_len, "%s", identity_val); if (BN_hex2bn(&psk_bn, psk_val) > 0) { if (BN_num_bytes(psk_bn) <= max_psk_len) { psk_len = BN_bn2bin(psk_bn, psk); } BN_free(psk_bn); } PUTBACK; FREETMPS; LEAVE; return psk_len; } unsigned int ssleay_ctx_set_psk_client_callback_invoke(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) { dSP; SSL_CTX *ctx; int count = -1; char *identity_val, *psk_val; unsigned int psk_len = 0; BIGNUM *psk_bn = NULL; SV * cb_func; SV * hintsv; /* this n_a is required for building with old perls: */ STRLEN n_a; ctx = SSL_get_SSL_CTX(ssl); PR1("STARTED: ssleay_ctx_set_psk_client_callback_invoke\n"); cb_func = cb_data_advanced_get(ctx, "ssleay_ctx_set_psk_client_callback!!func"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ctx_set_psk_client_callback_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); if (hint != NULL) { hintsv = sv_2mortal( newSVpv(hint, strlen(hint))); XPUSHs(hintsv); } PUTBACK; count = call_sv( cb_func, G_ARRAY ); SPAGAIN; if (count != 2) croak ("Net::SSLeay: ssleay_ctx_set_psk_client_callback_invoke perl function did not return 2 values.\n"); psk_val = POPpx; identity_val = POPpx; my_snprintf(identity, max_identity_len, "%s", identity_val); if (BN_hex2bn(&psk_bn, psk_val) > 0) { if (BN_num_bytes(psk_bn) <= max_psk_len) { psk_len = BN_bn2bin(psk_bn, psk); } BN_free(psk_bn); } PUTBACK; FREETMPS; LEAVE; return psk_len; } #endif #if (OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG)) || (OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT)) int next_proto_helper_AV2protodata(AV * list, unsigned char *out) { int i, last_index, ptr = 0; last_index = av_len(list); if (last_index<0) return 0; for(i=0; i<=last_index; i++) { char *p = SvPV_nolen(*av_fetch(list, i, 0)); size_t len = strlen(p); if (len>255) return 0; if (out) { /* if out == NULL we only calculate the length of output */ out[ptr] = (unsigned char)len; strncpy((char*)out+ptr+1, p, len); } ptr += strlen(p) + 1; } return ptr; } int next_proto_helper_protodata2AV(AV * list, const unsigned char *in, unsigned int inlen) { unsigned int i = 0; unsigned char il; if (!list || inlen<2) return 0; while (i inlen) return 0; av_push(list, newSVpv((const char*)in+i, il)); i += il; } return 1; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) && !defined(LIBRESSL_VERSION_NUMBER) int next_proto_select_cb_invoke(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { SV *cb_func, *cb_data; unsigned char *next_proto_data; size_t next_proto_len; int next_proto_status; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); /* this n_a is required for building with old perls: */ STRLEN n_a; PR1("STARTED: next_proto_select_cb_invoke\n"); cb_func = cb_data_advanced_get(ctx, "next_proto_select_cb!!func"); cb_data = cb_data_advanced_get(ctx, "next_proto_select_cb!!data"); /* clear last_status value = store undef */ cb_data_advanced_put(ssl, "next_proto_select_cb!!last_status", NULL); cb_data_advanced_put(ssl, "next_proto_select_cb!!last_negotiated", NULL); if (SvROK(cb_func) && (SvTYPE(SvRV(cb_func)) == SVt_PVCV)) { int count = -1; AV *list = newAV(); SV *tmpsv; dSP; if (!next_proto_helper_protodata2AV(list, in, inlen)) return SSL_TLSEXT_ERR_ALERT_FATAL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newRV_inc((SV*)list))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv( cb_func, G_ARRAY ); SPAGAIN; if (count != 2) croak ("Net::SSLeay: next_proto_select_cb_invoke perl function did not return 2 values.\n"); next_proto_data = (unsigned char*)POPpx; next_proto_status = POPi; next_proto_len = strlen((const char*)next_proto_data); if (next_proto_len<=255) { /* store last_status + last_negotiated into global hash */ cb_data_advanced_put(ssl, "next_proto_select_cb!!last_status", newSViv(next_proto_status)); tmpsv = newSVpv((const char*)next_proto_data, next_proto_len); cb_data_advanced_put(ssl, "next_proto_select_cb!!last_negotiated", tmpsv); *out = (unsigned char *)SvPVX(tmpsv); *outlen = next_proto_len; } PUTBACK; FREETMPS; LEAVE; return next_proto_len>255 ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_OK; } else if (SvROK(cb_data) && (SvTYPE(SvRV(cb_data)) == SVt_PVAV)) { next_proto_len = next_proto_helper_AV2protodata((AV*)SvRV(cb_data), NULL); Newx(next_proto_data, next_proto_len, unsigned char); if (!next_proto_data) return SSL_TLSEXT_ERR_ALERT_FATAL; next_proto_len = next_proto_helper_AV2protodata((AV*)SvRV(cb_data), next_proto_data); next_proto_status = SSL_select_next_proto(out, outlen, in, inlen, next_proto_data, next_proto_len); Safefree(next_proto_data); if (next_proto_status != OPENSSL_NPN_NEGOTIATED) { *outlen = *in; *out = (unsigned char *)in+1; } /* store last_status + last_negotiated into global hash */ cb_data_advanced_put(ssl, "next_proto_select_cb!!last_status", newSViv(next_proto_status)); cb_data_advanced_put(ssl, "next_proto_select_cb!!last_negotiated", newSVpv((const char*)*out, *outlen)); return SSL_TLSEXT_ERR_OK; } return SSL_TLSEXT_ERR_ALERT_FATAL; } int next_protos_advertised_cb_invoke(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg_unused) { SV *cb_func, *cb_data; unsigned char *protodata = NULL; unsigned short protodata_len = 0; SV *tmpsv; AV *tmpav; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); PR1("STARTED: next_protos_advertised_cb_invoke"); cb_func = cb_data_advanced_get(ctx, "next_protos_advertised_cb!!func"); cb_data = cb_data_advanced_get(ctx, "next_protos_advertised_cb!!data"); if (SvROK(cb_func) && (SvTYPE(SvRV(cb_func)) == SVt_PVCV)) { int count = -1; dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv( cb_func, G_SCALAR ); SPAGAIN; if (count != 1) croak ("Net::SSLeay: next_protos_advertised_cb_invoke perl function did not return scalar value.\n"); tmpsv = POPs; if (SvOK(tmpsv) && SvROK(tmpsv) && (SvTYPE(SvRV(tmpsv)) == SVt_PVAV)) { tmpav = (AV*)SvRV(tmpsv); protodata_len = next_proto_helper_AV2protodata(tmpav, NULL); Newx(protodata, protodata_len, unsigned char); if (protodata) next_proto_helper_AV2protodata(tmpav, protodata); } PUTBACK; FREETMPS; LEAVE; } else if (SvROK(cb_data) && (SvTYPE(SvRV(cb_data)) == SVt_PVAV)) { tmpav = (AV*)SvRV(cb_data); protodata_len = next_proto_helper_AV2protodata(tmpav, NULL); Newx(protodata, protodata_len, unsigned char); if (protodata) next_proto_helper_AV2protodata(tmpav, protodata); } if (protodata) { tmpsv = newSVpv((const char*)protodata, protodata_len); Safefree(protodata); cb_data_advanced_put(ssl, "next_protos_advertised_cb!!last_advertised", tmpsv); *out = (unsigned char *)SvPVX(tmpsv); *outlen = protodata_len; return SSL_TLSEXT_ERR_OK; } return SSL_TLSEXT_ERR_ALERT_FATAL; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) int alpn_select_cb_invoke(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { SV *cb_func, *cb_data; unsigned char *alpn_data; size_t alpn_len; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); PR1("STARTED: alpn_select_cb_invoke\n"); cb_func = cb_data_advanced_get(ctx, "alpn_select_cb!!func"); cb_data = cb_data_advanced_get(ctx, "alpn_select_cb!!data"); if (SvROK(cb_func) && (SvTYPE(SvRV(cb_func)) == SVt_PVCV)) { int count = -1; AV *list = newAV(); SV *tmpsv; SV *alpn_data_sv; dSP; if (!next_proto_helper_protodata2AV(list, in, inlen)) return SSL_TLSEXT_ERR_ALERT_FATAL; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newRV_inc((SV*)list))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; count = call_sv( cb_func, G_ARRAY ); SPAGAIN; if (count != 1) croak ("Net::SSLeay: alpn_select_cb perl function did not return exactly 1 value.\n"); alpn_data_sv = POPs; if (SvOK(alpn_data_sv)) { alpn_data = (unsigned char*)SvPV_nolen(alpn_data_sv); alpn_len = strlen((const char*)alpn_data); if (alpn_len <= 255) { tmpsv = newSVpv((const char*)alpn_data, alpn_len); *out = (unsigned char *)SvPVX(tmpsv); *outlen = alpn_len; } } else { alpn_data = NULL; alpn_len = 0; } PUTBACK; FREETMPS; LEAVE; if (alpn_len>255) return SSL_TLSEXT_ERR_ALERT_FATAL; return alpn_data ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; } else if (SvROK(cb_data) && (SvTYPE(SvRV(cb_data)) == SVt_PVAV)) { int status; alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(cb_data), NULL); Newx(alpn_data, alpn_len, unsigned char); if (!alpn_data) return SSL_TLSEXT_ERR_ALERT_FATAL; alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(cb_data), alpn_data); /* This is the same function that is used for NPN. */ status = SSL_select_next_proto((unsigned char **)out, outlen, in, inlen, alpn_data, alpn_len); Safefree(alpn_data); if (status != OPENSSL_NPN_NEGOTIATED) { *outlen = *in; *out = in+1; } return status == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; } return SSL_TLSEXT_ERR_ALERT_FATAL; } #endif int pem_password_cb_invoke(char *buf, int bufsize, int rwflag, void *data) { dSP; char *str; int count = -1; size_t str_len = 0; simple_cb_data_t* cb = (simple_cb_data_t*)data; /* this n_a is required for building with old perls: */ STRLEN n_a; PR1("STARTED: pem_password_cb_invoke\n"); if (cb->func && SvOK(cb->func)) { ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal( newSViv(bufsize-1) )); XPUSHs(sv_2mortal( newSViv(rwflag) )); if (cb->data) XPUSHs( cb->data ); PUTBACK; count = call_sv( cb->func, G_SCALAR ); SPAGAIN; buf[0] = 0; /* start with an empty password */ if (count != 1) { croak("Net::SSLeay: pem_password_cb_invoke perl function did not return a scalar.\n"); } else { str = POPpx; str_len = strlen(str); if (str_len+1 < bufsize) { strcpy(buf, str); } else { str_len = 0; warn("Net::SSLeay: pem_password_cb_invoke password too long\n"); } } PUTBACK; FREETMPS; LEAVE; } return str_len; } void ssleay_RSA_generate_key_cb_invoke(int i, int n, void* data) { dSP; int count = -1; simple_cb_data_t* cb = (simple_cb_data_t*)data; /* PR1("STARTED: ssleay_RSA_generate_key_cb_invoke\n"); / * too noisy */ if (cb->func && SvOK(cb->func)) { ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal( newSViv(i) )); XPUSHs(sv_2mortal( newSViv(n) )); if (cb->data) XPUSHs( cb->data ); PUTBACK; count = call_sv( cb->func, G_VOID|G_DISCARD ); if (count != 0) croak ("Net::SSLeay: ssleay_RSA_generate_key_cb_invoke " "perl function did return something in void context.\n"); SPAGAIN; FREETMPS; LEAVE; } } void ssleay_info_cb_invoke(const SSL *ssl, int where, int ret) { dSP; SV *cb_func, *cb_data; cb_func = cb_data_advanced_get((void*)ssl, "ssleay_info_cb!!func"); cb_data = cb_data_advanced_get((void*)ssl, "ssleay_info_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: ssleay_info_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSViv(where)) ); XPUSHs(sv_2mortal(newSViv(ret)) ); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } void ssleay_ctx_info_cb_invoke(const SSL *ssl, int where, int ret) { dSP; SV *cb_func, *cb_data; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); cb_func = cb_data_advanced_get(ctx, "ssleay_ctx_info_cb!!func"); cb_data = cb_data_advanced_get(ctx, "ssleay_ctx_info_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: ssleay_ctx_info_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSViv(where)) ); XPUSHs(sv_2mortal(newSViv(ret)) ); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } void ssleay_msg_cb_invoke(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) { dSP; SV *cb_func, *cb_data; cb_func = cb_data_advanced_get(ssl, "ssleay_msg_cb!!func"); cb_data = cb_data_advanced_get(ssl, "ssleay_msg_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: ssleay_msg_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(write_p))); XPUSHs(sv_2mortal(newSViv(version))); XPUSHs(sv_2mortal(newSViv(content_type))); XPUSHs(sv_2mortal(newSVpv((const char*)buf, len))); XPUSHs(sv_2mortal(newSViv(len))); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } void ssleay_ctx_msg_cb_invoke(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) { dSP; SV *cb_func, *cb_data; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); cb_func = cb_data_advanced_get(ctx, "ssleay_ctx_msg_cb!!func"); cb_data = cb_data_advanced_get(ctx, "ssleay_ctx_msg_cb!!data"); if ( ! SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak ("Net::SSLeay: ssleay_ctx_msg_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(write_p))); XPUSHs(sv_2mortal(newSViv(version))); XPUSHs(sv_2mortal(newSViv(content_type))); XPUSHs(sv_2mortal(newSVpv((const char*)buf, len))); XPUSHs(sv_2mortal(newSViv(len))); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVsv(cb_data))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } /* * Support for tlsext_ticket_key_cb_invoke was already in 0.9.8 but it was * broken in various ways during the various 1.0.0* versions. * Better enable it only starting with 1.0.1. */ #if defined(SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB) && OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_TLSEXT) #define NET_SSLEAY_CAN_TICKET_KEY_CB int tlsext_ticket_key_cb_invoke( SSL *ssl, unsigned char *key_name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc ){ dSP; int count,usable_rv_count,hmac_key_len = 0; SV *cb_func, *cb_data; STRLEN svlen; unsigned char key[48]; /* key[0..15] aes, key[16..32] or key[16..48] hmac */ unsigned char name[16]; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); PR1("STARTED: tlsext_ticket_key_cb_invoke\n"); cb_func = cb_data_advanced_get(ctx, "tlsext_ticket_key_cb!!func"); cb_data = cb_data_advanced_get(ctx, "tlsext_ticket_key_cb!!data"); if (!SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV)) croak("callback must be a code reference"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVsv(cb_data))); if (!enc) { /* call as getkey(data,this_name) -> (key,current_name) */ XPUSHs(sv_2mortal(newSVpv((const char *)key_name,16))); } else { /* call as getkey(data) -> (key,current_name) */ } PUTBACK; count = call_sv( cb_func, G_ARRAY ); SPAGAIN; if (count>2) croak("too much return values - only (name,key) should be returned"); usable_rv_count = 0; if (count>0) { SV *sname = POPs; if (SvOK(sname)) { unsigned char *pname = (unsigned char *)SvPV(sname,svlen); if (svlen > 16) croak("name must be at at most 16 bytes, got %d",(int)svlen); if (svlen == 0) croak("name should not be empty"); OPENSSL_cleanse(name, 16); memcpy(name,pname,svlen); usable_rv_count++; } } if (count>1) { SV *skey = POPs; if (SvOK(skey)) { unsigned char *pkey = (unsigned char *)SvPV(skey,svlen); if (svlen != 32 && svlen != 48) croak("key must be 32 or 48 random bytes, got %d",(int)svlen); hmac_key_len = (int)svlen - 16; memcpy(key,pkey,(int)svlen); usable_rv_count++; } } PUTBACK; FREETMPS; LEAVE; if (!enc && usable_rv_count == 0) { TRACE(2,"no key returned for ticket"); return 0; } if (usable_rv_count != 2) croak("key functions needs to return (key,name)"); if (enc) { /* encrypt ticket information with given key */ RAND_bytes(iv, 16); EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key, iv); HMAC_Init_ex(hctx,key+16,hmac_key_len,EVP_sha256(),NULL); memcpy(key_name,name,16); return 1; } else { HMAC_Init_ex(hctx,key+16,hmac_key_len,EVP_sha256(),NULL); EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key, iv); if (memcmp(name,key_name,16) == 0) return 1; /* current key was used */ else return 2; /* different key was used, need to be renewed */ } } #endif int ssleay_ssl_ctx_sess_new_cb_invoke(struct ssl_st *ssl, SSL_SESSION *sess) { dSP; int count, remove; SSL_CTX *ctx; SV *cb_func; PR1("STARTED: ssleay_ssl_ctx_sess_new_cb_invoke\n"); ctx = SSL_get_SSL_CTX(ssl); cb_func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_sess_new_cb!!func"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ssl_ctx_sess_new_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSViv(PTR2IV(sess)))); PUTBACK; count = call_sv(cb_func, G_SCALAR); SPAGAIN; if (count != 1) croak("Net::SSLeay: ssleay_ssl_ctx_sess_new_cb_invoke perl function did not return a scalar\n"); remove = POPi; PUTBACK; FREETMPS; LEAVE; return remove; } void ssleay_ssl_ctx_sess_remove_cb_invoke(SSL_CTX *ctx, SSL_SESSION *sess) { dSP; SV *cb_func; PR1("STARTED: ssleay_ssl_ctx_sess_remove_cb_invoke\n"); cb_func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_sess_remove_cb!!func"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssleay_ssl_ctx_sess_remove_cb_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(PTR2IV(ctx)))); XPUSHs(sv_2mortal(newSViv(PTR2IV(sess)))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L int ossl_provider_do_all_cb_invoke(OSSL_PROVIDER *provider, void *cbdata) { dSP; int ret = 1; int count = -1; simple_cb_data_t *cb = cbdata; PR1("STARTED: ossl_provider_do_all_cb_invoke\n"); if (cb->func && SvOK(cb->func)) { ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(provider)))); if (cb->data) XPUSHs(cb->data); PUTBACK; count = call_sv(cb->func, G_SCALAR); SPAGAIN; if (count != 1) croak("Net::SSLeay: ossl_provider_do_all_cb_invoke perl function did not return a scalar\n"); ret = POPi; PUTBACK; FREETMPS; LEAVE; } return ret; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10101001 && !defined(LIBRESSL_VERSION_NUMBER) void ssl_ctx_keylog_cb_func_invoke(const SSL *ssl, const char *line) { dSP; SV *cb_func, *cb_data; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); PR1("STARTED: ssl_ctx_keylog_cb_func_invoke\n"); cb_func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_keylog_callback!!func"); if(!SvOK(cb_func)) croak ("Net::SSLeay: ssl_ctx_keylog_cb_func_invoke called, but not set to point to any perl function.\n"); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl)))); XPUSHs(sv_2mortal(newSVpv(line, 0))); PUTBACK; call_sv(cb_func, G_VOID); SPAGAIN; PUTBACK; FREETMPS; LEAVE; return; } #endif /* ============= end of callback stuff, begin helper functions ============== */ time_t ASN1_TIME_timet(ASN1_TIME *asn1t, time_t *gmtoff) { struct tm t; const char *p = (const char*) asn1t->data; size_t msec = 0, tz = 0, i, l; time_t result; int adj = 0; if (asn1t->type == V_ASN1_UTCTIME) { if (asn1t->length<12 || asn1t->length>17) return 0; if (asn1t->length>12) tz = 12; } else { if (asn1t->length<14) return 0; if (asn1t->length>14) { if (p[14] == '.') { msec = 14; for(i=msec+1;ilength && p[i]>='0' && p[i]<='9';i++) ; if (ilength) tz = i; } else { tz = 14; } } } l = msec ? msec : tz ? tz : asn1t->length; for(i=0;i'9') return 0; } /* extract data and time */ OPENSSL_cleanse(&t, sizeof(t)); if (asn1t->type == V_ASN1_UTCTIME) { /* YY - two digit year */ t.tm_year = (p[0]-'0')*10 + (p[1]-'0'); if (t.tm_year < 70) t.tm_year += 100; i=2; } else { /* YYYY */ t.tm_year = (p[0]-'0')*1000 + (p[1]-'0')*100 + (p[2]-'0')*10 + p[3]-'0'; t.tm_year -= 1900; i=4; } t.tm_mon = (p[i+0]-'0')*10 + (p[i+1]-'0') -1; /* MM, starts with 0 in tm */ t.tm_mday = (p[i+2]-'0')*10 + (p[i+3]-'0'); /* DD */ t.tm_hour = (p[i+4]-'0')*10 + (p[i+5]-'0'); /* hh */ t.tm_min = (p[i+6]-'0')*10 + (p[i+7]-'0'); /* mm */ t.tm_sec = (p[i+8]-'0')*10 + (p[i+9]-'0'); /* ss */ /* skip msec, because time_t does not support it */ if (tz) { /* TZ is 'Z' or [+-]DDDD and after TZ the string must stop*/ if (p[tz] == 'Z') { if (asn1t->length>tz+1 ) return 0; } else if (asn1t->lengthlength>tz+5 ) return 0; for(i=tz+1;i'9') return 0; } adj = ((p[tz+1]-'0')*10 + (p[tz+2]-'0'))*3600 + ((p[tz+3]-'0')*10 + (p[tz+4]-'0'))*60; if (p[tz]=='+') adj*= -1; /* +0500: subtract 5 hours to get UTC */ } } result = mktime(&t); if (result == -1) return 0; /* broken time */ result += adj; if (gmtoff && *gmtoff == -1) { *gmtoff = result - mktime(gmtime(&result)); result += *gmtoff; } else { result += result - mktime(gmtime(&result)); } return result; } X509 * find_issuer(X509 *cert,X509_STORE *store, STACK_OF(X509) *chain) { int i; X509 *issuer = NULL; /* search first in the chain */ if (chain) { for(i=0;i= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) unsigned long OpenSSL_version_num() const char * OpenSSL_version(t=OPENSSL_VERSION) int t #endif /* OpenSSL 1.1.0 */ #if (OPENSSL_VERSION_MAJOR >= 3) unsigned int OPENSSL_version_major() unsigned int OPENSSL_version_minor() unsigned int OPENSSL_version_patch() const char * OPENSSL_version_pre_release() const char * OPENSSL_version_build_metadata() const char * OPENSSL_info(int t) #endif #define REM1 "============= SSL CONTEXT functions ==============" SSL_CTX * SSL_CTX_new() CODE: RETVAL = SSL_CTX_new (SSLv23_method()); OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER < 0x10100000L #ifndef OPENSSL_NO_SSL2 SSL_CTX * SSL_CTX_v2_new() CODE: RETVAL = SSL_CTX_new (SSLv2_method()); OUTPUT: RETVAL #endif #endif #ifndef OPENSSL_NO_SSL3 SSL_CTX * SSL_CTX_v3_new() CODE: RETVAL = SSL_CTX_new (SSLv3_method()); OUTPUT: RETVAL #endif SSL_CTX * SSL_CTX_v23_new() CODE: RETVAL = SSL_CTX_new (SSLv23_method()); OUTPUT: RETVAL SSL_CTX * SSL_CTX_tlsv1_new() CODE: RETVAL = SSL_CTX_new (TLSv1_method()); OUTPUT: RETVAL #ifdef SSL_TXT_TLSV1_1 SSL_CTX * SSL_CTX_tlsv1_1_new() CODE: RETVAL = SSL_CTX_new (TLSv1_1_method()); OUTPUT: RETVAL #endif #ifdef SSL_TXT_TLSV1_2 SSL_CTX * SSL_CTX_tlsv1_2_new() CODE: RETVAL = SSL_CTX_new (TLSv1_2_method()); OUTPUT: RETVAL #endif SSL_CTX * SSL_CTX_new_with_method(meth) SSL_METHOD * meth CODE: RETVAL = SSL_CTX_new (meth); OUTPUT: RETVAL void SSL_CTX_free(ctx) SSL_CTX * ctx CODE: SSL_CTX_free(ctx); cb_data_advanced_drop(ctx); /* clean callback related data from global hash */ int SSL_CTX_add_session(ctx,ses) SSL_CTX * ctx SSL_SESSION * ses int SSL_CTX_remove_session(ctx,ses) SSL_CTX * ctx SSL_SESSION * ses void SSL_CTX_flush_sessions(ctx,tm) SSL_CTX * ctx long tm int SSL_CTX_set_default_verify_paths(ctx) SSL_CTX * ctx int SSL_CTX_load_verify_locations(ctx,CAfile,CApath) SSL_CTX * ctx char * CAfile char * CApath CODE: RETVAL = SSL_CTX_load_verify_locations (ctx, CAfile?(*CAfile?CAfile:NULL):NULL, CApath?(*CApath?CApath:NULL):NULL ); OUTPUT: RETVAL void SSL_CTX_set_verify(ctx,mode,callback=&PL_sv_undef) SSL_CTX * ctx int mode SV * callback CODE: /* Former versions of SSLeay checked if the callback was a true boolean value * and didn't call it if it was false. Therefor some people set the callback * to '0' if they don't want to use it (IO::Socket::SSL for example). Therefor * we don't execute the callback if it's value isn't something true to retain * backwards compatibility. */ if (callback==NULL || !SvOK(callback) || !SvTRUE(callback)) { SSL_CTX_set_verify(ctx, mode, NULL); cb_data_advanced_put(ctx, "ssleay_verify_callback!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_verify_callback!!func", newSVsv(callback)); SSL_CTX_set_verify(ctx, mode, &ssleay_verify_callback_invoke); } #if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(LIBRESSL_VERSION_NUMBER) void SSL_CTX_set_security_level(SSL_CTX * ctx, int level) int SSL_CTX_get_security_level(SSL_CTX * ctx) #endif #if OPENSSL_VERSION_NUMBER >= 0x10101007L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx) #endif #if OPENSSL_VERSION_NUMBER >= 0x10101003L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) #endif #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1 */ void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val) #endif void SSL_CTX_sess_set_new_cb(ctx, callback) SSL_CTX * ctx SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_sess_set_new_cb(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ssl_ctx_sess_new_cb!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ssl_ctx_sess_new_cb!!func", newSVsv(callback)); SSL_CTX_sess_set_new_cb(ctx, &ssleay_ssl_ctx_sess_new_cb_invoke); } void SSL_CTX_sess_set_remove_cb(ctx, callback) SSL_CTX * ctx SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_sess_set_remove_cb(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ssl_ctx_sess_remove_cb!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ssl_ctx_sess_remove_cb!!func", newSVsv(callback)); SSL_CTX_sess_set_remove_cb(ctx, &ssleay_ssl_ctx_sess_remove_cb_invoke); } int SSL_get_error(s,ret) SSL * s int ret #define REM10 "============= SSL functions ==============" SSL * SSL_new(ctx) SSL_CTX * ctx void SSL_free(s) SSL * s CODE: SSL_free(s); cb_data_advanced_drop(s); /* clean callback related data from global hash */ #if 0 /* this seems to be gone in 0.9.0 */ void SSL_debug(file) char * file #endif int SSL_accept(s) SSL * s void SSL_clear(s) SSL * s int SSL_connect(s) SSL * s #if defined(WIN32) int SSL_set_fd(s,fd) SSL * s perl_filehandle_t fd CODE: RETVAL = SSL_set_fd(s,_get_osfhandle(fd)); OUTPUT: RETVAL int SSL_set_rfd(s,fd) SSL * s perl_filehandle_t fd CODE: RETVAL = SSL_set_rfd(s,_get_osfhandle(fd)); OUTPUT: RETVAL int SSL_set_wfd(s,fd) SSL * s perl_filehandle_t fd CODE: RETVAL = SSL_set_wfd(s,_get_osfhandle(fd)); OUTPUT: RETVAL #else int SSL_set_fd(s,fd) SSL * s perl_filehandle_t fd int SSL_set_rfd(s,fd) SSL * s perl_filehandle_t fd int SSL_set_wfd(s,fd) SSL * s perl_filehandle_t fd #endif int SSL_get_fd(s) SSL * s void SSL_read(s,max=32768) SSL * s int max PREINIT: char *buf; int got; int succeeded = 1; PPCODE: New(0, buf, max, char); got = SSL_read(s, buf, max); if (got <= 0 && SSL_ERROR_ZERO_RETURN != SSL_get_error(s, got)) succeeded = 0; /* If in list context, return 2-item list: * first return value: data gotten, or undef on error (got<0) * second return value: result from SSL_read() */ if (GIMME_V==G_ARRAY) { EXTEND(SP, 2); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0))); PUSHs(sv_2mortal(newSViv(got))); /* If in scalar or void context, return data gotten, or undef on error. */ } else { EXTEND(SP, 1); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0))); } Safefree(buf); void SSL_peek(s,max=32768) SSL * s int max PREINIT: char *buf; int got; int succeeded = 1; PPCODE: New(0, buf, max, char); got = SSL_peek(s, buf, max); if (got <= 0 && SSL_ERROR_ZERO_RETURN != SSL_get_error(s, got)) succeeded = 0; /* If in list context, return 2-item list: * first return value: data gotten, or undef on error (got<0) * second return value: result from SSL_peek() */ if (GIMME_V==G_ARRAY) { EXTEND(SP, 2); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0))); PUSHs(sv_2mortal(newSViv(got))); /* If in scalar or void context, return data gotten, or undef on error. */ } else { EXTEND(SP, 1); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0))); } Safefree(buf); #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1 */ void SSL_read_ex(s,max=32768) SSL * s int max PREINIT: char *buf; size_t readbytes; int succeeded; PPCODE: Newx(buf, max, char); succeeded = SSL_read_ex(s, buf, max, &readbytes); /* Return 2-item list: * first return value: data gotten, or undef on error * second return value: result from SSL_read_ex() */ EXTEND(SP, 2); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, readbytes) : newSV(0))); PUSHs(sv_2mortal(newSViv(succeeded))); Safefree(buf); void SSL_peek_ex(s,max=32768) SSL * s int max PREINIT: char *buf; size_t readbytes; int succeeded; PPCODE: Newx(buf, max, char); succeeded = SSL_peek_ex(s, buf, max, &readbytes); /* Return 2-item list: * first return value: data gotten, or undef on error * second return value: result from SSL_peek_ex() */ EXTEND(SP, 2); PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, readbytes) : newSV(0))); PUSHs(sv_2mortal(newSViv(succeeded))); Safefree(buf); void SSL_write_ex(s,buf) SSL * s PREINIT: STRLEN len; size_t written; int succeeded; INPUT: char * buf = SvPV( ST(1), len); PPCODE: succeeded = SSL_write_ex(s, buf, len, &written); /* Return 2-item list: * first return value: data gotten, or undef on error * second return value: result from SSL_read_ex() */ EXTEND(SP, 2); PUSHs(sv_2mortal(newSVuv(written))); PUSHs(sv_2mortal(newSViv(succeeded))); #endif int SSL_write(s,buf) SSL * s PREINIT: STRLEN len; INPUT: char * buf = SvPV( ST(1), len); CODE: RETVAL = SSL_write (s, buf, (int)len); OUTPUT: RETVAL int SSL_write_partial(s,from,count,buf) SSL * s int from int count PREINIT: STRLEN ulen; IV len; INPUT: char * buf = SvPV( ST(3), ulen); CODE: /* if (SvROK( ST(3) )) { SV* t = SvRV( ST(3) ); buf = SvPV( t, len); } else buf = SvPV( ST(3), len); */ PR4("write_partial from=%d count=%d len=%lu\n",from,count,ulen); /*PR2("buf='%s'\n",&buf[from]); / * too noisy */ len = (IV)ulen; len -= from; if (len < 0) { croak("from beyound end of buffer"); RETVAL = -1; } else RETVAL = SSL_write (s, &(buf[from]), (count<=len)?count:len); OUTPUT: RETVAL int SSL_use_RSAPrivateKey(s,rsa) SSL * s RSA * rsa int SSL_use_RSAPrivateKey_ASN1(s,d,len) SSL * s unsigned char * d long len int SSL_use_RSAPrivateKey_file(s,file,type) SSL * s char * file int type int SSL_CTX_use_RSAPrivateKey_file(ctx,file,type) SSL_CTX * ctx char * file int type int SSL_use_PrivateKey(s,pkey) SSL * s EVP_PKEY * pkey int SSL_use_PrivateKey_ASN1(pk,s,d,len) int pk SSL * s unsigned char * d long len int SSL_use_PrivateKey_file(s,file,type) SSL * s char * file int type int SSL_CTX_use_PrivateKey_file(ctx,file,type) SSL_CTX * ctx char * file int type int SSL_use_certificate(s,x) SSL * s X509 * x int SSL_use_certificate_ASN1(s,d,len) SSL * s unsigned char * d long len int SSL_use_certificate_file(s,file,type) SSL * s char * file int type int SSL_CTX_use_certificate_file(ctx,file,type) SSL_CTX * ctx char * file int type const char * SSL_state_string(s) SSL * s const char * SSL_rstate_string(s) SSL * s const char * SSL_state_string_long(s) SSL * s const char * SSL_rstate_string_long(s) SSL * s long SSL_get_time(ses) SSL_SESSION * ses long SSL_set_time(ses,t) SSL_SESSION * ses long t long SSL_get_timeout(ses) SSL_SESSION * ses long SSL_set_timeout(ses,t) SSL_SESSION * ses long t void SSL_copy_session_id(to,from) SSL * to SSL * from void SSL_set_read_ahead(s,yes=1) SSL * s int yes int SSL_get_read_ahead(s) SSL * s int SSL_pending(s) SSL * s #if OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.0 */ int SSL_has_pending(s) SSL * s #endif int SSL_CTX_set_cipher_list(s,str) SSL_CTX * s char * str void SSL_get_ciphers(s) SSL * s PREINIT: STACK_OF(SSL_CIPHER) *sk = NULL; const SSL_CIPHER *c; int i; PPCODE: sk = SSL_get_ciphers(s); if( sk == NULL ) { XSRETURN_EMPTY; } for (i=0; i= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_SESSION_is_resumable(ses) SSL_SESSION * ses SSL_SESSION * SSL_SESSION_dup(sess) SSL_SESSION * sess #endif #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1 */ void SSL_set_post_handshake_auth(SSL *ssl, int val) int SSL_verify_client_post_handshake(SSL *ssl) #endif void i2d_SSL_SESSION(sess) SSL_SESSION * sess PPCODE: STRLEN len; unsigned char *pc,*pi; if (!(len = i2d_SSL_SESSION(sess,NULL))) croak("invalid SSL_SESSION"); Newx(pc,len,unsigned char); if (!pc) croak("out of memory"); pi = pc; i2d_SSL_SESSION(sess,&pi); XPUSHs(sv_2mortal(newSVpv((char*)pc,len))); Safefree(pc); SSL_SESSION * d2i_SSL_SESSION(pv) SV *pv CODE: RETVAL = NULL; if (SvPOK(pv)) { const unsigned char *p; STRLEN len; p = (unsigned char*)SvPV(pv,len); RETVAL = d2i_SSL_SESSION(NULL,&p,len); } OUTPUT: RETVAL #if (OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) int SSL_SESSION_up_ref(sess) SSL_SESSION * sess #endif int SSL_set_session(to,ses) SSL * to SSL_SESSION * ses #define REM30 "SSLeay-0.9.0 defines these as macros. I expand them here for safety's sake" SSL_SESSION * SSL_get_session(s) SSL * s ALIAS: SSL_get0_session = 1 SSL_SESSION * SSL_get1_session(s) SSL * s X509 * SSL_get_certificate(s) SSL * s SSL_CTX * SSL_get_SSL_CTX(s) SSL * s #if OPENSSL_VERSION_NUMBER >= 0x0090806fL SSL_CTX * SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) #endif long SSL_ctrl(ssl,cmd,larg,parg) SSL * ssl int cmd long larg char * parg long SSL_CTX_ctrl(ctx,cmd,larg,parg) SSL_CTX * ctx int cmd long larg char * parg #ifdef NET_SSLEAY_32BIT_CONSTANTS long SSL_get_options(ssl) SSL * ssl long SSL_set_options(ssl,op) SSL * ssl long op long SSL_CTX_get_options(ctx) SSL_CTX * ctx long SSL_CTX_set_options(ctx,op) SSL_CTX * ctx long op #else uint64_t SSL_get_options(ssl) SSL * ssl uint64_t SSL_set_options(ssl,op) SSL * ssl uint64_t op uint64_t SSL_CTX_get_options(ctx) SSL_CTX * ctx uint64_t SSL_CTX_set_options(ctx,op) SSL_CTX * ctx uint64_t op #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L struct lhash_st_SSL_SESSION * SSL_CTX_sessions(ctx) SSL_CTX * ctx #else LHASH * SSL_CTX_sessions(ctx) SSL_CTX * ctx CODE: /* NOTE: This should be deprecated. Corresponding macro was removed from ssl.h as of 0.9.2 */ if (ctx == NULL) croak("NULL SSL context passed as argument."); RETVAL = ctx -> sessions; OUTPUT: RETVAL #endif unsigned long SSL_CTX_sess_number(ctx) SSL_CTX * ctx int SSL_CTX_sess_connect(ctx) SSL_CTX * ctx int SSL_CTX_sess_connect_good(ctx) SSL_CTX * ctx int SSL_CTX_sess_connect_renegotiate(ctx) SSL_CTX * ctx int SSL_CTX_sess_accept(ctx) SSL_CTX * ctx int SSL_CTX_sess_accept_renegotiate(ctx) SSL_CTX * ctx int SSL_CTX_sess_accept_good(ctx) SSL_CTX * ctx int SSL_CTX_sess_hits(ctx) SSL_CTX * ctx int SSL_CTX_sess_cb_hits(ctx) SSL_CTX * ctx int SSL_CTX_sess_misses(ctx) SSL_CTX * ctx int SSL_CTX_sess_timeouts(ctx) SSL_CTX * ctx int SSL_CTX_sess_cache_full(ctx) SSL_CTX * ctx int SSL_CTX_sess_get_cache_size(ctx) SSL_CTX * ctx long SSL_CTX_sess_set_cache_size(ctx,size) SSL_CTX * ctx int size int SSL_want(s) SSL * s # OpenSSL 1.1.1 documents SSL_in_init and the related functions as # returning 0 or 1. However, older versions and e.g. LibreSSL may # return other values than 1 which we fold to 1. int SSL_in_before(s) SSL * s CODE: RETVAL = SSL_in_before(s) == 0 ? 0 : 1; OUTPUT: RETVAL int SSL_is_init_finished(s) SSL * s CODE: RETVAL = SSL_is_init_finished(s) == 0 ? 0 : 1; OUTPUT: RETVAL int SSL_in_init(s) SSL * s CODE: RETVAL = SSL_in_init(s) == 0 ? 0 : 1; OUTPUT: RETVAL int SSL_in_connect_init(s) SSL * s CODE: RETVAL = SSL_in_connect_init(s) == 0 ? 0 : 1; OUTPUT: RETVAL int SSL_in_accept_init(s) SSL * s CODE: RETVAL = SSL_in_accept_init(s) == 0 ? 0 : 1; OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER < 0x10100000L int SSL_state(s) SSL * s int SSL_get_state(ssl) SSL * ssl CODE: RETVAL = SSL_state(ssl); OUTPUT: RETVAL #else int SSL_state(s) SSL * s CODE: RETVAL = SSL_get_state(s); OUTPUT: RETVAL int SSL_get_state(s) SSL * s #endif #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) long SSL_set_tlsext_host_name(SSL *ssl, const char *name) const char * SSL_get_servername(const SSL *s, int type=TLSEXT_NAMETYPE_host_name) int SSL_get_servername_type(const SSL *s) void SSL_CTX_set_tlsext_servername_callback(ctx,callback=&PL_sv_undef,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_tlsext_servername_callback(ctx, NULL); SSL_CTX_set_tlsext_servername_arg(ctx, NULL); cb_data_advanced_put(ctx, "tlsext_servername_callback!!data", NULL); cb_data_advanced_put(ctx, "tlsext_servername_callback!!func", NULL); } else { cb_data_advanced_put(ctx, "tlsext_servername_callback!!data", newSVsv(data)); cb_data_advanced_put(ctx, "tlsext_servername_callback!!func", newSVsv(callback)); SSL_CTX_set_tlsext_servername_callback(ctx, &tlsext_servername_callback_invoke); SSL_CTX_set_tlsext_servername_arg(ctx, (void*)ctx); } #endif #if OPENSSL_VERSION_NUMBER >= 0x1010006fL /* In OpenSSL 1.1.0 but actually called for $ssl starting from 1.1.0f */ #ifndef LIBRESSL_VERSION_NUMBER #ifndef OPENSSL_IS_BORINGSSL void SSL_set_default_passwd_cb(ssl,callback=&PL_sv_undef) SSL * ssl SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_set_default_passwd_cb(ssl, NULL); SSL_set_default_passwd_cb_userdata(ssl, NULL); cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!func", NULL); } else { cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!func", newSVsv(callback)); SSL_set_default_passwd_cb_userdata(ssl, (void*)ssl); SSL_set_default_passwd_cb(ssl, &ssleay_ssl_passwd_cb_invoke); } void SSL_set_default_passwd_cb_userdata(ssl,data=&PL_sv_undef) SSL * ssl SV * data CODE: /* SSL_set_default_passwd_cb_userdata is set in SSL_set_default_passwd_cb */ if (data==NULL || !SvOK(data)) { cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!data", NULL); } else { cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!data", newSVsv(data)); } #endif /* !BoringSSL */ #endif /* !LibreSSL */ #endif /* >= 1.1.0f */ #if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(LIBRESSL_VERSION_NUMBER) void SSL_set_security_level(SSL * ssl, int level) int SSL_get_security_level(SSL * ssl) #endif #if OPENSSL_VERSION_NUMBER >= 0x10101007L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_set_num_tickets(SSL *ssl, size_t num_tickets) size_t SSL_get_num_tickets(SSL *ssl) #endif #if OPENSSL_VERSION_NUMBER >= 0x10101003L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_set_ciphersuites(SSL *ssl, const char *str) #endif const BIO_METHOD * BIO_f_ssl() const BIO_METHOD * BIO_s_mem() unsigned long ERR_get_error() unsigned long ERR_peek_error() void ERR_put_error(lib,func,reason,file,line) int lib int func int reason char * file int line void ERR_clear_error() char * ERR_error_string(error,buf=NULL) unsigned long error char * buf CODE: RETVAL = ERR_error_string(error,buf); OUTPUT: RETVAL void SSL_load_error_strings() void ERR_load_crypto_strings() int SSL_FIPS_mode_set(int onoff) CODE: #ifdef USE_ITHREADS MUTEX_LOCK(&LIB_init_mutex); #endif #ifdef OPENSSL_FIPS RETVAL = FIPS_mode_set(onoff); if (!RETVAL) { ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); } #else RETVAL = 1; fprintf(stderr, "SSL_FIPS_mode_set not available: OpenSSL not compiled with FIPS support\n"); #endif #ifdef USE_ITHREADS MUTEX_UNLOCK(&LIB_init_mutex); #endif OUTPUT: RETVAL int SSL_library_init() ALIAS: SSLeay_add_ssl_algorithms = 1 OpenSSL_add_ssl_algorithms = 2 add_ssl_algorithms = 3 CODE: #ifdef USE_ITHREADS MUTEX_LOCK(&LIB_init_mutex); #endif RETVAL = 0; if (!LIB_initialized) { RETVAL = SSL_library_init(); LIB_initialized = 1; } #ifdef USE_ITHREADS MUTEX_UNLOCK(&LIB_init_mutex); #endif OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER >= 0x0090700fL #define REM5 "NOTE: requires 0.9.7+" #ifndef OPENSSL_NO_ENGINE void ENGINE_load_builtin_engines() void ENGINE_register_all_complete() ENGINE* ENGINE_by_id(id) char * id int ENGINE_set_default(e, flags) ENGINE * e int flags #endif /* OPENSSL_NO_ENGINE */ #endif void ERR_load_SSL_strings() void ERR_load_RAND_strings() int RAND_bytes(buf, num) SV *buf int num PREINIT: int rc; unsigned char *random; CODE: New(0, random, num, unsigned char); rc = RAND_bytes(random, num); sv_setpvn(buf, (const char*)random, num); Safefree(random); RETVAL = rc; OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER) int RAND_priv_bytes(buf, num) SV *buf int num PREINIT: int rc; unsigned char *random; CODE: New(0, random, num, unsigned char); rc = RAND_priv_bytes(random, num); sv_setpvn(buf, (const char*)random, num); Safefree(random); RETVAL = rc; OUTPUT: RETVAL #endif int RAND_pseudo_bytes(buf, num) SV *buf int num PREINIT: int rc; unsigned char *random; CODE: New(0, random, num, unsigned char); rc = RAND_pseudo_bytes(random, num); sv_setpvn(buf, (const char*)random, num); Safefree(random); RETVAL = rc; OUTPUT: RETVAL void RAND_add(buf, num, entropy) SV *buf int num double entropy PREINIT: STRLEN len; CODE: RAND_add((const void *)SvPV(buf, len), num, entropy); int RAND_poll() int RAND_status() SV * RAND_file_name(num) size_t num PREINIT: char *buf; CODE: Newxz(buf, num, char); if (!RAND_file_name(buf, num)) { Safefree(buf); XSRETURN_UNDEF; } RETVAL = newSVpv(buf, 0); Safefree(buf); OUTPUT: RETVAL void RAND_seed(buf) PREINIT: STRLEN len; INPUT: char * buf = SvPV( ST(1), len); CODE: RAND_seed (buf, (int)len); void RAND_cleanup() int RAND_load_file(file_name, how_much) char * file_name int how_much int RAND_write_file(file_name) char * file_name #define REM40 "Minimal X509 stuff..., this is a bit ugly and should be put in its own modules Net::SSLeay::X509.pm" #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2050000fL) int X509_check_host(X509 *cert, const char *name, unsigned int flags = 0, SV *peername = &PL_sv_undef) PREINIT: char *c_peername = NULL; CODE: RETVAL = X509_check_host(cert, name, 0, flags, (items == 4) ? &c_peername : NULL); if (items == 4) sv_setpv(peername, c_peername); OUTPUT: RETVAL CLEANUP: if (c_peername) OPENSSL_free(c_peername); int X509_check_email(X509 *cert, const char *address, unsigned int flags = 0) CODE: RETVAL = X509_check_email(cert, address, 0, flags); OUTPUT: RETVAL int X509_check_ip(X509 *cert, SV *address, unsigned int flags = 0) PREINIT: unsigned char *c_address; size_t addresslen; CODE: c_address = (unsigned char *)SvPV(address, addresslen); RETVAL = X509_check_ip(cert, c_address, addresslen, flags); OUTPUT: RETVAL int X509_check_ip_asc(X509 *cert, const char *address, unsigned int flags = 0) #endif X509_NAME* X509_get_issuer_name(cert) X509 * cert X509_NAME* X509_get_subject_name(cert) X509 * cert void * X509_get_ex_data(cert,idx) X509 * cert int idx int X509_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL) long argl void * argp CRYPTO_EX_new * new_func CRYPTO_EX_dup * dup_func CRYPTO_EX_free * free_func void * X509_get_app_data(cert) X509 * cert CODE: RETVAL = X509_get_ex_data(cert,0); OUTPUT: RETVAL int X509_set_ex_data(cert,idx,data) X509 * cert int idx void * data int X509_set_app_data(cert,arg) X509 * cert char * arg CODE: RETVAL = X509_set_ex_data(cert,0,arg); OUTPUT: RETVAL int X509_set_issuer_name(X509 *x, X509_NAME *name) int X509_set_subject_name(X509 *x, X509_NAME *name) int X509_set_version(X509 *x, long version) int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) long X509_get_version(X509 *x) EVP_PKEY * X509_get_pubkey(X509 *x) ASN1_INTEGER * X509_get_serialNumber(X509 *x) #if (OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2080100fL) const ASN1_INTEGER * X509_get0_serialNumber(const X509 *x) #endif int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) int X509_certificate_type(X509 *x, EVP_PKEY *pubkey=NULL); int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) int X509_verify(X509 *x, EVP_PKEY *r) X509_NAME * X509_NAME_new() unsigned long X509_NAME_hash(X509_NAME *name) void X509_NAME_oneline(name) X509_NAME * name PREINIT: char * buf; CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ if ((buf = X509_NAME_oneline(name, NULL, 0))) { sv_setpvn( ST(0), buf, strlen(buf)); OPENSSL_free(buf); /* mem was allocated by openssl */ } void X509_NAME_print_ex(name,flags=XN_FLAG_RFC2253,utf8_decode=0) X509_NAME * name unsigned long flags int utf8_decode PREINIT: char * buf; BIO * bp; int n, i, ident=0; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp) { if (X509_NAME_print_ex(bp, name, ident, flags)) { n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) { sv_setpvn(ST(0), buf, i); if (utf8_decode) sv_utf8_decode(ST(0)); } Safefree(buf); } } BIO_free(bp); } void X509_NAME_get_text_by_NID(name,nid) X509_NAME * name int nid PREINIT: char* buf; int length; CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ length = X509_NAME_get_text_by_NID(name, nid, NULL, 0); if (length>=0) { New(0, buf, length+1, char); if (X509_NAME_get_text_by_NID(name, nid, buf, length + 1)>=0) sv_setpvn( ST(0), buf, length); Safefree(buf); } #if OPENSSL_VERSION_NUMBER >= 0x0090500fL #define REM17 "requires 0.9.5+" int X509_NAME_add_entry_by_NID(name,nid,type,bytes,loc=-1,set=0) X509_NAME *name int nid int type int loc int set PREINIT: STRLEN len; INPUT: unsigned char *bytes = (unsigned char *)SvPV(ST(3), len); CODE: RETVAL = X509_NAME_add_entry_by_NID(name,nid,type,bytes,len,loc,set); OUTPUT: RETVAL int X509_NAME_add_entry_by_OBJ(name,obj,type,bytes,loc=-1,set=0) X509_NAME *name ASN1_OBJECT *obj int type int loc int set PREINIT: STRLEN len; INPUT: unsigned char *bytes = (unsigned char *)SvPV(ST(3), len); CODE: RETVAL = X509_NAME_add_entry_by_OBJ(name,obj,type,bytes,len,loc,set); OUTPUT: RETVAL int X509_NAME_add_entry_by_txt(name,field,type,bytes,loc=-1,set=0) X509_NAME *name char *field int type int loc int set PREINIT: STRLEN len; INPUT: unsigned char *bytes = (unsigned char *)SvPV(ST(3), len); CODE: RETVAL = X509_NAME_add_entry_by_txt(name,field,type,bytes,len,loc,set); OUTPUT: RETVAL #endif int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) int X509_NAME_entry_count(X509_NAME *name) X509_NAME_ENTRY * X509_NAME_get_entry(X509_NAME *name, int loc) ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) void X509_CRL_free(X509_CRL *x) X509_CRL * X509_CRL_new() #if OPENSSL_VERSION_NUMBER >= 0x0090700fL #define REM19 "requires 0.9.7+" int X509_CRL_set_version(X509_CRL *x, long version) int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) int X509_CRL_sort(X509_CRL *x) #endif long X509_CRL_get_version(X509_CRL *x) X509_NAME * X509_CRL_get_issuer(X509_CRL *x) ASN1_TIME * X509_CRL_get_lastUpdate(X509_CRL *x) ASN1_TIME * X509_CRL_get_nextUpdate(X509_CRL *x) int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r) int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) #if OPENSSL_VERSION_NUMBER >= 0x0090700fL #define REM20 "requires 0.9.7+" int P_X509_CRL_set_serial(crl,crl_number) X509_CRL *crl ASN1_INTEGER * crl_number; CODE: RETVAL = 0; if (crl && crl_number) if (X509_CRL_add1_ext_i2d(crl, NID_crl_number, crl_number, 0, 0)) RETVAL = 1; OUTPUT: RETVAL ASN1_INTEGER * P_X509_CRL_get_serial(crl) X509_CRL *crl INIT: int i; CODE: RETVAL = (ASN1_INTEGER *)X509_CRL_get_ext_d2i(crl, NID_crl_number, &i, NULL); if (!RETVAL || i==-1) XSRETURN_UNDEF; OUTPUT: RETVAL void P_X509_CRL_add_revoked_serial_hex(crl,serial_hex,rev_time,reason_code=0,comp_time=NULL) X509_CRL *crl char * serial_hex ASN1_TIME *rev_time long reason_code ASN1_TIME *comp_time PREINIT: BIGNUM *bn = NULL; ASN1_INTEGER *sn; X509_REVOKED *rev; ASN1_ENUMERATED *rsn = NULL; int rv; PPCODE: rv=0; rev = X509_REVOKED_new(); if (rev) { if (BN_hex2bn(&bn, serial_hex)) { sn = BN_to_ASN1_INTEGER(bn, NULL); if (sn) { X509_REVOKED_set_serialNumber(rev, sn); ASN1_INTEGER_free(sn); rv = 1; } BN_free(bn); } } if (!rv) XSRETURN_IV(0); if (!rev_time) XSRETURN_IV(0); if (!X509_REVOKED_set_revocationDate(rev, rev_time)) XSRETURN_IV(0); if(reason_code) { rv = 0; rsn = ASN1_ENUMERATED_new(); if (rsn) { if (ASN1_ENUMERATED_set(rsn, reason_code)) if (X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rsn, 0, 0)) rv=1; ASN1_ENUMERATED_free(rsn); } if (!rv) XSRETURN_IV(0); } if(comp_time) { X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0); } if(!X509_CRL_add0_revoked(crl, rev)) XSRETURN_IV(0); XSRETURN_IV(1); #endif X509_REQ * X509_REQ_new() void X509_REQ_free(X509_REQ *x) X509_NAME * X509_REQ_get_subject_name(X509_REQ *x) int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *x) int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pk, const EVP_MD *md) int X509_REQ_verify(X509_REQ *x, EVP_PKEY *r) int X509_REQ_set_version(X509_REQ *x, long version) long X509_REQ_get_version(X509_REQ *x) int X509_REQ_get_attr_count(const X509_REQ *req); int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos=-1) int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, int lastpos=-1) int X509_REQ_add1_attr_by_NID(req,nid,type,bytes) X509_REQ *req int nid int type PREINIT: STRLEN len; INPUT: unsigned char *bytes = (unsigned char *)SvPV(ST(3), len); CODE: RETVAL = X509_REQ_add1_attr_by_NID(req,nid,type,bytes,len); OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER >= 0x0090700fL #define REM21 "requires 0.9.7+" void P_X509_REQ_get_attr(req,n) X509_REQ *req int n INIT: X509_ATTRIBUTE * att; int count, i; ASN1_STRING * s; ASN1_TYPE * t; PPCODE: att = X509_REQ_get_attr(req,n); count = X509_ATTRIBUTE_count(att); for (i=0; ivalue.asn1_string; XPUSHs(sv_2mortal(newSViv(PTR2IV(s)))); } #endif int P_X509_REQ_add_extensions(x,...) X509_REQ *x PREINIT: int i=1; int nid; char *data; X509_EXTENSION *ex; STACK_OF(X509_EXTENSION) *stack; CODE: if (items>1) { RETVAL = 1; stack = sk_X509_EXTENSION_new_null(); while(i+11) { RETVAL = 1; while(i+11) { RETVAL = 1; while(i+1= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) /* OpenSSL 1.1.0-pre5, LibreSSL 2.7.0 */ X509 * X509_STORE_CTX_get0_cert(x509_store_ctx) X509_STORE_CTX *x509_store_ctx #endif STACK_OF(X509) * X509_STORE_CTX_get1_chain(x509_store_ctx) X509_STORE_CTX *x509_store_ctx int X509_STORE_CTX_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL) long argl void * argp CRYPTO_EX_new * new_func CRYPTO_EX_dup * dup_func CRYPTO_EX_free * free_func void * X509_STORE_CTX_get_ex_data(x509_store_ctx,idx) X509_STORE_CTX * x509_store_ctx int idx void * X509_STORE_CTX_get_app_data(x509_store_ctx) X509_STORE_CTX * x509_store_ctx CODE: RETVAL = X509_STORE_CTX_get_ex_data(x509_store_ctx,0); OUTPUT: RETVAL void X509_get_fingerprint(cert,type) X509 * cert char * type PREINIT: const EVP_MD *digest_tp = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dsz, k = 0; char text[EVP_MAX_MD_SIZE * 3 + 1]; CODE: #ifndef OPENSSL_NO_MD5 if (!k && !strcmp(type,"md5")) { k = 1; digest_tp = EVP_md5(); } #endif if (!k && !strcmp(type,"sha1")) { k = 1; digest_tp = EVP_sha1(); } #if OPENSSL_VERSION_NUMBER >= 0x0090800fL #ifndef OPENSSL_NO_SHA256 if (!k && !strcmp(type,"sha256")) { k = 1; digest_tp = EVP_sha256(); } #endif #endif if (!k && !strcmp(type,"ripemd160")) { k = 1; digest_tp = EVP_ripemd160(); } if (!k) /* Default digest */ digest_tp = EVP_sha1(); if ( digest_tp == NULL ) { /* Out of memory */ XSRETURN_UNDEF; } if (!X509_digest(cert, digest_tp, digest, &dsz)) { /* Out of memory */ XSRETURN_UNDEF; } text[0] = '\0'; for(k=0; k= 0 && (subjAltNameExt = X509_get_ext(cert, i)) && (subjAltNameDNs = X509V3_EXT_d2i(subjAltNameExt))) { num_gnames = sk_GENERAL_NAME_num(subjAltNameDNs); for (j = 0; j < num_gnames; j++) { subjAltNameDN = sk_GENERAL_NAME_value(subjAltNameDNs, j); switch (subjAltNameDN->type) { case GEN_OTHERNAME: EXTEND(SP, 2); count++; PUSHs(sv_2mortal(newSViv(subjAltNameDN->type))); PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.otherName->value->value.utf8string), ASN1_STRING_length(subjAltNameDN->d.otherName->value->value.utf8string)))); break; case GEN_EMAIL: case GEN_DNS: case GEN_URI: EXTEND(SP, 2); count++; PUSHs(sv_2mortal(newSViv(subjAltNameDN->type))); PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.ia5), ASN1_STRING_length(subjAltNameDN->d.ia5)))); break; case GEN_DIRNAME: { char * buf = X509_NAME_oneline(subjAltNameDN->d.dirn, NULL, 0); EXTEND(SP, 2); count++; PUSHs(sv_2mortal(newSViv(subjAltNameDN->type))); PUSHs(sv_2mortal(newSVpv((buf), strlen((buf))))); } break; case GEN_RID: { char buf[2501]; /* Much more than what's suggested on OBJ_obj2txt manual page */ int len = OBJ_obj2txt(buf, sizeof(buf), subjAltNameDN->d.rid, 1); if (len < 0 || len > (int)((sizeof(buf) - 1))) break; /* Skip bad or overly long RID */ EXTEND(SP, 2); count++; PUSHs(sv_2mortal(newSViv(subjAltNameDN->type))); PUSHs(sv_2mortal(newSVpv(buf, 0))); } break; case GEN_IPADD: EXTEND(SP, 2); count++; PUSHs(sv_2mortal(newSViv(subjAltNameDN->type))); PUSHs(sv_2mortal(newSVpv((const char*)subjAltNameDN->d.ip->data, subjAltNameDN->d.ip->length))); break; } } sk_GENERAL_NAME_pop_free(subjAltNameDNs, GENERAL_NAME_free); } XSRETURN(count * 2); #if OPENSSL_VERSION_NUMBER >= 0x0090700fL void P_X509_get_crl_distribution_points(cert) X509 * cert INIT: GENERAL_NAMES *gnames; GENERAL_NAME *gn; STACK_OF(DIST_POINT) *points; DIST_POINT *p; int i, j; PPCODE: points = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL); if (points) for (i = 0; i < sk_DIST_POINT_num(points); i++) { p = sk_DIST_POINT_value(points, i); if (!p->distpoint) continue; if (p->distpoint->type == 0) { /* full name */ gnames = p->distpoint->name.fullname; for (j = 0; j < sk_GENERAL_NAME_num(gnames); j++) { gn = sk_GENERAL_NAME_value(gnames, j); if (gn->type == GEN_URI) { XPUSHs(sv_2mortal(newSVpv((char*)ASN1_STRING_data(gn->d.ia5),ASN1_STRING_length(gn->d.ia5)))); } } } else { /* relative name - not supported */ /* XXX-TODO: the code below is just an idea; do not enable it without proper test case BIO *bp; char *buf; int n; X509_NAME ntmp; ntmp.entries = p->distpoint->name.relativename; bp = BIO_new(BIO_s_mem()); if (bp) { X509_NAME_print_ex(bp, &ntmp, 0, XN_FLAG_RFC2253); n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { j = BIO_read(bp,buf,n); if (j>=0 && j<=n) XPUSHs(sv_2mortal(newSVpvn(buf,j))); Safefree(buf); } BIO_free(bp); } */ } } void P_X509_get_ocsp_uri(cert) X509 * cert PPCODE: AUTHORITY_INFO_ACCESS *info; int i; info = X509_get_ext_d2i(cert, NID_info_access, NULL, NULL); if (!info) XSRETURN_UNDEF; for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); if (OBJ_obj2nid(ad->method) == NID_ad_OCSP && ad->location->type == GEN_URI) { XPUSHs(sv_2mortal(newSVpv( (char*)ASN1_STRING_data(ad->location->d.uniformResourceIdentifier), ASN1_STRING_length(ad->location->d.uniformResourceIdentifier) ))); if (GIMME == G_SCALAR) break; /* get only first */ } } void P_X509_get_ext_key_usage(cert,format=0) X509 * cert int format PREINIT: EXTENDED_KEY_USAGE *extusage; int i, nid; char buffer[100]; /* openssl doc: a buffer length of 80 should be more than enough to handle any OID encountered in practice */ ASN1_OBJECT *o; PPCODE: extusage = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL); for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { o = sk_ASN1_OBJECT_value(extusage,i); nid = OBJ_obj2nid(o); OBJ_obj2txt(buffer, sizeof(buffer)-1, o, 1); if(format==0) XPUSHs(sv_2mortal(newSVpv(buffer,0))); /* format 0: oid */ else if(format==1 && nid>0) XPUSHs(sv_2mortal(newSViv(nid))); /* format 1: nid */ else if(format==2 && nid>0) XPUSHs(sv_2mortal(newSVpv(OBJ_nid2sn(nid),0))); /* format 2: shortname */ else if(format==3 && nid>0) XPUSHs(sv_2mortal(newSVpv(OBJ_nid2ln(nid),0))); /* format 3: longname */ } #endif void P_X509_get_key_usage(cert) X509 * cert INIT: ASN1_BIT_STRING * u; PPCODE: u = X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL); if (u) { if (ASN1_BIT_STRING_get_bit(u,0)) XPUSHs(sv_2mortal(newSVpv("digitalSignature",0))); if (ASN1_BIT_STRING_get_bit(u,1)) XPUSHs(sv_2mortal(newSVpv("nonRepudiation",0))); if (ASN1_BIT_STRING_get_bit(u,2)) XPUSHs(sv_2mortal(newSVpv("keyEncipherment",0))); if (ASN1_BIT_STRING_get_bit(u,3)) XPUSHs(sv_2mortal(newSVpv("dataEncipherment",0))); if (ASN1_BIT_STRING_get_bit(u,4)) XPUSHs(sv_2mortal(newSVpv("keyAgreement",0))); if (ASN1_BIT_STRING_get_bit(u,5)) XPUSHs(sv_2mortal(newSVpv("keyCertSign",0))); if (ASN1_BIT_STRING_get_bit(u,6)) XPUSHs(sv_2mortal(newSVpv("cRLSign",0))); if (ASN1_BIT_STRING_get_bit(u,7)) XPUSHs(sv_2mortal(newSVpv("encipherOnly",0))); if (ASN1_BIT_STRING_get_bit(u,8)) XPUSHs(sv_2mortal(newSVpv("decipherOnly",0))); } void P_X509_get_netscape_cert_type(cert) X509 * cert INIT: ASN1_BIT_STRING * u; PPCODE: u = X509_get_ext_d2i(cert, NID_netscape_cert_type, NULL, NULL); if (u) { if (ASN1_BIT_STRING_get_bit(u,0)) XPUSHs(sv_2mortal(newSVpv("client",0))); if (ASN1_BIT_STRING_get_bit(u,1)) XPUSHs(sv_2mortal(newSVpv("server",0))); if (ASN1_BIT_STRING_get_bit(u,2)) XPUSHs(sv_2mortal(newSVpv("email",0))); if (ASN1_BIT_STRING_get_bit(u,3)) XPUSHs(sv_2mortal(newSVpv("objsign",0))); if (ASN1_BIT_STRING_get_bit(u,4)) XPUSHs(sv_2mortal(newSVpv("reserved",0))); if (ASN1_BIT_STRING_get_bit(u,5)) XPUSHs(sv_2mortal(newSVpv("sslCA",0))); if (ASN1_BIT_STRING_get_bit(u,6)) XPUSHs(sv_2mortal(newSVpv("emailCA",0))); if (ASN1_BIT_STRING_get_bit(u,7)) XPUSHs(sv_2mortal(newSVpv("objCA",0))); } int X509_get_ext_by_NID(x,nid,loc=-1) X509* x int nid int loc X509_EXTENSION * X509_get_ext(x,loc) X509* x int loc int X509_EXTENSION_get_critical(X509_EXTENSION *ex) ASN1_OCTET_STRING * X509_EXTENSION_get_data(X509_EXTENSION *ne) ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex) int X509_get_ext_count(X509 *x) int X509_CRL_get_ext_count(X509_CRL *x) int X509_CRL_get_ext_by_NID(x,ni,loc=-1) X509_CRL* x int ni int loc X509_EXTENSION * X509_CRL_get_ext(x,loc) X509_CRL* x int loc void X509V3_EXT_print(ext,flags=0,utf8_decode=0) X509_EXTENSION * ext unsigned long flags int utf8_decode PREINIT: BIO * bp; char * buf; int i, n; int indent=0; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp) { if(X509V3_EXT_print(bp,ext,flags,indent)) { n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) { sv_setpvn(ST(0), buf, i); if (utf8_decode) sv_utf8_decode(ST(0)); } Safefree(buf); } } BIO_free(bp); } void * X509V3_EXT_d2i(ext) X509_EXTENSION *ext X509_STORE_CTX * X509_STORE_CTX_new() int X509_STORE_CTX_init(ctx, store=NULL, x509=NULL, chain=NULL) X509_STORE_CTX * ctx X509_STORE * store X509 * x509 STACK_OF(X509) * chain void X509_STORE_CTX_free(ctx) X509_STORE_CTX * ctx int X509_verify_cert(x509_store_ctx) X509_STORE_CTX * x509_store_ctx int X509_STORE_CTX_get_error(x509_store_ctx) X509_STORE_CTX * x509_store_ctx int X509_STORE_CTX_get_error_depth(x509_store_ctx) X509_STORE_CTX * x509_store_ctx int X509_STORE_CTX_set_ex_data(x509_store_ctx,idx,data) X509_STORE_CTX * x509_store_ctx int idx void * data int X509_STORE_CTX_set_app_data(x509_store_ctx,arg) X509_STORE_CTX * x509_store_ctx char * arg CODE: RETVAL = X509_STORE_CTX_set_ex_data(x509_store_ctx,0,arg); OUTPUT: RETVAL void X509_STORE_CTX_set_error(x509_store_ctx,s) X509_STORE_CTX * x509_store_ctx int s void X509_STORE_CTX_set_cert(x509_store_ctx,x) X509_STORE_CTX * x509_store_ctx X509 * x X509_STORE * X509_STORE_new() void X509_STORE_free(store) X509_STORE * store X509_LOOKUP * X509_STORE_add_lookup(store, method) X509_STORE * store X509_LOOKUP_METHOD * method int X509_STORE_add_cert(ctx, x) X509_STORE *ctx X509 *x int X509_STORE_add_crl(ctx, x) X509_STORE *ctx X509_CRL *x #if OPENSSL_VERSION_NUMBER >= 0x0090800fL void X509_STORE_set_flags(ctx, flags) X509_STORE *ctx long flags void X509_STORE_set_purpose(ctx, purpose) X509_STORE *ctx int purpose void X509_STORE_set_trust(ctx, trust) X509_STORE *ctx int trust int X509_STORE_set1_param(ctx, pm) X509_STORE *ctx X509_VERIFY_PARAM *pm #endif X509_LOOKUP_METHOD * X509_LOOKUP_hash_dir() void X509_LOOKUP_add_dir(lookup, dir, type) X509_LOOKUP * lookup char * dir int type int X509_load_cert_file(ctx, file, type) X509_LOOKUP *ctx char *file int type int X509_load_crl_file(ctx, file, type) X509_LOOKUP *ctx char *file int type int X509_load_cert_crl_file(ctx, file, type) X509_LOOKUP *ctx char *file int type const char * X509_verify_cert_error_string(n) long n ASN1_INTEGER * ASN1_INTEGER_new() void ASN1_INTEGER_free(ASN1_INTEGER *i) int ASN1_INTEGER_set(ASN1_INTEGER *i, long val) long ASN1_INTEGER_get(ASN1_INTEGER *a) void P_ASN1_INTEGER_set_hex(i,str) ASN1_INTEGER * i char * str INIT: BIGNUM *bn; int rv = 1; PPCODE: bn = BN_new(); if (!BN_hex2bn(&bn, str)) XSRETURN_IV(0); if (!BN_to_ASN1_INTEGER(bn, i)) rv = 0; BN_free(bn); XSRETURN_IV(rv); void P_ASN1_INTEGER_set_dec(i,str) ASN1_INTEGER * i char * str INIT: BIGNUM *bn; int rv = 1; PPCODE: bn = BN_new(); if (!BN_dec2bn(&bn, str)) XSRETURN_IV(0); if (!BN_to_ASN1_INTEGER(bn, i)) rv = 0; BN_free(bn); XSRETURN_IV(rv); void P_ASN1_INTEGER_get_hex(i) ASN1_INTEGER * i INIT: BIGNUM *bn; char *result; PPCODE: bn = BN_new(); if (!bn) XSRETURN_UNDEF; ASN1_INTEGER_to_BN(i, bn); result = BN_bn2hex(bn); BN_free(bn); if (!result) XSRETURN_UNDEF; XPUSHs(sv_2mortal(newSVpv((const char*)result, strlen(result)))); OPENSSL_free(result); void P_ASN1_INTEGER_get_dec(i) ASN1_INTEGER * i INIT: BIGNUM *bn; char *result; PPCODE: bn = BN_new(); if (!bn) XSRETURN_UNDEF; ASN1_INTEGER_to_BN(i, bn); result = BN_bn2dec(bn); BN_free(bn); if (!result) XSRETURN_UNDEF; XPUSHs(sv_2mortal(newSVpv((const char*)result, strlen(result)))); OPENSSL_free(result); void P_ASN1_STRING_get(s,utf8_decode=0) ASN1_STRING * s int utf8_decode PREINIT: SV * u8; PPCODE: u8 = newSVpv((const char*)ASN1_STRING_data(s), ASN1_STRING_length(s)); if (utf8_decode) sv_utf8_decode(u8); XPUSHs(sv_2mortal(u8)); ASN1_TIME * X509_get_notBefore(cert) X509 * cert ASN1_TIME * X509_get_notAfter(cert) X509 * cert ASN1_TIME * X509_gmtime_adj(s, adj) ASN1_TIME * s long adj ASN1_TIME * ASN1_TIME_set(s,t) ASN1_TIME *s time_t t void ASN1_TIME_free(s) ASN1_TIME *s time_t ASN1_TIME_timet(s) ASN1_TIME *s CODE: RETVAL = ASN1_TIME_timet(s,NULL); OUTPUT: RETVAL ASN1_TIME * ASN1_TIME_new() void P_ASN1_TIME_put2string(tm) ASN1_TIME * tm PREINIT: BIO *bp=NULL; int i=0; char buffer[256]; ALIAS: P_ASN1_UTCTIME_put2string = 1 CODE: ST(0) = sv_newmortal(); /* undef retval to start with */ if (tm) { bp = BIO_new(BIO_s_mem()); if (bp) { ASN1_TIME_print(bp,tm); i = BIO_read(bp,buffer,255); buffer[i] = '\0'; if (i>0) sv_setpvn(ST(0), buffer, i); BIO_free(bp); } } #if OPENSSL_VERSION_NUMBER >= 0x0090705f #define REM15 "NOTE: requires 0.9.7e+" void P_ASN1_TIME_get_isotime(tm) ASN1_TIME *tm PREINIT: ASN1_GENERALIZEDTIME *tmp = NULL; char buf[256]; CODE: buf[0] = '\0'; /* ASN1_TIME_to_generalizedtime is buggy on pre-0.9.7e */ ASN1_TIME_to_generalizedtime(tm,&tmp); if (tmp) { if (ASN1_GENERALIZEDTIME_check(tmp)) { if (strlen((char*)tmp->data)>=14 && strlen((char*)tmp->data)<200) { strcpy (buf,"yyyy-mm-ddThh:mm:ss"); strncpy(buf, (char*)tmp->data, 4); strncpy(buf+5, (char*)tmp->data+4, 2); strncpy(buf+8, (char*)tmp->data+6, 2); strncpy(buf+11,(char*)tmp->data+8, 2); strncpy(buf+14,(char*)tmp->data+10,2); strncpy(buf+17,(char*)tmp->data+12,2); if (strlen((char*)tmp->data)>14) strcat(buf+19,(char*)tmp->data+14); } } ASN1_GENERALIZEDTIME_free(tmp); } ST(0) = sv_newmortal(); sv_setpv(ST(0), buf); void P_ASN1_TIME_set_isotime(tm,str) ASN1_TIME *tm const char *str PREINIT: ASN1_TIME t; char buf[256]; int i,rv; CODE: if (!tm) XSRETURN_UNDEF; /* we support only "2012-03-22T23:55:33" or "2012-03-22T23:55:33Z" or "2012-03-22T23:55:33" */ if (strlen(str) < 19) XSRETURN_UNDEF; for (i=0; i<4; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; for (i=5; i<7; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; for (i=8; i<10; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; for (i=11; i<13; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; for (i=14; i<16; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; for (i=17; i<19; i++) if ((str[i] > '9') || (str[i] < '0')) XSRETURN_UNDEF; strncpy(buf, str, 4); strncpy(buf+4, str+5, 2); strncpy(buf+6, str+8, 2); strncpy(buf+8, str+11, 2); strncpy(buf+10, str+14, 2); strncpy(buf+12, str+17, 2); buf[14] = '\0'; if (strlen(str)>19 && strlen(str)<200) strcat(buf,str+19); /* WORKAROUND: ASN1_TIME_set_string() not available in 0.9.8 !!!*/ /* in 1.0.0 we would simply: rv = ASN1_TIME_set_string(tm,buf); */ t.length = strlen(buf); t.data = (unsigned char *)buf; t.flags = 0; t.type = V_ASN1_UTCTIME; if (!ASN1_TIME_check(&t)) { t.type = V_ASN1_GENERALIZEDTIME; if (!ASN1_TIME_check(&t)) XSRETURN_UNDEF; } tm->type = t.type; tm->flags = t.flags; if (!ASN1_STRING_set(tm,t.data,t.length)) XSRETURN_UNDEF; rv = 1; /* end of ASN1_TIME_set_string() reimplementation */ ST(0) = sv_newmortal(); sv_setiv(ST(0), rv); /* 1 = success, undef = failure */ #endif int EVP_PKEY_copy_parameters(to,from) EVP_PKEY * to EVP_PKEY * from EVP_PKEY * EVP_PKEY_new() void EVP_PKEY_free(EVP_PKEY *pkey) int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) int EVP_PKEY_bits(EVP_PKEY *pkey) int EVP_PKEY_size(EVP_PKEY *pkey) #if OPENSSL_VERSION_NUMBER >= 0x1000000fL int EVP_PKEY_id(const EVP_PKEY *pkey) #endif void PEM_get_string_X509(x509) X509 * x509 PREINIT: BIO *bp; int i, n; char *buf; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp && x509) { PEM_write_bio_X509(bp,x509); n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) sv_setpvn(ST(0), buf, i); Safefree(buf); } BIO_free(bp); } void PEM_get_string_X509_REQ(x509_req) X509_REQ * x509_req PREINIT: BIO *bp; int i, n; char *buf; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp && x509_req) { PEM_write_bio_X509_REQ(bp,x509_req); n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) sv_setpvn(ST(0), buf, i); Safefree(buf); } BIO_free(bp); } void PEM_get_string_X509_CRL(x509_crl) X509_CRL * x509_crl PREINIT: BIO *bp; int i, n; char *buf; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp && x509_crl) { PEM_write_bio_X509_CRL(bp,x509_crl); n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) sv_setpvn(ST(0), buf, i); Safefree(buf); } BIO_free(bp); } void PEM_get_string_PrivateKey(pk,passwd=NULL,enc_alg=NULL) EVP_PKEY * pk char * passwd const EVP_CIPHER * enc_alg PREINIT: BIO *bp; int i, n; char *buf; size_t passwd_len = 0; pem_password_cb * cb = NULL; void * u = NULL; CODE: ST(0) = sv_newmortal(); /* undef to start with */ bp = BIO_new(BIO_s_mem()); if (bp && pk) { if (passwd) passwd_len = strlen(passwd); if (passwd_len>0) { /* encrypted key */ if (!enc_alg) PEM_write_bio_PrivateKey(bp,pk,EVP_des_cbc(),(unsigned char *)passwd,passwd_len,cb,u); else PEM_write_bio_PrivateKey(bp,pk,enc_alg,(unsigned char *)passwd,passwd_len,cb,u); } else { /* unencrypted key */ PEM_write_bio_PrivateKey(bp,pk,NULL,(unsigned char *)passwd,passwd_len,cb,u); } n = BIO_ctrl_pending(bp); New(0, buf, n, char); if (buf) { i = BIO_read(bp,buf,n); if (i>=0 && i<=n) sv_setpvn(ST(0), buf, i); Safefree(buf); } BIO_free(bp); } int CTX_use_PKCS12_file(ctx, file, password=NULL) SSL_CTX *ctx char *file char *password PREINIT: PKCS12 *p12; EVP_PKEY *private_key; X509 *certificate; FILE *fp; CODE: RETVAL = 0; if ((fp = fopen (file, "rb"))) { #if OPENSSL_VERSION_NUMBER >= 0x0090700fL OPENSSL_add_all_algorithms_noconf(); #else OpenSSL_add_all_algorithms(); #endif if ((p12 = d2i_PKCS12_fp(fp, NULL))) { if (PKCS12_parse(p12, password, &private_key, &certificate, NULL)) { if (private_key) { if (SSL_CTX_use_PrivateKey(ctx, private_key)) RETVAL = 1; EVP_PKEY_free(private_key); } if (certificate) { if (SSL_CTX_use_certificate(ctx, certificate)) RETVAL = 1; X509_free(certificate); } } PKCS12_free(p12); } if (!RETVAL) ERR_print_errors_fp(stderr); fclose(fp); } OUTPUT: RETVAL void P_PKCS12_load_file(file, load_chain=0, password=NULL) char *file int load_chain char *password PREINIT: PKCS12 *p12; EVP_PKEY *private_key = NULL; X509 *certificate = NULL; STACK_OF(X509) *cachain = NULL; X509 *x; FILE *fp; int i, result; PPCODE: if ((fp = fopen (file, "rb"))) { #if OPENSSL_VERSION_NUMBER >= 0x0090700fL OPENSSL_add_all_algorithms_noconf(); #else OpenSSL_add_all_algorithms(); #endif if ((p12 = d2i_PKCS12_fp(fp, NULL))) { if(load_chain) result= PKCS12_parse(p12, password, &private_key, &certificate, &cachain); else result= PKCS12_parse(p12, password, &private_key, &certificate, NULL); if (result) { if (private_key) XPUSHs(sv_2mortal(newSViv(PTR2IV(private_key)))); else XPUSHs(sv_2mortal(newSVpv(NULL,0))); /* undef */ if (certificate) XPUSHs(sv_2mortal(newSViv(PTR2IV(certificate)))); else XPUSHs(sv_2mortal(newSVpv(NULL,0))); /* undef */ if (cachain) { for (i=0; i= 0x00905000L void RIPEMD160(data) PREINIT: STRLEN len; unsigned char md[RIPEMD160_DIGEST_LENGTH]; INPUT: unsigned char * data = (unsigned char *) SvPV( ST(0), len); CODE: if (RIPEMD160(data,len,md)) { XSRETURN_PVN((char *) md, RIPEMD160_DIGEST_LENGTH); } else { XSRETURN_UNDEF; } #endif #if !defined(OPENSSL_NO_SHA) void SHA1(data) PREINIT: STRLEN len; unsigned char md[SHA_DIGEST_LENGTH]; INPUT: unsigned char * data = (unsigned char *) SvPV( ST(0), len); CODE: if (SHA1(data,len,md)) { XSRETURN_PVN((char *) md, SHA_DIGEST_LENGTH); } else { XSRETURN_UNDEF; } #endif #if !defined(OPENSSL_NO_SHA256) && OPENSSL_VERSION_NUMBER >= 0x0090800fL void SHA256(data) PREINIT: STRLEN len; unsigned char md[SHA256_DIGEST_LENGTH]; INPUT: unsigned char * data = (unsigned char *) SvPV( ST(0), len); CODE: if (SHA256(data,len,md)) { XSRETURN_PVN((char *) md, SHA256_DIGEST_LENGTH); } else { XSRETURN_UNDEF; } #endif #if !defined(OPENSSL_NO_SHA512) && OPENSSL_VERSION_NUMBER >= 0x0090800fL void SHA512(data) PREINIT: STRLEN len; unsigned char md[SHA512_DIGEST_LENGTH]; INPUT: unsigned char * data = (unsigned char *) SvPV( ST(0), len); CODE: if (SHA512(data,len,md)) { XSRETURN_PVN((char *) md, SHA512_DIGEST_LENGTH); } else { XSRETURN_UNDEF; } #endif #ifndef OPENSSL_NO_SSL2 #if OPENSSL_VERSION_NUMBER < 0x10000000L const SSL_METHOD * SSLv2_method() #endif #endif #ifndef OPENSSL_NO_SSL3 const SSL_METHOD * SSLv3_method() #endif const SSL_METHOD * SSLv23_method() const SSL_METHOD * SSLv23_server_method() const SSL_METHOD * SSLv23_client_method() const SSL_METHOD * TLSv1_method() const SSL_METHOD * TLSv1_server_method() const SSL_METHOD * TLSv1_client_method() #ifdef SSL_TXT_TLSV1_1 const SSL_METHOD * TLSv1_1_method() const SSL_METHOD * TLSv1_1_server_method() const SSL_METHOD * TLSv1_1_client_method() #endif #ifdef SSL_TXT_TLSV1_2 const SSL_METHOD * TLSv1_2_method() const SSL_METHOD * TLSv1_2_server_method() const SSL_METHOD * TLSv1_2_client_method() #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x20020002L) const SSL_METHOD * TLS_method() const SSL_METHOD * TLS_server_method() const SSL_METHOD * TLS_client_method() #endif /* OpenSSL 1.1.0 or LibreSSL 2.2.2 */ #if (OPENSSL_VERSION_NUMBER >= 0x10100002L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2060000fL) int SSL_CTX_set_min_proto_version(ctx, version) SSL_CTX * ctx int version int SSL_CTX_set_max_proto_version(ctx, version) SSL_CTX * ctx int version int SSL_set_min_proto_version(ssl, version) SSL * ssl int version int SSL_set_max_proto_version(ssl, version) SSL * ssl int version #endif /* OpenSSL 1.1.0-pre2 or LibreSSL 2.6.0 */ #if OPENSSL_VERSION_NUMBER >= 0x1010007fL && !defined(LIBRESSL_VERSION_NUMBER) int SSL_CTX_get_min_proto_version(ctx) SSL_CTX * ctx int SSL_CTX_get_max_proto_version(ctx) SSL_CTX * ctx int SSL_get_min_proto_version(ssl) SSL * ssl int SSL_get_max_proto_version(ssl) SSL * ssl #endif /* OpenSSL 1.1.0g */ #if OPENSSL_VERSION_NUMBER < 0x10000000L int SSL_set_ssl_method(ssl, method) SSL * ssl SSL_METHOD * method #else int SSL_set_ssl_method(ssl, method) SSL * ssl const SSL_METHOD * method #endif const SSL_METHOD * SSL_get_ssl_method(ssl) SSL * ssl #define REM_AUTOMATICALLY_GENERATED_1_09 BIO * BIO_new_buffer_ssl_connect(ctx) SSL_CTX * ctx BIO * BIO_new_file(filename,mode) char * filename char * mode BIO * BIO_new_ssl(ctx,client) SSL_CTX * ctx int client BIO * BIO_new_ssl_connect(ctx) SSL_CTX * ctx BIO * BIO_new(type) BIO_METHOD * type; int BIO_free(bio) BIO * bio; void BIO_read(s,max=32768) BIO * s int max PREINIT: char *buf = NULL; int got; CODE: New(0, buf, max, char); ST(0) = sv_newmortal(); /* Undefined to start with */ if ((got = BIO_read(s, buf, max)) >= 0) sv_setpvn( ST(0), buf, got); Safefree(buf); int BIO_write(s,buf) BIO * s PREINIT: STRLEN len; INPUT: char * buf = SvPV( ST(1), len); CODE: RETVAL = BIO_write (s, buf, (int)len); OUTPUT: RETVAL int BIO_eof(s) BIO * s int BIO_pending(s) BIO * s int BIO_wpending(s) BIO * s int BIO_ssl_copy_session_id(to,from) BIO * to BIO * from void BIO_ssl_shutdown(ssl_bio) BIO * ssl_bio int SSL_add_client_CA(ssl,x) SSL * ssl X509 * x const char * SSL_alert_desc_string(value) int value const char * SSL_alert_desc_string_long(value) int value const char * SSL_alert_type_string(value) int value const char * SSL_alert_type_string_long(value) int value long SSL_callback_ctrl(ssl,i,fp) SSL * ssl int i callback_no_ret * fp int SSL_check_private_key(ctx) SSL * ctx # /* buf and size were required with Net::SSLeay 1.88 and earlier. */ # /* With OpenSSL 0.9.8l and older compile can warn about discarded const. */ void SSL_CIPHER_description(const SSL_CIPHER *cipher, char *unused_buf=NULL, int unused_size=0) PREINIT: char *description; char buf[512]; PPCODE: description = SSL_CIPHER_description(cipher, buf, sizeof(buf)); if(description == NULL) { XSRETURN_EMPTY; } XPUSHs(sv_2mortal(newSVpv(description, 0))); const char * SSL_CIPHER_get_name(const SSL_CIPHER *c) int SSL_CIPHER_get_bits(c, ...) const SSL_CIPHER * c CODE: int alg_bits; RETVAL = SSL_CIPHER_get_bits(c, &alg_bits); if (items > 2) croak("SSL_CIPHER_get_bits: Need to call with one or two parameters"); if (items > 1) sv_setsv(ST(1), sv_2mortal(newSViv(alg_bits))); OUTPUT: RETVAL const char * SSL_CIPHER_get_version(const SSL_CIPHER *cipher) #ifndef OPENSSL_NO_COMP int SSL_COMP_add_compression_method(id,cm) int id COMP_METHOD * cm #endif int SSL_CTX_add_client_CA(ctx,x) SSL_CTX * ctx X509 * x long SSL_CTX_callback_ctrl(ctx,i,fp) SSL_CTX * ctx int i callback_no_ret * fp int SSL_CTX_check_private_key(ctx) SSL_CTX * ctx void * SSL_CTX_get_ex_data(ssl,idx) SSL_CTX * ssl int idx int SSL_CTX_get_quiet_shutdown(ctx) SSL_CTX * ctx long SSL_CTX_get_timeout(ctx) SSL_CTX * ctx int SSL_CTX_get_verify_depth(ctx) SSL_CTX * ctx int SSL_CTX_get_verify_mode(ctx) SSL_CTX * ctx void SSL_CTX_set_cert_store(ctx,store) SSL_CTX * ctx X509_STORE * store X509_STORE * SSL_CTX_get_cert_store(ctx) SSL_CTX * ctx void SSL_CTX_set_cert_verify_callback(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_cert_verify_callback(ctx, NULL, NULL); cb_data_advanced_put(ctx, "ssleay_ctx_cert_verify_cb!!func", NULL); cb_data_advanced_put(ctx, "ssleay_ctx_cert_verify_cb!!data", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_cert_verify_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "ssleay_ctx_cert_verify_cb!!data", newSVsv(data)); #if OPENSSL_VERSION_NUMBER >= 0x0090700fL SSL_CTX_set_cert_verify_callback(ctx, ssleay_ctx_cert_verify_cb_invoke, ctx); #else SSL_CTX_set_cert_verify_callback(ctx, ssleay_ctx_cert_verify_cb_invoke, (char*)ctx); #endif } X509_NAME_STACK * SSL_CTX_get_client_CA_list(ctx) SSL_CTX *ctx void SSL_CTX_set_client_CA_list(ctx,list) SSL_CTX * ctx X509_NAME_STACK * list void SSL_CTX_set_default_passwd_cb(ctx,callback=&PL_sv_undef) SSL_CTX * ctx SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_default_passwd_cb(ctx, NULL); SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ctx_passwd_cb!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_passwd_cb!!func", newSVsv(callback)); SSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)ctx); SSL_CTX_set_default_passwd_cb(ctx, &ssleay_ctx_passwd_cb_invoke); } void SSL_CTX_set_default_passwd_cb_userdata(ctx,data=&PL_sv_undef) SSL_CTX * ctx SV * data CODE: /* SSL_CTX_set_default_passwd_cb_userdata is set in SSL_CTX_set_default_passwd_cb */ if (data==NULL || !SvOK(data)) { cb_data_advanced_put(ctx, "ssleay_ctx_passwd_cb!!data", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_passwd_cb!!data", newSVsv(data)); } int SSL_CTX_set_ex_data(ssl,idx,data) SSL_CTX * ssl int idx void * data int SSL_CTX_set_purpose(s,purpose) SSL_CTX * s int purpose void SSL_CTX_set_quiet_shutdown(ctx,mode) SSL_CTX * ctx int mode #if OPENSSL_VERSION_NUMBER < 0x10000000L int SSL_CTX_set_ssl_version(ctx,meth) SSL_CTX * ctx SSL_METHOD * meth #else int SSL_CTX_set_ssl_version(ctx,meth) SSL_CTX * ctx const SSL_METHOD * meth #endif long SSL_CTX_set_timeout(ctx,t) SSL_CTX * ctx long t int SSL_CTX_set_trust(s,trust) SSL_CTX * s int trust void SSL_CTX_set_verify_depth(ctx,depth) SSL_CTX * ctx int depth int SSL_CTX_use_certificate(ctx,x) SSL_CTX * ctx X509 * x int SSL_CTX_use_certificate_chain_file(ctx,file) SSL_CTX * ctx const char * file #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) int SSL_use_certificate_chain_file(ssl,file) SSL * ssl const char * file #endif /* OpenSSL 1.1.0 */ int SSL_CTX_use_PrivateKey(ctx,pkey) SSL_CTX * ctx EVP_PKEY * pkey int SSL_CTX_use_RSAPrivateKey(ctx,rsa) SSL_CTX * ctx RSA * rsa int SSL_do_handshake(s) SSL * s SSL * SSL_dup(ssl) SSL * ssl const SSL_CIPHER * SSL_get_current_cipher(s) SSL * s long SSL_get_default_timeout(s) SSL * s void * SSL_get_ex_data(ssl,idx) SSL * ssl int idx size_t SSL_get_finished(ssl,buf,count=2*EVP_MAX_MD_SIZE) SSL *ssl SV *buf size_t count PREINIT: unsigned char *finished; size_t finished_len; CODE: Newx(finished, count, unsigned char); finished_len = SSL_get_finished(ssl, finished, count); if (count > finished_len) count = finished_len; sv_setpvn(buf, (const char *)finished, count); Safefree(finished); RETVAL = finished_len; OUTPUT: RETVAL size_t SSL_get_peer_finished(ssl,buf,count=2*EVP_MAX_MD_SIZE) SSL *ssl SV *buf size_t count PREINIT: unsigned char *finished; size_t finished_len; CODE: Newx(finished, count, unsigned char); finished_len = SSL_get_peer_finished(ssl, finished, count); if (count > finished_len) count = finished_len; sv_setpvn(buf, (const char *)finished, count); Safefree(finished); RETVAL = finished_len; OUTPUT: RETVAL int SSL_get_quiet_shutdown(ssl) SSL * ssl int SSL_get_shutdown(ssl) SSL * ssl int SSL_get_verify_depth(s) SSL * s int SSL_get_verify_mode(s) SSL * s long SSL_get_verify_result(ssl) SSL * ssl int SSL_renegotiate(s) SSL * s #if OPENSSL_VERSION_NUMBER < 0x10000000L int SSL_SESSION_cmp(a,b) SSL_SESSION * a SSL_SESSION * b #endif void * SSL_SESSION_get_ex_data(ss,idx) SSL_SESSION * ss int idx long SSL_SESSION_get_time(s) SSL_SESSION * s long SSL_SESSION_get_timeout(s) SSL_SESSION * s int SSL_SESSION_print_fp(fp,ses) FILE * fp SSL_SESSION * ses int SSL_SESSION_set_ex_data(ss,idx,data) SSL_SESSION * ss int idx void * data long SSL_SESSION_set_time(s,t) SSL_SESSION * s long t long SSL_SESSION_set_timeout(s,t) SSL_SESSION * s long t void SSL_set_accept_state(s) SSL * s void sk_X509_NAME_free(sk) X509_NAME_STACK *sk int sk_X509_NAME_num(sk) X509_NAME_STACK *sk X509_NAME * sk_X509_NAME_value(sk,i) X509_NAME_STACK *sk int i X509_NAME_STACK * SSL_get_client_CA_list(s) SSL * s void SSL_set_client_CA_list(s,list) SSL * s X509_NAME_STACK * list void SSL_set_connect_state(s) SSL * s int SSL_set_ex_data(ssl,idx,data) SSL * ssl int idx void * data void SSL_set_info_callback(ssl,callback,data=&PL_sv_undef) SSL * ssl SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_set_info_callback(ssl, NULL); cb_data_advanced_put(ssl, "ssleay_info_cb!!func", NULL); cb_data_advanced_put(ssl, "ssleay_info_cb!!data", NULL); } else { cb_data_advanced_put(ssl, "ssleay_info_cb!!func", newSVsv(callback)); cb_data_advanced_put(ssl, "ssleay_info_cb!!data", newSVsv(data)); SSL_set_info_callback(ssl, ssleay_info_cb_invoke); } void SSL_CTX_set_info_callback(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_info_callback(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ctx_info_cb!!func", NULL); cb_data_advanced_put(ctx, "ssleay_ctx_info_cb!!data", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_info_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "ssleay_ctx_info_cb!!data", newSVsv(data)); SSL_CTX_set_info_callback(ctx, ssleay_ctx_info_cb_invoke); } void SSL_set_msg_callback(ssl,callback,data=&PL_sv_undef) SSL * ssl SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_set_msg_callback(ssl, NULL); cb_data_advanced_put(ssl, "ssleay_msg_cb!!func", NULL); cb_data_advanced_put(ssl, "ssleay_msg_cb!!data", NULL); } else { cb_data_advanced_put(ssl, "ssleay_msg_cb!!func", newSVsv(callback)); cb_data_advanced_put(ssl, "ssleay_msg_cb!!data", newSVsv(data)); SSL_set_msg_callback(ssl, ssleay_msg_cb_invoke); } void SSL_CTX_set_msg_callback(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_msg_callback(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ctx_msg_cb!!func", NULL); cb_data_advanced_put(ctx, "ssleay_ctx_msg_cb!!data", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_msg_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "ssleay_ctx_msg_cb!!data", newSVsv(data)); SSL_CTX_set_msg_callback(ctx, ssleay_ctx_msg_cb_invoke); } #if OPENSSL_VERSION_NUMBER >= 0x10101001 && !defined(LIBRESSL_VERSION_NUMBER) void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SV *callback) CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_keylog_callback(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ssl_ctx_keylog_callback!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ssl_ctx_keylog_callback!!func", newSVsv(callback)); SSL_CTX_set_keylog_callback(ctx, ssl_ctx_keylog_cb_func_invoke); } SV * SSL_CTX_get_keylog_callback(const SSL_CTX *ctx) CODE: SV *func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_keylog_callback!!func"); /* without increment the reference will go away and ssl_ctx_keylog_cb_func_invoke croaks */ SvREFCNT_inc(func); RETVAL = func; OUTPUT: RETVAL #endif int SSL_set_purpose(s,purpose) SSL * s int purpose void SSL_set_quiet_shutdown(ssl,mode) SSL * ssl int mode void SSL_set_shutdown(ssl,mode) SSL * ssl int mode int SSL_set_trust(s,trust) SSL * s int trust void SSL_set_verify_depth(s,depth) SSL * s int depth void SSL_set_verify_result(ssl,v) SSL * ssl long v int SSL_shutdown(s) SSL * s const char * SSL_get_version(ssl) const SSL * ssl int SSL_version(ssl) SSL * ssl #if OPENSSL_VERSION_NUMBER >= 0x10100006L && !defined(LIBRESSL_VERSION_NUMBER) /* 1.1.0-pre6 */ int SSL_client_version(ssl) const SSL * ssl int SSL_is_dtls(ssl) const SSL * ssl #endif #define REM_MANUALLY_ADDED_1_09 X509_NAME_STACK * SSL_load_client_CA_file(file) const char * file int SSL_add_file_cert_subjects_to_stack(stackCAs,file) X509_NAME_STACK * stackCAs const char * file #ifndef WIN32 #ifndef VMS #ifndef MAC_OS_pre_X int SSL_add_dir_cert_subjects_to_stack(stackCAs,dir) X509_NAME_STACK * stackCAs const char * dir #endif #endif #endif int SSL_CTX_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL) long argl void * argp CRYPTO_EX_new * new_func CRYPTO_EX_dup * dup_func CRYPTO_EX_free * free_func int SSL_CTX_set_session_id_context(ctx,sid_ctx,sid_ctx_len) SSL_CTX * ctx const unsigned char * sid_ctx unsigned int sid_ctx_len int SSL_set_session_id_context(ssl,sid_ctx,sid_ctx_len) SSL * ssl const unsigned char * sid_ctx unsigned int sid_ctx_len #if OPENSSL_VERSION_NUMBER < 0x10100000L void SSL_CTX_set_tmp_rsa_callback(ctx, cb) SSL_CTX * ctx cb_ssl_int_int_ret_RSA * cb void SSL_set_tmp_rsa_callback(ssl, cb) SSL * ssl cb_ssl_int_int_ret_RSA * cb #endif void SSL_CTX_set_tmp_dh_callback(ctx, dh) SSL_CTX * ctx cb_ssl_int_int_ret_DH * dh void SSL_set_tmp_dh_callback(ssl,dh) SSL * ssl cb_ssl_int_int_ret_DH * dh int SSL_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL) long argl void * argp CRYPTO_EX_new * new_func CRYPTO_EX_dup * dup_func CRYPTO_EX_free * free_func int SSL_SESSION_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL) long argl void * argp CRYPTO_EX_new * new_func CRYPTO_EX_dup * dup_func CRYPTO_EX_free * free_func #define REM_SEMIAUTOMATIC_MACRO_GEN_1_09 long SSL_clear_num_renegotiations(ssl) SSL * ssl CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL); OUTPUT: RETVAL long SSL_CTX_add_extra_chain_cert(ctx,x509) SSL_CTX * ctx X509 * x509 CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char*)x509); OUTPUT: RETVAL void * SSL_CTX_get_app_data(ctx) SSL_CTX * ctx CODE: RETVAL = SSL_CTX_get_ex_data(ctx,0); OUTPUT: RETVAL long SSL_CTX_get_mode(ctx) SSL_CTX * ctx CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,0,NULL); OUTPUT: RETVAL long SSL_CTX_get_read_ahead(ctx) SSL_CTX * ctx CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL); OUTPUT: RETVAL long SSL_CTX_get_session_cache_mode(ctx) SSL_CTX * ctx CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL); OUTPUT: RETVAL #if OPENSSL_VERSION_NUMBER < 0x10100000L long SSL_CTX_need_tmp_RSA(ctx) SSL_CTX * ctx CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL); OUTPUT: RETVAL #endif int SSL_CTX_set_app_data(ctx,arg) SSL_CTX * ctx char * arg CODE: RETVAL = SSL_CTX_set_ex_data(ctx,0,arg); OUTPUT: RETVAL long SSL_CTX_set_mode(ctx,op) SSL_CTX * ctx long op CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,op,NULL); OUTPUT: RETVAL long SSL_CTX_set_read_ahead(ctx,m) SSL_CTX * ctx long m CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL); OUTPUT: RETVAL long SSL_CTX_set_session_cache_mode(ctx,m) SSL_CTX * ctx long m CODE: RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL); OUTPUT: RETVAL long SSL_CTX_set_tmp_dh(ctx,dh) SSL_CTX * ctx DH * dh #if OPENSSL_VERSION_NUMBER < 0x10100000L long SSL_CTX_set_tmp_rsa(ctx,rsa) SSL_CTX * ctx RSA * rsa #endif #if OPENSSL_VERSION_NUMBER > 0x10000000L && !defined OPENSSL_NO_EC EC_KEY * EC_KEY_new_by_curve_name(nid) int nid void EC_KEY_free(key) EC_KEY * key long SSL_CTX_set_tmp_ecdh(ctx,ecdh) SSL_CTX * ctx EC_KEY * ecdh int EVP_PKEY_assign_EC_KEY(pkey,key) EVP_PKEY * pkey EC_KEY * key EC_KEY * EC_KEY_generate_key(curve) SV *curve; CODE: EC_GROUP *group = NULL; EC_KEY *eckey = NULL; int nid; RETVAL = 0; if (SvIOK(curve)) { nid = SvIV(curve); } else { nid = OBJ_sn2nid(SvPV_nolen(curve)); #if OPENSSL_VERSION_NUMBER > 0x10002000L if (!nid) nid = EC_curve_nist2nid(SvPV_nolen(curve)); #endif if (!nid) croak("unknown curve %s",SvPV_nolen(curve)); } group = EC_GROUP_new_by_curve_name(nid); if (!group) croak("unknown curve nid=%d",nid); EC_GROUP_set_asn1_flag(group,OPENSSL_EC_NAMED_CURVE); eckey = EC_KEY_new(); if ( eckey && EC_KEY_set_group(eckey, group) && EC_KEY_generate_key(eckey)) { RETVAL = eckey; } else { if (eckey) EC_KEY_free(eckey); } if (group) EC_GROUP_free(group); OUTPUT: RETVAL #ifdef SSL_CTRL_SET_ECDH_AUTO long SSL_CTX_set_ecdh_auto(ctx,onoff) SSL_CTX * ctx int onoff long SSL_set_ecdh_auto(ssl,onoff) SSL * ssl int onoff #endif #ifdef SSL_CTRL_SET_CURVES_LIST long SSL_CTX_set1_curves_list(ctx,list) SSL_CTX * ctx char * list long SSL_set1_curves_list(ssl,list) SSL * ssl char * list #endif #if SSL_CTRL_SET_GROUPS_LIST long SSL_CTX_set1_groups_list(ctx,list) SSL_CTX * ctx char * list long SSL_set1_groups_list(ssl,list) SSL * ssl char * list #endif #endif void * SSL_get_app_data(s) SSL * s CODE: RETVAL = SSL_get_ex_data(s,0); OUTPUT: RETVAL int SSL_get_cipher_bits(s,np=NULL) SSL * s int * np CODE: RETVAL = SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np); OUTPUT: RETVAL long SSL_get_mode(ssl) SSL * ssl CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_MODE,0,NULL); OUTPUT: RETVAL void SSL_set_state(ssl,state) SSL * ssl int state CODE: #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* not available */ #elif defined(OPENSSL_NO_SSL_INTERN) SSL_set_state(ssl,state); #else ssl->state = state; #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L long SSL_need_tmp_RSA(ssl) SSL * ssl CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL); OUTPUT: RETVAL #endif long SSL_num_renegotiations(ssl) SSL * ssl CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL); OUTPUT: RETVAL void * SSL_SESSION_get_app_data(ses) SSL_SESSION * ses CODE: RETVAL = SSL_SESSION_get_ex_data(ses,0); OUTPUT: RETVAL long SSL_session_reused(ssl) SSL * ssl int SSL_SESSION_set_app_data(s,a) SSL_SESSION * s void * a CODE: RETVAL = SSL_SESSION_set_ex_data(s,0,(char *)a); OUTPUT: RETVAL int SSL_set_app_data(s,arg) SSL * s void * arg CODE: RETVAL = SSL_set_ex_data(s,0,(char *)arg); OUTPUT: RETVAL long SSL_set_mode(ssl,op) SSL * ssl long op CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_MODE,op,NULL); OUTPUT: RETVAL int SSL_set_pref_cipher(s,n) SSL * s const char * n CODE: RETVAL = SSL_set_cipher_list(s,n); OUTPUT: RETVAL long SSL_set_tmp_dh(ssl,dh) SSL * ssl DH * dh #if OPENSSL_VERSION_NUMBER < 0x10100000L long SSL_set_tmp_rsa(ssl,rsa) SSL * ssl char * rsa CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa); OUTPUT: RETVAL #endif #if OPENSSL_VERSION_NUMBER >= 0x0090800fL RSA * RSA_generate_key(bits,ee,perl_cb=&PL_sv_undef,perl_data=&PL_sv_undef) int bits unsigned long ee SV* perl_cb SV* perl_data PREINIT: simple_cb_data_t* cb_data = NULL; CODE: /* openssl 0.9.8 deprecated RSA_generate_key. */ /* This equivalent was contributed by Brian Fraser for Android, */ /* but was not portable to old OpenSSLs where RSA_generate_key_ex is not available. */ /* It should now be more versatile. */ /* as of openssl 1.1.0-pre1 it is not possible anymore to generate the BN_GENCB structure directly. */ /* instead BN_EGNCB_new() has to be used. */ int rc; RSA * ret; BIGNUM *e; e = BN_new(); if(!e) croak("Net::SSLeay: RSA_generate_key perl function could not create BN structure.\n"); BN_set_word(e, ee); cb_data = simple_cb_data_new(perl_cb, perl_data); ret = RSA_new(); if(!ret) { simple_cb_data_free(cb_data); BN_free(e); croak("Net::SSLeay: RSA_generate_key perl function could not create RSA structure.\n"); } #if (OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) BN_GENCB *new_cb; new_cb = BN_GENCB_new(); if(!new_cb) { simple_cb_data_free(cb_data); BN_free(e); RSA_free(ret); croak("Net::SSLeay: RSA_generate_key perl function could not create BN_GENCB structure.\n"); } BN_GENCB_set_old(new_cb, ssleay_RSA_generate_key_cb_invoke, cb_data); rc = RSA_generate_key_ex(ret, bits, e, new_cb); BN_GENCB_free(new_cb); #else BN_GENCB new_cb; BN_GENCB_set_old(&new_cb, ssleay_RSA_generate_key_cb_invoke, cb_data); rc = RSA_generate_key_ex(ret, bits, e, &new_cb); #endif simple_cb_data_free(cb_data); BN_free(e); if (rc == -1 || ret == NULL) { if (ret) RSA_free(ret); croak("Net::SSLeay: Couldn't generate RSA key"); } e = NULL; RETVAL = ret; OUTPUT: RETVAL #else RSA * RSA_generate_key(bits,e,perl_cb=&PL_sv_undef,perl_data=&PL_sv_undef) int bits unsigned long e SV* perl_cb SV* perl_data PREINIT: simple_cb_data_t* cb = NULL; CODE: cb = simple_cb_data_new(perl_cb, perl_data); RETVAL = RSA_generate_key(bits, e, ssleay_RSA_generate_key_cb_invoke, cb); simple_cb_data_free(cb); OUTPUT: RETVAL #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) void RSA_get_key_parameters(rsa) RSA * rsa PPCODE: { /* Caution: returned list consists of SV pointers to BIGNUMs, which would need to be blessed as Crypt::OpenSSL::Bignum for further use */ XPUSHs(bn2sv(rsa->n)); XPUSHs(bn2sv(rsa->e)); XPUSHs(bn2sv(rsa->d)); XPUSHs(bn2sv(rsa->p)); XPUSHs(bn2sv(rsa->q)); XPUSHs(bn2sv(rsa->dmp1)); XPUSHs(bn2sv(rsa->dmq1)); XPUSHs(bn2sv(rsa->iqmp)); } #endif void RSA_free(r) RSA * r X509 * X509_new() void X509_free(a) X509 * a X509_CRL * d2i_X509_CRL_bio(BIO *bp,void *unused=NULL) X509_REQ * d2i_X509_REQ_bio(BIO *bp,void *unused=NULL) X509 * d2i_X509_bio(BIO *bp,void *unused=NULL) DH * PEM_read_bio_DHparams(bio,x=NULL,cb=NULL,u=NULL) BIO * bio void * x pem_password_cb * cb void * u X509_CRL * PEM_read_bio_X509_CRL(bio,x=NULL,cb=NULL,u=NULL) BIO * bio void * x pem_password_cb * cb void * u X509 * PEM_read_bio_X509(BIO *bio,void *x=NULL,void *cb=NULL,void *u=NULL) STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(bio, stack=NULL, cb=NULL, u=NULL) BIO * bio STACK_OF(X509_INFO) * stack pem_password_cb * cb void * u int sk_X509_INFO_num(stack) STACK_OF(X509_INFO) * stack X509_INFO * sk_X509_INFO_value(stack, index) const STACK_OF(X509_INFO) * stack int index void sk_X509_INFO_free(stack) STACK_OF(X509_INFO) * stack STACK_OF(X509) * sk_X509_new_null() void sk_X509_free(stack) STACK_OF(X509) * stack int sk_X509_push(stack, data) STACK_OF(X509) * stack X509 * data X509 * sk_X509_pop(stack) STACK_OF(X509) * stack X509 * sk_X509_shift(stack) STACK_OF(X509) * stack int sk_X509_unshift(stack,x509) STACK_OF(X509) * stack X509 * x509 int sk_X509_insert(stack,x509,index) STACK_OF(X509) * stack X509 * x509 int index X509 * sk_X509_delete(stack,index) STACK_OF(X509) * stack int index X509 * sk_X509_value(stack,index) STACK_OF(X509) * stack int index int sk_X509_num(stack) STACK_OF(X509) * stack X509 * P_X509_INFO_get_x509(info) X509_INFO * info CODE: RETVAL = info->x509; OUTPUT: RETVAL X509_REQ * PEM_read_bio_X509_REQ(BIO *bio,void *x=NULL,pem_password_cb *cb=NULL,void *u=NULL) EVP_PKEY * PEM_read_bio_PrivateKey(bio,perl_cb=&PL_sv_undef,perl_data=&PL_sv_undef) BIO *bio SV* perl_cb SV* perl_data PREINIT: simple_cb_data_t* cb = NULL; CODE: RETVAL = 0; if (SvOK(perl_cb)) { /* setup our callback */ cb = simple_cb_data_new(perl_cb, perl_data); RETVAL = PEM_read_bio_PrivateKey(bio, NULL, pem_password_cb_invoke, (void*)cb); simple_cb_data_free(cb); } else if (!SvOK(perl_cb) && SvOK(perl_data) && SvPOK(perl_data)) { /* use perl_data as the password */ RETVAL = PEM_read_bio_PrivateKey(bio, NULL, NULL, SvPVX(perl_data)); } else if (!SvOK(perl_cb) && !SvOK(perl_data)) { /* will trigger default password callback */ RETVAL = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); } OUTPUT: RETVAL void DH_free(dh) DH * dh long SSL_total_renegotiations(ssl) SSL * ssl CODE: RETVAL = SSL_ctrl(ssl,SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL); OUTPUT: RETVAL #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) void SSL_SESSION_get_master_key(s) SSL_SESSION * s PREINIT: size_t master_key_length; unsigned char* master_key; CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ master_key_length = SSL_SESSION_get_master_key(s, 0, 0); /* get the length */ New(0, master_key, master_key_length, unsigned char); SSL_SESSION_get_master_key(s, master_key, master_key_length); sv_setpvn(ST(0), (const char*)master_key, master_key_length); Safefree(master_key); #else void SSL_SESSION_get_master_key(s) SSL_SESSION * s CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ sv_setpvn(ST(0), (const char*)s->master_key, s->master_key_length); #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L void SSL_SESSION_set_master_key(s,key) SSL_SESSION * s PREINIT: STRLEN len; INPUT: char * key = SvPV(ST(1), len); CODE: memcpy(s->master_key, key, len); s->master_key_length = len; #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) void SSL_get_client_random(s) SSL * s PREINIT: size_t random_length; unsigned char* random_data; CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ random_length = SSL_get_client_random(s, 0, 0); /* get the length */ New(0, random_data, random_length, unsigned char); SSL_get_client_random(s, random_data, random_length); sv_setpvn(ST(0), (const char*)random_data, random_length); Safefree(random_data); #else void SSL_get_client_random(s) SSL * s CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ sv_setpvn(ST(0), (const char*)s->s3->client_random, SSL3_RANDOM_SIZE); #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) void SSL_get_server_random(s) SSL * s PREINIT: size_t random_length; unsigned char* random_data; CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ random_length = SSL_get_server_random(s, 0, 0); /* get the length */ New(0, random_data, random_length, unsigned char); SSL_get_server_random(s, random_data, random_length); sv_setpvn(ST(0), (const char*)random_data, random_length); Safefree(random_data); #else void SSL_get_server_random(s) SSL * s CODE: ST(0) = sv_newmortal(); /* Undefined to start with */ sv_setpvn(ST(0), (const char*)s->s3->server_random, SSL3_RANDOM_SIZE); #endif int SSL_get_keyblock_size(s) SSL * s CODE: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) const SSL_CIPHER *ssl_cipher; int cipher = NID_undef, digest = NID_undef, mac_secret_size = 0; const EVP_CIPHER *c = NULL; const EVP_MD *h = NULL; ssl_cipher = SSL_get_current_cipher(s); if (ssl_cipher) cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher); if (cipher != NID_undef) c = EVP_get_cipherbynid(cipher); if (ssl_cipher) digest = SSL_CIPHER_get_digest_nid(ssl_cipher); if (digest != NID_undef) /* No digest if e.g., AEAD cipher */ h = EVP_get_digestbynid(digest); if (h) mac_secret_size = EVP_MD_size(h); RETVAL = -1; if (c) RETVAL = 2 * (EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c)); #else if (s == NULL || s->enc_read_ctx == NULL || s->enc_read_ctx->cipher == NULL || s->read_hash == NULL) { RETVAL = -1; } else { const EVP_CIPHER *c; const EVP_MD *h; int md_size = -1; c = s->enc_read_ctx->cipher; #if OPENSSL_VERSION_NUMBER >= 0x10001000L h = NULL; if (s->s3) md_size = s->s3->tmp.new_mac_secret_size; #elif OPENSSL_VERSION_NUMBER >= 0x00909000L h = EVP_MD_CTX_md(s->read_hash); md_size = EVP_MD_size(h); #else h = s->read_hash; md_size = EVP_MD_size(h); #endif /* No digest if e.g., AEAD cipher */ RETVAL = (md_size >= 0) ? (2 * (EVP_CIPHER_key_length(c) + md_size + EVP_CIPHER_iv_length(c))) : -1; } #endif OUTPUT: RETVAL #if defined(SSL_F_SSL_SET_HELLO_EXTENSION) int SSL_set_hello_extension(s, type, data) SSL * s int type PREINIT: STRLEN len; INPUT: char * data = SvPV( ST(2), len); CODE: RETVAL = SSL_set_hello_extension(s, type, data, len); OUTPUT: RETVAL #endif #if defined(SSL_F_SSL_SET_HELLO_EXTENSION) || defined(SSL_F_SSL_SET_SESSION_TICKET_EXT) void SSL_set_session_secret_cb(s,callback=&PL_sv_undef,data=&PL_sv_undef) SSL * s SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_set_session_secret_cb(s, NULL, NULL); cb_data_advanced_put(s, "ssleay_session_secret_cb!!func", NULL); cb_data_advanced_put(s, "ssleay_session_secret_cb!!data", NULL); } else { cb_data_advanced_put(s, "ssleay_session_secret_cb!!func", newSVsv(callback)); cb_data_advanced_put(s, "ssleay_session_secret_cb!!data", newSVsv(data)); SSL_set_session_secret_cb(s, (tls_session_secret_cb_fn)&ssleay_session_secret_cb_invoke, s); } #endif #ifdef NET_SSLEAY_CAN_PSK_CLIENT_CALLBACK void SSL_set_psk_client_callback(s,callback=&PL_sv_undef) SSL * s SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_set_psk_client_callback(s, NULL); cb_data_advanced_put(s, "ssleay_set_psk_client_callback!!func", NULL); } else { cb_data_advanced_put(s, "ssleay_set_psk_client_callback!!func", newSVsv(callback)); SSL_set_psk_client_callback(s, ssleay_set_psk_client_callback_invoke); } void SSL_CTX_set_psk_client_callback(ctx,callback=&PL_sv_undef) SSL_CTX * ctx SV * callback CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_psk_client_callback(ctx, NULL); cb_data_advanced_put(ctx, "ssleay_ctx_set_psk_client_callback!!func", NULL); } else { cb_data_advanced_put(ctx, "ssleay_ctx_set_psk_client_callback!!func", newSVsv(callback)); SSL_CTX_set_psk_client_callback(ctx, ssleay_ctx_set_psk_client_callback_invoke); } #endif #ifdef NET_SSLEAY_CAN_TICKET_KEY_CB void SSL_CTX_set_tlsext_ticket_getkey_cb(ctx,callback=&PL_sv_undef,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_tlsext_ticket_key_cb(ctx, NULL); cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!func", NULL); cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!data", NULL); } else { cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!data", newSVsv(data)); SSL_CTX_set_tlsext_ticket_key_cb(ctx, &tlsext_ticket_key_cb_invoke); } #endif #if OPENSSL_VERSION_NUMBER < 0x0090700fL #define REM11 "NOTE: before 0.9.7" int EVP_add_digest(EVP_MD *digest) #else int EVP_add_digest(const EVP_MD *digest) #endif #ifndef OPENSSL_NO_SHA const EVP_MD *EVP_sha1() #endif #if !defined(OPENSSL_NO_SHA256) && OPENSSL_VERSION_NUMBER >= 0x0090800fL const EVP_MD *EVP_sha256() #endif #if !defined(OPENSSL_NO_SHA512) && OPENSSL_VERSION_NUMBER >= 0x0090800fL const EVP_MD *EVP_sha512() #endif void OpenSSL_add_all_digests() const EVP_MD * EVP_get_digestbyname(const char *name) int EVP_MD_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) #if OPENSSL_VERSION_NUMBER >= 0x1000000fL SV* P_EVP_MD_list_all() INIT: AV * results; CODE: results = (AV *)sv_2mortal((SV *)newAV()); EVP_MD_do_all_sorted(handler_list_md_fn, results); RETVAL = newRV((SV *)results); OUTPUT: RETVAL #endif #if OPENSSL_VERSION_NUMBER >= 0x0090700fL #define REM16 "NOTE: requires 0.9.7+" const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) EVP_MD_CTX *EVP_MD_CTX_create() int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) void EVP_DigestUpdate(ctx,data) PREINIT: STRLEN len; INPUT: EVP_MD_CTX *ctx = INT2PTR(EVP_MD_CTX *, SvIV(ST(0))); unsigned char *data = (unsigned char *) SvPV(ST(1), len); CODE: XSRETURN_IV(EVP_DigestUpdate(ctx,data,len)); void EVP_DigestFinal(ctx) EVP_MD_CTX *ctx INIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; CODE: if (EVP_DigestFinal(ctx,md,&md_size)) XSRETURN_PVN((char *)md, md_size); else XSRETURN_UNDEF; void EVP_DigestFinal_ex(ctx) EVP_MD_CTX *ctx INIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; CODE: if (EVP_DigestFinal_ex(ctx,md,&md_size)) XSRETURN_PVN((char *)md, md_size); else XSRETURN_UNDEF; void EVP_Digest(...) PREINIT: STRLEN len; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; INPUT: unsigned char *data = (unsigned char *) SvPV(ST(0), len); EVP_MD *type = INT2PTR(EVP_MD *, SvIV(ST(1))); ENGINE *impl = (items>2 && SvOK(ST(2))) ? INT2PTR(ENGINE *, SvIV(ST(2))) : NULL; CODE: if (EVP_Digest(data,len,md,&md_size,type,impl)) XSRETURN_PVN((char *)md, md_size); else XSRETURN_UNDEF; #endif const EVP_CIPHER * EVP_get_cipherbyname(const char *name) void OpenSSL_add_all_algorithms() #if OPENSSL_VERSION_NUMBER >= 0x0090700fL void OPENSSL_add_all_algorithms_noconf() void OPENSSL_add_all_algorithms_conf() #endif #if OPENSSL_VERSION_NUMBER >= 0x10000003L int SSL_CTX_set1_param(ctx, vpm) SSL_CTX * ctx X509_VERIFY_PARAM *vpm int SSL_set1_param(ctx, vpm) SSL * ctx X509_VERIFY_PARAM *vpm #endif #if OPENSSL_VERSION_NUMBER >= 0x0090800fL X509_VERIFY_PARAM * X509_VERIFY_PARAM_new() void X509_VERIFY_PARAM_free(param) X509_VERIFY_PARAM *param int X509_VERIFY_PARAM_inherit(to, from) X509_VERIFY_PARAM *to X509_VERIFY_PARAM *from int X509_VERIFY_PARAM_set1(to, from) X509_VERIFY_PARAM *to X509_VERIFY_PARAM *from int X509_VERIFY_PARAM_set1_name(param, name) X509_VERIFY_PARAM *param const char *name int X509_VERIFY_PARAM_set_flags(param, flags) X509_VERIFY_PARAM *param unsigned long flags #if OPENSSL_VERSION_NUMBER >= 0x0090801fL #define REM13 "NOTE: requires 0.9.8a+" int X509_VERIFY_PARAM_clear_flags(param, flags) X509_VERIFY_PARAM *param unsigned long flags unsigned long X509_VERIFY_PARAM_get_flags(param) X509_VERIFY_PARAM *param #endif int X509_VERIFY_PARAM_set_purpose(param, purpose) X509_VERIFY_PARAM *param int purpose int X509_VERIFY_PARAM_set_trust(param, trust) X509_VERIFY_PARAM *param int trust void X509_VERIFY_PARAM_set_depth(param, depth) X509_VERIFY_PARAM *param int depth void X509_VERIFY_PARAM_set_time(param, t) X509_VERIFY_PARAM *param time_t t int X509_VERIFY_PARAM_add0_policy(param, policy) X509_VERIFY_PARAM *param ASN1_OBJECT *policy int X509_VERIFY_PARAM_set1_policies(param, policies) X509_VERIFY_PARAM *param STACK_OF(ASN1_OBJECT) *policies int X509_VERIFY_PARAM_get_depth(param) X509_VERIFY_PARAM *param int X509_VERIFY_PARAM_add0_table(param) X509_VERIFY_PARAM *param const X509_VERIFY_PARAM * X509_VERIFY_PARAM_lookup(name) const char *name void X509_VERIFY_PARAM_table_cleanup() #if (OPENSSL_VERSION_NUMBER >= 0x10002001L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) /* OpenSSL 1.0.2-beta1, LibreSSL 2.7.0 */ X509_VERIFY_PARAM * SSL_CTX_get0_param(ctx) SSL_CTX * ctx X509_VERIFY_PARAM * SSL_get0_param(ssl) SSL * ssl int X509_VERIFY_PARAM_set1_host(param, name) X509_VERIFY_PARAM *param PREINIT: STRLEN namelen; INPUT: const char * name = SvPV(ST(1), namelen); CODE: RETVAL = X509_VERIFY_PARAM_set1_host(param, name, namelen); OUTPUT: RETVAL int X509_VERIFY_PARAM_set1_email(param, email) X509_VERIFY_PARAM *param PREINIT: STRLEN emaillen; INPUT: const char * email = SvPV(ST(1), emaillen); CODE: RETVAL = X509_VERIFY_PARAM_set1_email(param, email, emaillen); OUTPUT: RETVAL int X509_VERIFY_PARAM_set1_ip(param, ip) X509_VERIFY_PARAM *param PREINIT: STRLEN iplen; INPUT: const unsigned char * ip = (const unsigned char *)SvPV(ST(1), iplen); CODE: RETVAL = X509_VERIFY_PARAM_set1_ip(param, ip, iplen); OUTPUT: RETVAL int X509_VERIFY_PARAM_set1_ip_asc(param, ipasc) X509_VERIFY_PARAM *param const char *ipasc #endif /* OpenSSL 1.0.2-beta1, LibreSSL 2.7.0 */ #if (OPENSSL_VERSION_NUMBER >= 0x10002002L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) /* OpenSSL 1.0.2-beta2, LibreSSL 2.7.0 */ int X509_VERIFY_PARAM_add1_host(param, name) X509_VERIFY_PARAM *param PREINIT: STRLEN namelen; INPUT: const char * name = SvPV(ST(1), namelen); CODE: RETVAL = X509_VERIFY_PARAM_add1_host(param, name, namelen); OUTPUT: RETVAL void X509_VERIFY_PARAM_set_hostflags(param, flags) X509_VERIFY_PARAM *param unsigned int flags char * X509_VERIFY_PARAM_get0_peername(param) X509_VERIFY_PARAM *param #endif /* OpenSSL 1.0.2-beta2, LibreSSL 2.7.0 */ void X509_policy_tree_free(tree) X509_POLICY_TREE *tree int X509_policy_tree_level_count(tree) X509_POLICY_TREE *tree X509_POLICY_LEVEL * X509_policy_tree_get0_level(tree, i) X509_POLICY_TREE *tree int i STACK_OF(X509_POLICY_NODE) * X509_policy_tree_get0_policies(tree) X509_POLICY_TREE *tree STACK_OF(X509_POLICY_NODE) * X509_policy_tree_get0_user_policies(tree) X509_POLICY_TREE *tree int X509_policy_level_node_count(level) X509_POLICY_LEVEL *level X509_POLICY_NODE * X509_policy_level_get0_node(level, i) X509_POLICY_LEVEL *level int i const ASN1_OBJECT * X509_policy_node_get0_policy(node) const X509_POLICY_NODE *node STACK_OF(POLICYQUALINFO) * X509_policy_node_get0_qualifiers(node) X509_POLICY_NODE *node const X509_POLICY_NODE * X509_policy_node_get0_parent(node) const X509_POLICY_NODE *node #endif ASN1_OBJECT * OBJ_dup(o) ASN1_OBJECT *o ASN1_OBJECT * OBJ_nid2obj(n) int n const char * OBJ_nid2ln(n) int n const char * OBJ_nid2sn(n) int n int OBJ_obj2nid(o) ASN1_OBJECT *o ASN1_OBJECT * OBJ_txt2obj(s, no_name=0) const char *s int no_name void OBJ_obj2txt(a, no_name=0) ASN1_OBJECT *a int no_name PREINIT: char buf[100]; /* openssl doc: a buffer length of 80 should be more than enough to handle any OID encountered in practice */ int len; CODE: len = OBJ_obj2txt(buf, sizeof(buf), a, no_name); ST(0) = sv_newmortal(); sv_setpvn(ST(0), buf, len); #if OPENSSL_VERSION_NUMBER < 0x0090700fL #define REM14 "NOTE: before 0.9.7" int OBJ_txt2nid(s) char *s #else int OBJ_txt2nid(s) const char *s #endif int OBJ_ln2nid(s) const char *s int OBJ_sn2nid(s) const char *s int OBJ_cmp(a, b) ASN1_OBJECT *a ASN1_OBJECT *b #if OPENSSL_VERSION_NUMBER >= 0x0090700fL void X509_pubkey_digest(data,type) const X509 *data const EVP_MD *type PREINIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; PPCODE: if (X509_pubkey_digest(data,type,md,&md_size)) XSRETURN_PVN((char *)md, md_size); else XSRETURN_UNDEF; #endif void X509_digest(data,type) const X509 *data const EVP_MD *type PREINIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; PPCODE: if (X509_digest(data,type,md,&md_size)) XSRETURN_PVN((char *)md, md_size); XSRETURN_UNDEF; void X509_CRL_digest(data,type) const X509_CRL *data const EVP_MD *type PREINIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; PPCODE: if (X509_CRL_digest(data,type,md,&md_size)) XSRETURN_PVN((char *)md, md_size); XSRETURN_UNDEF; void X509_REQ_digest(data,type) const X509_REQ *data const EVP_MD *type PREINIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; PPCODE: if (X509_REQ_digest(data,type,md,&md_size)) XSRETURN_PVN((char *)md, md_size); XSRETURN_UNDEF; void X509_NAME_digest(data,type) const X509_NAME *data const EVP_MD *type PREINIT: unsigned char md[EVP_MAX_MD_SIZE]; unsigned int md_size; PPCODE: if (X509_NAME_digest(data,type,md,&md_size)) XSRETURN_PVN((char *)md, md_size); XSRETURN_UNDEF; unsigned long X509_subject_name_hash(X509 *x) unsigned long X509_issuer_name_hash(X509 *a) unsigned long X509_issuer_and_serial_hash(X509 *a) ASN1_OBJECT * P_X509_get_signature_alg(x) X509 * x CODE: #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) RETVAL = (X509_get0_tbs_sigalg(x)->algorithm); #else RETVAL = (x->cert_info->signature->algorithm); #endif OUTPUT: RETVAL ASN1_OBJECT * P_X509_get_pubkey_alg(x) X509 * x PREINIT: CODE: #if OPENSSL_VERSION_NUMBER >= 0x10100000L { X509_ALGOR * algor; X509_PUBKEY_get0_param(0, 0, 0, &algor, X509_get_X509_PUBKEY(x)); RETVAL = (algor->algorithm); } #else RETVAL = (x->cert_info->key->algor->algorithm); #endif OUTPUT: RETVAL void X509_get_X509_PUBKEY(x) const X509 *x PPCODE: X509_PUBKEY *pkey; STRLEN len; unsigned char *pc, *pi; if (!(pkey = X509_get_X509_PUBKEY(x))) croak("invalid certificate"); if (!(len = i2d_X509_PUBKEY(pkey, NULL))) croak("invalid certificate public key"); Newx(pc,len,unsigned char); if (!pc) croak("out of memory"); pi = pc; i2d_X509_PUBKEY(pkey, &pi); if (pi-pc != len) croak("invalid encoded length"); XPUSHs(sv_2mortal(newSVpv((char*)pc,len))); Safefree(pc); #if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) && !defined(LIBRESSL_VERSION_NUMBER) int SSL_CTX_set_next_protos_advertised_cb(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: RETVAL = 1; if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_next_protos_advertised_cb(ctx, NULL, NULL); cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", NULL); cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", NULL); PR1("SSL_CTX_set_next_protos_advertised_cb - undef\n"); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVAV)) { /* callback param array ref like ['proto1','proto2'] */ cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", NULL); cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", newSVsv(callback)); SSL_CTX_set_next_protos_advertised_cb(ctx, next_protos_advertised_cb_invoke, ctx); PR2("SSL_CTX_set_next_protos_advertised_cb - simple ctx=%p\n",ctx); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) { cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", newSVsv(data)); SSL_CTX_set_next_protos_advertised_cb(ctx, next_protos_advertised_cb_invoke, ctx); PR2("SSL_CTX_set_next_protos_advertised_cb - advanced ctx=%p\n",ctx); } else { RETVAL = 0; } OUTPUT: RETVAL int SSL_CTX_set_next_proto_select_cb(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: RETVAL = 1; if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_next_proto_select_cb(ctx, NULL, NULL); cb_data_advanced_put(ctx, "next_proto_select_cb!!func", NULL); cb_data_advanced_put(ctx, "next_proto_select_cb!!data", NULL); PR1("SSL_CTX_set_next_proto_select_cb - undef\n"); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVAV)) { /* callback param array ref like ['proto1','proto2'] */ cb_data_advanced_put(ctx, "next_proto_select_cb!!func", NULL); cb_data_advanced_put(ctx, "next_proto_select_cb!!data", newSVsv(callback)); SSL_CTX_set_next_proto_select_cb(ctx, next_proto_select_cb_invoke, ctx); PR2("SSL_CTX_set_next_proto_select_cb - simple ctx=%p\n",ctx); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) { cb_data_advanced_put(ctx, "next_proto_select_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "next_proto_select_cb!!data", newSVsv(data)); SSL_CTX_set_next_proto_select_cb(ctx, next_proto_select_cb_invoke, ctx); PR2("SSL_CTX_set_next_proto_select_cb - advanced ctx=%p\n",ctx); } else { RETVAL = 0; } OUTPUT: RETVAL void P_next_proto_negotiated(s) const SSL *s PREINIT: const unsigned char *data; unsigned int len; PPCODE: SSL_get0_next_proto_negotiated(s, &data, &len); XPUSHs(sv_2mortal(newSVpv((char *)data, len))); void P_next_proto_last_status(s) const SSL *s PPCODE: XPUSHs(sv_2mortal(newSVsv(cb_data_advanced_get((void*)s, "next_proto_select_cb!!last_status")))); #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L #if !defined(OPENSSL_NO_TLSEXT) int SSL_set_tlsext_status_type(SSL *ssl,int cmd) long SSL_set_tlsext_status_ocsp_resp(ssl,staple) SSL * ssl PREINIT: char * p; STRLEN staplelen; INPUT: char * staple = SvPV( ST(1), staplelen); CODE: /* OpenSSL will free the memory */ New(0, p, staplelen, char); memcpy(p, staple, staplelen); RETVAL = SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,staplelen,(void *)p); OUTPUT: RETVAL int SSL_CTX_set_tlsext_status_cb(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: RETVAL = 1; if (callback==NULL || !SvOK(callback)) { cb_data_advanced_put(ctx, "tlsext_status_cb!!func", NULL); cb_data_advanced_put(ctx, "tlsext_status_cb!!data", NULL); SSL_CTX_set_tlsext_status_cb(ctx, NULL); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) { cb_data_advanced_put(ctx, "tlsext_status_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "tlsext_status_cb!!data", newSVsv(data)); SSL_CTX_set_tlsext_status_cb(ctx, tlsext_status_cb_invoke); } else { croak("argument must be code reference"); } OUTPUT: RETVAL int SSL_set_session_ticket_ext_cb(ssl,callback,data=&PL_sv_undef) SSL * ssl SV * callback SV * data CODE: RETVAL = 1; if (callback==NULL || !SvOK(callback)) { cb_data_advanced_put(ssl, "session_ticket_ext_cb!!func", NULL); cb_data_advanced_put(ssl, "session_ticket_ext_cb!!data", NULL); SSL_set_session_ticket_ext_cb(ssl, NULL, NULL); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) { cb_data_advanced_put(ssl, "session_ticket_ext_cb!!func", newSVsv(callback)); cb_data_advanced_put(ssl, "session_ticket_ext_cb!!data", newSVsv(data)); SSL_set_session_ticket_ext_cb(ssl, (tls_session_ticket_ext_cb_fn)&session_ticket_ext_cb_invoke, ssl); } else { croak("argument must be code reference"); } OUTPUT: RETVAL int SSL_set_session_ticket_ext(ssl,ticket) SSL *ssl PREINIT: unsigned char * p; STRLEN ticketlen; INPUT: unsigned char * ticket = (unsigned char *)SvPV( ST(1), ticketlen); CODE: RETVAL = 0; if (ticketlen > 0) { Newx(p, ticketlen, unsigned char); if (!p) croak("Net::SSLeay: set_session_ticket_ext could not allocate memory.\n"); memcpy(p, ticket, ticketlen); RETVAL = SSL_set_session_ticket_ext(ssl, p, ticketlen); Safefree(p); } OUTPUT: RETVAL #endif OCSP_RESPONSE * d2i_OCSP_RESPONSE(pv) SV *pv CODE: RETVAL = NULL; if (SvPOK(pv)) { const unsigned char *p; STRLEN len; p = (unsigned char*)SvPV(pv,len); RETVAL = d2i_OCSP_RESPONSE(NULL,&p,len); } OUTPUT: RETVAL void i2d_OCSP_RESPONSE(r) OCSP_RESPONSE * r PPCODE: STRLEN len; unsigned char *pc,*pi; if (!(len = i2d_OCSP_RESPONSE(r,NULL))) croak("invalid OCSP response"); Newx(pc,len,unsigned char); if (!pc) croak("out of memory"); pi = pc; i2d_OCSP_RESPONSE(r,&pi); XPUSHs(sv_2mortal(newSVpv((char*)pc,len))); Safefree(pc); void OCSP_RESPONSE_free(r) OCSP_RESPONSE * r OCSP_REQUEST * d2i_OCSP_REQUEST(pv) SV *pv CODE: RETVAL = NULL; if (SvPOK(pv)) { const unsigned char *p; STRLEN len; p = (unsigned char*)SvPV(pv,len); RETVAL = d2i_OCSP_REQUEST(NULL,&p,len); } OUTPUT: RETVAL void i2d_OCSP_REQUEST(r) OCSP_REQUEST * r PPCODE: STRLEN len; unsigned char *pc,*pi; if (!(len = i2d_OCSP_REQUEST(r,NULL))) croak("invalid OCSP request"); Newx(pc,len,unsigned char); if (!pc) croak("out of memory"); pi = pc; i2d_OCSP_REQUEST(r,&pi); XPUSHs(sv_2mortal(newSVpv((char*)pc,len))); Safefree(pc); void OCSP_REQUEST_free(r) OCSP_REQUEST * r const char * OCSP_response_status_str(long status) long OCSP_response_status(OCSP_RESPONSE *r) void SSL_OCSP_cert2ids(ssl,...) SSL *ssl PPCODE: SSL_CTX *ctx; X509_STORE *store; STACK_OF(X509) *chain; X509 *cert,*issuer; OCSP_CERTID *id; int i; STRLEN len; unsigned char *pi; if (!ssl) croak("not a SSL object"); ctx = SSL_get_SSL_CTX(ssl); if (!ctx) croak("invalid SSL object - no context"); store = SSL_CTX_get_cert_store(ctx); chain = SSL_get_peer_cert_chain(ssl); for(i=0;i= 0) sir = OCSP_resp_get0(bsr,first); } if (sir) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L status = OCSP_single_get0_status(sir, &revocationReason, &revocationTime, &thisupdate, &nextupdate); #else status = sir->certStatus->type; if (status == V_OCSP_CERTSTATUS_REVOKED) revocationTime = sir->certStatus->value.revoked->revocationTime; thisupdate = sir->thisUpdate; nextupdate = sir->nextUpdate; #endif if (status == V_OCSP_CERTSTATUS_REVOKED) { error = "certificate status is revoked"; } else if (status != V_OCSP_CERTSTATUS_GOOD) { error = "certificate status is unknown"; } else if (!OCSP_check_validity(thisupdate, nextupdate, 0, -1)) { error = "response not yet valid or expired"; } } else { error = "cannot find entry for certificate in OCSP response"; } end: if (want_array) { AV *idav = newAV(); if (!idsv) { /* getall: create new SV with OCSP_CERTID */ unsigned char *pi,*pc; #if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER) int len = i2d_OCSP_CERTID((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sir),NULL); #else int len = i2d_OCSP_CERTID(sir->certId,NULL); #endif if(!len) continue; Newx(pc,len,unsigned char); if (!pc) croak("out of memory"); pi = pc; #if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER) i2d_OCSP_CERTID((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sir),&pi); #else i2d_OCSP_CERTID(sir->certId,&pi); #endif idsv = newSVpv((char*)pc,len); Safefree(pc); } else { /* reuse idsv from ST(..), but increment refcount */ idsv = SvREFCNT_inc(idsv); } av_push(idav, idsv); av_push(idav, error ? newSVpv(error,0) : newSV(0)); if (sir) { HV *details = newHV(); av_push(idav,newRV_noinc((SV*)details)); hv_store(details,"statusType",10, newSViv(status),0); if (nextupdate) hv_store(details,"nextUpdate",10, newSViv(ASN1_TIME_timet(nextupdate, &gmtoff)),0); if (thisupdate) hv_store(details,"thisUpdate",10, newSViv(ASN1_TIME_timet(thisupdate, &gmtoff)),0); if (status == V_OCSP_CERTSTATUS_REVOKED) { #if OPENSSL_VERSION_NUMBER < 0x10100000L OCSP_REVOKEDINFO *rev = sir->certStatus->value.revoked; revocationReason = ASN1_ENUMERATED_get(rev->revocationReason); #endif hv_store(details,"revocationTime",14,newSViv(ASN1_TIME_timet(revocationTime, &gmtoff)),0); hv_store(details,"revocationReason",16,newSViv(revocationReason),0); hv_store(details,"revocationReason_str",20,newSVpv( OCSP_crl_reason_str(revocationReason),0),0); } } XPUSHs(sv_2mortal(newRV_noinc((SV*)idav))); } else if (!error) { /* compute lowest nextUpdate */ time_t nu = ASN1_TIME_timet(nextupdate, &gmtoff); if (!nextupd || nextupd>nu) nextupd = nu; } if (certid) OCSP_CERTID_free(certid); if (error && !want_array) { OCSP_BASICRESP_free(bsr); croak("%s", error); } } OCSP_BASICRESP_free(bsr); if (!want_array) XPUSHs(sv_2mortal(newSViv(nextupd))); #endif #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) int SSL_CTX_set_alpn_select_cb(ctx,callback,data=&PL_sv_undef) SSL_CTX * ctx SV * callback SV * data CODE: RETVAL = 1; if (callback==NULL || !SvOK(callback)) { SSL_CTX_set_alpn_select_cb(ctx, NULL, NULL); cb_data_advanced_put(ctx, "alpn_select_cb!!func", NULL); cb_data_advanced_put(ctx, "alpn_select_cb!!data", NULL); PR1("SSL_CTX_set_alpn_select_cb - undef\n"); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVAV)) { /* callback param array ref like ['proto1','proto2'] */ cb_data_advanced_put(ctx, "alpn_select_cb!!func", NULL); cb_data_advanced_put(ctx, "alpn_select_cb!!data", newSVsv(callback)); SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb_invoke, ctx); PR2("SSL_CTX_set_alpn_select_cb - simple ctx=%p\n",ctx); } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) { cb_data_advanced_put(ctx, "alpn_select_cb!!func", newSVsv(callback)); cb_data_advanced_put(ctx, "alpn_select_cb!!data", newSVsv(data)); SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb_invoke, ctx); PR2("SSL_CTX_set_alpn_select_cb - advanced ctx=%p\n",ctx); } else { RETVAL = 0; } OUTPUT: RETVAL int SSL_CTX_set_alpn_protos(ctx,data=&PL_sv_undef) SSL_CTX * ctx SV * data PREINIT: unsigned char *alpn_data; unsigned char alpn_len; CODE: RETVAL = -1; if (!SvROK(data) || (SvTYPE(SvRV(data)) != SVt_PVAV)) croak("Net::SSLeay: CTX_set_alpn_protos needs a single array reference.\n"); alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), NULL); Newx(alpn_data, alpn_len, unsigned char); if (!alpn_data) croak("Net::SSLeay: CTX_set_alpn_protos could not allocate memory.\n"); alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), alpn_data); RETVAL = SSL_CTX_set_alpn_protos(ctx, alpn_data, alpn_len); Safefree(alpn_data); OUTPUT: RETVAL int SSL_set_alpn_protos(ssl,data=&PL_sv_undef) SSL * ssl SV * data PREINIT: unsigned char *alpn_data; unsigned char alpn_len; CODE: RETVAL = -1; if (!SvROK(data) || (SvTYPE(SvRV(data)) != SVt_PVAV)) croak("Net::SSLeay: set_alpn_protos needs a single array reference.\n"); alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), NULL); Newx(alpn_data, alpn_len, unsigned char); if (!alpn_data) croak("Net::SSLeay: set_alpn_protos could not allocate memory.\n"); alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), alpn_data); RETVAL = SSL_set_alpn_protos(ssl, alpn_data, alpn_len); Safefree(alpn_data); OUTPUT: RETVAL void P_alpn_selected(s) const SSL *s PREINIT: const unsigned char *data; unsigned int len; PPCODE: SSL_get0_alpn_selected(s, &data, &len); XPUSHs(sv_2mortal(newSVpv((char *)data, len))); #endif #if OPENSSL_VERSION_NUMBER >= 0x10001000L void SSL_export_keying_material(ssl, outlen, label, context=&PL_sv_undef) SSL * ssl int outlen SV * context PREINIT: unsigned char * out; STRLEN llen; STRLEN contextlen = 0; char *context_arg = NULL; int use_context = 0; int ret; INPUT: char * label = SvPV( ST(2), llen); PPCODE: Newx(out, outlen, unsigned char); if (context != &PL_sv_undef) { use_context = 1; context_arg = SvPV( ST(3), contextlen); } ret = SSL_export_keying_material(ssl, out, outlen, label, llen, (unsigned char*)context_arg, contextlen, use_context); PUSHs(sv_2mortal(ret>0 ? newSVpvn((const char *)out, outlen) : newSV(0))); EXTEND(SP, 1); Safefree(out); #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L OSSL_LIB_CTX * OSSL_LIB_CTX_get0_global_default() OSSL_PROVIDER * OSSL_PROVIDER_load(SV *libctx, const char *name) CODE: OSSL_LIB_CTX *ctx = NULL; if (libctx != &PL_sv_undef) ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx)); RETVAL = OSSL_PROVIDER_load(ctx, name); if (RETVAL == NULL) XSRETURN_UNDEF; OUTPUT: RETVAL OSSL_PROVIDER * OSSL_PROVIDER_try_load(SV *libctx, const char *name, int retain_fallbacks) CODE: OSSL_LIB_CTX *ctx = NULL; if (libctx != &PL_sv_undef) ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx)); RETVAL = OSSL_PROVIDER_try_load(ctx, name, retain_fallbacks); if (RETVAL == NULL) XSRETURN_UNDEF; OUTPUT: RETVAL int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) int OSSL_PROVIDER_available(SV *libctx, const char *name) CODE: OSSL_LIB_CTX *ctx = NULL; if (libctx != &PL_sv_undef) ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx)); RETVAL = OSSL_PROVIDER_available(ctx, name); OUTPUT: RETVAL int OSSL_PROVIDER_do_all(SV *libctx, SV *perl_cb, SV *perl_cbdata = &PL_sv_undef) PREINIT: simple_cb_data_t* cbdata = NULL; CODE: OSSL_LIB_CTX *ctx = NULL; if (libctx != &PL_sv_undef) ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx)); /* setup our callback */ cbdata = simple_cb_data_new(perl_cb, perl_cbdata); RETVAL = OSSL_PROVIDER_do_all(ctx, ossl_provider_do_all_cb_invoke, cbdata); simple_cb_data_free(cbdata); OUTPUT: RETVAL const char * OSSL_PROVIDER_get0_name(const OSSL_PROVIDER *prov) int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov) #endif #define REM_EOF "/* EOF - SSLeay.xs */" Net-SSLeay-1.92/constants.c0000644000175000001440000052127614167101614014231 0ustar csnusers/* * This file 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. */ #ifdef NET_SSLEAY_32BIT_CONSTANTS static double #else static uint64_t #endif constant (const char *name, size_t len) { /* Initially switch on the length of the name. */ switch (len) { case 5: /* Names all of length 5. */ /* RSA_3 ST_OK */ /* Offset 0 gives the best switch position. */ switch (*name++) { case 'R': if (!memcmp(name, "SA_3", 4)) { /* R */ #ifdef RSA_3 return RSA_3; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "T_OK", 4)) { /* S */ #ifdef SSL_ST_OK return SSL_ST_OK; #else goto not_there; #endif } break; } break; case 6: /* Names all of length 6. */ /* OP_ALL RSA_F4 */ /* Offset 0 gives the best switch position. */ switch (*name++) { case 'O': if (!memcmp(name, "P_ALL", 5)) { /* O */ #ifdef SSL_OP_ALL return SSL_OP_ALL; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SA_F4", 5)) { /* R */ #ifdef RSA_F4 return RSA_F4; #else goto not_there; #endif } break; } break; case 7: /* Names all of length 7. */ /* CB_EXIT CB_LOOP CB_READ GEN_DNS GEN_RID GEN_URI NID_dsa NID_md2 NID_md5 NID_rc4 NID_rsa NID_sha NOTHING READING ST_INIT WRITING */ /* Offset 4 gives the best switch position. */ switch (name[4]) { case 'D': if (!memcmp(name, "GEN_DNS", 7)) { /* ^ */ #ifdef GEN_DNS return GEN_DNS; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "CB_READ", 7)) { /* ^ */ #ifdef SSL_CB_READ return SSL_CB_READ; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "NOTHING", 7)) { /* ^ */ #ifdef SSL_NOTHING return SSL_NOTHING; #else goto not_there; #endif } if (!memcmp(name, "READING", 7)) { /* ^ */ #ifdef SSL_READING return SSL_READING; #else goto not_there; #endif } if (!memcmp(name, "WRITING", 7)) { /* ^ */ #ifdef SSL_WRITING return SSL_WRITING; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "ST_INIT", 7)) { /* ^ */ #ifdef SSL_ST_INIT return SSL_ST_INIT; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "CB_LOOP", 7)) { /* ^ */ #ifdef SSL_CB_LOOP return SSL_CB_LOOP; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "GEN_RID", 7)) { /* ^ */ #ifdef GEN_RID return GEN_RID; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "GEN_URI", 7)) { /* ^ */ #ifdef GEN_URI return GEN_URI; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "CB_EXIT", 7)) { /* ^ */ #ifdef SSL_CB_EXIT return SSL_CB_EXIT; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_dsa", 7)) { /* ^ */ #ifdef NID_dsa return NID_dsa; #else goto not_there; #endif } break; case 'm': if (!memcmp(name, "NID_md2", 7)) { /* ^ */ #ifdef NID_md2 return NID_md2; #else goto not_there; #endif } if (!memcmp(name, "NID_md5", 7)) { /* ^ */ #ifdef NID_md5 return NID_md5; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_rc4", 7)) { /* ^ */ #ifdef NID_rc4 return NID_rc4; #else goto not_there; #endif } if (!memcmp(name, "NID_rsa", 7)) { /* ^ */ #ifdef NID_rsa return NID_rsa; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_sha", 7)) { /* ^ */ #ifdef NID_sha return NID_sha; #else goto not_there; #endif } break; } break; case 8: /* Names all of length 8. */ /* CB_ALERT CB_WRITE F_READ_N GEN_X400 NID_X500 NID_X509 NID_mdc2 NID_name NID_pkcs NID_sha1 */ /* Offset 5 gives the best switch position. */ switch (name[5]) { case '4': if (!memcmp(name, "GEN_X400", 8)) { /* ^ */ #ifdef GEN_X400 return GEN_X400; #else goto not_there; #endif } break; case '5': if (!memcmp(name, "NID_X500", 8)) { /* ^ */ #ifdef NID_X500 return NID_X500; #else goto not_there; #endif } if (!memcmp(name, "NID_X509", 8)) { /* ^ */ #ifdef NID_X509 return NID_X509; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "F_READ_N", 8)) { /* ^ */ #ifdef SSL_F_READ_N return SSL_F_READ_N; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "CB_ALERT", 8)) { /* ^ */ #ifdef SSL_CB_ALERT return SSL_CB_ALERT; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "CB_WRITE", 8)) { /* ^ */ #ifdef SSL_CB_WRITE return SSL_CB_WRITE; #else goto not_there; #endif } break; case 'a': if (!memcmp(name, "NID_name", 8)) { /* ^ */ #ifdef NID_name return NID_name; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_mdc2", 8)) { /* ^ */ #ifdef NID_mdc2 return NID_mdc2; #else goto not_there; #endif } break; case 'h': if (!memcmp(name, "NID_sha1", 8)) { /* ^ */ #ifdef NID_sha1 return NID_sha1; #else goto not_there; #endif } break; case 'k': if (!memcmp(name, "NID_pkcs", 8)) { /* ^ */ #ifdef NID_pkcs return NID_pkcs; #else goto not_there; #endif } break; } break; case 9: /* Names all of length 9. */ /* ERROR_SSL EVP_PK_DH EVP_PK_EC F_SSL_NEW GEN_EMAIL GEN_IPADD NID_dsa_2 NID_id_ad NID_id_ce NID_id_kp NID_id_pe NID_pbes2 NID_pkcs3 NID_pkcs7 NID_pkcs9 NID_sxnet NID_title NID_undef ST_ACCEPT ST_BEFORE X509_V_OK */ /* Offset 8 gives the best switch position. */ switch (name[8]) { case '2': if (!memcmp(name, "NID_dsa_", 8)) { /* 2 */ #ifdef NID_dsa_2 return NID_dsa_2; #else goto not_there; #endif } if (!memcmp(name, "NID_pbes", 8)) { /* 2 */ #ifdef NID_pbes2 return NID_pbes2; #else goto not_there; #endif } break; case '3': if (!memcmp(name, "NID_pkcs", 8)) { /* 3 */ #ifdef NID_pkcs3 return NID_pkcs3; #else goto not_there; #endif } break; case '7': if (!memcmp(name, "NID_pkcs", 8)) { /* 7 */ #ifdef NID_pkcs7 return NID_pkcs7; #else goto not_there; #endif } break; case '9': if (!memcmp(name, "NID_pkcs", 8)) { /* 9 */ #ifdef NID_pkcs9 return NID_pkcs9; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "EVP_PK_E", 8)) { /* C */ #ifdef EVP_PK_EC return EVP_PK_EC; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "GEN_IPAD", 8)) { /* D */ #ifdef GEN_IPADD return GEN_IPADD; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "ST_BEFOR", 8)) { /* E */ #ifdef SSL_ST_BEFORE return SSL_ST_BEFORE; #else goto not_there; #endif } break; case 'H': if (!memcmp(name, "EVP_PK_D", 8)) { /* H */ #ifdef EVP_PK_DH return EVP_PK_DH; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "X509_V_O", 8)) { /* K */ #ifdef X509_V_OK return X509_V_OK; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "ERROR_SS", 8)) { /* L */ #ifdef SSL_ERROR_SSL return SSL_ERROR_SSL; #else goto not_there; #endif } if (!memcmp(name, "GEN_EMAI", 8)) { /* L */ #ifdef GEN_EMAIL return GEN_EMAIL; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "ST_ACCEP", 8)) { /* T */ #ifdef SSL_ST_ACCEPT return SSL_ST_ACCEPT; #else goto not_there; #endif } break; case 'W': if (!memcmp(name, "F_SSL_NE", 8)) { /* W */ #ifdef SSL_F_SSL_NEW return SSL_F_SSL_NEW; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_id_a", 8)) { /* d */ #ifdef NID_id_ad return NID_id_ad; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_id_c", 8)) { /* e */ #ifdef NID_id_ce return NID_id_ce; #else goto not_there; #endif } if (!memcmp(name, "NID_id_p", 8)) { /* e */ #ifdef NID_id_pe return NID_id_pe; #else goto not_there; #endif } if (!memcmp(name, "NID_titl", 8)) { /* e */ #ifdef NID_title return NID_title; #else goto not_there; #endif } break; case 'f': if (!memcmp(name, "NID_unde", 8)) { /* f */ #ifdef NID_undef return NID_undef; #else goto not_there; #endif } break; case 'p': if (!memcmp(name, "NID_id_k", 8)) { /* p */ #ifdef NID_id_kp return NID_id_kp; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_sxne", 8)) { /* t */ #ifdef NID_sxnet return NID_sxnet; #else goto not_there; #endif } break; } break; case 10: /* Names all of length 10. */ /* ERROR_NONE EVP_PKS_EC EVP_PK_DSA EVP_PK_RSA F_SSL_READ NID_bf_cbc NID_bf_ecb NID_crlBag NID_keyBag NID_ms_efs NID_ms_sgc NID_ns_sgc NID_pbmac1 NID_rc4_40 NID_rsadsi R_X509_LIB SSLEAY_DIR ST_CONNECT */ /* Offset 9 gives the best switch position. */ switch (name[9]) { case '0': if (!memcmp(name, "NID_rc4_4", 9)) { /* 0 */ #ifdef NID_rc4_40 return NID_rc4_40; #else goto not_there; #endif } break; case '1': if (!memcmp(name, "NID_pbmac", 9)) { /* 1 */ #ifdef NID_pbmac1 return NID_pbmac1; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "EVP_PK_DS", 9)) { /* A */ #ifdef EVP_PK_DSA return EVP_PK_DSA; #else goto not_there; #endif } if (!memcmp(name, "EVP_PK_RS", 9)) { /* A */ #ifdef EVP_PK_RSA return EVP_PK_RSA; #else goto not_there; #endif } break; case 'B': if (!memcmp(name, "R_X509_LI", 9)) { /* B */ #ifdef SSL_R_X509_LIB return SSL_R_X509_LIB; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "EVP_PKS_E", 9)) { /* C */ #ifdef EVP_PKS_EC return EVP_PKS_EC; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "F_SSL_REA", 9)) { /* D */ #ifdef SSL_F_SSL_READ return SSL_F_SSL_READ; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "ERROR_NON", 9)) { /* E */ #ifdef SSL_ERROR_NONE return SSL_ERROR_NONE; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSLEAY_DI", 9)) { /* R */ #ifdef SSLEAY_DIR return SSLEAY_DIR; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "ST_CONNEC", 9)) { /* T */ #ifdef SSL_ST_CONNECT return SSL_ST_CONNECT; #else goto not_there; #endif } break; case 'b': if (!memcmp(name, "NID_bf_ec", 9)) { /* b */ #ifdef NID_bf_ecb return NID_bf_ecb; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_bf_cb", 9)) { /* c */ #ifdef NID_bf_cbc return NID_bf_cbc; #else goto not_there; #endif } if (!memcmp(name, "NID_ms_sg", 9)) { /* c */ #ifdef NID_ms_sgc return NID_ms_sgc; #else goto not_there; #endif } if (!memcmp(name, "NID_ns_sg", 9)) { /* c */ #ifdef NID_ns_sgc return NID_ns_sgc; #else goto not_there; #endif } break; case 'g': if (!memcmp(name, "NID_crlBa", 9)) { /* g */ #ifdef NID_crlBag return NID_crlBag; #else goto not_there; #endif } if (!memcmp(name, "NID_keyBa", 9)) { /* g */ #ifdef NID_keyBag return NID_keyBag; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_rsads", 9)) { /* i */ #ifdef NID_rsadsi return NID_rsadsi; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_ms_ef", 9)) { /* s */ #ifdef NID_ms_efs return NID_ms_efs; #else goto not_there; #endif } break; } break; case 11: /* Names all of length 11. */ /* EVP_PKS_DSA EVP_PKS_RSA EVP_PKT_ENC EVP_PKT_EXP GEN_DIRNAME NID_ad_OCSP NID_certBag NID_des_cbc NID_des_ecb NID_des_ede NID_ext_req NID_id_pkix NID_rc2_cbc NID_rc2_ecb NID_rc5_cbc NID_rc5_ecb NID_surname NID_x509Crl OPENSSL_DIR OP_NO_SSLv2 OP_NO_SSLv3 OP_NO_TLSv1 R_BAD_STATE SSL3_MT_CCS VERIFY_NONE VERIFY_PEER X509_LOOKUP */ /* Offset 9 gives the best switch position. */ switch (name[9]) { case 'C': if (!memcmp(name, "SSL3_MT_CCS", 11)) { /* ^ */ #ifdef SSL3_MT_CCS return SSL3_MT_CCS; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "VERIFY_PEER", 11)) { /* ^ */ #ifdef SSL_VERIFY_PEER return SSL_VERIFY_PEER; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "OPENSSL_DIR", 11)) { /* ^ */ #ifdef OPENSSL_DIR return OPENSSL_DIR; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "GEN_DIRNAME", 11)) { /* ^ */ #ifdef GEN_DIRNAME return GEN_DIRNAME; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "EVP_PKT_ENC", 11)) { /* ^ */ #ifdef EVP_PKT_ENC return EVP_PKT_ENC; #else goto not_there; #endif } if (!memcmp(name, "VERIFY_NONE", 11)) { /* ^ */ #ifdef SSL_VERIFY_NONE return SSL_VERIFY_NONE; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "EVP_PKS_DSA", 11)) { /* ^ */ #ifdef EVP_PKS_DSA return EVP_PKS_DSA; #else goto not_there; #endif } if (!memcmp(name, "EVP_PKS_RSA", 11)) { /* ^ */ #ifdef EVP_PKS_RSA return EVP_PKS_RSA; #else goto not_there; #endif } if (!memcmp(name, "NID_ad_OCSP", 11)) { /* ^ */ #ifdef NID_ad_OCSP return NID_ad_OCSP; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "R_BAD_STATE", 11)) { /* ^ */ #ifdef SSL_R_BAD_STATE return SSL_R_BAD_STATE; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "X509_LOOKUP", 11)) { /* ^ */ #ifdef SSL_X509_LOOKUP return SSL_X509_LOOKUP; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "EVP_PKT_EXP", 11)) { /* ^ */ #ifdef EVP_PKT_EXP return EVP_PKT_EXP; #else goto not_there; #endif } break; case 'a': if (!memcmp(name, "NID_certBag", 11)) { /* ^ */ #ifdef NID_certBag return NID_certBag; #else goto not_there; #endif } break; case 'b': if (!memcmp(name, "NID_des_cbc", 11)) { /* ^ */ #ifdef NID_des_cbc return NID_des_cbc; #else goto not_there; #endif } if (!memcmp(name, "NID_rc2_cbc", 11)) { /* ^ */ #ifdef NID_rc2_cbc return NID_rc2_cbc; #else goto not_there; #endif } if (!memcmp(name, "NID_rc5_cbc", 11)) { /* ^ */ #ifdef NID_rc5_cbc return NID_rc5_cbc; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_des_ecb", 11)) { /* ^ */ #ifdef NID_des_ecb return NID_des_ecb; #else goto not_there; #endif } if (!memcmp(name, "NID_rc2_ecb", 11)) { /* ^ */ #ifdef NID_rc2_ecb return NID_rc2_ecb; #else goto not_there; #endif } if (!memcmp(name, "NID_rc5_ecb", 11)) { /* ^ */ #ifdef NID_rc5_ecb return NID_rc5_ecb; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_des_ede", 11)) { /* ^ */ #ifdef NID_des_ede return NID_des_ede; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_ext_req", 11)) { /* ^ */ #ifdef NID_ext_req return NID_ext_req; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_id_pkix", 11)) { /* ^ */ #ifdef NID_id_pkix return NID_id_pkix; #else goto not_there; #endif } break; case 'm': if (!memcmp(name, "NID_surname", 11)) { /* ^ */ #ifdef NID_surname return NID_surname; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_x509Crl", 11)) { /* ^ */ #ifdef NID_x509Crl return NID_x509Crl; #else goto not_there; #endif } break; case 'v': if (!memcmp(name, "OP_NO_SSLv2", 11)) { /* ^ */ #ifdef SSL_OP_NO_SSLv2 return SSL_OP_NO_SSLv2; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_SSLv3", 11)) { /* ^ */ #ifdef SSL_OP_NO_SSLv3 return SSL_OP_NO_SSLv3; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_TLSv1", 11)) { /* ^ */ #ifdef SSL_OP_NO_TLSv1 return SSL_OP_NO_TLSv1; #else goto not_there; #endif } break; } break; case 12: /* Names all of length 12. */ /* EVP_PKT_EXCH EVP_PKT_SIGN FILETYPE_PEM F_SSL_SET_FD GEN_EDIPARTY MBSTRING_ASC MBSTRING_BMP NID_bf_cfb64 NID_bf_ofb64 NID_des_ede3 NID_desx_cbc NID_idea_cbc NID_idea_ecb NID_initials NID_md5_sha1 NID_netscape OP_NO_TICKET R_PEER_ERROR R_SHORT_READ SSL2_VERSION SSL3_VERSION ST_READ_BODY TLS1_VERSION */ /* Offset 10 gives the best switch position. */ switch (name[10]) { case '6': if (!memcmp(name, "NID_bf_cfb64", 12)) { /* ^ */ #ifdef NID_bf_cfb64 return NID_bf_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_bf_ofb64", 12)) { /* ^ */ #ifdef NID_bf_ofb64 return NID_bf_ofb64; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "R_SHORT_READ", 12)) { /* ^ */ #ifdef SSL_R_SHORT_READ return SSL_R_SHORT_READ; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "EVP_PKT_EXCH", 12)) { /* ^ */ #ifdef EVP_PKT_EXCH return EVP_PKT_EXCH; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "ST_READ_BODY", 12)) { /* ^ */ #ifdef SSL_ST_READ_BODY return SSL_ST_READ_BODY; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "FILETYPE_PEM", 12)) { /* ^ */ #ifdef SSL_FILETYPE_PEM return SSL_FILETYPE_PEM; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_TICKET", 12)) { /* ^ */ #ifdef SSL_OP_NO_TICKET return SSL_OP_NO_TICKET; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "F_SSL_SET_FD", 12)) { /* ^ */ #ifdef SSL_F_SSL_SET_FD return SSL_F_SSL_SET_FD; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "EVP_PKT_SIGN", 12)) { /* ^ */ #ifdef EVP_PKT_SIGN return EVP_PKT_SIGN; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "MBSTRING_BMP", 12)) { /* ^ */ #ifdef MBSTRING_BMP return MBSTRING_BMP; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "R_PEER_ERROR", 12)) { /* ^ */ #ifdef SSL_R_PEER_ERROR return SSL_R_PEER_ERROR; #else goto not_there; #endif } if (!memcmp(name, "SSL2_VERSION", 12)) { /* ^ */ #ifdef SSL2_VERSION return SSL2_VERSION; #else goto not_there; #endif } if (!memcmp(name, "SSL3_VERSION", 12)) { /* ^ */ #ifdef SSL3_VERSION return SSL3_VERSION; #else goto not_there; #endif } if (!memcmp(name, "TLS1_VERSION", 12)) { /* ^ */ #ifdef TLS1_VERSION return TLS1_VERSION; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "MBSTRING_ASC", 12)) { /* ^ */ #ifdef MBSTRING_ASC return MBSTRING_ASC; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "GEN_EDIPARTY", 12)) { /* ^ */ #ifdef GEN_EDIPARTY return GEN_EDIPARTY; #else goto not_there; #endif } break; case 'a': if (!memcmp(name, "NID_md5_sha1", 12)) { /* ^ */ #ifdef NID_md5_sha1 return NID_md5_sha1; #else goto not_there; #endif } break; case 'b': if (!memcmp(name, "NID_desx_cbc", 12)) { /* ^ */ #ifdef NID_desx_cbc return NID_desx_cbc; #else goto not_there; #endif } if (!memcmp(name, "NID_idea_cbc", 12)) { /* ^ */ #ifdef NID_idea_cbc return NID_idea_cbc; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_idea_ecb", 12)) { /* ^ */ #ifdef NID_idea_ecb return NID_idea_ecb; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_des_ede3", 12)) { /* ^ */ #ifdef NID_des_ede3 return NID_des_ede3; #else goto not_there; #endif } break; case 'l': if (!memcmp(name, "NID_initials", 12)) { /* ^ */ #ifdef NID_initials return NID_initials; #else goto not_there; #endif } break; case 'p': if (!memcmp(name, "NID_netscape", 12)) { /* ^ */ #ifdef NID_netscape return NID_netscape; #else goto not_there; #endif } break; } break; case 13: /* Names all of length 13. */ /* CB_READ_ALERT ERROR_SYSCALL FILETYPE_ASN1 F_SSL_SET_RFD F_SSL_SET_WFD GEN_OTHERNAME MBSTRING_FLAG MBSTRING_UNIV MBSTRING_UTF8 NID_OCSP_sign NID_algorithm NID_cast5_cbc NID_cast5_ecb NID_code_sign NID_delta_crl NID_des_cfb64 NID_des_ofb64 NID_givenName NID_id_pbkdf2 NID_id_qt_cps NID_key_usage NID_rc2_cfb64 NID_rc2_ofb64 NID_rc5_cfb64 NID_rc5_ofb64 NID_ripemd160 NID_secretBag OP_NO_TLSv1_1 OP_NO_TLSv1_2 OP_NO_TLSv1_3 OP_TLS_D5_BUG SENT_SHUTDOWN SSL2_MT_ERROR SSL3_RT_ALERT SSLEAY_CFLAGS XN_FLAG_FN_LN XN_FLAG_FN_SN */ /* Offset 12 gives the best switch position. */ switch (name[12]) { case '0': if (!memcmp(name, "NID_ripemd16", 12)) { /* 0 */ #ifdef NID_ripemd160 return NID_ripemd160; #else goto not_there; #endif } break; case '1': if (!memcmp(name, "FILETYPE_ASN", 12)) { /* 1 */ #ifdef SSL_FILETYPE_ASN1 return SSL_FILETYPE_ASN1; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_TLSv1_", 12)) { /* 1 */ #ifdef SSL_OP_NO_TLSv1_1 return SSL_OP_NO_TLSv1_1; #else goto not_there; #endif } break; case '2': if (!memcmp(name, "NID_id_pbkdf", 12)) { /* 2 */ #ifdef NID_id_pbkdf2 return NID_id_pbkdf2; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_TLSv1_", 12)) { /* 2 */ #ifdef SSL_OP_NO_TLSv1_2 return SSL_OP_NO_TLSv1_2; #else goto not_there; #endif } break; case '3': if (!memcmp(name, "OP_NO_TLSv1_", 12)) { /* 3 */ #ifdef SSL_OP_NO_TLSv1_3 return SSL_OP_NO_TLSv1_3; #else goto not_there; #endif } break; case '4': if (!memcmp(name, "NID_des_cfb6", 12)) { /* 4 */ #ifdef NID_des_cfb64 return NID_des_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_des_ofb6", 12)) { /* 4 */ #ifdef NID_des_ofb64 return NID_des_ofb64; #else goto not_there; #endif } if (!memcmp(name, "NID_rc2_cfb6", 12)) { /* 4 */ #ifdef NID_rc2_cfb64 return NID_rc2_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_rc2_ofb6", 12)) { /* 4 */ #ifdef NID_rc2_ofb64 return NID_rc2_ofb64; #else goto not_there; #endif } if (!memcmp(name, "NID_rc5_cfb6", 12)) { /* 4 */ #ifdef NID_rc5_cfb64 return NID_rc5_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_rc5_ofb6", 12)) { /* 4 */ #ifdef NID_rc5_ofb64 return NID_rc5_ofb64; #else goto not_there; #endif } break; case '8': if (!memcmp(name, "MBSTRING_UTF", 12)) { /* 8 */ #ifdef MBSTRING_UTF8 return MBSTRING_UTF8; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "F_SSL_SET_RF", 12)) { /* D */ #ifdef SSL_F_SSL_SET_RFD return SSL_F_SSL_SET_RFD; #else goto not_there; #endif } if (!memcmp(name, "F_SSL_SET_WF", 12)) { /* D */ #ifdef SSL_F_SSL_SET_WFD return SSL_F_SSL_SET_WFD; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "GEN_OTHERNAM", 12)) { /* E */ #ifdef GEN_OTHERNAME return GEN_OTHERNAME; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "MBSTRING_FLA", 12)) { /* G */ #ifdef MBSTRING_FLAG return MBSTRING_FLAG; #else goto not_there; #endif } if (!memcmp(name, "OP_TLS_D5_BU", 12)) { /* G */ #ifdef SSL_OP_TLS_D5_BUG return SSL_OP_TLS_D5_BUG; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "ERROR_SYSCAL", 12)) { /* L */ #ifdef SSL_ERROR_SYSCALL return SSL_ERROR_SYSCALL; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "SENT_SHUTDOW", 12)) { /* N */ #ifdef SSL_SENT_SHUTDOWN return SSL_SENT_SHUTDOWN; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_FN_L", 12)) { /* N */ #ifdef XN_FLAG_FN_LN return XN_FLAG_FN_LN; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_FN_S", 12)) { /* N */ #ifdef XN_FLAG_FN_SN return XN_FLAG_FN_SN; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL2_MT_ERRO", 12)) { /* R */ #ifdef SSL2_MT_ERROR return SSL2_MT_ERROR; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "SSLEAY_CFLAG", 12)) { /* S */ #ifdef SSLEAY_CFLAGS return SSLEAY_CFLAGS; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "CB_READ_ALER", 12)) { /* T */ #ifdef SSL_CB_READ_ALERT return SSL_CB_READ_ALERT; #else goto not_there; #endif } if (!memcmp(name, "SSL3_RT_ALER", 12)) { /* T */ #ifdef SSL3_RT_ALERT return SSL3_RT_ALERT; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "MBSTRING_UNI", 12)) { /* V */ #ifdef MBSTRING_UNIV return MBSTRING_UNIV; #else goto not_there; #endif } break; case 'b': if (!memcmp(name, "NID_cast5_ec", 12)) { /* b */ #ifdef NID_cast5_ecb return NID_cast5_ecb; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_cast5_cb", 12)) { /* c */ #ifdef NID_cast5_cbc return NID_cast5_cbc; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_givenNam", 12)) { /* e */ #ifdef NID_givenName return NID_givenName; #else goto not_there; #endif } if (!memcmp(name, "NID_key_usag", 12)) { /* e */ #ifdef NID_key_usage return NID_key_usage; #else goto not_there; #endif } break; case 'g': if (!memcmp(name, "NID_secretBa", 12)) { /* g */ #ifdef NID_secretBag return NID_secretBag; #else goto not_there; #endif } break; case 'l': if (!memcmp(name, "NID_delta_cr", 12)) { /* l */ #ifdef NID_delta_crl return NID_delta_crl; #else goto not_there; #endif } break; case 'm': if (!memcmp(name, "NID_algorith", 12)) { /* m */ #ifdef NID_algorithm return NID_algorithm; #else goto not_there; #endif } break; case 'n': if (!memcmp(name, "NID_OCSP_sig", 12)) { /* n */ #ifdef NID_OCSP_sign return NID_OCSP_sign; #else goto not_there; #endif } if (!memcmp(name, "NID_code_sig", 12)) { /* n */ #ifdef NID_code_sign return NID_code_sign; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_id_qt_cp", 12)) { /* s */ #ifdef NID_id_qt_cps return NID_id_qt_cps; #else goto not_there; #endif } break; } break; case 14: /* Names all of length 14. */ /* CB_ACCEPT_EXIT CB_ACCEPT_LOOP CB_WRITE_ALERT F_CLIENT_HELLO F_SERVER_HELLO F_SSL_CERT_NEW NID_commonName NID_crl_number NID_crl_reason NID_dsaWithSHA NID_idea_cfb64 NID_idea_ofb64 NID_localKeyID NID_md5WithRSA NID_ms_ext_req NID_pkcs7_data NID_rc2_40_cbc NID_rc2_64_cbc NID_time_stamp OPENSSL_CFLAGS OP_NO_SSL_MASK R_BAD_CHECKSUM R_NO_PUBLICKEY R_NULL_SSL_CTX SESS_CACHE_OFF SSL3_RT_HEADER SSLEAY_VERSION ST_READ_HEADER TLS1_1_VERSION TLS1_2_VERSION TLS1_3_VERSION X509_TRUST_TSA XN_FLAG_COMPAT XN_FLAG_DN_REV XN_FLAG_FN_OID XN_FLAG_SPC_EQ */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case '4': if (!memcmp(name, "NID_idea_cfb6", 13)) { /* 4 */ #ifdef NID_idea_cfb64 return NID_idea_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_idea_ofb6", 13)) { /* 4 */ #ifdef NID_idea_ofb64 return NID_idea_ofb64; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "NID_dsaWithSH", 13)) { /* A */ #ifdef NID_dsaWithSHA return NID_dsaWithSHA; #else goto not_there; #endif } if (!memcmp(name, "NID_md5WithRS", 13)) { /* A */ #ifdef NID_md5WithRSA return NID_md5WithRSA; #else goto not_there; #endif } if (!memcmp(name, "X509_TRUST_TS", 13)) { /* A */ #ifdef X509_TRUST_TSA return X509_TRUST_TSA; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "NID_localKeyI", 13)) { /* D */ #ifdef NID_localKeyID return NID_localKeyID; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_FN_OI", 13)) { /* D */ #ifdef XN_FLAG_FN_OID return XN_FLAG_FN_OID; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "SESS_CACHE_OF", 13)) { /* F */ #ifdef SSL_SESS_CACHE_OFF return SSL_SESS_CACHE_OFF; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "OP_NO_SSL_MAS", 13)) { /* K */ #ifdef SSL_OP_NO_SSL_MASK return SSL_OP_NO_SSL_MASK; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "R_BAD_CHECKSU", 13)) { /* M */ #ifdef SSL_R_BAD_CHECKSUM return SSL_R_BAD_CHECKSUM; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "SSLEAY_VERSIO", 13)) { /* N */ #ifdef SSLEAY_VERSION return SSLEAY_VERSION; #else goto not_there; #endif } if (!memcmp(name, "TLS1_1_VERSIO", 13)) { /* N */ #ifdef TLS1_1_VERSION return TLS1_1_VERSION; #else goto not_there; #endif } if (!memcmp(name, "TLS1_2_VERSIO", 13)) { /* N */ #ifdef TLS1_2_VERSION return TLS1_2_VERSION; #else goto not_there; #endif } if (!memcmp(name, "TLS1_3_VERSIO", 13)) { /* N */ #ifdef TLS1_3_VERSION return TLS1_3_VERSION; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "F_CLIENT_HELL", 13)) { /* O */ #ifdef SSL_F_CLIENT_HELLO return SSL_F_CLIENT_HELLO; #else goto not_there; #endif } if (!memcmp(name, "F_SERVER_HELL", 13)) { /* O */ #ifdef SSL_F_SERVER_HELLO return SSL_F_SERVER_HELLO; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "CB_ACCEPT_LOO", 13)) { /* P */ #ifdef SSL_CB_ACCEPT_LOOP return SSL_CB_ACCEPT_LOOP; #else goto not_there; #endif } break; case 'Q': if (!memcmp(name, "XN_FLAG_SPC_E", 13)) { /* Q */ #ifdef XN_FLAG_SPC_EQ return XN_FLAG_SPC_EQ; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL3_RT_HEADE", 13)) { /* R */ #ifdef SSL3_RT_HEADER return SSL3_RT_HEADER; #else goto not_there; #endif } if (!memcmp(name, "ST_READ_HEADE", 13)) { /* R */ #ifdef SSL_ST_READ_HEADER return SSL_ST_READ_HEADER; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "OPENSSL_CFLAG", 13)) { /* S */ #ifdef OPENSSL_CFLAGS return OPENSSL_CFLAGS; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "CB_ACCEPT_EXI", 13)) { /* T */ #ifdef SSL_CB_ACCEPT_EXIT return SSL_CB_ACCEPT_EXIT; #else goto not_there; #endif } if (!memcmp(name, "CB_WRITE_ALER", 13)) { /* T */ #ifdef SSL_CB_WRITE_ALERT return SSL_CB_WRITE_ALERT; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_COMPA", 13)) { /* T */ #ifdef XN_FLAG_COMPAT return XN_FLAG_COMPAT; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "XN_FLAG_DN_RE", 13)) { /* V */ #ifdef XN_FLAG_DN_REV return XN_FLAG_DN_REV; #else goto not_there; #endif } break; case 'W': if (!memcmp(name, "F_SSL_CERT_NE", 13)) { /* W */ #ifdef SSL_F_SSL_CERT_NEW return SSL_F_SSL_CERT_NEW; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "R_NULL_SSL_CT", 13)) { /* X */ #ifdef SSL_R_NULL_SSL_CTX return SSL_R_NULL_SSL_CTX; #else goto not_there; #endif } break; case 'Y': if (!memcmp(name, "R_NO_PUBLICKE", 13)) { /* Y */ #ifdef SSL_R_NO_PUBLICKEY return SSL_R_NO_PUBLICKEY; #else goto not_there; #endif } break; case 'a': if (!memcmp(name, "NID_pkcs7_dat", 13)) { /* a */ #ifdef NID_pkcs7_data return NID_pkcs7_data; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_rc2_40_cb", 13)) { /* c */ #ifdef NID_rc2_40_cbc return NID_rc2_40_cbc; #else goto not_there; #endif } if (!memcmp(name, "NID_rc2_64_cb", 13)) { /* c */ #ifdef NID_rc2_64_cbc return NID_rc2_64_cbc; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_commonNam", 13)) { /* e */ #ifdef NID_commonName return NID_commonName; #else goto not_there; #endif } break; case 'n': if (!memcmp(name, "NID_crl_reaso", 13)) { /* n */ #ifdef NID_crl_reason return NID_crl_reason; #else goto not_there; #endif } break; case 'p': if (!memcmp(name, "NID_time_stam", 13)) { /* p */ #ifdef NID_time_stamp return NID_time_stamp; #else goto not_there; #endif } break; case 'q': if (!memcmp(name, "NID_ms_ext_re", 13)) { /* q */ #ifdef NID_ms_ext_req return NID_ms_ext_req; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_crl_numbe", 13)) { /* r */ #ifdef NID_crl_number return NID_crl_number; #else goto not_there; #endif } break; } break; case 15: /* Names all of length 15. */ /* CB_CONNECT_EXIT CB_CONNECT_LOOP ERROR_WANT_READ F_WRITE_PENDING MODE_AUTO_RETRY NID_cast5_cfb64 NID_cast5_ofb64 NID_client_auth NID_countryName NID_des_ede_cbc NID_description NID_dnQualifier NID_dsaWithSHA1 NID_info_access NID_mdc2WithRSA NID_ms_code_com NID_ms_code_ind NID_ms_ctl_sign NID_server_auth NID_sha1WithRSA OPENSSL_VERSION OP_NO_QUERY_MTU R_NO_PRIVATEKEY R_UNKNOWN_STATE SESS_CACHE_BOTH SSLEAY_BUILT_ON SSLEAY_PLATFORM XN_FLAG_FN_MASK XN_FLAG_FN_NONE XN_FLAG_ONELINE XN_FLAG_RFC2253 */ /* Offset 14 gives the best switch position. */ switch (name[14]) { case '1': if (!memcmp(name, "NID_dsaWithSHA", 14)) { /* 1 */ #ifdef NID_dsaWithSHA1 return NID_dsaWithSHA1; #else goto not_there; #endif } break; case '3': if (!memcmp(name, "XN_FLAG_RFC225", 14)) { /* 3 */ #ifdef XN_FLAG_RFC2253 return XN_FLAG_RFC2253; #else goto not_there; #endif } break; case '4': if (!memcmp(name, "NID_cast5_cfb6", 14)) { /* 4 */ #ifdef NID_cast5_cfb64 return NID_cast5_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_cast5_ofb6", 14)) { /* 4 */ #ifdef NID_cast5_ofb64 return NID_cast5_ofb64; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "NID_mdc2WithRS", 14)) { /* A */ #ifdef NID_mdc2WithRSA return NID_mdc2WithRSA; #else goto not_there; #endif } if (!memcmp(name, "NID_sha1WithRS", 14)) { /* A */ #ifdef NID_sha1WithRSA return NID_sha1WithRSA; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "ERROR_WANT_REA", 14)) { /* D */ #ifdef SSL_ERROR_WANT_READ return SSL_ERROR_WANT_READ; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "R_UNKNOWN_STAT", 14)) { /* E */ #ifdef SSL_R_UNKNOWN_STATE return SSL_R_UNKNOWN_STATE; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_FN_NON", 14)) { /* E */ #ifdef XN_FLAG_FN_NONE return XN_FLAG_FN_NONE; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_ONELIN", 14)) { /* E */ #ifdef XN_FLAG_ONELINE return XN_FLAG_ONELINE; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "F_WRITE_PENDIN", 14)) { /* G */ #ifdef SSL_F_WRITE_PENDING return SSL_F_WRITE_PENDING; #else goto not_there; #endif } break; case 'H': if (!memcmp(name, "SESS_CACHE_BOT", 14)) { /* H */ #ifdef SSL_SESS_CACHE_BOTH return SSL_SESS_CACHE_BOTH; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "XN_FLAG_FN_MAS", 14)) { /* K */ #ifdef XN_FLAG_FN_MASK return XN_FLAG_FN_MASK; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "SSLEAY_PLATFOR", 14)) { /* M */ #ifdef SSLEAY_PLATFORM return SSLEAY_PLATFORM; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "OPENSSL_VERSIO", 14)) { /* N */ #ifdef OPENSSL_VERSION return OPENSSL_VERSION; #else goto not_there; #endif } if (!memcmp(name, "SSLEAY_BUILT_O", 14)) { /* N */ #ifdef SSLEAY_BUILT_ON return SSLEAY_BUILT_ON; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "CB_CONNECT_LOO", 14)) { /* P */ #ifdef SSL_CB_CONNECT_LOOP return SSL_CB_CONNECT_LOOP; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "CB_CONNECT_EXI", 14)) { /* T */ #ifdef SSL_CB_CONNECT_EXIT return SSL_CB_CONNECT_EXIT; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "OP_NO_QUERY_MT", 14)) { /* U */ #ifdef SSL_OP_NO_QUERY_MTU return SSL_OP_NO_QUERY_MTU; #else goto not_there; #endif } break; case 'Y': if (!memcmp(name, "MODE_AUTO_RETR", 14)) { /* Y */ #ifdef SSL_MODE_AUTO_RETRY return SSL_MODE_AUTO_RETRY; #else goto not_there; #endif } if (!memcmp(name, "R_NO_PRIVATEKE", 14)) { /* Y */ #ifdef SSL_R_NO_PRIVATEKEY return SSL_R_NO_PRIVATEKEY; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_des_ede_cb", 14)) { /* c */ #ifdef NID_des_ede_cbc return NID_des_ede_cbc; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_ms_code_in", 14)) { /* d */ #ifdef NID_ms_code_ind return NID_ms_code_ind; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_countryNam", 14)) { /* e */ #ifdef NID_countryName return NID_countryName; #else goto not_there; #endif } break; case 'h': if (!memcmp(name, "NID_client_aut", 14)) { /* h */ #ifdef NID_client_auth return NID_client_auth; #else goto not_there; #endif } if (!memcmp(name, "NID_server_aut", 14)) { /* h */ #ifdef NID_server_auth return NID_server_auth; #else goto not_there; #endif } break; case 'm': if (!memcmp(name, "NID_ms_code_co", 14)) { /* m */ #ifdef NID_ms_code_com return NID_ms_code_com; #else goto not_there; #endif } break; case 'n': if (!memcmp(name, "NID_descriptio", 14)) { /* n */ #ifdef NID_description return NID_description; #else goto not_there; #endif } if (!memcmp(name, "NID_ms_ctl_sig", 14)) { /* n */ #ifdef NID_ms_ctl_sign return NID_ms_ctl_sign; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_dnQualifie", 14)) { /* r */ #ifdef NID_dnQualifier return NID_dnQualifier; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_info_acces", 14)) { /* s */ #ifdef NID_info_access return NID_info_access; #else goto not_there; #endif } break; } break; case 16: /* Names all of length 16. */ /* ERROR_WANT_WRITE NID_des_ede3_cbc NID_friendlyName NID_hmacWithSHA1 NID_localityName NID_pkcs7_digest NID_pkcs7_signed NID_serialNumber OPENSSL_BUILT_ON OPENSSL_CPU_INFO OPENSSL_PLATFORM OP_EPHEMERAL_RSA OP_PKCS1_CHECK_1 OP_PKCS1_CHECK_2 OP_SINGLE_DH_USE R_BAD_MAC_DECODE R_NO_CIPHER_LIST SSL3_MT_FINISHED X509_PURPOSE_ANY X509_TRUST_EMAIL XN_FLAG_FN_ALIGN XN_FLAG_SEP_MASK */ /* Offset 15 gives the best switch position. */ switch (name[15]) { case '1': if (!memcmp(name, "NID_hmacWithSHA", 15)) { /* 1 */ #ifdef NID_hmacWithSHA1 return NID_hmacWithSHA1; #else goto not_there; #endif } if (!memcmp(name, "OP_PKCS1_CHECK_", 15)) { /* 1 */ #ifdef SSL_OP_PKCS1_CHECK_1 return SSL_OP_PKCS1_CHECK_1; #else goto not_there; #endif } break; case '2': if (!memcmp(name, "OP_PKCS1_CHECK_", 15)) { /* 2 */ #ifdef SSL_OP_PKCS1_CHECK_2 return SSL_OP_PKCS1_CHECK_2; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "OP_EPHEMERAL_RS", 15)) { /* A */ #ifdef SSL_OP_EPHEMERAL_RSA return SSL_OP_EPHEMERAL_RSA; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "SSL3_MT_FINISHE", 15)) { /* D */ #ifdef SSL3_MT_FINISHED return SSL3_MT_FINISHED; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "ERROR_WANT_WRIT", 15)) { /* E */ #ifdef SSL_ERROR_WANT_WRITE return SSL_ERROR_WANT_WRITE; #else goto not_there; #endif } if (!memcmp(name, "OP_SINGLE_DH_US", 15)) { /* E */ #ifdef SSL_OP_SINGLE_DH_USE return SSL_OP_SINGLE_DH_USE; #else goto not_there; #endif } if (!memcmp(name, "R_BAD_MAC_DECOD", 15)) { /* E */ #ifdef SSL_R_BAD_MAC_DECODE return SSL_R_BAD_MAC_DECODE; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "XN_FLAG_SEP_MAS", 15)) { /* K */ #ifdef XN_FLAG_SEP_MASK return XN_FLAG_SEP_MASK; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "X509_TRUST_EMAI", 15)) { /* L */ #ifdef X509_TRUST_EMAIL return X509_TRUST_EMAIL; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "OPENSSL_PLATFOR", 15)) { /* M */ #ifdef OPENSSL_PLATFORM return OPENSSL_PLATFORM; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "OPENSSL_BUILT_O", 15)) { /* N */ #ifdef OPENSSL_BUILT_ON return OPENSSL_BUILT_ON; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_FN_ALIG", 15)) { /* N */ #ifdef XN_FLAG_FN_ALIGN return XN_FLAG_FN_ALIGN; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "OPENSSL_CPU_INF", 15)) { /* O */ #ifdef OPENSSL_CPU_INFO return OPENSSL_CPU_INFO; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "R_NO_CIPHER_LIS", 15)) { /* T */ #ifdef SSL_R_NO_CIPHER_LIST return SSL_R_NO_CIPHER_LIST; #else goto not_there; #endif } break; case 'Y': if (!memcmp(name, "X509_PURPOSE_AN", 15)) { /* Y */ #ifdef X509_PURPOSE_ANY return X509_PURPOSE_ANY; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_des_ede3_cb", 15)) { /* c */ #ifdef NID_des_ede3_cbc return NID_des_ede3_cbc; #else goto not_there; #endif } break; case 'd': if (!memcmp(name, "NID_pkcs7_signe", 15)) { /* d */ #ifdef NID_pkcs7_signed return NID_pkcs7_signed; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_friendlyNam", 15)) { /* e */ #ifdef NID_friendlyName return NID_friendlyName; #else goto not_there; #endif } if (!memcmp(name, "NID_localityNam", 15)) { /* e */ #ifdef NID_localityName return NID_localityName; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_serialNumbe", 15)) { /* r */ #ifdef NID_serialNumber return NID_serialNumber; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_pkcs7_diges", 15)) { /* t */ #ifdef NID_pkcs7_digest return NID_pkcs7_digest; #else goto not_there; #endif } break; } break; case 17: /* Names all of length 17. */ /* CB_HANDSHAKE_DONE ERROR_WANT_ACCEPT ERROR_ZERO_RETURN F_D2I_SSL_SESSION F_I2D_SSL_SESSION F_SSL_SESSION_NEW NID_ad_ca_issuers NID_des_ede_cfb64 NID_des_ede_ofb64 NID_dsaWithSHA1_2 NID_email_protect NID_ext_key_usage NID_id_qt_unotice NID_rsaEncryption OP_NO_ANTI_REPLAY OP_NO_COMPRESSION OP_TLSEXT_PADDING RECEIVED_SHUTDOWN R_BAD_WRITE_RETRY R_NO_CIPHER_MATCH SESS_CACHE_CLIENT SESS_CACHE_SERVER SSL3_RT_HANDSHAKE X509_FILETYPE_PEM X509_TRUST_COMPAT XN_FLAG_MULTILINE */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case 'A': if (!memcmp(name, "NID_dsaWithSHA1_2", 17)) { /* ^ */ #ifdef NID_dsaWithSHA1_2 return NID_dsaWithSHA1_2; #else goto not_there; #endif } if (!memcmp(name, "R_NO_CIPHER_MATCH", 17)) { /* ^ */ #ifdef SSL_R_NO_CIPHER_MATCH return SSL_R_NO_CIPHER_MATCH; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "ERROR_WANT_ACCEPT", 17)) { /* ^ */ #ifdef SSL_ERROR_WANT_ACCEPT return SSL_ERROR_WANT_ACCEPT; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "CB_HANDSHAKE_DONE", 17)) { /* ^ */ #ifdef SSL_CB_HANDSHAKE_DONE return SSL_CB_HANDSHAKE_DONE; #else goto not_there; #endif } if (!memcmp(name, "OP_TLSEXT_PADDING", 17)) { /* ^ */ #ifdef SSL_OP_TLSEXT_PADDING return SSL_OP_TLSEXT_PADDING; #else goto not_there; #endif } if (!memcmp(name, "RECEIVED_SHUTDOWN", 17)) { /* ^ */ #ifdef SSL_RECEIVED_SHUTDOWN return SSL_RECEIVED_SHUTDOWN; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "R_BAD_WRITE_RETRY", 17)) { /* ^ */ #ifdef SSL_R_BAD_WRITE_RETRY return SSL_R_BAD_WRITE_RETRY; #else goto not_there; #endif } break; case 'H': if (!memcmp(name, "SSL3_RT_HANDSHAKE", 17)) { /* ^ */ #ifdef SSL3_RT_HANDSHAKE return SSL3_RT_HANDSHAKE; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "SESS_CACHE_CLIENT", 17)) { /* ^ */ #ifdef SSL_SESS_CACHE_CLIENT return SSL_SESS_CACHE_CLIENT; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "XN_FLAG_MULTILINE", 17)) { /* ^ */ #ifdef XN_FLAG_MULTILINE return XN_FLAG_MULTILINE; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "X509_TRUST_COMPAT", 17)) { /* ^ */ #ifdef X509_TRUST_COMPAT return X509_TRUST_COMPAT; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "OP_NO_ANTI_REPLAY", 17)) { /* ^ */ #ifdef SSL_OP_NO_ANTI_REPLAY return SSL_OP_NO_ANTI_REPLAY; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SESS_CACHE_SERVER", 17)) { /* ^ */ #ifdef SSL_SESS_CACHE_SERVER return SSL_SESS_CACHE_SERVER; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "F_D2I_SSL_SESSION", 17)) { /* ^ */ #ifdef SSL_F_D2I_SSL_SESSION return SSL_F_D2I_SSL_SESSION; #else goto not_there; #endif } if (!memcmp(name, "F_I2D_SSL_SESSION", 17)) { /* ^ */ #ifdef SSL_F_I2D_SSL_SESSION return SSL_F_I2D_SSL_SESSION; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_COMPRESSION", 17)) { /* ^ */ #ifdef SSL_OP_NO_COMPRESSION return SSL_OP_NO_COMPRESSION; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "ERROR_ZERO_RETURN", 17)) { /* ^ */ #ifdef SSL_ERROR_ZERO_RETURN return SSL_ERROR_ZERO_RETURN; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "F_SSL_SESSION_NEW", 17)) { /* ^ */ #ifdef SSL_F_SSL_SESSION_NEW return SSL_F_SSL_SESSION_NEW; #else goto not_there; #endif } if (!memcmp(name, "X509_FILETYPE_PEM", 17)) { /* ^ */ #ifdef X509_FILETYPE_PEM return X509_FILETYPE_PEM; #else goto not_there; #endif } break; case 'f': if (!memcmp(name, "NID_des_ede_cfb64", 17)) { /* ^ */ #ifdef NID_des_ede_cfb64 return NID_des_ede_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_des_ede_ofb64", 17)) { /* ^ */ #ifdef NID_des_ede_ofb64 return NID_des_ede_ofb64; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_ext_key_usage", 17)) { /* ^ */ #ifdef NID_ext_key_usage return NID_ext_key_usage; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_email_protect", 17)) { /* ^ */ #ifdef NID_email_protect return NID_email_protect; #else goto not_there; #endif } if (!memcmp(name, "NID_id_qt_unotice", 17)) { /* ^ */ #ifdef NID_id_qt_unotice return NID_id_qt_unotice; #else goto not_there; #endif } if (!memcmp(name, "NID_rsaEncryption", 17)) { /* ^ */ #ifdef NID_rsaEncryption return NID_rsaEncryption; #else goto not_there; #endif } break; case 'u': if (!memcmp(name, "NID_ad_ca_issuers", 17)) { /* ^ */ #ifdef NID_ad_ca_issuers return NID_ad_ca_issuers; #else goto not_there; #endif } break; } break; case 18: /* Names all of length 18. */ /* CB_HANDSHAKE_START ERROR_WANT_CONNECT F_GET_CLIENT_HELLO F_GET_SERVER_HELLO NID_des_ede3_cfb64 NID_des_ede3_ofb64 NID_dhKeyAgreement OP_COOKIE_EXCHANGE OP_SINGLE_ECDH_USE R_BAD_SSL_FILETYPE SSL3_MT_KEY_UPDATE SSL3_MT_NEXT_PROTO VERIFY_CLIENT_ONCE X509_FILETYPE_ASN1 */ /* Offset 11 gives the best switch position. */ switch (name[11]) { case '3': if (!memcmp(name, "NID_des_ede3_cfb64", 18)) { /* ^ */ #ifdef NID_des_ede3_cfb64 return NID_des_ede3_cfb64; #else goto not_there; #endif } if (!memcmp(name, "NID_des_ede3_ofb64", 18)) { /* ^ */ #ifdef NID_des_ede3_ofb64 return NID_des_ede3_ofb64; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "ERROR_WANT_CONNECT", 18)) { /* ^ */ #ifdef SSL_ERROR_WANT_CONNECT return SSL_ERROR_WANT_CONNECT; #else goto not_there; #endif } if (!memcmp(name, "OP_SINGLE_ECDH_USE", 18)) { /* ^ */ #ifdef SSL_OP_SINGLE_ECDH_USE return SSL_OP_SINGLE_ECDH_USE; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "CB_HANDSHAKE_START", 18)) { /* ^ */ #ifdef SSL_CB_HANDSHAKE_START return SSL_CB_HANDSHAKE_START; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "R_BAD_SSL_FILETYPE", 18)) { /* ^ */ #ifdef SSL_R_BAD_SSL_FILETYPE return SSL_R_BAD_SSL_FILETYPE; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "VERIFY_CLIENT_ONCE", 18)) { /* ^ */ #ifdef SSL_VERIFY_CLIENT_ONCE return SSL_VERIFY_CLIENT_ONCE; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "X509_FILETYPE_ASN1", 18)) { /* ^ */ #ifdef X509_FILETYPE_ASN1 return X509_FILETYPE_ASN1; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "F_GET_SERVER_HELLO", 18)) { /* ^ */ #ifdef SSL_F_GET_SERVER_HELLO return SSL_F_GET_SERVER_HELLO; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "F_GET_CLIENT_HELLO", 18)) { /* ^ */ #ifdef SSL_F_GET_CLIENT_HELLO return SSL_F_GET_CLIENT_HELLO; #else goto not_there; #endif } if (!memcmp(name, "SSL3_MT_NEXT_PROTO", 18)) { /* ^ */ #ifdef SSL3_MT_NEXT_PROTO return SSL3_MT_NEXT_PROTO; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "OP_COOKIE_EXCHANGE", 18)) { /* ^ */ #ifdef SSL_OP_COOKIE_EXCHANGE return SSL_OP_COOKIE_EXCHANGE; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "SSL3_MT_KEY_UPDATE", 18)) { /* ^ */ #ifdef SSL3_MT_KEY_UPDATE return SSL3_MT_KEY_UPDATE; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_dhKeyAgreement", 18)) { /* ^ */ #ifdef NID_dhKeyAgreement return NID_dhKeyAgreement; #else goto not_there; #endif } break; } break; case 19: /* Names all of length 19. */ /* F_CLIENT_MASTER_KEY F_GET_SERVER_VERIFY NID_invalidity_date NID_issuer_alt_name NID_pkcs7_encrypted NID_pkcs7_enveloped NID_rle_compression NID_safeContentsBag NID_sdsiCertificate NID_x509Certificate OPENSSL_ENGINES_DIR OPENSSL_MODULES_DIR OP_ALLOW_NO_DHE_KEX OP_CISCO_ANYCONNECT OP_NON_EXPORT_FIRST OP_NO_RENEGOTIATION OP_TLS_ROLLBACK_BUG SSL3_MT_CERTIFICATE SSL3_MT_SERVER_DONE */ /* Offset 12 gives the best switch position. */ switch (name[12]) { case 'A': if (!memcmp(name, "OP_TLS_ROLLBACK_BUG", 19)) { /* ^ */ #ifdef SSL_OP_TLS_ROLLBACK_BUG return SSL_OP_TLS_ROLLBACK_BUG; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "OP_CISCO_ANYCONNECT", 19)) { /* ^ */ #ifdef SSL_OP_CISCO_ANYCONNECT return SSL_OP_CISCO_ANYCONNECT; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "OP_ALLOW_NO_DHE_KEX", 19)) { /* ^ */ #ifdef SSL_OP_ALLOW_NO_DHE_KEX return SSL_OP_ALLOW_NO_DHE_KEX; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "SSL3_MT_SERVER_DONE", 19)) { /* ^ */ #ifdef SSL3_MT_SERVER_DONE return SSL3_MT_SERVER_DONE; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "SSL3_MT_CERTIFICATE", 19)) { /* ^ */ #ifdef SSL3_MT_CERTIFICATE return SSL3_MT_CERTIFICATE; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "OPENSSL_MODULES_DIR", 19)) { /* ^ */ #ifdef OPENSSL_MODULES_DIR return OPENSSL_MODULES_DIR; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "OPENSSL_ENGINES_DIR", 19)) { /* ^ */ #ifdef OPENSSL_ENGINES_DIR return OPENSSL_ENGINES_DIR; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "F_CLIENT_MASTER_KEY", 19)) { /* ^ */ #ifdef SSL_F_CLIENT_MASTER_KEY return SSL_F_CLIENT_MASTER_KEY; #else goto not_there; #endif } if (!memcmp(name, "OP_NON_EXPORT_FIRST", 19)) { /* ^ */ #ifdef SSL_OP_NON_EXPORT_FIRST return SSL_OP_NON_EXPORT_FIRST; #else goto not_there; #endif } if (!memcmp(name, "OP_NO_RENEGOTIATION", 19)) { /* ^ */ #ifdef SSL_OP_NO_RENEGOTIATION return SSL_OP_NO_RENEGOTIATION; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "F_GET_SERVER_VERIFY", 19)) { /* ^ */ #ifdef SSL_F_GET_SERVER_VERIFY return SSL_F_GET_SERVER_VERIFY; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_pkcs7_encrypted", 19)) { /* ^ */ #ifdef NID_pkcs7_encrypted return NID_pkcs7_encrypted; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_safeContentsBag", 19)) { /* ^ */ #ifdef NID_safeContentsBag return NID_safeContentsBag; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_sdsiCertificate", 19)) { /* ^ */ #ifdef NID_sdsiCertificate return NID_sdsiCertificate; #else goto not_there; #endif } if (!memcmp(name, "NID_x509Certificate", 19)) { /* ^ */ #ifdef NID_x509Certificate return NID_x509Certificate; #else goto not_there; #endif } break; case 'l': if (!memcmp(name, "NID_issuer_alt_name", 19)) { /* ^ */ #ifdef NID_issuer_alt_name return NID_issuer_alt_name; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_rle_compression", 19)) { /* ^ */ #ifdef NID_rle_compression return NID_rle_compression; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_invalidity_date", 19)) { /* ^ */ #ifdef NID_invalidity_date return NID_invalidity_date; #else goto not_there; #endif } break; case 'v': if (!memcmp(name, "NID_pkcs7_enveloped", 19)) { /* ^ */ #ifdef NID_pkcs7_enveloped return NID_pkcs7_enveloped; #else goto not_there; #endif } break; } break; case 20: /* Names all of length 20. */ /* ASN1_STRFLGS_ESC_MSB ASN1_STRFLGS_RFC2253 F_CLIENT_CERTIFICATE F_SSL_USE_PRIVATEKEY MODE_RELEASE_BUFFERS NID_netscape_comment NID_organizationName NID_ripemd160WithRSA NID_subject_alt_name NID_uniqueIdentifier NID_zlib_compression OP_PRIORITIZE_CHACHA R_NO_CERTIFICATE_SET SESSION_ASN1_VERSION SSL2_MT_CLIENT_HELLO SSL2_MT_SERVER_HELLO SSL3_MT_CLIENT_HELLO SSL3_MT_MESSAGE_HASH SSL3_MT_SERVER_HELLO X509_TRUST_OCSP_SIGN X509_V_ERR_PATH_LOOP */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case 'A': if (!memcmp(name, "R_NO_CERTIFICATE_SET", 20)) { /* ^ */ #ifdef SSL_R_NO_CERTIFICATE_SET return SSL_R_NO_CERTIFICATE_SET; #else goto not_there; #endif } break; case 'B': if (!memcmp(name, "MODE_RELEASE_BUFFERS", 20)) { /* ^ */ #ifdef SSL_MODE_RELEASE_BUFFERS return SSL_MODE_RELEASE_BUFFERS; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "ASN1_STRFLGS_ESC_MSB", 20)) { /* ^ */ #ifdef ASN1_STRFLGS_ESC_MSB return ASN1_STRFLGS_ESC_MSB; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "SSL3_MT_MESSAGE_HASH", 20)) { /* ^ */ #ifdef SSL3_MT_MESSAGE_HASH return SSL3_MT_MESSAGE_HASH; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "F_CLIENT_CERTIFICATE", 20)) { /* ^ */ #ifdef SSL_F_CLIENT_CERTIFICATE return SSL_F_CLIENT_CERTIFICATE; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "ASN1_STRFLGS_RFC2253", 20)) { /* ^ */ #ifdef ASN1_STRFLGS_RFC2253 return ASN1_STRFLGS_RFC2253; #else goto not_there; #endif } if (!memcmp(name, "SSL2_MT_SERVER_HELLO", 20)) { /* ^ */ #ifdef SSL2_MT_SERVER_HELLO return SSL2_MT_SERVER_HELLO; #else goto not_there; #endif } if (!memcmp(name, "SSL3_MT_SERVER_HELLO", 20)) { /* ^ */ #ifdef SSL3_MT_SERVER_HELLO return SSL3_MT_SERVER_HELLO; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_TRUST_OCSP_SIGN", 20)) { /* ^ */ #ifdef X509_TRUST_OCSP_SIGN return X509_TRUST_OCSP_SIGN; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "SSL2_MT_CLIENT_HELLO", 20)) { /* ^ */ #ifdef SSL2_MT_CLIENT_HELLO return SSL2_MT_CLIENT_HELLO; #else goto not_there; #endif } if (!memcmp(name, "SSL3_MT_CLIENT_HELLO", 20)) { /* ^ */ #ifdef SSL3_MT_CLIENT_HELLO return SSL3_MT_CLIENT_HELLO; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_PATH_LOOP", 20)) { /* ^ */ #ifdef X509_V_ERR_PATH_LOOP return X509_V_ERR_PATH_LOOP; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "F_SSL_USE_PRIVATEKEY", 20)) { /* ^ */ #ifdef SSL_F_SSL_USE_PRIVATEKEY return SSL_F_SSL_USE_PRIVATEKEY; #else goto not_there; #endif } if (!memcmp(name, "SESSION_ASN1_VERSION", 20)) { /* ^ */ #ifdef SSL_SESSION_ASN1_VERSION return SSL_SESSION_ASN1_VERSION; #else goto not_there; #endif } break; case 'W': if (!memcmp(name, "NID_ripemd160WithRSA", 20)) { /* ^ */ #ifdef NID_ripemd160WithRSA return NID_ripemd160WithRSA; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "OP_PRIORITIZE_CHACHA", 20)) { /* ^ */ #ifdef SSL_OP_PRIORITIZE_CHACHA return SSL_OP_PRIORITIZE_CHACHA; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_netscape_comment", 20)) { /* ^ */ #ifdef NID_netscape_comment return NID_netscape_comment; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_organizationName", 20)) { /* ^ */ #ifdef NID_organizationName return NID_organizationName; #else goto not_there; #endif } break; case 'l': if (!memcmp(name, "NID_subject_alt_name", 20)) { /* ^ */ #ifdef NID_subject_alt_name return NID_subject_alt_name; #else goto not_there; #endif } break; case 'n': if (!memcmp(name, "NID_uniqueIdentifier", 20)) { /* ^ */ #ifdef NID_uniqueIdentifier return NID_uniqueIdentifier; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_zlib_compression", 20)) { /* ^ */ #ifdef NID_zlib_compression return NID_zlib_compression; #else goto not_there; #endif } break; } break; case 21: /* Names all of length 21. */ /* ASN1_STRFLGS_ESC_CTRL F_GET_CLIENT_FINISHED F_GET_SERVER_FINISHED F_REQUEST_CERTIFICATE F_SSL_GET_NEW_SESSION F_SSL_USE_CERTIFICATE NID_SMIMECapabilities NID_basic_constraints NID_netscape_base_url NID_pkcs9_contentType NID_pkcs9_signingTime OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR OPENSSL_VERSION_PATCH OP_NETSCAPE_CA_DN_BUG SSL2_MT_SERVER_VERIFY SSL3_MT_HELLO_REQUEST VERIFY_POST_HANDSHAKE X509_FILETYPE_DEFAULT X509_PURPOSE_CRL_SIGN X509_TRUST_SSL_CLIENT X509_TRUST_SSL_SERVER X509_V_ERR_INVALID_CA X509_V_ERR_OUT_OF_MEM X509_V_FLAG_CRL_CHECK XN_FLAG_SEP_CPLUS_SPC XN_FLAG_SEP_MULTILINE XN_FLAG_SEP_SPLUS_SPC */ /* Offset 19 gives the best switch position. */ switch (name[19]) { case 'C': if (!memcmp(name, "OPENSSL_VERSION_PATCH", 21)) { /* ^ */ #ifdef OPENSSL_VERSION_PATCH return OPENSSL_VERSION_PATCH; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_INVALID_CA", 21)) { /* ^ */ #ifdef X509_V_ERR_INVALID_CA return X509_V_ERR_INVALID_CA; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_CRL_CHECK", 21)) { /* ^ */ #ifdef X509_V_FLAG_CRL_CHECK return X509_V_FLAG_CRL_CHECK; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "F_GET_CLIENT_FINISHED", 21)) { /* ^ */ #ifdef SSL_F_GET_CLIENT_FINISHED return SSL_F_GET_CLIENT_FINISHED; #else goto not_there; #endif } if (!memcmp(name, "F_GET_SERVER_FINISHED", 21)) { /* ^ */ #ifdef SSL_F_GET_SERVER_FINISHED return SSL_F_GET_SERVER_FINISHED; #else goto not_there; #endif } if (!memcmp(name, "X509_TRUST_SSL_SERVER", 21)) { /* ^ */ #ifdef X509_TRUST_SSL_SERVER return X509_TRUST_SSL_SERVER; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_OUT_OF_MEM", 21)) { /* ^ */ #ifdef X509_V_ERR_OUT_OF_MEM return X509_V_ERR_OUT_OF_MEM; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "SSL2_MT_SERVER_VERIFY", 21)) { /* ^ */ #ifdef SSL2_MT_SERVER_VERIFY return SSL2_MT_SERVER_VERIFY; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "X509_PURPOSE_CRL_SIGN", 21)) { /* ^ */ #ifdef X509_PURPOSE_CRL_SIGN return X509_PURPOSE_CRL_SIGN; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "VERIFY_POST_HANDSHAKE", 21)) { /* ^ */ #ifdef SSL_VERIFY_POST_HANDSHAKE return SSL_VERIFY_POST_HANDSHAKE; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "X509_FILETYPE_DEFAULT", 21)) { /* ^ */ #ifdef X509_FILETYPE_DEFAULT return X509_FILETYPE_DEFAULT; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_TRUST_SSL_CLIENT", 21)) { /* ^ */ #ifdef X509_TRUST_SSL_CLIENT return X509_TRUST_SSL_CLIENT; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_SEP_MULTILINE", 21)) { /* ^ */ #ifdef XN_FLAG_SEP_MULTILINE return XN_FLAG_SEP_MULTILINE; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "F_SSL_GET_NEW_SESSION", 21)) { /* ^ */ #ifdef SSL_F_SSL_GET_NEW_SESSION return SSL_F_SSL_GET_NEW_SESSION; #else goto not_there; #endif } if (!memcmp(name, "OPENSSL_VERSION_MAJOR", 21)) { /* ^ */ #ifdef OPENSSL_VERSION_MAJOR return OPENSSL_VERSION_MAJOR; #else goto not_there; #endif } if (!memcmp(name, "OPENSSL_VERSION_MINOR", 21)) { /* ^ */ #ifdef OPENSSL_VERSION_MINOR return OPENSSL_VERSION_MINOR; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "XN_FLAG_SEP_CPLUS_SPC", 21)) { /* ^ */ #ifdef XN_FLAG_SEP_CPLUS_SPC return XN_FLAG_SEP_CPLUS_SPC; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_SEP_SPLUS_SPC", 21)) { /* ^ */ #ifdef XN_FLAG_SEP_SPLUS_SPC return XN_FLAG_SEP_SPLUS_SPC; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "ASN1_STRFLGS_ESC_CTRL", 21)) { /* ^ */ #ifdef ASN1_STRFLGS_ESC_CTRL return ASN1_STRFLGS_ESC_CTRL; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "SSL3_MT_HELLO_REQUEST", 21)) { /* ^ */ #ifdef SSL3_MT_HELLO_REQUEST return SSL3_MT_HELLO_REQUEST; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "F_REQUEST_CERTIFICATE", 21)) { /* ^ */ #ifdef SSL_F_REQUEST_CERTIFICATE return SSL_F_REQUEST_CERTIFICATE; #else goto not_there; #endif } if (!memcmp(name, "F_SSL_USE_CERTIFICATE", 21)) { /* ^ */ #ifdef SSL_F_SSL_USE_CERTIFICATE return SSL_F_SSL_USE_CERTIFICATE; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "OP_NETSCAPE_CA_DN_BUG", 21)) { /* ^ */ #ifdef SSL_OP_NETSCAPE_CA_DN_BUG return SSL_OP_NETSCAPE_CA_DN_BUG; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_SMIMECapabilities", 21)) { /* ^ */ #ifdef NID_SMIMECapabilities return NID_SMIMECapabilities; #else goto not_there; #endif } break; case 'm': if (!memcmp(name, "NID_pkcs9_signingTime", 21)) { /* ^ */ #ifdef NID_pkcs9_signingTime return NID_pkcs9_signingTime; #else goto not_there; #endif } break; case 'p': if (!memcmp(name, "NID_pkcs9_contentType", 21)) { /* ^ */ #ifdef NID_pkcs9_contentType return NID_pkcs9_contentType; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_netscape_base_url", 21)) { /* ^ */ #ifdef NID_netscape_base_url return NID_netscape_base_url; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_basic_constraints", 21)) { /* ^ */ #ifdef NID_basic_constraints return NID_basic_constraints; #else goto not_there; #endif } break; } break; case 22: /* Names all of length 22. */ /* ASN1_STRFLGS_ESC_QUOTE ERROR_WANT_X509_LOOKUP F_SSL_SESSION_PRINT_FP NID_netscape_cert_type NID_netscape_data_type NID_pkcs9_emailAddress OPENSSL_VERSION_NUMBER OPENSSL_VERSION_STRING OP_NO_ENCRYPT_THEN_MAC R_PEER_ERROR_NO_CIPHER SESS_CACHE_NO_INTERNAL TLSEXT_STATUSTYPE_ocsp V_OCSP_CERTSTATUS_GOOD X509_TRUST_OBJECT_SIGN X509_V_ERR_UNSPECIFIED X509_V_FLAG_USE_DELTAS XN_FLAG_SEP_COMMA_PLUS */ /* Offset 18 gives the best switch position. */ switch (name[18]) { case 'F': if (!memcmp(name, "X509_V_ERR_UNSPECIFIED", 22)) { /* ^ */ #ifdef X509_V_ERR_UNSPECIFIED return X509_V_ERR_UNSPECIFIED; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "V_OCSP_CERTSTATUS_GOOD", 22)) { /* ^ */ #ifdef V_OCSP_CERTSTATUS_GOOD return V_OCSP_CERTSTATUS_GOOD; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "X509_V_FLAG_USE_DELTAS", 22)) { /* ^ */ #ifdef X509_V_FLAG_USE_DELTAS return X509_V_FLAG_USE_DELTAS; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "OPENSSL_VERSION_NUMBER", 22)) { /* ^ */ #ifdef OPENSSL_VERSION_NUMBER return OPENSSL_VERSION_NUMBER; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "ERROR_WANT_X509_LOOKUP", 22)) { /* ^ */ #ifdef SSL_ERROR_WANT_X509_LOOKUP return SSL_ERROR_WANT_X509_LOOKUP; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "R_PEER_ERROR_NO_CIPHER", 22)) { /* ^ */ #ifdef SSL_R_PEER_ERROR_NO_CIPHER return SSL_R_PEER_ERROR_NO_CIPHER; #else goto not_there; #endif } if (!memcmp(name, "XN_FLAG_SEP_COMMA_PLUS", 22)) { /* ^ */ #ifdef XN_FLAG_SEP_COMMA_PLUS return XN_FLAG_SEP_COMMA_PLUS; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "OPENSSL_VERSION_STRING", 22)) { /* ^ */ #ifdef OPENSSL_VERSION_STRING return OPENSSL_VERSION_STRING; #else goto not_there; #endif } if (!memcmp(name, "SESS_CACHE_NO_INTERNAL", 22)) { /* ^ */ #ifdef SSL_SESS_CACHE_NO_INTERNAL return SSL_SESS_CACHE_NO_INTERNAL; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_TRUST_OBJECT_SIGN", 22)) { /* ^ */ #ifdef X509_TRUST_OBJECT_SIGN return X509_TRUST_OBJECT_SIGN; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "F_SSL_SESSION_PRINT_FP", 22)) { /* ^ */ #ifdef SSL_F_SSL_SESSION_PRINT_FP return SSL_F_SSL_SESSION_PRINT_FP; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "ASN1_STRFLGS_ESC_QUOTE", 22)) { /* ^ */ #ifdef ASN1_STRFLGS_ESC_QUOTE return ASN1_STRFLGS_ESC_QUOTE; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "OP_NO_ENCRYPT_THEN_MAC", 22)) { /* ^ */ #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC return SSL_OP_NO_ENCRYPT_THEN_MAC; #else goto not_there; #endif } break; case 'o': if (!memcmp(name, "TLSEXT_STATUSTYPE_ocsp", 22)) { /* ^ */ #ifdef TLSEXT_STATUSTYPE_ocsp return TLSEXT_STATUSTYPE_ocsp; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_pkcs9_emailAddress", 22)) { /* ^ */ #ifdef NID_pkcs9_emailAddress return NID_pkcs9_emailAddress; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_netscape_cert_type", 22)) { /* ^ */ #ifdef NID_netscape_cert_type return NID_netscape_cert_type; #else goto not_there; #endif } if (!memcmp(name, "NID_netscape_data_type", 22)) { /* ^ */ #ifdef NID_netscape_data_type return NID_netscape_data_type; #else goto not_there; #endif } break; } break; case 23: /* Names all of length 23. */ /* F_GET_CLIENT_MASTER_KEY F_SSL_USE_RSAPRIVATEKEY LIBRESSL_VERSION_NUMBER NID_pkcs8ShroudedKeyBag NID_pkcs9_messageDigest NID_stateOrProvinceName OPENSSL_INFO_CONFIG_DIR OP_CRYPTOPRO_TLSEXT_BUG R_BAD_RESPONSE_ARGUMENT R_PUBLIC_KEY_IS_NOT_RSA SSL2_MT_CLIENT_FINISHED SSL2_MT_SERVER_FINISHED SSL3_MT_CERTIFICATE_URL X509_PURPOSE_SMIME_SIGN X509_PURPOSE_SSL_CLIENT X509_PURPOSE_SSL_SERVER X509_TRUST_OCSP_REQUEST X509_V_ERR_CERT_REVOKED X509_V_ERR_INVALID_CALL X509_V_ERR_STORE_LOOKUP X509_V_FLAG_INHIBIT_ANY X509_V_FLAG_INHIBIT_MAP X509_V_FLAG_POLICY_MASK X509_V_FLAG_X509_STRICT */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case '5': if (!memcmp(name, "X509_V_FLAG_X509_STRICT", 23)) { /* ^ */ #ifdef X509_V_FLAG_X509_STRICT return X509_V_FLAG_X509_STRICT; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "OPENSSL_INFO_CONFIG_DIR", 23)) { /* ^ */ #ifdef OPENSSL_INFO_CONFIG_DIR return OPENSSL_INFO_CONFIG_DIR; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "R_BAD_RESPONSE_ARGUMENT", 23)) { /* ^ */ #ifdef SSL_R_BAD_RESPONSE_ARGUMENT return SSL_R_BAD_RESPONSE_ARGUMENT; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "SSL3_MT_CERTIFICATE_URL", 23)) { /* ^ */ #ifdef SSL3_MT_CERTIFICATE_URL return SSL3_MT_CERTIFICATE_URL; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "LIBRESSL_VERSION_NUMBER", 23)) { /* ^ */ #ifdef LIBRESSL_VERSION_NUMBER return LIBRESSL_VERSION_NUMBER; #else goto not_there; #endif } if (!memcmp(name, "R_PUBLIC_KEY_IS_NOT_RSA", 23)) { /* ^ */ #ifdef SSL_R_PUBLIC_KEY_IS_NOT_RSA return SSL_R_PUBLIC_KEY_IS_NOT_RSA; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "F_GET_CLIENT_MASTER_KEY", 23)) { /* ^ */ #ifdef SSL_F_GET_CLIENT_MASTER_KEY return SSL_F_GET_CLIENT_MASTER_KEY; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_V_FLAG_INHIBIT_ANY", 23)) { /* ^ */ #ifdef X509_V_FLAG_INHIBIT_ANY return X509_V_FLAG_INHIBIT_ANY; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_INHIBIT_MAP", 23)) { /* ^ */ #ifdef X509_V_FLAG_INHIBIT_MAP return X509_V_FLAG_INHIBIT_MAP; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_STORE_LOOKUP", 23)) { /* ^ */ #ifdef X509_V_ERR_STORE_LOOKUP return X509_V_ERR_STORE_LOOKUP; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_POLICY_MASK", 23)) { /* ^ */ #ifdef X509_V_FLAG_POLICY_MASK return X509_V_FLAG_POLICY_MASK; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "F_SSL_USE_RSAPRIVATEKEY", 23)) { /* ^ */ #ifdef SSL_F_SSL_USE_RSAPRIVATEKEY return SSL_F_SSL_USE_RSAPRIVATEKEY; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL2_MT_SERVER_FINISHED", 23)) { /* ^ */ #ifdef SSL2_MT_SERVER_FINISHED return SSL2_MT_SERVER_FINISHED; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_CERT_REVOKED", 23)) { /* ^ */ #ifdef X509_V_ERR_CERT_REVOKED return X509_V_ERR_CERT_REVOKED; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_PURPOSE_SMIME_SIGN", 23)) { /* ^ */ #ifdef X509_PURPOSE_SMIME_SIGN return X509_PURPOSE_SMIME_SIGN; #else goto not_there; #endif } if (!memcmp(name, "X509_PURPOSE_SSL_CLIENT", 23)) { /* ^ */ #ifdef X509_PURPOSE_SSL_CLIENT return X509_PURPOSE_SSL_CLIENT; #else goto not_there; #endif } if (!memcmp(name, "X509_PURPOSE_SSL_SERVER", 23)) { /* ^ */ #ifdef X509_PURPOSE_SSL_SERVER return X509_PURPOSE_SSL_SERVER; #else goto not_there; #endif } if (!memcmp(name, "X509_TRUST_OCSP_REQUEST", 23)) { /* ^ */ #ifdef X509_TRUST_OCSP_REQUEST return X509_TRUST_OCSP_REQUEST; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "OP_CRYPTOPRO_TLSEXT_BUG", 23)) { /* ^ */ #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG return SSL_OP_CRYPTOPRO_TLSEXT_BUG; #else goto not_there; #endif } if (!memcmp(name, "SSL2_MT_CLIENT_FINISHED", 23)) { /* ^ */ #ifdef SSL2_MT_CLIENT_FINISHED return SSL2_MT_CLIENT_FINISHED; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "X509_V_ERR_INVALID_CALL", 23)) { /* ^ */ #ifdef X509_V_ERR_INVALID_CALL return X509_V_ERR_INVALID_CALL; #else goto not_there; #endif } break; case 'o': if (!memcmp(name, "NID_stateOrProvinceName", 23)) { /* ^ */ #ifdef NID_stateOrProvinceName return NID_stateOrProvinceName; #else goto not_there; #endif } break; case 's': if (!memcmp(name, "NID_pkcs9_messageDigest", 23)) { /* ^ */ #ifdef NID_pkcs9_messageDigest return NID_pkcs9_messageDigest; #else goto not_there; #endif } break; case 'u': if (!memcmp(name, "NID_pkcs8ShroudedKeyBag", 23)) { /* ^ */ #ifdef NID_pkcs8ShroudedKeyBag return NID_pkcs8ShroudedKeyBag; #else goto not_there; #endif } break; } break; case 24: /* Names all of length 24. */ /* F_SSL_RSA_PUBLIC_ENCRYPT NID_certificate_policies NID_md2WithRSAEncryption NID_md5WithRSAEncryption NID_netscape_renewal_url NID_pbeWithMD2AndDES_CBC NID_pbeWithMD2AndRC2_CBC NID_pbeWithMD5AndDES_CBC NID_pbeWithMD5AndRC2_CBC NID_shaWithRSAEncryption OPENSSL_INFO_ENGINES_DIR OPENSSL_INFO_MODULES_DIR OPENSSL_INFO_SEED_SOURCE OP_LEGACY_SERVER_CONNECT OP_MICROSOFT_SESS_ID_BUG OP_TLS_BLOCK_PADDING_BUG R_CHALLENGE_IS_DIFFERENT R_CIPHER_TABLE_SRC_ERROR R_PEER_ERROR_CERTIFICATE R_READ_WRONG_PACKET_TYPE SESS_CACHE_NO_AUTO_CLEAR SSL3_RT_APPLICATION_DATA X509_PURPOSE_OCSP_HELPER X509_V_ERR_CERT_REJECTED X509_V_ERR_DANE_NO_MATCH X509_V_ERR_NO_VALID_SCTS X509_V_FLAG_POLICY_CHECK */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case '2': if (!memcmp(name, "NID_pbeWithMD2AndDES_CBC", 24)) { /* ^ */ #ifdef NID_pbeWithMD2AndDES_CBC return NID_pbeWithMD2AndDES_CBC; #else goto not_there; #endif } if (!memcmp(name, "NID_pbeWithMD2AndRC2_CBC", 24)) { /* ^ */ #ifdef NID_pbeWithMD2AndRC2_CBC return NID_pbeWithMD2AndRC2_CBC; #else goto not_there; #endif } break; case '5': if (!memcmp(name, "NID_pbeWithMD5AndDES_CBC", 24)) { /* ^ */ #ifdef NID_pbeWithMD5AndDES_CBC return NID_pbeWithMD5AndDES_CBC; #else goto not_there; #endif } if (!memcmp(name, "NID_pbeWithMD5AndRC2_CBC", 24)) { /* ^ */ #ifdef NID_pbeWithMD5AndRC2_CBC return NID_pbeWithMD5AndRC2_CBC; #else goto not_there; #endif } break; case 'A': if (!memcmp(name, "NID_md2WithRSAEncryption", 24)) { /* ^ */ #ifdef NID_md2WithRSAEncryption return NID_md2WithRSAEncryption; #else goto not_there; #endif } if (!memcmp(name, "NID_md5WithRSAEncryption", 24)) { /* ^ */ #ifdef NID_md5WithRSAEncryption return NID_md5WithRSAEncryption; #else goto not_there; #endif } if (!memcmp(name, "NID_shaWithRSAEncryption", 24)) { /* ^ */ #ifdef NID_shaWithRSAEncryption return NID_shaWithRSAEncryption; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "R_PEER_ERROR_CERTIFICATE", 24)) { /* ^ */ #ifdef SSL_R_PEER_ERROR_CERTIFICATE return SSL_R_PEER_ERROR_CERTIFICATE; #else goto not_there; #endif } if (!memcmp(name, "SSL3_RT_APPLICATION_DATA", 24)) { /* ^ */ #ifdef SSL3_RT_APPLICATION_DATA return SSL3_RT_APPLICATION_DATA; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "OPENSSL_INFO_ENGINES_DIR", 24)) { /* ^ */ #ifdef OPENSSL_INFO_ENGINES_DIR return OPENSSL_INFO_ENGINES_DIR; #else goto not_there; #endif } if (!memcmp(name, "R_CIPHER_TABLE_SRC_ERROR", 24)) { /* ^ */ #ifdef SSL_R_CIPHER_TABLE_SRC_ERROR return SSL_R_CIPHER_TABLE_SRC_ERROR; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "F_SSL_RSA_PUBLIC_ENCRYPT", 24)) { /* ^ */ #ifdef SSL_F_SSL_RSA_PUBLIC_ENCRYPT return SSL_F_SSL_RSA_PUBLIC_ENCRYPT; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "OPENSSL_INFO_MODULES_DIR", 24)) { /* ^ */ #ifdef OPENSSL_INFO_MODULES_DIR return OPENSSL_INFO_MODULES_DIR; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_V_ERR_DANE_NO_MATCH", 24)) { /* ^ */ #ifdef X509_V_ERR_DANE_NO_MATCH return X509_V_ERR_DANE_NO_MATCH; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_PURPOSE_OCSP_HELPER", 24)) { /* ^ */ #ifdef X509_PURPOSE_OCSP_HELPER return X509_PURPOSE_OCSP_HELPER; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_POLICY_CHECK", 24)) { /* ^ */ #ifdef X509_V_FLAG_POLICY_CHECK return X509_V_FLAG_POLICY_CHECK; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "OP_TLS_BLOCK_PADDING_BUG", 24)) { /* ^ */ #ifdef SSL_OP_TLS_BLOCK_PADDING_BUG return SSL_OP_TLS_BLOCK_PADDING_BUG; #else goto not_there; #endif } if (!memcmp(name, "R_READ_WRONG_PACKET_TYPE", 24)) { /* ^ */ #ifdef SSL_R_READ_WRONG_PACKET_TYPE return SSL_R_READ_WRONG_PACKET_TYPE; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "X509_V_ERR_CERT_REJECTED", 24)) { /* ^ */ #ifdef X509_V_ERR_CERT_REJECTED return X509_V_ERR_CERT_REJECTED; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "OPENSSL_INFO_SEED_SOURCE", 24)) { /* ^ */ #ifdef OPENSSL_INFO_SEED_SOURCE return OPENSSL_INFO_SEED_SOURCE; #else goto not_there; #endif } if (!memcmp(name, "OP_MICROSOFT_SESS_ID_BUG", 24)) { /* ^ */ #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG return SSL_OP_MICROSOFT_SESS_ID_BUG; #else goto not_there; #endif } if (!memcmp(name, "R_CHALLENGE_IS_DIFFERENT", 24)) { /* ^ */ #ifdef SSL_R_CHALLENGE_IS_DIFFERENT return SSL_R_CHALLENGE_IS_DIFFERENT; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "OP_LEGACY_SERVER_CONNECT", 24)) { /* ^ */ #ifdef SSL_OP_LEGACY_SERVER_CONNECT return SSL_OP_LEGACY_SERVER_CONNECT; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "SESS_CACHE_NO_AUTO_CLEAR", 24)) { /* ^ */ #ifdef SSL_SESS_CACHE_NO_AUTO_CLEAR return SSL_SESS_CACHE_NO_AUTO_CLEAR; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_NO_VALID_SCTS", 24)) { /* ^ */ #ifdef X509_V_ERR_NO_VALID_SCTS return X509_V_ERR_NO_VALID_SCTS; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_netscape_renewal_url", 24)) { /* ^ */ #ifdef NID_netscape_renewal_url return NID_netscape_renewal_url; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_certificate_policies", 24)) { /* ^ */ #ifdef NID_certificate_policies return NID_certificate_policies; #else goto not_there; #endif } break; } break; case 25: /* Names all of length 25. */ /* F_SSL_RSA_PRIVATE_DECRYPT F_SSL_USE_PRIVATEKEY_ASN1 F_SSL_USE_PRIVATEKEY_FILE MODE_ENABLE_PARTIAL_WRITE NID_pbeWithSHA1AndDES_CBC NID_pbeWithSHA1AndRC2_CBC NID_sha1WithRSAEncryption OPENSSL_INFO_CPU_SETTINGS OP_MSIE_SSLV2_RSA_PADDING OP_NETSCAPE_CHALLENGE_BUG OP_SAFARI_ECDHE_ECDSA_BUG R_BAD_AUTHENTICATION_TYPE SSL2_MT_CLIENT_MASTER_KEY SSL3_MT_END_OF_EARLY_DATA SSL3_MT_NEWSESSION_TICKET SSL3_MT_SUPPLEMENTAL_DATA V_OCSP_CERTSTATUS_REVOKED V_OCSP_CERTSTATUS_UNKNOWN X509_V_ERR_CA_MD_TOO_WEAK X509_V_ERR_CERT_UNTRUSTED X509_V_ERR_EMAIL_MISMATCH X509_V_ERR_INVALID_NON_CA X509_V_ERR_SUBTREE_MINMAX X509_V_FLAG_CRL_CHECK_ALL 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_TRUSTED_FIRST */ /* Offset 19 gives the best switch position. */ switch (name[19]) { case 'A': if (!memcmp(name, "OP_MSIE_SSLV2_RSA_PADDING", 25)) { /* ^ */ #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING return SSL_OP_MSIE_SSLV2_RSA_PADDING; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "NID_pbeWithSHA1AndRC2_CBC", 25)) { /* ^ */ #ifdef NID_pbeWithSHA1AndRC2_CBC return NID_pbeWithSHA1AndRC2_CBC; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_CRL_CHECK_ALL", 25)) { /* ^ */ #ifdef X509_V_FLAG_CRL_CHECK_ALL return X509_V_FLAG_CRL_CHECK_ALL; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_NO_ALT_CHAINS", 25)) { /* ^ */ #ifdef X509_V_FLAG_NO_ALT_CHAINS return X509_V_FLAG_NO_ALT_CHAINS; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "F_SSL_RSA_PRIVATE_DECRYPT", 25)) { /* ^ */ #ifdef SSL_F_SSL_RSA_PRIVATE_DECRYPT return SSL_F_SSL_RSA_PRIVATE_DECRYPT; #else goto not_there; #endif } if (!memcmp(name, "NID_pbeWithSHA1AndDES_CBC", 25)) { /* ^ */ #ifdef NID_pbeWithSHA1AndDES_CBC return NID_pbeWithSHA1AndDES_CBC; #else goto not_there; #endif } if (!memcmp(name, "SSL2_MT_CLIENT_MASTER_KEY", 25)) { /* ^ */ #ifdef SSL2_MT_CLIENT_MASTER_KEY return SSL2_MT_CLIENT_MASTER_KEY; #else goto not_there; #endif } if (!memcmp(name, "V_OCSP_CERTSTATUS_REVOKED", 25)) { /* ^ */ #ifdef V_OCSP_CERTSTATUS_REVOKED return V_OCSP_CERTSTATUS_REVOKED; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "OP_NETSCAPE_CHALLENGE_BUG", 25)) { /* ^ */ #ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG return SSL_OP_NETSCAPE_CHALLENGE_BUG; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "X509_V_FLAG_NO_CHECK_TIME", 25)) { /* ^ */ #ifdef X509_V_FLAG_NO_CHECK_TIME return X509_V_FLAG_NO_CHECK_TIME; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "SSL3_MT_SUPPLEMENTAL_DATA", 25)) { /* ^ */ #ifdef SSL3_MT_SUPPLEMENTAL_DATA return SSL3_MT_SUPPLEMENTAL_DATA; #else goto not_there; #endif } break; case 'M': if (!memcmp(name, "X509_V_ERR_SUBTREE_MINMAX", 25)) { /* ^ */ #ifdef X509_V_ERR_SUBTREE_MINMAX return X509_V_ERR_SUBTREE_MINMAX; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "R_BAD_AUTHENTICATION_TYPE", 25)) { /* ^ */ #ifdef SSL_R_BAD_AUTHENTICATION_TYPE return SSL_R_BAD_AUTHENTICATION_TYPE; #else goto not_there; #endif } if (!memcmp(name, "V_OCSP_CERTSTATUS_UNKNOWN", 25)) { /* ^ */ #ifdef V_OCSP_CERTSTATUS_UNKNOWN return V_OCSP_CERTSTATUS_UNKNOWN; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_INVALID_NON_CA", 25)) { /* ^ */ #ifdef X509_V_ERR_INVALID_NON_CA return X509_V_ERR_INVALID_NON_CA; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_CA_MD_TOO_WEAK", 25)) { /* ^ */ #ifdef X509_V_ERR_CA_MD_TOO_WEAK return X509_V_ERR_CA_MD_TOO_WEAK; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "X509_V_FLAG_NOTIFY_POLICY", 25)) { /* ^ */ #ifdef X509_V_FLAG_NOTIFY_POLICY return X509_V_FLAG_NOTIFY_POLICY; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "X509_V_ERR_CERT_UNTRUSTED", 25)) { /* ^ */ #ifdef X509_V_ERR_CERT_UNTRUSTED return X509_V_ERR_CERT_UNTRUSTED; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "OP_SAFARI_ECDHE_ECDSA_BUG", 25)) { /* ^ */ #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG return SSL_OP_SAFARI_ECDHE_ECDSA_BUG; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_EMAIL_MISMATCH", 25)) { /* ^ */ #ifdef X509_V_ERR_EMAIL_MISMATCH return X509_V_ERR_EMAIL_MISMATCH; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "OPENSSL_INFO_CPU_SETTINGS", 25)) { /* ^ */ #ifdef OPENSSL_INFO_CPU_SETTINGS return OPENSSL_INFO_CPU_SETTINGS; #else goto not_there; #endif } if (!memcmp(name, "SSL3_MT_NEWSESSION_TICKET", 25)) { /* ^ */ #ifdef SSL3_MT_NEWSESSION_TICKET return SSL3_MT_NEWSESSION_TICKET; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "X509_V_FLAG_LEGACY_VERIFY", 25)) { /* ^ */ #ifdef X509_V_FLAG_LEGACY_VERIFY return X509_V_FLAG_LEGACY_VERIFY; #else goto not_there; #endif } break; case 'Y': if (!memcmp(name, "F_SSL_USE_PRIVATEKEY_ASN1", 25)) { /* ^ */ #ifdef SSL_F_SSL_USE_PRIVATEKEY_ASN1 return SSL_F_SSL_USE_PRIVATEKEY_ASN1; #else goto not_there; #endif } if (!memcmp(name, "F_SSL_USE_PRIVATEKEY_FILE", 25)) { /* ^ */ #ifdef SSL_F_SSL_USE_PRIVATEKEY_FILE return SSL_F_SSL_USE_PRIVATEKEY_FILE; #else goto not_there; #endif } if (!memcmp(name, "SSL3_MT_END_OF_EARLY_DATA", 25)) { /* ^ */ #ifdef SSL3_MT_END_OF_EARLY_DATA return SSL3_MT_END_OF_EARLY_DATA; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "MODE_ENABLE_PARTIAL_WRITE", 25)) { /* ^ */ #ifdef SSL_MODE_ENABLE_PARTIAL_WRITE return SSL_MODE_ENABLE_PARTIAL_WRITE; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_PARTIAL_CHAIN", 25)) { /* ^ */ #ifdef X509_V_FLAG_PARTIAL_CHAIN return X509_V_FLAG_PARTIAL_CHAIN; #else goto not_there; #endif } if (!memcmp(name, "X509_V_FLAG_TRUSTED_FIRST", 25)) { /* ^ */ #ifdef X509_V_FLAG_TRUSTED_FIRST return X509_V_FLAG_TRUSTED_FIRST; #else goto not_there; #endif } break; case 'y': if (!memcmp(name, "NID_sha1WithRSAEncryption", 25)) { /* ^ */ #ifdef NID_sha1WithRSAEncryption return NID_sha1WithRSAEncryption; #else goto not_there; #endif } break; } break; case 26: /* Names all of length 26. */ /* F_SSL_USE_CERTIFICATE_ASN1 F_SSL_USE_CERTIFICATE_FILE NID_netscape_ca_policy_url NID_netscape_cert_sequence NID_organizationalUnitName NID_pbeWithMD5AndCast5_CBC NID_pkcs9_countersignature NID_pkcs9_unstructuredName NID_subject_key_identifier OPENSSL_INFO_DSO_EXTENSION OP_ENABLE_MIDDLEBOX_COMPAT OP_NO_CLIENT_RENEGOTIATION R_INVALID_CHALLENGE_LENGTH R_NO_CERTIFICATE_SPECIFIED R_PUBLIC_KEY_ENCRYPT_ERROR SSL2_MT_CLIENT_CERTIFICATE SSL3_MT_CERTIFICATE_STATUS SSL3_MT_CERTIFICATE_VERIFY SSL3_MT_CHANGE_CIPHER_SPEC SSL3_RT_CHANGE_CIPHER_SPEC SSL3_RT_INNER_CONTENT_TYPE X509_PURPOSE_NS_SSL_SERVER X509_PURPOSE_SMIME_ENCRYPT X509_V_ERR_CRL_HAS_EXPIRED X509_V_ERR_INVALID_PURPOSE X509_V_FLAG_SUITEB_128_LOS X509_V_FLAG_SUITEB_192_LOS X509_V_FLAG_USE_CHECK_TIME */ /* Offset 20 gives the best switch position. */ switch (name[20]) { case '2': if (!memcmp(name, "X509_V_FLAG_SUITEB_128_LOS", 26)) { /* ^ */ #ifdef X509_V_FLAG_SUITEB_128_LOS return X509_V_FLAG_SUITEB_128_LOS; #else goto not_there; #endif } break; case '9': if (!memcmp(name, "X509_V_FLAG_SUITEB_192_LOS", 26)) { /* ^ */ #ifdef X509_V_FLAG_SUITEB_192_LOS return X509_V_FLAG_SUITEB_192_LOS; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "OP_ENABLE_MIDDLEBOX_COMPAT", 26)) { /* ^ */ #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT return SSL_OP_ENABLE_MIDDLEBOX_COMPAT; #else goto not_there; #endif } if (!memcmp(name, "R_NO_CERTIFICATE_SPECIFIED", 26)) { /* ^ */ #ifdef SSL_R_NO_CERTIFICATE_SPECIFIED return SSL_R_NO_CERTIFICATE_SPECIFIED; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "F_SSL_USE_CERTIFICATE_ASN1", 26)) { /* ^ */ #ifdef SSL_F_SSL_USE_CERTIFICATE_ASN1 return SSL_F_SSL_USE_CERTIFICATE_ASN1; #else goto not_there; #endif } if (!memcmp(name, "F_SSL_USE_CERTIFICATE_FILE", 26)) { /* ^ */ #ifdef SSL_F_SSL_USE_CERTIFICATE_FILE return SSL_F_SSL_USE_CERTIFICATE_FILE; #else goto not_there; #endif } if (!memcmp(name, "OPENSSL_INFO_DSO_EXTENSION", 26)) { /* ^ */ #ifdef OPENSSL_INFO_DSO_EXTENSION return OPENSSL_INFO_DSO_EXTENSION; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "SSL2_MT_CLIENT_CERTIFICATE", 26)) { /* ^ */ #ifdef SSL2_MT_CLIENT_CERTIFICATE return SSL2_MT_CLIENT_CERTIFICATE; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "OP_NO_CLIENT_RENEGOTIATION", 26)) { /* ^ */ #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION return SSL_OP_NO_CLIENT_RENEGOTIATION; #else goto not_there; #endif } break; case 'K': if (!memcmp(name, "X509_V_FLAG_USE_CHECK_TIME", 26)) { /* ^ */ #ifdef X509_V_FLAG_USE_CHECK_TIME return X509_V_FLAG_USE_CHECK_TIME; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "R_INVALID_CHALLENGE_LENGTH", 26)) { /* ^ */ #ifdef SSL_R_INVALID_CHALLENGE_LENGTH return SSL_R_INVALID_CHALLENGE_LENGTH; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_PURPOSE_SMIME_ENCRYPT", 26)) { /* ^ */ #ifdef X509_PURPOSE_SMIME_ENCRYPT return X509_PURPOSE_SMIME_ENCRYPT; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL3_MT_CHANGE_CIPHER_SPEC", 26)) { /* ^ */ #ifdef SSL3_MT_CHANGE_CIPHER_SPEC return SSL3_MT_CHANGE_CIPHER_SPEC; #else goto not_there; #endif } if (!memcmp(name, "SSL3_RT_CHANGE_CIPHER_SPEC", 26)) { /* ^ */ #ifdef SSL3_RT_CHANGE_CIPHER_SPEC return SSL3_RT_CHANGE_CIPHER_SPEC; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "SSL3_MT_CERTIFICATE_STATUS", 26)) { /* ^ */ #ifdef SSL3_MT_CERTIFICATE_STATUS return SSL3_MT_CERTIFICATE_STATUS; #else goto not_there; #endif } if (!memcmp(name, "X509_PURPOSE_NS_SSL_SERVER", 26)) { /* ^ */ #ifdef X509_PURPOSE_NS_SSL_SERVER return X509_PURPOSE_NS_SSL_SERVER; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "SSL3_RT_INNER_CONTENT_TYPE", 26)) { /* ^ */ #ifdef SSL3_RT_INNER_CONTENT_TYPE return SSL3_RT_INNER_CONTENT_TYPE; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "X509_V_ERR_INVALID_PURPOSE", 26)) { /* ^ */ #ifdef X509_V_ERR_INVALID_PURPOSE return X509_V_ERR_INVALID_PURPOSE; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "SSL3_MT_CERTIFICATE_VERIFY", 26)) { /* ^ */ #ifdef SSL3_MT_CERTIFICATE_VERIFY return SSL3_MT_CERTIFICATE_VERIFY; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "X509_V_ERR_CRL_HAS_EXPIRED", 26)) { /* ^ */ #ifdef X509_V_ERR_CRL_HAS_EXPIRED return X509_V_ERR_CRL_HAS_EXPIRED; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "R_PUBLIC_KEY_ENCRYPT_ERROR", 26)) { /* ^ */ #ifdef SSL_R_PUBLIC_KEY_ENCRYPT_ERROR return SSL_R_PUBLIC_KEY_ENCRYPT_ERROR; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_netscape_ca_policy_url", 26)) { /* ^ */ #ifdef NID_netscape_ca_policy_url return NID_netscape_ca_policy_url; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_pkcs9_unstructuredName", 26)) { /* ^ */ #ifdef NID_pkcs9_unstructuredName return NID_pkcs9_unstructuredName; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_organizationalUnitName", 26)) { /* ^ */ #ifdef NID_organizationalUnitName return NID_organizationalUnitName; #else goto not_there; #endif } break; case 'n': if (!memcmp(name, "NID_pkcs9_countersignature", 26)) { /* ^ */ #ifdef NID_pkcs9_countersignature return NID_pkcs9_countersignature; #else goto not_there; #endif } break; case 'q': if (!memcmp(name, "NID_netscape_cert_sequence", 26)) { /* ^ */ #ifdef NID_netscape_cert_sequence return NID_netscape_cert_sequence; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_pbeWithMD5AndCast5_CBC", 26)) { /* ^ */ #ifdef NID_pbeWithMD5AndCast5_CBC return NID_pbeWithMD5AndCast5_CBC; #else goto not_there; #endif } if (!memcmp(name, "NID_subject_key_identifier", 26)) { /* ^ */ #ifdef NID_subject_key_identifier return NID_subject_key_identifier; #else goto not_there; #endif } break; } break; case 27: /* Names all of length 27. */ /* NID_crl_distribution_points NID_netscape_cert_extension NID_netscape_revocation_url NID_pbe_WithSHA1And40BitRC4 NID_pkcs9_challengePassword NID_pkcs9_extCertAttributes OPENSSL_FULL_VERSION_STRING OPENSSL_INFO_LIST_SEPARATOR OP_CIPHER_SERVER_PREFERENCE OP_SSLEAY_080_CLIENT_DH_BUG R_BAD_SSL_SESSION_ID_LENGTH R_UNKNOWN_REMOTE_ERROR_TYPE SSL2_MT_REQUEST_CERTIFICATE SSL3_MT_CERTIFICATE_REQUEST SSL3_MT_CLIENT_KEY_EXCHANGE SSL3_MT_SERVER_KEY_EXCHANGE VERIFY_FAIL_IF_NO_PEER_CERT X509_PURPOSE_TIMESTAMP_SIGN X509_V_ERR_CA_KEY_TOO_SMALL X509_V_ERR_CERT_HAS_EXPIRED X509_V_ERR_EE_KEY_TOO_SMALL X509_V_FLAG_CB_ISSUER_CHECK X509_V_FLAG_EXPLICIT_POLICY X509_V_FLAG_IGNORE_CRITICAL XN_FLAG_DUMP_UNKNOWN_FIELDS */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case 'B': if (!memcmp(name, "X509_V_FLAG_CB_ISSUER_CHECK", 27)) { /* ^ */ #ifdef X509_V_FLAG_CB_ISSUER_CHECK return X509_V_FLAG_CB_ISSUER_CHECK; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "NID_pkcs9_extCertAttributes", 27)) { /* ^ */ #ifdef NID_pkcs9_extCertAttributes return NID_pkcs9_extCertAttributes; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "SSL3_MT_CERTIFICATE_REQUEST", 27)) { /* ^ */ #ifdef SSL3_MT_CERTIFICATE_REQUEST return SSL3_MT_CERTIFICATE_REQUEST; #else goto not_there; #endif } if (!memcmp(name, "VERIFY_FAIL_IF_NO_PEER_CERT", 27)) { /* ^ */ #ifdef SSL_VERIFY_FAIL_IF_NO_PEER_CERT return SSL_VERIFY_FAIL_IF_NO_PEER_CERT; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "X509_V_FLAG_IGNORE_CRITICAL", 27)) { /* ^ */ #ifdef X509_V_FLAG_IGNORE_CRITICAL return X509_V_FLAG_IGNORE_CRITICAL; #else goto not_there; #endif } break; case 'H': if (!memcmp(name, "NID_pbe_WithSHA1And40BitRC4", 27)) { /* ^ */ #ifdef NID_pbe_WithSHA1And40BitRC4 return NID_pbe_WithSHA1And40BitRC4; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "OPENSSL_INFO_LIST_SEPARATOR", 27)) { /* ^ */ #ifdef OPENSSL_INFO_LIST_SEPARATOR return OPENSSL_INFO_LIST_SEPARATOR; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "R_UNKNOWN_REMOTE_ERROR_TYPE", 27)) { /* ^ */ #ifdef SSL_R_UNKNOWN_REMOTE_ERROR_TYPE return SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL3_MT_SERVER_KEY_EXCHANGE", 27)) { /* ^ */ #ifdef SSL3_MT_SERVER_KEY_EXCHANGE return SSL3_MT_SERVER_KEY_EXCHANGE; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_CERT_HAS_EXPIRED", 27)) { /* ^ */ #ifdef X509_V_ERR_CERT_HAS_EXPIRED return X509_V_ERR_CERT_HAS_EXPIRED; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "R_BAD_SSL_SESSION_ID_LENGTH", 27)) { /* ^ */ #ifdef SSL_R_BAD_SSL_SESSION_ID_LENGTH return SSL_R_BAD_SSL_SESSION_ID_LENGTH; #else goto not_there; #endif } if (!memcmp(name, "SSL2_MT_REQUEST_CERTIFICATE", 27)) { /* ^ */ #ifdef SSL2_MT_REQUEST_CERTIFICATE return SSL2_MT_REQUEST_CERTIFICATE; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "SSL3_MT_CLIENT_KEY_EXCHANGE", 27)) { /* ^ */ #ifdef SSL3_MT_CLIENT_KEY_EXCHANGE return SSL3_MT_CLIENT_KEY_EXCHANGE; #else goto not_there; #endif } if (!memcmp(name, "X509_PURPOSE_TIMESTAMP_SIGN", 27)) { /* ^ */ #ifdef X509_PURPOSE_TIMESTAMP_SIGN return X509_PURPOSE_TIMESTAMP_SIGN; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "XN_FLAG_DUMP_UNKNOWN_FIELDS", 27)) { /* ^ */ #ifdef XN_FLAG_DUMP_UNKNOWN_FIELDS return XN_FLAG_DUMP_UNKNOWN_FIELDS; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "OPENSSL_FULL_VERSION_STRING", 27)) { /* ^ */ #ifdef OPENSSL_FULL_VERSION_STRING return OPENSSL_FULL_VERSION_STRING; #else goto not_there; #endif } if (!memcmp(name, "OP_CIPHER_SERVER_PREFERENCE", 27)) { /* ^ */ #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE return SSL_OP_CIPHER_SERVER_PREFERENCE; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "X509_V_FLAG_EXPLICIT_POLICY", 27)) { /* ^ */ #ifdef X509_V_FLAG_EXPLICIT_POLICY return X509_V_FLAG_EXPLICIT_POLICY; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "OP_SSLEAY_080_CLIENT_DH_BUG", 27)) { /* ^ */ #ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG return SSL_OP_SSLEAY_080_CLIENT_DH_BUG; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_CA_KEY_TOO_SMALL", 27)) { /* ^ */ #ifdef X509_V_ERR_CA_KEY_TOO_SMALL return X509_V_ERR_CA_KEY_TOO_SMALL; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_EE_KEY_TOO_SMALL", 27)) { /* ^ */ #ifdef X509_V_ERR_EE_KEY_TOO_SMALL return X509_V_ERR_EE_KEY_TOO_SMALL; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_netscape_cert_extension", 27)) { /* ^ */ #ifdef NID_netscape_cert_extension return NID_netscape_cert_extension; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_crl_distribution_points", 27)) { /* ^ */ #ifdef NID_crl_distribution_points return NID_crl_distribution_points; #else goto not_there; #endif } break; case 'l': if (!memcmp(name, "NID_pkcs9_challengePassword", 27)) { /* ^ */ #ifdef NID_pkcs9_challengePassword return NID_pkcs9_challengePassword; #else goto not_there; #endif } break; case 'r': if (!memcmp(name, "NID_netscape_revocation_url", 27)) { /* ^ */ #ifdef NID_netscape_revocation_url return NID_netscape_revocation_url; #else goto not_there; #endif } break; } break; case 28: /* Names all of length 28. */ /* F_SSL_USE_RSAPRIVATEKEY_ASN1 F_SSL_USE_RSAPRIVATEKEY_FILE NID_authority_key_identifier NID_netscape_ssl_server_name NID_pbe_WithSHA1And128BitRC4 NID_pkcs7_signedAndEnveloped NID_private_key_usage_period SESS_CACHE_NO_INTERNAL_STORE SSL3_MT_ENCRYPTED_EXTENSIONS X509_CHECK_FLAG_NO_WILDCARDS X509_V_ERR_CRL_NOT_YET_VALID X509_V_ERR_HOSTNAME_MISMATCH X509_V_ERR_INVALID_EXTENSION X509_V_ERR_OCSP_CERT_UNKNOWN X509_V_ERR_UNABLE_TO_GET_CRL X509_V_ERR_UNNESTED_RESOURCE */ /* Offset 11 gives the best switch position. */ switch (name[11]) { case 'C': if (!memcmp(name, "X509_V_ERR_CRL_NOT_YET_VALID", 28)) { /* ^ */ #ifdef X509_V_ERR_CRL_NOT_YET_VALID return X509_V_ERR_CRL_NOT_YET_VALID; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "X509_CHECK_FLAG_NO_WILDCARDS", 28)) { /* ^ */ #ifdef X509_CHECK_FLAG_NO_WILDCARDS return X509_CHECK_FLAG_NO_WILDCARDS; #else goto not_there; #endif } break; case 'H': if (!memcmp(name, "X509_V_ERR_HOSTNAME_MISMATCH", 28)) { /* ^ */ #ifdef X509_V_ERR_HOSTNAME_MISMATCH return X509_V_ERR_HOSTNAME_MISMATCH; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "X509_V_ERR_INVALID_EXTENSION", 28)) { /* ^ */ #ifdef X509_V_ERR_INVALID_EXTENSION return X509_V_ERR_INVALID_EXTENSION; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "SESS_CACHE_NO_INTERNAL_STORE", 28)) { /* ^ */ #ifdef SSL_SESS_CACHE_NO_INTERNAL_STORE return SSL_SESS_CACHE_NO_INTERNAL_STORE; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_OCSP_CERT_UNKNOWN", 28)) { /* ^ */ #ifdef X509_V_ERR_OCSP_CERT_UNKNOWN return X509_V_ERR_OCSP_CERT_UNKNOWN; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "SSL3_MT_ENCRYPTED_EXTENSIONS", 28)) { /* ^ */ #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS return SSL3_MT_ENCRYPTED_EXTENSIONS; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "F_SSL_USE_RSAPRIVATEKEY_ASN1", 28)) { /* ^ */ #ifdef SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 return SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1; #else goto not_there; #endif } if (!memcmp(name, "F_SSL_USE_RSAPRIVATEKEY_FILE", 28)) { /* ^ */ #ifdef SSL_F_SSL_USE_RSAPRIVATEKEY_FILE return SSL_F_SSL_USE_RSAPRIVATEKEY_FILE; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_GET_CRL", 28)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_GET_CRL return X509_V_ERR_UNABLE_TO_GET_CRL; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_UNNESTED_RESOURCE", 28)) { /* ^ */ #ifdef X509_V_ERR_UNNESTED_RESOURCE return X509_V_ERR_UNNESTED_RESOURCE; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "NID_private_key_usage_period", 28)) { /* ^ */ #ifdef NID_private_key_usage_period return NID_private_key_usage_period; #else goto not_there; #endif } break; case 'e': if (!memcmp(name, "NID_netscape_ssl_server_name", 28)) { /* ^ */ #ifdef NID_netscape_ssl_server_name return NID_netscape_ssl_server_name; #else goto not_there; #endif } break; case 'h': if (!memcmp(name, "NID_pbe_WithSHA1And128BitRC4", 28)) { /* ^ */ #ifdef NID_pbe_WithSHA1And128BitRC4 return NID_pbe_WithSHA1And128BitRC4; #else goto not_there; #endif } break; case 'i': if (!memcmp(name, "NID_pkcs7_signedAndEnveloped", 28)) { /* ^ */ #ifdef NID_pkcs7_signedAndEnveloped return NID_pkcs7_signedAndEnveloped; #else goto not_there; #endif } break; case 't': if (!memcmp(name, "NID_authority_key_identifier", 28)) { /* ^ */ #ifdef NID_authority_key_identifier return NID_authority_key_identifier; #else goto not_there; #endif } break; } break; case 29: /* Names all of length 29. */ /* NID_pkcs9_unstructuredAddress OCSP_RESPONSE_STATUS_TRYLATER OP_MICROSOFT_BIG_SSLV3_BUFFER R_SSL_SESSION_ID_IS_DIFFERENT SESS_CACHE_NO_INTERNAL_LOOKUP X509_V_ERR_AKID_SKID_MISMATCH X509_V_ERR_CERT_NOT_YET_VALID X509_V_ERR_EXCLUDED_VIOLATION X509_V_ERR_NO_EXPLICIT_POLICY X509_V_ERR_OCSP_VERIFY_FAILED X509_V_ERR_OCSP_VERIFY_NEEDED X509_V_FLAG_ALLOW_PROXY_CERTS */ /* Offset 16 gives the best switch position. */ switch (name[16]) { case 'A': if (!memcmp(name, "OCSP_RESPONSE_STATUS_TRYLATER", 29)) { /* ^ */ #ifdef OCSP_RESPONSE_STATUS_TRYLATER return OCSP_RESPONSE_STATUS_TRYLATER; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "X509_V_ERR_EXCLUDED_VIOLATION", 29)) { /* ^ */ #ifdef X509_V_ERR_EXCLUDED_VIOLATION return X509_V_ERR_EXCLUDED_VIOLATION; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_V_ERR_CERT_NOT_YET_VALID", 29)) { /* ^ */ #ifdef X509_V_ERR_CERT_NOT_YET_VALID return X509_V_ERR_CERT_NOT_YET_VALID; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "X509_V_ERR_NO_EXPLICIT_POLICY", 29)) { /* ^ */ #ifdef X509_V_ERR_NO_EXPLICIT_POLICY return X509_V_ERR_NO_EXPLICIT_POLICY; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_V_ERR_AKID_SKID_MISMATCH", 29)) { /* ^ */ #ifdef X509_V_ERR_AKID_SKID_MISMATCH return X509_V_ERR_AKID_SKID_MISMATCH; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "SESS_CACHE_NO_INTERNAL_LOOKUP", 29)) { /* ^ */ #ifdef SSL_SESS_CACHE_NO_INTERNAL_LOOKUP return SSL_SESS_CACHE_NO_INTERNAL_LOOKUP; #else goto not_there; #endif } break; case 'V': if (!memcmp(name, "X509_V_ERR_OCSP_VERIFY_FAILED", 29)) { /* ^ */ #ifdef X509_V_ERR_OCSP_VERIFY_FAILED return X509_V_ERR_OCSP_VERIFY_FAILED; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_OCSP_VERIFY_NEEDED", 29)) { /* ^ */ #ifdef X509_V_ERR_OCSP_VERIFY_NEEDED return X509_V_ERR_OCSP_VERIFY_NEEDED; #else goto not_there; #endif } break; case 'W': if (!memcmp(name, "X509_V_FLAG_ALLOW_PROXY_CERTS", 29)) { /* ^ */ #ifdef X509_V_FLAG_ALLOW_PROXY_CERTS return X509_V_FLAG_ALLOW_PROXY_CERTS; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "OP_MICROSOFT_BIG_SSLV3_BUFFER", 29)) { /* ^ */ #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER return SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; #else goto not_there; #endif } if (!memcmp(name, "R_SSL_SESSION_ID_IS_DIFFERENT", 29)) { /* ^ */ #ifdef SSL_R_SSL_SESSION_ID_IS_DIFFERENT return SSL_R_SSL_SESSION_ID_IS_DIFFERENT; #else goto not_there; #endif } break; case 'c': if (!memcmp(name, "NID_pkcs9_unstructuredAddress", 29)) { /* ^ */ #ifdef NID_pkcs9_unstructuredAddress return NID_pkcs9_unstructuredAddress; #else goto not_there; #endif } break; } break; case 30: /* Names all of length 30. */ /* NID_netscape_ca_revocation_url OP_DONT_INSERT_EMPTY_FRAGMENTS OP_SSLREF2_REUSE_CERT_TYPE_BUG R_UNABLE_TO_EXTRACT_PUBLIC_KEY X509_V_ERR_CERT_CHAIN_TOO_LONG X509_V_ERR_DIFFERENT_CRL_SCOPE X509_V_ERR_IP_ADDRESS_MISMATCH X509_V_ERR_PERMITTED_VIOLATION X509_V_FLAG_CHECK_SS_SIGNATURE */ /* Offset 24 gives the best switch position. */ switch (name[24]) { case 'G': if (!memcmp(name, "OP_DONT_INSERT_EMPTY_FRAGMENTS", 30)) { /* ^ */ #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS return SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "R_UNABLE_TO_EXTRACT_PUBLIC_KEY", 30)) { /* ^ */ #ifdef SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY return SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "X509_V_ERR_PERMITTED_VIOLATION", 30)) { /* ^ */ #ifdef X509_V_ERR_PERMITTED_VIOLATION return X509_V_ERR_PERMITTED_VIOLATION; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_V_FLAG_CHECK_SS_SIGNATURE", 30)) { /* ^ */ #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE return X509_V_FLAG_CHECK_SS_SIGNATURE; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_CERT_CHAIN_TOO_LONG", 30)) { /* ^ */ #ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG return X509_V_ERR_CERT_CHAIN_TOO_LONG; #else goto not_there; #endif } break; case 'P': if (!memcmp(name, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", 30)) { /* ^ */ #ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG return SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_V_ERR_IP_ADDRESS_MISMATCH", 30)) { /* ^ */ #ifdef X509_V_ERR_IP_ADDRESS_MISMATCH return X509_V_ERR_IP_ADDRESS_MISMATCH; #else goto not_there; #endif } break; case '_': if (!memcmp(name, "X509_V_ERR_DIFFERENT_CRL_SCOPE", 30)) { /* ^ */ #ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE return X509_V_ERR_DIFFERENT_CRL_SCOPE; #else goto not_there; #endif } break; case 'o': if (!memcmp(name, "NID_netscape_ca_revocation_url", 30)) { /* ^ */ #ifdef NID_netscape_ca_revocation_url return NID_netscape_ca_revocation_url; #else goto not_there; #endif } break; } break; case 31: /* Names all of length 31. */ /* MIN_RSA_MODULUS_LENGTH_IN_BYTES MODE_ACCEPT_MOVING_WRITE_BUFFER NID_pbe_WithSHA1And40BitRC2_CBC OCSP_RESPONSE_STATUS_SUCCESSFUL X509_V_ERR_KEYUSAGE_NO_CERTSIGN X509_V_ERR_KEYUSAGE_NO_CRL_SIGN X509_V_ERR_PATH_LENGTH_EXCEEDED X509_V_FLAG_SUITEB_128_LOS_ONLY */ /* Offset 30 gives the best switch position. */ switch (name[30]) { case 'C': if (!memcmp(name, "NID_pbe_WithSHA1And40BitRC2_CB", 30)) { /* C */ #ifdef NID_pbe_WithSHA1And40BitRC2_CBC return NID_pbe_WithSHA1And40BitRC2_CBC; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "X509_V_ERR_PATH_LENGTH_EXCEEDE", 30)) { /* D */ #ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED return X509_V_ERR_PATH_LENGTH_EXCEEDED; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "OCSP_RESPONSE_STATUS_SUCCESSFU", 30)) { /* L */ #ifdef OCSP_RESPONSE_STATUS_SUCCESSFUL return OCSP_RESPONSE_STATUS_SUCCESSFUL; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "X509_V_ERR_KEYUSAGE_NO_CERTSIG", 30)) { /* N */ #ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; #else goto not_there; #endif } if (!memcmp(name, "X509_V_ERR_KEYUSAGE_NO_CRL_SIG", 30)) { /* N */ #ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN return X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "MODE_ACCEPT_MOVING_WRITE_BUFFE", 30)) { /* R */ #ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER return SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "MIN_RSA_MODULUS_LENGTH_IN_BYTE", 30)) { /* S */ #ifdef SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES return SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES; #else goto not_there; #endif } break; case 'Y': if (!memcmp(name, "X509_V_FLAG_SUITEB_128_LOS_ONL", 30)) { /* Y */ #ifdef X509_V_FLAG_SUITEB_128_LOS_ONLY return X509_V_FLAG_SUITEB_128_LOS_ONLY; #else goto not_there; #endif } break; } break; case 32: /* Names all of length 32. */ /* NID_pbe_WithSHA1And128BitRC2_CBC OCSP_RESPONSE_STATUS_SIGREQUIRED X509_V_ERR_CRL_SIGNATURE_FAILURE X509_V_ERR_SUITE_B_INVALID_CURVE X509_V_FLAG_EXTENDED_CRL_SUPPORT */ /* Offset 25 gives the best switch position. */ switch (name[25]) { case 'D': if (!memcmp(name, "X509_V_ERR_SUITE_B_INVALID_CURVE", 32)) { /* ^ */ #ifdef X509_V_ERR_SUITE_B_INVALID_CURVE return X509_V_ERR_SUITE_B_INVALID_CURVE; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "OCSP_RESPONSE_STATUS_SIGREQUIRED", 32)) { /* ^ */ #ifdef OCSP_RESPONSE_STATUS_SIGREQUIRED return OCSP_RESPONSE_STATUS_SIGREQUIRED; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "X509_V_ERR_CRL_SIGNATURE_FAILURE", 32)) { /* ^ */ #ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE return X509_V_ERR_CRL_SIGNATURE_FAILURE; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "NID_pbe_WithSHA1And128BitRC2_CBC", 32)) { /* ^ */ #ifdef NID_pbe_WithSHA1And128BitRC2_CBC return NID_pbe_WithSHA1And128BitRC2_CBC; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_V_FLAG_EXTENDED_CRL_SUPPORT", 32)) { /* ^ */ #ifdef X509_V_FLAG_EXTENDED_CRL_SUPPORT return X509_V_FLAG_EXTENDED_CRL_SUPPORT; #else goto not_there; #endif } break; } break; case 33: /* Names all of length 33. */ /* OCSP_RESPONSE_STATUS_UNAUTHORIZED X509_V_ERR_CERT_SIGNATURE_FAILURE */ /* Offset 32 gives the best switch position. */ switch (name[32]) { case 'D': if (!memcmp(name, "OCSP_RESPONSE_STATUS_UNAUTHORIZE", 32)) { /* D */ #ifdef OCSP_RESPONSE_STATUS_UNAUTHORIZED return OCSP_RESPONSE_STATUS_UNAUTHORIZED; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "X509_V_ERR_CERT_SIGNATURE_FAILUR", 32)) { /* E */ #ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE return X509_V_ERR_CERT_SIGNATURE_FAILURE; #else goto not_there; #endif } break; } break; case 34: /* Names all of length 34. */ /* OCSP_RESPONSE_STATUS_INTERNALERROR OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG X509_V_ERR_SUBJECT_ISSUER_MISMATCH X509_V_ERR_SUITE_B_INVALID_VERSION X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED X509_V_ERR_UNSUPPORTED_NAME_SYNTAX */ /* Offset 24 gives the best switch position. */ switch (name[24]) { case 'A': if (!memcmp(name, "X509_V_ERR_UNSUPPORTED_NAME_SYNTAX", 34)) { /* ^ */ #ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", 34)) { /* ^ */ #ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG return SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "OCSP_RESPONSE_STATUS_INTERNALERROR", 34)) { /* ^ */ #ifdef OCSP_RESPONSE_STATUS_INTERNALERROR return OCSP_RESPONSE_STATUS_INTERNALERROR; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "X509_V_ERR_SUITE_B_INVALID_VERSION", 34)) { /* ^ */ #ifdef X509_V_ERR_SUITE_B_INVALID_VERSION return X509_V_ERR_SUITE_B_INVALID_VERSION; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED", 34)) { /* ^ */ #ifdef X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "X509_V_ERR_SUBJECT_ISSUER_MISMATCH", 34)) { /* ^ */ #ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; #else goto not_there; #endif } break; } break; case 35: /* Names all of length 35. */ /* OPENSSL_INFO_DIR_FILENAME_SEPARATOR OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG R_PEER_DID_NOT_RETURN_A_CERTIFICATE X509_CHECK_FLAG_NEVER_CHECK_SUBJECT X509_V_ERR_APPLICATION_VERIFICATION X509_V_ERR_INVALID_POLICY_EXTENSION X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER _NET_SSLEAY_TEST_UNDEFINED_CONSTANT */ /* Offset 29 gives the best switch position. */ switch (name[29]) { case 'A': if (!memcmp(name, "OPENSSL_INFO_DIR_FILENAME_SEPARATOR", 35)) { /* ^ */ #ifdef OPENSSL_INFO_DIR_FILENAME_SEPARATOR return OPENSSL_INFO_DIR_FILENAME_SEPARATOR; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "X509_V_ERR_APPLICATION_VERIFICATION", 35)) { /* ^ */ #ifdef X509_V_ERR_APPLICATION_VERIFICATION return X509_V_ERR_APPLICATION_VERIFICATION; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "X509_V_ERR_INVALID_POLICY_EXTENSION", 35)) { /* ^ */ #ifdef X509_V_ERR_INVALID_POLICY_EXTENSION return X509_V_ERR_INVALID_POLICY_EXTENSION; #else goto not_there; #endif } break; case 'F': if (!memcmp(name, "R_PEER_DID_NOT_RETURN_A_CERTIFICATE", 35)) { /* ^ */ #ifdef SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE return SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE; #else goto not_there; #endif } break; case 'G': if (!memcmp(name, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", 35)) { /* ^ */ #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG return SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER", 35)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER return X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "_NET_SSLEAY_TEST_UNDEFINED_CONSTANT", 35)) { /* ^ */ #ifdef _NET_SSLEAY_TEST_UNDEFINED_CONSTANT return _NET_SSLEAY_TEST_UNDEFINED_CONSTANT; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "X509_CHECK_FLAG_NEVER_CHECK_SUBJECT", 35)) { /* ^ */ #ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT return X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; #else goto not_there; #endif } break; } break; case 36: /* Names all of length 36. */ /* OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS X509_V_ERR_CRL_PATH_VALIDATION_ERROR X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN X509_V_ERR_SUITE_B_INVALID_ALGORITHM X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT */ /* Offset 25 gives the best switch position. */ switch (name[25]) { case 'A': if (!memcmp(name, "X509_V_ERR_CRL_PATH_VALIDATION_ERROR", 36)) { /* ^ */ #ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR return X509_V_ERR_CRL_PATH_VALIDATION_ERROR; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "X509_V_ERR_SUITE_B_INVALID_ALGORITHM", 36)) { /* ^ */ #ifdef X509_V_ERR_SUITE_B_INVALID_ALGORITHM return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT", 36)) { /* ^ */ #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT return X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT", 36)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT return X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; #else goto not_there; #endif } break; case 'L': if (!memcmp(name, "X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS", 36)) { /* ^ */ #ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS return X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", 36)) { /* ^ */ #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION return SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN", 36)) { /* ^ */ #ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN return X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; #else goto not_there; #endif } break; } break; case 37: /* Names all of length 37. */ /* OCSP_RESPONSE_STATUS_MALFORMEDREQUEST X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED */ /* Offset 31 gives the best switch position. */ switch (name[31]) { case 'C': if (!memcmp(name, "X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED", 37)) { /* ^ */ #ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED return X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; #else goto not_there; #endif } break; case 'D': if (!memcmp(name, "X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS", 37)) { /* ^ */ #ifdef X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS return X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "OCSP_RESPONSE_STATUS_MALFORMEDREQUEST", 37)) { /* ^ */ #ifdef OCSP_RESPONSE_STATUS_MALFORMEDREQUEST return OCSP_RESPONSE_STATUS_MALFORMEDREQUEST; #else goto not_there; #endif } break; } break; case 38: /* Names all of length 38. */ /* NID_pbe_WithSHA1And2_Key_TripleDES_CBC NID_pbe_WithSHA1And3_Key_TripleDES_CBC X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE */ /* Offset 19 gives the best switch position. */ switch (name[19]) { case '2': if (!memcmp(name, "NID_pbe_WithSHA1And2_Key_TripleDES_CBC", 38)) { /* ^ */ #ifdef NID_pbe_WithSHA1And2_Key_TripleDES_CBC return NID_pbe_WithSHA1And2_Key_TripleDES_CBC; #else goto not_there; #endif } break; case '3': if (!memcmp(name, "NID_pbe_WithSHA1And3_Key_TripleDES_CBC", 38)) { /* ^ */ #ifdef NID_pbe_WithSHA1And3_Key_TripleDES_CBC return NID_pbe_WithSHA1And3_Key_TripleDES_CBC; #else goto not_there; #endif } break; case 'R': if (!memcmp(name, "X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT", 38)) { /* ^ */ #ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT return X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE", 38)) { /* ^ */ #ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; #else goto not_there; #endif } break; case 'U': if (!memcmp(name, "X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH", 38)) { /* ^ */ #ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; #else goto not_there; #endif } break; } break; case 39: /* Names all of length 39. */ /* X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION */ /* Offset 26 gives the best switch position. */ switch (name[26]) { case 'A': if (!memcmp(name, "X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION", 39)) { /* ^ */ #ifdef X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION return X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; #else goto not_there; #endif } break; case 'C': if (!memcmp(name, "X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION", 39)) { /* ^ */ #ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION return X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS", 39)) { /* ^ */ #ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS return X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS; #else goto not_there; #endif } break; } break; case 40: /* Names all of length 40. */ /* X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE */ /* Offset 26 gives the best switch position. */ switch (name[26]) { case 'E': if (!memcmp(name, "X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE", 40)) { /* ^ */ #ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE return X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; #else goto not_there; #endif } break; case 'I': if (!memcmp(name, "X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE", 40)) { /* ^ */ #ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD", 40)) { /* ^ */ #ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD return X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX", 40)) { /* ^ */ #ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX return X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; #else goto not_there; #endif } break; } break; case 41: /* Names all of length 41. */ /* OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 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_PROXY_CERTIFICATES_NOT_ALLOWED */ /* Offset 26 gives the best switch position. */ switch (name[26]) { case 'E': if (!memcmp(name, "R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE", 41)) { /* ^ */ #ifdef SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE return SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; #else goto not_there; #endif } break; case 'N': if (!memcmp(name, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", 41)) { /* ^ */ #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION return SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; #else goto not_there; #endif } break; case 'O': if (!memcmp(name, "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD", 41)) { /* ^ */ #ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD return X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; #else goto not_there; #endif } break; case 'S': if (!memcmp(name, "X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD", 41)) { /* ^ */ #ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD return X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; #else goto not_there; #endif } break; case 'T': if (!memcmp(name, "X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED", 41)) { /* ^ */ #ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED return X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; #else goto not_there; #endif } break; case 'X': if (!memcmp(name, "X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD", 41)) { /* ^ */ #ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD return X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; #else goto not_there; #endif } break; } break; case 42: /* Names all of length 42. */ /* X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE */ /* Offset 29 gives the best switch position. */ switch (name[29]) { case 'C': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE", 42)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE return X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; #else goto not_there; #endif } break; case 'E': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE", 42)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE return X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; #else goto not_there; #endif } break; } break; case 43: /* Names all of length 43. */ /* X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION */ /* Offset 14 gives the best switch position. */ switch (name[14]) { case 'A': if (!memcmp(name, "X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION", 43)) { /* ^ */ #ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION return X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; #else goto not_there; #endif } break; case 'B': if (!memcmp(name, "X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE", 43)) { /* ^ */ #ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE return X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; #else goto not_there; #endif } break; } break; case 44: if (!memcmp(name, "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY", 44)) { #ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY return X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; #else goto not_there; #endif } break; case 45: if (!memcmp(name, "X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", 45)) { #ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY return X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; #else goto not_there; #endif } break; case 46: if (!memcmp(name, "X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM", 46)) { #ifdef X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; #else goto not_there; #endif } break; case 47: if (!memcmp(name, "X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256", 47)) { #ifdef X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 return X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; #else goto not_there; #endif } break; } errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; } Net-SSLeay-1.92/META.json0000644000175000001440000000446014167654753013502 0ustar csnusers{ "abstract" : "Perl bindings for OpenSSL and LibreSSL", "author" : [ "Sampo Kellomäki ", "Florian Ragwitz ", "Mike McCauley ", "Chris Novakovic ", "Tuure Vartiainen ", "Heikki Vatiainen " ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-SSLeay", "no_index" : { "directory" : [ "t", "inc", "helper_script", "examples" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "English" : "0", "ExtUtils::MakeMaker" : "0", "File::Spec::Functions" : "0", "Text::Wrap" : "0", "constant" : "0" } }, "develop" : { "requires" : { "Test::Kwalitee" : "1.00", "Test::Pod::Coverage" : "1.00" } }, "runtime" : { "requires" : { "MIME::Base64" : "0", "perl" : "5.008001" } }, "test" : { "requires" : { "Carp" : "0", "Config" : "0", "Cwd" : "0", "English" : "0", "File::Basename" : "0", "File::Spec::Functions" : "0", "Scalar::Util" : "0", "SelectSaver" : "0", "Socket" : "0", "Storable" : "0", "Test::Builder" : "0", "Test::More" : "0.60_01", "base" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/radiator-software/p5-net-ssleay/issues" }, "repository" : { "type" : "git", "url" : "git://github.com/radiator-software/p5-net-ssleay.git", "web" : "https://github.com/radiator-software/p5-net-ssleay" } }, "version" : "1.92", "x_serialization_backend" : "JSON::PP version 4.06" } Net-SSLeay-1.92/t/0000755000175000001440000000000014167654753012320 5ustar csnusersNet-SSLeay-1.92/t/external/0000755000175000001440000000000014167654753014142 5ustar csnusersNet-SSLeay-1.92/t/external/ocsp.t0000644000175000001440000001735213765201207015264 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(initialise_libssl); use IO::Socket::INET; if (!defined &Net::SSLeay::OCSP_response_status) { plan skip_all => 'No support for OCSP in your OpenSSL'; } #$Net::SSLeay::trace=3; my @tests = ( { # this should give us OCSP stapling host => 'www.microsoft.com', port => 443, fingerprint => '5f0b37e633840ca02468552ea3b1197e5e118f7b', ocsp_staple => 1, expect_status => Net::SSLeay::V_OCSP_CERTSTATUS_GOOD(), }, { # no OCSP stapling host => 'www.heise.de', port => 443, fingerprint => '36a7d7bfc59db65c040bccd291ae563d9ef7bafc', expect_status => Net::SSLeay::V_OCSP_CERTSTATUS_GOOD(), }, { # this is revoked host => 'revoked.grc.com', port => 443, fingerprint => '310665f4c8e78db761c764e798dca66047341264', expect_status => Net::SSLeay::V_OCSP_CERTSTATUS_REVOKED(), }, ); my $release_tests = $ENV{RELEASE_TESTING} ? 1:0; plan tests => $release_tests + @tests; initialise_libssl(); my $timeout = 10; # used to TCP connect and SSL connect my $http_ua = eval { require HTTP::Tiny } && HTTP::Tiny->new(verify_SSL => 0); my $sha1 = Net::SSLeay::EVP_get_digestbyname('sha1'); my @fp_mismatch; TEST: for my $test (@tests) { my $cleanup = __cleanup__->new; SKIP: { skip 'HTTP::Tiny required but not installed', 1 unless $http_ua; my $cl = IO::Socket::INET->new( PeerAddr => $test->{host}, PeerPort => $test->{port}, Timeout => $timeout, ); skip "TCP connect to $test->{host}:$test->{port} failed: $!",1 if !$cl; diag("tcp connect to $test->{host}:$test->{port} ok"); my $ctx = Net::SSLeay::CTX_new() or die "failed to create CTX"; # enable verification with hopefully usable CAs Net::SSLeay::CTX_set_default_verify_paths($ctx); Net::SSLeay::CTX_load_verify_locations($ctx, Mozilla::CA::SSL_ca_file(),'') if eval { require Mozilla::CA }; Net::SSLeay::CTX_set_verify($ctx,Net::SSLeay::VERIFY_PEER(),undef); # setup TLS extension callback to catch stapled OCSP response my $stapled_response; Net::SSLeay::CTX_set_tlsext_status_cb($ctx,sub { my ($ssl,$resp) = @_; diag("got ".($resp ? '':'no ')."stapled OCSP response"); return 1 if ! $resp; $stapled_response = Net::SSLeay::i2d_OCSP_RESPONSE($resp); return 1; }); # create SSL object only after we have the context fully done since # some parts of the context (like verification mode) will be copied # to the SSL object and thus later changes to the CTX don't affect # the SSL object my $ssl = Net::SSLeay::new($ctx) or die "failed to create SSL"; # setup TLS extension to request stapled OCSP response Net::SSLeay::set_tlsext_status_type($ssl, Net::SSLeay::TLSEXT_STATUSTYPE_ocsp()); # non-blocking SSL_connect with timeout $cl->blocking(0); Net::SSLeay::set_fd($ssl,fileno($cl)); my $end = time() + $timeout; my ($rv,@err); while (($rv = Net::SSLeay::connect($ssl)) < 0) { my $to = $end-time(); $to<=0 and last; my $err = Net::SSLeay::get_error($ssl,$rv); vec( my $vec = '',fileno($cl),1) = 1; if ( $err == Net::SSLeay::ERROR_WANT_READ()) { select($vec,undef,undef,$to); } elsif ( $err == Net::SSLeay::ERROR_WANT_WRITE()) { select(undef,$vec,undef,$to); } else { while ( my $err = Net::SSLeay::ERR_get_error()) { push @err, Net::SSLeay::ERR_error_string($err); } last } } skip "SSL_connect with $test->{host}:$test->{port} failed: @err",1 if $rv<=0; diag("SSL_connect ok"); # make sure we talk to the right party, e.g. no SSL interception my $leaf_cert = Net::SSLeay::get_peer_certificate($ssl); $cleanup->add(sub { Net::SSLeay::X509_free($leaf_cert) }) if $leaf_cert; my $fp = $leaf_cert && unpack("H*",Net::SSLeay::X509_digest($leaf_cert,$sha1)); skip "could not get fingerprint",1 if !$fp; if ($fp ne $test->{fingerprint}) { push @fp_mismatch, [ $fp,$test ]; skip("bad fingerprint for $test->{host}:$test->{port} -". " expected $test->{fingerprint}, got $fp",1) } diag("fingerprint matches"); if ( $test->{ocsp_staple} && ! $stapled_response ) { fail("did not get expected stapled OCSP response on $test->{host}:$test->{port}"); next TEST; } # create OCSP_REQUEST for all certs my @requests; for my $cert (Net::SSLeay::get_peer_cert_chain($ssl)) { my $subj = Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($cert)); my $uri = Net::SSLeay::P_X509_get_ocsp_uri($cert); if (!$uri) { diag("no OCSP URI for cert $subj"); next; } my $id = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) } or do { fail("failed to get OCSP_CERTIDs for cert $subj: $@"); next TEST; }; my $req = Net::SSLeay::OCSP_ids2req($id); push @requests, [ $uri,$req,$id,$subj ]; $cleanup->add(sub { Net::SSLeay::OCSP_REQUEST_free($req) }); } if (!@requests) { fail("no certificate checks for $test->{host}:$test->{port}"); next TEST; } my $check_response = sub { my ($resp,$req,$id,$expect_status) = @_; if ( Net::SSLeay::OCSP_response_status($resp) != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) { return [ undef,"response bad status ". Net::SSLeay::OCSP_response_status_str(Net::SSLeay::OCSP_response_status($resp)) ]; } elsif ( ! eval { Net::SSLeay::OCSP_response_verify($ssl,$resp,$req) }) { return [ undef,"cannot verify response: $@" ]; } # extract result for id my ($status) = Net::SSLeay::OCSP_response_results($resp,$id); return [ undef,"no data for cert in response: $status->[1]" ] if ! $status->[2]; if ($expect_status != $status->[2]{statusType}) { return [ undef, "unexpected status=$status->[2]{statusType} (expected $expect_status): $status->[1]" ] } elsif ( $status->[2]{nextUpdate} ) { diag("status=$expect_status as expected: nextUpd=".localtime($status->[2]{nextUpdate})); } else { diag("status=$expect_status as expected: no nextUpd"); } return $status; }; if ($stapled_response) { my $stat = $check_response->( Net::SSLeay::d2i_OCSP_RESPONSE($stapled_response), undef, # no OCSP_REQUEST $requests[0][2], # stapled response is for the leaf certificate $test->{expect_status} ); if (!$stat->[0]) { fail($stat->[1]); next TEST; } } for(my $i=0;$i<@requests;$i++) { my ($uri,$req,$id,$subj) = @{$requests[$i]}; if ( ! $http_ua ) { diag("no HTTP: skip checking $uri | $subj"); next } my $res = $http_ua->request('POST',$uri, { headers => { 'Content-type' => 'application/ocsp-request' }, content => Net::SSLeay::i2d_OCSP_REQUEST($req), timeout => $timeout, }); if (!$res->{success}) { if ($res->{status} == 599) { # internal error, assume network problem diag("disabling HTTP because of $http_ua->{reason}"); $http_ua = undef; } diag("$http_ua->{reason}: skip checking $uri | $subj"); next; } my $resp = eval { Net::SSLeay::d2i_OCSP_RESPONSE($res->{content}) }; if (!$resp) { diag("bad OCSP response($@): skip checking $uri | $subj"); next; } my $stat = $check_response->( $resp, $req, $id, ($i>0) ? Net::SSLeay::V_OCSP_CERTSTATUS_GOOD() : $test->{expect_status}, ); if (!$stat->[0]) { fail($stat->[1]); next TEST; } } pass("OCSP test $test->{host}:$test->{port} ok"); } } if ($release_tests) { if (!@fp_mismatch) { pass("all fingerprints matched"); } else { for(@fp_mismatch) { my ($fp,$test) = @$_; diag("fingerprint mismatch for $test->{host}:$test->{port} -". " expected $test->{fingerprint}, got $fp") } fail("some fingerprints did not matched - please adjust test"); } } { # cleanup stuff when going out of scope package __cleanup__; sub new { bless [],shift }; sub add { my $self = shift; push @$self,@_ } sub DESTROY { my $self = shift; &$_ for(@$self) } } Net-SSLeay-1.92/t/local/0000755000175000001440000000000014167654753013412 5ustar csnusersNet-SSLeay-1.92/t/local/21_constants.t0000644000175000001440000003761214167101614016105 0ustar csnusers# This file 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. use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(dies_like); # We rely on symbolic references in the dies_like() tests: no strict 'refs'; plan tests => 607; my @constants = qw( ASN1_STRFLGS_ESC_CTRL ASN1_STRFLGS_ESC_MSB ASN1_STRFLGS_ESC_QUOTE ASN1_STRFLGS_RFC2253 CB_ACCEPT_EXIT CB_ACCEPT_LOOP CB_ALERT CB_CONNECT_EXIT CB_CONNECT_LOOP CB_EXIT CB_HANDSHAKE_DONE CB_HANDSHAKE_START CB_LOOP CB_READ CB_READ_ALERT CB_WRITE CB_WRITE_ALERT ERROR_NONE ERROR_SSL ERROR_SYSCALL ERROR_WANT_ACCEPT ERROR_WANT_CONNECT ERROR_WANT_READ ERROR_WANT_WRITE ERROR_WANT_X509_LOOKUP ERROR_ZERO_RETURN EVP_PKS_DSA EVP_PKS_EC EVP_PKS_RSA EVP_PKT_ENC EVP_PKT_EXCH EVP_PKT_EXP EVP_PKT_SIGN EVP_PK_DH EVP_PK_DSA EVP_PK_EC EVP_PK_RSA FILETYPE_ASN1 FILETYPE_PEM F_CLIENT_CERTIFICATE F_CLIENT_HELLO F_CLIENT_MASTER_KEY F_D2I_SSL_SESSION F_GET_CLIENT_FINISHED F_GET_CLIENT_HELLO F_GET_CLIENT_MASTER_KEY F_GET_SERVER_FINISHED F_GET_SERVER_HELLO F_GET_SERVER_VERIFY F_I2D_SSL_SESSION F_READ_N F_REQUEST_CERTIFICATE F_SERVER_HELLO F_SSL_CERT_NEW F_SSL_GET_NEW_SESSION F_SSL_NEW F_SSL_READ F_SSL_RSA_PRIVATE_DECRYPT F_SSL_RSA_PUBLIC_ENCRYPT F_SSL_SESSION_NEW F_SSL_SESSION_PRINT_FP F_SSL_SET_FD F_SSL_SET_RFD F_SSL_SET_WFD F_SSL_USE_CERTIFICATE F_SSL_USE_CERTIFICATE_ASN1 F_SSL_USE_CERTIFICATE_FILE F_SSL_USE_PRIVATEKEY F_SSL_USE_PRIVATEKEY_ASN1 F_SSL_USE_PRIVATEKEY_FILE F_SSL_USE_RSAPRIVATEKEY F_SSL_USE_RSAPRIVATEKEY_ASN1 F_SSL_USE_RSAPRIVATEKEY_FILE F_WRITE_PENDING GEN_DIRNAME GEN_DNS GEN_EDIPARTY GEN_EMAIL GEN_IPADD GEN_OTHERNAME GEN_RID GEN_URI GEN_X400 LIBRESSL_VERSION_NUMBER MBSTRING_ASC MBSTRING_BMP MBSTRING_FLAG MBSTRING_UNIV MBSTRING_UTF8 MIN_RSA_MODULUS_LENGTH_IN_BYTES MODE_ACCEPT_MOVING_WRITE_BUFFER MODE_AUTO_RETRY MODE_ENABLE_PARTIAL_WRITE MODE_RELEASE_BUFFERS NID_OCSP_sign NID_SMIMECapabilities NID_X500 NID_X509 NID_ad_OCSP NID_ad_ca_issuers NID_algorithm NID_authority_key_identifier NID_basic_constraints NID_bf_cbc NID_bf_cfb64 NID_bf_ecb NID_bf_ofb64 NID_cast5_cbc NID_cast5_cfb64 NID_cast5_ecb NID_cast5_ofb64 NID_certBag NID_certificate_policies NID_client_auth NID_code_sign NID_commonName NID_countryName NID_crlBag NID_crl_distribution_points NID_crl_number NID_crl_reason NID_delta_crl NID_des_cbc NID_des_cfb64 NID_des_ecb NID_des_ede NID_des_ede3 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 NID_description NID_desx_cbc NID_dhKeyAgreement NID_dnQualifier NID_dsa NID_dsaWithSHA NID_dsaWithSHA1 NID_dsaWithSHA1_2 NID_dsa_2 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 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 NID_ms_code_com NID_ms_code_ind NID_ms_ctl_sign NID_ms_efs NID_ms_ext_req NID_ms_sgc 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 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 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 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 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_shaWithRSAEncryption NID_stateOrProvinceName NID_subject_alt_name NID_subject_key_identifier NID_surname NID_sxnet NID_time_stamp NID_title NID_undef NID_uniqueIdentifier NID_x509Certificate NID_x509Crl NID_zlib_compression NOTHING OCSP_RESPONSE_STATUS_INTERNALERROR OCSP_RESPONSE_STATUS_MALFORMEDREQUEST OCSP_RESPONSE_STATUS_SIGREQUIRED OCSP_RESPONSE_STATUS_SUCCESSFUL OCSP_RESPONSE_STATUS_TRYLATER OCSP_RESPONSE_STATUS_UNAUTHORIZED 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_MODULES_DIR OPENSSL_PLATFORM OPENSSL_VERSION OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR OPENSSL_VERSION_NUMBER OPENSSL_VERSION_PATCH OPENSSL_VERSION_STRING OP_ALL OP_ALLOW_NO_DHE_KEX OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION OP_CIPHER_SERVER_PREFERENCE OP_CISCO_ANYCONNECT OP_COOKIE_EXCHANGE OP_CRYPTOPRO_TLSEXT_BUG OP_DONT_INSERT_EMPTY_FRAGMENTS OP_ENABLE_MIDDLEBOX_COMPAT OP_EPHEMERAL_RSA OP_LEGACY_SERVER_CONNECT OP_MICROSOFT_BIG_SSLV3_BUFFER OP_MICROSOFT_SESS_ID_BUG OP_MSIE_SSLV2_RSA_PADDING OP_NETSCAPE_CA_DN_BUG OP_NETSCAPE_CHALLENGE_BUG OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG OP_NON_EXPORT_FIRST OP_NO_ANTI_REPLAY OP_NO_CLIENT_RENEGOTIATION OP_NO_COMPRESSION OP_NO_ENCRYPT_THEN_MAC OP_NO_QUERY_MTU OP_NO_RENEGOTIATION OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION OP_NO_SSL_MASK OP_NO_SSLv2 OP_NO_SSLv3 OP_NO_TICKET OP_NO_TLSv1 OP_NO_TLSv1_1 OP_NO_TLSv1_2 OP_NO_TLSv1_3 OP_PKCS1_CHECK_1 OP_PKCS1_CHECK_2 OP_PRIORITIZE_CHACHA OP_SAFARI_ECDHE_ECDSA_BUG OP_SINGLE_DH_USE OP_SINGLE_ECDH_USE OP_SSLEAY_080_CLIENT_DH_BUG OP_SSLREF2_REUSE_CERT_TYPE_BUG OP_TLSEXT_PADDING OP_TLS_BLOCK_PADDING_BUG OP_TLS_D5_BUG OP_TLS_ROLLBACK_BUG READING RECEIVED_SHUTDOWN RSA_3 RSA_F4 R_BAD_AUTHENTICATION_TYPE R_BAD_CHECKSUM R_BAD_MAC_DECODE R_BAD_RESPONSE_ARGUMENT R_BAD_SSL_FILETYPE R_BAD_SSL_SESSION_ID_LENGTH R_BAD_STATE R_BAD_WRITE_RETRY R_CHALLENGE_IS_DIFFERENT R_CIPHER_TABLE_SRC_ERROR R_INVALID_CHALLENGE_LENGTH R_NO_CERTIFICATE_SET R_NO_CERTIFICATE_SPECIFIED R_NO_CIPHER_LIST R_NO_CIPHER_MATCH R_NO_PRIVATEKEY R_NO_PUBLICKEY R_NULL_SSL_CTX R_PEER_DID_NOT_RETURN_A_CERTIFICATE R_PEER_ERROR R_PEER_ERROR_CERTIFICATE R_PEER_ERROR_NO_CIPHER R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE R_PUBLIC_KEY_ENCRYPT_ERROR R_PUBLIC_KEY_IS_NOT_RSA R_READ_WRONG_PACKET_TYPE R_SHORT_READ R_SSL_SESSION_ID_IS_DIFFERENT R_UNABLE_TO_EXTRACT_PUBLIC_KEY R_UNKNOWN_REMOTE_ERROR_TYPE R_UNKNOWN_STATE R_X509_LIB SENT_SHUTDOWN SESSION_ASN1_VERSION SESS_CACHE_BOTH SESS_CACHE_CLIENT SESS_CACHE_NO_AUTO_CLEAR SESS_CACHE_NO_INTERNAL SESS_CACHE_NO_INTERNAL_LOOKUP SESS_CACHE_NO_INTERNAL_STORE SESS_CACHE_OFF SESS_CACHE_SERVER SSL2_MT_CLIENT_CERTIFICATE SSL2_MT_CLIENT_FINISHED SSL2_MT_CLIENT_HELLO SSL2_MT_CLIENT_MASTER_KEY SSL2_MT_ERROR SSL2_MT_REQUEST_CERTIFICATE SSL2_MT_SERVER_FINISHED SSL2_MT_SERVER_HELLO SSL2_MT_SERVER_VERIFY SSL2_VERSION SSL3_MT_CCS SSL3_MT_CERTIFICATE SSL3_MT_CERTIFICATE_REQUEST SSL3_MT_CERTIFICATE_STATUS SSL3_MT_CERTIFICATE_URL SSL3_MT_CERTIFICATE_VERIFY SSL3_MT_CHANGE_CIPHER_SPEC SSL3_MT_CLIENT_HELLO SSL3_MT_CLIENT_KEY_EXCHANGE SSL3_MT_ENCRYPTED_EXTENSIONS SSL3_MT_END_OF_EARLY_DATA SSL3_MT_FINISHED SSL3_MT_HELLO_REQUEST SSL3_MT_KEY_UPDATE SSL3_MT_MESSAGE_HASH SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEXT_PROTO SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO SSL3_MT_SERVER_KEY_EXCHANGE SSL3_MT_SUPPLEMENTAL_DATA SSL3_RT_ALERT SSL3_RT_APPLICATION_DATA SSL3_RT_CHANGE_CIPHER_SPEC SSL3_RT_HANDSHAKE SSL3_RT_HEADER SSL3_RT_INNER_CONTENT_TYPE SSL3_VERSION SSLEAY_BUILT_ON SSLEAY_CFLAGS SSLEAY_DIR SSLEAY_PLATFORM SSLEAY_VERSION ST_ACCEPT ST_BEFORE ST_CONNECT ST_INIT ST_OK ST_READ_BODY ST_READ_HEADER TLS1_1_VERSION TLS1_2_VERSION TLS1_3_VERSION TLS1_VERSION TLSEXT_STATUSTYPE_ocsp VERIFY_CLIENT_ONCE VERIFY_FAIL_IF_NO_PEER_CERT VERIFY_NONE VERIFY_PEER VERIFY_POST_HANDSHAKE V_OCSP_CERTSTATUS_GOOD V_OCSP_CERTSTATUS_REVOKED V_OCSP_CERTSTATUS_UNKNOWN WRITING 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 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_TRUST_COMPAT 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_V_ERR_AKID_ISSUER_SERIAL_MISMATCH X509_V_ERR_AKID_SKID_MISMATCH X509_V_ERR_APPLICATION_VERIFICATION 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 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_EE_KEY_TOO_SMALL X509_V_ERR_EMAIL_MISMATCH 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_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_KEYUSAGE_NO_CERTSIGN X509_V_ERR_KEYUSAGE_NO_CRL_SIGN X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE X509_V_ERR_NO_EXPLICIT_POLICY 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 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_STORE_LOOKUP X509_V_ERR_SUBJECT_ISSUER_MISMATCH 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_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 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 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 XN_FLAG_SPC_EQ ); my %exported = map { $_ => 1 } @Net::SSLeay::EXPORT_OK; my @missing; for my $c (@constants) { dies_like( sub { "Net::SSLeay::$c"->(); die "ok\n"; }, qr/^(?:ok\n$|Your vendor has not defined SSLeay macro )/, "constant is exported or not defined: $c" ); push @missing, $c if !exists $exported{$c}; } is( join( q{,}, sort @missing ), '', 'no constants missing from @EXPORT_OK (total missing: ' . scalar(@missing) . ')' ); dies_like( sub { Net::SSLeay::_NET_SSLEAY_TEST_UNDEFINED_CONSTANT() }, qr/^Your vendor has not defined SSLeay macro _NET_SSLEAY_TEST_UNDEFINED_CONSTANT/, 'referencing an undefined constant raises an exception' ); Net-SSLeay-1.92/t/local/11_read.t0000644000175000001440000002262114124712004014767 0ustar csnusers# Various SSL read and write related tests: SSL_read, SSL_peek, SSL_read_ex, # SSL_peek_ex, SSL_write_ex, SSL_pending and SSL_has_pending use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl tcp_socket ); use Storable; if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 53; } initialise_libssl(); my $pid; alarm(30); END { kill 9,$pid if $pid } my $server = tcp_socket(); # See that lengths differ for all msgs my $msg1 = "1 first message from server"; my $msg2 = "2 second message from server"; my $msg3 = "3 third message from server: pad"; my @rounds = qw(openssl openssl-1.1.0 openssl-1.1.1); sub server { # SSL server - just handle connections, send to client and exit my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { foreach my $round (@rounds) { my ($ctx, $ssl, $cl); next if skip_round($round); $cl = $server->accept(); $ctx = Net::SSLeay::CTX_new(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); Net::SSLeay::write($ssl, $msg1); Net::SSLeay::write($ssl, $msg2); my $msg = Net::SSLeay::read($ssl); Net::SSLeay::write($ssl, $msg); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); } $server->close() || die("server listen socket close: $!"); exit(0); } } sub client { foreach my $round (@rounds) { my ($ctx, $ssl, $cl); $cl = $server->connect(); $ctx = Net::SSLeay::CTX_new(); $ssl = Net::SSLeay::new($ctx); my ($reason, $num_tests) = skip_round($round); if ($reason) { SKIP: { skip($reason, $num_tests); } next; } round_openssl($ctx, $ssl, $cl) if $round eq 'openssl'; round_openssl_1_1_0($ctx, $ssl, $cl) if $round eq 'openssl-1.1.0'; round_openssl_1_1_1($ctx, $ssl, $cl) if $round eq 'openssl-1.1.1'; Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); } $server->close() || die("client listen socket close: $!"); return; } # Returns list for skip() if we should skip this round, false if we # shouldn't sub skip_round { my ($round) = @_; return if $round eq 'openssl'; if ($round eq 'openssl-1.1.0') { if (Net::SSLeay::constant("OPENSSL_VERSION_NUMBER") < 0x1010000f || Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER")) { return ("Need OpenSSL 1.1.0 or later", 6); } else { return; } } if ($round eq 'openssl-1.1.1') { if (Net::SSLeay::constant("OPENSSL_VERSION_NUMBER") < 0x1010100f || Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER")) { return ("Need OpenSSL 1.1.1 or later", 26); } else { return; } } diag("Unknown round: $round"); return; } sub round_openssl { my ($ctx, $ssl, $cl) = @_; my ($peek_msg, $read_msg, $len, $err, $ret); # ssl is not connected yet $peek_msg = Net::SSLeay::peek($ssl); is($peek_msg, undef, "scalar: peek returns undef for closed ssl"); ($peek_msg, $len) = Net::SSLeay::peek($ssl); is($peek_msg, undef, "list: peek returns undef for closed ssl"); cmp_ok($len, '<=', 0, 'list: peek returns length <=0 for closed ssl'); $err = Net::SSLeay::get_error($ssl, $len); isnt($err, Net::SSLeay::ERROR_WANT_READ(), "peek err $err is not retryable WANT_READ"); isnt($err, Net::SSLeay::ERROR_WANT_WRITE(), "peek err $err is not retryable WANT_WRITE"); $read_msg = Net::SSLeay::read($ssl); is($read_msg, undef, "scalar: read returns undef for closed ssl"); ($read_msg, $len) = Net::SSLeay::read($ssl); is($read_msg, undef, "list: read returns undef for closed ssl"); cmp_ok($len, '<=', 0, 'list: read returns length <=0 for closed ssl'); $err = Net::SSLeay::get_error($ssl, $len); isnt($err, Net::SSLeay::ERROR_WANT_READ(), "read err $err is not retryable WANT_READ"); isnt($err, Net::SSLeay::ERROR_WANT_WRITE(), "read err $err is not retryable WANT_WRITE"); $ret = Net::SSLeay::pending($ssl); is($ret, 0, "pending returns 0 for closed ssl"); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::connect($ssl); # msg1 $ret = Net::SSLeay::pending($ssl); is($ret, 0, "pending returns 0"); $peek_msg = Net::SSLeay::peek($ssl); is($peek_msg, $msg1, "scalar: peek returns msg1"); # processing was triggered by peek $ret = Net::SSLeay::pending($ssl); is($ret, length($msg1), "pending returns msg1 length"); ($peek_msg, $len) = Net::SSLeay::peek($ssl); is($peek_msg, $msg1, "list: peek returns msg1"); is($len, length($msg1), "list: peek returns msg1 length"); $read_msg = Net::SSLeay::read($ssl); is($peek_msg, $read_msg, "scalar: read and peek agree about msg1"); # msg2 $peek_msg = Net::SSLeay::peek($ssl); is($peek_msg, $msg2, "scalar: peek returns msg2"); ($read_msg, $len) = Net::SSLeay::read($ssl); is($peek_msg, $read_msg, "list: read and peek agree about msg2"); is($len, length($msg2), "list: read returns msg2 length"); # msg3 Net::SSLeay::write($ssl, $msg3); is(Net::SSLeay::read($ssl), $msg3, "ping with msg3"); return; } # Test has_pending and other functionality added in 1.1.0. # Revisit: Better tests for has_pending sub round_openssl_1_1_0 { my ($ctx, $ssl, $cl) = @_; my ($peek_msg, $read_msg, $len, $err, $ret); # ssl is not connected yet $ret = Net::SSLeay::has_pending($ssl); is($ret, 0, "1.1.0: has_pending returns 0 for closed ssl"); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::connect($ssl); # msg1 $ret = Net::SSLeay::has_pending($ssl); is($ret, 0, "1.1.0: has_pending returns 0"); # This triggers processing after which we have pending data $peek_msg = Net::SSLeay::peek($ssl); is($peek_msg, $msg1, "1.1.0: peek returns msg1"); $ret = Net::SSLeay::has_pending($ssl); is($ret, 1, "1.1.0: has_pending returns 1"); Net::SSLeay::read($ssl); # Read and discard $ret = Net::SSLeay::has_pending($ssl); is($ret, 0, "1.1.0: has_pending returns 0 after read"); # msg2 Net::SSLeay::read($ssl); # Read and discard # msg3 Net::SSLeay::write($ssl, $msg3); is(Net::SSLeay::read($ssl), $msg3, "1.1.0: ping with msg3"); return; } sub round_openssl_1_1_1 { my ($ctx, $ssl, $cl) = @_; my ($peek_msg, $read_msg, $len, $err, $err_ex, $ret); # ssl is not connected yet ($peek_msg, $ret) = Net::SSLeay::peek_ex($ssl); is($peek_msg, undef, "1.1.1: list: peek_ex returns undef message for closed ssl"); is($ret, 0, '1.1.1: list: peek_ex returns 0 for closed ssl'); $err = Net::SSLeay::get_error($ssl, $ret); isnt($err, Net::SSLeay::ERROR_WANT_READ(), "1.1.1: peek_ex err $err is not retryable WANT_READ"); isnt($err, Net::SSLeay::ERROR_WANT_WRITE(), "1.1.1: peek_ex err $err is not retryable WANT_WRITE"); ($read_msg, $len) = Net::SSLeay::read($ssl); is($read_msg, undef, "1.1.1: list: read returns undef message for closed ssl"); cmp_ok($len, '<=', 0, '1.1.1: list: read returns length <=0 for closed ssl'); $err = Net::SSLeay::get_error($ssl, $len); isnt($err, Net::SSLeay::ERROR_WANT_READ(), "1.1.1: read err $err is not retryable WANT_READ"); isnt($err, Net::SSLeay::ERROR_WANT_WRITE(), "1.1.1: read err $err is not retryable WANT_WRITE"); ($read_msg, $ret) = Net::SSLeay::read_ex($ssl); is($read_msg, undef, "1.1.1: list: read_ex returns undef message for closed sssl"); is($ret, 0, "1.1.1: list: read_ex returns 0 for closed sssl"); $err_ex = Net::SSLeay::get_error($ssl, $ret); is ($err_ex, $err, '1.1.1: read_ex and read err are equal'); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::connect($ssl); # msg1 $ret = Net::SSLeay::has_pending($ssl); is($ret, 0, "1.1.1: has_pending returns 0"); # This triggers processing after which we have pending data ($peek_msg, $ret) = Net::SSLeay::peek_ex($ssl); is($peek_msg, $msg1, "1.1.1: list: peek_ex returns msg1"); is($ret, 1, "1.1.1: list: peek_ex returns 1"); $len = Net::SSLeay::pending($ssl); is($len, length($msg1), "1.1.1: pending returns msg1 length"); $ret = Net::SSLeay::has_pending($ssl); is($ret, 1, "1.1.1: has_pending returns 1"); ($read_msg, $ret) = Net::SSLeay::read_ex($ssl); is($read_msg, $msg1, "1.1.1: list: read_ex returns msg1"); is($ret, 1, "1.1.1: list: read_ex returns 1"); $len = Net::SSLeay::pending($ssl); is($len, 0, "1.1.1: pending returns 0 after read_ex"); $ret = Net::SSLeay::has_pending($ssl); is($ret, 0, "1.1.1: has_pending returns 0 after read_ex"); # msg2 Net::SSLeay::read($ssl); # Read and discard # msg3 ($len, $ret) = Net::SSLeay::write_ex($ssl, $msg3); is($len, length($msg3), "1.1.1: write_ex wrote all"); is($ret, 1, "1.1.1: write_ex returns 1"); my ($read_msg1, $ret1) = Net::SSLeay::read_ex($ssl, 5); my ($read_msg2, $ret2) = Net::SSLeay::read_ex($ssl, (length($msg3) - 5)); is($ret1, 1, '1.1.1: ping with msg3 part1 ok'); is($ret2, 1, '1.1.1: ping with msg3 part2 ok'); is(length($read_msg1), 5, '1.1.1: ping with msg3, part1 length was 5'); is($read_msg1 . $read_msg2, $msg3, "1.1.1: ping with msg3 in two parts"); return; } server(); client(); waitpid $pid, 0; exit(0); Net-SSLeay-1.92/t/local/65_ticket_sharing_2.t0000644000175000001440000001323013765145713017321 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl new_ctx ); use English qw( $EVAL_ERROR -no_match_vars ); if ( !defined &Net::SSLeay::set_session_ticket_ext_cb ) { plan skip_all => "no support for session_ticket_ext_cb"; } elsif ( !eval { Net::SSLeay::CTX_free( new_ctx( undef, 'TLSv1.2' ) ); 1 } ) { my $err = $EVAL_ERROR; # This test only reflects the session protocol found in TLSv1.2 and below: # https://wiki.openssl.org/index.php/TLS1.3#Sessions # TODO(GH-224): write an equivalent test for TLSv1.3 if ( $err =~ /no usable protocol versions/ ) { plan skip_all => 'TLSv1.2 or below not available in this libssl'; } else { die $err; } } else { plan tests => 4; } initialise_libssl(); # for debugging only my $DEBUG = 0; my $PCAP = 0; require Net::PcapWriter if $PCAP; my $SSL_ERROR; # set in _minSSL my %TRANSFER; # set in _handshake my $SESSION_TICKET = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\xff"; my $SESSION_TICKET_CB_DATA = "dada"; my $set_session_ticket_ext_cb_run = 0; my $client = _minSSL->new(); my $server = _minSSL->new( cert => [ data_file_path('simple-cert.cert.pem'), data_file_path('simple-cert.key.pem'), ]); # now attach the ticket callback to server # ---------------------------------------------- my $ticketcb = sub { my ($ssl, $ticket, $data) = @_; is(unpack('H*', $data), unpack('H*', $SESSION_TICKET_CB_DATA), 'server set callback data with set_session_ticket_ext_cb'); is(unpack('H*', $ticket), unpack('H*', $SESSION_TICKET), 'client set session ticket with set_session_ticket_ext'); $set_session_ticket_ext_cb_run = 1; return 1; }; my $set_ticket_cb = sub { Net::SSLeay::set_session_ticket_ext_cb($server->_ssl, $ticketcb, $SESSION_TICKET_CB_DATA); Net::SSLeay::set_session_ticket_ext($client->_ssl, $SESSION_TICKET); }; is( _handshake($client,$server,$set_ticket_cb),'full',"full handshake with a ticket"); ok($set_session_ticket_ext_cb_run == 1, 'server run a callback set with set_session_ticket_ext_cb'); my $i; sub _handshake { my ($client,$server,$after_init) = @_; $client->state_connect; $server->state_accept; &$after_init if $after_init; my $pcap = $PCAP && do { my $fname = 'test'.(++$i).'.pcap'; open(my $fh,'>',$fname); diag("pcap in $fname"); $fh->autoflush; Net::PcapWriter->new($fh)->tcp_conn('1.1.1.1',1000,'2.2.2.2',443); }; my ($client_done,$server_done,@hs); %TRANSFER = (); for(my $tries = 0; $tries < 10 and !$client_done || !$server_done; $tries++ ) { $client_done ||= $client->handshake || 0; $server_done ||= $server->handshake || 0; my $transfer = 0; if (defined(my $data = $client->bio_read())) { $pcap && $pcap->write(0,$data); $DEBUG && warn "client -> server: ".length($data)." bytes\n"; $server->bio_write($data); push @hs,'>'; $TRANSFER{client} += length($data); $transfer++; } if (defined(my $data = $server->bio_read())) { $pcap && $pcap->write(1,$data); $DEBUG && warn "server -> client: ".length($data)." bytes\n"; $client->bio_write($data); # assume certificate was sent if length>700 push @hs, length($data) > 700 ? '<[C]':'<'; $TRANSFER{server} += length($data); $transfer++; } if (!$transfer) { # no more data to transfer - assume we are done $client_done = $server_done = 1; } } return !$client_done || !$server_done ? 'failed' : "@hs" eq '> <[C] > <' ? 'full' : "@hs" eq '> < >' ? 'reuse' : "@hs"; } { package _minSSL; use Test::Net::SSLeay qw(new_ctx); sub new { my ($class,%args) = @_; my $ctx = new_ctx( undef, 'TLSv1.2' ); Net::SSLeay::CTX_set_options($ctx,Net::SSLeay::OP_ALL()); my $id = 'client'; if ($args{cert}) { my ($cert,$key) = @{ delete $args{cert} }; Net::SSLeay::set_cert_and_key($ctx, $cert, $key) || die "failed to use cert file $cert,$key"; $id = 'server'; } my $self = bless { id => $id, ctx => $ctx }, $class; return $self; } sub state_accept { my $self = shift; _reset($self); Net::SSLeay::set_accept_state($self->{ssl}); } sub state_connect { my $self = shift; _reset($self); Net::SSLeay::set_connect_state($self->{ssl}); } sub handshake { my $self = shift; my $rv = Net::SSLeay::do_handshake($self->{ssl}); $rv = _error($self,$rv); return $rv; } sub ssl_read { my ($self) = @_; my ($data,$rv) = Net::SSLeay::read($self->{ssl}); return _error($self,$rv || -1) if !$rv || $rv<0; return $data; } sub bio_write { my ($self,$data) = @_; defined $data and $data ne '' or return; Net::SSLeay::BIO_write($self->{rbio},$data); } sub ssl_write { my ($self,$data) = @_; my $rv = Net::SSLeay::write($self->{ssl},$data); return _error($self,$rv || -1) if !$rv || $rv<0; return $rv; } sub bio_read { my ($self) = @_; return Net::SSLeay::BIO_read($self->{wbio}); } sub _ssl { shift->{ssl} } sub _ctx { shift->{ctx} } sub _reset { my $self = shift; my $ssl = Net::SSLeay::new($self->{ctx}); my @bio = ( Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()), Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()), ); Net::SSLeay::set_bio($ssl,$bio[0],$bio[1]); $self->{ssl} = $ssl; $self->{rbio} = $bio[0]; $self->{wbio} = $bio[1]; } sub _error { my ($self,$rv) = @_; if ($rv>0) { $SSL_ERROR = undef; return $rv; } my $err = Net::SSLeay::get_error($self->{ssl},$rv); if ($err == Net::SSLeay::ERROR_WANT_READ() || $err == Net::SSLeay::ERROR_WANT_WRITE()) { $SSL_ERROR = $err; $DEBUG && warn "[$self->{id}] rw:$err\n"; return; } $DEBUG && warn "[$self->{id}] ".Net::SSLeay::ERR_error_string($err)."\n"; return; } } Net-SSLeay-1.92/t/local/06_tcpecho.t0000644000175000001440000000223414124712004015503 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork initialise_libssl tcp_socket ); BEGIN { if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 4; } } initialise_libssl(); my $server = tcp_socket(); my $msg = 'ssleay-tcp-test'; my $pid; { $pid = fork(); die "fork failed: $!" unless defined $pid; if ($pid == 0) { $server->accept(\*Net::SSLeay::SSLCAT_S); my $got = Net::SSLeay::tcp_read_all(); is($got, $msg, 'tcp_read_all'); ok(Net::SSLeay::tcp_write_all(uc($got)), 'tcp_write_all'); close Net::SSLeay::SSLCAT_S; $server->close() || die("server listen socket close: $!"); exit; } } my @results; { my ($got) = Net::SSLeay::tcpcat($server->get_addr(), $server->get_port(), $msg); push @results, [ $got eq uc($msg), 'sent and received correctly' ]; } $server->close() || die("client listen socket close: $!"); waitpid $pid, 0; push @results, [ $? == 0, 'server exited with 0' ]; END { Test::More->builder->current_test(2); for my $t (@results) { ok( $t->[0], $t->[1] ); } } Net-SSLeay-1.92/t/local/03_use.t0000644000175000001440000001010414167101614014650 0ustar csnusers# Basic module loading test, plus OS/Perl/libssl information to assist # with diagnosing later test failures use lib 'inc'; use Test::Net::SSLeay; BEGIN { plan tests => 1; use_ok('Net::SSLeay'); } diag(""); diag("Testing Net::SSLeay $Net::SSLeay::VERSION"); diag(""); diag("Perl information:"); diag(" Version: '" . $] . "'"); diag(" Executable path: '" . $^X . "'"); diag(""); my $version_num; if (defined &Net::SSLeay::OpenSSL_version_num) { diag("Library version with OpenSSL_version_num():"); $version_num = Net::SSLeay::OpenSSL_version_num(); } else { diag("Library version with SSLeay():"); $version_num = Net::SSLeay::SSLeay(); } diag(" OPENSSL_VERSION_NUMBER: " . sprintf("'0x%08x'", $version_num)); diag(""); my $have_openssl_version = defined &Net::SSLeay::OpenSSL_version; diag("Library information with SSLeay_version()" . ($have_openssl_version ? " and OpenSSL_version()" : '') . ":"); diag(" SSLEAY_VERSION: '" . Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_VERSION()) . "'"); diag(" SSLEAY_CFLAGS: '" . Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_CFLAGS()) . "'"); diag(" SSLEAY_BUILT_ON: '" . Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_BUILT_ON()) . "'"); diag(" SSLEAY_PLATFORM: '" . Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_PLATFORM()) . "'"); diag(" SSLEAY_DIR: '" . Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_DIR()) . "'"); # This constant was added about the same time as OpenSSL_version() if ($have_openssl_version) { diag(" OPENSSL_ENGINES_DIR: '" . Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_ENGINES_DIR()) . "'"); } # These were added in OpenSSL 3.0.0 if (eval { Net::SSLeay::OPENSSL_MODULES_DIR(); 1; }) { diag(" OPENSSL_MODULES_DIR: '" . Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_MODULES_DIR()) . "'"); diag(" OPENSSL_CPU_INFO: '" . Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_CPU_INFO()) . "'"); diag(" OPENSSL_VERSION_STRING: '" . Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_VERSION_STRING()) . "'"); diag(" OPENSSL_FULL_VERSION_STRING: '" . Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_FULL_VERSION_STRING()) . "'"); } # These were added in OpenSSL 3.0.0 if (defined &Net::SSLeay::OPENSSL_version_major) { diag(""); diag("Library version information with OPENSSL_version_*():"); diag(" OPENSSL_version_major(): '" . Net::SSLeay::OPENSSL_version_major() . "'"); diag(" OPENSSL_version_minor(): '" . Net::SSLeay::OPENSSL_version_minor() . "'"); diag(" OPENSSL_version_patch(): '" . Net::SSLeay::OPENSSL_version_patch() . "'"); diag(" OPENSSL_version_pre_release(): '" . Net::SSLeay::OPENSSL_version_pre_release() . "'"); diag(" OPENSSL_version_build_metadata(): '" . Net::SSLeay::OPENSSL_version_build_metadata() . "'"); diag(""); diag("Library information with OPENSSL_info():"); diag(" OPENSSL_INFO_CONFIG_DIR: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_CONFIG_DIR()) . "'"); diag(" OPENSSL_INFO_ENGINES_DIR: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_ENGINES_DIR()) . "'"); diag(" OPENSSL_INFO_MODULES_DIR: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_MODULES_DIR()) . "'"); diag(" OPENSSL_INFO_DSO_EXTENSION: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_DSO_EXTENSION()) . "'"); diag(" OPENSSL_INFO_DIR_FILENAME_SEPARATOR: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_DIR_FILENAME_SEPARATOR()) . "'"); diag(" OPENSSL_INFO_LIST_SEPARATOR: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_LIST_SEPARATOR()) . "'"); diag(" OPENSSL_INFO_SEED_SOURCE: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_SEED_SOURCE()) . "'"); diag(" OPENSSL_INFO_CPU_SETTINGS: '" . Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_CPU_SETTINGS()) . "'"); } Net-SSLeay-1.92/t/local/46_msg_callback.t0000644000175000001440000000700714124712004016467 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl new_ctx tcp_socket ); if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 10; } initialise_libssl(); my $pid; alarm(30); END { kill 9,$pid if $pid } my $server = tcp_socket(); { # SSL server - just handle single connect and shutdown connection my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { for(qw(ctx ssl)) { my $cl = $server->accept(); my $ctx = new_ctx(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); for(1,2) { last if Net::SSLeay::shutdown($ssl)>0; } close($cl) || die("server close: $!"); } $server->close() || die("server listen socket close: $!"); exit; } } sub client { my ($where) = @_; # SSL client - connect and shutdown, all the while getting state updates # with info callback my @cb_data; my @states; my $msgcb = sub { my ($write_p,$version,$content_type,$buf,$len,$ssl,$cb_data) = @_; # buffer is of course randomized/timestamped, this is hard to test, so # skip this my $hex_buf = unpack("H*", $buf||''); # version appears to be different running in different test envs that # have a different openssl version, so we skip that too. This isn't a # good test for that, and it's not up to Net::SSLeay to make all # openssl implementations look the same # the 3 things this sub needs to do: # 1. not die # 2. no memory leak # 3. provide information # # The validness of the buffer can be checked, so we use this as a # validation instead. This selftest is not here to validate the # protocol and the intricacies of the possible implementation or # version (ssl3 vs tls1 etc) push @states,(defined $buf and length($buf) == $len)||0; # cb_data can act as a check push @cb_data, $cb_data; }; my $cl = $server->connect(); my $ctx = new_ctx(); Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL); Net::SSLeay::CTX_set_msg_callback($ctx, $msgcb, "CB_DATA") if $where eq 'ctx'; my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::set_msg_callback($ssl, $msgcb, "CB_DATA") if $where eq 'ssl'; Net::SSLeay::connect($ssl); for(1,2) { last if Net::SSLeay::shutdown($ssl)>0; } close($cl) || die("client close: $!"); ok(scalar(@states) > 1, "at least 2 messages logged: $where"); my $all_ok = 1; $all_ok &= $_ for @states; is($all_ok, 1, "all states are OK: length(buf) = len for $where"); ok(scalar(@cb_data) > 1, "all cb data SV's are OK for $where (at least 2)"); my $all_cb_data_ok = 0; $all_cb_data_ok++ for grep {$_ eq "CB_DATA"} grep {defined} @cb_data; is(scalar(@cb_data), $all_cb_data_ok, "all cb data SV's are OK for $where"); eval { Net::SSLeay::CTX_set_msg_callback($ctx, undef) if $where eq 'ctx'; Net::SSLeay::set_msg_callback($ssl, undef) if $where eq 'ssl'; }; is($@, '', "no error during set_msg_callback() for $where"); } client('ctx'); client('ssl'); $server->close() || die("client listen socket close: $!"); waitpid $pid, 0; Net-SSLeay-1.92/t/local/61_threads-cb-crash.t0000644000175000001440000000414513755162614017213 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_thread data_file_path initialise_libssl ); use FindBin; if (not can_thread()) { plan skip_all => "Threads not supported on this system"; } elsif ($^O eq 'cygwin') { # XXX-TODO perhaps perl+ithreads related issue (needs more investigation) plan skip_all => "this test sometimes crashes on Cygwin"; } else { # NOTE: expect warnings about threads still running under perl 5.8 and threads 1.71 plan tests => 1; } require threads; initialise_libssl(); my $start_time = time; my $file = data_file_path('simple-cert.key.pem'); #exit the whole program if it runs too long threads->new( sub { sleep 20; warn "FATAL: TIMEOUT!"; exit } )->detach; #print STDERR "Gonna start main thread part\n"; my $ctx = Net::SSLeay::CTX_new() or warn "CTX_new failed" and exit; Net::SSLeay::CTX_set_default_passwd_cb($ctx, \&callback); Net::SSLeay::CTX_use_PrivateKey_file($ctx, $file, &Net::SSLeay::FILETYPE_PEM) or warn "CTX_use_PrivateKey_file (file=$file) failed" and exit; Net::SSLeay::CTX_set_default_passwd_cb($ctx, undef); Net::SSLeay::CTX_free($ctx); #print STDERR "Gonna start multi-threading part\n"; threads->new(\&do_check) for (1..10); #print STDERR "Waiting for all threads to finish\n"; do_sleep(50) while(threads->list()); pass("successfully finished, duration=".(time-$start_time)); exit(0); sub callback { #printf STDERR ("[thread:%04d] Inside callback\n", threads->tid); return "secret"; # password } sub do_sleep { my $miliseconds = shift; select(undef, undef, undef, $miliseconds/1000); } sub do_check { #printf STDERR ("[thread:%04d] do_check started\n", threads->tid); my $c = Net::SSLeay::CTX_new() or warn "CTX_new failed" and exit; Net::SSLeay::CTX_set_default_passwd_cb($c, \&callback); Net::SSLeay::CTX_use_PrivateKey_file($c, $file, &Net::SSLeay::FILETYPE_PEM) or warn "CTX_use_PrivateKey_file (file=$file) failed" and exit; Net::SSLeay::CTX_set_default_passwd_cb($c, undef); Net::SSLeay::CTX_free($c); #do_sleep(rand(500)); #printf STDERR ("[thread:%04d] do_check finished\n", threads->tid); threads->detach(); } Net-SSLeay-1.92/t/local/38_priv-key.t0000755000175000001440000000273713755162614015663 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl ); plan tests => 10; initialise_libssl(); my $key_pem = data_file_path('simple-cert.key.pem'); my $key_pem_encrypted = data_file_path('simple-cert.key.enc.pem'); my $key_password = 'test'; { ok(my $bio_pem = Net::SSLeay::BIO_new_file($key_pem, 'r'), "BIO_new_file 3"); ok(Net::SSLeay::PEM_read_bio_PrivateKey($bio_pem), "PEM_read_bio_PrivateKey no password"); } { ok(my $bio_pem_encrypted = Net::SSLeay::BIO_new_file($key_pem_encrypted, 'r'), "BIO_new_file"); ok(Net::SSLeay::PEM_read_bio_PrivateKey($bio_pem_encrypted, sub { $key_password }), "PEM_read_bio_PrivateKey encrypted - callback"); } { ok(my $bio_pem_encrypted = Net::SSLeay::BIO_new_file($key_pem_encrypted, 'r'), "BIO_new_file"); ok(Net::SSLeay::PEM_read_bio_PrivateKey($bio_pem_encrypted, undef, $key_password), "PEM_read_bio_PrivateKey encrypted - password"); } { ok(my $bio_pem_encrypted = Net::SSLeay::BIO_new_file($key_pem_encrypted, 'r'), "BIO_new_file"); ok(!Net::SSLeay::PEM_read_bio_PrivateKey($bio_pem_encrypted, sub { $key_password . 'invalid' }), "PEM_read_bio_PrivateKey encrypted - callback (wrong password)"); } { ok(my $bio_pem_encrypted = Net::SSLeay::BIO_new_file($key_pem_encrypted, 'r'), "BIO_new_file"); ok(!Net::SSLeay::PEM_read_bio_PrivateKey($bio_pem_encrypted, undef, $key_password . 'invalid'), "PEM_read_bio_PrivateKey encrypted - password (wrong password)"); } Net-SSLeay-1.92/t/local/41_alpn_support.t0000644000175000001440000000553014124712004016605 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl new_ctx tcp_socket ); BEGIN { if (Net::SSLeay::SSLeay < 0x10002000) { plan skip_all => "OpenSSL 1.0.2 or above required"; } elsif (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 6; } } initialise_libssl(); my $server = tcp_socket(); my $pid; my $msg = 'ssleay-alpn-test'; my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); my @results; { # SSL server $pid = fork(); BAIL_OUT("failed to fork: $!") unless defined $pid; if ($pid == 0) { my $ns = $server->accept(); my ( $ctx, $proto ) = new_ctx(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); # TLSv1.3 servers send session tickets after the handshake; if a client # closes the connection before the server sends the tickets, accept() # fails with SSL_ERROR_SYSCALL and errno=EPIPE, which will cause this # process to receive a SIGPIPE signal and exit unsuccessfully if ( $proto eq 'TLSv1.3' && defined &Net::SSLeay::CTX_set_num_tickets ) { Net::SSLeay::CTX_set_num_tickets( $ctx, 0 ); } my $rv = Net::SSLeay::CTX_set_alpn_select_cb($ctx, ['http/1.1','spdy/2']); is($rv, 1, 'CTX_set_alpn_select_cb'); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($ns)); Net::SSLeay::accept($ssl); is(Net::SSLeay::P_alpn_selected($ssl), 'spdy/2', 'P_alpn_selected/server'); my $got = Net::SSLeay::ssl_read_all($ssl); is($got, $msg, 'ssl_read_all compare'); Net::SSLeay::ssl_write_all($ssl, uc($got)); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close($ns) || die("server close: $!"); $server->close() || die("server listen socket close: $!"); exit; } } { # SSL client my $s1 = $server->connect(); my $ctx1 = new_ctx(); my $rv = Net::SSLeay::CTX_set_alpn_protos($ctx1, ['spdy/2','http/1.1']); push @results, [ $rv==0, 'CTX_set_alpn_protos']; Net::SSLeay::CTX_set_options($ctx1, &Net::SSLeay::OP_ALL); my $ssl1 = Net::SSLeay::new($ctx1); Net::SSLeay::set_fd($ssl1, $s1); Net::SSLeay::connect($ssl1); Net::SSLeay::ssl_write_all($ssl1, $msg); push @results, [ 'spdy/2' eq Net::SSLeay::P_alpn_selected($ssl1), 'P_alpn_selected/client']; Net::SSLeay::free($ssl1); Net::SSLeay::CTX_free($ctx1); close($s1) || die("client close: $!"); $server->close() || die("client listen socket close: $!"); } waitpid $pid, 0; push @results, [$? == 0, 'server exited with 0']; END { Test::More->builder->current_test(3); ok( $_->[0], $_->[1] ) for (@results); } Net-SSLeay-1.92/t/local/34_x509_crl.t0000755000175000001440000001501013755162614015442 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl is_openssl ); plan tests => 42; initialise_libssl(); my $ca_crt_pem = data_file_path('intermediate-ca.cert.pem'); my $ca_key_pem = data_file_path('intermediate-ca.key.pem'); ok(my $bio1 = Net::SSLeay::BIO_new_file($ca_crt_pem, 'r'), "BIO_new_file 1"); ok(my $ca_cert = Net::SSLeay::PEM_read_bio_X509($bio1), "PEM_read_bio_X509"); ok(my $bio2 = Net::SSLeay::BIO_new_file($ca_key_pem, 'r'), "BIO_new_file 2"); ok(my $ca_pk = Net::SSLeay::PEM_read_bio_PrivateKey($bio2), "PEM_read_bio_PrivateKey"); { ### X509_CRL show info my $crl_der = data_file_path('intermediate-ca.crl.der'); my $crl_pem = data_file_path('intermediate-ca.crl.pem'); ok(my $bio1 = Net::SSLeay::BIO_new_file($crl_der, 'rb'), "BIO_new_file 1"); ok(my $bio2 = Net::SSLeay::BIO_new_file($crl_pem, 'r'), "BIO_new_file 2"); ok(my $crl1 = Net::SSLeay::d2i_X509_CRL_bio($bio1), "d2i_X509_CRL_bio"); ok(my $crl2 = Net::SSLeay::PEM_read_bio_X509_CRL($bio2), "PEM_read_bio_X509_CRL"); ok(my $name1 = Net::SSLeay::X509_CRL_get_issuer($crl1), "X509_CRL_get_issuer 1"); ok(my $name2 = Net::SSLeay::X509_CRL_get_issuer($crl2), "X509_CRL_get_issuer 2"); is(Net::SSLeay::X509_NAME_cmp($name1, $name2), 0, "X509_NAME_cmp"); is(Net::SSLeay::X509_NAME_print_ex($name1), 'CN=Intermediate CA,OU=Test Suite,O=Net-SSLeay,C=PL', "X509_NAME_print_ex"); ok(my $time_last = Net::SSLeay::X509_CRL_get_lastUpdate($crl1), "X509_CRL_get_lastUpdate"); ok(my $time_next = Net::SSLeay::X509_CRL_get_nextUpdate($crl1), "X509_CRL_get_nextUpdate"); SKIP: { skip 'openssl-0.9.7e required', 2 unless Net::SSLeay::SSLeay >= 0x0090705f; is(Net::SSLeay::P_ASN1_TIME_get_isotime($time_last), '2020-07-01T00:00:00Z', "P_ASN1_TIME_get_isotime last"); is(Net::SSLeay::P_ASN1_TIME_get_isotime($time_next), '2020-07-08T00:00:00Z', "P_ASN1_TIME_get_isotime next"); } is(Net::SSLeay::X509_CRL_get_version($crl1), 1, "X509_CRL_get_version"); ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); is(unpack("H*",Net::SSLeay::X509_CRL_digest($crl1, $sha1_digest)), 'f0e5c853477a206c03f7347aee09a01d91df0ac5', "X509_CRL_digest"); } { ### X509_CRL create ok(my $crl = Net::SSLeay::X509_CRL_new(), "X509_CRL_new"); ok(my $name = Net::SSLeay::X509_get_subject_name($ca_cert), "X509_get_subject_name"); SKIP: { skip('requires openssl-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(Net::SSLeay::X509_CRL_set_issuer_name($crl, $name), "X509_CRL_set_issuer_name"); } if (Net::SSLeay::SSLeay >= 0x0090705f) { Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_CRL_get_lastUpdate($crl), "2010-02-01T00:00:00Z"); Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_CRL_get_nextUpdate($crl), "2011-02-01T00:00:00Z"); } else { # P_ASN1_TIME_set_isotime not available before openssl-0.9.7e Net::SSLeay::X509_gmtime_adj(Net::SSLeay::X509_CRL_get_lastUpdate($crl), 0); Net::SSLeay::X509_gmtime_adj(Net::SSLeay::X509_CRL_get_lastUpdate($crl), 0); } SKIP: { skip('requires openssl-0.9.7', 2) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(Net::SSLeay::X509_CRL_set_version($crl, 1), "X509_CRL_set_version"); my $ser = Net::SSLeay::ASN1_INTEGER_new(); Net::SSLeay::P_ASN1_INTEGER_set_hex($ser, "4AFED5654654BCEDED4AFED5654654BCEDED"); ok(Net::SSLeay::P_X509_CRL_set_serial($crl, $ser), "P_X509_CRL_set_serial"); Net::SSLeay::ASN1_INTEGER_free($ser); } my @rev_table = ( { serial_hex=>'1A2B3D', rev_datetime=>"2011-02-01T00:00:00Z", comp_datetime=>"2911-11-11T00:00:00Z", reason=>2 }, # 2 = cACompromise { serial_hex=>'2A2B3D', rev_datetime=>"2011-03-01T00:00:00Z", comp_datetime=>"2911-11-11T00:00:00Z", reason=>3 }, # 3 = affiliationChanged ); my $rev_datetime = Net::SSLeay::ASN1_TIME_new(); my $comp_datetime = Net::SSLeay::ASN1_TIME_new(); for my $item (@rev_table) { if (Net::SSLeay::SSLeay >= 0x0090705f) { Net::SSLeay::P_ASN1_TIME_set_isotime($rev_datetime, $item->{rev_datetime}); Net::SSLeay::P_ASN1_TIME_set_isotime($comp_datetime, $item->{comp_datetime}); } else { # P_ASN1_TIME_set_isotime not available before openssl-0.9.7e Net::SSLeay::X509_gmtime_adj($rev_datetime, 0); Net::SSLeay::X509_gmtime_adj($comp_datetime, 0); } SKIP: { skip('requires openssl-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(Net::SSLeay::P_X509_CRL_add_revoked_serial_hex($crl, $item->{serial_hex}, $rev_datetime, $item->{reason}, $comp_datetime), "P_X509_CRL_add_revoked_serial_hex"); } } Net::SSLeay::ASN1_TIME_free($rev_datetime); Net::SSLeay::ASN1_TIME_free($comp_datetime); ok(Net::SSLeay::P_X509_CRL_add_extensions($crl,$ca_cert, &Net::SSLeay::NID_authority_key_identifier => 'keyid:always,issuer:always', ), "P_X509_CRL_add_extensions"); ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); SKIP: { skip('requires openssl-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(Net::SSLeay::X509_CRL_sort($crl), "X509_CRL_sort"); } ok(Net::SSLeay::X509_CRL_sign($crl, $ca_pk, $sha1_digest), "X509_CRL_sign"); like(my $crl_pem = Net::SSLeay::PEM_get_string_X509_CRL($crl), qr/-----BEGIN X509 CRL-----/, "PEM_get_string_X509_CRL"); #write_file("tmp.crl.pem", $crl_pem); is(Net::SSLeay::X509_CRL_free($crl), undef, "X509_CRL_free"); } { ### special tests my $crl_der = data_file_path('intermediate-ca.crl.der'); ok(my $bio = Net::SSLeay::BIO_new_file($crl_der, 'rb'), "BIO_new_file"); ok(my $crl = Net::SSLeay::d2i_X509_CRL_bio($bio), "d2i_X509_CRL_bio"); is(Net::SSLeay::X509_CRL_verify($crl, Net::SSLeay::X509_get_pubkey($ca_cert)), 1, "X509_CRL_verify"); ok(my $time_last = Net::SSLeay::X509_CRL_get_lastUpdate($crl), "X509_CRL_get_lastUpdate"); ok(my $time_next = Net::SSLeay::X509_CRL_get_nextUpdate($crl), "X509_CRL_get_nextUpdate"); SKIP: { skip('requires openssl-0.9.7', 2) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(my $sn = Net::SSLeay::P_X509_CRL_get_serial($crl), "P_X509_CRL_get_serial"); is(Net::SSLeay::ASN1_INTEGER_get($sn), 1, "ASN1_INTEGER_get"); } SKIP: { skip('requires openssl-0.9.7', 3) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(my $crl2 = Net::SSLeay::X509_CRL_new(), "X509_CRL_new"); ok(Net::SSLeay::X509_CRL_set_lastUpdate($crl2, $time_last), "X509_CRL_set_lastUpdate"); ok(Net::SSLeay::X509_CRL_set_nextUpdate($crl2, $time_next), "X509_CRL_set_nextUpdate"); Net::SSLeay::X509_CRL_free($crl2); } } Net-SSLeay-1.92/t/local/09_ctx_new.t0000644000175000001440000001741214000617570015541 0ustar csnusers# Test SSL_CTX_new and related functions, and handshake state machine retrieval use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(initialise_libssl); plan tests => 44; initialise_libssl(); sub is_known_proto_version { return 1 if $_[0] == 0x0000; # Automatic version selection return 1 if $_[0] == Net::SSLeay::SSL3_VERSION(); # OpenSSL 0.9.8+ return 1 if $_[0] == Net::SSLeay::TLS1_VERSION(); # OpenSSL 0.9.8+ return 1 if $_[0] == Net::SSLeay::TLS1_1_VERSION(); # OpenSSL 0.9.8+ return 1 if $_[0] == Net::SSLeay::TLS1_2_VERSION(); # OpenSSL 0.9.8+ if (eval { Net::SSLeay::TLS1_3_VERSION() }) { return 1 if $_[0] == Net::SSLeay::TLS1_3_VERSION(); # OpenSSL 1.1.1+ } return; } # Shortcuts from SSLeay.xs my $ctx = Net::SSLeay::CTX_new(); ok($ctx, 'CTX_new'); $ctx = Net::SSLeay::CTX_v23_new(); ok($ctx, 'CTX_v23_new'); $ctx = Net::SSLeay::CTX_tlsv1_new(); ok($ctx, 'CTX_tlsv1_new'); my $ctx_23 = Net::SSLeay::CTX_new_with_method(Net::SSLeay::SSLv23_method()); ok($ctx_23, 'CTX_new with SSLv23_method'); my $ctx_23_client = Net::SSLeay::CTX_new_with_method(Net::SSLeay::SSLv23_client_method()); ok($ctx_23_client, 'CTX_new with SSLv23_client_method'); my $ctx_23_server = Net::SSLeay::CTX_new_with_method(Net::SSLeay::SSLv23_server_method()); ok($ctx_23_server, 'CTX_new with SSLv23_server_method'); my $ctx_tls1 = Net::SSLeay::CTX_new_with_method(Net::SSLeay::TLSv1_method()); ok($ctx_tls1, 'CTX_new with TLSv1_method'); # Retrieve information about the handshake state machine is(Net::SSLeay::in_connect_init(Net::SSLeay::new($ctx_23_client)), 1, 'in_connect_init() is 1 for client'); is(Net::SSLeay::in_accept_init(Net::SSLeay::new($ctx_23_client)), 0, 'in_accept_init() is 0 for client'); is(Net::SSLeay::in_connect_init(Net::SSLeay::new($ctx_23_server)), 0, 'in_connect_init() is 0 for server'); is(Net::SSLeay::in_accept_init(Net::SSLeay::new($ctx_23_server)), 1, 'in_accept_init() is 1 for server'); # Need recent enough OpenSSL or LibreSSL for TLS_method functions my ($ctx_tls, $ssl_tls, $ctx_tls_client, $ssl_tls_client, $ctx_tls_server, $ssl_tls_server); if (exists &Net::SSLeay::TLS_method) { $ctx_tls = Net::SSLeay::CTX_new_with_method(Net::SSLeay::TLS_method()); ok($ctx_tls, 'CTX_new with TLS_method'); $ssl_tls = Net::SSLeay::new($ctx_tls); ok($ssl_tls, 'New SSL created with ctx_tls'); $ctx_tls_client = Net::SSLeay::CTX_new_with_method(Net::SSLeay::TLS_client_method()); ok($ctx_tls_client, 'CTX_new with TLS_client_method'); $ctx_tls_server = Net::SSLeay::CTX_new_with_method(Net::SSLeay::TLS_server_method()); ok($ctx_tls_server, 'CTX_new with TLS_server_method'); } else { SKIP: { skip('Do not have Net::SSLeay::TLS_method', 4); }; } # Having TLS_method() does not necessarily that proto setters are available if ($ctx_tls && exists &Net::SSLeay::CTX_set_min_proto_version) { my $ver_1_0 = Net::SSLeay::TLS1_VERSION(); ok($ver_1_0, "Net::SSLeay::TLS1_VERSION() returns non-false: $ver_1_0, hex " . sprintf('0x%04x', $ver_1_0)); my $ver_min = Net::SSLeay::TLS1_1_VERSION(); ok($ver_min, "Net::SSLeay::TLS1_1_VERSION() returns non-false: $ver_min, hex " . sprintf('0x%04x', $ver_min)); my $ver_max = Net::SSLeay::TLS1_2_VERSION(); ok($ver_max, "Net::SSLeay::TLS1_2_VERSION() returns $ver_max, hex " . sprintf('0x%04x', $ver_max)); isnt($ver_1_0, $ver_min, 'Version 1_0 and 1_1 values are different'); isnt($ver_min, $ver_max, 'Version 1_1 and 1_2 values are different'); my $rv; $rv = Net::SSLeay::CTX_set_min_proto_version($ctx_tls_client, $ver_min); is($rv, 1, 'Setting client CTX minimum version'); $rv = Net::SSLeay::CTX_set_min_proto_version($ctx_tls_client, 0); is($rv, 1, 'Setting client CTX minimum version to automatic'); $rv = Net::SSLeay::CTX_set_min_proto_version($ctx_tls_client, -1); is($rv, 0, 'Setting client CTX minimum version to bad value'); $rv = Net::SSLeay::CTX_set_min_proto_version($ctx_tls_client, $ver_min); is($rv, 1, 'Setting client CTX minimum version back to good value'); $rv = Net::SSLeay::CTX_set_max_proto_version($ctx_tls_client, $ver_max); is($rv, 1, 'Setting client CTX maximum version'); # This SSL should have min and max versions set based on its # CTX. We test the getters later, if they exist. $ssl_tls_client = Net::SSLeay::new($ctx_tls_client); ok($ssl_tls_client, 'New SSL created from client CTX'); # This SSL should have min and max versions set to automatic based # on its CTX. We change them now and test the getters later, if # they exist. $ssl_tls_server = Net::SSLeay::new($ctx_tls_server); ok($ssl_tls_server, 'New SSL created from server CTX'); $rv = Net::SSLeay::set_min_proto_version($ssl_tls_server, Net::SSLeay::TLS1_VERSION()); is($rv, 1, 'Setting SSL minimum version for ssl_tls_server'); $rv = Net::SSLeay::set_max_proto_version($ssl_tls_server, Net::SSLeay::TLS1_2_VERSION()); is($rv, 1, 'Setting SSL maximum version for ssl_tls_server'); } else { SKIP: { skip('Do not have Net::SSLeay::CTX_get_min_proto_version', 14); }; } # Having TLS_method() does not necessarily that proto getters are available if ($ctx_tls && exists &Net::SSLeay::CTX_get_min_proto_version) { my $ver; $ver = Net::SSLeay::CTX_get_min_proto_version($ctx_tls); ok(is_known_proto_version($ver), 'TLS_method CTX has known minimum version'); $ver = Net::SSLeay::CTX_get_max_proto_version($ctx_tls); ok(is_known_proto_version($ver), 'TLS_method CTX has known maximum version'); $ver = Net::SSLeay::get_min_proto_version($ssl_tls); ok(is_known_proto_version($ver), 'SSL from TLS_method CTX has known minimum version'); $ver = Net::SSLeay::get_max_proto_version($ssl_tls); ok(is_known_proto_version($ver), 'SSL from TLS_method CTX has known maximum version'); # First see if our CTX has min and max settings enabled $ver = Net::SSLeay::CTX_get_min_proto_version($ctx_tls_client); is($ver, Net::SSLeay::TLS1_1_VERSION(), 'TLS_client CTX has minimum version correctly set'); $ver = Net::SSLeay::CTX_get_max_proto_version($ctx_tls_client); is($ver, Net::SSLeay::TLS1_2_VERSION(), 'TLS_client CTX has maximum version correctly set'); # Then see if our client SSL has min and max settings enabled $ver = Net::SSLeay::get_min_proto_version($ssl_tls_client); is($ver, Net::SSLeay::TLS1_1_VERSION(), 'SSL from TLS_client CTX has minimum version correctly set'); $ver = Net::SSLeay::get_max_proto_version($ssl_tls_client); is($ver, Net::SSLeay::TLS1_2_VERSION(), 'SSL from TLS_client CTX has maximum version correctly set'); # Then see if our server SSL has min and max settings enabled $ver = Net::SSLeay::get_min_proto_version($ssl_tls_server); is($ver, Net::SSLeay::TLS1_VERSION(), 'SSL from TLS_server CTX has minimum version correctly set'); $ver = Net::SSLeay::get_max_proto_version($ssl_tls_server); is($ver, Net::SSLeay::TLS1_2_VERSION(), 'SSL from TLS_server CTX has maximum version correctly set'); } else { SKIP: { skip('Do not have Net::SSLeay::CTX_get_min_proto_version', 10); }; } if (eval {Net::SSLeay::TLS1_3_VERSION()}) { my $ver_1_2 = Net::SSLeay::TLS1_2_VERSION(); ok($ver_1_2, "Net::SSLeay::TLS1_2_VERSION() returns non-false: $ver_1_2, hex " . sprintf('0x%04x', $ver_1_2)); my $ver_1_3 = Net::SSLeay::TLS1_3_VERSION(); ok($ver_1_3, "Net::SSLeay::TLS1_3_VERSION() returns non-false: $ver_1_3, hex " . sprintf('0x%04x', $ver_1_3)); isnt($ver_1_2, $ver_1_3, 'Version 1_2 and 1_3 values are different'); my $rv = 0; ok(eval {$rv = Net::SSLeay::OP_NO_TLSv1_3()}, 'Have OP_NO_TLSv1_3'); isnt($rv, 0, 'OP_NO_TLSv1_3 returns non-zero value'); } else { SKIP: { skip('Do not have Net::SSLeay::TLS1_3_VERSION', 5); }; } exit(0); Net-SSLeay-1.92/t/local/40_npn_support.t0000644000175000001440000000571014124712004016445 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl new_ctx tcp_socket ); BEGIN { if (Net::SSLeay::SSLeay < 0x10001000) { plan skip_all => "OpenSSL 1.0.1 or above required"; } elsif (Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER")) { plan skip_all => "LibreSSL removed support for NPN"; } elsif (not can_fork()) { plan skip_all => "fork() not supported on this system"; } elsif ( !eval { new_ctx( undef, 'TLSv1.2' ); 1 } ) { # NPN isn't well-defined for TLSv1.3, so these tests can't be run if # that's the only available protocol version plan skip_all => 'TLSv1.2 or below not available in this libssl'; } else { plan tests => 7; } } initialise_libssl(); my $server = tcp_socket(); my $msg = 'ssleay-npn-test'; my $pid; my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); my @results; { # SSL server $pid = fork(); BAIL_OUT("failed to fork: $!") unless defined $pid; if ($pid == 0) { my $ns = $server->accept(); my ( $ctx, $proto ) = new_ctx( undef, 'TLSv1.2' ); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); my $rv = Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, ['spdy/2','http1.1']); is($rv, 1, 'CTX_set_next_protos_advertised_cb'); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($ns)); Net::SSLeay::accept($ssl); is('spdy/2' , Net::SSLeay::P_next_proto_negotiated($ssl), 'P_next_proto_negotiated/server'); my $got = Net::SSLeay::ssl_read_all($ssl); is($got, $msg, 'ssl_read_all compare'); Net::SSLeay::ssl_write_all($ssl, uc($got)); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close($ns) || die("server close: $!"); $server->close() || die("server listen socket close: $!"); exit; } } { # SSL client my $s1 = $server->connect(); my $ctx1 = new_ctx( undef, 'TLSv1.2' ); my $rv = Net::SSLeay::CTX_set_next_proto_select_cb($ctx1, ['http1.1','spdy/2']); push @results, [ $rv==1, 'CTX_set_next_proto_select_cb']; Net::SSLeay::CTX_set_options($ctx1, &Net::SSLeay::OP_ALL); my $ssl1 = Net::SSLeay::new($ctx1); Net::SSLeay::set_fd($ssl1, $s1); Net::SSLeay::connect($ssl1); Net::SSLeay::ssl_write_all($ssl1, $msg); push @results, [ 'spdy/2' eq Net::SSLeay::P_next_proto_negotiated($ssl1), 'P_next_proto_negotiated/client']; push @results, [ 1 == Net::SSLeay::P_next_proto_last_status($ssl1), 'P_next_proto_last_status/client']; Net::SSLeay::free($ssl1); Net::SSLeay::CTX_free($ctx1); close($s1) || die("client close: $!"); $server->close() || die("client listen socket close: $!"); } waitpid $pid, 0; push @results, [$? == 0, 'server exited with 0']; END { Test::More->builder->current_test(3); ok( $_->[0], $_->[1] ) for (@results); } Net-SSLeay-1.92/t/local/42_info_callback.t0000644000175000001440000000510514124712004016625 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl new_ctx tcp_socket ); if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 2; } initialise_libssl(); my $pid; alarm(30); END { kill 9,$pid if $pid } my $server = tcp_socket(); { # SSL server - just handle single connect and shutdown connection my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { for(qw(ctx ssl)) { my $cl = $server->accept(); my $ctx = new_ctx(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); for(1,2) { last if Net::SSLeay::shutdown($ssl)>0; } close($cl) || die("server close: $!"); } $server->close() || die("server listen socket close: $!"); exit; } } sub client { my ($where,$expect) = @_; # SSL client - connect and shutdown, all the while getting state updates # with info callback my @states; my $infocb = sub { my ($ssl,$where,$ret) = @_; push @states,[$where,$ret]; }; my $cl = $server->connect(); my $ctx = new_ctx(); Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL); Net::SSLeay::CTX_set_info_callback($ctx, $infocb) if $where eq 'ctx'; my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::set_info_callback($ssl, $infocb) if $where eq 'ssl'; Net::SSLeay::connect($ssl); for(1,2) { last if Net::SSLeay::shutdown($ssl)>0; } for my $st (@states) { my @txt; for(qw( CB_READ_ALERT CB_WRITE_ALERT CB_ACCEPT_EXIT CB_ACCEPT_LOOP CB_CONNECT_EXIT CB_CONNECT_LOOP CB_HANDSHAKE_START CB_HANDSHAKE_DONE CB_READ CB_WRITE CB_ALERT CB_LOOP CB_EXIT )) { my $i = eval "Net::SSLeay::$_()" or BAIL_OUT("no state $_ known"); if (($st->[0] & $i) == $i) { $st->[0] &= ~$i; push @txt,$_; } } die "incomplete: @txt | $st->[0]" if $st->[0]; $st = join("|",@txt); } if ("@states" =~ $expect) { pass("$where: @states"); } else { fail("$where: @states"); } close($cl) || die("client close: $!"); } my $expect = qr{^ CB_HANDSHAKE_START\s (CB_CONNECT_LOOP\s)+ CB_HANDSHAKE_DONE\s CB_CONNECT_EXIT\b }x; client('ctx',$expect); client('ssl',$expect); $server->close() || die("client listen socket close: $!"); waitpid $pid, 0; Net-SSLeay-1.92/t/local/22_provider.t0000644000175000001440000001031614163136013015711 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay (initialise_libssl); # We don't do intialise_libssl() now because we want to want to # trigger automatic loading of the default provider. # # Quote from # https://www.openssl.org/docs/manmaster/man7/OSSL_PROVIDER-default.html # about default provider: # # It is loaded automatically the first time that an algorithm is # fetched from a provider or a function acting on providers is # called and no other provider has been loaded yet. # #initialise_libssl(); # Don't do this if (defined &Net::SSLeay::OSSL_PROVIDER_load) { plan(tests => 16); } else { plan(skip_all => "no support for providers"); } # Supplied OpenSSL configuration file may load unwanted providers. local $ENV{OPENSSL_CONF} = ''; # provider loading, availability and unloading { # See top of file why things are done in this order. We don't want # to load the default provider automatically. my $null_provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'null'); ok($null_provider, 'null provider load returns a pointer'); my $null_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'null'); is($null_avail, 1, 'null provider loaded and available'); my $default_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'default'); is($default_avail, 0, 'default provider not loaded, not available'); if ($default_avail) { diag('Default provider was already available. More provider tests in this and other provider test files may fail'); diag('If your configuration loads the default provider, consider ignoring the errors or using OPENSSL_CONF environment variable'); diag('For example: OPENSSL_CONF=/path/to/openssl/ssl/openssl.cnf.dist make test'); } my $null_unload = Net::SSLeay::OSSL_PROVIDER_unload($null_provider); is($null_unload, 1, 'null provider successfully unloaded'); $null_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'null'); is($null_avail, 0, 'null provider is no longer available'); $default_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'default'); is($default_avail, 0, 'default provider still not loaded, not available'); my $default_provider_undef_libctx = Net::SSLeay::OSSL_PROVIDER_load(undef, 'default'); ok($default_provider_undef_libctx, 'default provider with NULL libctx loaded successfully'); my $libctx = Net::SSLeay::OSSL_LIB_CTX_get0_global_default(); ok($libctx, 'OSSL_LIB_CTX_get0_global_default() returns a pointer'); my $default_provider_default_libctx = Net::SSLeay::OSSL_PROVIDER_load($libctx, 'default'); ok($default_provider_default_libctx, 'default provider with default libctx loaded successfully'); is($default_provider_default_libctx, $default_provider_undef_libctx, 'OSSL_PROVIDER_load with undef and defined libctx return the same pointer'); } # get0_name, selftest { my $null_provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'null'); my $default_provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'default'); is(Net::SSLeay::OSSL_PROVIDER_get0_name($null_provider), 'null', 'get0_name for null provider'); is(Net::SSLeay::OSSL_PROVIDER_get0_name($default_provider), 'default', 'get0_name for default provider'); is(Net::SSLeay::OSSL_PROVIDER_self_test($null_provider), 1, 'self_test for null provider'); is(Net::SSLeay::OSSL_PROVIDER_self_test($default_provider), 1, 'self_test for default provider'); } # do_all { my %seen_providers; sub all_cb { my ($provider_cb, $cbdata_cb) = @_; fail('provider already seen') if exists $seen_providers{$provider_cb}; $seen_providers{$provider_cb} = $cbdata_cb; return 1; }; my $null_provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'null'); my $default_provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'default'); my $cbdata = 'data for cb'; Net::SSLeay::OSSL_PROVIDER_do_all(undef, \&all_cb, $cbdata); foreach my $provider ($null_provider, $default_provider) { my $name = Net::SSLeay::OSSL_PROVIDER_get0_name($provider); is(delete $seen_providers{$provider}, $cbdata, "provider '$name' was seen"); } foreach my $provider (keys(%seen_providers)) { my $name = Net::SSLeay::OSSL_PROVIDER_get0_name($provider); diag("Provider '$name' was also seen by the callback"); } } Net-SSLeay-1.92/t/local/50_digest.t0000644000175000001440000003166013755162614015360 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl ); plan tests => 203; initialise_libssl(); Net::SSLeay::OpenSSL_add_all_digests(); sub digest_chunked_f1 { my ($file, $digest) = @_; my $md = Net::SSLeay::EVP_get_digestbyname($digest) or BAIL_OUT "digest '$digest' not available"; my $ctx = Net::SSLeay::EVP_MD_CTX_create(); Net::SSLeay::EVP_DigestInit($ctx, $md); open my $fh, "<", $file or BAIL_OUT "cannot open file '$file'"; binmode $fh; while(my $len = sysread($fh, my $chunk, 500)) { Net::SSLeay::EVP_DigestUpdate($ctx,$chunk); } close $fh; my $result = Net::SSLeay::EVP_DigestFinal($ctx); Net::SSLeay::EVP_MD_CTX_destroy($ctx); return $result; } sub digest_chunked_f2 { my ($file, $digest) = @_; my $md = Net::SSLeay::EVP_get_digestbyname($digest) or BAIL_OUT "digest '$digest' not available"; my $ctx = Net::SSLeay::EVP_MD_CTX_create(); Net::SSLeay::EVP_DigestInit_ex($ctx, $md, 0); #NULL ENGINE just to test whether the function exists open my $fh, "<", $file or BAIL_OUT "cannot open file '$file'"; binmode $fh; while(my $len = sysread($fh, my $chunk, 5)) { Net::SSLeay::EVP_DigestUpdate($ctx,$chunk); } close $fh; my $result = Net::SSLeay::EVP_DigestFinal_ex($ctx); Net::SSLeay::EVP_MD_CTX_destroy($ctx); return $result; } sub digest_file { my ($file, $expected_results, $available_digests) = @_; for my $d (sort keys %$expected_results) { SKIP: { skip "digest '$d' not available (or pre-1.0.0)", 2 unless $available_digests->{$d}; is( unpack("H*", digest_chunked_f1($file, $d)), $expected_results->{$d}, "$d chunked.1 [$file]"); is( unpack("H*", digest_chunked_f2($file, $d)), $expected_results->{$d}, "$d chunked.2 [$file]"); } } open my $f, "<", $file or BAIL_OUT "cannot open file '$file'"; binmode $f; sysread($f, my $data, -s $file) or BAIL_OUT "sysread failed"; close $f; is(length($data), -s $file, 'got the whole file'); SKIP: { skip "Net::SSLeay::MD2 not available", 1 unless exists &Net::SSLeay::MD2 and exists $available_digests->{md2}; is( unpack("H*", Net::SSLeay::MD2($data)), $expected_results->{md2}, "MD2 all-in-one-go [$file]"); } SKIP: { skip "Net::SSLeay::MD4 not available", 1 unless exists &Net::SSLeay::MD4 and exists $available_digests->{md4}; is( unpack("H*", Net::SSLeay::MD4($data)), $expected_results->{md4}, "MD4 all-in-one-go [$file]"); } SKIP: { skip "Net::SSLeay::MD5 not available", 1 unless exists &Net::SSLeay::MD5 and exists $available_digests->{md5}; is( unpack("H*", Net::SSLeay::MD5($data)), $expected_results->{md5}, "MD5 all-in-one-go [$file]"); } SKIP: { skip "Net::SSLeay::RIPEMD160 not available", 1 unless exists &Net::SSLeay::RIPEMD160 and exists $available_digests->{ripemd160}; is( unpack("H*", Net::SSLeay::RIPEMD160($data)), $expected_results->{ripemd160}, "RIPEMD160 all-in-one-go [$file]"); } } sub digest_strings { my ($fps, $available_digests) = @_; for my $data (sort keys %$fps) { for my $d (sort keys %{$fps->{$data}}) { SKIP: { skip "digest '$d' not available (or pre-1.0.0)", 2 unless $available_digests->{$d}; my $md = Net::SSLeay::EVP_get_digestbyname($d) or BAIL_OUT "digest '$d' not available"; my $ctx = Net::SSLeay::EVP_MD_CTX_create(); Net::SSLeay::EVP_DigestInit($ctx, $md); Net::SSLeay::EVP_DigestUpdate($ctx, $data); my $result1 = Net::SSLeay::EVP_DigestFinal($ctx); Net::SSLeay::EVP_MD_CTX_destroy($ctx); is(unpack('H*', $result1), $fps->{$data}->{$d}, "$d for '$data'"); # test EVP_Digest my $result2 = Net::SSLeay::EVP_Digest($data, Net::SSLeay::EVP_get_digestbyname($d)); is(unpack('H*', $result2), $fps->{$data}->{$d}, "EVP_Digest($d)"); } } SKIP: { skip "Net::SSLeay::MD2 not available", 1 unless exists &Net::SSLeay::MD2 and exists $available_digests->{md2}; is(unpack('H*', Net::SSLeay::MD2($data)), $fps->{$data}->{md2}, "MD2 hash for '$data'"); } SKIP: { skip "Net::SSLeay::MD4 not available", 1 unless exists &Net::SSLeay::MD4 and exists $available_digests->{md4}; is(unpack('H*', Net::SSLeay::MD4($data)), $fps->{$data}->{md4}, "MD4 hash for '$data'"); } SKIP: { skip "Net::SSLeay::MD5 not available", 1 unless exists &Net::SSLeay::MD5 and exists $available_digests->{md5}; is(unpack('H*', Net::SSLeay::MD5($data)), $fps->{$data}->{md5}, "MD5 hash for '$data'"); } SKIP: { skip "Net::SSLeay::RIPEMD160 not available", 1 unless exists &Net::SSLeay::RIPEMD160 and exists $available_digests->{ripemd160}; is(unpack('H*', Net::SSLeay::RIPEMD160($data)), $fps->{$data}->{ripemd160}, "RIPEMD160 hash for '$data'"); } SKIP: { skip "Net::SSLeay::SHA1 not available", 1 unless exists &Net::SSLeay::SHA1 and exists $available_digests->{sha1}; is(unpack('H*', Net::SSLeay::SHA1($data)), $fps->{$data}->{sha1}, "SHA1 hash for '$data'"); } SKIP: { skip "Net::SSLeay::SHA256 not available", 1 unless exists &Net::SSLeay::SHA256 and exists $available_digests->{sha256}; is(unpack('H*', Net::SSLeay::SHA256($data)), $fps->{$data}->{sha256}, "SHA256 hash for '$data'"); } SKIP: { skip "Net::SSLeay::SHA512 not available", 1 unless exists &Net::SSLeay::SHA512 and exists $available_digests->{sha512}; is(unpack('H*', Net::SSLeay::SHA512($data)), $fps->{$data}->{sha512}, "SHA512 hash for '$data'"); } } } my %all_digests; eval { if (Net::SSLeay::SSLeay >= 0x1000000f) { my $ctx = Net::SSLeay::EVP_MD_CTX_create(); %all_digests = map { $_=>1 } grep { # P_EVP_MD_list_all() does not remove digests disabled in FIPS my $md; $md = Net::SSLeay::EVP_get_digestbyname($_) and Net::SSLeay::EVP_DigestInit($ctx, $md) } @{Net::SSLeay::P_EVP_MD_list_all()}; } else { %all_digests = (); } }; is($@, '', 'digest init OK'); SKIP: { skip "pre-1.0.0", 1 unless Net::SSLeay::SSLeay >= 0x1000000f; isnt(scalar(keys %all_digests), 0, 'non-empty digest list'); } my $file = data_file_path('binary-test.file'); my $file_digests = { md2 => '67ae6d821be6898101414c56b1fb4f46', md4 => '480438696e7d9a6ab3ecc1e2a3419f78', md5 => 'cc89b43c171818c347639fa5170aee16', mdc2 => 'ee605fe3fc966a7b17185ebdbcd13ada', ripemd160 => 'cb70ba43fc6d263f6d7816170c1a33f28c2000fe', sha => 'c151c6f408cb94bc5c53b17852efbe8bfbeec2b9', sha1 => '059404d1d0e952d0457a6c99b6e68b3b44c8ef13', sha224 => '161c65efa1b9762f7e0448b5b369a3e2c236876b0b57a35add5106bb', sha256 => 'e416730ddaa34729adb32ec6ddad4e50fca1fe97de313e800196b1f8cd5032bd', sha512 => '8b5e7181fc76d49e1cb7971a6980b5d8db6b23c3b0553cf42f559156fd08e64567d17c4147c864efd4d3a5e22fb6602d613a055f7f14faad22744dbc3df89d59', whirlpool => '31079767aa2dd9b8ab01caadd954a88aaaf6001941c38d17ba43c0ef80a074c3eedf35b73c3941929dea281805c6c5ffc0a619abef4c6a3365d6cb31412d0e0c', }; my %fps = ( '' => { md2 => '8350e5a3e24c153df2275c9f80692773', md4 => '31d6cfe0d16ae931b73c59d7e0c089c0', md5 => 'd41d8cd98f00b204e9800998ecf8427e', ripemd160 => '9c1185a5c5e9fc54612808977ee8f548b2258d31', sha1 => 'da39a3ee5e6b4b0d3255bfef95601890afd80709', sha256 => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha512 => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', }, 'a' => { md2 => '32ec01ec4a6dac72c0ab96fb34c0b5d1', md4 => 'bde52cb31de33e46245e05fbdbd6fb24', md5 => '0cc175b9c0f1b6a831c399e269772661', ripemd160 => '0bdc9d2d256b3ee9daae347be6f4dc835a467ffe', sha1=>'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', sha256=>'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', sha512=>'1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75', }, '38' => { md2 => '4b85c826321a5ce87db408c908d0709e', md4 => 'ae9c7ebfb68ea795483d270f5934b71d', md5 => 'a5771bce93e200c36f7cd9dfd0e5deaa', ripemd160 => '6b2d075b1cd34cd1c3e43a995f110c55649dad0e', sha1=>'5b384ce32d8cdef02bc3a139d4cac0a22bb029e8', sha256=>'aea92132c4cbeb263e6ac2bf6c183b5d81737f179f21efdc5863739672f0f470', sha512=>'caae34a5e81031268bcdaf6f1d8c04d37b7f2c349afb705b575966f63e2ebf0fd910c3b05160ba087ab7af35d40b7c719c53cd8b947c96111f64105fd45cc1b2', }, 'abc' => { md2 => 'da853b0d3f88d99b30283a69e6ded6bb', md4 => 'a448017aaf21d8525fc10ae87aa6729d', md5 => '900150983cd24fb0d6963f7d28e17f72', ripemd160 => '8eb208f7e05d987a9b044a8e98c6b087f15a0bfc', sha1=>'a9993e364706816aba3e25717850c26c9cd0d89d', sha256=>'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha512=>'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', }, 'message digest' => { md2 => 'ab4f496bfb2a530b219ff33031fe06b0', md4 => 'd9130a8164549fe818874806e1c7014b', md5 => 'f96b697d7cb7938d525a2f31aaf161d0', ripemd160 => '5d0689ef49d2fae572b881b123a85ffa21595f36', sha1=>'c12252ceda8be8994d5fa0290a47231c1d16aae3', sha256=>'f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650', sha512=>'107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c', }, 'abcdefghijklmnopqrstuvwxyz' => { md2 => '4e8ddff3650292ab5a4108c3aa47940b', md4 => 'd79e1c308aa5bbcdeea8ed63df412da9', md5 => 'c3fcd3d76192e4007dfb496cca67e13b', ripemd160 => 'f71c27109c692c1b56bbdceb5b9d2865b3708dbc', sha1=>'32d10c7b8cf96570ca04ce37f2a19d84240d3a89', sha256=>'71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73', sha512=>'4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1', }, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' => { md2 => 'da33def2a42df13975352846c30338cd', md4 => '043f8582f241db351ce627e153e7f0e4', md5 => 'd174ab98d277d9f5a5611c2c9f419d9f', ripemd160 => 'b0e20b6e3116640286ed3a87a5713079b21f5189', sha1=>'761c457bf73b14d27e9e9265c46f4b4dda11f940', sha256=>'db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0', sha512=>'1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894', }, '12345678901234567890123456789012345678901234567890123456789012345678901234567890' => { md2 => 'd5976f79d83d3a0dc9806c3c66f3efd8', md4 => 'e33b4ddc9c38f2199c3e7b164fcc0536', md5 => '57edf4a22be3c955ac49da2e2107b67a', ripemd160 => '9b752e45573d4b39f4dbd3323cab82bf63326bfb', sha1=>'50abf5706a150990a08b2c5ea40fa0e585554732', sha256=>'f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e', sha512=>'72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843', }, ); SKIP: { skip "MD5 not available", 3 unless exists &Net::SSLeay::MD5; is(Net::SSLeay::EVP_MD_type(Net::SSLeay::EVP_get_digestbyname("MD5")), 4, 'EVP_MD_type md5'); is(Net::SSLeay::EVP_MD_size(Net::SSLeay::EVP_get_digestbyname("MD5")), 16, 'EVP_MD_size md5'); SKIP: { skip "pre-0.9.7", 1 unless Net::SSLeay::SSLeay >= 0x0090700f; my $md = Net::SSLeay::EVP_get_digestbyname("md5"); my $ctx = Net::SSLeay::EVP_MD_CTX_create(); skip "MD5 not available", 1 unless Net::SSLeay::EVP_DigestInit($ctx, $md); my $md2 = Net::SSLeay::EVP_MD_CTX_md($ctx); is(Net::SSLeay::EVP_MD_size($md2), 16, 'EVP_MD_size via EVP_MD_CTX_md md5'); } } SKIP: { skip "Net::SSLeay::EVP_sha512 not available", 1 unless exists &Net::SSLeay::EVP_sha512; is(Net::SSLeay::EVP_MD_size(Net::SSLeay::EVP_sha512()), 64, 'EVP_MD_size sha512'); } SKIP: { skip "Net::SSLeay::EVP_sha256 not available", 1 unless exists &Net::SSLeay::EVP_sha256; is(Net::SSLeay::EVP_MD_size(Net::SSLeay::EVP_sha256()), 32, 'EVP_MD_size sha256'); } SKIP: { skip "Net::SSLeay::EVP_sha1 not available", 1 unless exists &Net::SSLeay::EVP_sha1; is(Net::SSLeay::EVP_MD_size(Net::SSLeay::EVP_sha1()), 20, 'EVP_MD_size sha1'); } digest_file($file, $file_digests, \%all_digests); digest_strings(\%fps, \%all_digests); Net-SSLeay-1.92/t/local/45_exporter.t0000644000175000001440000001171214124712004015732 0ustar csnusers# Various TLS exporter-related tests use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl is_protocol_usable new_ctx tcp_socket ); use Storable; if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } elsif (!defined &Net::SSLeay::export_keying_material) { plan skip_all => "No export_keying_material()"; } else { plan tests => 36; } initialise_libssl(); my @rounds = qw( TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 ); my %usable = map { $_ => is_protocol_usable($_) } @rounds; my $pid; alarm(30); END { kill 9,$pid if $pid } my (%server_stats, %client_stats); my ($server_ctx, $client_ctx, $server_ssl, $client_ssl); my $server = tcp_socket(); sub server { # SSL server - just handle connections, write, wait for read and repeat my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { my ($ctx, $ssl, $ret, $cl); foreach my $round (@rounds) { next unless $usable{$round}; $cl = $server->accept(); $ctx = new_ctx( $round, $round ); Net::SSLeay::CTX_set_security_level($ctx, 0) if Net::SSLeay::SSLeay() >= 0x30000000 && ($round eq 'TLSv1' || $round eq 'TLSv1.1'); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); Net::SSLeay::write($ssl, $round); my $msg = Net::SSLeay::read($ssl); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("server close: $!"); } $server->close() || die("server listen socket close: $!"); exit(0); } } # SSL client - connect to server, read, test and repeat sub client { for my $round (@rounds) { if ($usable{$round}) { my $cl = $server->connect(); my $ctx = new_ctx( $round, $round ); Net::SSLeay::CTX_set_security_level($ctx, 0) if Net::SSLeay::SSLeay() >= 0x30000000 && ($round eq 'TLSv1' || $round eq 'TLSv1.1'); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd( $ssl, $cl ); my $ret = Net::SSLeay::connect($ssl); if ($ret <= 0) { diag("Protocol $round, connect() returns $ret, Error: ".Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error())); } my $msg = Net::SSLeay::read($ssl); test_export($ssl); Net::SSLeay::write( $ssl, $msg ); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); } else { SKIP: { skip( "$round not available in this libssl", 9 ); } } } $server->close() || die("client listen socket close: $!"); return 1; } sub test_export { my ($ssl) = @_; my ($bytes1_0, $bytes1_1, $bytes1_2, $bytes1_3, $bytes2_0, $bytes2_2_64); my $tls_version = Net::SSLeay::get_version($ssl); $bytes1_0 = Net::SSLeay::export_keying_material($ssl, 64, 'label 1'); $bytes1_1 = Net::SSLeay::export_keying_material($ssl, 64, 'label 1', undef); $bytes1_2 = Net::SSLeay::export_keying_material($ssl, 64, 'label 1', ''); $bytes1_3 = Net::SSLeay::export_keying_material($ssl, 64, 'label 1', 'context'); $bytes2_0 = Net::SSLeay::export_keying_material($ssl, 128, 'label 1', ''); $bytes2_2_64 = substr($bytes2_0, 0, 64); is(length($bytes1_0), 64, "$tls_version: Got enough for bytes1_0"); is(length($bytes1_1), 64, "$tls_version: Got enough for bytes1_1"); is(length($bytes1_2), 64, "$tls_version: Got enough for bytes1_2"); is(length($bytes1_3), 64, "$tls_version: Got enough for bytes1_3"); is(length($bytes2_0), 128, "$tls_version: Got enough for bytes2_0"); $bytes1_0 = unpack('H*', $bytes1_0); $bytes1_1 = unpack('H*', $bytes1_1); $bytes1_2 = unpack('H*', $bytes1_2); $bytes1_3 = unpack('H*', $bytes1_3); $bytes2_0 = unpack('H*', $bytes2_0); $bytes2_2_64 = unpack('H*', $bytes2_2_64); # Last argument should default to undef is($bytes1_0, $bytes1_1, "$tls_version: context default param is undef"); # Empty and undefined context are the same for TLSv1.3. # Different length export changes the whole values for TLSv1.3. if ($tls_version eq 'TLSv1.3') { is($bytes1_0, $bytes1_2, "$tls_version: empty and undefined context yields equal values"); isnt($bytes2_2_64, $bytes1_2, "$tls_version: export length does matter"); } else { isnt($bytes1_0, $bytes1_2, "$tls_version: empty and undefined context yields different values"); is($bytes2_2_64, $bytes1_2, "$tls_version: export length does not matter"); } isnt($bytes1_3, $bytes1_0, "$tls_version: different context"); return; } # For SSL_export_keying_material_early available with TLSv1.3 sub test_export_early { return; } server(); client(); waitpid $pid, 0; exit(0); Net-SSLeay-1.92/t/local/04_basic.t0000644000175000001440000000715214167101614015147 0ustar csnusers# Test version and initialisation functions use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(lives_ok); plan tests => 29; lives_ok( sub { Net::SSLeay::randomize() }, 'seed pseudorandom number generator' ); lives_ok( sub { Net::SSLeay::ERR_load_crypto_strings() }, 'load libcrypto error strings' ); lives_ok( sub { Net::SSLeay::load_error_strings() }, 'load libssl error strings' ); lives_ok( sub { Net::SSLeay::library_init() }, 'register default TLS ciphers and digest functions' ); lives_ok( sub { Net::SSLeay::OpenSSL_add_all_digests() }, 'register all digest functions' ); #version numbers: 0x00903100 ~ 0.9.3, 0x0090600f ~ 0.6.9 ok( Net::SSLeay::SSLeay() >= 0x00903100, 'SSLeay (version min 0.9.3)' ); isnt( Net::SSLeay::SSLeay_version(), '', 'SSLeay (version string)' ); is( Net::SSLeay::SSLeay_version(), Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_VERSION()), 'SSLeay_version optional argument' ); is(Net::SSLeay::hello(), 1, 'hello world'); if (exists &Net::SSLeay::OpenSSL_version) { is(Net::SSLeay::SSLeay(), Net::SSLeay::OpenSSL_version_num(), 'OpenSSL_version_num'); is(Net::SSLeay::OpenSSL_version(), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_VERSION()), 'OpenSSL_version optional argument'); is(Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_VERSION()), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_VERSION()), 'OpenSSL_version(OPENSSL_VERSION)'); is(Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_CFLAGS()), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_CFLAGS()), 'OpenSSL_version(OPENSSL_CFLAGS)'); is(Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_BUILT_ON()), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_BUILT_ON()), 'OpenSSL_version(OPENSSL_BUILT_ON)'); is(Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_PLATFORM()), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_PLATFORM()), 'OpenSSL_version(OPENSSL_PLATFORM)'); is(Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_DIR()), Net::SSLeay::OpenSSL_version(Net::SSLeay::OPENSSL_DIR()), 'OpenSSL_version(OPENSSL_DIR)'); } else { SKIP: { skip('Only on OpenSSL 1.1.0 or later', 7); } } if (defined &Net::SSLeay::OPENSSL_version_major) { my $major = Net::SSLeay::OPENSSL_version_major(); my $minor = Net::SSLeay::OPENSSL_version_minor(); my $patch = Net::SSLeay::OPENSSL_version_patch(); # Separate test for being defined because cmp_ok won't fail this: # cmp_ok(undef, '>=', 0) isnt($major, undef, 'major is defined'); isnt($minor, undef, 'minor is defined'); isnt($patch, undef, 'patch is defined'); cmp_ok($major, '>=', 3, 'OPENSSL_version_major'); cmp_ok($minor, '>=', 0, 'OPENSSL_version_minor'); cmp_ok($patch, '>=', 0, 'OPENSSL_version_patch'); is(Net::SSLeay::OPENSSL_VERSION_MAJOR(), $major, 'OPENSSL_VERSION_MAJOR and OPENSSL_version_major are equal'); is(Net::SSLeay::OPENSSL_VERSION_MINOR(), $minor, 'OPENSSL_VERSION_MINOR and OPENSSL_version_minor are equal'); is(Net::SSLeay::OPENSSL_VERSION_PATCH(), $patch, 'OPENSSL_VERSION_PATCH and OPENSSL_version_patch are equal'); isnt(defined Net::SSLeay::OPENSSL_version_pre_release(), undef, 'OPENSSL_version_pre_release returns a defined value'); isnt(defined Net::SSLeay::OPENSSL_version_build_metadata(), undef, 'OPENSSL_version_build_metadata returns a defined value'); isnt(Net::SSLeay::OPENSSL_info(Net::SSLeay::OPENSSL_INFO_CONFIG_DIR()), undef, 'OPENSSL_INFO(OPENSSL_INFO_CONFIG_DIR) returns a defined value'); is(Net::SSLeay::OPENSSL_info(-1), undef, 'OPENSSL_INFO(-1) returns an undefined value'); } else { SKIP: { skip('Only on OpenSSL 3.0.0 or later', 13); } } Net-SSLeay-1.92/t/local/07_sslecho.t0000644000175000001440000002736314140310470015530 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl new_ctx tcp_socket ); BEGIN { if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 122; } } initialise_libssl(); $SIG{'PIPE'} = 'IGNORE'; my $server = tcp_socket(); my $pid; my $msg = 'ssleay-test'; my $ca_cert_pem = data_file_path('intermediate-ca.certchain.pem'); my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); my $cert_name = '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=simple-cert.net-ssleay.example'; my $cert_issuer = '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=Intermediate CA'; my $cert_sha1_fp = '9C:2E:90:B9:A7:84:7A:3A:2B:BE:FD:A5:D1:46:EA:31:75:E9:03:26'; $ENV{RND_SEED} = '1234567890123456789012345678901234567890'; { my ( $ctx, $ctx_protocol ) = new_ctx(); ok($ctx, 'new CTX'); ok(Net::SSLeay::CTX_set_cipher_list($ctx, 'ALL'), 'CTX_set_cipher_list'); my ($dummy, $errs) = Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); ok($errs eq '', "set_cert_and_key: $errs"); SKIP: { skip 'Disabling session tickets requires OpenSSL >= 1.1.1', 1 unless defined (&Net::SSLeay::CTX_set_num_tickets); # TLS 1.3 server sends session tickets after a handhake as part of # the SSL_accept(). If a client finishes all its job including closing # TCP connection before a server sends the tickets, SSL_accept() fails # with SSL_ERROR_SYSCALL and EPIPE errno and the server receives # SIGPIPE signal. ok(Net::SSLeay::CTX_set_num_tickets($ctx, 0), 'Session tickets disabled'); } # The client side of this test uses Net::SSLeay::sslcat(), which by default # will attempt to auto-negotiate the SSL/TLS protocol version to use when it # connects to the server. This conflicts with the server-side SSL_CTX # created by Test::Net::SSLeay::new_ctx(), which only accepts the most recent # SSL/TLS protocol version supported by libssl; atempts to negotiate the # version will fail. We need to force sslcat() to communicate with the server # using the same protocol version that was chosen for the server SSL_CTX, # which is done by setting a specific value for $Net::SSLeay::ssl_version my %ssl_versions = ( 'SSLv2' => 2, 'SSLv3' => 3, 'TLSv1' => 10, 'TLSv1.1' => 11, 'TLSv1.2' => 12, 'TLSv1.3' => 13, ); $Net::SSLeay::ssl_version = $ssl_versions{$ctx_protocol}; $pid = fork(); BAIL_OUT("failed to fork: $!") unless defined $pid; if ($pid == 0) { for (1 .. 7) { my $ns = $server->accept(); my $ssl = Net::SSLeay::new($ctx); ok($ssl, 'new'); is(Net::SSLeay::in_before($ssl), 1, 'in_before is 1'); is(Net::SSLeay::in_init($ssl), 1, 'in_init is 1'); ok(Net::SSLeay::set_fd($ssl, fileno($ns)), 'set_fd using fileno'); ok(Net::SSLeay::accept($ssl), 'accept'); is(Net::SSLeay::is_init_finished($ssl), 1, 'is_init_finished is 1'); ok(Net::SSLeay::get_cipher($ssl), 'get_cipher'); like(Net::SSLeay::get_shared_ciphers($ssl), qr/(AES|RSA|SHA|CBC|DES)/, 'get_shared_ciphers'); my $got = Net::SSLeay::ssl_read_all($ssl); is($got, $msg, 'ssl_read_all') if $_ < 7; is(Net::SSLeay::get_shutdown($ssl), Net::SSLeay::RECEIVED_SHUTDOWN(), 'shutdown from peer'); ok(Net::SSLeay::ssl_write_all($ssl, uc($got)), 'ssl_write_all'); # With 1.1.1e and $Net::SSLeay::trace=3 you'll see these without shutdown: # SSL_read 9740: 1 - error:14095126:SSL routines:ssl3_read_n:unexpected eof while reading my $sret = Net::SSLeay::shutdown($ssl); if ($sret < 0) { # ERROR_SYSCALL seen on < 1.1.1, if so also print errno string my $err = Net::SSLeay::get_error($ssl, $sret); my $extra = ($err == Net::SSLeay::ERROR_SYSCALL()) ? "$err, $!" : "$err"; ok($err == Net::SSLeay::ERROR_ZERO_RETURN() || $err == Net::SSLeay::ERROR_SYSCALL(), "server shutdown not success, but acceptable: $extra"); } else { pass('server shutdown success'); } Net::SSLeay::free($ssl); close($ns) || die("server close: $!"); } Net::SSLeay::CTX_free($ctx); $server->close() || die("server listen socket close: $!"); exit; } } my @results; { my ($got) = Net::SSLeay::sslcat($server->get_addr(), $server->get_port(), $msg); push @results, [ $got eq uc($msg), 'send and received correctly' ]; } { my $s = $server->connect(); push @results, [ my $ctx = new_ctx(), 'new CTX' ]; push @results, [ my $ssl = Net::SSLeay::new($ctx), 'new' ]; push @results, [ Net::SSLeay::set_fd($ssl, $s), 'set_fd using glob ref' ]; push @results, [ Net::SSLeay::connect($ssl), 'connect' ]; push @results, [ Net::SSLeay::get_cipher($ssl), 'get_cipher' ]; push @results, [ Net::SSLeay::ssl_write_all($ssl, $msg), 'write' ]; push @results, [ Net::SSLeay::shutdown($ssl) >= 0, 'client side ssl shutdown' ]; shutdown($s, 1); my $got = Net::SSLeay::ssl_read_all($ssl); push @results, [ $got eq uc($msg), 'read' ]; Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); shutdown($s, 2); close($s) || die("client close: $!"); } { my $verify_cb_1_called = 0; my $verify_cb_2_called = 0; my $verify_cb_3_called = 0; { my $ctx = new_ctx(); push @results, [ Net::SSLeay::CTX_load_verify_locations($ctx, $ca_cert_pem, ''), 'CTX_load_verify_locations' ]; Net::SSLeay::CTX_set_verify($ctx, &Net::SSLeay::VERIFY_PEER, \&verify); my $ctx2 = new_ctx(); Net::SSLeay::CTX_set_cert_verify_callback($ctx2, \&verify4, 1); { my $s = $server->connect(); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($s)); Net::SSLeay::connect($ssl); Net::SSLeay::ssl_write_all($ssl, $msg); push @results, [Net::SSLeay::shutdown($ssl) >= 0, 'verify: client side ssl shutdown' ]; shutdown $s, 2; close $s; Net::SSLeay::free($ssl); push @results, [ $verify_cb_1_called == 1, 'verify cb 1 called once' ]; push @results, [ $verify_cb_2_called == 0, 'verify cb 2 wasn\'t called yet' ]; push @results, [ $verify_cb_3_called == 0, 'verify cb 3 wasn\'t called yet' ]; } { my $s1 = $server->connect(); my $s2 = $server->connect(); my $s3 = $server->connect(); my $ssl1 = Net::SSLeay::new($ctx); Net::SSLeay::set_verify($ssl1, &Net::SSLeay::VERIFY_PEER, \&verify2); Net::SSLeay::set_fd($ssl1, $s1); my $ssl2 = Net::SSLeay::new($ctx); Net::SSLeay::set_verify($ssl2, &Net::SSLeay::VERIFY_PEER, \&verify3); Net::SSLeay::set_fd($ssl2, $s2); my $ssl3 = Net::SSLeay::new($ctx2); Net::SSLeay::set_fd($ssl3, $s3); Net::SSLeay::connect($ssl1); Net::SSLeay::ssl_write_all($ssl1, $msg); push @results, [Net::SSLeay::shutdown($ssl1) >= 0, 'client side ssl1 shutdown' ]; shutdown $s1, 2; Net::SSLeay::connect($ssl2); Net::SSLeay::ssl_write_all($ssl2, $msg); push @results, [Net::SSLeay::shutdown($ssl2) >= 0, 'client side ssl2 shutdown' ]; shutdown $s2, 2; Net::SSLeay::connect($ssl3); Net::SSLeay::ssl_write_all($ssl3, $msg); push @results, [Net::SSLeay::shutdown($ssl3) >= 0, 'client side ssl3 shutdown' ]; shutdown $s3, 2; close($s1) || die("client close s1: $!"); close($s2) || die("client close s2: $!"); close($s3) || die("client close s3: $!"); Net::SSLeay::free($ssl1); Net::SSLeay::free($ssl2); Net::SSLeay::free($ssl3); push @results, [ $verify_cb_1_called == 1, 'verify cb 1 wasn\'t called again' ]; push @results, [ $verify_cb_2_called == 1, 'verify cb 2 called once' ]; push @results, [ $verify_cb_3_called == 1, 'verify cb 3 wasn\'t called yet' ]; } Net::SSLeay::CTX_free($ctx); Net::SSLeay::CTX_free($ctx2); } sub verify { my ($ok, $x509_store_ctx) = @_; # Skip intermediate certs but propagate possible not ok condition my $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($x509_store_ctx); return $ok unless $depth == 0; $verify_cb_1_called++; my $cert = Net::SSLeay::X509_STORE_CTX_get_current_cert($x509_store_ctx); push @results, [ $cert, 'verify cb cert' ]; my $issuer_name = Net::SSLeay::X509_get_issuer_name( $cert ); my $issuer = Net::SSLeay::X509_NAME_oneline( $issuer_name ); my $subject_name = Net::SSLeay::X509_get_subject_name( $cert ); my $subject = Net::SSLeay::X509_NAME_oneline( $subject_name ); my $cn = Net::SSLeay::X509_NAME_get_text_by_NID($subject_name, &Net::SSLeay::NID_commonName); my $fingerprint = Net::SSLeay::X509_get_fingerprint($cert, 'SHA-1'); push @results, [ $ok == 1, 'verify is ok' ]; push @results, [ $issuer eq $cert_issuer, 'cert issuer' ]; push @results, [ $subject eq $cert_name, 'cert subject' ]; push @results, [ substr($cn, length($cn) - 1, 1) ne "\0", 'tailing 0 character is not returned from get_text_by_NID' ]; push @results, [ $fingerprint eq $cert_sha1_fp, 'SHA-1 fingerprint' ]; return 1; } sub verify2 { my ($ok, $x509_store_ctx) = @_; # Skip intermediate certs but propagate possible not ok condition my $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($x509_store_ctx); return $ok unless $depth == 0; $verify_cb_2_called++; push @results, [ $ok == 1, 'verify 2 is ok' ]; return $ok; } sub verify3 { my ($ok, $x509_store_ctx) = @_; # Skip intermediate certs but propagate possible not ok condition my $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($x509_store_ctx); return $ok unless $depth == 0; $verify_cb_3_called++; push @results, [ $ok == 1, 'verify 3 is ok' ]; return $ok; } sub verify4 { my ($cert_store, $userdata) = @_; push @results, [$userdata == 1, 'CTX_set_cert_verify_callback']; return $userdata; } } { my $s = $server->connect(); my $ctx = new_ctx(); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($s)); Net::SSLeay::connect($ssl); my $cert = Net::SSLeay::get_peer_certificate($ssl); my $subject = Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($cert) ); my $issuer = Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($cert) ); push @results, [ $subject eq $cert_name, 'get_peer_certificate subject' ]; push @results, [ $issuer eq $cert_issuer, 'get_peer_certificate issuer' ]; my $data = 'a' x 1024 ** 2; my $written = Net::SSLeay::ssl_write_all($ssl, \$data); push @results, [ $written == length $data, 'ssl_write_all' ]; push @results, [Net::SSLeay::shutdown($ssl) >= 0, 'client side aaa write ssl shutdown' ]; shutdown $s, 1; my $got = Net::SSLeay::ssl_read_all($ssl); push @results, [ $got eq uc($data), 'ssl_read_all' ]; Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close($s) || die("client close: $!"); } $server->close() || die("client listen socket close: $!"); waitpid $pid, 0; push @results, [ $? == 0, 'server exited with 0' ]; END { Test::More->builder->current_test(87); for my $t (@results) { ok( $t->[0], $t->[1] ); } } Net-SSLeay-1.92/t/local/62_threads-ctx_new-deadlock.t0000644000175000001440000000263313755162614020745 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_thread initialise_libssl ); use FindBin; if (not can_thread()) { plan skip_all => "Threads not supported on this system"; } elsif ($^O eq 'cygwin') { #XXX-TODO perhaps perl+ithreads related issue (needs more investigation) plan skip_all => "this test sometimes crashes on Cygwin"; } else { plan tests => 1; } require threads; initialise_libssl(); my $start_time = time; #exit the whole program if it runs too long threads->new( sub { sleep 20; warn "FATAL: TIMEOUT!"; exit } )->detach; #print STDERR "Gonna start multi-threading part\n"; threads->new(\&do_check) for (1..20); #print STDERR "Waiting for all threads to finish\n"; do_sleep(50) while (threads->list()); pass("successfully finished, duration=".(time-$start_time)); exit(0); sub do_sleep { my $miliseconds = shift; select(undef, undef, undef, $miliseconds/1000); } sub do_check { #printf STDERR ("[thread:%04d] do_check started\n", threads->tid); my $c = Net::SSLeay::CTX_new() or warn "CTX_new failed" and exit; my $d = Net::SSLeay::new($c) or warn "SSL_new" and exit; my $e = Net::SSLeay::SESSION_new() or warn "SSL_SESSION_new failed" and exit; Net::SSLeay::set_session($d,$e); Net::SSLeay::SESSION_free($e); Net::SSLeay::free($d); Net::SSLeay::CTX_free($c); #printf STDERR ("[thread:%04d] do_check finished\n", threads->tid); threads->detach(); } Net-SSLeay-1.92/t/local/10_rand.t0000644000175000001440000001255714163136013015011 0ustar csnusers# RAND-related tests use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl is_libressl ); plan tests => 53; initialise_libssl(); is(Net::SSLeay::RAND_status(), 1, 'RAND_status'); is(Net::SSLeay::RAND_poll(), 1, 'RAND_poll'); # RAND_file_name has significant differences between the two libraries is_libressl() ? test_rand_file_name_libressl() : test_rand_file_name_openssl(); # RAND_load_file my $binary_file = data_file_path('binary-test.file'); my $binary_file_size = -s $binary_file; cmp_ok($binary_file_size, '>=', 1000, "Have binary file with good size: $binary_file $binary_file_size"); is(Net::SSLeay::RAND_load_file($binary_file, $binary_file_size), $binary_file_size, 'RAND_load with specific size'); if (Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER")) { # RAND_load_file does nothing on LibreSSL but should return something sane cmp_ok(Net::SSLeay::RAND_load_file($binary_file, -1), '>', 0, 'RAND_load with -1 is positive with LibreSSL'); } else { is(Net::SSLeay::RAND_load_file($binary_file, -1), $binary_file_size, 'RAND_load with -1 returns file size'); } test_rand_bytes(); exit(0); # With LibreSSL RAND_file_name is expected to always succeed as long # as the buffer size is large enough. Their manual states that it's # implemented for API compatibility only and its use is discouraged. sub test_rand_file_name_libressl { my $file_name = Net::SSLeay::RAND_file_name(300); isnt($file_name, undef, 'RAND_file_name returns defined value'); isnt($file_name, q{}, "RAND_file_name returns non-empty string: $file_name"); $file_name = Net::SSLeay::RAND_file_name(2); is($file_name, undef, "RAND_file_name return value is undef with too short buffer"); return; } # With OpenSSL there are a number of options that affect # RAND_file_name return value. Note: we override environment variables # temporarily because some environments do not have HOME set or may # already have RANDFILE set. We do not try to trigger a failure which # happens if there's no HOME nor RANDFILE in order to keep the test # from becoming overly complicated. sub test_rand_file_name_openssl { my $file_name; local %ENV = %ENV; delete $ENV{RANDFILE}; # NOTE: If there are test failures, are you using some type of # setuid environment? If so, this may affect usability of # environment variables. $ENV{HOME} = '/nosuchdir-1/home'; $file_name = Net::SSLeay::RAND_file_name(300); if (Net::SSLeay::SSLeay() >= 0x10100006 && Net::SSLeay::SSLeay() <= 0x1010000f) { # This was broken starting with 1.0.0-pre6 and fixed after 1.0.0 is($file_name, q{}, "RAND_file_name return value is empty and doesn't include '.rnd'"); } else { like($file_name, qr/\.rnd/s, "RAND_file_name return value '$file_name' includes '.rnd'"); } my $randfile = '/nosuchdir-2/randfile'; $ENV{RANDFILE} = $randfile; $file_name = Net::SSLeay::RAND_file_name(300); if (Net::SSLeay::SSLeay() < 0x1010001f) { # On Windows, and possibly other non-Unix systems, 1.0.2 # series and earlier did not honour RANDFILE. 1.1.0a is an # educated guess when it starts working with all platforms. isnt($file_name, q{}, "RAND_file_name returns non-empty string when RANDFILE is set: $file_name"); } else { is($file_name, $randfile, "RAND_file_name return value '$file_name' is RANDFILE environment value"); } # RANDFILE is longer than 2 octets. OpenSSL 1.1.0a and later # return undef with short buffer $file_name = Net::SSLeay::RAND_file_name(2); if (Net::SSLeay::SSLeay() < 0x1010001f) { is($file_name, q{}, "RAND_file_name return value is empty string with too short buffer"); } else { is($file_name, undef, "RAND_file_name return value is undef with too short buffer"); } return; } sub test_rand_bytes { my ($ret, $rand_bytes, $rand_length, $rand_expected_length); my @rand_lengths = (0, 1, 1024, 65536, 1024**2); foreach $rand_expected_length (@rand_lengths) { $rand_length = $rand_expected_length; $ret = Net::SSLeay::RAND_bytes($rand_bytes, $rand_length); test_rand_bytes_results('RAND_bytes', $ret, $rand_bytes, $rand_length, $rand_expected_length); } foreach $rand_expected_length (@rand_lengths) { $rand_length = $rand_expected_length; $ret = Net::SSLeay::RAND_pseudo_bytes($rand_bytes, $rand_length); test_rand_bytes_results('RAND_pseudo_bytes', $ret, $rand_bytes, $rand_length, $rand_expected_length); } if (defined &Net::SSLeay::RAND_priv_bytes) { foreach $rand_expected_length (@rand_lengths) { $rand_length = $rand_expected_length; $ret = Net::SSLeay::RAND_priv_bytes($rand_bytes, $rand_length); test_rand_bytes_results('RAND_priv_bytes', $ret, $rand_bytes, $rand_length, $rand_expected_length); } } else { SKIP : { # Multiplier is the test count in test_rand_bytes_results skip("Do not have Net::SSLeay::RAND_priv_bytes", ((scalar @rand_lengths) * 3)); }; } } sub test_rand_bytes_results { my ($func, $ret, $rand_bytes, $rand_length, $rand_expected_length) = @_; # RAND_bytes functions do not update their rand_length argument, but check for this is($ret, 1, "$func: $rand_expected_length return value ok"); is(length($rand_bytes), $rand_length, "$func: length of rand_bytes and rand_length match"); is(length($rand_bytes), $rand_expected_length, "$func: length of rand_bytes is expected length $rand_length"); } Net-SSLeay-1.92/t/local/20_functions.t0000644000175000001440000000205214135367260016074 0ustar csnusers# Checks whether (a subset of) the functions that should be exported by # Net::SSLeay can be autoloaded. This script does not check whether constants # can be autoloaded - see t/local/21_constants.t for that. use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(dies_like); my @functions = qw( die_if_ssl_error die_now do_https dump_peer_certificate get_http get_http4 get_https get_https3 get_https4 get_httpx get_httpx4 make_form make_headers post_http post_http4 post_https post_https3 post_https4 post_httpx post_httpx4 print_errs set_cert_and_key set_server_cert_and_key sslcat tcpcat tcpxcat ); plan tests => @functions + 1; for (@functions) { dies_like( sub { "Net::SSLeay::$_"->(); die "ok\n" }, qr/^(?!Can't locate .*\.al in \@INC)/, "function is autoloadable: $_" ); } dies_like( sub { Net::SSLeay::doesnt_exist() }, qr/^Can't locate .*\.al in \@INC/, 'nonexistent function is not autoloadable' ); Net-SSLeay-1.92/t/local/31_rsa_generate_key.t0000644000175000001440000000327014135367260017400 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( dies_like initialise_libssl lives_ok ); plan tests => 14; initialise_libssl(); lives_ok(sub { Net::SSLeay::RSA_generate_key(2048, 0x10001); }, 'RSA_generate_key with valid callback'); dies_like(sub { Net::SSLeay::RSA_generate_key(2048, 0x10001, 1); }, qr/Undefined subroutine &main::1 called/, 'RSA_generate_key with invalid callback'); { my $called = 0; lives_ok(sub { Net::SSLeay::RSA_generate_key(2048, 0x10001, \&cb); }, 'RSA_generate_key with valid callback'); cmp_ok( $called, '>', 0, 'callback has been called' ); sub cb { my ($i, $n, $d) = @_; if ($called == 0) { is( wantarray(), undef, 'RSA_generate_key callback is executed in void context' ); is( $d, undef, 'userdata will be undef if no userdata was given' ); ok( defined $i, 'first argument is defined' ); ok( defined $n, 'second argument is defined' ); } $called++; } } { my $called = 0; my $userdata = 'foo'; lives_ok(sub { Net::SSLeay::RSA_generate_key(2048, 0x10001, \&cb_data, $userdata); }, 'RSA_generate_key with valid callback and userdata'); cmp_ok( $called, '>', 0, 'callback has been called' ); sub cb_data { my ($i, $n, $d) = @_; if ($called == 0) { is( wantarray(), undef, 'RSA_generate_key callback is executed in void context' ); ok( defined $i, 'first argument is defined' ); ok( defined $n, 'second argument is defined' ); is( $d, $userdata, 'third argument is the userdata we passed in' ); } $called++; } } Net-SSLeay-1.92/t/local/kwalitee.t0000644000175000001440000000044313732725160015371 0ustar csnusers# Ensure module distribution passes Kwalitee checks use lib 'inc'; use Test::Net::SSLeay; if (!$ENV{RELEASE_TESTING}) { plan skip_all => 'These tests are for only for release candidate testing. Enable with RELEASE_TESTING=1'; } require Test::Kwalitee; Test::Kwalitee::kwalitee_ok(); Net-SSLeay-1.92/t/local/08_pipe.t0000644000175000001440000000466313755162614015044 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_really_fork data_file_path initialise_libssl ); use IO::Handle; use Symbol qw( gensym ); if (not can_really_fork()) { # Perl's pseudofork implementation doesn't correctly dup file handles # connected to pipes, so this test requires a native fork() system call plan skip_all => "fork() not natively supported on this system"; } else { plan tests => 11; } initialise_libssl(); my $cert = data_file_path('simple-cert.cert.pem'); my $key = data_file_path('simple-cert.key.pem'); my $how_much = 1024 ** 2; my $rs = gensym(); my $ws = gensym(); my $rc = gensym(); my $wc = gensym(); pipe $rs, $wc or die "pipe 1 ($!)"; pipe $rc, $ws or die "pipe 2 ($!)"; for my $h ($rs, $ws, $rc, $wc) { my $old_select = select $h; $| = 1; select $old_select; } my $pid = fork(); die unless defined $pid; if ($pid == 0) { my $ctx = Net::SSLeay::CTX_new(); Net::SSLeay::set_server_cert_and_key($ctx, $cert, $key); my $ssl = Net::SSLeay::new($ctx); ok( Net::SSLeay::set_rfd($ssl, fileno($rs)), 'set_rfd using fileno' ); ok( Net::SSLeay::set_wfd($ssl, fileno($ws)), 'set_wfd using fileno' ); ok( Net::SSLeay::accept($ssl), 'accept' ); ok( my $got = Net::SSLeay::ssl_read_all($ssl, $how_much), 'ssl_read_all' ); is( Net::SSLeay::ssl_write_all($ssl, \$got), length $got, 'ssl_write_all' ); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close $ws; close $rs; exit; } my @results; { my $ctx = Net::SSLeay::CTX_new(); my $ssl = Net::SSLeay::new($ctx); my $rc_handle = IO::Handle->new_from_fd( fileno($rc), 'r' ); my $wc_handle = IO::Handle->new_from_fd( fileno($wc), 'w' ); push @results, [ Net::SSLeay::set_rfd($ssl, $rc_handle), 'set_rfd using an io handle' ]; push @results, [ Net::SSLeay::set_wfd($ssl, $wc_handle), 'set_wfd using an io handle' ]; push @results, [ Net::SSLeay::connect($ssl), 'connect' ]; my $data = 'B' x $how_much; push @results, [ Net::SSLeay::ssl_write_all($ssl, \$data) == length $data, 'ssl_write_all' ]; my $got = Net::SSLeay::ssl_read_all($ssl, $how_much); push @results, [ $got eq $data, 'ssl_read_all' ]; Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close $wc; close $rc; } waitpid $pid, 0; push @results, [ $? == 0, 'server exited with 0' ]; Test::More->builder->current_test(5); for my $t (@results) { ok( $t->[0], $t->[1] ); } Net-SSLeay-1.92/t/local/32_x509_get_cert_info.t0000644000175000001440000005243214124712004017456 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl is_libressl is_openssl ); use lib '.'; my $tests = ( is_openssl() && Net::SSLeay::SSLeay < 0x10100003 ) || is_libressl() ? 723 : 726; plan tests => $tests; initialise_libssl(); # Check some basic X509 features added in 1.54: my $name = Net::SSLeay::X509_NAME_new(); ok ($name, "X509_NAME_new"); my $hash = Net::SSLeay::X509_NAME_hash($name); ok ($hash = 4003674586, "X509_NAME_hash"); # Caution from perl 25 onwards, need use lib '.'; above in order to 'do' these files my $dump = {}; for my $cert ( qw( extended-cert simple-cert strange-cert wildcard-cert ) ) { $dump->{"$cert.cert.pem"} = do( data_file_path("$cert.cert.dump") ); } my %available_digests = map {$_=>1} qw( md5 sha1 ); if (Net::SSLeay::SSLeay >= 0x1000000f) { my $ctx = Net::SSLeay::EVP_MD_CTX_create(); %available_digests = map { $_=>1 } grep { # P_EVP_MD_list_all() does not remove digests disabled in FIPS my $md; $md = Net::SSLeay::EVP_get_digestbyname($_) and Net::SSLeay::EVP_DigestInit($ctx, $md) } @{Net::SSLeay::P_EVP_MD_list_all()}; } for my $f (keys (%$dump)) { my $filename = data_file_path($f); ok(my $bio = Net::SSLeay::BIO_new_file($filename, 'rb'), "BIO_new_file\t$f"); ok(my $x509 = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509\t$f"); ok(Net::SSLeay::X509_get_pubkey($x509), "X509_get_pubkey\t$f"); #only test whether the function works ok(my $subj_name = Net::SSLeay::X509_get_subject_name($x509), "X509_get_subject_name\t$f"); is(my $subj_count = Net::SSLeay::X509_NAME_entry_count($subj_name), $dump->{$f}->{subject}->{count}, "X509_NAME_entry_count\t$f"); #BEWARE: values are not the same across different openssl versions therefore cannot test exact match #is(Net::SSLeay::X509_NAME_oneline($subj_name), $dump->{$f}->{subject}->{oneline}, "X509_NAME_oneline\t$f"); #is(Net::SSLeay::X509_NAME_print_ex($subj_name), $dump->{$f}->{subject}->{print_rfc2253}, "X509_NAME_print_ex\t$f"); like(Net::SSLeay::X509_NAME_oneline($subj_name), qr|/OU=.*?/CN=|, "X509_NAME_oneline\t$f"); like(Net::SSLeay::X509_NAME_print_ex($subj_name), qr|CN=.*?,OU=|, "X509_NAME_print_ex\t$f"); for my $i (0..$subj_count-1) { ok(my $entry = Net::SSLeay::X509_NAME_get_entry($subj_name, $i), "X509_NAME_get_entry\t$f:$i"); ok(my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry), "X509_NAME_ENTRY_get_data\t$f:$i"); ok(my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry), "X509_NAME_ENTRY_get_object\t$f:$i"); is(Net::SSLeay::OBJ_obj2txt($asn1_object,1), $dump->{$f}->{subject}->{entries}->[$i]->{oid}, "OBJ_obj2txt\t$f:$i"); is(Net::SSLeay::P_ASN1_STRING_get($asn1_string), $dump->{$f}->{subject}->{entries}->[$i]->{data}, "P_ASN1_STRING_get.1\t$f:$i"); is(Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), $dump->{$f}->{subject}->{entries}->[$i]->{data_utf8_decoded}, "P_ASN1_STRING_get.2\t$f:$i"); if (defined $dump->{$f}->{entries}->[$i]->{nid}) { is(my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object), $dump->{$f}->{subject}->{entries}->[$i]->{nid}, "OBJ_obj2nid\t$f:$i"); is(Net::SSLeay::OBJ_nid2ln($nid), $dump->{$f}->{subject}->{entries}->[$i]->{ln}, "OBJ_nid2ln\t$f:$i"); is(Net::SSLeay::OBJ_nid2sn($nid), $dump->{$f}->{subject}->{entries}->[$i]->{sn}, "OBJ_nid2sn\t$f:$i"); } } ok(my $issuer_name = Net::SSLeay::X509_get_issuer_name($x509), "X509_get_subject_name\t$f"); is(my $issuer_count = Net::SSLeay::X509_NAME_entry_count($issuer_name), $dump->{$f}->{issuer}->{count}, "X509_NAME_entry_count\t$f"); is(Net::SSLeay::X509_NAME_oneline($issuer_name), $dump->{$f}->{issuer}->{oneline}, "X509_NAME_oneline\t$f"); is(Net::SSLeay::X509_NAME_print_ex($issuer_name), $dump->{$f}->{issuer}->{print_rfc2253}, "X509_NAME_print_ex\t$f"); for my $i (0..$issuer_count-1) { ok(my $entry = Net::SSLeay::X509_NAME_get_entry($issuer_name, $i), "X509_NAME_get_entry\t$f:$i"); ok(my $asn1_string = Net::SSLeay::X509_NAME_ENTRY_get_data($entry), "X509_NAME_ENTRY_get_data\t$f:$i"); ok(my $asn1_object = Net::SSLeay::X509_NAME_ENTRY_get_object($entry), "X509_NAME_ENTRY_get_object\t$f:$i"); is(Net::SSLeay::OBJ_obj2txt($asn1_object,1), $dump->{$f}->{issuer}->{entries}->[$i]->{oid}, "OBJ_obj2txt\t$f:$i"); is(Net::SSLeay::P_ASN1_STRING_get($asn1_string), $dump->{$f}->{issuer}->{entries}->[$i]->{data}, "P_ASN1_STRING_get.1\t$f:$i"); is(Net::SSLeay::P_ASN1_STRING_get($asn1_string, 1), $dump->{$f}->{issuer}->{entries}->[$i]->{data_utf8_decoded}, "P_ASN1_STRING_get.2\t$f:$i"); if (defined $dump->{$f}->{entries}->[$i]->{nid}) { is(my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object), $dump->{$f}->{issuer}->{entries}->[$i]->{nid}, "OBJ_obj2nid\t$f:$i"); is(Net::SSLeay::OBJ_nid2ln($nid), $dump->{$f}->{issuer}->{entries}->[$i]->{ln}, "OBJ_nid2ln\t$f:$i"); is(Net::SSLeay::OBJ_nid2sn($nid), $dump->{$f}->{issuer}->{entries}->[$i]->{sn}, "OBJ_nid2sn\t$f:$i"); } } my @subjectaltnames = Net::SSLeay::X509_get_subjectAltNames($x509); is(scalar(@subjectaltnames), scalar(@{$dump->{$f}->{subject}->{altnames}}), "subjectaltnames size\t$f"); for my $i (0..$#subjectaltnames) { SKIP: { skip('altname types are different on pre-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f || ($i%2)==1; is($subjectaltnames[$i], $dump->{$f}->{subject}->{altnames}->[$i], "subjectaltnames match\t$f:$i"); } } #BEWARE: values are not the same across different openssl versions or FIPS mode, therefore testing just >0 #is(Net::SSLeay::X509_subject_name_hash($x509), $dump->{$f}->{hash}->{subject}->{dec}, 'X509_subject_name_hash dec'); #is(Net::SSLeay::X509_issuer_name_hash($x509), $dump->{$f}->{hash}->{issuer}->{dec}, 'X509_issuer_name_hash dec'); #is(Net::SSLeay::X509_issuer_and_serial_hash($x509), $dump->{$f}->{hash}->{issuer_and_serial}->{dec}, "X509_issuer_and_serial_hash dec\t$f"); cmp_ok(Net::SSLeay::X509_subject_name_hash($x509), '>', 0, "X509_subject_name_hash dec\t$f"); cmp_ok(Net::SSLeay::X509_issuer_name_hash($x509), '>', 0, "X509_issuer_name_hash dec\t$f"); cmp_ok(Net::SSLeay::X509_issuer_and_serial_hash($x509), '>', 0, "X509_issuer_and_serial_hash dec\t$f"); for my $digest (qw( md5 sha1 )) { is(Net::SSLeay::X509_get_fingerprint($x509, $digest), (exists $available_digests{$digest} ? $dump->{$f}->{fingerprint}->{$digest} : undef), "X509_get_fingerprint $digest\t$f"); } my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"); SKIP: { skip('requires openssl-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f; is(Net::SSLeay::X509_pubkey_digest($x509, $sha1_digest), $dump->{$f}->{digest_sha1}->{pubkey}, "X509_pubkey_digest\t$f"); } is(Net::SSLeay::X509_digest($x509, $sha1_digest), $dump->{$f}->{digest_sha1}->{x509}, "X509_digest\t$f"); SKIP: { skip('P_ASN1_TIME_get_isotime requires 0.9.7e+', 2) unless Net::SSLeay::SSLeay >= 0x0090705f; is(Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($x509)), $dump->{$f}->{not_before}, "X509_get_notBefore\t$f"); is(Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($x509)), $dump->{$f}->{not_after}, "X509_get_notAfter\t$f"); } ok(my $ai = Net::SSLeay::X509_get_serialNumber($x509), "X509_get_serialNumber\t$f"); is(Net::SSLeay::P_ASN1_INTEGER_get_hex($ai), $dump->{$f}->{serial}->{hex}, "serial P_ASN1_INTEGER_get_hex\t$f"); is(Net::SSLeay::P_ASN1_INTEGER_get_dec($ai), $dump->{$f}->{serial}->{dec}, "serial P_ASN1_INTEGER_get_dec\t$f"); SKIP: { # X509_get0_serialNumber should function the same as X509_get_serialNumber skip('X509_get0_serialNumber requires OpenSSL 1.1.0+ or LibreSSL 2.8.1+', 3) unless defined (&Net::SSLeay::X509_get0_serialNumber); ok(my $ai = Net::SSLeay::X509_get0_serialNumber($x509), "X509_get0_serialNumber\t$f"); is(Net::SSLeay::P_ASN1_INTEGER_get_hex($ai), $dump->{$f}->{serial}->{hex}, "serial P_ASN1_INTEGER_get_hex\t$f"); is(Net::SSLeay::P_ASN1_INTEGER_get_dec($ai), $dump->{$f}->{serial}->{dec}, "serial P_ASN1_INTEGER_get_dec\t$f"); } # On platforms with 64-bit long int returns 4294967295 rather than -1 # Caution, there is much difference between 32 and 64 bit behaviours with # Net::SSLeay::ASN1_INTEGER_get. # This test is deleted # my $asn1_integer = Net::SSLeay::ASN1_INTEGER_get($ai); # if ($asn1_integer == 4294967295) { # $asn1_integer = -1; # } # is($asn1_integer, $dump->{$f}->{serial}->{long}, "serial ASN1_INTEGER_get\t$f"); is(Net::SSLeay::X509_get_version($x509), $dump->{$f}->{version}, "X509_get_version\t$f"); is(my $ext_count = Net::SSLeay::X509_get_ext_count($x509), $dump->{$f}->{extensions}->{count}, "X509_get_ext_count\t$f"); for my $i (0..$ext_count-1) { ok(my $ext = Net::SSLeay::X509_get_ext($x509,$i), "X509_get_ext\t$f:$i"); ok(my $asn1_string = Net::SSLeay::X509_EXTENSION_get_data($ext), "X509_EXTENSION_get_data\t$f:$i"); ok(my $asn1_object = Net::SSLeay::X509_EXTENSION_get_object($ext), "X509_EXTENSION_get_object\t$f:$i"); SKIP: { skip('X509_EXTENSION_get_critical works differently on pre-0.9.7', 1) unless Net::SSLeay::SSLeay >= 0x0090700f; is(Net::SSLeay::X509_EXTENSION_get_critical($ext), $dump->{$f}->{extensions}->{entries}->[$i]->{critical}, "X509_EXTENSION_get_critical\t$f:$i"); } is(Net::SSLeay::OBJ_obj2txt($asn1_object,1), $dump->{$f}->{extensions}->{entries}->[$i]->{oid}, "OBJ_obj2txt\t$f:$i"); if (defined $dump->{$f}->{extensions}->{entries}->[$i]->{nid}) { is(my $nid = Net::SSLeay::OBJ_obj2nid($asn1_object), $dump->{$f}->{extensions}->{entries}->[$i]->{nid}, "OBJ_obj2nid\t$f:$i"); is(Net::SSLeay::OBJ_nid2ln($nid), $dump->{$f}->{extensions}->{entries}->[$i]->{ln}, "OBJ_nid2ln nid=$nid\t$f:$i"); is(Net::SSLeay::OBJ_nid2sn($nid), $dump->{$f}->{extensions}->{entries}->[$i]->{sn}, "OBJ_nid2sn nid=$nid\t$f:$i"); #BEARE: handling some special cases - mostly things that varies with different openssl versions SKIP: { my $ext_data = $dump->{$f}->{extensions}->{entries}->[$i]->{data}; if ( is_openssl() ) { if ( $nid == 85 || $nid == 86 ) { # IPv6 address formatting is broken in a way that loses # information between OpenSSL 3.0.0-alpha1 and 3.0.0-alpha7, # so there's no point in running this test if ( $ext_data =~ /IP Address:(?!(?:\d{1,3}\.){3}\d{1,3})/ && Net::SSLeay::SSLeay == 0x30000000 && Net::SSLeay::SSLeay_version( Net::SSLeay::SSLEAY_VERSION() ) =~ /-alpha[2-6]/ ) { skip( 'This OpenSSL version does not correctly format IPv6 addresses', 1 ); } # "othername" fields in subject and issuer alternative name # output are unsupported before OpenSSL 3.0.0-alpha2 if ( $ext_data =~ m|othername:| && ( Net::SSLeay::SSLeay < 0x30000000 || ( Net::SSLeay::SSLeay == 0x30000000 && Net::SSLeay::SSLeay_version( Net::SSLeay::SSLEAY_VERSION() ) =~ /-alpha1\ / ) ) ) { $ext_data =~ s{(othername:) [^, ]+}{$1}g; } } elsif ( $nid == 89 ) { # The output formatting for certificate policies has a # trailing newline before OpenSSL 3.0.0-alpha1 if ( Net::SSLeay::SSLeay < 0x30000000 ) { $ext_data .= "\n"; } } elsif ( $nid == 90 ) { # Authority key identifier formatting has a "keyid:" prefix # and a trailing newline before OpenSSL 3.0.0-alpha1 if ( Net::SSLeay::SSLeay < 0x30000000 ) { $ext_data = 'keyid:' . $ext_data . "\n"; } } elsif ( $nid == 103 ) { # The output format for CRL distribution points varies between # different OpenSSL major versions if ( Net::SSLeay::SSLeay < 0x10000001 ) { # OpenSSL 0.9.8: $ext_data =~ s{Full Name:\n }{}g; $ext_data .= "\n"; } elsif ( Net::SSLeay::SSLeay < 0x30000000 ) { # OpenSSL 1.0.0 to 1.1.1: $ext_data =~ s{(Full Name:\n )}{\n$1}g; $ext_data .= "\n"; } } elsif ( $nid == 126 ) { # OID 1.3.6.1.5.5.7.3.17 ("ipsec Internet Key Exchange") isn't # given its name in extended key usage formatted output before # OpenSSL 1.1.0-pre3 if ( Net::SSLeay::SSLeay < 0x10100003 ) { $ext_data =~ s{ipsec Internet Key Exchange(,|$)}{1.3.6.1.5.5.7.3.17$1}g; } } elsif ( $nid == 177 ) { # Authority information access formatting has a trailing # newline before OpenSSL 3.0.0-alpha1 if ( Net::SSLeay::SSLeay < 0x30000000 ) { $ext_data .= "\n"; } } } # LibreSSL is a fork of OpenSSL 1.0.1g, so any pre-1.0.2 changes above # also apply here: elsif ( is_libressl() ) { if ( $nid == 85 || $nid == 86 ) { # "othername" fields in subject and issuer alternative name # output are unsupported $ext_data =~ s{(othername:) [^, ]+}{$1}g; } elsif ( $nid == 89 ) { # The output formatting for certificate policies has a # trailing newline $ext_data .= "\n"; } elsif ( $nid == 90 ) { # Authority key identifier formatting has a "keyid:" prefix # and a trailing newline $ext_data = 'keyid:' . $ext_data . "\n"; } elsif ( $nid == 103 ) { # The output format for CRL distribution points contains # extra newlines between the values, and has leading and # trailing newlines $ext_data =~ s{(Full Name:\n )}{\n$1}g; $ext_data .= "\n"; } elsif ( $nid == 126 ) { # OID 1.3.6.1.5.5.7.3.17 ("ipsec Internet Key Exchange") isn't # given its name in extended key usage formatted output $ext_data =~ s{ipsec Internet Key Exchange(,|$)}{1.3.6.1.5.5.7.3.17$1}g; } elsif ( $nid == 177 ) { # Authority information access formatting has a trailing # newline $ext_data .= "\n"; } } is( Net::SSLeay::X509V3_EXT_print($ext), $ext_data, "X509V3_EXT_print nid=$nid\t$f:$i" ); } } } SKIP: { skip('crl_distribution_points requires 0.9.7+', int(@{$dump->{$f}->{cdp}})+1) unless Net::SSLeay::SSLeay >= 0x0090700f; my @cdp = Net::SSLeay::P_X509_get_crl_distribution_points($x509); is(scalar(@cdp), scalar(@{$dump->{$f}->{cdp}}), "cdp size\t$f"); for my $i (0..$#cdp) { is($cdp[$i], $dump->{$f}->{cdp}->[$i], "cdp match\t$f:$i"); } } my @keyusage = Net::SSLeay::P_X509_get_key_usage($x509); my @ns_cert_type = Net::SSLeay::P_X509_get_netscape_cert_type($x509); is(scalar(@keyusage), scalar(@{$dump->{$f}->{keyusage}}), "keyusage size\t$f"); is(scalar(@ns_cert_type), scalar(@{$dump->{$f}->{ns_cert_type}}), "ns_cert_type size\t$f"); for my $i (0..$#keyusage) { is($keyusage[$i], $dump->{$f}->{keyusage}->[$i], "keyusage match\t$f:$i"); } for my $i (0..$#ns_cert_type) { is($ns_cert_type[$i], $dump->{$f}->{ns_cert_type}->[$i], "ns_cert_type match\t$f:$i"); } SKIP: { # "ipsec Internet Key Exchange" isn't known by its name in OpenSSL # 1.1.0-pre2 and below or in LibreSSL if ( is_openssl() && Net::SSLeay::SSLeay < 0x10100003 || is_libressl() ) { @{ $dump->{$f}->{extkeyusage}->{ln} } = grep { $_ ne 'ipsec Internet Key Exchange' } @{ $dump->{$f}->{extkeyusage}->{ln} }; @{ $dump->{$f}->{extkeyusage}->{nid} } = grep { $_ != 1022 } @{ $dump->{$f}->{extkeyusage}->{nid} }; @{ $dump->{$f}->{extkeyusage}->{sn} } = grep { $_ ne 'ipsecIKE' } @{ $dump->{$f}->{extkeyusage}->{sn} }; } my $test_count = 4 + scalar(@{$dump->{$f}->{extkeyusage}->{oid}}) + scalar(@{$dump->{$f}->{extkeyusage}->{nid}}) + scalar(@{$dump->{$f}->{extkeyusage}->{sn}}) + scalar(@{$dump->{$f}->{extkeyusage}->{ln}}); skip('extended key usage requires 0.9.7+', $test_count) unless Net::SSLeay::SSLeay >= 0x0090700f; my @extkeyusage_oid = Net::SSLeay::P_X509_get_ext_key_usage($x509,0); my @extkeyusage_nid = Net::SSLeay::P_X509_get_ext_key_usage($x509,1); my @extkeyusage_sn = Net::SSLeay::P_X509_get_ext_key_usage($x509,2); my @extkeyusage_ln = Net::SSLeay::P_X509_get_ext_key_usage($x509,3); is(scalar(@extkeyusage_oid), scalar(@{$dump->{$f}->{extkeyusage}->{oid}}), "extku_oid size\t$f"); is(scalar(@extkeyusage_nid), scalar(@{$dump->{$f}->{extkeyusage}->{nid}}), "extku_nid size\t$f"); is(scalar(@extkeyusage_sn), scalar(@{$dump->{$f}->{extkeyusage}->{sn}}), "extku_sn size\t$f"); is(scalar(@extkeyusage_ln), scalar(@{$dump->{$f}->{extkeyusage}->{ln}}), "extku_ln size\t$f"); for my $i (0..$#extkeyusage_oid) { is($extkeyusage_oid[$i], $dump->{$f}->{extkeyusage}->{oid}->[$i], "extkeyusage_oid match\t$f:$i"); } for my $i (0..$#extkeyusage_nid) { is($extkeyusage_nid[$i], $dump->{$f}->{extkeyusage}->{nid}->[$i], "extkeyusage_nid match\t$f:$i"); } for my $i (0..$#extkeyusage_sn) { is($extkeyusage_sn[$i], $dump->{$f}->{extkeyusage}->{sn}->[$i], "extkeyusage_sn match\t$f:$i"); } for my $i (0..$#extkeyusage_ln) { is($extkeyusage_ln[$i], $dump->{$f}->{extkeyusage}->{ln}->[$i], "extkeyusage_ln match\t$f:$i"); } } ok(my $pubkey = Net::SSLeay::X509_get_pubkey($x509), "X509_get_pubkey"); is(Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_signature_alg($x509)), $dump->{$f}->{signature_alg}, "P_X509_get_signature_alg"); is(Net::SSLeay::OBJ_obj2txt(Net::SSLeay::P_X509_get_pubkey_alg($x509)), $dump->{$f}->{pubkey_alg}, "P_X509_get_pubkey_alg"); is(Net::SSLeay::EVP_PKEY_size($pubkey), $dump->{$f}->{pubkey_size}, "EVP_PKEY_size"); is(Net::SSLeay::EVP_PKEY_bits($pubkey), $dump->{$f}->{pubkey_bits}, "EVP_PKEY_bits"); SKIP: { skip('EVP_PKEY_id requires OpenSSL 1.0.0+', 1) unless Net::SSLeay::SSLeay >= 0x1000000f; is(Net::SSLeay::EVP_PKEY_id($pubkey), $dump->{$f}->{pubkey_id}, "EVP_PKEY_id"); } } my $ctx = Net::SSLeay::X509_STORE_CTX_new(); my $filename = data_file_path('simple-cert.cert.pem'); my $bio = Net::SSLeay::BIO_new_file($filename, 'rb'); my $x509 = Net::SSLeay::PEM_read_bio_X509($bio); my $x509_store = Net::SSLeay::X509_STORE_new(); Net::SSLeay::X509_STORE_CTX_set_cert($ctx,$x509); my $ca_filename = data_file_path('root-ca.cert.pem'); my $ca_bio = Net::SSLeay::BIO_new_file($ca_filename, 'rb'); my $ca_x509 = Net::SSLeay::PEM_read_bio_X509($ca_bio); is (Net::SSLeay::X509_STORE_add_cert($x509_store,$ca_x509), 1, 'X509_STORE_add_cert'); is (Net::SSLeay::X509_STORE_CTX_init($ctx, $x509_store, $x509), 1, 'X509_STORE_CTX_init'); SKIP: { skip('X509_STORE_CTX_get0_cert requires OpenSSL 1.1.0-pre5+ or LibreSSL 2.7.0+', 1) unless defined (&Net::SSLeay::X509_STORE_CTX_get0_cert); ok (my $x509_from_cert = Net::SSLeay::X509_STORE_CTX_get0_cert($ctx),'Get x509 from store ctx'); }; Net::SSLeay::X509_verify_cert($ctx); ok (my $sk_x509 = Net::SSLeay::X509_STORE_CTX_get1_chain($ctx),'Get STACK_OF(x509) from store ctx'); my $size; ok ($size = Net::SSLeay::sk_X509_num($sk_x509),'STACK_OF(X509) size '.$size); ok (Net::SSLeay::sk_X509_value($sk_x509,0),'STACK_OF(X509) value at 0'); my $new_filename = data_file_path('wildcard-cert.cert.pem'); my $new_bio = Net::SSLeay::BIO_new_file($new_filename,'rb'); my $new_x509 = Net::SSLeay::PEM_read_bio_X509($new_bio); ok (Net::SSLeay::sk_X509_insert($sk_x509,$new_x509,1),'STACK_OK(X509) insert'); my $new_size; $new_size = Net::SSLeay::sk_X509_num($sk_x509); ok ($new_size == $size + 1, 'size is ' . ($size + 1) . ' after insert'); ok (Net::SSLeay::sk_X509_delete($sk_x509, 1),'STACK_OK(X509) delete'); $new_size = Net::SSLeay::sk_X509_num($sk_x509); ok ($new_size == $size, "size is $size after delete"); ok (Net::SSLeay::sk_X509_unshift($sk_x509,$new_x509),'STACK_OF(X509) unshift'); $new_size = Net::SSLeay::sk_X509_num($sk_x509); ok ($new_size == $size + 1, 'size is ' . ($size + 1) . ' after unshift'); ok (Net::SSLeay::sk_X509_shift($sk_x509),'STACK_OF(X509) shift'); $new_size = Net::SSLeay::sk_X509_num($sk_x509); ok ($new_size == $size, "size is $size after shift"); ok (Net::SSLeay::sk_X509_pop($sk_x509),'STACK_OF(X509) pop'); $new_size = Net::SSLeay::sk_X509_num($sk_x509); ok ($new_size == $size - 1, 'size is ' . ($size + 1) . ' after pop'); Net-SSLeay-1.92/t/local/15_bio.t0000644000175000001440000000125213755162614014645 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(initialise_libssl); plan tests => 7; initialise_libssl(); my $data = '0123456789' x 100; my $len = length $data; ok( my $bio = Net::SSLeay::BIO_new( &Net::SSLeay::BIO_s_mem ), 'BIO_new' ); is( Net::SSLeay::BIO_write($bio, $data), $len, 'BIO_write' ); is( Net::SSLeay::BIO_pending($bio), $len, 'BIO_pending' ); my $read_len = 9; is( Net::SSLeay::BIO_read($bio, $read_len), substr($data, 0, $read_len), 'BIO_read part' ); is( Net::SSLeay::BIO_pending($bio), $len - $read_len, 'BIO_pending' ); is( Net::SSLeay::BIO_read($bio), substr($data, $read_len), 'BIO_read rest' ); ok( Net::SSLeay::BIO_free($bio), 'BIO_free' ); Net-SSLeay-1.92/t/local/33_x509_create_cert.t0000755000175000001440000004632014124712004017132 0ustar csnusersuse lib 'inc'; use Net::SSLeay qw(MBSTRING_ASC MBSTRING_UTF8 EVP_PK_RSA EVP_PKT_SIGN EVP_PKT_ENC); use Test::Net::SSLeay qw( data_file_path initialise_libssl is_openssl ); use utf8; plan tests => 139; initialise_libssl(); if (defined &Net::SSLeay::OSSL_PROVIDER_load) { my $provider = Net::SSLeay::OSSL_PROVIDER_load(undef, 'legacy'); diag('Failed to load legacy provider: PEM_get_string_PrivateKey may fail') unless $provider; } my $ca_crt_pem = data_file_path('root-ca.cert.pem'); my $ca_key_pem = data_file_path('root-ca.key.pem'); ok(my $bio1 = Net::SSLeay::BIO_new_file($ca_crt_pem, 'r'), "BIO_new_file 1"); ok(my $ca_cert = Net::SSLeay::PEM_read_bio_X509($bio1), "PEM_read_bio_X509"); ok(my $bio2 = Net::SSLeay::BIO_new_file($ca_key_pem, 'r'), "BIO_new_file 2"); ok(my $ca_pk = Net::SSLeay::PEM_read_bio_PrivateKey($bio2), "PEM_read_bio_PrivateKey"); is(Net::SSLeay::X509_verify($ca_cert, $ca_pk), 1, "X509_verify"); ok(my $ca_subject = Net::SSLeay::X509_get_subject_name($ca_cert), "X509_get_subject_name"); ok(my $ca_issuer = Net::SSLeay::X509_get_issuer_name($ca_cert), "X509_get_issuer_name"); is(Net::SSLeay::X509_NAME_cmp($ca_issuer, $ca_subject), 0, "X509_NAME_cmp"); { ### X509 certificate - create directly, sign with $ca_pk ok(my $pk = Net::SSLeay::EVP_PKEY_new(), "EVP_PKEY_new"); ok(my $rsa = Net::SSLeay::RSA_generate_key(2048, &Net::SSLeay::RSA_F4), "RSA_generate_key"); ok(Net::SSLeay::EVP_PKEY_assign_RSA($pk,$rsa), "EVP_PKEY_assign_RSA"); SKIP: { skip 'openssl<1.1.0 required', 1 unless Net::SSLeay::SSLeay < 0x10100000 or Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"); my @params = Net::SSLeay::RSA_get_key_parameters($rsa); ok(@params == 8, "RSA_get_key_parameters"); } ok(my $x509 = Net::SSLeay::X509_new(), "X509_new"); ok(Net::SSLeay::X509_set_pubkey($x509,$pk), "X509_set_pubkey"); ok(my $name = Net::SSLeay::X509_get_subject_name($x509), "X509_get_subject_name"); ok(Net::SSLeay::X509_NAME_add_entry_by_NID($name, &Net::SSLeay::NID_commonName, MBSTRING_UTF8, "Common name text X509"), "X509_NAME_add_entry_by_NID"); #set countryName via add_entry_by_OBJ ok(my $obj = Net::SSLeay::OBJ_nid2obj(&Net::SSLeay::NID_countryName), "OBJ_nid2obj"); ok(Net::SSLeay::X509_NAME_add_entry_by_OBJ($name, $obj, MBSTRING_UTF8, "UK"), "X509_NAME_add_entry_by_OBJ"); #set organizationName via add_entry_by_txt ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "organizationName", MBSTRING_UTF8, "Company Name"), "X509_NAME_add_entry_by_txt"); ok(Net::SSLeay::X509_set_version($x509, 3), "X509_set_version"); ok(my $sn = Net::SSLeay::X509_get_serialNumber($x509), "X509_get_serialNumber"); my $pubkey = Net::SSLeay::X509_get_X509_PUBKEY($x509); ok($pubkey ne '', "X509_get_X509_PUBKEY"); ##let us do some ASN1_INTEGER related testing #test big integer via P_ASN1_INTEGER_set_dec Net::SSLeay::P_ASN1_INTEGER_set_dec($sn, '123456789123456789123456789123456789123456789'); # On platforms with 64-bit long int returns 4294967295 rather than -1 my $asn1_integer = Net::SSLeay::ASN1_INTEGER_get(Net::SSLeay::X509_get_serialNumber($x509)); if ($asn1_integer == 4294967295) { $asn1_integer = -1; } is($asn1_integer, -1, "ASN1_INTEGER_get"); is(Net::SSLeay::P_ASN1_INTEGER_get_hex(Net::SSLeay::X509_get_serialNumber($x509)), '058936E53D139AFEFABB2683F150B684045F15', "P_ASN1_INTEGER_get_hex"); #test short integer via P_ASN1_INTEGER_set_hex Net::SSLeay::P_ASN1_INTEGER_set_hex($sn, 'D05F14'); is(Net::SSLeay::ASN1_INTEGER_get(Net::SSLeay::X509_get_serialNumber($x509)), 13655828, "ASN1_INTEGER_get"); is(Net::SSLeay::P_ASN1_INTEGER_get_dec(Net::SSLeay::X509_get_serialNumber($x509)), '13655828', "P_ASN1_INTEGER_get_dec"); #test short integer via ASN1_INTEGER_set Net::SSLeay::ASN1_INTEGER_set($sn, 123456); is(Net::SSLeay::P_ASN1_INTEGER_get_hex(Net::SSLeay::X509_get_serialNumber($x509)), '01E240', "P_ASN1_INTEGER_get_hex"); Net::SSLeay::X509_set_issuer_name($x509, Net::SSLeay::X509_get_subject_name($ca_cert)); SKIP: { skip 'openssl-0.9.7e required', 2 unless Net::SSLeay::SSLeay >= 0x0090705f; ok(Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_get_notBefore($x509), "2010-02-01T00:00:00Z"), "P_ASN1_TIME_set_isotime+X509_get_notBefore"); ok(Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_get_notAfter($x509), "2099-02-01T00:00:00Z"), "P_ASN1_TIME_set_isotime+X509_get_notAfter"); } ok(Net::SSLeay::P_X509_add_extensions($x509,$ca_cert, &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.dom.com,DNS:s2.dom.com,DNS:s3.dom.com', &Net::SSLeay::NID_crl_distribution_points => 'URI:http://pki.dom.com/crl1.pem,URI:http://pki.dom.com/crl2.pem', ), "P_X509_add_extensions"); ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); ok(Net::SSLeay::X509_sign($x509, $ca_pk, $sha1_digest), "X509_sign"); is(Net::SSLeay::X509_get_version($x509), 3, "X509_get_version"); is(Net::SSLeay::X509_verify($x509, Net::SSLeay::X509_get_pubkey($ca_cert)), 1, "X509_verify"); like(my $crt_pem = Net::SSLeay::PEM_get_string_X509($x509), qr/-----BEGIN CERTIFICATE-----/, "PEM_get_string_X509"); like(my $key_pem1 = Net::SSLeay::PEM_get_string_PrivateKey($pk), qr/-----BEGIN (RSA )?PRIVATE KEY-----/, "PEM_get_string_PrivateKey+nopasswd"); like(my $key_pem2 = Net::SSLeay::PEM_get_string_PrivateKey($pk,"password"), qr/-----BEGIN (ENCRYPTED|RSA) PRIVATE KEY-----/, "PEM_get_string_PrivateKey+passwd"); ok(my $alg1 = Net::SSLeay::EVP_get_cipherbyname("DES-EDE3-CBC"), "EVP_get_cipherbyname"); like(my $key_pem3 = Net::SSLeay::PEM_get_string_PrivateKey($pk,"password",$alg1), qr/-----BEGIN (ENCRYPTED|RSA) PRIVATE KEY-----/, "PEM_get_string_PrivateKey+passwd+enc_alg"); # DES-EDE3-OFB has no ASN1 support, detected by changes to do_pk8pkey as of openssl 1.0.1n # https://git.openssl.org/?p=openssl.git;a=commit;h=4d9dc0c269be87b92da188df1fbd8bfee4700eb3 # this test now fails # ok(my $alg2 = Net::SSLeay::EVP_get_cipherbyname("DES-EDE3-OFB"), "EVP_get_cipherbyname"); # like(my $key_pem4 = Net::SSLeay::PEM_get_string_PrivateKey($pk,"password",$alg2), qr/-----BEGIN (ENCRYPTED|RSA) PRIVATE KEY-----/, "PEM_get_string_PrivateKey+passwd+enc_alg"); is(Net::SSLeay::X509_NAME_print_ex($name), "O=Company Name,C=UK,CN=Common name text X509", "X509_NAME_print_ex"); # 2014-06-06: Sigh, some versions of openssl have this patch, which afffects the results of this test: # https://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=3009244da47b989c4cc59ba02cf81a4e9d8f8431 # with this patch, the result is "ce83889f1beab8e70aa142e07e94b0ebbd9d59e0" # is(unpack("H*",Net::SSLeay::X509_NAME_digest($name, $sha1_digest)), "044d7ea7fddced7b9b63799600b9989a63b36819", "X509_NAME_digest"); ok(my $ext_idx = Net::SSLeay::X509_get_ext_by_NID($x509, &Net::SSLeay::NID_ext_key_usage), "X509_get_ext_by_NID"); ok(my $ext = Net::SSLeay::X509_get_ext($x509, $ext_idx), "X509_get_ext"); is(Net::SSLeay::X509V3_EXT_print($ext), 'TLS Web Server Authentication, TLS Web Client Authentication', "X509V3_EXT_print"); #write_file("tmp_cert1.crt.pem", $crt_pem); #write_file("tmp_cert1.key1.pem", $key_pem1); #write_file("tmp_cert1.key2.pem", $key_pem2); #write_file("tmp_cert1.key3.pem", $key_pem3); #write_file("tmp_cert1.key4.pem", $key_pem4); } { ### X509_REQ certificate request >> sign >> X509 certificate ## PHASE1 - create certificate request ok(my $pk = Net::SSLeay::EVP_PKEY_new(), "EVP_PKEY_new"); ok(my $rsa = Net::SSLeay::RSA_generate_key(2048, &Net::SSLeay::RSA_F4), "RSA_generate_key"); ok(Net::SSLeay::EVP_PKEY_assign_RSA($pk,$rsa), "EVP_PKEY_assign_RSA"); ok(my $req = Net::SSLeay::X509_REQ_new(), "X509_REQ_new"); ok(Net::SSLeay::X509_REQ_set_pubkey($req,$pk), "X509_REQ_set_pubkey"); ok(my $name = Net::SSLeay::X509_REQ_get_subject_name($req), "X509_REQ_get_subject_name"); ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "commonName", MBSTRING_UTF8, "Common name text X509_REQ"), "X509_NAME_add_entry_by_txt"); ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "countryName", MBSTRING_UTF8, "UK"), "X509_NAME_add_entry_by_txt"); ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "organizationName", MBSTRING_UTF8, "Company Name"), "X509_NAME_add_entry_by_txt"); # All these subjectAltNames should be copied to the # certificate. This array is also used later when checking the # signed certificate. my @req_altnames = ( # Numeric type, Type name, Value to add, Value to expect back, if not equal #[ Net::SSLeay::GEN_DIRNAME(), 'dirName', 'dir_sect' ], # Would need config file [ Net::SSLeay::GEN_DNS(), 'DNS', 's1.com' ], [ Net::SSLeay::GEN_DNS(), 'DNS', 's2.com' ], #[ Net::SSLeay::GEN_EDIPARTY(), 'EdiPartyName?', '' ], # Name not in OpenSSL source [ Net::SSLeay::GEN_EMAIL(), 'email', 'foo@xample.com.com' ], [ Net::SSLeay::GEN_IPADD(), 'IP', '10.20.30.41', pack('CCCC', '10', '20', '30', '41') ], [ Net::SSLeay::GEN_IPADD(), 'IP', '2001:db8:23::1', pack('nnnnnnnn', 0x2001, 0x0db8, 0x23, 0, 0, 0, 0, 0x01) ], [ Net::SSLeay::GEN_OTHERNAME(), 'otherName', '2.3.4.5;UTF8:some other identifier', 'some other identifier' ], [ Net::SSLeay::GEN_RID(), 'RID', '1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.1.2.3.4.99.1234' ], [ Net::SSLeay::GEN_URI(), 'URI', 'https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top' ], #[ Net::SSLeay::GEN_X400(), 'X400Name?', '' ], # Name not in OpenSSL source ); # Create a comma separated list of typename:value altnames my $req_ext_altname = ''; foreach my $alt (@req_altnames) { $req_ext_altname .= "$alt->[1]:$alt->[2],"; } chop $req_ext_altname; # Remove trailing comma ok(Net::SSLeay::P_X509_REQ_add_extensions($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 => $req_ext_altname, &Net::SSLeay::NID_crl_distribution_points => 'URI:http://pki.com/crl1,URI:http://pki.com/crl2', ), "P_X509_REQ_add_extensions"); #54 = NID_pkcs9_challengePassword - XXX-TODO add new constant ok(Net::SSLeay::X509_REQ_add1_attr_by_NID($req, 54, MBSTRING_ASC, 'password xyz'), "X509_REQ_add1_attr_by_NID"); #49 = NID_pkcs9_unstructuredName - XXX-TODO add new constant ok(Net::SSLeay::X509_REQ_add1_attr_by_NID($req, 49, MBSTRING_ASC, 'Any Uns.name'), "X509_REQ_add1_attr_by_NID"); ok(Net::SSLeay::X509_REQ_set_version($req, 2), "X509_REQ_set_version"); ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); ok(Net::SSLeay::X509_REQ_sign($req, $pk, $sha1_digest), "X509_REQ_sign"); ok(my $req_pubkey = Net::SSLeay::X509_REQ_get_pubkey($req), "X509_REQ_get_pubkey"); is(Net::SSLeay::X509_REQ_verify($req, $req_pubkey), 1, "X509_REQ_verify"); is(Net::SSLeay::X509_REQ_get_version($req), 2, "X509_REQ_get_version"); ok(my $obj_challengePassword = Net::SSLeay::OBJ_txt2obj('1.2.840.113549.1.9.7'), "OBJ_txt2obj"); ok(my $nid_challengePassword = Net::SSLeay::OBJ_obj2nid($obj_challengePassword), "OBJ_obj2nid"); is(Net::SSLeay::X509_REQ_get_attr_count($req), 3, "X509_REQ_get_attr_count"); is(my $n1 = Net::SSLeay::X509_REQ_get_attr_by_NID($req, $nid_challengePassword,-1), 1, "X509_REQ_get_attr_by_NID"); is(my $n2 = Net::SSLeay::X509_REQ_get_attr_by_OBJ($req, $obj_challengePassword,-1), 1, "X509_REQ_get_attr_by_OBJ"); SKIP: { skip('requires openssl-0.9.7', 3) unless Net::SSLeay::SSLeay >= 0x0090700f; ok(my @attr_values = Net::SSLeay::P_X509_REQ_get_attr($req, $n1), "P_X509_REQ_get_attr"); is(scalar(@attr_values), 1, "attr_values size"); is(Net::SSLeay::P_ASN1_STRING_get($attr_values[0]), "password xyz", "attr_values[0]"); } like(my $req_pem = Net::SSLeay::PEM_get_string_X509_REQ($req), qr/-----BEGIN CERTIFICATE REQUEST-----/, "PEM_get_string_X509_REQ"); like(my $key_pem = Net::SSLeay::PEM_get_string_PrivateKey($pk), qr/-----BEGIN (RSA )?PRIVATE KEY-----/, "PEM_get_string_PrivateKey"); #write_file("tmp_cert2.req.pem", $req_pem); #write_file("tmp_cert2.key.pem", $key_pem); ## PHASE2 - turn X509_REQ into X509 cert + sign with CA key ok(my $x509ss = Net::SSLeay::X509_new(), "X509_new"); ok(Net::SSLeay::X509_set_version($x509ss, 2), "X509_set_version"); ok(my $sn = Net::SSLeay::X509_get_serialNumber($x509ss), "X509_get_serialNumber"); Net::SSLeay::P_ASN1_INTEGER_set_hex($sn, 'ABCDEF'); Net::SSLeay::X509_set_issuer_name($x509ss, Net::SSLeay::X509_get_subject_name($ca_cert)); ok(Net::SSLeay::X509_gmtime_adj(Net::SSLeay::X509_get_notBefore($x509ss), 0), "X509_gmtime_adj + X509_get_notBefore"); ok(Net::SSLeay::X509_gmtime_adj(Net::SSLeay::X509_get_notAfter($x509ss), 60*60*24*100), "X509_gmtime_adj + X509_get_notAfter"); ok(Net::SSLeay::X509_set_subject_name($x509ss, Net::SSLeay::X509_REQ_get_subject_name($req)), "X509_set_subject_name + X509_REQ_get_subject_name"); ok(Net::SSLeay::P_X509_copy_extensions($req, $x509ss), "P_X509_copy_extensions"); ok(my $tmppkey = Net::SSLeay::X509_REQ_get_pubkey($req), "X509_REQ_get_pubkey"); ok(Net::SSLeay::X509_set_pubkey($x509ss,$tmppkey), "X509_set_pubkey"); Net::SSLeay::EVP_PKEY_free($tmppkey); ok(Net::SSLeay::X509_sign($x509ss, $ca_pk, $sha1_digest), "X509_sign"); like(my $crt_pem = Net::SSLeay::PEM_get_string_X509($x509ss), qr/-----BEGIN CERTIFICATE-----/, "PEM_get_string_X509"); #write_file("tmp_cert2.crt.pem", $crt_pem); ## PHASE3 - check some certificate parameters is(Net::SSLeay::X509_NAME_print_ex(Net::SSLeay::X509_get_subject_name($x509ss)), "O=Company Name,C=UK,CN=Common name text X509_REQ", "X509_NAME_print_ex 1"); is(Net::SSLeay::X509_NAME_print_ex(Net::SSLeay::X509_get_issuer_name($x509ss)), 'CN=Root CA,OU=Test Suite,O=Net-SSLeay,C=PL', "X509_NAME_print_ex 2"); SKIP: { skip 'openssl-0.9.7e required', 2 unless Net::SSLeay::SSLeay >= 0x0090705f; like(Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($x509ss)), qr/^\d\d\d\d-\d\d-\d\d/, "X509_get_notBefore"); like(Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($x509ss)), qr/^\d\d\d\d-\d\d-\d\d/, "X509_get_notAfter"); } # See that all subjectAltNames added to request were copied to the certificate my @altnames = Net::SSLeay::X509_get_subjectAltNames($x509ss); for (my $i = 0; $i < @req_altnames; $i++) { my ($type, $name) = ($altnames[2*$i], $altnames[2*$i+1]); my $test_vec = $req_altnames[$i]; my $expected = defined $test_vec->[3] ? $test_vec->[3] : $test_vec->[2]; is($type, $test_vec->[0], "subjectAltName type in certificate matches request: $type"); is($name, $expected, "subjectAltName value in certificate matches request: $test_vec->[2]"); } my $mask = EVP_PK_RSA | EVP_PKT_SIGN | EVP_PKT_ENC; is(Net::SSLeay::X509_certificate_type($x509ss)&$mask, $mask, "X509_certificate_type"); is(Net::SSLeay::X509_REQ_free($req), undef, "X509_REQ_free"); is(Net::SSLeay::X509_free($x509ss), undef, "X509_free"); } { ### X509 certificate - unicode ok(my $x509 = Net::SSLeay::X509_new(), "X509_new"); ok(my $name = Net::SSLeay::X509_get_subject_name($x509), "X509_get_subject_name"); my $txt = "\x{17E}lut\xFD"; utf8::encode($txt); ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "CN", MBSTRING_UTF8, $txt), "X509_NAME_add_entry_by_txt"); ok(Net::SSLeay::X509_NAME_add_entry_by_txt($name, "OU", MBSTRING_UTF8, "Unit"), "X509_NAME_add_entry_by_txt"); is(Net::SSLeay::X509_NAME_print_ex($name), 'OU=Unit,CN=\C5\BElut\C3\BD', "X509_NAME_print_ex"); } { ### X509 certificate - copy some fields from other certificate my $orig_crt_pem = data_file_path('wildcard-cert.cert.pem'); ok(my $bio = Net::SSLeay::BIO_new_file($orig_crt_pem, 'r'), "BIO_new_file"); ok(my $orig_cert = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509"); ok(my $pk = Net::SSLeay::EVP_PKEY_new(), "EVP_PKEY_new"); ok(my $rsa = Net::SSLeay::RSA_generate_key(2048, &Net::SSLeay::RSA_F4), "RSA_generate_key"); ok(Net::SSLeay::EVP_PKEY_assign_RSA($pk,$rsa), "EVP_PKEY_assign_RSA"); ok(my $x509 = Net::SSLeay::X509_new(), "X509_new"); ok(Net::SSLeay::X509_set_pubkey($x509,$pk), "X509_set_pubkey"); ok(my $name = Net::SSLeay::X509_get_subject_name($orig_cert), "X509_get_subject_name"); ok(Net::SSLeay::X509_set_subject_name($x509, $name), "X509_set_subject_name"); ok(my $sn = Net::SSLeay::X509_get_serialNumber($orig_cert), "X509_get_serialNumber"); ok(Net::SSLeay::X509_set_serialNumber($x509, $sn), "X509_get_serialNumber"); Net::SSLeay::X509_set_issuer_name($x509, Net::SSLeay::X509_get_subject_name($ca_cert)); SKIP: { skip 'openssl-0.9.7e required', 2 unless Net::SSLeay::SSLeay >= 0x0090705f; ok(Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_get_notBefore($x509), "2010-02-01T00:00:00Z") , "P_ASN1_TIME_set_isotime+X509_get_notBefore"); ok(Net::SSLeay::P_ASN1_TIME_set_isotime(Net::SSLeay::X509_get_notAfter($x509), "2038-01-01T00:00:00Z"), "P_ASN1_TIME_set_isotime+X509_get_notAfter"); } ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); ok(Net::SSLeay::X509_sign($x509, $ca_pk, $sha1_digest), "X509_sign"); like(my $crt_pem = Net::SSLeay::PEM_get_string_X509($x509), qr/-----BEGIN CERTIFICATE-----/, "PEM_get_string_X509"); like(my $key_pem = Net::SSLeay::PEM_get_string_PrivateKey($pk), qr/-----BEGIN (RSA )?PRIVATE KEY-----/, "PEM_get_string_PrivateKey"); #write_file("tmp_cert3.crt.pem", $crt_pem); #write_file("tmp_cert3.key.pem", $key_pem); } { ### X509 request from file + some special tests my $req_pem = data_file_path('simple-cert.csr.pem'); ok(my $bio = Net::SSLeay::BIO_new_file($req_pem, 'r'), "BIO_new_file"); ok(my $req = Net::SSLeay::PEM_read_bio_X509_REQ($bio), "PEM_read_bio_X509"); ok(my $sha1_digest = Net::SSLeay::EVP_get_digestbyname("sha1"), "EVP_get_digestbyname"); is(unpack("H*", Net::SSLeay::X509_REQ_digest($req, $sha1_digest)), "372c21a20a6d4e15bf8ecefb487cc604d9a10960", "X509_REQ_digest"); ok(my $req2 = Net::SSLeay::X509_REQ_new(), "X509_REQ_new"); ok(my $name = Net::SSLeay::X509_REQ_get_subject_name($req), "X509_REQ_get_subject_name"); ok(Net::SSLeay::X509_REQ_set_subject_name($req2, $name), "X509_REQ_set_subject_name"); is(Net::SSLeay::X509_REQ_free($req), undef, "X509_REQ_free"); } { ### X509 + X509_REQ loading DER format my $req_der = data_file_path('simple-cert.csr.der'); ok(my $bio1 = Net::SSLeay::BIO_new_file($req_der, 'rb'), "BIO_new_file"); ok(my $req = Net::SSLeay::d2i_X509_REQ_bio($bio1), "d2i_X509_REQ_bio"); my $x509_der = data_file_path('simple-cert.cert.der'); ok(my $bio2 = Net::SSLeay::BIO_new_file($x509_der, 'rb'), "BIO_new_file"); ok(my $x509 = Net::SSLeay::d2i_X509_bio($bio2), "d2i_X509_bio"); } Net-SSLeay-1.92/t/local/02_pod_coverage.t0000644000175000001440000000117013732725160016520 0ustar csnusers# Ensure all public symbols in Net::SSLeay, Net::SSLeay::Handle, and our private # Test:: modules are appropriately documented use lib 'inc'; use Test::Net::SSLeay; if (!$ENV{RELEASE_TESTING}) { plan skip_all => 'These tests are for only for release candidate testing. Enable with RELEASE_TESTING=1'; } eval "use Test::Pod::Coverage 1.00"; if ($@) { plan skip_all => 'Test::Pod::Coverage >= 1.00 required for testing pod coverage'; } else { plan tests => 4; } pod_coverage_ok('Net::SSLeay'); pod_coverage_ok('Net::SSLeay::Handle'); pod_coverage_ok('Test::Net::SSLeay'); pod_coverage_ok('Test::Net::SSLeay::Socket'); Net-SSLeay-1.92/t/local/37_asn1_time.t0000644000175000001440000000320113755162614015754 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(initialise_libssl); plan tests => 10; initialise_libssl(); my $atime1 = Net::SSLeay::ASN1_TIME_new(); ok($atime1, 'ASN1_TIME_new [1]'); Net::SSLeay::ASN1_TIME_set($atime1, 1999888777); SKIP: { skip 'openssl-0.9.8i is buggy', 2 if Net::SSLeay::SSLeay == 0x0090809f; is(Net::SSLeay::P_ASN1_TIME_put2string($atime1), 'May 16 20:39:37 2033 GMT', 'P_ASN1_TIME_put2string'); is(Net::SSLeay::P_ASN1_UTCTIME_put2string($atime1), 'May 16 20:39:37 2033 GMT', 'P_ASN1_UTCTIME_put2string'); } SKIP: { skip 'openssl-0.9.7e required', 1 unless Net::SSLeay::SSLeay >= 0x0090705f; is(Net::SSLeay::P_ASN1_TIME_get_isotime($atime1), '2033-05-16T20:39:37Z', 'P_ASN1_TIME_get_isotime'); } Net::SSLeay::ASN1_TIME_free($atime1); my $atime2 = Net::SSLeay::ASN1_TIME_new(); ok($atime2, 'ASN1_TIME_new [2]'); SKIP: { skip 'openssl-0.9.7e required', 2 unless Net::SSLeay::SSLeay >= 0x0090705f; Net::SSLeay::P_ASN1_TIME_set_isotime($atime2, '2075-06-19T13:08:52Z'); SKIP: { skip 'openssl-0.9.8i is buggy', 1 if Net::SSLeay::SSLeay == 0x0090809f; is(Net::SSLeay::P_ASN1_TIME_put2string($atime2), 'Jun 19 13:08:52 2075 GMT', 'P_ASN1_TIME_put2string y=2075'); } is(Net::SSLeay::P_ASN1_TIME_get_isotime($atime2), '2075-06-19T13:08:52Z', 'P_ASN1_TIME_get_isotime y=2075'); } Net::SSLeay::ASN1_TIME_free($atime2); my $atime3 = Net::SSLeay::ASN1_TIME_new(); ok($atime1, 'ASN1_TIME_new [3]'); ok(Net::SSLeay::X509_gmtime_adj($atime3, 60*60*24*365*2)); like(Net::SSLeay::P_ASN1_TIME_put2string($atime3), qr/[A-Z][a-z]+ +\d+ +\d+:\d+:\d+ +20\d\d/, 'X509_gmtime_adj'); Net::SSLeay::ASN1_TIME_free($atime3); Net-SSLeay-1.92/t/local/35_ephemeral.t0000644000175000001440000000110113755162614016031 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw(initialise_libssl); if (Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") || Net::SSLeay::constant("OPENSSL_VERSION_NUMBER") >= 0x10100000) { plan skip_all => "LibreSSL and OpenSSL 1.1.0 removed support for ephemeral/temporary RSA private keys"; } else { plan tests => 3; } initialise_libssl(); ok( my $ctx = Net::SSLeay::CTX_new(), 'CTX_new' ); ok( my $rsa = Net::SSLeay::RSA_generate_key(2048, Net::SSLeay::RSA_F4()), 'RSA_generate_key' ); ok( Net::SSLeay::CTX_set_tmp_rsa($ctx, $rsa), 'CTX_set_tmp_rsa' ); Net-SSLeay-1.92/t/local/01_pod.t0000644000175000001440000000130113753340350014635 0ustar csnusers# Ensure all pod-formatted documentation is valid use lib 'inc'; use Test::Net::SSLeay; # Starting with Net-SSLeay 1.88, the pod syntax uses constructs that are not # legal according to older Test::Pod versions (e.g. 1.40, in RHEL 6). # Here's a snippet from the Changes file for Test::Pod 1.41: # Test::Pod no longer complains about the construct L, as it is no # longer illegal (as of Perl 5.11.3). eval "use Test::Pod 1.41"; if ($@) { plan skip_all => "Test::Pod 1.41 required for testing pod"; } all_pod_files_ok(qw( blib/lib/Net/SSLeay.pm blib/lib/Net/SSLeay/Handle.pm helper_script/generate-test-pki inc/Test/Net/SSLeay.pm inc/Test/Net/SSLeay/Socket.pm )); Net-SSLeay-1.92/t/local/43_misc_functions.t0000644000175000001440000003164614140310470017112 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl is_libressl new_ctx tcp_socket ); if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 46; } initialise_libssl(); my $pid; alarm(30); END { kill 9,$pid if $pid } # Values that were previously looked up for get_keyblock_size test # Revisit: currently the only known user for get_keyblock_size is # EAP-FAST. How it works with AEAD ciphers is for future study. our %non_aead_cipher_to_keyblock_size = ( 'RC4-MD5' => 64, 'RC4-SHA' => 72, 'AES256-SHA256' => 160, 'AES128-SHA256' => 128, 'AES128-SHA' => 104, 'AES256-SHA' => 136, ); our %tls_1_2_aead_cipher_to_keyblock_size = ( 'AES128-GCM-SHA256' => 56, 'AES256-GCM-SHA384' => 88, ); # LibreSSL uses different names for the TLSv1.3 ciphersuites: our %tls_1_3_aead_cipher_to_keyblock_size = is_libressl() ? ( 'AEAD-AES128-GCM-SHA256' => 56, 'AEAD-AES256-GCM-SHA384' => 88, 'AEAD-CHACHA20-POLY1305-SHA256' => 88, ) : ( 'TLS_AES_128_GCM_SHA256' => 56, 'TLS_AES_256_GCM_SHA384' => 88, 'TLS_CHACHA20_POLY1305_SHA256' => 88, ); # Combine the AEAD hashes our %aead_cipher_to_keyblock_size = (%tls_1_2_aead_cipher_to_keyblock_size, %tls_1_3_aead_cipher_to_keyblock_size); # Combine the hashes our %cipher_to_keyblock_size = (%non_aead_cipher_to_keyblock_size, %aead_cipher_to_keyblock_size); our %version_str2int = ( 'SSLv3' => sub { return eval { Net::SSLeay::SSL3_VERSION(); } }, 'TLSv1' => sub { return eval { Net::SSLeay::TLS1_VERSION(); } }, 'TLSv1.1' => sub { return eval { Net::SSLeay::TLS1_1_VERSION(); } }, 'TLSv1.2' => sub { return eval { Net::SSLeay::TLS1_2_VERSION(); } }, 'TLSv1.3' => sub { return eval { Net::SSLeay::TLS1_3_VERSION(); } }, ); # Tests that don't need a connection client_test_ciphersuites(); test_cipher_funcs(); # Tests that need a connection my $server = tcp_socket(); { # SSL server - just handle single connect, send information to # client and exit my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { my $cl = $server->accept(); my $ctx = new_ctx(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); # my $get_keyblock_size_ciphers = join(':', keys(%cipher_to_keyblock_size)); my $get_keyblock_size_ciphers = join(':', keys(%non_aead_cipher_to_keyblock_size)); Net::SSLeay::CTX_set_cipher_list($ctx, $get_keyblock_size_ciphers); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); # Send our idea of Finished messages to the client. my ($f_len, $finished_s, $finished_c); $f_len = Net::SSLeay::get_finished($ssl, $finished_s); Net::SSLeay::write($ssl, "server: $f_len ". unpack('H*', $finished_s)); $f_len = Net::SSLeay::get_peer_finished($ssl, $finished_c); Net::SSLeay::write($ssl, "client: $f_len ". unpack('H*', $finished_c)); # Echo back the termination request from client my $end = Net::SSLeay::read($ssl); Net::SSLeay::write($ssl, $end); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("server close: $!"); $server->close() || die("server listen socket close: $!"); exit(0); } } sub client { # SSL client - connect to server and receive information that we # compare to our expected values my ($f_len, $f_len_trunc, $finished_s, $finished_c, $msg, $expected); my $cl = $server->connect(); my $ctx = new_ctx(); Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, $cl); client_test_finished($ssl); client_test_keyblock_size($ssl); client_test_version_funcs($ssl); # Tell the server to quit and see that our connection is still up my $end = "end"; Net::SSLeay::write($ssl, $end); ok($end eq Net::SSLeay::read($ssl), 'Successful termination'); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); $server->close() || die("client listen socket close: $!"); return; } client(); waitpid $pid, 0; exit(0); # Test get_finished() and get_peer_finished() with server. sub client_test_finished { my ($ssl) = @_; my ($f_len, $f_len_trunc, $finished_s, $finished_c, $msg, $expected); # Finished messages have not been sent yet $f_len = Net::SSLeay::get_peer_finished($ssl, $finished_s); ok($f_len == 0, 'Return value for get_peer_finished is empty before connect for server'); ok(defined $finished_s && $finished_s eq '', 'Server Finished is empty'); $f_len = Net::SSLeay::get_finished($ssl, $finished_c); ok($f_len == 0, 'Finished is empty before connect for client'); ok(defined $finished_c && $finished_c eq '', 'Client Finished is empty'); # Complete connection. After this we have Finished messages from both peers. Net::SSLeay::connect($ssl); $f_len = Net::SSLeay::get_peer_finished($ssl, $finished_s); ok($f_len, 'Server Finished is not empty'); ok($f_len == length($finished_s), 'Return value for get_peer_finished equals to Finished length'); $expected = "server: $f_len " . unpack('H*', $finished_s); $msg = Net::SSLeay::read($ssl); ok($msg eq $expected, 'Server Finished is equal'); $f_len = Net::SSLeay::get_finished($ssl, $finished_c); ok($f_len, 'Client Finished is not empty'); ok($f_len == length($finished_c), 'Return value for get_finished equals to Finished length'); $expected = "client: $f_len " . unpack('H*', $finished_c); $msg = Net::SSLeay::read($ssl); ok($msg eq $expected, 'Client Finished is equal'); ok($finished_s ne $finished_c, 'Server and Client Finished are not equal'); # Finished should still be the same. See that we can fetch truncated values. my $trunc8_s = substr($finished_s, 0, 8); $f_len_trunc = Net::SSLeay::get_peer_finished($ssl, $finished_s, 8); ok($f_len_trunc == $f_len, 'Return value for get_peer_finished is unchanged when count is set'); ok($trunc8_s eq $finished_s, 'Count works for get_peer_finished'); my $trunc8_c = substr($finished_c, 0, 8); $f_len_trunc = Net::SSLeay::get_finished($ssl, $finished_c, 8); ok($f_len_trunc == $f_len, 'Return value for get_finished is unchanged when count is set'); ok($trunc8_c eq $finished_c, 'Count works for get_finished'); } # Test get_keyblock_size # Notes: With TLS 1.3 the cipher is always an AEAD cipher. If AEAD # ciphers are enabled for TLS 1.2 and earlier, with LibreSSL # get_keyblock_size returns -1 when AEAD cipher is chosen. sub client_test_keyblock_size { my ($ssl) = @_; my $cipher = Net::SSLeay::get_cipher($ssl); ok($cipher, "get_cipher returns a value: $cipher"); my $keyblock_size = &Net::SSLeay::get_keyblock_size($ssl); ok(defined $keyblock_size, 'get_keyblock_size return value is defined'); if ($keyblock_size == -1) { # Accept -1 with AEAD ciphers with LibreSSL ok(is_libressl(), 'get_keyblock_size returns -1 with LibreSSL'); ok(defined $aead_cipher_to_keyblock_size{$cipher}, 'keyblock size is -1 for an AEAD cipher'); } else { ok($keyblock_size >= 0, 'get_keyblock_size return value is not negative'); ok($cipher_to_keyblock_size{$cipher} == $keyblock_size, "keyblock size $keyblock_size is the expected value $cipher_to_keyblock_size{$cipher}"); } } # Test SSL_get_version and related functions sub client_test_version_funcs { my ($ssl) = @_; my $version_str = Net::SSLeay::get_version($ssl); my $version_const = $version_str2int{$version_str}; my $version = Net::SSLeay::version($ssl); ok(defined $version_const, "Net::SSLeay::get_version return value $version_str is known"); is(&$version_const, $version, "Net:SSLeay::version return value $version matches get_version string"); if (defined &Net::SSLeay::client_version) { if ($version_str eq 'TLSv1.3') { # Noticed that client_version and version are equal for all SSL/TLS versions except of TLSv1.3 # For more, see https://github.com/openssl/openssl/issues/7079 is(Net::SSLeay::client_version($ssl), &{$version_str2int{'TLSv1.2'}}, 'Net::SSLeay::client_version TLSv1.2 is expected when Net::SSLeay::version indicates TLSv1.3'); } else { is(Net::SSLeay::client_version($ssl), $version, 'Net::SSLeay::client_version equals to Net::SSLeay::version'); } is(Net::SSLeay::is_dtls($ssl), 0, 'Net::SSLeay::is_dtls returns 0'); } else { SKIP: { skip('Do not have Net::SSLeay::client_version nor Net::SSLeay::is_dtls', 2); }; } return; } sub client_test_ciphersuites { unless (defined &Net::SSLeay::CTX_set_ciphersuites) { SKIP: { skip('Do not have Net::SSLeay::CTX_set_ciphersuites', 10); } return; } my $ciphersuites = join(':', keys(%tls_1_3_aead_cipher_to_keyblock_size)); # In OpenSSL 3.0.0 alpha 11 (commit c1e8a0c66e32b4144fdeb49bd5ff7acb76df72b9) # SSL_CTX_set_ciphersuites() and SSL_set_ciphersuites() were # changed to ignore unknown ciphers my $ret_partially_bad_ciphersuites = 1; if (Net::SSLeay::SSLeay() == 0x30000000) { my $ssleay_version = Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_VERSION()); $ret_partially_bad_ciphersuites = 0 if ($ssleay_version =~ m/-alpha(\d+)/s) && $1 < 11; } elsif (Net::SSLeay::SSLeay() < 0x30000000) { $ret_partially_bad_ciphersuites = 0; } my ($ctx, $rv, $ssl); $ctx = new_ctx(); $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, $ciphersuites); is($rv, 1, 'CTX set good ciphersuites'); $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, ''); is($rv, 1, 'CTX set empty ciphersuites'); { no warnings 'uninitialized'; $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, undef); }; is($rv, 1, 'CTX set undef ciphersuites'); $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, 'nosuchthing:' . $ciphersuites); is($rv, $ret_partially_bad_ciphersuites, 'CTX set partially bad ciphersuites'); $rv = Net::SSLeay::CTX_set_ciphersuites($ctx, 'nosuchthing:'); is($rv, 0, 'CTX set bad ciphersuites'); $ssl = Net::SSLeay::new($ctx); $rv = Net::SSLeay::set_ciphersuites($ssl, $ciphersuites); is($rv, 1, 'SSL set good ciphersuites'); $rv = Net::SSLeay::set_ciphersuites($ssl, ''); is($rv, 1, 'SSL set empty ciphersuites'); { no warnings 'uninitialized'; $rv = Net::SSLeay::set_ciphersuites($ssl, undef); }; is($rv, 1, 'SSL set undef ciphersuites'); $rv = Net::SSLeay::set_ciphersuites($ssl, 'nosuchthing:' . $ciphersuites); is($rv, $ret_partially_bad_ciphersuites, 'SSL set partially bad ciphersuites'); $rv = Net::SSLeay::set_ciphersuites($ssl, 'nosuchthing:'); is($rv, 0, 'SSL set bad ciphersuites'); return; } sub test_cipher_funcs { my ($ctx, $rv, $ssl); $ctx = new_ctx(); $ssl = Net::SSLeay::new($ctx); # OpenSSL API says these can accept NULL ssl { no warnings 'uninitialized'; my @a = Net::SSLeay::get_ciphers(undef); is(@a, 0, 'SSL_get_ciphers with undefined ssl'); is(Net::SSLeay::get_cipher_list(undef, 0), undef, 'SSL_get_cipher_list with undefined ssl'); is(Net::SSLeay::CIPHER_get_name(undef), '(NONE)', 'SSL_CIPHER_get_name with undefined ssl'); is(Net::SSLeay::CIPHER_get_bits(undef), 0, 'SSL_CIPHER_get_bits with undefined ssl'); is(Net::SSLeay::CIPHER_get_version(undef), '(NONE)', 'SSL_CIPHER_get_version with undefined ssl'); } # 10 is based on experimentation. Lowest count seen was 15 in # OpenSSL 0.9.8zh. my @ciphers = Net::SSLeay::get_ciphers($ssl); cmp_ok(@ciphers, '>=', 10, 'SSL_get_ciphers: number of ciphers: ' . @ciphers); my $first; my ($name_failed, $desc_failed, $vers_failed, $bits_failed, $alg_bits_failed) = (0, 0, 0, 0, 0); foreach my $c (@ciphers) { # Shortest seen: RC4-MD5 my $name = Net::SSLeay::CIPHER_get_name($c); $name_failed++ if $name !~ m/^[A-Z0-9_-]{7,}\z/s; $first = $name unless $first; # Cipher description should begin with its name my $desc = Net::SSLeay::CIPHER_description($c); $desc_failed++ if $desc !~ m/^$name\s+/s; # For example: TLSv1/SSLv3, SSLv2 my $vers = Net::SSLeay::CIPHER_get_version($c); $vers_failed++ if length($vers) < 5; # See that get_bits returns the same no matter how it's called my $alg_bits; my $bits = Net::SSLeay::CIPHER_get_bits($c, $alg_bits); $bits_failed++ if $bits ne Net::SSLeay::CIPHER_get_bits($c); # Once again, a value that should be reasonable $alg_bits_failed++ if $alg_bits < 56; } is($name_failed, 0, 'CIPHER_get_name'); is($desc_failed, 0, 'CIPHER_description matches with CIPHER_name'); is($vers_failed, 0, 'CIPHER_get_version'); is($bits_failed, 0, 'CIPHER_get_bits'); is($alg_bits_failed, 0, 'CIPHER_get_bits with alg_bits'); is($first, Net::SSLeay::get_cipher_list($ssl, 0), 'SSL_get_cipher_list'); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); return; } Net-SSLeay-1.92/t/local/39_pkcs12.t0000644000175000001440000000622414124712004015172 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl ); plan tests => 17; initialise_libssl(); # Encrypted PKCS#12 archive, no chain: my $filename1 = data_file_path('simple-cert.enc.p12'); my $filename1_password = 'test'; # Encrypted PKCS#12 archive, full chain: my $filename2 = data_file_path('simple-cert.certchain.enc.p12'); my $filename2_password = 'test'; # PKCS#12 archive, no chain: my $filename3 = data_file_path('simple-cert.p12'); { my($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename1, 1, $filename1_password); ok($privkey, '$privkey [1]'); ok($cert, '$cert [1]'); is(scalar(@cachain), 0, 'size of @cachain [1]'); my $subj_name = Net::SSLeay::X509_get_subject_name($cert); is(Net::SSLeay::X509_NAME_oneline($subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=simple-cert.net-ssleay.example', "X509_NAME_oneline [1]"); } { my($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename2, 1, $filename2_password); ok($privkey, '$privkey [2]'); ok($cert, '$cert [2]'); is(scalar(@cachain), 2, 'size of @cachain [2]'); my $subj_name = Net::SSLeay::X509_get_subject_name($cert); my $ca1_subj_name = Net::SSLeay::X509_get_subject_name($cachain[0]); my $ca2_subj_name = Net::SSLeay::X509_get_subject_name($cachain[1]); is(Net::SSLeay::X509_NAME_oneline($subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=simple-cert.net-ssleay.example', "X509_NAME_oneline [2/1]"); # OpenSSL versions 1.0.0-beta2 to 3.0.0-alpha6 inclusive and all versions of # LibreSSL return the CA certificate chain with the root CA certificate at the # end; all other versions return the certificate chain with the root CA # certificate at the start if ( Net::SSLeay::SSLeay < 0x10000002 || ( Net::SSLeay::SSLeay == 0x30000000 && Net::SSLeay::SSLeay_version( Net::SSLeay::SSLEAY_VERSION() ) !~ /-alpha[1-6] / ) || Net::SSLeay::SSLeay > 0x30000000 ) { is(Net::SSLeay::X509_NAME_oneline($ca1_subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=Intermediate CA', "X509_NAME_oneline [2/3]"); is(Net::SSLeay::X509_NAME_oneline($ca2_subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=Root CA', "X509_NAME_oneline [2/4]"); } else { is(Net::SSLeay::X509_NAME_oneline($ca1_subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=Root CA', "X509_NAME_oneline [2/3]"); is(Net::SSLeay::X509_NAME_oneline($ca2_subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=Intermediate CA', "X509_NAME_oneline [2/4]"); } } { my($privkey, $cert, @cachain) = Net::SSLeay::P_PKCS12_load_file($filename3, 1); ok($privkey, '$privkey [3]'); ok($cert, '$cert [3]'); is(scalar(@cachain), 0, 'size of @cachain [3]'); my $subj_name = Net::SSLeay::X509_get_subject_name($cert); is(Net::SSLeay::X509_NAME_oneline($subj_name), '/C=PL/O=Net-SSLeay/OU=Test Suite/CN=simple-cert.net-ssleay.example', "X509_NAME_oneline [3]"); } { my($privkey, $cert, @should_be_empty) = Net::SSLeay::P_PKCS12_load_file($filename2, 0, $filename2_password); ok($privkey, '$privkey [4]'); ok($cert, '$cert [4]'); is(scalar(@should_be_empty), 0, 'size of @should_be_empty'); } Net-SSLeay-1.92/t/local/44_sess.t0000644000175000001440000003066014124712004015041 0ustar csnusers# Test session-related functions use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl is_protocol_usable new_ctx tcp_socket ); use Storable; if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } else { plan tests => 58; } initialise_libssl(); my @rounds = qw( TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 TLSv1.3-num-tickets-ssl TLSv1.3-num-tickets-ctx-6 TLSv1.3-num-tickets-ctx-0 ); my %usable = map { ( my $proto = $_ ) =~ s/-.*$//; $_ => is_protocol_usable($proto) } @rounds; my $pid; alarm(30); END { kill 9,$pid if $pid } my (%server_stats, %client_stats); # Update client and server stats so that when something fails, it # remains in failed state sub set_client_stat { my ($round, $param, $is_ok) = @_; if ($is_ok) { $client_stats{$round}->{$param} = 1 unless defined $client_stats{$round}->{$param}; return; } $client_stats{$round}->{$param} = 0; } sub set_server_stat { my ($round, $param, $is_ok) = @_; if ($is_ok) { $server_stats{$round}->{$param} = 1 unless defined $server_stats{$round}->{$param}; return; } $server_stats{$round}->{$param} = 0; } # Separate session callbacks for client and server. The callbacks # update stats and check that SSL_CTX, SSL and SESSION are as # expected. sub client_new_cb { my ($ssl, $ssl_session, $expected_ctx, $round) = @_; $client_stats{$round}->{new_cb_called}++; my $ctx = Net::SSLeay::get_SSL_CTX($ssl); my $ssl_version = Net::SSLeay::get_version($ssl); my $is_ok = ($ctx eq $expected_ctx && $ssl_session eq Net::SSLeay::SSL_get0_session($ssl) && $round =~ m/^$ssl_version/); diag("client_new_cb params not ok: $round") unless $is_ok; set_client_stat($round, 'new_params_ok', $is_ok); if (defined &Net::SSLeay::SESSION_is_resumable) { my $is_resumable = Net::SSLeay::SESSION_is_resumable($ssl_session); BAIL_OUT("is_resumable is not 0 or 1: $round") unless defined $is_resumable && ($is_resumable == 0 || $is_resumable == 1); set_client_stat($round, 'new_session_is_resumable', $is_resumable); } #Net::SSLeay::SESSION_print_fp(*STDOUT, $ssl_session); return 0; } sub client_remove_cb { my ($ctx, $ssl_session, $expected_ctx, $round) = @_; $client_stats{$round}->{remove_cb_called}++; my $is_ok = ($ctx eq $expected_ctx); diag("client_remove_cb params not ok: $round") unless $is_ok; set_client_stat($round, 'remove_params_ok', $is_ok); #Net::SSLeay::SESSION_print_fp(*STDOUT, $ssl_session); return; } sub server_new_cb { my ($ssl, $ssl_session, $expected_ctx, $round) = @_; $server_stats{$round}->{new_cb_called}++; my $ctx = Net::SSLeay::get_SSL_CTX($ssl); my $ssl_version = Net::SSLeay::get_version($ssl); my $is_ok = ($ctx eq $expected_ctx && $ssl_session eq Net::SSLeay::SSL_get0_session($ssl) && $round =~ m/^$ssl_version/); diag("server_new_cb params not ok: $round") unless $is_ok; set_server_stat($round, 'new_params_ok', $is_ok); if (defined &Net::SSLeay::SESSION_is_resumable) { my $is_resumable = Net::SSLeay::SESSION_is_resumable($ssl_session); BAIL_OUT("is_resumable is not 0 or 1: $round") unless defined $is_resumable && ($is_resumable == 0 || $is_resumable == 1); set_server_stat($round, 'new_session_is_resumable', $is_resumable); } #Net::SSLeay::SESSION_print_fp(*STDOUT, $ssl_session); return 0; } sub server_remove_cb { my ($ctx, $ssl_session, $expected_ctx, $round) = @_; $server_stats{$round}->{remove_cb_called}++; my $is_ok = ($ctx eq $expected_ctx); diag("server_remove_cb params not ok: $round") unless $is_ok; set_server_stat($round, 'remove_params_ok', $is_ok); return; } my ($server_ctx, $client_ctx, $server_ssl, $client_ssl); my $server = tcp_socket(); sub server { # SSL server - just handle connections, send information to # client and exit my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { my ($ctx, $ssl, $ret, $cl); foreach my $round (@rounds) { ( my $proto = $round ) =~ s/-.*?$//; next unless $usable{$proto}; $cl = $server->accept(); $ctx = new_ctx( $proto, $proto ); Net::SSLeay::CTX_set_security_level($ctx, 0) if Net::SSLeay::SSLeay() >= 0x30000000 && ($proto eq 'TLSv1' || $proto eq 'TLSv1.1'); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); Net::SSLeay::CTX_set_session_cache_mode($ctx, Net::SSLeay::SESS_CACHE_SERVER()); # Need OP_NO_TICKET to enable server side (Session ID based) resumption. # See also SSL_CTX_set_options documenation about its use with TLSv1.3 if ( $round !~ /^TLSv1\.3/ ) { my $ctx_options = Net::SSLeay::OP_ALL(); # OP_NO_TICKET requires OpenSSL 0.9.8f or above if ( eval { Net::SSLeay::OP_NO_TICKET(); 1; } ) { $ctx_options |= Net::SSLeay::OP_NO_TICKET(); } Net::SSLeay::CTX_set_options($ctx, $ctx_options); } Net::SSLeay::CTX_sess_set_new_cb($ctx, sub {server_new_cb(@_, $ctx, $round);}); Net::SSLeay::CTX_sess_set_remove_cb($ctx, sub {server_remove_cb(@_, $ctx, $round);}); # Test set_num_tickets separately for CTX and SSL if (defined &Net::SSLeay::CTX_set_num_tickets) { Net::SSLeay::CTX_set_num_tickets($ctx, 6) if ($round eq 'TLSv1.3-num-tickets-ctx-6'); Net::SSLeay::CTX_set_num_tickets($ctx, 0) if ($round eq 'TLSv1.3-num-tickets-ctx-0'); $server_stats{$round}->{get_num_tickets} = Net::SSLeay::CTX_get_num_tickets($ctx); } $ssl = Net::SSLeay::new($ctx); if (defined &Net::SSLeay::set_num_tickets) { Net::SSLeay::set_num_tickets($ssl, 4) if ($round eq 'TLSv1.3-num-tickets-ssl'); $server_stats{$round}->{get_num_tickets} = Net::SSLeay::get_num_tickets($ssl); } Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); Net::SSLeay::write($ssl, "msg from server: $round"); Net::SSLeay::read($ssl); Net::SSLeay::shutdown($ssl); my $sess = Net::SSLeay::get1_session($ssl); $ret = Net::SSLeay::CTX_remove_session($ctx, $sess); if (defined &Net::SSLeay::SESSION_is_resumable) { my $is_resumable = Net::SSLeay::SESSION_is_resumable($sess); BAIL_OUT("is_resumable is not 0 or 1: $round") unless defined $is_resumable && ($is_resumable == 0 || $is_resumable == 1); set_server_stat($round, 'old_session_is_resumable', $is_resumable); } Net::SSLeay::SESSION_free($sess) unless $ret; # Not cached, undo get1 Net::SSLeay::free($ssl); close($cl) || die("server close: $!"); } $cl = $server->accept(); print $cl "end\n"; print $cl unpack( 'H*', Storable::freeze(\%server_stats) ), "\n"; close($cl) || die("server close stats socket: $!"); $server->close() || die("server listen socket close: $!"); #use Data::Dumper; print "Server:\n" . Dumper(\%server_stats); exit(0); } } sub client { # SSL client - connect to server and receive information that we # compare to our expected values my ($ctx, $ssl, $ret, $cl); foreach my $round (@rounds) { ( my $proto = $round ) =~ s/-.*?$//; next unless $usable{$proto}; $cl = $server->connect(); $ctx = new_ctx( $proto, $proto ); Net::SSLeay::CTX_set_security_level($ctx, 0) if Net::SSLeay::SSLeay() >= 0x30000000 && ($proto eq 'TLSv1' || $proto eq 'TLSv1.1'); Net::SSLeay::CTX_set_session_cache_mode($ctx, Net::SSLeay::SESS_CACHE_CLIENT()); Net::SSLeay::CTX_set_options($ctx, Net::SSLeay::OP_ALL()); Net::SSLeay::CTX_sess_set_new_cb($ctx, sub {client_new_cb(@_, $ctx, $round);}); Net::SSLeay::CTX_sess_set_remove_cb($ctx, sub {client_remove_cb(@_, $ctx, $round);}); $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, $cl); my $ret = Net::SSLeay::connect($ssl); if ($ret <= 0) { diag("Protocol $proto, connect() returns $ret, Error: ".Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error())); } my $msg = Net::SSLeay::read($ssl); #print "server said: $msg\n"; Net::SSLeay::write($ssl, "continue"); my $sess = Net::SSLeay::get1_session($ssl); $ret = Net::SSLeay::CTX_remove_session($ctx, $sess); Net::SSLeay::SESSION_free($sess) unless $ret; # Not cached, undo get1 if (defined &Net::SSLeay::SESSION_is_resumable) { my $is_resumable = Net::SSLeay::SESSION_is_resumable($sess); BAIL_OUT("is_resumable is not 0 or 1: $round") unless defined $is_resumable && ($is_resumable == 0 || $is_resumable == 1); set_client_stat($round, 'old_session_is_resumable', $is_resumable); } Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); } $cl = $server->connect(); chomp( my $server_end = <$cl> ); is( $server_end, 'end', 'Successful termination' ); # Stats from server chomp( my $server_stats = <$cl> ); my $server_stats_ref = Storable::thaw( pack( 'H*', $server_stats ) ); close($cl) || die("client close stats socket: $!"); $server->close() || die("client listen socket close: $!"); test_stats($server_stats_ref, \%client_stats); return; } sub test_stats { my ($srv_stats, $clt_stats) = @_; for my $round (@rounds) { # The TLSv1.3-specific results will be checked separately later next if $round =~ /-/; if (!$usable{$round}) { SKIP: { skip( "$round not available in this libssl", 12 ); } next; } my $s = $srv_stats->{$round}; my $c = $clt_stats->{$round}; # With TLSv1.3, two session tickets are sent by default, so new_cb is # called twice; with all other protocol versions, new_cb is called once my $cbs = ( $round =~ /^TLSv1\.3/ ? 2 : 1 ); is( $s->{new_cb_called}, $cbs, "Server $round new_cb call count" ); is( $s->{new_params_ok}, 1, "Server $round new_cb params were correct" ); is( $s->{remove_cb_called}, 1, "Server $round remove_cb call count" ); is( $s->{remove_params_ok}, 1, "Server $round remove_cb params were correct" ); is( $c->{new_cb_called}, $cbs, "Client $round new_cb call count" ); is( $c->{new_params_ok}, 1, "Client $round new_cb params were correct" ); is( $c->{remove_cb_called}, 1, "Client $round remove_cb call count" ); is( $c->{remove_params_ok}, 1, "Client $round remove_cb params were correct" ); if ( defined &Net::SSLeay::SESSION_is_resumable || $round =~ /^TLSv1\.3/ ) { is( $s->{new_session_is_resumable}, 1, "Server $round session is resumable" ); is( $s->{old_session_is_resumable}, 0, "Server $round session is no longer resumable" ); is( $c->{new_session_is_resumable}, 1, "Client $round session is resumable" ); is( $c->{old_session_is_resumable}, 0, "Client $round session is no longer resumable" ); } else { SKIP: { skip( 'Do not have Net::SSLeay::SESSION_is_resumable', 4 ); } } } if ($usable{'TLSv1.3'}) { is( $srv_stats->{'TLSv1.3-num-tickets-ssl'}->{get_num_tickets}, 4, 'Server TLSv1.3 get_num_tickets 4' ); is( $srv_stats->{'TLSv1.3-num-tickets-ssl'}->{new_cb_called}, 4, 'Server TLSv1.3 new_cb call count with set_num_tickets 4' ); is( $clt_stats->{'TLSv1.3-num-tickets-ssl'}->{new_cb_called}, 4, 'Client TLSv1.3 new_cb call count with set_num_tickets 4' ); is( $srv_stats->{'TLSv1.3-num-tickets-ctx-6'}->{get_num_tickets}, 6, 'Server TLSv1.3 CTX_get_num_tickets 6' ); is( $srv_stats->{'TLSv1.3-num-tickets-ctx-6'}->{new_cb_called}, 6, 'Server TLSv1.3 new_cb call count with CTX_set_num_tickets 6' ); is( $clt_stats->{'TLSv1.3-num-tickets-ctx-6'}->{new_cb_called}, 6, 'Client TLSv1.3 new_cb call count with CTX_set_num_tickets 6' ); is( $srv_stats->{'TLSv1.3-num-tickets-ctx-0'}->{get_num_tickets}, 0, 'Server TLSv1.3 CTX_get_num_tickets 0' ); is( $srv_stats->{'TLSv1.3-num-tickets-ctx-0'}->{new_cb_called}, undef, 'Server TLSv1.3 new_cb call count with CTX_set_num_tickets 0' ); is( $clt_stats->{'TLSv1.3-num-tickets-ctx-0'}->{new_cb_called}, undef, 'Client TLSv1.3 new_cb call count with CTX_set_num_tickets 0' ); } else { SKIP: { skip( 'TLSv1.3 not available in this libssl', 9 ); } } # use Data::Dumper; print "Server:\n" . Dumper(\%srv_stats); # use Data::Dumper; print "Client:\n" . Dumper(\%clt_stats); } server(); client(); waitpid $pid, 0; exit(0); Net-SSLeay-1.92/t/local/36_verify.t0000644000175000001440000004111114140310470015361 0ustar csnusers# Test various verify and ASN functions use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl is_libressl is_openssl new_ctx tcp_socket ); plan tests => 105; initialise_libssl(); my $root_ca_pem = data_file_path('root-ca.cert.pem'); my $ca_pem = data_file_path('verify-ca.certchain.pem'); my $ca_dir = ''; my $cert_pem = data_file_path('verify-cert.cert.pem'); my $certchain_pem = data_file_path('verify-cert.certchain.pem'); my $key_pem = data_file_path('verify-cert.key.pem'); # The above certificate must specify the following policy OID: my $required_oid = '1.2.3.4.5'; my $pm; my $pm2; my $verify_result = -1; SKIP: { skip 'openssl-0.9.8 required', 7 unless Net::SSLeay::SSLeay >= 0x0090800f; $pm = Net::SSLeay::X509_VERIFY_PARAM_new(); ok($pm, 'X509_VERIFY_PARAM_new'); $pm2 = Net::SSLeay::X509_VERIFY_PARAM_new(); ok($pm2, 'X509_VERIFY_PARAM_new 2'); ok(Net::SSLeay::X509_VERIFY_PARAM_inherit($pm2, $pm), 'X509_VERIFY_PARAM_inherit'); ok(Net::SSLeay::X509_VERIFY_PARAM_set1($pm2, $pm), 'X509_VERIFY_PARAM_inherit'); ok(Net::SSLeay::X509_VERIFY_PARAM_set1_name($pm, 'fred'), 'X509_VERIFY_PARAM_set1_name'); ok(Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS() == 0x40, 'X509_V_FLAG_ALLOW_PROXY_CERTS'); ok(Net::SSLeay::X509_VERIFY_PARAM_set_flags($pm, Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS()), 'X509_VERIFY_PARAM_set_flags'); } SKIP: { skip 'openssl-0.9.8a required', 3 unless Net::SSLeay::SSLeay >= 0x0090801f; # Between versions 3.2.4 and 3.4.0, LibreSSL signals the use of its legacy # X.509 verifier via the X509_V_FLAG_LEGACY_VERIFY flag; this flag persists # even after X509_VERIFY_PARAM_clear_flags() is called my $base_flags = is_libressl() && Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") >= 0x3020400f && Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") <= 0x3040000f ? Net::SSLeay::X509_V_FLAG_LEGACY_VERIFY() : 0; ok(Net::SSLeay::X509_VERIFY_PARAM_get_flags($pm) == ($base_flags | Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS()), 'X509_VERIFY_PARAM_get_flags'); ok(Net::SSLeay::X509_VERIFY_PARAM_clear_flags($pm, Net::SSLeay::X509_V_FLAG_ALLOW_PROXY_CERTS()), 'X509_VERIFY_PARAM_clear_flags'); ok(Net::SSLeay::X509_VERIFY_PARAM_get_flags($pm) == ($base_flags | 0), 'X509_VERIFY_PARAM_get_flags'); }; SKIP: { skip 'openssl-0.9.8 required', 4 unless Net::SSLeay::SSLeay >= 0x0090800f; ok(Net::SSLeay::X509_PURPOSE_SSL_CLIENT() == 1, 'X509_PURPOSE_SSL_CLIENT'); ok(Net::SSLeay::X509_VERIFY_PARAM_set_purpose($pm, Net::SSLeay::X509_PURPOSE_SSL_CLIENT()), 'X509_VERIFY_PARAM_set_purpose'); ok(Net::SSLeay::X509_TRUST_EMAIL() == 4, 'X509_TRUST_EMAIL'); ok(Net::SSLeay::X509_VERIFY_PARAM_set_trust($pm, Net::SSLeay::X509_TRUST_EMAIL()), 'X509_VERIFY_PARAM_set_trust'); Net::SSLeay::X509_VERIFY_PARAM_set_depth($pm, 5); Net::SSLeay::X509_VERIFY_PARAM_set_time($pm, time); Net::SSLeay::X509_VERIFY_PARAM_free($pm); Net::SSLeay::X509_VERIFY_PARAM_free($pm2); } # Test ASN1 objects my $asn_object = Net::SSLeay::OBJ_txt2obj('1.2.3.4', 0); ok($asn_object, 'OBJ_txt2obj'); ok(Net::SSLeay::OBJ_obj2txt($asn_object, 0) eq '1.2.3.4', 'OBJ_obj2txt'); ok(Net::SSLeay::OBJ_txt2nid('1.2.840.113549.1') == 2, 'OBJ_txt2nid'); # NID_pkcs ok(Net::SSLeay::OBJ_txt2nid('1.2.840.113549.2.5') == 4, 'OBJ_txt2nid'); # NID_md5 ok(Net::SSLeay::OBJ_ln2nid('RSA Data Security, Inc. PKCS') == 2, 'OBJ_ln2nid'); # NID_pkcs ok(Net::SSLeay::OBJ_ln2nid('md5') == 4, 'OBJ_ln2nid'); # NID_md5 ok(Net::SSLeay::OBJ_sn2nid('pkcs') == 2, 'OBJ_sn2nid'); # NID_pkcs ok(Net::SSLeay::OBJ_sn2nid('MD5') == 4, 'OBJ_sn2nid'); # NID_md5 my $asn_object2 = Net::SSLeay::OBJ_txt2obj('1.2.3.4', 0); ok(Net::SSLeay::OBJ_cmp($asn_object2, $asn_object) == 0, 'OBJ_cmp'); $asn_object2 = Net::SSLeay::OBJ_txt2obj('1.2.3.5', 0); ok(Net::SSLeay::OBJ_cmp($asn_object2, $asn_object) != 0, 'OBJ_cmp'); ok(1, "Finished with tests that don't need fork"); my $server; SKIP: { if (not can_fork()) { skip "fork() not supported on this system", 54; } $server = tcp_socket(); run_server(); # Forks: child does not return $server->close() || die("client listen socket close: $!"); client(); } verify_local_trust(); sub test_policy_checks { my ($ctx, $cl, $ok) = @_; $pm = Net::SSLeay::X509_VERIFY_PARAM_new(); # Certificate must have this policy Net::SSLeay::X509_VERIFY_PARAM_set_flags($pm, Net::SSLeay::X509_V_FLAG_POLICY_CHECK() | Net::SSLeay::X509_V_FLAG_EXPLICIT_POLICY()); my $oid = $ok ? $required_oid : ( $required_oid . '.1' ); my $pobject = Net::SSLeay::OBJ_txt2obj($oid, 1); ok($pobject, "OBJ_txt2obj($oid)"); is(Net::SSLeay::X509_VERIFY_PARAM_add0_policy($pm, $pobject), 1, "X509_VERIFY_PARAM_add0_policy($oid)"); my $ssl = client_get_ssl($ctx, $cl, $pm); my $ret = Net::SSLeay::connect($ssl); is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal'); if ($ok) { is($ret, 1, 'connect ok: policy checks succeeded'); is($verify_result, Net::SSLeay::X509_V_OK(), 'Verify result is X509_V_OK'); print "connect failed: $ret: " . Net::SSLeay::print_errs() . "\n" unless $ret == 1; } else { isnt($ret, 1, 'connect not ok: policy checks must fail') if !$ok; is($verify_result, Net::SSLeay::X509_V_ERR_NO_EXPLICIT_POLICY(), 'Verify result is X509_V_ERR_NO_EXPLICIT_POLICY'); } Net::SSLeay::X509_VERIFY_PARAM_free($pm); } # These need at least OpenSSL 1.0.2 or LibreSSL 2.7.0 sub test_hostname_checks { my ($ctx, $cl, $ok) = @_; SKIP: { skip 'No Net::SSLeay::X509_VERIFY_PARAM_set1_host, skipping hostname_checks', 13 unless (exists &Net::SSLeay::X509_VERIFY_PARAM_set1_host); $pm = Net::SSLeay::X509_VERIFY_PARAM_new(); # Note: wildcards are supported by default is(Net::SSLeay::X509_VERIFY_PARAM_set1_host($pm, 'test.johndoe.net-ssleay.example'), 1, 'X509_VERIFY_PARAM_set1_host(test.johndoe.net-ssleay.example)') if $ok; is(Net::SSLeay::X509_VERIFY_PARAM_add1_host($pm, 'invalid.net-ssleay.example'), 1, 'X509_VERIFY_PARAM_add1_host(invalid.net-ssleay.example)') if !$ok; is(Net::SSLeay::X509_VERIFY_PARAM_set1_email($pm, 'john.doe@net-ssleay.example'), 1, 'X509_VERIFY_PARAM_set1_email(john.doe@net-ssleay.example)'); # Note: 'set' means that only one successfully set can be active # set1_ip: IPv4 or IPv6 address as 4 or 16 octet binary. # setip_ip_asc: IPv4 or IPv6 address as ASCII string is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, pack('CCCC', 192, 168, 0, 3)), 1, 'X509_VERIFY_PARAM_set1_ip(192.168.0.3)'); # is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, pack('NNNN', hex('20010db8'), hex('01480100'), 0, hex('31'))), 1, 'X509_VERIFY_PARAM_set1_ip(2001:db8:148:100::31)'); # is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '10.20.30.40'), 1, 'X509_VERIFY_PARAM_set1_ip_asc(10.20.30.40)'); # is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '2001:db8:148:100::31'), 1, 'X509_VERIFY_PARAM_set1_ip_asc(2001:db8:148:100::31))'); # Also see that incorrect values do not change anything. is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, '123'), 0, 'X509_VERIFY_PARAM_set1_ip(123)'); is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip($pm, '123456789012345'), 0, 'X509_VERIFY_PARAM_set1_ip(123456789012345)'); is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '10.20.30.256'), 0, 'X509_VERIFY_PARAM_set1_ip_asc(10.20.30.256)'); is(Net::SSLeay::X509_VERIFY_PARAM_set1_ip_asc($pm, '12345::'), 0, 'X509_VERIFY_PARAM_set1_ip_asc(12345::)'); my $ssl = client_get_ssl($ctx, $cl, $pm); my $ret = Net::SSLeay::connect($ssl); is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal'); if ($ok) { is($ret, 1, 'connect ok: hostname checks succeeded'); is($verify_result, Net::SSLeay::X509_V_OK(), 'Verify result is X509_V_OK'); print "connect failed: $ret: " . Net::SSLeay::print_errs() . "\n" unless $ret == 1; } else { isnt($ret, 1, 'connect not ok: hostname checks must fail') if !$ok; is($verify_result, Net::SSLeay::X509_V_ERR_HOSTNAME_MISMATCH(), 'Verify result is X509_V_ERR_HOSTNAME_MISMATCH'); } # For some reason OpenSSL 1.0.2 and LibreSSL return undef for get0_peername. Are we doing this wrong? $pm2 = Net::SSLeay::get0_param($ssl); my $peername = Net::SSLeay::X509_VERIFY_PARAM_get0_peername($pm2); if ($ok) { is($peername, '*.johndoe.net-ssleay.example', 'X509_VERIFY_PARAM_get0_peername returns *.johndoe.net-ssleay.example') if (Net::SSLeay::SSLeay >= 0x10100000 && is_openssl()); is($peername, undef, 'X509_VERIFY_PARAM_get0_peername returns undefined for OpenSSL 1.0.2 and LibreSSL') if (Net::SSLeay::SSLeay < 0x10100000 || is_libressl()); } else { is($peername, undef, 'X509_VERIFY_PARAM_get0_peername returns undefined'); } Net::SSLeay::X509_VERIFY_PARAM_free($pm); Net::SSLeay::X509_VERIFY_PARAM_free($pm2); } } sub test_wildcard_checks { my ($ctx, $cl) = @_; SKIP: { skip 'No Net::SSLeay::X509_VERIFY_PARAM_set1_host, skipping wildcard_checks', 7 unless (exists &Net::SSLeay::X509_VERIFY_PARAM_set1_host); $pm = Net::SSLeay::X509_VERIFY_PARAM_new(); # Wildcards are allowed by default: disallow is(Net::SSLeay::X509_VERIFY_PARAM_set1_host($pm, 'test.johndoe.net-ssleay.example'), 1, 'X509_VERIFY_PARAM_set1_host'); is(Net::SSLeay::X509_VERIFY_PARAM_set_hostflags($pm, Net::SSLeay::X509_CHECK_FLAG_NO_WILDCARDS()), undef, 'X509_VERIFY_PARAM_set_hostflags(X509_CHECK_FLAG_NO_WILDCARDS)'); my $ssl = client_get_ssl($ctx, $cl, $pm); my $ret = Net::SSLeay::connect($ssl); isnt($ret, 1, 'Connect must fail in wildcard test'); is($verify_result, Net::SSLeay::get_verify_result($ssl), 'Verify callback result and get_verify_result are equal'); is($verify_result, Net::SSLeay::X509_V_ERR_HOSTNAME_MISMATCH(), 'Verify result is X509_V_ERR_HOSTNAME_MISMATCH'); Net::SSLeay::X509_VERIFY_PARAM_free($pm); } } sub verify_local_trust { # Read entire certificate chain my $bio = Net::SSLeay::BIO_new_file($certchain_pem, 'r'); ok(my $x509_info_sk = Net::SSLeay::PEM_X509_INFO_read_bio($bio), "PEM_X509_INFO_read_bio able to read in entire chain"); Net::SSLeay::BIO_free($bio); # Read just the leaf certificate from the chain $bio = Net::SSLeay::BIO_new_file($certchain_pem, 'r'); ok(my $cert = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509 able to read in single cert from chain"); Net::SSLeay::BIO_free($bio); # Read root CA certificate $bio = Net::SSLeay::BIO_new_file($root_ca_pem, 'r'); ok(my $ca = Net::SSLeay::PEM_read_bio_X509($bio), "PEM_read_bio_X509 able to read in root CA"); Net::SSLeay::BIO_free($bio); ok(my $x509_sk = Net::SSLeay::sk_X509_new_null(), "sk_X509_new_null creates STACK_OF(X509) successfully"); ok(my $num = Net::SSLeay::sk_X509_INFO_num($x509_info_sk), "sk_X509_INFO_num is nonzero"); # Set up STORE_CTX and verify leaf certificate using only root CA (should fail due to incomplete chain) ok(my $store = Net::SSLeay::X509_STORE_new(), "X509_STORE_new creates new store"); ok(Net::SSLeay::X509_STORE_add_cert($store, $ca), "X509_STORE_add_cert CA cert"); ok(my $ctx = Net::SSLeay::X509_STORE_CTX_new(), "X509_STORE_CTX_new creates new store context"); is(Net::SSLeay::X509_STORE_CTX_init($ctx, $store, $cert), 1, 'X509_STORE_CTX_init succeeds'); ok(!Net::SSLeay::X509_verify_cert($ctx), 'X509_verify_cert correctly fails'); is(Net::SSLeay::X509_STORE_CTX_get_error($ctx), Net::SSLeay::X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY(), "X509_STORE_CTX_get_error returns unable to get local issuer certificate"); Net::SSLeay::X509_STORE_free($store); Net::SSLeay::X509_STORE_CTX_free($ctx); # Add all certificates from entire certificate chain to X509 stack for (my $i = 0; $i < $num; $i++) { ok(my $x509_info = Net::SSLeay::sk_X509_INFO_value($x509_info_sk, $i), "sk_X509_INFO_value"); ok(my $x509 = Net::SSLeay::P_X509_INFO_get_x509($x509_info), "P_X509_INFO_get_x509"); ok(Net::SSLeay::sk_X509_push($x509_sk, $x509), "sk_X509_push"); } # set up STORE_CTX and verify leaf certificate using root CA and chain (should succeed) ok($store = Net::SSLeay::X509_STORE_new(), "X509_STORE_new creates new store"); ok(Net::SSLeay::X509_STORE_add_cert($store, $ca), "X509_STORE_add_cert CA cert"); ok($ctx = Net::SSLeay::X509_STORE_CTX_new(), "X509_STORE_CTX_new creates new store context"); is(Net::SSLeay::X509_STORE_CTX_init($ctx, $store, $cert, $x509_sk), 1, 'X509_STORE_CTX_init succeeds'); ok(Net::SSLeay::X509_verify_cert($ctx), 'X509_verify_cert correctly succeeds'); is(Net::SSLeay::X509_STORE_CTX_get_error($ctx), Net::SSLeay::X509_V_OK(), "X509_STORE_CTX_get_error returns ok"); Net::SSLeay::X509_STORE_free($store); Net::SSLeay::X509_STORE_CTX_free($ctx); Net::SSLeay::sk_X509_free($x509_sk); } # Prepare and return a new $ssl based on callers verification needs # Note that this adds tests to caller's test count. sub client_get_ssl { my ($ctx, $cl, $pm) = @_; my $store = Net::SSLeay::CTX_get_cert_store($ctx); ok($store, 'CTX_get_cert_store'); is(Net::SSLeay::X509_STORE_set1_param($store, $pm), 1, 'X509_STORE_set1_param'); # Needs OpenSSL 1.0.0 or later #Net::SSLeay::CTX_set1_param($ctx, $pm); $verify_result = -1; # Last verification result, set by callback below my $verify_cb = sub { $verify_result = Net::SSLeay::X509_STORE_CTX_get_error($_[1]); return $_[0];}; my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_verify($ssl, Net::SSLeay::VERIFY_PEER(), $verify_cb); Net::SSLeay::set_fd($ssl, $cl); return $ssl; } # SSL client - connect to server and test different verification # settings sub client { my ($ctx, $cl); foreach my $task (qw( policy_checks_ok policy_checks_fail hostname_checks_ok hostname_checks_fail wildcard_checks finish)) { $ctx = new_ctx(); is(Net::SSLeay::CTX_load_verify_locations($ctx, $ca_pem, $ca_dir), 1, "load_verify_locations($ca_pem $ca_dir)"); $cl = $server->connect(); test_policy_checks($ctx, $cl, 1) if $task eq 'policy_checks_ok'; test_policy_checks($ctx, $cl, 0) if $task eq 'policy_checks_fail'; test_hostname_checks($ctx, $cl, 1) if $task eq 'hostname_checks_ok'; test_hostname_checks($ctx, $cl, 0) if $task eq 'hostname_checks_fail'; test_wildcard_checks($ctx, $cl) if $task eq 'wildcard_checks'; last if $task eq 'finish'; # Leaves $cl alive close($cl) || die("client close: $!"); } # Tell the server to quit and see that our connection is still up $ctx = new_ctx(); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, $cl); Net::SSLeay::connect($ssl); my $end = "end"; Net::SSLeay::ssl_write_all($ssl, $end); Net::SSLeay::shutdown($ssl); ok($end eq Net::SSLeay::ssl_read_all($ssl), 'Successful termination'); Net::SSLeay::free($ssl); close($cl) || die("client final close: $!"); return; } # SSL server - just accept connnections and exit when told to by # the client sub run_server { my $pid; defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); return if $pid != 0; $SIG{'PIPE'} = 'IGNORE'; my $ctx = new_ctx(); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); my $ret = Net::SSLeay::CTX_check_private_key($ctx); BAIL_OUT("Server: CTX_check_private_key failed: $cert_pem, $key_pem") unless $ret == 1; if (defined &Net::SSLeay::CTX_set_num_tickets) { # TLS 1.3 server sends session tickets after a handhake as part of # the SSL_accept(). If a client finishes all its job including closing # TCP connectino before a server sends the tickets, SSL_accept() fails # with SSL_ERROR_SYSCALL and EPIPE errno and the server receives # SIGPIPE signal. my $ret = Net::SSLeay::CTX_set_num_tickets($ctx, 0); BAIL_OUT("Session tickets disabled") unless $ret; } while (1) { my $cl = $server->accept() or BAIL_OUT("accept failed: $!"); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); my $ret = Net::SSLeay::accept($ssl); next unless $ret == 1; # Termination request or other message from client my $msg = Net::SSLeay::ssl_read_all($ssl); if (defined $msg and $msg eq 'end') { Net::SSLeay::ssl_write_all($ssl, 'end'); Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("server close: $!"); $server->close() || die("server listen socket close: $!"); exit (0); } } } Net-SSLeay-1.92/t/local/22_provider_try_load_zero_retain.t0000644000175000001440000000212514163136013022206 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay (initialise_libssl); # Avoid default provider automatic loading. See 22_provider.t for more # information. # #initialise_libssl(); # Don't do this # # We use a separate test file so that we get a newly loaded library # that still has triggers for automatic loading enabled. if (defined &Net::SSLeay::OSSL_PROVIDER_load) { plan(tests => 3); } else { plan(skip_all => "no support for providers"); } # Supplied OpenSSL configuration file may load unwanted providers. local $ENV{OPENSSL_CONF} = ''; my ($null_provider, $default_avail, $null_avail); $null_provider = Net::SSLeay::OSSL_PROVIDER_try_load(undef, 'null', 0); ok($null_provider, 'try_load("null", retain_fallbacks = 0) returns a pointer'); $default_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'default'); is($default_avail, 0, 'default provider not automatically loaded after try_load("null", retain_fallbacks = 0)'); $null_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'null'); is($null_avail, 1, 'null provider loaded after try_load("null", retain_fallbacks = 0)'); Net-SSLeay-1.92/t/local/05_passwd_cb.t0000644000175000001440000001270513755162614016045 0ustar csnusers# Test password entry callback functionality use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl ); plan tests => 36; initialise_libssl(); my $key_pem = data_file_path('simple-cert.key.enc.pem'); my $key_password = 'test'; my $cb_1_calls = 0; my $cb_2_calls = 0; my $cb_3_calls = 0; my $cb_4_calls = 0; my $cb_bad_calls = 0; sub callback1 { my ($rwflag, $userdata) = @_; $cb_1_calls++; is ($rwflag, 0, 'rwflag is set correctly'); is( $$userdata, $key_password, 'received userdata properly' ); return $$userdata; } sub callback2 { my ($rwflag, $userdata) = @_; $cb_2_calls++; is( $$userdata, $key_password, 'received userdata properly' ); return $$userdata; } sub callback3 { my ($rwflag, $userdata) = @_; $cb_3_calls++; is( $userdata, undef, 'received no userdata' ); return $key_password; } sub callback_bad { my ($rwflag, $userdata) = @_; $cb_bad_calls++; is( $userdata, $key_password, 'received userdata properly' ); return $key_password . 'incorrect'; # Return incorrect password } my $ctx_1 = Net::SSLeay::CTX_new(); ok($ctx_1, 'CTX_new 1'); my $ctx_2 = Net::SSLeay::CTX_new(); ok($ctx_2, 'CTX_new 2'); my $ctx_3 = Net::SSLeay::CTX_new(); ok($ctx_3, 'CTX_new 3'); my $ctx_4 = Net::SSLeay::CTX_new(); ok($ctx_4, 'CTX_new 4'); Net::SSLeay::CTX_set_default_passwd_cb($ctx_1, \&callback1); Net::SSLeay::CTX_set_default_passwd_cb_userdata($ctx_1, \$key_password); Net::SSLeay::CTX_set_default_passwd_cb($ctx_2, \&callback2); Net::SSLeay::CTX_set_default_passwd_cb_userdata($ctx_2, \$key_password); Net::SSLeay::CTX_set_default_passwd_cb($ctx_3, \&callback3); ok( Net::SSLeay::CTX_use_PrivateKey_file($ctx_1, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'CTX_use_PrivateKey_file works with right passphrase and userdata' ); ok( Net::SSLeay::CTX_use_PrivateKey_file($ctx_2, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'CTX_use_PrivateKey_file works with right passphrase and userdata' ); ok( Net::SSLeay::CTX_use_PrivateKey_file($ctx_3, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'CTX_use_PrivateKey_file works with right passphrase and without userdata' ); Net::SSLeay::CTX_set_default_passwd_cb($ctx_4, sub { $cb_4_calls++; return $key_password; }); ok( Net::SSLeay::CTX_use_PrivateKey_file($ctx_4, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'CTX_use_PrivateKey_file works when callback data is unset' ); ok( $cb_1_calls == 1 && $cb_2_calls == 1 && $cb_3_calls == 1 && $cb_4_calls == 1, 'different cbs per ctx work' ); $key_password = 'incorrect'; ok( !Net::SSLeay::CTX_use_PrivateKey_file($ctx_1, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'CTX_use_PrivateKey_file doesn\'t work with wrong passphrase' ); is($cb_1_calls, 2, 'callback1 called 2 times'); # OpenSSL 1.1.0 has SSL_set_default_passwd_cb, but the callback is not # called for SSL before OpenSSL 1.1.0f if (exists &Net::SSLeay::set_default_passwd_cb) { test_ssl_funcs(); } else { SKIP: { skip('Do not have Net::SSLeay::set_default_passwd_cb', 19); }; } exit(0); sub test_ssl_funcs { my $ctx_1 = Net::SSLeay::CTX_new(); my $ssl_1 = Net::SSLeay::new($ctx_1); ok($ssl_1, 'SSL_new 1'); my $ctx_2 = Net::SSLeay::CTX_new(); my $ssl_2 = Net::SSLeay::new($ctx_2); ok($ssl_2, 'SSL_new 2'); my $ctx_3 = Net::SSLeay::CTX_new(); my $ssl_3 = Net::SSLeay::new($ctx_3); ok($ssl_3, 'SSL_new 3'); my $ctx_4 = Net::SSLeay::CTX_new(); my $ssl_4 = Net::SSLeay::new($ctx_4); ok($ssl_4, 'SSL_new 4'); $cb_1_calls = $cb_2_calls = $cb_3_calls = $cb_4_calls = $cb_bad_calls = 0; $key_password = 'test'; Net::SSLeay::set_default_passwd_cb($ssl_1, \&callback1); Net::SSLeay::set_default_passwd_cb_userdata($ssl_1, \$key_password); Net::SSLeay::set_default_passwd_cb($ssl_2, \&callback2); Net::SSLeay::set_default_passwd_cb_userdata($ssl_2, \$key_password); Net::SSLeay::set_default_passwd_cb($ssl_3, \&callback3); ok( Net::SSLeay::use_PrivateKey_file($ssl_1, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file works with right passphrase and userdata' ); ok( Net::SSLeay::use_PrivateKey_file($ssl_2, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file works with right passphrase and userdata' ); # Setting the callback for CTX should not change anything Net::SSLeay::CTX_set_default_passwd_cb($ctx_2, \&callback_bad); Net::SSLeay::CTX_set_default_passwd_cb_userdata($ctx_2, \$key_password); ok( Net::SSLeay::use_PrivateKey_file($ssl_2, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file works with right passphrase and userdata after bad passphrase set for CTX' ); ok( Net::SSLeay::use_PrivateKey_file($ssl_3, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file works with right passphrase and without userdata' ); Net::SSLeay::set_default_passwd_cb($ssl_4, sub { $cb_4_calls++; return $key_password; }); ok( Net::SSLeay::use_PrivateKey_file($ssl_4, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file works when callback data is unset' ); ok( $cb_1_calls == 1 && $cb_2_calls == 2 && $cb_3_calls == 1 && $cb_4_calls == 1 && $cb_bad_calls == 0, 'different cbs per ssl work' ); $key_password = 'incorrect'; ok( !Net::SSLeay::use_PrivateKey_file($ssl_1, $key_pem, &Net::SSLeay::FILETYPE_PEM), 'use_PrivateKey_file doesn\'t work with wrong passphrase' ); is($cb_1_calls, 2, 'callback1 called 2 times'); } Net-SSLeay-1.92/t/local/66_curves.t0000644000175000001440000001216013765145713015413 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( data_file_path initialise_libssl ); initialise_libssl(); my @set_list = ( defined &Net::SSLeay::CTX_set1_groups_list ? (\&Net::SSLeay::CTX_set1_groups_list) : (), defined &Net::SSLeay::CTX_set1_curves_list ? (\&Net::SSLeay::CTX_set1_curves_list) : (), ); if (!@set_list) { plan skip_all => "no support for CTX_set_curves_list"; } else { plan tests => 4 * @set_list; } # for debugging only my $DEBUG = 0; my $PCAP = 0; require Net::PcapWriter if $PCAP; my $SSL_ERROR; # set in _minSSL my %TRANSFER; # set in _handshake my $client = _minSSL->new(); my $server = _minSSL->new( cert => [ data_file_path('simple-cert.cert.pem'), data_file_path('simple-cert.key.pem'), ]); my $set_curves; while ($set_curves = shift @set_list) { ok(_handshake($client,$server,'P-521:P-384','P-521',1), 'first curve'); ok(_handshake($client,$server,'P-521:P-384','P-384',1), 'second curve'); ok(_handshake($client,$server,'P-521:P-384','P-256',0), 'wrong curve failed'); ok(_handshake($client,$server,'P-521:P-384','P-384:P-521',1), 'both curve'); } my $i; sub _handshake { my ($client,$server,$server_curve,$client_curve,$expect_ok) = @_; $client->state_connect($client_curve); $server->state_accept($server_curve); my $pcap = $PCAP && do { my $fname = 'test'.(++$i).'.pcap'; open(my $fh,'>',$fname); diag("pcap in $fname"); $fh->autoflush; Net::PcapWriter->new($fh)->tcp_conn('1.1.1.1',1000,'2.2.2.2',443); }; my ($client_done,$server_done,@hs); %TRANSFER = (); for(my $tries = 0; $tries < 10 and !$client_done || !$server_done; $tries++ ) { $client_done ||= $client->handshake || 0; $server_done ||= $server->handshake || 0; my $transfer = 0; if (defined(my $data = $client->bio_read())) { $pcap && $pcap->write(0,$data); $DEBUG && warn "client -> server: ".length($data)." bytes\n"; $server->bio_write($data); push @hs,'>'; $TRANSFER{client} += length($data); $transfer++; } if (defined(my $data = $server->bio_read())) { $pcap && $pcap->write(1,$data); $DEBUG && warn "server -> client: ".length($data)." bytes\n"; $client->bio_write($data); # assume certificate was sent if length>700 push @hs, length($data) > 700 ? '<[C]':'<'; $TRANSFER{server} += length($data); $transfer++; } if (!$transfer) { # no more data to transfer - assume we are done $client_done = $server_done = 1; } } my $result = "$client_done - $server_done - @hs"; return $result eq '1 - 1 - > <[C] > <' if $expect_ok; return 1 if $result eq '1 - 1 - > <'; # failed connect with OpenSSL >= 1.1.0 return 1 if $result =~ qr{^\Q0 - 0 - > < < <}; # OpenSSL 1.0.2, LibreSSL return 0; # unexpected result } { package _minSSL; use Test::Net::SSLeay qw(new_ctx); sub new { my ($class,%args) = @_; my $ctx = new_ctx(); Net::SSLeay::CTX_set_options($ctx,Net::SSLeay::OP_ALL()); Net::SSLeay::CTX_set_cipher_list($ctx,'ECDHE'); Net::SSLeay::CTX_set_ecdh_auto($ctx,1) if defined &Net::SSLeay::CTX_set_ecdh_auto; my $id = 'client'; if ($args{cert}) { my ($cert,$key) = @{ delete $args{cert} }; Net::SSLeay::set_cert_and_key($ctx, $cert, $key) || die "failed to use cert file $cert,$key"; $id = 'server'; } my $self = bless { id => $id, ctx => $ctx }, $class; return $self; } sub state_accept { my ($self,$curve) = @_; _reset($self,$curve); Net::SSLeay::set_accept_state($self->{ssl}); } sub state_connect { my ($self,$curve) = @_; _reset($self,$curve); Net::SSLeay::set_connect_state($self->{ssl}); } sub handshake { my $self = shift; my $rv = Net::SSLeay::do_handshake($self->{ssl}); $rv = _error($self,$rv); return $rv; } sub ssl_read { my ($self) = @_; my ($data,$rv) = Net::SSLeay::read($self->{ssl}); return _error($self,$rv || -1) if !$rv || $rv<0; return $data; } sub bio_write { my ($self,$data) = @_; defined $data and $data ne '' or return; Net::SSLeay::BIO_write($self->{rbio},$data); } sub ssl_write { my ($self,$data) = @_; my $rv = Net::SSLeay::write($self->{ssl},$data); return _error($self,$rv || -1) if !$rv || $rv<0; return $rv; } sub bio_read { my ($self) = @_; return Net::SSLeay::BIO_read($self->{wbio}); } sub _ssl { shift->{ssl} } sub _ctx { shift->{ctx} } sub _reset { my ($self,$curve) = @_; $set_curves->($self->{ctx},$curve) if $curve; my $ssl = Net::SSLeay::new($self->{ctx}); my @bio = ( Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()), Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()), ); Net::SSLeay::set_bio($ssl,$bio[0],$bio[1]); $self->{ssl} = $ssl; $self->{rbio} = $bio[0]; $self->{wbio} = $bio[1]; } sub _error { my ($self,$rv) = @_; if ($rv>0) { $SSL_ERROR = undef; return $rv; } my $err = Net::SSLeay::get_error($self->{ssl},$rv); if ($err == Net::SSLeay::ERROR_WANT_READ() || $err == Net::SSLeay::ERROR_WANT_WRITE()) { $SSL_ERROR = $err; $DEBUG && warn "[$self->{id}] rw:$err\n"; return; } $DEBUG && warn "[$self->{id}] ".Net::SSLeay::ERR_error_string($err)."\n"; return; } } Net-SSLeay-1.92/t/local/22_provider_try_load.t0000644000175000001440000000212114163136013017601 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay (initialise_libssl); # Avoid default provider automatic loading. See 22_provider.t for more # information. # #initialise_libssl(); # Don't do this # # We use a separate test file so that we get a newly loaded library # that still has triggers for automatic loading enabled. if (defined &Net::SSLeay::OSSL_PROVIDER_load) { plan(tests => 3); } else { plan(skip_all => "no support for providers"); } # Supplied OpenSSL configuration file may load unwanted providers. local $ENV{OPENSSL_CONF} = ''; my ($null_provider, $default_avail, $null_avail); $null_provider = Net::SSLeay::OSSL_PROVIDER_try_load(undef, 'null', 1); ok($null_provider, 'try_load("null", retain_fallbacks = 1) returns a pointer'); $default_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'default'); is($default_avail, 1, 'default provider automatically loaded after try_load("null", retain_fallbacks = 1)'); $null_avail = Net::SSLeay::OSSL_PROVIDER_available(undef, 'null'); is($null_avail, 1, 'null provider loaded after try_load("null", retain_fallbacks = 1)'); Net-SSLeay-1.92/t/local/30_error.t0000644000175000001440000001030614135367260015217 0ustar csnusersuse lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( dies_like doesnt_warn initialise_libssl lives_ok warns_like ); plan tests => 11; doesnt_warn('tests run without outputting unexpected warnings'); initialise_libssl(); # See below near 'sub put_err' for more about how error string and # erro code contents have changed between library versions. my $err_string = "foo $$: 1 - error:10000080:BIO routines:"; $err_string = "foo $$: 1 - error:20000080:BIO routines:" if Net::SSLeay::SSLeay_version(Net::SSLeay::SSLEAY_VERSION()) =~ m/^OpenSSL 3.0.0-alpha[1-4] /s; $err_string = "foo $$: 1 - error:2006D080:BIO routines:" if (Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") || Net::SSLeay::constant("OPENSSL_VERSION_NUMBER") < 0x30000000); # Note, die_now usually just prints the process id and the argument string eg: # 57611: test # but on some systems, perhaps if diagnostics are enabled, it might [roduce something like: # found: Uncaught exception from user code: # 57611: test # therefore the qr match strings below have been chnaged so they dont have tooccur at the # beginning of the line. { dies_like(sub { Net::SSLeay::die_now('test') }, qr/$$: test\n$/, 'die_now dies without errors'); lives_ok(sub { Net::SSLeay::die_if_ssl_error('test'); }, 'die_if_ssl_error lives without errors'); put_err(); dies_like(sub { Net::SSLeay::die_now('test'); }, qr/$$: test\n$/, 'die_now dies with errors'); put_err(); dies_like(sub { Net::SSLeay::die_if_ssl_error('test'); }, qr/$$: test\n$/, 'die_if_ssl_error dies with errors'); } { local $Net::SSLeay::trace = 1; dies_like(sub { Net::SSLeay::die_now('foo'); }, qr/$$: foo\n$/, 'die_now dies without arrors and with trace'); lives_ok(sub { Net::SSLeay::die_if_ssl_error('foo'); }, 'die_if_ssl_error lives without errors and with trace'); put_err(); warns_like(sub { dies_like(sub { Net::SSLeay::die_now('foo'); }, qr/^$$: foo\n$/, 'die_now dies with errors and trace'); }, qr/$err_string/i, 'die_now raises warnings about the occurred error when tracing'); put_err(); warns_like(sub { dies_like(sub { Net::SSLeay::die_if_ssl_error('foo'); }, qr/^$$: foo\n$/, 'die_if_ssl_error dies with errors and trace'); }, qr/$err_string/i, 'die_if_ssl_error raises warnings about the occurred error when tracing'); } # The resulting error strings looks something like below. The number # after 'foo' is the process id. OpenSSL 3.0.0 drops function name and # changes how error code is packed. # - OpenSSL 3.0.0: foo 61488: 1 - error:10000080:BIO routines::no such file # - OpenSSL 3.0.0-alpha5: foo 16380: 1 - error:10000080:BIO routines::no such file # - OpenSSL 3.0.0-alpha1: foo 16293: 1 - error:20000080:BIO routines::no such file # - OpenSSL 1.1.1l: foo 61202: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 1.1.0l: foo 61295: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 1.0.2u: foo 61400: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 1.0.1u: foo 13621: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 1.0.0t: foo 14349: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 0.9.8zh: foo 14605: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # - OpenSSL 0.9.8f: foo 14692: 1 - error:2006D080:BIO routines:BIO_new_file:no such file # # 1.1.1 series and earlier create error by ORing together lib, func # and reason with 24 bit left shift, 12 bit left shift and without bit # shift, respectively. # 3.0.0 alpha1 drops function name from error string and alpha5 # changes bit shift of lib to 23. # LibreSSL 2.5.1 drops function name from error string. sub put_err { Net::SSLeay::ERR_put_error( 32, #lib - 0x20 ERR_LIB_BIO 'BIO routines' 109, #func - 0x6D BIO_F_BIO_NEW_FILE 'BIO_new_file' 128, #reason - 0x80 BIO_R_NO_SUCH_FILE 'no such file' 1, #file - file name (not packed into error code) 1, #line - line number (not packed into error code) ); } Net-SSLeay-1.92/t/local/47_keylog.t0000644000175000001440000001450114163136013015360 0ustar csnusers# Tests for logging TLS key material use lib 'inc'; use Net::SSLeay; use Test::Net::SSLeay qw( can_fork data_file_path initialise_libssl is_protocol_usable new_ctx tcp_socket ); if (not can_fork()) { plan skip_all => "fork() not supported on this system"; } elsif (!defined &Net::SSLeay::CTX_set_keylog_callback) { plan skip_all => "No CTX_set_keylog_callback()"; } else { plan tests => 11; } initialise_libssl(); # TLSv1.3 keylog is different from previous TLS versions. We expect # that both types can be tested my @rounds = qw( TLSv1.2 TLSv1.3 ); my %keylog = ( 'TLSv1.2' => {}, 'TLSv1.3' => {}, ); # %keylog ends up looking like this if everything goes as planned # See below for more information about the keys and the values. # $VAR1 = { # 'TLSv1.2' => { # 'CLIENT_RANDOM' => '54f8fdb2... 2232f0ab...' # }, # 'TLSv1.3' => { # 'CLIENT_HANDSHAKE_TRAFFIC_SECRET' => '0d862c40... d85e3d34...', # 'CLIENT_TRAFFIC_SECRET_0' => '0d862c40... 5c211de7...', # 'EXPORTER_SECRET' => '0d862c40... 332b80bb...', # 'SERVER_HANDSHAKE_TRAFFIC_SECRET' => '0d862c40... 93a9c58e...', # 'SERVER_TRAFFIC_SECRET_0' => '0d862c40... 34b7afff...' # } # }; # This will trigger diagnostics if the desired TLS versions are not # available. my %usable = map { $_ => is_protocol_usable($_) } @rounds; my $pid; alarm(30); END { kill 9,$pid if $pid } my $server = tcp_socket(); sub server { # SSL server - just handle connections, write, wait for read and repeat my $cert_pem = data_file_path('simple-cert.cert.pem'); my $key_pem = data_file_path('simple-cert.key.pem'); defined($pid = fork()) or BAIL_OUT("failed to fork: $!"); if ($pid == 0) { my ($ctx, $ssl, $ret, $cl); foreach my $round (@rounds) { next unless $usable{$round}; $cl = $server->accept(); $ctx = new_ctx( $round, $round ); Net::SSLeay::CTX_set_keylog_callback($ctx, \&keylog_cb); Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem); $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd($ssl, fileno($cl)); Net::SSLeay::accept($ssl); # Keylog data has been collected at this point. Doing some # reads and writes allows us to see our connection works. my $ssl_version = Net::SSLeay::read($ssl); Net::SSLeay::write($ssl, $ssl_version); my $keys = $keylog{$ssl_version}; foreach my $label (keys %{$keylog{$round}}) { Net::SSLeay::write($ssl, $label); Net::SSLeay::write($ssl, $keylog{$ssl_version}->{$label}); } Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("server close: $!"); } $server->close() || die("server listen socket close: $!"); exit(0); } } # SSL client - connect to server, read, test and repeat sub client { # For storing keylog information the server sends my %server_keylog; for my $round (@rounds) { if ($usable{$round}) { my $cl = $server->connect(); my $ctx = new_ctx( $round, $round ); Net::SSLeay::CTX_set_keylog_callback($ctx, \&keylog_cb); my $ssl = Net::SSLeay::new($ctx); Net::SSLeay::set_fd( $ssl, $cl ); my $ret = Net::SSLeay::connect($ssl); if ($ret <= 0) { diag("Protocol $round, connect() returns $ret, Error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error())); } # Pull server's keylog for this TLS version. Net::SSLeay::write($ssl, $round); my $ssl_version = Net::SSLeay::read($ssl); my %keys; while (my $label = Net::SSLeay::read($ssl)) { $keys{$label} = Net::SSLeay::read($ssl); } $server_keylog{$round} = \%keys; Net::SSLeay::shutdown($ssl); Net::SSLeay::free($ssl); close($cl) || die("client close: $!"); } else { diag("$round not available in this libssl but required by test"); } } $server->close() || die("client listen socket close: $!"); # Server and connections are gone but the client has all the data # it needs for the tests # Start with set/get test { my $ctx = new_ctx(); my $cb = Net::SSLeay::CTX_get_keylog_callback($ctx); is($cb, undef, 'Keylog callback is initially undefined'); Net::SSLeay::CTX_set_keylog_callback($ctx, \&keylog_cb); $cb = Net::SSLeay::CTX_get_keylog_callback($ctx); is($cb, \&keylog_cb, 'CTX_get_keylog_callback'); Net::SSLeay::CTX_set_keylog_callback($ctx, undef); $cb = Net::SSLeay::CTX_get_keylog_callback($ctx); is($cb, undef, 'Keylog callback successfully unset'); } # Make it clear we have separate keylog hashes. The also align # nicely below. The compare server and client keylogs. my %client_keylog = %keylog; foreach my $round (@rounds) { ok(exists $server_keylog{$round}, "Server keylog for $round exists"); ok(exists $client_keylog{$round}, "Client keylog for $round exists"); my $s_kl = delete $server_keylog{$round}; my $c_kl = delete $client_keylog{$round}; is_deeply($s_kl, $c_kl, "Client and Server have equal keylog for $round"); } is_deeply(\%server_keylog, {}, 'Server keylog has no unexpected entries'); is_deeply(\%client_keylog, {}, 'Client keylog has no unexpected entries'); return 1; } # The keylog file format is specified by Mozilla: # https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format # Quote: # This key log file is a series of lines. Comment lines begin with # a sharp character ('#') and are ignored. Secrets follow the # format