from time import time
from base64 import b16encode
from functools import partial
from operator import __eq__, __ne__, __lt__, __le__, __gt__, __ge__

from six import (
    integer_types as _integer_types,
    text_type as _text_type)

from OpenSSL._util import (
    ffi as _ffi,
    lib as _lib,
    exception_from_error_queue as _exception_from_error_queue,
    byte_string as _byte_string,
    native as _native)

FILETYPE_PEM = _lib.SSL_FILETYPE_PEM
FILETYPE_ASN1 = _lib.SSL_FILETYPE_ASN1

# TODO This was an API mistake.  OpenSSL has no such constant.
FILETYPE_TEXT = 2 ** 16 - 1

TYPE_RSA = _lib.EVP_PKEY_RSA
TYPE_DSA = _lib.EVP_PKEY_DSA


class Error(Exception):
    """
    An error occurred in an `OpenSSL.crypto` API.
    """


_raise_current_error = partial(_exception_from_error_queue, Error)

def _untested_error(where):
    """
    An OpenSSL API failed somehow.  Additionally, the failure which was
    encountered isn't one that's exercised by the test suite so future behavior
    of pyOpenSSL is now somewhat less predictable.
    """
    raise RuntimeError("Unknown %s failure" % (where,))



def _new_mem_buf(buffer=None):
    """
    Allocate a new OpenSSL memory BIO.

    Arrange for the garbage collector to clean it up automatically.

    :param buffer: None or some bytes to use to put into the BIO so that they
        can be read out.
    """
    if buffer is None:
        bio = _lib.BIO_new(_lib.BIO_s_mem())
        free = _lib.BIO_free
    else:
        data = _ffi.new("char[]", buffer)
        bio = _lib.BIO_new_mem_buf(data, len(buffer))
        # Keep the memory alive as long as the bio is alive!
        def free(bio, ref=data):
            return _lib.BIO_free(bio)

    if bio == _ffi.NULL:
        # TODO: This is untested.
        _raise_current_error()

    bio = _ffi.gc(bio, free)
    return bio



def _bio_to_string(bio):
    """
    Copy the contents of an OpenSSL BIO object into a Python byte string.
    """
    result_buffer = _ffi.new('char**')
    buffer_length = _lib.BIO_get_mem_data(bio, result_buffer)
    return _ffi.buffer(result_buffer[0], buffer_length)[:]



def _set_asn1_time(boundary, when):
    """
    The the time value of an ASN1 time object.

    @param boundary: An ASN1_GENERALIZEDTIME pointer (or an object safely
        castable to that type) which will have its value set.
    @param when: A string representation of the desired time value.

    @raise TypeError: If C{when} is not a L{bytes} string.
    @raise ValueError: If C{when} does not represent a time in the required
        format.
    @raise RuntimeError: If the time value cannot be set for some other
        (unspecified) reason.
    """
    if not isinstance(when, bytes):
        raise TypeError("when must be a byte string")

    set_result = _lib.ASN1_GENERALIZEDTIME_set_string(
        _ffi.cast('ASN1_GENERALIZEDTIME*', boundary), when)
    if set_result == 0:
        dummy = _ffi.gc(_lib.ASN1_STRING_new(), _lib.ASN1_STRING_free)
        _lib.ASN1_STRING_set(dummy, when, len(when))
        check_result = _lib.ASN1_GENERALIZEDTIME_check(
            _ffi.cast('ASN1_GENERALIZEDTIME*', dummy))
        if not check_result:
            raise ValueError("Invalid string")
        else:
            _untested_error()



def _get_asn1_time(timestamp):
    """
    Retrieve the time value of an ASN1 time object.

    @param timestamp: An ASN1_GENERALIZEDTIME* (or an object safely castable to
        that type) from which the time value will be retrieved.

    @return: The time value from C{timestamp} as a L{bytes} string in a certain
        format.  Or C{None} if the object contains no time value.
    """
    string_timestamp = _ffi.cast('ASN1_STRING*', timestamp)
    if _lib.ASN1_STRING_length(string_timestamp) == 0:
        return None
    elif _lib.ASN1_STRING_type(string_timestamp) == _lib.V_ASN1_GENERALIZEDTIME:
        return _ffi.string(_lib.ASN1_STRING_data(string_timestamp))
    else:
        generalized_timestamp = _ffi.new("ASN1_GENERALIZEDTIME**")
        _lib.ASN1_TIME_to_generalizedtime(timestamp, generalized_timestamp)
        if generalized_timestamp[0] == _ffi.NULL:
            # This may happen:
            #   - if timestamp was not an ASN1_TIME
            #   - if allocating memory for the ASN1_GENERALIZEDTIME failed
            #   - if a copy of the time data from timestamp cannot be made for
            #     the newly allocated ASN1_GENERALIZEDTIME
            #
            # These are difficult to test.  cffi enforces the ASN1_TIME type.
            # Memory allocation failures are a pain to trigger
            # deterministically.
            _untested_error("ASN1_TIME_to_generalizedtime")
        else:
            string_timestamp = _ffi.cast(
                "ASN1_STRING*", generalized_timestamp[0])
            string_data = _lib.ASN1_STRING_data(string_timestamp)
            string_result = _ffi.string(string_data)
            _lib.ASN1_GENERALIZEDTIME_free(generalized_timestamp[0])
            return string_result



class PKey(object):
    _only_public = False
    _initialized = True

    def __init__(self):
        pkey = _lib.EVP_PKEY_new()
        self._pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free)
        self._initialized = False


    def generate_key(self, type, bits):
        """
        Generate a key of a given type, with a given number of a bits

        :param type: The key type (TYPE_RSA or TYPE_DSA)
        :param bits: The number of bits

        :return: None
        """
        if not isinstance(type, int):
            raise TypeError("type must be an integer")

        if not isinstance(bits, int):
            raise TypeError("bits must be an integer")

        # TODO Check error return
        exponent = _lib.BN_new()
        exponent = _ffi.gc(exponent, _lib.BN_free)
        _lib.BN_set_word(exponent, _lib.RSA_F4)

        if type == TYPE_RSA:
            if bits <= 0:
                raise ValueError("Invalid number of bits")

            rsa = _lib.RSA_new()

            result = _lib.RSA_generate_key_ex(rsa, bits, exponent, _ffi.NULL)
            if result == 0:
                # TODO: The test for this case is commented out.  Different
                # builds of OpenSSL appear to have different failure modes that
                # make it hard to test.  Visual inspection of the OpenSSL
                # source reveals that a return value of 0 signals an error.
                # Manual testing on a particular build of OpenSSL suggests that
                # this is probably the appropriate way to handle those errors.
                _raise_current_error()

            result = _lib.EVP_PKEY_assign_RSA(self._pkey, rsa)
            if not result:
                # TODO: It appears as though this can fail if an engine is in
                # use which does not support RSA.
                _raise_current_error()

        elif type == TYPE_DSA:
            dsa = _lib.DSA_generate_parameters(
                bits, _ffi.NULL, 0, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL)
            if dsa == _ffi.NULL:
                # TODO: This is untested.
                _raise_current_error()
            if not _lib.DSA_generate_key(dsa):
                # TODO: This is untested.
                _raise_current_error()
            if not _lib.EVP_PKEY_assign_DSA(self._pkey, dsa):
                # TODO: This is untested.
                _raise_current_error()
        else:
            raise Error("No such key type")

        self._initialized = True


    def check(self):
        """
        Check the consistency of an RSA private key.

        :return: True if key is consistent.
        :raise Error: if the key is inconsistent.
        :raise TypeError: if the key is of a type which cannot be checked.
            Only RSA keys can currently be checked.
        """
        if self._only_public:
            raise TypeError("public key only")

        if _lib.EVP_PKEY_type(self._pkey.type) != _lib.EVP_PKEY_RSA:
            raise TypeError("key type unsupported")

        rsa = _lib.EVP_PKEY_get1_RSA(self._pkey)
        rsa = _ffi.gc(rsa, _lib.RSA_free)
        result = _lib.RSA_check_key(rsa)
        if result:
            return True
        _raise_current_error()


    def type(self):
        """
        Returns the type of the key

        :return: The type of the key.
        """
        return self._pkey.type


    def bits(self):
        """
        Returns the number of bits of the key

        :return: The number of bits of the key.
        """
        return _lib.EVP_PKEY_bits(self._pkey)
PKeyType = PKey



class X509Name(object):
    def __init__(self, name):
        """
        Create a new X509Name, copying the given X509Name instance.

        :param name: An X509Name object to copy
        """
        name = _lib.X509_NAME_dup(name._name)
        self._name = _ffi.gc(name, _lib.X509_NAME_free)


    def __setattr__(self, name, value):
        if name.startswith('_'):
            return super(X509Name, self).__setattr__(name, value)

        # Note: we really do not want str subclasses here, so we do not use
        # isinstance.
        if type(name) is not str:
            raise TypeError("attribute name must be string, not '%.200s'" % (
                    type(value).__name__,))

        nid = _lib.OBJ_txt2nid(_byte_string(name))
        if nid == _lib.NID_undef:
            try:
                _raise_current_error()
            except Error:
                pass
            raise AttributeError("No such attribute")

        # If there's an old entry for this NID, remove it
        for i in range(_lib.X509_NAME_entry_count(self._name)):
            ent = _lib.X509_NAME_get_entry(self._name, i)
            ent_obj = _lib.X509_NAME_ENTRY_get_object(ent)
            ent_nid = _lib.OBJ_obj2nid(ent_obj)
            if nid == ent_nid:
                ent = _lib.X509_NAME_delete_entry(self._name, i)
                _lib.X509_NAME_ENTRY_free(ent)
                break

        if isinstance(value, _text_type):
            value = value.encode('utf-8')

        add_result = _lib.X509_NAME_add_entry_by_NID(
            self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0)
        if not add_result:
            _raise_current_error()


    def __getattr__(self, name):
        """
        Find attribute. An X509Name object has the following attributes:
        countryName (alias C), stateOrProvince (alias ST), locality (alias L),
        organization (alias O), organizationalUnit (alias OU), commonName (alias
        CN) and more...
        """
        nid = _lib.OBJ_txt2nid(_byte_string(name))
        if nid == _lib.NID_undef:
            # This is a bit weird.  OBJ_txt2nid indicated failure, but it seems
            # a lower level function, a2d_ASN1_OBJECT, also feels the need to
            # push something onto the error queue.  If we don't clean that up
            # now, someone else will bump into it later and be quite confused.
            # See lp#314814.
            try:
                _raise_current_error()
            except Error:
                pass
            return super(X509Name, self).__getattr__(name)

        entry_index = _lib.X509_NAME_get_index_by_NID(self._name, nid, -1)
        if entry_index == -1:
            return None

        entry = _lib.X509_NAME_get_entry(self._name, entry_index)
        data = _lib.X509_NAME_ENTRY_get_data(entry)

        result_buffer = _ffi.new("unsigned char**")
        data_length = _lib.ASN1_STRING_to_UTF8(result_buffer, data)
        if data_length < 0:
            # TODO: This is untested.
            _raise_current_error()

        try:
            result = _ffi.buffer(result_buffer[0], data_length)[:].decode('utf-8')
        finally:
            # XXX untested
            _lib.OPENSSL_free(result_buffer[0])
        return result


    def _cmp(op):
        def f(self, other):
            if not isinstance(other, X509Name):
                return NotImplemented
            result = _lib.X509_NAME_cmp(self._name, other._name)
            return op(result, 0)
        return f

    __eq__ = _cmp(__eq__)
    __ne__ = _cmp(__ne__)

    __lt__ = _cmp(__lt__)
    __le__ = _cmp(__le__)

    __gt__ = _cmp(__gt__)
    __ge__ = _cmp(__ge__)

    def __repr__(self):
        """
        String representation of an X509Name
        """
        result_buffer = _ffi.new("char[]", 512);
        format_result = _lib.X509_NAME_oneline(
            self._name, result_buffer, len(result_buffer))

        if format_result == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        return "<X509Name object '%s'>" % (
            _native(_ffi.string(result_buffer)),)


    def hash(self):
        """
        Return the hash value of this name

        :return: None
        """
        return _lib.X509_NAME_hash(self._name)


    def der(self):
        """
        Return the DER encoding of this name

        :return: A :py:class:`bytes` instance giving the DER encoded form of
            this name.
        """
        result_buffer = _ffi.new('unsigned char**')
        encode_result = _lib.i2d_X509_NAME(self._name, result_buffer)
        if encode_result < 0:
            # TODO: This is untested.
            _raise_current_error()

        string_result = _ffi.buffer(result_buffer[0], encode_result)[:]
        _lib.OPENSSL_free(result_buffer[0])
        return string_result


    def get_components(self):
        """
        Returns the split-up components of this name.

        :return: List of tuples (name, value).
        """
        result = []
        for i in range(_lib.X509_NAME_entry_count(self._name)):
            ent = _lib.X509_NAME_get_entry(self._name, i)

            fname = _lib.X509_NAME_ENTRY_get_object(ent)
            fval = _lib.X509_NAME_ENTRY_get_data(ent)

            nid = _lib.OBJ_obj2nid(fname)
            name = _lib.OBJ_nid2sn(nid)

            result.append((
                    _ffi.string(name),
                    _ffi.string(
                        _lib.ASN1_STRING_data(fval),
                        _lib.ASN1_STRING_length(fval))))

        return result
X509NameType = X509Name


class X509Extension(object):
    def __init__(self, type_name, critical, value, subject=None, issuer=None):
        """
        :param typename: The name of the extension to create.
        :type typename: :py:data:`str`

        :param critical: A flag indicating whether this is a critical extension.

        :param value: The value of the extension.
        :type value: :py:data:`str`

        :param subject: Optional X509 cert to use as subject.
        :type subject: :py:class:`X509`

        :param issuer: Optional X509 cert to use as issuer.
        :type issuer: :py:class:`X509`

        :return: The X509Extension object
        """
        ctx = _ffi.new("X509V3_CTX*")

        # A context is necessary for any extension which uses the r2i conversion
        # method.  That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
        # Start off by initializing most of the fields to NULL.
        _lib.X509V3_set_ctx(ctx, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL, 0)

        # We have no configuration database - but perhaps we should (some
        # extensions may require it).
        _lib.X509V3_set_ctx_nodb(ctx)

        # Initialize the subject and issuer, if appropriate.  ctx is a local,
        # and as far as I can tell none of the X509V3_* APIs invoked here steal
        # any references, so no need to mess with reference counts or duplicates.
        if issuer is not None:
            if not isinstance(issuer, X509):
                raise TypeError("issuer must be an X509 instance")
            ctx.issuer_cert = issuer._x509
        if subject is not None:
            if not isinstance(subject, X509):
                raise TypeError("subject must be an X509 instance")
            ctx.subject_cert = subject._x509

        if critical:
            # There are other OpenSSL APIs which would let us pass in critical
            # separately, but they're harder to use, and since value is already
            # a pile of crappy junk smuggling a ton of utterly important
            # structured data, what's the point of trying to avoid nasty stuff
            # with strings? (However, X509V3_EXT_i2d in particular seems like it
            # would be a better API to invoke.  I do not know where to get the
            # ext_struc it desires for its last parameter, though.)
            value = b"critical," + value

        extension = _lib.X509V3_EXT_nconf(_ffi.NULL, ctx, type_name, value)
        if extension == _ffi.NULL:
            _raise_current_error()
        self._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)


    @property
    def _nid(self):
        return _lib.OBJ_obj2nid(self._extension.object)

    _prefixes = {
        _lib.GEN_EMAIL: "email",
        _lib.GEN_DNS: "DNS",
        _lib.GEN_URI: "URI",
        }

    def _subjectAltNameString(self):
        method = _lib.X509V3_EXT_get(self._extension)
        if method == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()
        payload = self._extension.value.data
        length = self._extension.value.length

        payloadptr = _ffi.new("unsigned char**")
        payloadptr[0] = payload

        if method.it != _ffi.NULL:
            ptr = _lib.ASN1_ITEM_ptr(method.it)
            data = _lib.ASN1_item_d2i(_ffi.NULL, payloadptr, length, ptr)
            names = _ffi.cast("GENERAL_NAMES*", data)
        else:
            names = _ffi.cast(
                "GENERAL_NAMES*",
                method.d2i(_ffi.NULL, payloadptr, length))

        parts = []
        for i in range(_lib.sk_GENERAL_NAME_num(names)):
            name = _lib.sk_GENERAL_NAME_value(names, i)
            try:
                label = self._prefixes[name.type]
            except KeyError:
                bio = _new_mem_buf()
                _lib.GENERAL_NAME_print(bio, name)
                parts.append(_native(_bio_to_string(bio)))
            else:
                value = _native(
                    _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[:])
                parts.append(label + ":" + value)
        return ", ".join(parts)


    def __str__(self):
        """
        :return: a nice text representation of the extension
        """
        if _lib.NID_subject_alt_name == self._nid:
            return self._subjectAltNameString()

        bio = _new_mem_buf()
        print_result = _lib.X509V3_EXT_print(bio, self._extension, 0, 0)
        if not print_result:
            # TODO: This is untested.
            _raise_current_error()

        return _native(_bio_to_string(bio))


    def get_critical(self):
        """
        Returns the critical field of the X509Extension

        :return: The critical field.
        """
        return _lib.X509_EXTENSION_get_critical(self._extension)


    def get_short_name(self):
        """
        Returns the short version of the type name of the X509Extension

        :return: The short type name.
        """
        obj = _lib.X509_EXTENSION_get_object(self._extension)
        nid = _lib.OBJ_obj2nid(obj)
        return _ffi.string(_lib.OBJ_nid2sn(nid))


    def get_data(self):
        """
        Returns the data of the X509Extension

        :return: A :py:data:`str` giving the X509Extension's ASN.1 encoded data.
        """
        octet_result = _lib.X509_EXTENSION_get_data(self._extension)
        string_result = _ffi.cast('ASN1_STRING*', octet_result)
        char_result = _lib.ASN1_STRING_data(string_result)
        result_length = _lib.ASN1_STRING_length(string_result)
        return _ffi.buffer(char_result, result_length)[:]

X509ExtensionType = X509Extension


class X509Req(object):
    def __init__(self):
        req = _lib.X509_REQ_new()
        self._req = _ffi.gc(req, _lib.X509_REQ_free)


    def set_pubkey(self, pkey):
        """
        Set the public key of the certificate request

        :param pkey: The public key to use
        :return: None
        """
        set_result = _lib.X509_REQ_set_pubkey(self._req, pkey._pkey)
        if not set_result:
            # TODO: This is untested.
            _raise_current_error()


    def get_pubkey(self):
        """
        Get the public key from the certificate request

        :return: The public key
        """
        pkey = PKey.__new__(PKey)
        pkey._pkey = _lib.X509_REQ_get_pubkey(self._req)
        if pkey._pkey == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()
        pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
        pkey._only_public = True
        return pkey


    def set_version(self, version):
        """
        Set the version subfield (RFC 2459, section 4.1.2.1) of the certificate
        request.

        :param version: The version number
        :return: None
        """
        set_result = _lib.X509_REQ_set_version(self._req, version)
        if not set_result:
            _raise_current_error()


    def get_version(self):
        """
        Get the version subfield (RFC 2459, section 4.1.2.1) of the certificate
        request.

        :return: an integer giving the value of the version subfield
        """
        return _lib.X509_REQ_get_version(self._req)


    def get_subject(self):
        """
        Create an X509Name object for the subject of the certificate request

        :return: An X509Name object
        """
        name = X509Name.__new__(X509Name)
        name._name = _lib.X509_REQ_get_subject_name(self._req)
        if name._name == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        # The name is owned by the X509Req structure.  As long as the X509Name
        # Python object is alive, keep the X509Req Python object alive.
        name._owner = self

        return name


    def add_extensions(self, extensions):
        """
        Add extensions to the request.

        :param extensions: a sequence of X509Extension objects
        :return: None
        """
        stack = _lib.sk_X509_EXTENSION_new_null()
        if stack == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free)

        for ext in extensions:
            if not isinstance(ext, X509Extension):
                raise ValueError("One of the elements is not an X509Extension")

            # TODO push can fail (here and elsewhere)
            _lib.sk_X509_EXTENSION_push(stack, ext._extension)

        add_result = _lib.X509_REQ_add_extensions(self._req, stack)
        if not add_result:
            # TODO: This is untested.
            _raise_current_error()


    def sign(self, pkey, digest):
        """
        Sign the certificate request using the supplied key and digest

        :param pkey: The key to sign with
        :param digest: The message digest to use
        :return: None
        """
        if pkey._only_public:
            raise ValueError("Key has only public part")

        if not pkey._initialized:
            raise ValueError("Key is uninitialized")

        digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
        if digest_obj == _ffi.NULL:
            raise ValueError("No such digest method")

        sign_result = _lib.X509_REQ_sign(self._req, pkey._pkey, digest_obj)
        if not sign_result:
            # TODO: This is untested.
            _raise_current_error()


    def verify(self, pkey):
        """
        Verifies a certificate request using the supplied public key

        :param key: a public key
        :return: True if the signature is correct.

        :raise OpenSSL.crypto.Error: If the signature is invalid or there is a
            problem verifying the signature.
        """
        if not isinstance(pkey, PKey):
            raise TypeError("pkey must be a PKey instance")

        result = _lib.X509_REQ_verify(self._req, pkey._pkey)
        if result <= 0:
            _raise_current_error()

        return result


X509ReqType = X509Req



class X509(object):
    def __init__(self):
        # TODO Allocation failure?  And why not __new__ instead of __init__?
        x509 = _lib.X509_new()
        self._x509 = _ffi.gc(x509, _lib.X509_free)


    def set_version(self, version):
        """
        Set version number of the certificate

        :param version: The version number
        :type version: :py:class:`int`

        :return: None
        """
        if not isinstance(version, int):
            raise TypeError("version must be an integer")

        _lib.X509_set_version(self._x509, version)


    def get_version(self):
        """
        Return version number of the certificate

        :return: Version number as a Python integer
        """
        return _lib.X509_get_version(self._x509)


    def get_pubkey(self):
        """
        Get the public key of the certificate

        :return: The public key
        """
        pkey = PKey.__new__(PKey)
        pkey._pkey = _lib.X509_get_pubkey(self._x509)
        if pkey._pkey == _ffi.NULL:
            _raise_current_error()
        pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
        pkey._only_public = True
        return pkey


    def set_pubkey(self, pkey):
        """
        Set the public key of the certificate

        :param pkey: The public key

        :return: None
        """
        if not isinstance(pkey, PKey):
            raise TypeError("pkey must be a PKey instance")

        set_result = _lib.X509_set_pubkey(self._x509, pkey._pkey)
        if not set_result:
            _raise_current_error()


    def sign(self, pkey, digest):
        """
        Sign the certificate using the supplied key and digest

        :param pkey: The key to sign with
        :param digest: The message digest to use
        :return: None
        """
        if not isinstance(pkey, PKey):
            raise TypeError("pkey must be a PKey instance")

        if pkey._only_public:
            raise ValueError("Key only has public part")

        if not pkey._initialized:
            raise ValueError("Key is uninitialized")

        evp_md = _lib.EVP_get_digestbyname(_byte_string(digest))
        if evp_md == _ffi.NULL:
            raise ValueError("No such digest method")

        sign_result = _lib.X509_sign(self._x509, pkey._pkey, evp_md)
        if not sign_result:
            _raise_current_error()


    def get_signature_algorithm(self):
        """
        Retrieve the signature algorithm used in the certificate

        :return: A byte string giving the name of the signature algorithm used in
                 the certificate.
        :raise ValueError: If the signature algorithm is undefined.
        """
        alg = self._x509.cert_info.signature.algorithm
        nid = _lib.OBJ_obj2nid(alg)
        if nid == _lib.NID_undef:
            raise ValueError("Undefined signature algorithm")
        return _ffi.string(_lib.OBJ_nid2ln(nid))


    def digest(self, digest_name):
        """
        Return the digest of the X509 object.

        :param digest_name: The name of the digest algorithm to use.
        :type digest_name: :py:class:`bytes`

        :return: The digest of the object
        """
        digest = _lib.EVP_get_digestbyname(_byte_string(digest_name))
        if digest == _ffi.NULL:
            raise ValueError("No such digest method")

        result_buffer = _ffi.new("char[]", _lib.EVP_MAX_MD_SIZE)
        result_length = _ffi.new("unsigned int[]", 1)
        result_length[0] = len(result_buffer)

        digest_result = _lib.X509_digest(
            self._x509, digest, result_buffer, result_length)

        if not digest_result:
            # TODO: This is untested.
            _raise_current_error()

        return b":".join([
                b16encode(ch).upper() for ch
                in _ffi.buffer(result_buffer, result_length[0])])


    def subject_name_hash(self):
        """
        Return the hash of the X509 subject.

        :return: The hash of the subject.
        """
        return _lib.X509_subject_name_hash(self._x509)


    def set_serial_number(self, serial):
        """
        Set serial number of the certificate

        :param serial: The serial number
        :type serial: :py:class:`int`

        :return: None
        """
        if not isinstance(serial, _integer_types):
            raise TypeError("serial must be an integer")

        hex_serial = hex(serial)[2:]
        if not isinstance(hex_serial, bytes):
            hex_serial = hex_serial.encode('ascii')

        bignum_serial = _ffi.new("BIGNUM**")

        # BN_hex2bn stores the result in &bignum.  Unless it doesn't feel like
        # it.  If bignum is still NULL after this call, then the return value is
        # actually the result.  I hope.  -exarkun
        small_serial = _lib.BN_hex2bn(bignum_serial, hex_serial)

        if bignum_serial[0] == _ffi.NULL:
            set_result = _lib.ASN1_INTEGER_set(
                _lib.X509_get_serialNumber(self._x509), small_serial)
            if set_result:
                # TODO Not tested
                _raise_current_error()
        else:
            asn1_serial = _lib.BN_to_ASN1_INTEGER(bignum_serial[0], _ffi.NULL)
            _lib.BN_free(bignum_serial[0])
            if asn1_serial == _ffi.NULL:
                # TODO Not tested
                _raise_current_error()
            asn1_serial = _ffi.gc(asn1_serial, _lib.ASN1_INTEGER_free)
            set_result = _lib.X509_set_serialNumber(self._x509, asn1_serial)
            if not set_result:
                # TODO Not tested
                _raise_current_error()


    def get_serial_number(self):
        """
        Return serial number of the certificate

        :return: Serial number as a Python integer
        """
        asn1_serial = _lib.X509_get_serialNumber(self._x509)
        bignum_serial = _lib.ASN1_INTEGER_to_BN(asn1_serial, _ffi.NULL)
        try:
            hex_serial = _lib.BN_bn2hex(bignum_serial)
            try:
                hexstring_serial = _ffi.string(hex_serial)
                serial = int(hexstring_serial, 16)
                return serial
            finally:
                _lib.OPENSSL_free(hex_serial)
        finally:
            _lib.BN_free(bignum_serial)


    def gmtime_adj_notAfter(self, amount):
        """
        Adjust the time stamp for when the certificate stops being valid

        :param amount: The number of seconds by which to adjust the ending
                       validity time.
        :type amount: :py:class:`int`

        :return: None
        """
        if not isinstance(amount, int):
            raise TypeError("amount must be an integer")

        notAfter = _lib.X509_get_notAfter(self._x509)
        _lib.X509_gmtime_adj(notAfter, amount)


    def gmtime_adj_notBefore(self, amount):
        """
        Change the timestamp for when the certificate starts being valid to the current
        time plus an offset.

        :param amount: The number of seconds by which to adjust the starting validity
                       time.
        :return: None
        """
        if not isinstance(amount, int):
            raise TypeError("amount must be an integer")

        notBefore = _lib.X509_get_notBefore(self._x509)
        _lib.X509_gmtime_adj(notBefore, amount)


    def has_expired(self):
        """
        Check whether the certificate has expired.

        :return: True if the certificate has expired, false otherwise
        """
        now = int(time())
        notAfter = _lib.X509_get_notAfter(self._x509)
        return _lib.ASN1_UTCTIME_cmp_time_t(
            _ffi.cast('ASN1_UTCTIME*', notAfter), now) < 0


    def _get_boundary_time(self, which):
        return _get_asn1_time(which(self._x509))


    def get_notBefore(self):
        """
        Retrieve the time stamp for when the certificate starts being valid

        :return: A string giving the timestamp, in the format::

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm

                 or None if there is no value set.
        """
        return self._get_boundary_time(_lib.X509_get_notBefore)


    def _set_boundary_time(self, which, when):
        return _set_asn1_time(which(self._x509), when)


    def set_notBefore(self, when):
        """
        Set the time stamp for when the certificate starts being valid

        :param when: A string giving the timestamp, in the format:

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm
        :type when: :py:class:`bytes`

        :return: None
        """
        return self._set_boundary_time(_lib.X509_get_notBefore, when)


    def get_notAfter(self):
        """
        Retrieve the time stamp for when the certificate stops being valid

        :return: A string giving the timestamp, in the format::

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm

                 or None if there is no value set.
        """
        return self._get_boundary_time(_lib.X509_get_notAfter)


    def set_notAfter(self, when):
        """
        Set the time stamp for when the certificate stops being valid

        :param when: A string giving the timestamp, in the format:

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm
        :type when: :py:class:`bytes`

        :return: None
        """
        return self._set_boundary_time(_lib.X509_get_notAfter, when)


    def _get_name(self, which):
        name = X509Name.__new__(X509Name)
        name._name = which(self._x509)
        if name._name == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        # The name is owned by the X509 structure.  As long as the X509Name
        # Python object is alive, keep the X509 Python object alive.
        name._owner = self

        return name


    def _set_name(self, which, name):
        if not isinstance(name, X509Name):
            raise TypeError("name must be an X509Name")
        set_result = which(self._x509, name._name)
        if not set_result:
            # TODO: This is untested.
            _raise_current_error()


    def get_issuer(self):
        """
        Create an X509Name object for the issuer of the certificate

        :return: An X509Name object
        """
        return self._get_name(_lib.X509_get_issuer_name)


    def set_issuer(self, issuer):
        """
        Set the issuer of the certificate

        :param issuer: The issuer name
        :type issuer: :py:class:`X509Name`

        :return: None
        """
        return self._set_name(_lib.X509_set_issuer_name, issuer)


    def get_subject(self):
        """
        Create an X509Name object for the subject of the certificate

        :return: An X509Name object
        """
        return self._get_name(_lib.X509_get_subject_name)


    def set_subject(self, subject):
        """
        Set the subject of the certificate

        :param subject: The subject name
        :type subject: :py:class:`X509Name`
        :return: None
        """
        return self._set_name(_lib.X509_set_subject_name, subject)


    def get_extension_count(self):
        """
        Get the number of extensions on the certificate.

        :return: The number of extensions as an integer.
        """
        return _lib.X509_get_ext_count(self._x509)


    def add_extensions(self, extensions):
        """
        Add extensions to the certificate.

        :param extensions: a sequence of X509Extension objects
        :return: None
        """
        for ext in extensions:
            if not isinstance(ext, X509Extension):
                raise ValueError("One of the elements is not an X509Extension")

            add_result = _lib.X509_add_ext(self._x509, ext._extension, -1)
            if not add_result:
                _raise_current_error()


    def get_extension(self, index):
        """
        Get a specific extension of the certificate by index.

        :param index: The index of the extension to retrieve.
        :return: The X509Extension object at the specified index.
        """
        ext = X509Extension.__new__(X509Extension)
        ext._extension = _lib.X509_get_ext(self._x509, index)
        if ext._extension == _ffi.NULL:
            raise IndexError("extension index out of bounds")

        extension = _lib.X509_EXTENSION_dup(ext._extension)
        ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)
        return ext

X509Type = X509



class X509Store(object):
    def __init__(self):
        store = _lib.X509_STORE_new()
        self._store = _ffi.gc(store, _lib.X509_STORE_free)


    def add_cert(self, cert):
        if not isinstance(cert, X509):
            raise TypeError()

        result = _lib.X509_STORE_add_cert(self._store, cert._x509)
        if not result:
            _raise_current_error()


X509StoreType = X509Store



def load_certificate(type, buffer):
    """
    Load a certificate from a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)

    :param buffer: The buffer the certificate is stored in
    :type buffer: :py:class:`bytes`

    :return: The X509 object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    if type == FILETYPE_PEM:
        x509 = _lib.PEM_read_bio_X509(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
    elif type == FILETYPE_ASN1:
        x509 = _lib.d2i_X509_bio(bio, _ffi.NULL);
    else:
        raise ValueError(
            "type argument must be FILETYPE_PEM or FILETYPE_ASN1")

    if x509 == _ffi.NULL:
        _raise_current_error()

    cert = X509.__new__(X509)
    cert._x509 = _ffi.gc(x509, _lib.X509_free)
    return cert


def dump_certificate(type, cert):
    """
    Dump a certificate to a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1, or
        FILETYPE_TEXT)
    :param cert: The certificate to dump
    :return: The buffer with the dumped certificate in
    """
    bio = _new_mem_buf()

    if type == FILETYPE_PEM:
        result_code = _lib.PEM_write_bio_X509(bio, cert._x509)
    elif type == FILETYPE_ASN1:
        result_code = _lib.i2d_X509_bio(bio, cert._x509)
    elif type == FILETYPE_TEXT:
        result_code = _lib.X509_print_ex(bio, cert._x509, 0, 0)
    else:
        raise ValueError(
            "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
            "FILETYPE_TEXT")

    return _bio_to_string(bio)



def dump_privatekey(type, pkey, cipher=None, passphrase=None):
    """
    Dump a private key to a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1, or
        FILETYPE_TEXT)
    :param pkey: The PKey to dump
    :param cipher: (optional) if encrypted PEM format, the cipher to
                   use
    :param passphrase: (optional) if encrypted PEM format, this can be either
                       the passphrase to use, or a callback for providing the
                       passphrase.
    :return: The buffer with the dumped key in
    :rtype: :py:data:`str`
    """
    bio = _new_mem_buf()

    if cipher is not None:
        if passphrase is None:
            raise TypeError(
                "if a value is given for cipher "
                "one must also be given for passphrase")
        cipher_obj = _lib.EVP_get_cipherbyname(_byte_string(cipher))
        if cipher_obj == _ffi.NULL:
            raise ValueError("Invalid cipher name")
    else:
        cipher_obj = _ffi.NULL

    helper = _PassphraseHelper(type, passphrase)
    if type == FILETYPE_PEM:
        result_code = _lib.PEM_write_bio_PrivateKey(
            bio, pkey._pkey, cipher_obj, _ffi.NULL, 0,
            helper.callback, helper.callback_args)
        helper.raise_if_problem()
    elif type == FILETYPE_ASN1:
        result_code = _lib.i2d_PrivateKey_bio(bio, pkey._pkey)
    elif type == FILETYPE_TEXT:
        rsa = _lib.EVP_PKEY_get1_RSA(pkey._pkey)
        result_code = _lib.RSA_print(bio, rsa, 0)
        # TODO RSA_free(rsa)?
    else:
        raise ValueError(
            "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
            "FILETYPE_TEXT")

    if result_code == 0:
        _raise_current_error()

    return _bio_to_string(bio)



def _X509_REVOKED_dup(original):
    copy = _lib.X509_REVOKED_new()
    if copy == _ffi.NULL:
        # TODO: This is untested.
        _raise_current_error()

    if original.serialNumber != _ffi.NULL:
        copy.serialNumber = _lib.ASN1_INTEGER_dup(original.serialNumber)

    if original.revocationDate != _ffi.NULL:
        copy.revocationDate = _lib.M_ASN1_TIME_dup(original.revocationDate)

    if original.extensions != _ffi.NULL:
        extension_stack = _lib.sk_X509_EXTENSION_new_null()
        for i in range(_lib.sk_X509_EXTENSION_num(original.extensions)):
            original_ext = _lib.sk_X509_EXTENSION_value(original.extensions, i)
            copy_ext = _lib.X509_EXTENSION_dup(original_ext)
            _lib.sk_X509_EXTENSION_push(extension_stack, copy_ext)
        copy.extensions = extension_stack

    copy.sequence = original.sequence
    return copy



class Revoked(object):
    # http://www.openssl.org/docs/apps/x509v3_config.html#CRL_distribution_points_
    # which differs from crl_reasons of crypto/x509v3/v3_enum.c that matches
    # OCSP_crl_reason_str.  We use the latter, just like the command line
    # program.
    _crl_reasons = [
        b"unspecified",
        b"keyCompromise",
        b"CACompromise",
        b"affiliationChanged",
        b"superseded",
        b"cessationOfOperation",
        b"certificateHold",
        # b"removeFromCRL",
        ]

    def __init__(self):
        revoked = _lib.X509_REVOKED_new()
        self._revoked = _ffi.gc(revoked, _lib.X509_REVOKED_free)


    def set_serial(self, hex_str):
        """
        Set the serial number of a revoked Revoked structure

        :param hex_str: The new serial number.
        :type hex_str: :py:data:`str`
        :return: None
        """
        bignum_serial = _ffi.gc(_lib.BN_new(), _lib.BN_free)
        bignum_ptr = _ffi.new("BIGNUM**")
        bignum_ptr[0] = bignum_serial
        bn_result = _lib.BN_hex2bn(bignum_ptr, hex_str)
        if not bn_result:
            raise ValueError("bad hex string")

        asn1_serial = _ffi.gc(
            _lib.BN_to_ASN1_INTEGER(bignum_serial, _ffi.NULL),
            _lib.ASN1_INTEGER_free)
        _lib.X509_REVOKED_set_serialNumber(self._revoked, asn1_serial)


    def get_serial(self):
        """
        Return the serial number of a Revoked structure

        :return: The serial number as a string
        """
        bio = _new_mem_buf()

        result = _lib.i2a_ASN1_INTEGER(bio, self._revoked.serialNumber)
        if result < 0:
            # TODO: This is untested.
            _raise_current_error()

        return _bio_to_string(bio)


    def _delete_reason(self):
        stack = self._revoked.extensions
        for i in range(_lib.sk_X509_EXTENSION_num(stack)):
            ext = _lib.sk_X509_EXTENSION_value(stack, i)
            if _lib.OBJ_obj2nid(ext.object) == _lib.NID_crl_reason:
                _lib.X509_EXTENSION_free(ext)
                _lib.sk_X509_EXTENSION_delete(stack, i)
                break


    def set_reason(self, reason):
        """
        Set the reason of a Revoked object.

        If :py:data:`reason` is :py:data:`None`, delete the reason instead.

        :param reason: The reason string.
        :type reason: :py:class:`str` or :py:class:`NoneType`
        :return: None
        """
        if reason is None:
            self._delete_reason()
        elif not isinstance(reason, bytes):
            raise TypeError("reason must be None or a byte string")
        else:
            reason = reason.lower().replace(b' ', b'')
            reason_code = [r.lower() for r in self._crl_reasons].index(reason)

            new_reason_ext = _lib.ASN1_ENUMERATED_new()
            if new_reason_ext == _ffi.NULL:
                # TODO: This is untested.
                _raise_current_error()
            new_reason_ext = _ffi.gc(new_reason_ext, _lib.ASN1_ENUMERATED_free)

            set_result = _lib.ASN1_ENUMERATED_set(new_reason_ext, reason_code)
            if set_result == _ffi.NULL:
                # TODO: This is untested.
                _raise_current_error()

            self._delete_reason()
            add_result = _lib.X509_REVOKED_add1_ext_i2d(
                self._revoked, _lib.NID_crl_reason, new_reason_ext, 0, 0)

            if not add_result:
                # TODO: This is untested.
                _raise_current_error()


    def get_reason(self):
        """
        Return the reason of a Revoked object.

        :return: The reason as a string
        """
        extensions = self._revoked.extensions
        for i in range(_lib.sk_X509_EXTENSION_num(extensions)):
            ext = _lib.sk_X509_EXTENSION_value(extensions, i)
            if _lib.OBJ_obj2nid(ext.object) == _lib.NID_crl_reason:
                bio = _new_mem_buf()

                print_result = _lib.X509V3_EXT_print(bio, ext, 0, 0)
                if not print_result:
                    print_result = _lib.M_ASN1_OCTET_STRING_print(bio, ext.value)
                    if print_result == 0:
                        # TODO: This is untested.
                        _raise_current_error()

                return _bio_to_string(bio)


    def all_reasons(self):
        """
        Return a list of all the supported reason strings.

        :return: A list of reason strings.
        """
        return self._crl_reasons[:]


    def set_rev_date(self, when):
        """
        Set the revocation timestamp

        :param when: A string giving the timestamp, in the format:

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm

        :return: None
        """
        return _set_asn1_time(self._revoked.revocationDate, when)


    def get_rev_date(self):
        """
        Retrieve the revocation date

        :return: A string giving the timestamp, in the format:

                         YYYYMMDDhhmmssZ
                         YYYYMMDDhhmmss+hhmm
                         YYYYMMDDhhmmss-hhmm
        """
        return _get_asn1_time(self._revoked.revocationDate)



class CRL(object):
    def __init__(self):
        """
        Create a new empty CRL object.
        """
        crl = _lib.X509_CRL_new()
        self._crl = _ffi.gc(crl, _lib.X509_CRL_free)


    def get_revoked(self):
        """
        Return revoked portion of the CRL structure (by value not reference).

        :return: A tuple of Revoked objects.
        """
        results = []
        revoked_stack = self._crl.crl.revoked
        for i in range(_lib.sk_X509_REVOKED_num(revoked_stack)):
            revoked = _lib.sk_X509_REVOKED_value(revoked_stack, i)
            revoked_copy = _X509_REVOKED_dup(revoked)
            pyrev = Revoked.__new__(Revoked)
            pyrev._revoked = _ffi.gc(revoked_copy, _lib.X509_REVOKED_free)
            results.append(pyrev)
        if results:
            return tuple(results)


    def add_revoked(self, revoked):
        """
        Add a revoked (by value not reference) to the CRL structure

        :param revoked: The new revoked.
        :type revoked: :class:`X509`

        :return: None
        """
        copy = _X509_REVOKED_dup(revoked._revoked)
        if copy == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        add_result = _lib.X509_CRL_add0_revoked(self._crl, copy)
        if add_result == 0:
            # TODO: This is untested.
            _raise_current_error()


    def export(self, cert, key, type=FILETYPE_PEM, days=100):
        """
        export a CRL as a string

        :param cert: Used to sign CRL.
        :type cert: :class:`X509`

        :param key: Used to sign CRL.
        :type key: :class:`PKey`

        :param type: The export format, either :py:data:`FILETYPE_PEM`, :py:data:`FILETYPE_ASN1`, or :py:data:`FILETYPE_TEXT`.

        :param days: The number of days until the next update of this CRL.
        :type days: :py:data:`int`

        :return: :py:data:`str`
        """
        if not isinstance(cert, X509):
            raise TypeError("cert must be an X509 instance")
        if not isinstance(key, PKey):
            raise TypeError("key must be a PKey instance")
        if not isinstance(type, int):
            raise TypeError("type must be an integer")

        bio = _lib.BIO_new(_lib.BIO_s_mem())
        if bio == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        # A scratch time object to give different values to different CRL fields
        sometime = _lib.ASN1_TIME_new()
        if sometime == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()

        _lib.X509_gmtime_adj(sometime, 0)
        _lib.X509_CRL_set_lastUpdate(self._crl, sometime)

        _lib.X509_gmtime_adj(sometime, days * 24 * 60 * 60)
        _lib.X509_CRL_set_nextUpdate(self._crl, sometime)

        _lib.X509_CRL_set_issuer_name(self._crl, _lib.X509_get_subject_name(cert._x509))

        sign_result = _lib.X509_CRL_sign(self._crl, key._pkey, _lib.EVP_md5())
        if not sign_result:
            _raise_current_error()

        if type == FILETYPE_PEM:
            ret = _lib.PEM_write_bio_X509_CRL(bio, self._crl)
        elif type == FILETYPE_ASN1:
            ret = _lib.i2d_X509_CRL_bio(bio, self._crl)
        elif type == FILETYPE_TEXT:
            ret = _lib.X509_CRL_print(bio, self._crl)
        else:
            raise ValueError(
                "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT")

        if not ret:
            # TODO: This is untested.
            _raise_current_error()

        return _bio_to_string(bio)
CRLType = CRL



class PKCS7(object):
    def type_is_signed(self):
        """
        Check if this NID_pkcs7_signed object

        :return: True if the PKCS7 is of type signed
        """
        if _lib.PKCS7_type_is_signed(self._pkcs7):
            return True
        return False


    def type_is_enveloped(self):
        """
        Check if this NID_pkcs7_enveloped object

        :returns: True if the PKCS7 is of type enveloped
        """
        if _lib.PKCS7_type_is_enveloped(self._pkcs7):
            return True
        return False


    def type_is_signedAndEnveloped(self):
        """
        Check if this NID_pkcs7_signedAndEnveloped object

        :returns: True if the PKCS7 is of type signedAndEnveloped
        """
        if _lib.PKCS7_type_is_signedAndEnveloped(self._pkcs7):
            return True
        return False


    def type_is_data(self):
        """
        Check if this NID_pkcs7_data object

        :return: True if the PKCS7 is of type data
        """
        if _lib.PKCS7_type_is_data(self._pkcs7):
            return True
        return False


    def get_type_name(self):
        """
        Returns the type name of the PKCS7 structure

        :return: A string with the typename
        """
        nid = _lib.OBJ_obj2nid(self._pkcs7.type)
        string_type = _lib.OBJ_nid2sn(nid)
        return _ffi.string(string_type)

PKCS7Type = PKCS7



class PKCS12(object):
    def __init__(self):
        self._pkey = None
        self._cert = None
        self._cacerts = None
        self._friendlyname = None


    def get_certificate(self):
        """
        Return certificate portion of the PKCS12 structure

        :return: X509 object containing the certificate
        """
        return self._cert


    def set_certificate(self, cert):
        """
        Replace the certificate portion of the PKCS12 structure

        :param cert: The new certificate.
        :type cert: :py:class:`X509` or :py:data:`None`
        :return: None
        """
        if not isinstance(cert, X509):
            raise TypeError("cert must be an X509 instance")
        self._cert = cert


    def get_privatekey(self):
        """
        Return private key portion of the PKCS12 structure

        :returns: PKey object containing the private key
        """
        return self._pkey


    def set_privatekey(self, pkey):
        """
        Replace or set the certificate portion of the PKCS12 structure

        :param pkey: The new private key.
        :type pkey: :py:class:`PKey`
        :return: None
        """
        if not isinstance(pkey, PKey):
            raise TypeError("pkey must be a PKey instance")
        self._pkey = pkey


    def get_ca_certificates(self):
        """
        Return CA certificates within of the PKCS12 object

        :return: A newly created tuple containing the CA certificates in the chain,
                 if any are present, or None if no CA certificates are present.
        """
        if self._cacerts is not None:
            return tuple(self._cacerts)


    def set_ca_certificates(self, cacerts):
        """
        Replace or set the CA certificates withing the PKCS12 object.

        :param cacerts: The new CA certificates.
        :type cacerts: :py:data:`None` or an iterable of :py:class:`X509`
        :return: None
        """
        if cacerts is None:
            self._cacerts = None
        else:
            cacerts = list(cacerts)
            for cert in cacerts:
                if not isinstance(cert, X509):
                    raise TypeError("iterable must only contain X509 instances")
            self._cacerts = cacerts


    def set_friendlyname(self, name):
        """
        Replace or set the certificate portion of the PKCS12 structure

        :param name: The new friendly name.
        :type name: :py:class:`bytes`
        :return: None
        """
        if name is None:
            self._friendlyname = None
        elif not isinstance(name, bytes):
            raise TypeError("name must be a byte string or None (not %r)" % (name,))
        self._friendlyname = name


    def get_friendlyname(self):
        """
        Return friendly name portion of the PKCS12 structure

        :returns: String containing the friendlyname
        """
        return self._friendlyname


    def export(self, passphrase=None, iter=2048, maciter=1):
        """
        Dump a PKCS12 object as a string.  See also "man PKCS12_create".

        :param passphrase: used to encrypt the PKCS12
        :type passphrase: :py:data:`bytes`

        :param iter: How many times to repeat the encryption
        :type iter: :py:data:`int`

        :param maciter: How many times to repeat the MAC
        :type maciter: :py:data:`int`

        :return: The string containing the PKCS12
        """
        if self._cacerts is None:
            cacerts = _ffi.NULL
        else:
            cacerts = _lib.sk_X509_new_null()
            cacerts = _ffi.gc(cacerts, _lib.sk_X509_free)
            for cert in self._cacerts:
                _lib.sk_X509_push(cacerts, cert._x509)

        if passphrase is None:
            passphrase = _ffi.NULL

        friendlyname = self._friendlyname
        if friendlyname is None:
            friendlyname = _ffi.NULL

        if self._pkey is None:
            pkey = _ffi.NULL
        else:
            pkey = self._pkey._pkey

        if self._cert is None:
            cert = _ffi.NULL
        else:
            cert = self._cert._x509

        pkcs12 = _lib.PKCS12_create(
            passphrase, friendlyname, pkey, cert, cacerts,
            _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
            _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
            iter, maciter, 0)
        if pkcs12 == _ffi.NULL:
            _raise_current_error()
        pkcs12 = _ffi.gc(pkcs12, _lib.PKCS12_free)

        bio = _new_mem_buf()
        _lib.i2d_PKCS12_bio(bio, pkcs12)
        return _bio_to_string(bio)

PKCS12Type = PKCS12



class NetscapeSPKI(object):
    def __init__(self):
        spki = _lib.NETSCAPE_SPKI_new()
        self._spki = _ffi.gc(spki, _lib.NETSCAPE_SPKI_free)


    def sign(self, pkey, digest):
        """
        Sign the certificate request using the supplied key and digest

        :param pkey: The key to sign with
        :param digest: The message digest to use
        :return: None
        """
        if pkey._only_public:
            raise ValueError("Key has only public part")

        if not pkey._initialized:
            raise ValueError("Key is uninitialized")

        digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
        if digest_obj == _ffi.NULL:
            raise ValueError("No such digest method")

        sign_result = _lib.NETSCAPE_SPKI_sign(self._spki, pkey._pkey, digest_obj)
        if not sign_result:
            # TODO: This is untested.
            _raise_current_error()


    def verify(self, key):
        """
        Verifies a certificate request using the supplied public key

        :param key: a public key
        :return: True if the signature is correct.
        :raise OpenSSL.crypto.Error: If the signature is invalid or there is a
            problem verifying the signature.
        """
        answer = _lib.NETSCAPE_SPKI_verify(self._spki, key._pkey)
        if answer <= 0:
            _raise_current_error()
        return True


    def b64_encode(self):
        """
        Generate a base64 encoded string from an SPKI

        :return: The base64 encoded string
        """
        encoded = _lib.NETSCAPE_SPKI_b64_encode(self._spki)
        result = _ffi.string(encoded)
        _lib.CRYPTO_free(encoded)
        return result


    def get_pubkey(self):
        """
        Get the public key of the certificate

        :return: The public key
        """
        pkey = PKey.__new__(PKey)
        pkey._pkey = _lib.NETSCAPE_SPKI_get_pubkey(self._spki)
        if pkey._pkey == _ffi.NULL:
            # TODO: This is untested.
            _raise_current_error()
        pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
        pkey._only_public = True
        return pkey


    def set_pubkey(self, pkey):
        """
        Set the public key of the certificate

        :param pkey: The public key
        :return: None
        """
        set_result = _lib.NETSCAPE_SPKI_set_pubkey(self._spki, pkey._pkey)
        if not set_result:
            # TODO: This is untested.
            _raise_current_error()
NetscapeSPKIType = NetscapeSPKI


class _PassphraseHelper(object):
    def __init__(self, type, passphrase, more_args=False, truncate=False):
        if type != FILETYPE_PEM and passphrase is not None:
            raise ValueError("only FILETYPE_PEM key format supports encryption")
        self._passphrase = passphrase
        self._more_args = more_args
        self._truncate = truncate
        self._problems = []


    @property
    def callback(self):
        if self._passphrase is None:
            return _ffi.NULL
        elif isinstance(self._passphrase, bytes):
            return _ffi.NULL
        elif callable(self._passphrase):
            return _ffi.callback("pem_password_cb", self._read_passphrase)
        else:
            raise TypeError("Last argument must be string or callable")


    @property
    def callback_args(self):
        if self._passphrase is None:
            return _ffi.NULL
        elif isinstance(self._passphrase, bytes):
            return self._passphrase
        elif callable(self._passphrase):
            return _ffi.NULL
        else:
            raise TypeError("Last argument must be string or callable")


    def raise_if_problem(self, exceptionType=Error):
        try:
            _exception_from_error_queue(exceptionType)
        except exceptionType as e:
            from_queue = e
        if self._problems:
            raise self._problems[0]
        return from_queue


    def _read_passphrase(self, buf, size, rwflag, userdata):
        try:
            if self._more_args:
                result = self._passphrase(size, rwflag, userdata)
            else:
                result = self._passphrase(rwflag)
            if not isinstance(result, bytes):
                raise ValueError("String expected")
            if len(result) > size:
                if self._truncate:
                    result = result[:size]
                else:
                    raise ValueError("passphrase returned by callback is too long")
            for i in range(len(result)):
                buf[i] = result[i:i + 1]
            return len(result)
        except Exception as e:
            self._problems.append(e)
            return 0



def load_privatekey(type, buffer, passphrase=None):
    """
    Load a private key from a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
    :param buffer: The buffer the key is stored in
    :param passphrase: (optional) if encrypted PEM format, this can be
                       either the passphrase to use, or a callback for
                       providing the passphrase.

    :return: The PKey object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    helper = _PassphraseHelper(type, passphrase)
    if type == FILETYPE_PEM:
        evp_pkey = _lib.PEM_read_bio_PrivateKey(
            bio, _ffi.NULL, helper.callback, helper.callback_args)
        helper.raise_if_problem()
    elif type == FILETYPE_ASN1:
        evp_pkey = _lib.d2i_PrivateKey_bio(bio, _ffi.NULL)
    else:
        raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")

    if evp_pkey == _ffi.NULL:
        _raise_current_error()

    pkey = PKey.__new__(PKey)
    pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free)
    return pkey



def dump_certificate_request(type, req):
    """
    Dump a certificate request to a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
    :param req: The certificate request to dump
    :return: The buffer with the dumped certificate request in
    """
    bio = _new_mem_buf()

    if type == FILETYPE_PEM:
        result_code = _lib.PEM_write_bio_X509_REQ(bio, req._req)
    elif type == FILETYPE_ASN1:
        result_code = _lib.i2d_X509_REQ_bio(bio, req._req)
    elif type == FILETYPE_TEXT:
        result_code = _lib.X509_REQ_print_ex(bio, req._req, 0, 0)
    else:
        raise ValueError("type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT")

    if result_code == 0:
        # TODO: This is untested.
        _raise_current_error()

    return _bio_to_string(bio)



def load_certificate_request(type, buffer):
    """
    Load a certificate request from a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
    :param buffer: The buffer the certificate request is stored in
    :return: The X509Req object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    if type == FILETYPE_PEM:
        req = _lib.PEM_read_bio_X509_REQ(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
    elif type == FILETYPE_ASN1:
        req = _lib.d2i_X509_REQ_bio(bio, _ffi.NULL)
    else:
        raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")

    if req == _ffi.NULL:
        # TODO: This is untested.
        _raise_current_error()

    x509req = X509Req.__new__(X509Req)
    x509req._req = _ffi.gc(req, _lib.X509_REQ_free)
    return x509req



def sign(pkey, data, digest):
    """
    Sign data with a digest

    :param pkey: Pkey to sign with
    :param data: data to be signed
    :param digest: message digest to use
    :return: signature
    """
    digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
    if digest_obj == _ffi.NULL:
        raise ValueError("No such digest method")

    md_ctx = _ffi.new("EVP_MD_CTX*")
    md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup)

    _lib.EVP_SignInit(md_ctx, digest_obj)
    _lib.EVP_SignUpdate(md_ctx, data, len(data))

    signature_buffer = _ffi.new("unsigned char[]", 512)
    signature_length = _ffi.new("unsigned int*")
    signature_length[0] = len(signature_buffer)
    final_result = _lib.EVP_SignFinal(
        md_ctx, signature_buffer, signature_length, pkey._pkey)

    if final_result != 1:
        # TODO: This is untested.
        _raise_current_error()

    return _ffi.buffer(signature_buffer, signature_length[0])[:]



def verify(cert, signature, data, digest):
    """
    Verify a signature

    :param cert: signing certificate (X509 object)
    :param signature: signature returned by sign function
    :param data: data to be verified
    :param digest: message digest to use
    :return: None if the signature is correct, raise exception otherwise
    """
    digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
    if digest_obj == _ffi.NULL:
        raise ValueError("No such digest method")

    pkey = _lib.X509_get_pubkey(cert._x509)
    if pkey == _ffi.NULL:
        # TODO: This is untested.
        _raise_current_error()
    pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free)

    md_ctx = _ffi.new("EVP_MD_CTX*")
    md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup)

    _lib.EVP_VerifyInit(md_ctx, digest_obj)
    _lib.EVP_VerifyUpdate(md_ctx, data, len(data))
    verify_result = _lib.EVP_VerifyFinal(md_ctx, signature, len(signature), pkey)

    if verify_result != 1:
        _raise_current_error()



def load_crl(type, buffer):
    """
    Load a certificate revocation list from a buffer

    :param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
    :param buffer: The buffer the CRL is stored in

    :return: The PKey object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    if type == FILETYPE_PEM:
        crl = _lib.PEM_read_bio_X509_CRL(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
    elif type == FILETYPE_ASN1:
        crl = _lib.d2i_X509_CRL_bio(bio, _ffi.NULL)
    else:
        raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")

    if crl == _ffi.NULL:
        _raise_current_error()

    result = CRL.__new__(CRL)
    result._crl = crl
    return result



def load_pkcs7_data(type, buffer):
    """
    Load pkcs7 data from a buffer

    :param type: The file type (one of FILETYPE_PEM or FILETYPE_ASN1)
    :param buffer: The buffer with the pkcs7 data.
    :return: The PKCS7 object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    if type == FILETYPE_PEM:
        pkcs7 = _lib.PEM_read_bio_PKCS7(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
    elif type == FILETYPE_ASN1:
        pass
    else:
        # TODO: This is untested.
        _raise_current_error()
        raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")

    if pkcs7 == _ffi.NULL:
        _raise_current_error()

    pypkcs7 = PKCS7.__new__(PKCS7)
    pypkcs7._pkcs7 = _ffi.gc(pkcs7, _lib.PKCS7_free)
    return pypkcs7



def load_pkcs12(buffer, passphrase):
    """
    Load a PKCS12 object from a buffer

    :param buffer: The buffer the certificate is stored in
    :param passphrase: (Optional) The password to decrypt the PKCS12 lump
    :returns: The PKCS12 object
    """
    if isinstance(buffer, _text_type):
        buffer = buffer.encode("ascii")

    bio = _new_mem_buf(buffer)

    p12 = _lib.d2i_PKCS12_bio(bio, _ffi.NULL)
    if p12 == _ffi.NULL:
        _raise_current_error()
    p12 = _ffi.gc(p12, _lib.PKCS12_free)

    pkey = _ffi.new("EVP_PKEY**")
    cert = _ffi.new("X509**")
    cacerts = _ffi.new("Cryptography_STACK_OF_X509**")

    parse_result = _lib.PKCS12_parse(p12, passphrase, pkey, cert, cacerts)
    if not parse_result:
        _raise_current_error()

    cacerts = _ffi.gc(cacerts[0], _lib.sk_X509_free)

    # openssl 1.0.0 sometimes leaves an X509_check_private_key error in the
    # queue for no particular reason.  This error isn't interesting to anyone
    # outside this function.  It's not even interesting to us.  Get rid of it.
    try:
        _raise_current_error()
    except Error:
        pass

    if pkey[0] == _ffi.NULL:
        pykey = None
    else:
        pykey = PKey.__new__(PKey)
        pykey._pkey = _ffi.gc(pkey[0], _lib.EVP_PKEY_free)

    if cert[0] == _ffi.NULL:
        pycert = None
        friendlyname = None
    else:
        pycert = X509.__new__(X509)
        pycert._x509 = _ffi.gc(cert[0], _lib.X509_free)

        friendlyname_length = _ffi.new("int*")
        friendlyname_buffer = _lib.X509_alias_get0(cert[0], friendlyname_length)
        friendlyname = _ffi.buffer(friendlyname_buffer, friendlyname_length[0])[:]
        if friendlyname_buffer == _ffi.NULL:
            friendlyname = None

    pycacerts = []
    for i in range(_lib.sk_X509_num(cacerts)):
        pycacert = X509.__new__(X509)
        pycacert._x509 = _lib.sk_X509_value(cacerts, i)
        pycacerts.append(pycacert)
    if not pycacerts:
        pycacerts = None

    pkcs12 = PKCS12.__new__(PKCS12)
    pkcs12._pkey = pykey
    pkcs12._cert = pycert
    pkcs12._cacerts = pycacerts
    pkcs12._friendlyname = friendlyname
    return pkcs12


def _initialize_openssl_threads(get_ident, Lock):
    import _ssl
    return

    locks = list(Lock() for n in range(_lib.CRYPTO_num_locks()))

    def locking_function(mode, index, filename, line):
        if mode & _lib.CRYPTO_LOCK:
            locks[index].acquire()
        else:
            locks[index].release()

    _lib.CRYPTO_set_id_callback(
        _ffi.callback("unsigned long (*)(void)", get_ident))

    _lib.CRYPTO_set_locking_callback(
        _ffi.callback(
            "void (*)(int, int, const char*, int)", locking_function))


try:
    from thread import get_ident
    from threading import Lock
except ImportError:
    pass
else:
    _initialize_openssl_threads(get_ident, Lock)
    del get_ident, Lock

# There are no direct unit tests for this initialization.  It is tested
# indirectly since it is necessary for functions like dump_privatekey when
# using encryption.
#
# Thus OpenSSL.test.test_crypto.FunctionTests.test_dump_privatekey_passphrase
# and some other similar tests may fail without this (though they may not if
# the Python runtime has already done some initialization of the underlying
# OpenSSL library (and is linked against the same one that cryptography is
# using)).
_lib.OpenSSL_add_all_algorithms()

# This is similar but exercised mainly by exception_from_error_queue.  It calls
# both ERR_load_crypto_strings() and ERR_load_SSL_strings().
_lib.SSL_load_error_strings()
