]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blob - ctypescrypto/ec.py
Added explicit check for CMS functions in libcrypto
[oss/ctypescrypto.git] / ctypescrypto / ec.py
1 """
2 Support for EC keypair operation missing form public libcrypto API
3 """
4 from ctypescrypto.pkey import PKey, PKeyError
5 from ctypes import c_void_p, c_char_p, c_int, byref, POINTER
6 from ctypescrypto import libcrypto
7
8 __all__ = ['create']
9
10 def create(curve, data):
11     """
12     Creates EC keypair from the just secret key and curve name
13
14     @param curve - name of elliptic curve
15     @param num - byte array or long number representing key
16     """
17     ec_key = libcrypto.EC_KEY_new_by_curve_name(curve.nid)
18     if ec_key is None:
19         raise PKeyError("EC_KEY_new_by_curvename")
20     group = libcrypto.EC_KEY_get0_group(ec_key)
21     if group is None:
22         raise PKeyError("EC_KEY_get0_group")
23     libcrypto.EC_GROUP_set_asn1_flag(group, 1)
24     raw_key = libcrypto.BN_new()
25     if isinstance(data, int):
26         libcrypto.BN_hex2bn(byref(raw_key), hex(data))
27     else:
28         if raw_key is None:
29             raise PKeyError("BN_new")
30         if libcrypto.BN_bin2bn(data, len(data), raw_key) is None:
31             raise PKeyError("BN_bin2bn")
32     ctx = libcrypto.BN_CTX_new()
33     if ctx is None:
34         raise PKeyError("BN_CTX_new")
35     order = libcrypto.BN_new()
36     if order is None:
37         raise PKeyError("BN_new")
38     priv_key = libcrypto.BN_new()
39     if priv_key is None:
40         raise PKeyError("BN_new")
41     if libcrypto.EC_GROUP_get_order(group, order, ctx) <= 0:
42         raise PKeyError("EC_GROUP_get_order")
43     if libcrypto.BN_nnmod(priv_key, raw_key, order, ctx) <= 0:
44         raise PKeyError("BN_nnmod")
45     if libcrypto.EC_KEY_set_private_key(ec_key, priv_key) <= 0:
46         raise PKeyError("EC_KEY_set_private_key")
47     pub_key = libcrypto.EC_POINT_new(group)
48     if pub_key is None:
49         raise PKeyError("EC_POINT_new")
50     if libcrypto.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) <= 0:
51         raise PKeyError("EC_POINT_mul")
52     if libcrypto.EC_KEY_set_public_key(ec_key, pub_key) <= 0:
53         raise PKeyError("EC_KEY_set_public_key")
54     libcrypto.BN_free(raw_key)
55     libcrypto.BN_free(order)
56     libcrypto.BN_free(priv_key)
57     libcrypto.BN_CTX_free(ctx)
58     pkey = libcrypto.EVP_PKEY_new()
59     if pkey is None:
60         raise PKeyError("EVP_PKEY_new")
61     if libcrypto.EVP_PKEY_set1_EC_KEY(pkey, ec_key) <= 0:
62         raise PKeyError("EVP_PKEY_set1_EC_KEY")
63     libcrypto.EC_KEY_free(ec_key)
64     return PKey(ptr=pkey, cansign=True)
65
66 libcrypto.EVP_PKEY_new.restype = c_void_p
67 libcrypto.EC_KEY_new_by_curve_name.restype = c_void_p
68 libcrypto.EC_KEY_new_by_curve_name.argtypes = (c_int,)
69 libcrypto.BN_new.restype = c_void_p
70 libcrypto.BN_free.argtypes = (c_void_p, )
71 libcrypto.BN_hex2bn.argtypes = (POINTER(c_void_p), c_char_p)
72 libcrypto.BN_bin2bn.argtypes = ( c_char_p, c_int, c_void_p)
73 libcrypto.BN_bin2bn.restype = c_void_p
74 libcrypto.BN_CTX_new.restype = c_void_p
75 libcrypto.BN_CTX_free.argtypes = (c_void_p, )
76 libcrypto.BN_bin2bn.argtypes = (c_char_p, c_int, c_void_p)
77 libcrypto.BN_nnmod.restype = c_int
78 libcrypto.BN_nnmod.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p)
79 libcrypto.EC_KEY_set_private_key.argtypes = (c_void_p, c_void_p)
80 libcrypto.EC_POINT_new.argtypes = (c_void_p, )
81 libcrypto.EC_POINT_new.restype = c_void_p
82 libcrypto.EC_POINT_mul.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p,
83                                    c_void_p, c_void_p)
84 libcrypto.EC_KEY_set_public_key.argtypes = (c_void_p, c_void_p)
85 libcrypto.EC_KEY_get0_group.restype = c_void_p
86 libcrypto.EC_KEY_get0_group.argtypes = (c_void_p,)
87 libcrypto.EC_KEY_free.argtypes=(c_void_p,)
88 libcrypto.EVP_PKEY_set1_EC_KEY.argtypes = (c_void_p, c_void_p)
89 libcrypto.EC_GROUP_set_asn1_flag.argtypes = (c_void_p, c_int)
90 libcrypto.EC_GROUP_get_order.restype = c_int
91 libcrypto.EC_GROUP_get_order.argtypes = (c_void_p, c_void_p, c_void_p)