def pyssl_error(obj, ret): errcode = lib.ERR_peek_last_error() errstr = "" errval = 0 errtype = SSLError e = lib.ERR_peek_last_error() if obj.ssl != ffi.NULL: err = lib.SSL_get_error(obj.ssl, ret) if err == SSL_ERROR_ZERO_RETURN: errtype = SSLZeroReturnError errstr = "TLS/SSL connection has been closed" errval = SSL_ERROR_ZERO_RETURN elif err == SSL_ERROR_WANT_READ: errtype = SSLWantReadError errstr = "The operation did not complete (read)" errval = SSL_ERROR_WANT_READ elif err == SSL_ERROR_WANT_WRITE: errtype = SSLWantWriteError errstr = "The operation did not complete (write)" errval = SSL_ERROR_WANT_WRITE elif err == SSL_ERROR_WANT_X509_LOOKUP: errstr = "The operation did not complete (X509 lookup)" errval = SSL_ERROR_WANT_X509_LOOKUP elif err == SSL_ERROR_WANT_CONNECT: errstr = "The operation did not complete (connect)" errval = SSL_ERROR_WANT_CONNECT elif err == SSL_ERROR_SYSCALL: if e == 0: if ret == 0 or obj.socket is not None: errtype = SSLEOFError errstr = "EOF occurred in violation of protocol" errval = SSL_ERROR_EOF elif ret == -1 and obj.socket is not None: # the underlying BIO reported an I/0 error lib.ERR_clear_error() s = obj.get_socket_or_None() s.errorhandler() assert 0, "must not get here" #errno = ffi.errno #return IOError(errno) else: errtype = SSLSyscallError errstr = "Some I/O error occurred" errval = SSL_ERROR_SYSCALL else: errstr = _str_from_buf(lib.ERR_error_string(e, ffi.NULL)) errval = SSL_ERROR_SYSCALL elif err == SSL_ERROR_SSL: errval = SSL_ERROR_SSL if errcode != 0: errstr = _str_from_buf(lib.ERR_error_string(errcode, ffi.NULL)) else: errstr = "A failure in the SSL library occurred" else: errstr = "Invalid error code" errval = SSL_ERROR_INVALID_ERROR_CODE return fill_sslerror(errtype, errval, errstr, e)
def hash_name_mapper_callback(obj_name, userdata): if not obj_name: return name_fetcher = ffi.from_handle(userdata) # Ignore aliased names, they pollute the list and OpenSSL appears # to have a its own definition of alias as the resulting list # still contains duplicate and alternate names for several # algorithms. if obj_name.alias != 0: return name = _str_from_buf(obj_name.name) name_fetcher.meth_names.append(name)
def fill_sslerror(obj, errtype, ssl_errno, errstr, errcode): reason_str = None lib_str = None if errcode != 0: err_lib = lib.ERR_GET_LIB(errcode) err_reason = lib.ERR_GET_REASON(errcode) reason_str = ERR_CODES_TO_NAMES.get((err_lib, err_reason), None) lib_str = LIB_CODES_TO_NAMES.get(err_lib, None) # Set last part of msg to a lower-case version of reason_str errstr = _str_from_buf(lib.ERR_reason_error_string(errcode)) msg = errstr if not errstr: msg = "unknown error" # verify code for cert validation error verify_str = None if (obj and errtype is SSLCertVerificationError): verify_code = lib.SSL_get_verify_result(obj.ssl) if lib.Cryptography_HAS_102_VERIFICATION_ERROR_CODES: if verify_code == lib.X509_V_ERR_HOSTNAME_MISMATCH: verify_str = ("Host name mismatch, certificate is not " f"valid for '{obj.server_hostname}'.") elif verify_code == lib.X509_V_ERR_IP_ADDRESS_MISMATCH: verify_str = ("IP address name mismatch, certificate is not " f"valid for '{obj.server_hostname}'.") if not verify_str: verify_str = ffi.string( lib.X509_verify_cert_error_string(verify_code)).decode() if verify_str and reason_str and lib_str: msg = f"[{lib_str}: {reason_str}] {errstr}: {verify_str}" elif reason_str and lib_str: msg = "[%s: %s] %s" % (lib_str, reason_str, errstr) elif lib_str: msg = "[%s] %s" % (lib_str, errstr) err_value = errtype(ssl_errno, msg) err_value.reason = reason_str if reason_str else None err_value.library = lib_str if lib_str else None if (obj and errtype is SSLCertVerificationError): err_value.verify_code = verify_code err_value.verify_message = verify_str return err_value
def fill_sslerror(errtype, ssl_errno, errstr, errcode): reason_str = None lib_str = None if errcode != 0: err_lib = lib.ERR_GET_LIB(errcode) err_reason = lib.ERR_GET_REASON(errcode) reason_str = ERR_CODES_TO_NAMES.get((err_lib, err_reason), None) lib_str = LIB_CODES_TO_NAMES.get(err_lib, None) # Set last part of msg to a lower-case version of reason_str errstr = _str_from_buf(lib.ERR_reason_error_string(errcode)) msg = errstr if not errstr: msg = "unknown error" if reason_str and lib_str: msg = "[%s: %s] %s" % (lib_str, reason_str, errstr) elif lib_str: msg = "[%s] %s" % (lib_str, errstr) err_value = errtype(ssl_errno, msg) err_value.reason = reason_str if reason_str else None err_value.library = lib_str if lib_str else None return err_value
def pyssl_error(obj, ret): errcode = lib.ERR_peek_last_error() errstr = "" errval = 0 errtype = SSLError e = lib.ERR_peek_last_error() if obj.ssl != ffi.NULL: err = obj.err if err.ssl == SSL_ERROR_ZERO_RETURN: errtype = SSLZeroReturnError errstr = "TLS/SSL connection has been closed (EOF)" errval = SSL_ERROR_ZERO_RETURN elif err.ssl == SSL_ERROR_WANT_READ: errtype = SSLWantReadError errstr = "The operation did not complete (read)" errval = SSL_ERROR_WANT_READ elif err.ssl == SSL_ERROR_WANT_WRITE: errtype = SSLWantWriteError errstr = "The operation did not complete (write)" errval = SSL_ERROR_WANT_WRITE elif err.ssl == SSL_ERROR_WANT_X509_LOOKUP: errstr = "The operation did not complete (X509 lookup)" errval = SSL_ERROR_WANT_X509_LOOKUP elif err.ssl == SSL_ERROR_WANT_CONNECT: errstr = "The operation did not complete (connect)" errval = SSL_ERROR_WANT_CONNECT elif err.ssl == SSL_ERROR_SYSCALL: if e == 0: if ret == 0 or obj.socket is None: errtype = SSLEOFError errstr = "EOF occurred in violation of protocol" errval = SSL_ERROR_EOF elif ret == -1 and obj.socket is not None: # the underlying BIO reported an I/0 error lib.ERR_clear_error() # s = obj.get_socket_or_None() if sys.platform == 'win32': if err.ws: return OSError(err.ws) if err.c: ffi.errno = err.c errno = ffi.errno return OSError(errno, os.strerror(errno)) else: errtype = SSLSyscallError errstr = "Some I/O error occurred" errval = SSL_ERROR_SYSCALL else: errstr = _str_from_buf(lib.ERR_lib_error_string(e)) errval = SSL_ERROR_SYSCALL elif err.ssl == SSL_ERROR_SSL: errval = SSL_ERROR_SSL if e == 0: errstr = "A failure in the SSL library occurred" else: errstr = _str_from_buf(lib.ERR_lib_error_string(errcode)) err_lib = lib.ERR_GET_LIB(e) err_reason = lib.ERR_GET_REASON(e) reason_str = ERR_CODES_TO_NAMES.get((err_lib, err_reason), None) if (lib.ERR_GET_LIB(e) == lib.ERR_LIB_SSL and reason_str == 'CERTIFICATE_VERIFY_FAILED'): errtype = SSLCertVerificationError else: errstr = "Invalid error code" errval = SSL_ERROR_INVALID_ERROR_CODE return fill_sslerror(obj, errtype, errval, errstr, e)