def _evp_pkey_to_public_key(self, evp_pkey): """ Return the appropriate type of PublicKey given an evp_pkey cdata pointer. """ type = evp_pkey.type if type == self._lib.EVP_PKEY_RSA: rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) assert rsa_cdata != self._ffi.NULL rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) return _RSAPublicKey(self, rsa_cdata) elif type == self._lib.EVP_PKEY_DSA: dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) assert dsa_cdata != self._ffi.NULL dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) return _DSAPublicKey(self, dsa_cdata) elif (self._lib.Cryptography_HAS_EC == 1 and type == self._lib.EVP_PKEY_EC): ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) assert ec_cdata != self._ffi.NULL ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePublicKey(self, ec_cdata) else: raise UnsupportedAlgorithm("Unsupported key type.")
def _evp_pkey_to_public_key(self, evp_pkey): """ Return the appropriate type of PublicKey given an evp_pkey cdata pointer. """ type = evp_pkey.type if type == self._lib.EVP_PKEY_RSA: rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) assert rsa_cdata != self._ffi.NULL rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) return _RSAPublicKey(self, rsa_cdata) elif type == self._lib.EVP_PKEY_DSA: dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) assert dsa_cdata != self._ffi.NULL dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) return _DSAPublicKey(self, dsa_cdata) elif (self._lib.Cryptography_HAS_EC == 1 and type == self._lib.EVP_PKEY_EC): ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) assert ec_cdata != self._ffi.NULL ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePublicKey(self, ec_cdata) else: raise UnsupportedAlgorithm("Unsupported key type.")
def to_cryptography_pubkey(self) -> _EllipticCurvePublicKey: """ Returns a cryptography.io EllipticCurvePublicKey from the Umbral key. """ backend = default_backend() backend.openssl_assert(self.point_key.curve.ec_group != backend._ffi.NULL) backend.openssl_assert(self.point_key.ec_point != backend._ffi.NULL) ec_key = backend._lib.EC_KEY_new() backend.openssl_assert(ec_key != backend._ffi.NULL) ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) set_group_result = backend._lib.EC_KEY_set_group( ec_key, self.point_key.curve.ec_group ) backend.openssl_assert(set_group_result == 1) set_pubkey_result = backend._lib.EC_KEY_set_public_key( ec_key, self.point_key.ec_point ) backend.openssl_assert(set_pubkey_result == 1) evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) return _EllipticCurvePublicKey(backend, ec_key, evp_pkey)
def elliptic_curve_public_key_from_numbers(self, numbers): curve_nid = self._elliptic_curve_to_nid(numbers.curve) ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) assert ctx != self._ffi.NULL ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) ctx = self._ec_key_set_public_key_affine_coordinates( ctx, numbers.x, numbers.y) return _EllipticCurvePublicKey(self, ctx, numbers.curve)
def load_elliptic_curve_public_numbers(self, numbers): curve_nid = self._elliptic_curve_to_nid(numbers.curve) ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) assert ec_cdata != self._ffi.NULL ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) ec_cdata = self._ec_key_set_public_key_affine_coordinates( ec_cdata, numbers.x, numbers.y) return _EllipticCurvePublicKey(self, ec_cdata)
def load_elliptic_curve_public_numbers(self, numbers): curve_nid = self._elliptic_curve_to_nid(numbers.curve) ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) assert ec_cdata != self._ffi.NULL ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) ec_cdata = self._ec_key_set_public_key_affine_coordinates( ec_cdata, numbers.x, numbers.y) return _EllipticCurvePublicKey(self, ec_cdata)
def elliptic_curve_public_key_from_numbers(self, numbers): curve_nid = self._elliptic_curve_to_nid(numbers.curve) ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) assert ctx != self._ffi.NULL ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) ctx = self._ec_key_set_public_key_affine_coordinates( ctx, numbers.x, numbers.y) return _EllipticCurvePublicKey(self, ctx, numbers.curve)
def point_to_pubkey(curve: Curve, point): ec_key = BACKEND_LIB.EC_KEY_new() backend.openssl_assert(ec_key != BACKEND_FFI.NULL) ec_key = BACKEND_FFI.gc(ec_key, BACKEND_LIB.EC_KEY_free) set_group_result = BACKEND_LIB.EC_KEY_set_group(ec_key, curve.ec_group) backend.openssl_assert(set_group_result == 1) set_pubkey_result = BACKEND_LIB.EC_KEY_set_public_key(ec_key, point) backend.openssl_assert(set_pubkey_result == 1) evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) return _EllipticCurvePublicKey(backend, ec_key, evp_pkey)
def to_cryptography_pub_key(self): """ Converts the Point object to a cryptography.io EllipticCurvePublicKey """ backend.openssl_assert(self.group != backend._ffi.NULL) backend.openssl_assert(self.ec_point != backend._ffi.NULL) ec_key = backend._lib.EC_KEY_new() backend.openssl_assert(ec_key != backend._ffi.NULL) ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) res = backend._lib.EC_KEY_set_group(ec_key, self.group) backend.openssl_assert(res == 1) res = backend._lib.EC_KEY_set_public_key(ec_key, self.ec_point) backend.openssl_assert(res == 1) evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) return _EllipticCurvePublicKey(backend, ec_key, evp_pkey)
def _point_to_public_key(backend, group, point) -> _EllipticCurvePublicKey: """ Converts an EC_POINT to an EllipticCurvePublicKey. """ backend.openssl_assert(group != backend._ffi.NULL) backend.openssl_assert(point != backend._ffi.NULL) ec_key = backend._lib.EC_KEY_new() backend.openssl_assert(ec_key != backend._ffi.NULL) ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) res = backend._lib.EC_KEY_set_group(ec_key, group) backend.openssl_assert(res == 1) res = backend._lib.EC_KEY_set_public_key(ec_key, point) backend.openssl_assert(res == 1) evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) return _EllipticCurvePublicKey(backend, ec_key, evp_pkey)
def elliptic_curve_public_key_from_numbers(self, numbers): ec_key = self._ec_key_cdata_from_public_numbers(numbers) return _EllipticCurvePublicKey(self, ec_key, numbers.curve)
def recover_pubkey(cls, signature, data, check=None, backend=None, curve=ec.SECP256K1()): from cryptography.hazmat.backends.openssl.ec import _EllipticCurvePublicKey backend = backend or default_backend() curve_nid = backend._elliptic_curve_to_nid(curve) with backend._tmp_bn_ctx() as ctx: ec_cdata = backend._lib.EC_KEY_new_by_curve_name(curve_nid) backend.openssl_assert(ec_cdata != backend._ffi.NULL) ec_cdata = backend._ffi.gc(ec_cdata, backend._lib.EC_KEY_free) group = backend._lib.EC_KEY_get0_group(ec_cdata) backend.openssl_assert(group != backend._ffi.NULL) z_data = BlcSha.sha256(data) z_len = (backend._lib.EC_GROUP_get_degree(group) + 7) // 8 backend.openssl_assert(z_len > 0) z_buf = backend._ffi.new("unsigned char[]", z_data[-z_len:]) z = backend._lib.BN_CTX_get(ctx) backend._lib.BN_bin2bn(z_buf, z_len, z) # print(f'z: {backend._bn_to_int(z)}') sigbuf = backend._ffi.new("unsigned char[]", signature) psigbuf = backend._ffi.new("unsigned char **", sigbuf) sig = backend._lib.d2i_ECDSA_SIG(backend._ffi.NULL, psigbuf, len(signature)) backend.openssl_assert(sig != backend._ffi.NULL) pr = backend._ffi.new("BIGNUM **") ps = backend._ffi.new("BIGNUM **") backend._lib.ECDSA_SIG_get0(sig, pr, ps) r = backend._bn_to_int(pr[0]) s = backend._bn_to_int(ps[0]) # print(f'sig: {r}\n {s}') for y in [0, 1]: point = backend._lib.EC_POINT_new(group) backend._lib.EC_POINT_set_compressed_coordinates_GFp( group, point, pr[0], y, ctx) bnx = backend._lib.BN_CTX_get(ctx) bny = backend._lib.BN_CTX_get(ctx) backend._lib.EC_POINT_get_affine_coordinates_GFp( group, point, bnx, bny, ctx) # print(f'point: {backend._bn_to_int(bnx)}\n {backend._bn_to_int(bny)}') order = backend._lib.BN_CTX_get(ctx) backend._lib.EC_GROUP_get_order(group, order, ctx) # print(f'order: {backend._bn_to_int(order)}') inv = backend._lib.BN_CTX_get(ctx) backend._lib.BN_mod_inverse(inv, pr[0], order, ctx) # print(f'r inv: {backend._bn_to_int(inv)}') rs = backend._lib.BN_CTX_get(ctx) backend._lib.BN_mod_mul(rs, inv, ps[0], order, ctx) # print(f'r1 s: {backend._bn_to_int(rs)}') rz = backend._lib.BN_CTX_get(ctx) rzn = backend._lib.BN_CTX_get(ctx) zero = backend._lib.BN_CTX_get(ctx) backend._lib.BN_mod_mul(rz, inv, z, order, ctx) backend._lib.BN_mod_sub(rzn, zero, rz, order, ctx) # print(f'r1 z: {backend._bn_to_int(rz)}') # print(f'-r1 z: {backend._bn_to_int(rzn)}') zn = backend._lib.BN_CTX_get(ctx) backend._lib.BN_mod_sub(zn, zero, z, order, ctx) res = backend._lib.EC_POINT_new(group) backend._lib.EC_POINT_mul(group, res, rzn, point, rs, ctx) bnx = backend._lib.BN_CTX_get(ctx) bny = backend._lib.BN_CTX_get(ctx) backend._lib.EC_POINT_get_affine_coordinates_GFp( group, res, bnx, bny, ctx) # print(f'pkey: {backend._bn_to_int(bnx)}\n {backend._bn_to_int(bny)}') ec_cdata = backend._ec_key_set_public_key_affine_coordinates( ec_cdata, backend._bn_to_int(bnx), backend._bn_to_int(bny)) evp_pkey = backend._ec_cdata_to_evp_pkey(ec_cdata) pkey = _EllipticCurvePublicKey(backend, ec_cdata, evp_pkey) if not check or check(pkey): return pkey