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 get_extensions(self):
        """
        Get extensions to the request.

        :return: A :py:class:`list` of :py:class:`X509Extension` objects.
        """
        exts = []
        native_exts_obj = _lib.X509_REQ_get_extensions(self._req)
        for i in range(0, _lib.sk_X509_EXTENSION_num(native_exts_obj)):
            ext = X509Extension.__new__(X509Extension)
            ext._extension = _lib.sk_X509_EXTENSION_value(native_exts_obj, i)
            exts.append(ext)
        return exts


    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()
