Generates new private-public key pair for given algorithm
        (string like 'rsa','ec','gost2001') and algorithm-specific
        parameters.

        Algorithm specific paramteers for RSA:

        rsa_keygen_bits=number - size of key to be generated
        rsa_keygen_pubexp - RSA public expontent(default 65537)

        Algorithm specific parameters for DSA,DH and EC

        paramsfrom=PKey object

        copy parameters of newly generated key from existing key

        Algorithm specific parameters for GOST2001

        paramset= paramset name where name is one of
        'A','B','C','XA','XB','test'

        paramsfrom does work too

def generate(algorithm, **kwargs):
        """
        Generates new private-public key pair for given algorithm
        (string like 'rsa','ec','gost2001') and algorithm-specific
        parameters.

        Algorithm specific paramteers for RSA:

        rsa_keygen_bits=number - size of key to be generated
        rsa_keygen_pubexp - RSA public expontent(default 65537)

        Algorithm specific parameters for DSA,DH and EC

        paramsfrom=PKey object

        copy parameters of newly generated key from existing key

        Algorithm specific parameters for GOST2001

        paramset= paramset name where name is one of
        'A','B','C','XA','XB','test'

        paramsfrom does work too
        """
        tmpeng = c_void_p(None)
        if isinstance(algorithm, chartype):
            alg  = algorithm.encode("ascii")
        else:
            alg = algorithm
        ameth = libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng), alg, -1)
        if ameth is None:
            raise PKeyError("Algorithm %s not foind\n"%(algorithm))
        clear_err_stack()
        pkey_id = c_int(0)
        libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id), None, None, None,
                                          None, ameth)
        #libcrypto.ENGINE_finish(tmpeng)
        if "paramsfrom" in kwargs:
            ctx = libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key, None)
        else:
            ctx = libcrypto.EVP_PKEY_CTX_new_id(pkey_id, None)
        # FIXME support EC curve as keyword param by invoking paramgen
        # operation
        if ctx is None:
            raise PKeyError("Creating context for key type %d"%(pkey_id.value))
        if libcrypto.EVP_PKEY_keygen_init(ctx) <= 0:
            raise PKeyError("keygen_init")
        PKey._configure_context(ctx, kwargs, ["paramsfrom"])
        key = c_void_p(None)
        if libcrypto.EVP_PKEY_keygen(ctx, byref(key)) <= 0:
            raise PKeyError("Error generating key")
        libcrypto.EVP_PKEY_CTX_free(ctx)
        return PKey(ptr=key, cansign=True)