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