Esempio n. 1
0
    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)
Esempio n. 2
0
 def verify(self, digest, signature, **kwargs):
     """
     Verifies given signature on given digest
     Returns True if Ok, False if don't match
     Keyword arguments allows to set algorithm-specific
     parameters
     """
     ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
     if ctx is None:
         raise PKeyError("Initailizing verify context")
     if libcrypto.EVP_PKEY_verify_init(ctx) < 1:
         raise PKeyError("verify_init")
     self._configure_context(ctx, kwargs)
     ret = libcrypto.EVP_PKEY_verify(ctx, signature, len(signature), digest,
                                     len(digest))
     if ret < 0:
         raise PKeyError("Signature verification")
     libcrypto.EVP_PKEY_CTX_free(ctx)
     return ret > 0
Esempio n. 3
0
 def sign(self, digest, **kwargs):
     """
     Signs given digest and retirns signature
     Keyword arguments allows to set various algorithm-specific
     parameters. See pkeyutl(1) manual.
     """
     ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
     if ctx is None:
         raise PKeyError("Initailizing sign context")
     if libcrypto.EVP_PKEY_sign_init(ctx) < 1:
         raise PKeyError("sign_init")
     self._configure_context(ctx, kwargs)
     # Find out signature size
     siglen = c_long(0)
     if libcrypto.EVP_PKEY_sign(ctx, None, byref(siglen), digest,
                                len(digest)) < 1:
         raise PKeyError("computing signature length")
     sig = create_string_buffer(siglen.value)
     if libcrypto.EVP_PKEY_sign(ctx, sig, byref(siglen), digest,
                                len(digest)) < 1:
         raise PKeyError("signing")
     libcrypto.EVP_PKEY_CTX_free(ctx)
     return sig.raw[:int(siglen.value)]
Esempio n. 4
0
    def derive(self, peerkey, **kwargs):
        """
        Derives shared key (DH,ECDH,VKO 34.10). Requires
        private key available

        @param peerkey - other key (may be public only)

        Keyword parameters are algorithm-specific
        """
        if not self.cansign:
            raise ValueError("No private key available")
        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
        if ctx is None:
            raise PKeyError("Initailizing derive context")
        if libcrypto.EVP_PKEY_derive_init(ctx) < 1:
            raise PKeyError("derive_init")

        # This is workaround around missing functionality in GOST engine
        # it provides only numeric control command to set UKM, not
        # string one.
        self._configure_context(ctx, kwargs, ["ukm"])
        if libcrypto.EVP_PKEY_derive_set_peer(ctx, peerkey.key) <= 0:
            raise PKeyError("Cannot set peer key")
        if "ukm" in kwargs:
            # We just hardcode numeric command to set UKM here
            if libcrypto.EVP_PKEY_CTX_ctrl(ctx, -1, 1 << 10, 8, 8,
                                           kwargs["ukm"]) <= 0:
                raise PKeyError("Cannot set UKM")
        keylen = c_long(0)
        if libcrypto.EVP_PKEY_derive(ctx, None, byref(keylen)) <= 0:
            raise PKeyError("computing shared key length")
        buf = create_string_buffer(keylen.value)
        if libcrypto.EVP_PKEY_derive(ctx, buf, byref(keylen)) <= 0:
            raise PKeyError("computing actual shared key")
        libcrypto.EVP_PKEY_CTX_free(ctx)
        return buf.raw[:int(keylen.value)]