1# Net::SSLeay.pm - Perl module for using Eric Young's implementation of SSL 2# 3# Copyright (c) 1996-2003 Sampo Kellomäki <sampo@iki.fi> 4# Copyright (c) 2005-2010 Florian Ragwitz <rafl@debian.org> 5# Copyright (c) 2005-2018 Mike McCauley <mikem@airspayce.com> 6# Copyright (c) 2018- Chris Novakovic <chris@chrisn.me.uk> 7# Copyright (c) 2018- Tuure Vartiainen <vartiait@radiatorsoftware.com> 8# Copyright (c) 2018- Heikki Vatiainen <hvn@radiatorsoftware.com> 9# 10# All rights reserved. 11# 12# This module is released under the terms of the Artistic License 2.0. For 13# details, see the LICENSE file distributed with Net-SSLeay's source code. 14 15package Net::SSLeay; 16 17use 5.8.1; 18 19use strict; 20use Carp; 21use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD $CRLF); 22use Socket; 23use Errno; 24 25require Exporter; 26use AutoLoader; 27 28# 0=no warns, 1=only errors, 2=ciphers, 3=progress, 4=dump data 29$Net::SSLeay::trace = 0; # Do not change here, use 30 # $Net::SSLeay::trace = [1-4] in caller 31 32# 2 = insist on v2 SSL protocol 33# 3 = insist on v3 SSL 34# 10 = insist on TLSv1 35# 11 = insist on TLSv1.1 36# 12 = insist on TLSv1.2 37# 13 = insist on TLSv1.3 38# 0 or undef = guess (v23) 39# 40$Net::SSLeay::ssl_version = 0; # don't change here, use 41 # Net::SSLeay::version=[2,3,0] in caller 42 43#define to enable the "cat /proc/$$/stat" stuff 44$Net::SSLeay::linux_debug = 0; 45 46# Number of seconds to sleep after sending message and before half 47# closing connection. Useful with antiquated broken servers. 48$Net::SSLeay::slowly = 0; 49 50# RANDOM NUMBER INITIALIZATION 51# 52# Edit to your taste. Using /dev/random would be more secure, but may 53# block if randomness is not available, thus the default is 54# /dev/urandom. $how_random determines how many bits of randomness to take 55# from the device. You should take enough (read SSLeay/doc/rand), but 56# beware that randomness is limited resource so you should not waste 57# it either or you may end up with randomness depletion (situation where 58# /dev/random would block and /dev/urandom starts to return predictable 59# numbers). 60# 61# N.B. /dev/urandom does not exist on all systems, such as Solaris 2.6. In that 62# case you should get a third party package that emulates /dev/urandom 63# (e.g. via named pipe) or supply a random number file. Some such 64# packages are documented in Caveat section of the POD documentation. 65 66$Net::SSLeay::random_device = '/dev/urandom'; 67$Net::SSLeay::how_random = 512; 68 69# When updating this, also update $VERSION in the following files: 70# inc/Test/Net/SSLeay.pm 71# inc/Test/Net/SSLeay/Socket.pm 72# lib/Net/SSLeay/Handle.pm 73$VERSION = '1.90'; 74 75@ISA = qw(Exporter); 76 77#BEWARE: 78# 3-columns part of @EXPORT_OK related to constants is the output of command: 79# perl helper_script/regen_openssl_constants.pl -gen-pod 80# if you add/remove any constant you need to update it manually 81 82@EXPORT_OK = qw( 83 ASN1_STRFLGS_ESC_CTRL NID_netscape R_UNKNOWN_REMOTE_ERROR_TYPE 84 ASN1_STRFLGS_ESC_MSB NID_netscape_base_url R_UNKNOWN_STATE 85 ASN1_STRFLGS_ESC_QUOTE NID_netscape_ca_policy_url R_X509_LIB 86 ASN1_STRFLGS_RFC2253 NID_netscape_ca_revocation_url SENT_SHUTDOWN 87 CB_ACCEPT_EXIT NID_netscape_cert_extension SESSION_ASN1_VERSION 88 CB_ACCEPT_LOOP NID_netscape_cert_sequence SESS_CACHE_BOTH 89 CB_ALERT NID_netscape_cert_type SESS_CACHE_CLIENT 90 CB_CONNECT_EXIT NID_netscape_comment SESS_CACHE_NO_AUTO_CLEAR 91 CB_CONNECT_LOOP NID_netscape_data_type SESS_CACHE_NO_INTERNAL 92 CB_EXIT NID_netscape_renewal_url SESS_CACHE_NO_INTERNAL_LOOKUP 93 CB_HANDSHAKE_DONE NID_netscape_revocation_url SESS_CACHE_NO_INTERNAL_STORE 94 CB_HANDSHAKE_START NID_netscape_ssl_server_name SESS_CACHE_OFF 95 CB_LOOP NID_ns_sgc SESS_CACHE_SERVER 96 CB_READ NID_organizationName SSL3_VERSION 97 CB_READ_ALERT NID_organizationalUnitName SSLEAY_BUILT_ON 98 CB_WRITE NID_pbeWithMD2AndDES_CBC SSLEAY_CFLAGS 99 CB_WRITE_ALERT NID_pbeWithMD2AndRC2_CBC SSLEAY_DIR 100 ERROR_NONE NID_pbeWithMD5AndCast5_CBC SSLEAY_PLATFORM 101 ERROR_SSL NID_pbeWithMD5AndDES_CBC SSLEAY_VERSION 102 ERROR_SYSCALL NID_pbeWithMD5AndRC2_CBC ST_ACCEPT 103 ERROR_WANT_ACCEPT NID_pbeWithSHA1AndDES_CBC ST_BEFORE 104 ERROR_WANT_CONNECT NID_pbeWithSHA1AndRC2_CBC ST_CONNECT 105 ERROR_WANT_READ NID_pbe_WithSHA1And128BitRC2_CBC ST_INIT 106 ERROR_WANT_WRITE NID_pbe_WithSHA1And128BitRC4 ST_OK 107 ERROR_WANT_X509_LOOKUP NID_pbe_WithSHA1And2_Key_TripleDES_CBC ST_READ_BODY 108 ERROR_ZERO_RETURN NID_pbe_WithSHA1And3_Key_TripleDES_CBC ST_READ_HEADER 109 EVP_PKS_DSA NID_pbe_WithSHA1And40BitRC2_CBC TLS1_1_VERSION 110 EVP_PKS_EC NID_pbe_WithSHA1And40BitRC4 TLS1_2_VERSION 111 EVP_PKS_RSA NID_pbes2 TLS1_3_VERSION 112 EVP_PKT_ENC NID_pbmac1 TLS1_VERSION 113 EVP_PKT_EXCH NID_pkcs TLSEXT_STATUSTYPE_ocsp 114 EVP_PKT_EXP NID_pkcs3 VERIFY_CLIENT_ONCE 115 EVP_PKT_SIGN NID_pkcs7 VERIFY_FAIL_IF_NO_PEER_CERT 116 EVP_PK_DH NID_pkcs7_data VERIFY_NONE 117 EVP_PK_DSA NID_pkcs7_digest VERIFY_PEER 118 EVP_PK_EC NID_pkcs7_encrypted VERIFY_POST_HANDSHAKE 119 EVP_PK_RSA NID_pkcs7_enveloped V_OCSP_CERTSTATUS_GOOD 120 FILETYPE_ASN1 NID_pkcs7_signed V_OCSP_CERTSTATUS_REVOKED 121 FILETYPE_PEM NID_pkcs7_signedAndEnveloped V_OCSP_CERTSTATUS_UNKNOWN 122 F_CLIENT_CERTIFICATE NID_pkcs8ShroudedKeyBag WRITING 123 F_CLIENT_HELLO NID_pkcs9 X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 124 F_CLIENT_MASTER_KEY NID_pkcs9_challengePassword X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 125 F_D2I_SSL_SESSION NID_pkcs9_contentType X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 126 F_GET_CLIENT_FINISHED NID_pkcs9_countersignature X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 127 F_GET_CLIENT_HELLO NID_pkcs9_emailAddress X509_CHECK_FLAG_NO_WILDCARDS 128 F_GET_CLIENT_MASTER_KEY NID_pkcs9_extCertAttributes X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 129 F_GET_SERVER_FINISHED NID_pkcs9_messageDigest X509_FILETYPE_ASN1 130 F_GET_SERVER_HELLO NID_pkcs9_signingTime X509_FILETYPE_DEFAULT 131 F_GET_SERVER_VERIFY NID_pkcs9_unstructuredAddress X509_FILETYPE_PEM 132 F_I2D_SSL_SESSION NID_pkcs9_unstructuredName X509_LOOKUP 133 F_READ_N NID_private_key_usage_period X509_PURPOSE_ANY 134 F_REQUEST_CERTIFICATE NID_rc2_40_cbc X509_PURPOSE_CRL_SIGN 135 F_SERVER_HELLO NID_rc2_64_cbc X509_PURPOSE_NS_SSL_SERVER 136 F_SSL_CERT_NEW NID_rc2_cbc X509_PURPOSE_OCSP_HELPER 137 F_SSL_GET_NEW_SESSION NID_rc2_cfb64 X509_PURPOSE_SMIME_ENCRYPT 138 F_SSL_NEW NID_rc2_ecb X509_PURPOSE_SMIME_SIGN 139 F_SSL_READ NID_rc2_ofb64 X509_PURPOSE_SSL_CLIENT 140 F_SSL_RSA_PRIVATE_DECRYPT NID_rc4 X509_PURPOSE_SSL_SERVER 141 F_SSL_RSA_PUBLIC_ENCRYPT NID_rc4_40 X509_PURPOSE_TIMESTAMP_SIGN 142 F_SSL_SESSION_NEW NID_rc5_cbc X509_TRUST_COMPAT 143 F_SSL_SESSION_PRINT_FP NID_rc5_cfb64 X509_TRUST_EMAIL 144 F_SSL_SET_FD NID_rc5_ecb X509_TRUST_OBJECT_SIGN 145 F_SSL_SET_RFD NID_rc5_ofb64 X509_TRUST_OCSP_REQUEST 146 F_SSL_SET_WFD NID_ripemd160 X509_TRUST_OCSP_SIGN 147 F_SSL_USE_CERTIFICATE NID_ripemd160WithRSA X509_TRUST_SSL_CLIENT 148 F_SSL_USE_CERTIFICATE_ASN1 NID_rle_compression X509_TRUST_SSL_SERVER 149 F_SSL_USE_CERTIFICATE_FILE NID_rsa X509_TRUST_TSA 150 F_SSL_USE_PRIVATEKEY NID_rsaEncryption X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 151 F_SSL_USE_PRIVATEKEY_ASN1 NID_rsadsi X509_V_ERR_AKID_SKID_MISMATCH 152 F_SSL_USE_PRIVATEKEY_FILE NID_safeContentsBag X509_V_ERR_APPLICATION_VERIFICATION 153 F_SSL_USE_RSAPRIVATEKEY NID_sdsiCertificate X509_V_ERR_CA_KEY_TOO_SMALL 154 F_SSL_USE_RSAPRIVATEKEY_ASN1 NID_secretBag X509_V_ERR_CA_MD_TOO_WEAK 155 F_SSL_USE_RSAPRIVATEKEY_FILE NID_serialNumber X509_V_ERR_CERT_CHAIN_TOO_LONG 156 F_WRITE_PENDING NID_server_auth X509_V_ERR_CERT_HAS_EXPIRED 157 GEN_DIRNAME NID_sha X509_V_ERR_CERT_NOT_YET_VALID 158 GEN_DNS NID_sha1 X509_V_ERR_CERT_REJECTED 159 GEN_EDIPARTY NID_sha1WithRSA X509_V_ERR_CERT_REVOKED 160 GEN_EMAIL NID_sha1WithRSAEncryption X509_V_ERR_CERT_SIGNATURE_FAILURE 161 GEN_IPADD NID_shaWithRSAEncryption X509_V_ERR_CERT_UNTRUSTED 162 GEN_OTHERNAME NID_stateOrProvinceName X509_V_ERR_CRL_HAS_EXPIRED 163 GEN_RID NID_subject_alt_name X509_V_ERR_CRL_NOT_YET_VALID 164 GEN_URI NID_subject_key_identifier X509_V_ERR_CRL_PATH_VALIDATION_ERROR 165 GEN_X400 NID_surname X509_V_ERR_CRL_SIGNATURE_FAILURE 166 LIBRESSL_VERSION_NUMBER NID_sxnet X509_V_ERR_DANE_NO_MATCH 167 MBSTRING_ASC NID_time_stamp X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 168 MBSTRING_BMP NID_title X509_V_ERR_DIFFERENT_CRL_SCOPE 169 MBSTRING_FLAG NID_undef X509_V_ERR_EE_KEY_TOO_SMALL 170 MBSTRING_UNIV NID_uniqueIdentifier X509_V_ERR_EMAIL_MISMATCH 171 MBSTRING_UTF8 NID_x509Certificate X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 172 MIN_RSA_MODULUS_LENGTH_IN_BYTES NID_x509Crl X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 173 MODE_ACCEPT_MOVING_WRITE_BUFFER NID_zlib_compression X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 174 MODE_AUTO_RETRY NOTHING X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 175 MODE_ENABLE_PARTIAL_WRITE OCSP_RESPONSE_STATUS_INTERNALERROR X509_V_ERR_EXCLUDED_VIOLATION 176 MODE_RELEASE_BUFFERS OCSP_RESPONSE_STATUS_MALFORMEDREQUEST X509_V_ERR_HOSTNAME_MISMATCH 177 NID_OCSP_sign OCSP_RESPONSE_STATUS_SIGREQUIRED X509_V_ERR_INVALID_CA 178 NID_SMIMECapabilities OCSP_RESPONSE_STATUS_SUCCESSFUL X509_V_ERR_INVALID_CALL 179 NID_X500 OCSP_RESPONSE_STATUS_TRYLATER X509_V_ERR_INVALID_EXTENSION 180 NID_X509 OCSP_RESPONSE_STATUS_UNAUTHORIZED X509_V_ERR_INVALID_NON_CA 181 NID_ad_OCSP OPENSSL_BUILT_ON X509_V_ERR_INVALID_POLICY_EXTENSION 182 NID_ad_ca_issuers OPENSSL_CFLAGS X509_V_ERR_INVALID_PURPOSE 183 NID_algorithm OPENSSL_DIR X509_V_ERR_IP_ADDRESS_MISMATCH 184 NID_authority_key_identifier OPENSSL_ENGINES_DIR X509_V_ERR_KEYUSAGE_NO_CERTSIGN 185 NID_basic_constraints OPENSSL_PLATFORM X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 186 NID_bf_cbc OPENSSL_VERSION X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 187 NID_bf_cfb64 OPENSSL_VERSION_NUMBER X509_V_ERR_NO_EXPLICIT_POLICY 188 NID_bf_ecb OP_ALL X509_V_ERR_NO_VALID_SCTS 189 NID_bf_ofb64 OP_ALLOW_NO_DHE_KEX X509_V_ERR_OCSP_CERT_UNKNOWN 190 NID_cast5_cbc OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION X509_V_ERR_OCSP_VERIFY_FAILED 191 NID_cast5_cfb64 OP_CIPHER_SERVER_PREFERENCE X509_V_ERR_OCSP_VERIFY_NEEDED 192 NID_cast5_ecb OP_CISCO_ANYCONNECT X509_V_ERR_OUT_OF_MEM 193 NID_cast5_ofb64 OP_COOKIE_EXCHANGE X509_V_ERR_PATH_LENGTH_EXCEEDED 194 NID_certBag OP_CRYPTOPRO_TLSEXT_BUG X509_V_ERR_PATH_LOOP 195 NID_certificate_policies OP_DONT_INSERT_EMPTY_FRAGMENTS X509_V_ERR_PERMITTED_VIOLATION 196 NID_client_auth OP_ENABLE_MIDDLEBOX_COMPAT X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 197 NID_code_sign OP_EPHEMERAL_RSA X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 198 NID_commonName OP_LEGACY_SERVER_CONNECT X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 199 NID_countryName OP_MICROSOFT_BIG_SSLV3_BUFFER X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 200 NID_crlBag OP_MICROSOFT_SESS_ID_BUG X509_V_ERR_STORE_LOOKUP 201 NID_crl_distribution_points OP_MSIE_SSLV2_RSA_PADDING X509_V_ERR_SUBJECT_ISSUER_MISMATCH 202 NID_crl_number OP_NETSCAPE_CA_DN_BUG X509_V_ERR_SUBTREE_MINMAX 203 NID_crl_reason OP_NETSCAPE_CHALLENGE_BUG X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 204 NID_delta_crl OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG X509_V_ERR_SUITE_B_INVALID_ALGORITHM 205 NID_des_cbc OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG X509_V_ERR_SUITE_B_INVALID_CURVE 206 NID_des_cfb64 OP_NON_EXPORT_FIRST X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 207 NID_des_ecb OP_NO_ANTI_REPLAY X509_V_ERR_SUITE_B_INVALID_VERSION 208 NID_des_ede OP_NO_CLIENT_RENEGOTIATION X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 209 NID_des_ede3 OP_NO_COMPRESSION X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 210 NID_des_ede3_cbc OP_NO_ENCRYPT_THEN_MAC X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 211 NID_des_ede3_cfb64 OP_NO_QUERY_MTU X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 212 NID_des_ede3_ofb64 OP_NO_RENEGOTIATION X509_V_ERR_UNABLE_TO_GET_CRL 213 NID_des_ede_cbc OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 214 NID_des_ede_cfb64 OP_NO_SSL_MASK X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 215 NID_des_ede_ofb64 OP_NO_SSLv2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 216 NID_des_ofb64 OP_NO_SSLv3 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 217 NID_description OP_NO_TICKET X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 218 NID_desx_cbc OP_NO_TLSv1 X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 219 NID_dhKeyAgreement OP_NO_TLSv1_1 X509_V_ERR_UNNESTED_RESOURCE 220 NID_dnQualifier OP_NO_TLSv1_2 X509_V_ERR_UNSPECIFIED 221 NID_dsa OP_NO_TLSv1_3 X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 222 NID_dsaWithSHA OP_PKCS1_CHECK_1 X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 223 NID_dsaWithSHA1 OP_PKCS1_CHECK_2 X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 224 NID_dsaWithSHA1_2 OP_PRIORITIZE_CHACHA X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 225 NID_dsa_2 OP_SAFARI_ECDHE_ECDSA_BUG X509_V_FLAG_ALLOW_PROXY_CERTS 226 NID_email_protect OP_SINGLE_DH_USE X509_V_FLAG_CB_ISSUER_CHECK 227 NID_ext_key_usage OP_SINGLE_ECDH_USE X509_V_FLAG_CHECK_SS_SIGNATURE 228 NID_ext_req OP_SSLEAY_080_CLIENT_DH_BUG X509_V_FLAG_CRL_CHECK 229 NID_friendlyName OP_SSLREF2_REUSE_CERT_TYPE_BUG X509_V_FLAG_CRL_CHECK_ALL 230 NID_givenName OP_TLSEXT_PADDING X509_V_FLAG_EXPLICIT_POLICY 231 NID_hmacWithSHA1 OP_TLS_BLOCK_PADDING_BUG X509_V_FLAG_EXTENDED_CRL_SUPPORT 232 NID_id_ad OP_TLS_D5_BUG X509_V_FLAG_IGNORE_CRITICAL 233 NID_id_ce OP_TLS_ROLLBACK_BUG X509_V_FLAG_INHIBIT_ANY 234 NID_id_kp READING X509_V_FLAG_INHIBIT_MAP 235 NID_id_pbkdf2 RECEIVED_SHUTDOWN X509_V_FLAG_NOTIFY_POLICY 236 NID_id_pe RSA_3 X509_V_FLAG_NO_ALT_CHAINS 237 NID_id_pkix RSA_F4 X509_V_FLAG_NO_CHECK_TIME 238 NID_id_qt_cps R_BAD_AUTHENTICATION_TYPE X509_V_FLAG_PARTIAL_CHAIN 239 NID_id_qt_unotice R_BAD_CHECKSUM X509_V_FLAG_POLICY_CHECK 240 NID_idea_cbc R_BAD_MAC_DECODE X509_V_FLAG_POLICY_MASK 241 NID_idea_cfb64 R_BAD_RESPONSE_ARGUMENT X509_V_FLAG_SUITEB_128_LOS 242 NID_idea_ecb R_BAD_SSL_FILETYPE X509_V_FLAG_SUITEB_128_LOS_ONLY 243 NID_idea_ofb64 R_BAD_SSL_SESSION_ID_LENGTH X509_V_FLAG_SUITEB_192_LOS 244 NID_info_access R_BAD_STATE X509_V_FLAG_TRUSTED_FIRST 245 NID_initials R_BAD_WRITE_RETRY X509_V_FLAG_USE_CHECK_TIME 246 NID_invalidity_date R_CHALLENGE_IS_DIFFERENT X509_V_FLAG_USE_DELTAS 247 NID_issuer_alt_name R_CIPHER_TABLE_SRC_ERROR X509_V_FLAG_X509_STRICT 248 NID_keyBag R_INVALID_CHALLENGE_LENGTH X509_V_OK 249 NID_key_usage R_NO_CERTIFICATE_SET XN_FLAG_COMPAT 250 NID_localKeyID R_NO_CERTIFICATE_SPECIFIED XN_FLAG_DN_REV 251 NID_localityName R_NO_CIPHER_LIST XN_FLAG_DUMP_UNKNOWN_FIELDS 252 NID_md2 R_NO_CIPHER_MATCH XN_FLAG_FN_ALIGN 253 NID_md2WithRSAEncryption R_NO_PRIVATEKEY XN_FLAG_FN_LN 254 NID_md5 R_NO_PUBLICKEY XN_FLAG_FN_MASK 255 NID_md5WithRSA R_NULL_SSL_CTX XN_FLAG_FN_NONE 256 NID_md5WithRSAEncryption R_PEER_DID_NOT_RETURN_A_CERTIFICATE XN_FLAG_FN_OID 257 NID_md5_sha1 R_PEER_ERROR XN_FLAG_FN_SN 258 NID_mdc2 R_PEER_ERROR_CERTIFICATE XN_FLAG_MULTILINE 259 NID_mdc2WithRSA R_PEER_ERROR_NO_CIPHER XN_FLAG_ONELINE 260 NID_ms_code_com R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE XN_FLAG_RFC2253 261 NID_ms_code_ind R_PUBLIC_KEY_ENCRYPT_ERROR XN_FLAG_SEP_COMMA_PLUS 262 NID_ms_ctl_sign R_PUBLIC_KEY_IS_NOT_RSA XN_FLAG_SEP_CPLUS_SPC 263 NID_ms_efs R_READ_WRONG_PACKET_TYPE XN_FLAG_SEP_MASK 264 NID_ms_ext_req R_SHORT_READ XN_FLAG_SEP_MULTILINE 265 NID_ms_sgc R_SSL_SESSION_ID_IS_DIFFERENT XN_FLAG_SEP_SPLUS_SPC 266 NID_name R_UNABLE_TO_EXTRACT_PUBLIC_KEY XN_FLAG_SPC_EQ 267 BIO_eof 268 BIO_f_ssl 269 BIO_free 270 BIO_new 271 BIO_new_file 272 BIO_pending 273 BIO_read 274 BIO_s_mem 275 BIO_wpending 276 BIO_write 277 CTX_free 278 CTX_get_cert_store 279 CTX_new 280 CTX_use_RSAPrivateKey_file 281 CTX_use_certificate_file 282 CTX_v23_new 283 CTX_v2_new 284 CTX_v3_new 285 ERR_error_string 286 ERR_get_error 287 ERR_load_RAND_strings 288 ERR_load_SSL_strings 289 PEM_read_bio_X509_CRL 290 RSA_free 291 RSA_generate_key 292 SESSION 293 SESSION_free 294 SESSION_get_master_key 295 SESSION_new 296 SESSION_print 297 X509_NAME_get_text_by_NID 298 X509_NAME_oneline 299 X509_STORE_CTX_set_flags 300 X509_STORE_add_cert 301 X509_STORE_add_crl 302 X509_check_email 303 X509_check_host 304 X509_check_ip 305 X509_check_ip_asc 306 X509_free 307 X509_get_issuer_name 308 X509_get_subject_name 309 X509_load_cert_crl_file 310 X509_load_cert_file 311 X509_load_crl_file 312 accept 313 add_session 314 clear 315 clear_error 316 connect 317 copy_session_id 318 d2i_SSL_SESSION 319 die_if_ssl_error 320 die_now 321 do_https 322 dump_peer_certificate 323 err 324 flush_sessions 325 free 326 get_cipher 327 get_cipher_list 328 get_client_random 329 get_fd 330 get_http 331 get_http4 332 get_https 333 get_https3 334 get_https4 335 get_httpx 336 get_httpx4 337 get_peer_certificate 338 get_peer_cert_chain 339 get_rbio 340 get_read_ahead 341 get_server_random 342 get_shared_ciphers 343 get_time 344 get_timeout 345 get_wbio 346 i2d_SSL_SESSION 347 load_error_strings 348 make_form 349 make_headers 350 new 351 peek 352 pending 353 post_http 354 post_http4 355 post_https 356 post_https3 357 post_https4 358 post_httpx 359 post_httpx4 360 print_errs 361 read 362 remove_session 363 rstate_string 364 rstate_string_long 365 set_bio 366 set_cert_and_key 367 set_cipher_list 368 set_fd 369 set_read_ahead 370 set_rfd 371 set_server_cert_and_key 372 set_session 373 set_time 374 set_timeout 375 set_verify 376 set_wfd 377 ssl_read_CRLF 378 ssl_read_all 379 ssl_read_until 380 ssl_write_CRLF 381 ssl_write_all 382 sslcat 383 state_string 384 state_string_long 385 tcp_read_CRLF 386 tcp_read_all 387 tcp_read_until 388 tcp_write_CRLF 389 tcp_write_all 390 tcpcat 391 tcpxcat 392 use_PrivateKey 393 use_PrivateKey_ASN1 394 use_PrivateKey_file 395 use_RSAPrivateKey 396 use_RSAPrivateKey_ASN1 397 use_RSAPrivateKey_file 398 use_certificate 399 use_certificate_ASN1 400 use_certificate_file 401 write 402 d2i_OCSP_RESPONSE 403 i2d_OCSP_RESPONSE 404 OCSP_RESPONSE_free 405 d2i_OCSP_REQUEST 406 i2d_OCSP_REQUEST 407 OCSP_REQUEST_free 408 OCSP_cert2ids 409 OCSP_ids2req 410 OCSP_response_status 411 OCSP_response_status_str 412 OCSP_response_verify 413 OCSP_response_results 414 OCSP_RESPONSE_STATUS_INTERNALERROR 415 OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 416 OCSP_RESPONSE_STATUS_SIGREQUIRED 417 OCSP_RESPONSE_STATUS_SUCCESSFUL 418 OCSP_RESPONSE_STATUS_TRYLATER 419 OCSP_RESPONSE_STATUS_UNAUTHORIZED 420 TLSEXT_STATUSTYPE_ocsp 421 V_OCSP_CERTSTATUS_GOOD 422 V_OCSP_CERTSTATUS_REVOKED 423 V_OCSP_CERTSTATUS_UNKNOWN 424); 425 426sub AUTOLOAD { 427 # This AUTOLOAD is used to 'autoload' constants from the constant() 428 # XS function. If a constant is not found then control is passed 429 # to the AUTOLOAD in AutoLoader. 430 431 my $constname; 432 ($constname = $AUTOLOAD) =~ s/.*:://; 433 my $val = constant($constname); 434 if ($! != 0) { 435 if ($! =~ /((Invalid)|(not valid))/i || $!{EINVAL}) { 436 $AutoLoader::AUTOLOAD = $AUTOLOAD; 437 goto &AutoLoader::AUTOLOAD; 438 } 439 else { 440 croak "Your vendor has not defined SSLeay macro $constname"; 441 } 442 } 443 eval "sub $AUTOLOAD { $val }"; 444 goto &$AUTOLOAD; 445} 446 447eval { 448 require XSLoader; 449 XSLoader::load('Net::SSLeay', $VERSION); 450 1; 451} or do { 452 require DynaLoader; 453 push @ISA, 'DynaLoader'; 454 bootstrap Net::SSLeay $VERSION; 455}; 456 457# Preloaded methods go here. 458 459$CRLF = "\x0d\x0a"; # because \r\n is not fully portable 460 461### Print SSLeay error stack 462 463sub print_errs { 464 my ($msg) = @_; 465 my ($count, $err, $errs, $e) = (0,0,''); 466 while ($err = ERR_get_error()) { 467 $count ++; 468 $e = "$msg $$: $count - " . ERR_error_string($err) . "\n"; 469 $errs .= $e; 470 warn $e if $Net::SSLeay::trace; 471 } 472 return $errs; 473} 474 475# Death is conditional to SSLeay errors existing, i.e. this function checks 476# for errors and only dies in affirmative. 477# usage: Net::SSLeay::write($ssl, "foo") or die_if_ssl_error("SSL write ($!)"); 478 479sub die_if_ssl_error { 480 my ($msg) = @_; 481 die "$$: $msg\n" if print_errs($msg); 482} 483 484# Unconditional death. Used to print SSLeay errors before dying. 485# usage: Net::SSLeay::connect($ssl) or die_now("Failed SSL connect ($!)"); 486 487sub die_now { 488 my ($msg) = @_; 489 print_errs($msg); 490 die "$$: $msg\n"; 491} 492 493# Perl 5.6.* unicode support causes that length() no longer reliably 494# reflects the byte length of a string. This eval is to fix that. 495# Thanks to Sean Burke for the snippet. 496 497BEGIN{ 498eval 'use bytes; sub blength ($) { defined $_[0] ? length $_[0] : 0 }'; 499$@ and eval ' sub blength ($) { defined $_[0] ? length $_[0] : 0 }' ; 500} 501 502# Autoload methods go after __END__, and are processed by the autosplit program. 503 504 5051; 506__END__ 507 508### Some methods that are macros in C 509 510sub want_nothing { want(shift) == 1 } 511sub want_read { want(shift) == 2 } 512sub want_write { want(shift) == 3 } 513sub want_X509_lookup { want(shift) == 4 } 514 515### 516### Open TCP stream to given host and port, looking up the details 517### from system databases or DNS. 518### 519 520sub open_tcp_connection { 521 my ($dest_serv, $port) = @_; 522 my ($errs); 523 524 $port = getservbyname($port, 'tcp') unless $port =~ /^\d+$/; 525 my $dest_serv_ip = gethostbyname($dest_serv); 526 unless (defined($dest_serv_ip)) { 527 $errs = "$0 $$: open_tcp_connection: destination host not found:" 528 . " `$dest_serv' (port $port) ($!)\n"; 529 warn $errs if $trace; 530 return wantarray ? (0, $errs) : 0; 531 } 532 my $sin = sockaddr_in($port, $dest_serv_ip); 533 534 warn "Opening connection to $dest_serv:$port (" . 535 inet_ntoa($dest_serv_ip) . ")" if $trace>2; 536 537 my $proto = &Socket::IPPROTO_TCP; # getprotobyname('tcp') not available on android 538 if (socket (SSLCAT_S, &PF_INET(), &SOCK_STREAM(), $proto)) { 539 warn "next connect" if $trace>3; 540 if (CORE::connect (SSLCAT_S, $sin)) { 541 my $old_out = select (SSLCAT_S); $| = 1; select ($old_out); 542 warn "connected to $dest_serv, $port" if $trace>3; 543 return wantarray ? (1, undef) : 1; # Success 544 } 545 } 546 $errs = "$0 $$: open_tcp_connection: failed `$dest_serv', $port ($!)\n"; 547 warn $errs if $trace; 548 close SSLCAT_S; 549 return wantarray ? (0, $errs) : 0; # Fail 550} 551 552### Open connection via standard web proxy, if one was defined 553### using set_proxy(). 554 555sub open_proxy_tcp_connection { 556 my ($dest_serv, $port) = @_; 557 return open_tcp_connection($dest_serv, $port) if !$proxyhost; 558 559 warn "Connect via proxy: $proxyhost:$proxyport" if $trace>2; 560 my ($ret, $errs) = open_tcp_connection($proxyhost, $proxyport); 561 return wantarray ? (0, $errs) : 0 if !$ret; # Connection fail 562 563 warn "Asking proxy to connect to $dest_serv:$port" if $trace>2; 564 #print SSLCAT_S "CONNECT $dest_serv:$port HTTP/1.0$proxyauth$CRLF$CRLF"; 565 #my $line = <SSLCAT_S>; # *** bug? Mixing stdio with syscall read? 566 ($ret, $errs) = 567 tcp_write_all("CONNECT $dest_serv:$port HTTP/1.0$proxyauth$CRLF$CRLF"); 568 return wantarray ? (0,$errs) : 0 if $errs; 569 ($line, $errs) = tcp_read_until($CRLF . $CRLF, 1024); 570 warn "Proxy response: $line" if $trace>2; 571 return wantarray ? (0,$errs) : 0 if $errs; 572 return wantarray ? (1,'') : 1; # Success 573} 574 575### 576### read and write helpers that block 577### 578 579sub debug_read { 580 my ($replyr, $gotr) = @_; 581 my $vm = $trace>2 && $linux_debug ? 582 (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; 583 warn " got " . blength($$gotr) . ':' 584 . blength($$replyr) . " bytes (VM=$vm).\n" if $trace == 3; 585 warn " got `$$gotr' (" . blength($$gotr) . ':' 586 . blength($$replyr) . " bytes, VM=$vm)\n" if $trace>3; 587} 588 589sub ssl_read_all { 590 my ($ssl,$how_much) = @_; 591 $how_much = 2000000000 unless $how_much; 592 my ($got, $rv, $errs); 593 my $reply = ''; 594 595 while ($how_much > 0) { 596 ($got, $rv) = Net::SSLeay::read($ssl, 597 ($how_much > 32768) ? 32768 : $how_much 598 ); 599 if (! defined $got) { 600 my $err = Net::SSLeay::get_error($ssl, $rv); 601 if ($err != Net::SSLeay::ERROR_WANT_READ() and 602 $err != Net::SSLeay::ERROR_WANT_WRITE()) { 603 $errs = print_errs('SSL_read'); 604 last; 605 } 606 next; 607 } 608 $how_much -= blength($got); 609 debug_read(\$reply, \$got) if $trace>1; 610 last if $got eq ''; # EOF 611 $reply .= $got; 612 } 613 614 return wantarray ? ($reply, $errs) : $reply; 615} 616 617sub tcp_read_all { 618 my ($how_much) = @_; 619 $how_much = 2000000000 unless $how_much; 620 my ($n, $got, $errs); 621 my $reply = ''; 622 623 my $bsize = 0x10000; 624 while ($how_much > 0) { 625 $n = sysread(SSLCAT_S,$got, (($bsize < $how_much) ? $bsize : $how_much)); 626 warn "Read error: $! ($n,$how_much)" unless defined $n; 627 last if !$n; # EOF 628 $how_much -= $n; 629 debug_read(\$reply, \$got) if $trace>1; 630 $reply .= $got; 631 } 632 return wantarray ? ($reply, $errs) : $reply; 633} 634 635sub ssl_write_all { 636 my $ssl = $_[0]; 637 my ($data_ref, $errs); 638 if (ref $_[1]) { 639 $data_ref = $_[1]; 640 } else { 641 $data_ref = \$_[1]; 642 } 643 my ($wrote, $written, $to_write) = (0,0, blength($$data_ref)); 644 my $vm = $trace>2 && $linux_debug ? 645 (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; 646 warn " write_all VM at entry=$vm\n" if $trace>2; 647 while ($to_write) { 648 #sleep 1; # *** DEBUG 649 warn "partial `$$data_ref'\n" if $trace>3; 650 $wrote = write_partial($ssl, $written, $to_write, $$data_ref); 651 if (defined $wrote && ($wrote > 0)) { # write_partial can return -1 652 $written += $wrote; 653 $to_write -= $wrote; 654 } else { 655 if (defined $wrote) { 656 # check error conditions via SSL_get_error per man page 657 if ( my $sslerr = get_error($ssl, $wrote) ) { 658 my $errstr = ERR_error_string($sslerr); 659 my $errname = ''; 660 SWITCH: { 661 $sslerr == constant("ERROR_NONE") && do { 662 # according to map page SSL_get_error(3ssl): 663 # The TLS/SSL I/O operation completed. 664 # This result code is returned if and only if ret > 0 665 # so if we received it here complain... 666 warn "ERROR_NONE unexpected with invalid return value!" 667 if $trace; 668 $errname = "SSL_ERROR_NONE"; 669 }; 670 $sslerr == constant("ERROR_WANT_READ") && do { 671 # operation did not complete, call again later, so do not 672 # set errname and empty err_que since this is a known 673 # error that is expected but, we should continue to try 674 # writing the rest of our data with same io call and params. 675 warn "ERROR_WANT_READ (TLS/SSL Handshake, will continue)\n" 676 if $trace; 677 print_errs('SSL_write(want read)'); 678 last SWITCH; 679 }; 680 $sslerr == constant("ERROR_WANT_WRITE") && do { 681 # operation did not complete, call again later, so do not 682 # set errname and empty err_que since this is a known 683 # error that is expected but, we should continue to try 684 # writing the rest of our data with same io call and params. 685 warn "ERROR_WANT_WRITE (TLS/SSL Handshake, will continue)\n" 686 if $trace; 687 print_errs('SSL_write(want write)'); 688 last SWITCH; 689 }; 690 $sslerr == constant("ERROR_ZERO_RETURN") && do { 691 # valid protocol closure from other side, no longer able to 692 # write, since there is no longer a session... 693 warn "ERROR_ZERO_RETURN($wrote): TLS/SSLv3 Closure alert\n" 694 if $trace; 695 $errname = "SSL_ERROR_ZERO_RETURN"; 696 last SWITCH; 697 }; 698 $sslerr == constant("ERROR_SSL") && do { 699 # library/protocol error 700 warn "ERROR_SSL($wrote): Library/Protocol error occured\n" 701 if $trace; 702 $errname = "SSL_ERROR_SSL"; 703 last SWITCH; 704 }; 705 $sslerr == constant("ERROR_WANT_CONNECT") && do { 706 # according to man page, should never happen on call to 707 # SSL_write, so complain, but handle as known error type 708 warn "ERROR_WANT_CONNECT: Unexpected error for SSL_write\n" 709 if $trace; 710 $errname = "SSL_ERROR_WANT_CONNECT"; 711 last SWITCH; 712 }; 713 $sslerr == constant("ERROR_WANT_ACCEPT") && do { 714 # according to man page, should never happen on call to 715 # SSL_write, so complain, but handle as known error type 716 warn "ERROR_WANT_ACCEPT: Unexpected error for SSL_write\n" 717 if $trace; 718 $errname = "SSL_ERROR_WANT_ACCEPT"; 719 last SWITCH; 720 }; 721 $sslerr == constant("ERROR_WANT_X509_LOOKUP") && do { 722 # operation did not complete: waiting on call back, 723 # call again later, so do not set errname and empty err_que 724 # since this is a known error that is expected but, we should 725 # continue to try writing the rest of our data with same io 726 # call parameter. 727 warn "ERROR_WANT_X509_LOOKUP: (Cert Callback asked for in ". 728 "SSL_write will contine)\n" if $trace; 729 print_errs('SSL_write(want x509'); 730 last SWITCH; 731 }; 732 $sslerr == constant("ERROR_SYSCALL") && do { 733 # some IO error occured. According to man page: 734 # Check retval, ERR, fallback to errno 735 if ($wrote==0) { # EOF 736 warn "ERROR_SYSCALL($wrote): EOF violates protocol.\n" 737 if $trace; 738 $errname = "SSL_ERROR_SYSCALL(EOF)"; 739 } else { # -1 underlying BIO error reported. 740 # check error que for details, don't set errname since we 741 # are directly appending to errs 742 my $chkerrs = print_errs('SSL_write (syscall)'); 743 if ($chkerrs) { 744 warn "ERROR_SYSCALL($wrote): Have errors\n" if $trace; 745 $errs .= "ssl_write_all $$: 1 - ERROR_SYSCALL($wrote,". 746 "$sslerr,$errstr,$!)\n$chkerrs"; 747 } else { # que was empty, use errno 748 warn "ERROR_SYSCALL($wrote): errno($!)\n" if $trace; 749 $errs .= "ssl_write_all $$: 1 - ERROR_SYSCALL($wrote,". 750 "$sslerr) : $!\n"; 751 } 752 } 753 last SWITCH; 754 }; 755 warn "Unhandled val $sslerr from SSL_get_error(SSL,$wrote)\n" 756 if $trace; 757 $errname = "SSL_ERROR_?($sslerr)"; 758 } # end of SWITCH block 759 if ($errname) { # if we had an errname set add the error 760 $errs .= "ssl_write_all $$: 1 - $errname($wrote,$sslerr,". 761 "$errstr,$!)\n"; 762 } 763 } # endif on have SSL_get_error val 764 } # endif on $wrote defined 765 } # endelse on $wrote > 0 766 $vm = $trace>2 && $linux_debug ? 767 (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; 768 warn " written so far $wrote:$written bytes (VM=$vm)\n" if $trace>2; 769 # append remaining errors in que and report if errs exist 770 $errs .= print_errs('SSL_write'); 771 return (wantarray ? (undef, $errs) : undef) if $errs; 772 } 773 return wantarray ? ($written, $errs) : $written; 774} 775 776sub tcp_write_all { 777 my ($data_ref, $errs); 778 if (ref $_[0]) { 779 $data_ref = $_[0]; 780 } else { 781 $data_ref = \$_[0]; 782 } 783 my ($wrote, $written, $to_write) = (0,0, blength($$data_ref)); 784 my $vm = $trace>2 && $linux_debug ? 785 (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; 786 warn " write_all VM at entry=$vm to_write=$to_write\n" if $trace>2; 787 while ($to_write) { 788 warn "partial `$$data_ref'\n" if $trace>3; 789 $wrote = syswrite(SSLCAT_S, $$data_ref, $to_write, $written); 790 if (defined $wrote && ($wrote > 0)) { # write_partial can return -1 791 $written += $wrote; 792 $to_write -= $wrote; 793 } elsif (!defined($wrote)) { 794 warn "tcp_write_all: $!"; 795 return (wantarray ? (undef, "$!") : undef); 796 } 797 $vm = $trace>2 && $linux_debug ? 798 (split ' ', `cat /proc/$$/stat`)[22] : 'vm_unknown'; 799 warn " written so far $wrote:$written bytes (VM=$vm)\n" if $trace>2; 800 } 801 return wantarray ? ($written, '') : $written; 802} 803 804### from patch by Clinton Wong <clintdw@netcom.com> 805 806# ssl_read_until($ssl [, $delimit [, $max_length]]) 807# if $delimit missing, use $/ if it exists, otherwise use \n 808# read until delimiter reached, up to $max_length chars if defined 809 810sub ssl_read_until ($;$$) { 811 my ($ssl,$delim, $max_length) = @_; 812 813 # guess the delim string if missing 814 if ( ! defined $delim ) { 815 if ( defined $/ && length $/ ) { $delim = $/ } 816 else { $delim = "\n" } # Note: \n,$/ value depends on the platform 817 } 818 my $len_delim = length $delim; 819 820 my ($got); 821 my $reply = ''; 822 823 # If we have OpenSSL 0.9.6a or later, we can use SSL_peek to 824 # speed things up. 825 # N.B. 0.9.6a has security problems, so the support for 826 # anything earlier than 0.9.6e will be dropped soon. 827 if (&Net::SSLeay::OPENSSL_VERSION_NUMBER >= 0x0090601f) { 828 $max_length = 2000000000 unless (defined $max_length); 829 my ($pending, $peek_length, $found, $done); 830 while (blength($reply) < $max_length and !$done) { 831 #Block if necessary until we get some data 832 $got = Net::SSLeay::peek($ssl,1); 833 last if print_errs('SSL_peek'); 834 835 $pending = Net::SSLeay::pending($ssl) + blength($reply); 836 $peek_length = ($pending > $max_length) ? $max_length : $pending; 837 $peek_length -= blength($reply); 838 $got = Net::SSLeay::peek($ssl, $peek_length); 839 last if print_errs('SSL_peek'); 840 $peek_length = blength($got); 841 842 #$found = index($got, $delim); # Old and broken 843 844 # the delimiter may be split across two gets, so we prepend 845 # a little from the last get onto this one before we check 846 # for a match 847 my $match; 848 if(blength($reply) >= blength($delim) - 1) { 849 #if what we've read so far is greater or equal 850 #in length of what we need to prepatch 851 $match = substr $reply, blength($reply) - blength($delim) + 1; 852 } else { 853 $match = $reply; 854 } 855 856 $match .= $got; 857 $found = index($match, $delim); 858 859 if ($found > -1) { 860 #$got = Net::SSLeay::ssl_read_all($ssl, $found+$len_delim); 861 #read up to the end of the delimiter 862 $got = Net::SSLeay::ssl_read_all($ssl, 863 $found + $len_delim 864 - ((blength($match)) - (blength($got)))); 865 $done = 1; 866 } else { 867 $got = Net::SSLeay::ssl_read_all($ssl, $peek_length); 868 $done = 1 if ($peek_length == $max_length - blength($reply)); 869 } 870 871 last if print_errs('SSL_read'); 872 debug_read(\$reply, \$got) if $trace>1; 873 last if $got eq ''; 874 $reply .= $got; 875 } 876 } else { 877 while (!defined $max_length || length $reply < $max_length) { 878 $got = Net::SSLeay::ssl_read_all($ssl,1); # one by one 879 last if print_errs('SSL_read'); 880 debug_read(\$reply, \$got) if $trace>1; 881 last if $got eq ''; 882 $reply .= $got; 883 last if $len_delim 884 && substr($reply, blength($reply)-$len_delim) eq $delim; 885 } 886 } 887 return $reply; 888} 889 890sub tcp_read_until { 891 my ($delim, $max_length) = @_; 892 893 # guess the delim string if missing 894 if ( ! defined $delim ) { 895 if ( defined $/ && length $/ ) { $delim = $/ } 896 else { $delim = "\n" } # Note: \n,$/ value depends on the platform 897 } 898 my $len_delim = length $delim; 899 900 my ($n,$got); 901 my $reply = ''; 902 903 while (!defined $max_length || length $reply < $max_length) { 904 $n = sysread(SSLCAT_S, $got, 1); # one by one 905 warn "tcp_read_until: $!" if !defined $n; 906 debug_read(\$reply, \$got) if $trace>1; 907 last if !$n; # EOF 908 $reply .= $got; 909 last if $len_delim 910 && substr($reply, blength($reply)-$len_delim) eq $delim; 911 } 912 return $reply; 913} 914 915# ssl_read_CRLF($ssl [, $max_length]) 916sub ssl_read_CRLF ($;$) { ssl_read_until($_[0], $CRLF, $_[1]) } 917sub tcp_read_CRLF { tcp_read_until($CRLF, $_[0]) } 918 919# ssl_write_CRLF($ssl, $message) writes $message and appends CRLF 920sub ssl_write_CRLF ($$) { 921 # the next line uses less memory but might use more network packets 922 return ssl_write_all($_[0], $_[1]) + ssl_write_all($_[0], $CRLF); 923 924 # the next few lines do the same thing at the expense of memory, with 925 # the chance that it will use less packets, since CRLF is in the original 926 # message and won't be sent separately. 927 928 #my $data_ref; 929 #if (ref $_[1]) { $data_ref = $_[1] } 930 # else { $data_ref = \$_[1] } 931 #my $message = $$data_ref . $CRLF; 932 #return ssl_write_all($_[0], \$message); 933} 934 935sub tcp_write_CRLF { 936 # the next line uses less memory but might use more network packets 937 return tcp_write_all($_[0]) + tcp_write_all($CRLF); 938 939 # the next few lines do the same thing at the expense of memory, with 940 # the chance that it will use less packets, since CRLF is in the original 941 # message and won't be sent separately. 942 943 #my $data_ref; 944 #if (ref $_[1]) { $data_ref = $_[1] } 945 # else { $data_ref = \$_[1] } 946 #my $message = $$data_ref . $CRLF; 947 #return tcp_write_all($_[0], \$message); 948} 949 950### Quickly print out with whom we're talking 951 952sub dump_peer_certificate ($) { 953 my ($ssl) = @_; 954 my $cert = get_peer_certificate($ssl); 955 return if print_errs('get_peer_certificate'); 956 print "no cert defined\n" if !defined($cert); 957 # Cipher=NONE with empty cert fix 958 if (!defined($cert) || ($cert == 0)) { 959 warn "cert = `$cert'\n" if $trace; 960 return "Subject Name: undefined\nIssuer Name: undefined\n"; 961 } else { 962 my $x = 'Subject Name: ' 963 . X509_NAME_oneline(X509_get_subject_name($cert)) . "\n" 964 . 'Issuer Name: ' 965 . X509_NAME_oneline(X509_get_issuer_name($cert)) . "\n"; 966 Net::SSLeay::X509_free($cert); 967 return $x; 968 } 969} 970 971### Arrange some randomness for eay PRNG 972 973sub randomize (;$$$) { 974 my ($rn_seed_file, $seed, $egd_path) = @_; 975 my $rnsf = defined($rn_seed_file) && -r $rn_seed_file; 976 977 $egd_path = ''; 978 $egd_path = $ENV{'EGD_PATH'} if $ENV{'EGD_PATH'}; 979 980 RAND_seed(rand() + $$); # Stir it with time and pid 981 982 unless ($rnsf || -r $Net::SSLeay::random_device || $seed || -S $egd_path) { 983 my $poll_retval = Net::SSLeay::RAND_poll(); 984 warn "Random number generator not seeded!!!" if $trace && !$poll_retval; 985 } 986 987 RAND_load_file($rn_seed_file, -s _) if $rnsf; 988 RAND_seed($seed) if $seed; 989 RAND_seed($ENV{RND_SEED}) if $ENV{RND_SEED}; 990 RAND_load_file($Net::SSLeay::random_device, $Net::SSLeay::how_random/8) 991 if -r $Net::SSLeay::random_device; 992} 993 994sub new_x_ctx { 995 if ($ssl_version == 2) { 996 unless (exists &Net::SSLeay::CTX_v2_new) { 997 warn "ssl_version has been set to 2, but this version of OpenSSL has been compiled without SSLv2 support"; 998 return undef; 999 } 1000 $ctx = CTX_v2_new(); 1001 } 1002 elsif ($ssl_version == 3) { $ctx = CTX_v3_new(); } 1003 elsif ($ssl_version == 10) { $ctx = CTX_tlsv1_new(); } 1004 elsif ($ssl_version == 11) { 1005 unless (exists &Net::SSLeay::CTX_tlsv1_1_new) { 1006 warn "ssl_version has been set to 11, but this version of OpenSSL has been compiled without TLSv1.1 support"; 1007 return undef; 1008 } 1009 $ctx = CTX_tlsv1_1_new; 1010 } 1011 elsif ($ssl_version == 12) { 1012 unless (exists &Net::SSLeay::CTX_tlsv1_2_new) { 1013 warn "ssl_version has been set to 12, but this version of OpenSSL has been compiled without TLSv1.2 support"; 1014 return undef; 1015 } 1016 $ctx = CTX_tlsv1_2_new; 1017 } 1018 elsif ($ssl_version == 13) { 1019 unless (eval { Net::SSLeay::TLS1_3_VERSION(); } ) { 1020 warn "ssl_version has been set to 13, but this version of OpenSSL has been compiled without TLSv1.3 support"; 1021 return undef; 1022 } 1023 $ctx = CTX_new(); 1024 unless(Net::SSLeay::CTX_set_min_proto_version($ctx, Net::SSLeay::TLS1_3_VERSION())) { 1025 warn "CTX_set_min_proto failed for TLSv1.3"; 1026 return undef; 1027 } 1028 unless(Net::SSLeay::CTX_set_max_proto_version($ctx, Net::SSLeay::TLS1_3_VERSION())) { 1029 warn "CTX_set_max_proto failed for TLSv1.3"; 1030 return undef; 1031 } 1032 } 1033 else { $ctx = CTX_new(); } 1034 return $ctx; 1035} 1036 1037### 1038### Standard initialisation. Initialise the ssl library in the usual way 1039### at most once. Override this if you need differnet initialisation 1040### SSLeay_add_ssl_algorithms is also protected against multiple runs in SSLeay.xs 1041### and is also mutex protected in threading perls 1042### 1043 1044my $library_initialised; 1045sub initialize 1046{ 1047 if (!$library_initialised) 1048 { 1049 load_error_strings(); # Some bloat, but I'm after ease of use 1050 SSLeay_add_ssl_algorithms(); # and debuggability. 1051 randomize(); 1052 $library_initialised++; 1053 } 1054} 1055 1056### 1057### Basic request - response primitive (don't use for https) 1058### 1059 1060sub sslcat { # address, port, message, $crt, $key --> reply / (reply,errs,cert) 1061 my ($dest_serv, $port, $out_message, $crt_path, $key_path) = @_; 1062 my ($ctx, $ssl, $got, $errs, $written); 1063 1064 ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); 1065 return (wantarray ? (undef, $errs) : undef) unless $got; 1066 1067 ### Do SSL negotiation stuff 1068 1069 warn "Creating SSL $ssl_version context...\n" if $trace>2; 1070 initialize(); # Will init at most once 1071 1072 $ctx = new_x_ctx(); 1073 goto cleanup2 if $errs = print_errs('CTX_new') or !$ctx; 1074 1075 CTX_set_options($ctx, &OP_ALL); 1076 goto cleanup2 if $errs = print_errs('CTX_set_options'); 1077 1078 warn "Cert `$crt_path' given without key" if $crt_path && !$key_path; 1079 set_cert_and_key($ctx, $crt_path, $key_path) if $crt_path; 1080 1081 warn "Creating SSL connection (context was '$ctx')...\n" if $trace>2; 1082 $ssl = new($ctx); 1083 goto cleanup if $errs = print_errs('SSL_new') or !$ssl; 1084 1085 warn "Setting fd (ctx $ctx, con $ssl)...\n" if $trace>2; 1086 set_fd($ssl, fileno(SSLCAT_S)); 1087 goto cleanup if $errs = print_errs('set_fd'); 1088 1089 warn "Entering SSL negotiation phase...\n" if $trace>2; 1090 1091 if ($trace>2) { 1092 my $i = 0; 1093 my $p = ''; 1094 my $cipher_list = 'Cipher list: '; 1095 $p=Net::SSLeay::get_cipher_list($ssl,$i); 1096 $cipher_list .= $p if $p; 1097 do { 1098 $i++; 1099 $cipher_list .= ', ' . $p if $p; 1100 $p=Net::SSLeay::get_cipher_list($ssl,$i); 1101 } while $p; 1102 $cipher_list .= '\n'; 1103 warn $cipher_list; 1104 } 1105 1106 $got = Net::SSLeay::connect($ssl); 1107 warn "SSLeay connect returned $got\n" if $trace>2; 1108 goto cleanup if $errs = print_errs('SSL_connect'); 1109 1110 my $server_cert = get_peer_certificate($ssl); 1111 print_errs('get_peer_certificate'); 1112 if ($trace>1) { 1113 warn "Cipher `" . get_cipher($ssl) . "'\n"; 1114 print_errs('get_ciper'); 1115 warn dump_peer_certificate($ssl); 1116 } 1117 1118 ### Connected. Exchange some data (doing repeated tries if necessary). 1119 1120 warn "sslcat $$: sending " . blength($out_message) . " bytes...\n" 1121 if $trace==3; 1122 warn "sslcat $$: sending `$out_message' (" . blength($out_message) 1123 . " bytes)...\n" if $trace>3; 1124 ($written, $errs) = ssl_write_all($ssl, $out_message); 1125 goto cleanup unless $written; 1126 1127 sleep $slowly if $slowly; # Closing too soon can abort broken servers 1128 Net::SSLeay::shutdown($ssl); # Useful starting with OpenSSL 1.1.1e 1129 CORE::shutdown SSLCAT_S, 1; # Half close --> No more output, send EOF to server 1130 1131 warn "waiting for reply...\n" if $trace>2; 1132 ($got, $errs) = ssl_read_all($ssl); 1133 warn "Got " . blength($got) . " bytes.\n" if $trace==3; 1134 warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; 1135 1136cleanup: 1137 free ($ssl); 1138 $errs .= print_errs('SSL_free'); 1139cleanup2: 1140 CTX_free ($ctx); 1141 $errs .= print_errs('CTX_free'); 1142 close SSLCAT_S; 1143 return wantarray ? ($got, $errs, $server_cert) : $got; 1144} 1145 1146sub tcpcat { # address, port, message, $crt, $key --> reply / (reply,errs,cert) 1147 my ($dest_serv, $port, $out_message) = @_; 1148 my ($got, $errs, $written); 1149 1150 ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); 1151 return (wantarray ? (undef, $errs) : undef) unless $got; 1152 1153 ### Connected. Exchange some data (doing repeated tries if necessary). 1154 1155 warn "tcpcat $$: sending " . blength($out_message) . " bytes...\n" 1156 if $trace==3; 1157 warn "tcpcat $$: sending `$out_message' (" . blength($out_message) 1158 . " bytes)...\n" if $trace>3; 1159 ($written, $errs) = tcp_write_all($out_message); 1160 goto cleanup unless $written; 1161 1162 sleep $slowly if $slowly; # Closing too soon can abort broken servers 1163 CORE::shutdown SSLCAT_S, 1; # Half close --> No more output, send EOF to server 1164 1165 warn "waiting for reply...\n" if $trace>2; 1166 ($got, $errs) = tcp_read_all(); 1167 warn "Got " . blength($got) . " bytes.\n" if $trace==3; 1168 warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; 1169 1170cleanup: 1171 close SSLCAT_S; 1172 return wantarray ? ($got, $errs) : $got; 1173} 1174 1175sub tcpxcat { 1176 my ($usessl, $site, $port, $req, $crt_path, $key_path) = @_; 1177 if ($usessl) { 1178 return sslcat($site, $port, $req, $crt_path, $key_path); 1179 } else { 1180 return tcpcat($site, $port, $req); 1181 } 1182} 1183 1184### 1185### Basic request - response primitive, this is different from sslcat 1186### because this does not shutdown the connection. 1187### 1188 1189sub https_cat { # address, port, message --> returns reply / (reply,errs,cert) 1190 my ($dest_serv, $port, $out_message, $crt_path, $key_path) = @_; 1191 my ($ctx, $ssl, $got, $errs, $written); 1192 1193 ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); 1194 return (wantarray ? (undef, $errs) : undef) unless $got; 1195 1196 ### Do SSL negotiation stuff 1197 1198 warn "Creating SSL $ssl_version context...\n" if $trace>2; 1199 initialize(); 1200 1201 $ctx = new_x_ctx(); 1202 goto cleanup2 if $errs = print_errs('CTX_new') or !$ctx; 1203 1204 CTX_set_options($ctx, &OP_ALL); 1205 goto cleanup2 if $errs = print_errs('CTX_set_options'); 1206 1207 warn "Cert `$crt_path' given without key" if $crt_path && !$key_path; 1208 set_cert_and_key($ctx, $crt_path, $key_path) if $crt_path; 1209 1210 warn "Creating SSL connection (context was '$ctx')...\n" if $trace>2; 1211 $ssl = new($ctx); 1212 goto cleanup if $errs = print_errs('SSL_new') or !$ssl; 1213 1214 warn "Setting fd (ctx $ctx, con $ssl)...\n" if $trace>2; 1215 set_fd($ssl, fileno(SSLCAT_S)); 1216 goto cleanup if $errs = print_errs('set_fd'); 1217 1218 warn "Entering SSL negotiation phase...\n" if $trace>2; 1219 1220 if ($trace>2) { 1221 my $i = 0; 1222 my $p = ''; 1223 my $cipher_list = 'Cipher list: '; 1224 $p=Net::SSLeay::get_cipher_list($ssl,$i); 1225 $cipher_list .= $p if $p; 1226 do { 1227 $i++; 1228 $cipher_list .= ', ' . $p if $p; 1229 $p=Net::SSLeay::get_cipher_list($ssl,$i); 1230 } while $p; 1231 $cipher_list .= '\n'; 1232 warn $cipher_list; 1233 } 1234 1235 $got = Net::SSLeay::connect($ssl); 1236 warn "SSLeay connect failed" if $trace>2 && $got==0; 1237 goto cleanup if $errs = print_errs('SSL_connect'); 1238 1239 my $server_cert = get_peer_certificate($ssl); 1240 print_errs('get_peer_certificate'); 1241 if ($trace>1) { 1242 warn "Cipher `" . get_cipher($ssl) . "'\n"; 1243 print_errs('get_ciper'); 1244 warn dump_peer_certificate($ssl); 1245 } 1246 1247 ### Connected. Exchange some data (doing repeated tries if necessary). 1248 1249 warn "https_cat $$: sending " . blength($out_message) . " bytes...\n" 1250 if $trace==3; 1251 warn "https_cat $$: sending `$out_message' (" . blength($out_message) 1252 . " bytes)...\n" if $trace>3; 1253 ($written, $errs) = ssl_write_all($ssl, $out_message); 1254 goto cleanup unless $written; 1255 1256 warn "waiting for reply...\n" if $trace>2; 1257 ($got, $errs) = ssl_read_all($ssl); 1258 warn "Got " . blength($got) . " bytes.\n" if $trace==3; 1259 warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; 1260 1261cleanup: 1262 free ($ssl); 1263 $errs .= print_errs('SSL_free'); 1264cleanup2: 1265 CTX_free ($ctx); 1266 $errs .= print_errs('CTX_free'); 1267 close SSLCAT_S; 1268 return wantarray ? ($got, $errs, $server_cert) : $got; 1269} 1270 1271sub http_cat { # address, port, message --> returns reply / (reply,errs,cert) 1272 my ($dest_serv, $port, $out_message) = @_; 1273 my ($got, $errs, $written); 1274 1275 ($got, $errs) = open_proxy_tcp_connection($dest_serv, $port); 1276 return (wantarray ? (undef, $errs) : undef) unless $got; 1277 1278 ### Connected. Exchange some data (doing repeated tries if necessary). 1279 1280 warn "http_cat $$: sending " . blength($out_message) . " bytes...\n" 1281 if $trace==3; 1282 warn "http_cat $$: sending `$out_message' (" . blength($out_message) 1283 . " bytes)...\n" if $trace>3; 1284 ($written, $errs) = tcp_write_all($out_message); 1285 goto cleanup unless $written; 1286 1287 warn "waiting for reply...\n" if $trace>2; 1288 ($got, $errs) = tcp_read_all(); 1289 warn "Got " . blength($got) . " bytes.\n" if $trace==3; 1290 warn "Got `$got' (" . blength($got) . " bytes)\n" if $trace>3; 1291 1292cleanup: 1293 close SSLCAT_S; 1294 return wantarray ? ($got, $errs) : $got; 1295} 1296 1297sub httpx_cat { 1298 my ($usessl, $site, $port, $req, $crt_path, $key_path) = @_; 1299 warn "httpx_cat: usessl=$usessl ($site:$port)" if $trace; 1300 if ($usessl) { 1301 return https_cat($site, $port, $req, $crt_path, $key_path); 1302 } else { 1303 return http_cat($site, $port, $req); 1304 } 1305} 1306 1307### 1308### Easy set up of private key and certificate 1309### 1310 1311sub set_cert_and_key ($$$) { 1312 my ($ctx, $cert_path, $key_path) = @_; 1313 my $errs = ''; 1314 # Following will ask password unless private key is not encrypted 1315 CTX_use_PrivateKey_file( $ctx, $key_path, &FILETYPE_PEM ) == 1 1316 or $errs .= print_errs("private key `$key_path' ($!)"); 1317 CTX_use_certificate_file ($ctx, $cert_path, &FILETYPE_PEM) == 1 1318 or $errs .= print_errs("certificate `$cert_path' ($!)"); 1319 return wantarray ? (undef, $errs) : ($errs eq ''); 1320} 1321 1322### Old deprecated API 1323 1324sub set_server_cert_and_key ($$$) { &set_cert_and_key } 1325 1326### Set up to use web proxy 1327 1328sub set_proxy ($$;**) { 1329 ($proxyhost, $proxyport, $proxyuser, $proxypass) = @_; 1330 require MIME::Base64 if $proxyuser; 1331 $proxyauth = $proxyuser 1332 ? $CRLF . 'Proxy-authorization: Basic ' 1333 . MIME::Base64::encode("$proxyuser:$proxypass", '') 1334 : ''; 1335} 1336 1337### 1338### Easy https manipulation routines 1339### 1340 1341sub make_form { 1342 my (@fields) = @_; 1343 my $form; 1344 while (@fields) { 1345 my ($name, $data) = (shift(@fields), shift(@fields)); 1346 $data =~ s/([^\w\-.\@\$ ])/sprintf("%%%2.2x",ord($1))/gse; 1347 $data =~ tr[ ][+]; 1348 $form .= "$name=$data&"; 1349 } 1350 chop $form; 1351 return $form; 1352} 1353 1354sub make_headers { 1355 my (@headers) = @_; 1356 my $headers; 1357 while (@headers) { 1358 my $header = shift(@headers); 1359 my $value = shift(@headers); 1360 $header =~ s/:$//; 1361 $value =~ s/\x0d?\x0a$//; # because we add it soon, see below 1362 $headers .= "$header: $value$CRLF"; 1363 } 1364 return $headers; 1365} 1366 1367sub do_httpx3 { 1368 my ($method, $usessl, $site, $port, $path, $headers, 1369 $content, $mime_type, $crt_path, $key_path) = @_; 1370 my ($response, $page, $h,$v); 1371 1372 my $len = blength($content); 1373 if ($len) { 1374 $mime_type = "application/x-www-form-urlencoded" unless $mime_type; 1375 $content = "Content-Type: $mime_type$CRLF" 1376 . "Content-Length: $len$CRLF$CRLF$content"; 1377 } else { 1378 $content = "$CRLF$CRLF"; 1379 } 1380 my $req = "$method $path HTTP/1.0$CRLF"; 1381 unless (defined $headers && $headers =~ /^Host:/m) { 1382 $req .= "Host: $site"; 1383 unless (($port == 80 && !$usessl) || ($port == 443 && $usessl)) { 1384 $req .= ":$port"; 1385 } 1386 $req .= $CRLF; 1387 } 1388 $req .= (defined $headers ? $headers : '') . "Accept: */*$CRLF$content"; 1389 1390 warn "do_httpx3($method,$usessl,$site:$port)" if $trace; 1391 my ($http, $errs, $server_cert) 1392 = httpx_cat($usessl, $site, $port, $req, $crt_path, $key_path); 1393 return (undef, "HTTP/1.0 900 NET OR SSL ERROR$CRLF$CRLF$errs") if $errs; 1394 1395 $http = '' if !defined $http; 1396 ($headers, $page) = split /\s?\n\s?\n/, $http, 2; 1397 warn "headers >$headers< page >>$page<< http >>>$http<<<" if $trace>1; 1398 ($response, $headers) = split /\s?\n/, $headers, 2; 1399 return ($page, $response, $headers, $server_cert); 1400} 1401 1402sub do_https3 { splice(@_,1,0) = 1; do_httpx3; } # Legacy undocumented 1403 1404### do_https2() is a legacy version in the sense that it is unable 1405### to return all instances of duplicate headers. 1406 1407sub do_httpx2 { 1408 my ($page, $response, $headers, $server_cert) = &do_httpx3; 1409 X509_free($server_cert) if defined $server_cert; 1410 return ($page, $response, defined $headers ? 1411 map( { ($h,$v)=/^(\S+)\:\s*(.*)$/; (uc($h),$v); } 1412 split(/\s?\n/, $headers) 1413 ) : () 1414 ); 1415} 1416 1417sub do_https2 { splice(@_,1,0) = 1; do_httpx2; } # Legacy undocumented 1418 1419### Returns headers as a hash where multiple instances of same header 1420### are handled correctly. 1421 1422sub do_httpx4 { 1423 my ($page, $response, $headers, $server_cert) = &do_httpx3; 1424 my %hr = (); 1425 for my $hh (split /\s?\n/, $headers) { 1426 my ($h,$v) = ($hh =~ /^(\S+)\:\s*(.*)$/); 1427 push @{$hr{uc($h)}}, $v; 1428 } 1429 return ($page, $response, \%hr, $server_cert); 1430} 1431 1432sub do_https4 { splice(@_,1,0) = 1; do_httpx4; } # Legacy undocumented 1433 1434# https 1435 1436sub get_https { do_httpx2(GET => 1, @_) } 1437sub post_https { do_httpx2(POST => 1, @_) } 1438sub put_https { do_httpx2(PUT => 1, @_) } 1439sub head_https { do_httpx2(HEAD => 1, @_) } 1440 1441sub get_https3 { do_httpx3(GET => 1, @_) } 1442sub post_https3 { do_httpx3(POST => 1, @_) } 1443sub put_https3 { do_httpx3(PUT => 1, @_) } 1444sub head_https3 { do_httpx3(HEAD => 1, @_) } 1445 1446sub get_https4 { do_httpx4(GET => 1, @_) } 1447sub post_https4 { do_httpx4(POST => 1, @_) } 1448sub put_https4 { do_httpx4(PUT => 1, @_) } 1449sub head_https4 { do_httpx4(HEAD => 1, @_) } 1450 1451# http 1452 1453sub get_http { do_httpx2(GET => 0, @_) } 1454sub post_http { do_httpx2(POST => 0, @_) } 1455sub put_http { do_httpx2(PUT => 0, @_) } 1456sub head_http { do_httpx2(HEAD => 0, @_) } 1457 1458sub get_http3 { do_httpx3(GET => 0, @_) } 1459sub post_http3 { do_httpx3(POST => 0, @_) } 1460sub put_http3 { do_httpx3(PUT => 0, @_) } 1461sub head_http3 { do_httpx3(HEAD => 0, @_) } 1462 1463sub get_http4 { do_httpx4(GET => 0, @_) } 1464sub post_http4 { do_httpx4(POST => 0, @_) } 1465sub put_http4 { do_httpx4(PUT => 0, @_) } 1466sub head_http4 { do_httpx4(HEAD => 0, @_) } 1467 1468# Either https or http 1469 1470sub get_httpx { do_httpx2(GET => @_) } 1471sub post_httpx { do_httpx2(POST => @_) } 1472sub put_httpx { do_httpx2(PUT => @_) } 1473sub head_httpx { do_httpx2(HEAD => @_) } 1474 1475sub get_httpx3 { do_httpx3(GET => @_) } 1476sub post_httpx3 { do_httpx3(POST => @_) } 1477sub put_httpx3 { do_httpx3(PUT => @_) } 1478sub head_httpx3 { do_httpx3(HEAD => @_) } 1479 1480sub get_httpx4 { do_httpx4(GET => @_) } 1481sub post_httpx4 { do_httpx4(POST => @_) } 1482sub put_httpx4 { do_httpx4(PUT => @_) } 1483sub head_httpx4 { do_httpx4(HEAD => @_) } 1484 1485### Legacy, don't use 1486# ($page, $respone_or_err, %headers) = do_https(...); 1487 1488sub do_https { 1489 my ($site, $port, $path, $method, $headers, 1490 $content, $mime_type, $crt_path, $key_path) = @_; 1491 1492 do_https2($method, $site, $port, $path, $headers, 1493 $content, $mime_type, $crt_path, $key_path); 1494} 1495 14961; 1497__END__ 1498 1499