'Return the appropriate type of PublicKey given an evp_pkey cdata
pointer.'

def _evp_pkey_to_public_key(self, evp_pkey):

    key_type = self._lib.Cryptography_EVP_PKEY_id(evp_pkey)
    if (key_type == self._lib.EVP_PKEY_RSA):
        rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey)
        self.openssl_assert((rsa_cdata != self._ffi.NULL))
        rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free)
        return _RSAPublicKey(self, rsa_cdata, evp_pkey)
    elif (key_type == self._lib.EVP_PKEY_DSA):
        dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey)
        self.openssl_assert((dsa_cdata != self._ffi.NULL))
        dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
        return _DSAPublicKey(self, dsa_cdata, evp_pkey)
    elif ((self._lib.Cryptography_HAS_EC == 1) and (key_type == self._lib.EVP_PKEY_EC)):
        ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey)
        self.openssl_assert((ec_cdata != self._ffi.NULL))
        ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free)
        return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey)
    else:
        raise UnsupportedAlgorithm('Unsupported    key    type.')
