+ 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
+ """
+ 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")
+ for oper in kwargs:
+ rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
+ if rv==-2:
+ raise PKeyError("Parameter %s is not supported by key"%(oper))
+ if rv<1:
+ raise PKeyError("Error setting parameter %s"(oper))
+ if libcrypto.EVP_PKEY_derive_set_peer(ctx,peerkey.key)<=0:
+ raise PKeyError("Cannot set peer key")
+ 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)
+ 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[:keylen]
+ @staticmethod