def __init__(self, protocol=None, manual_validation=False, extra_trust_roots=None):
if not isinstance(manual_validation, bool):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(manual_validation)<EOL>))<EOL><DEDENT>self._manual_validation = manual_validation<EOL>if protocol is None:<EOL><INDENT>protocol = set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL><DEDENT>if isinstance(protocol, str_cls):<EOL><INDENT>protocol = set([protocol])<EOL><DEDENT>elif not isinstance(protocol, set):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(protocol)<EOL>))<EOL><DEDENT>valid_protocols = set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>unsupported_protocols = protocol - valid_protocols<EOL>if unsupported_protocols:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>repr(unsupported_protocols)<EOL>))<EOL><DEDENT>self._protocols = protocol<EOL>self._extra_trust_roots = []<EOL>if extra_trust_roots:<EOL><INDENT>for extra_trust_root in extra_trust_roots:<EOL><INDENT>if isinstance(extra_trust_root, Certificate):<EOL><INDENT>extra_trust_root = extra_trust_root.asn1<EOL><DEDENT>elif isinstance(extra_trust_root, byte_cls):<EOL><INDENT>extra_trust_root = parse_certificate(extra_trust_root)<EOL><DEDENT>elif isinstance(extra_trust_root, str_cls):<EOL><INDENT>with open(extra_trust_root, '<STR_LIT:rb>') as f:<EOL><INDENT>extra_trust_root = parse_certificate(f.read())<EOL><DEDENT><DEDENT>elif not isinstance(extra_trust_root, x509.Certificate):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(extra_trust_root)<EOL>))<EOL><DEDENT>self._extra_trust_roots.append(extra_trust_root)<EOL><DEDENT><DEDENT>ssl_ctx = None<EOL>try:<EOL><INDENT>if libcrypto_version_info < (<NUM_LIT:1>, <NUM_LIT:1>):<EOL><INDENT>method = libssl.SSLv23_method()<EOL><DEDENT>else:<EOL><INDENT>method = libssl.TLS_method()<EOL><DEDENT>ssl_ctx = libssl.SSL_CTX_new(method)<EOL>if is_null(ssl_ctx):<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>)<EOL><DEDENT>self._ssl_ctx = ssl_ctx<EOL>libssl.SSL_CTX_set_timeout(ssl_ctx, <NUM_LIT>)<EOL>libssl.SSL_CTX_ctrl(<EOL>ssl_ctx,<EOL>LibsslConst.SSL_CTRL_SET_SESS_CACHE_MODE,<EOL>LibsslConst.SSL_SESS_CACHE_CLIENT,<EOL>null()<EOL>)<EOL>if sys.platform in set(['<STR_LIT:win32>', '<STR_LIT>']):<EOL><INDENT>trust_list_path = _trust_list_path<EOL>if trust_list_path is None:<EOL><INDENT>trust_list_path = get_path()<EOL><DEDENT>if sys.platform == '<STR_LIT:win32>':<EOL><INDENT>path_encoding = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>path_encoding = '<STR_LIT:utf-8>'<EOL><DEDENT>result = libssl.SSL_CTX_load_verify_locations(<EOL>ssl_ctx,<EOL>trust_list_path.encode(path_encoding),<EOL>null()<EOL>)<EOL><DEDENT>else:<EOL><INDENT>result = libssl.SSL_CTX_set_default_verify_paths(ssl_ctx)<EOL><DEDENT>handle_openssl_error(result)<EOL>verify_mode = LibsslConst.SSL_VERIFY_NONE if manual_validation else LibsslConst.SSL_VERIFY_PEER<EOL>libssl.SSL_CTX_set_verify(ssl_ctx, verify_mode, null())<EOL>result = libssl.SSL_CTX_set_cipher_list(<EOL>ssl_ctx,<EOL>(<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>b'<STR_LIT>'<EOL>)<EOL>)<EOL>handle_openssl_error(result)<EOL>disabled_protocols = set(['<STR_LIT>'])<EOL>disabled_protocols |= (valid_protocols - self._protocols)<EOL>for disabled_protocol in disabled_protocols:<EOL><INDENT>libssl.SSL_CTX_ctrl(<EOL>ssl_ctx,<EOL>LibsslConst.SSL_CTRL_OPTIONS,<EOL>_PROTOCOL_MAP[disabled_protocol],<EOL>null()<EOL>)<EOL><DEDENT>if self._extra_trust_roots:<EOL><INDENT>x509_store = libssl.SSL_CTX_get_cert_store(ssl_ctx)<EOL>for cert in self._extra_trust_roots:<EOL><INDENT>oscrypto_cert = load_certificate(cert)<EOL>result = libssl.X509_STORE_add_cert(<EOL>x509_store,<EOL>oscrypto_cert.x509<EOL>)<EOL>handle_openssl_error(result)<EOL><DEDENT><DEDENT><DEDENT>except (Exception):<EOL><INDENT>if ssl_ctx:<EOL><INDENT>libssl.SSL_CTX_free(ssl_ctx)<EOL><DEDENT>self._ssl_ctx = None<EOL>raise<EOL><DEDENT>
:param protocol:
    A unicode string or set of unicode strings representing allowable
    protocols to negotiate with the server:

     - "TLSv1.2"
     - "TLSv1.1"
     - "TLSv1"
     - "SSLv3"

    Default is: {"TLSv1", "TLSv1.1", "TLSv1.2"}

:param manual_validation:
    If certificate and certificate path validation should be skipped
    and left to the developer to implement

:param extra_trust_roots:
    A list containing one or more certificates to be treated as trust
    roots, in one of the following formats:
     - A byte string of the DER encoded certificate
     - A unicode string of the certificate filename
     - An asn1crypto.x509.Certificate object
     - An oscrypto.asymmetric.Certificate object

:raises:
    ValueError - when any of the parameters contain an invalid value
    TypeError - when any of the parameters are of the wrong type
    OSError - when an error is returned by the OS crypto library