File: _curves.py

package info (click to toggle)
python-pgpy 0.6.0-1.4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,212 kB
  • sloc: python: 8,448; makefile: 155; sh: 10
file content (103 lines) | stat: -rw-r--r-- 3,195 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
""" _curves.py
specify some additional curves that OpenSSL provides but cryptography doesn't explicitly expose
"""

from cryptography import utils

from cryptography.hazmat.primitives.asymmetric import ec

from cryptography.hazmat.bindings.openssl.binding import Binding

__all__ = tuple()

# TODO: investigate defining additional curves using EC_GROUP_new_curve
#       https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography#Defining_Curves


def _openssl_get_supported_curves():
    if hasattr(_openssl_get_supported_curves, '_curves'):
        return _openssl_get_supported_curves._curves

    # use cryptography's cffi bindings to get an array of curve names
    b = Binding()
    cn = b.lib.EC_get_builtin_curves(b.ffi.NULL, 0)
    cs = b.ffi.new('EC_builtin_curve[]', cn)
    b.lib.EC_get_builtin_curves(cs, cn)

    # store the result so we don't have to do all of this every time
    curves = { b.ffi.string(b.lib.OBJ_nid2sn(c.nid)).decode('utf-8') for c in cs }
    # Ed25519 and X25519 are always present in cryptography>=2.6
    # The python cryptography lib provides a different interface for these curves,
    # so they are handled differently in the ECDHPriv/Pub and EdDSAPriv/Pub classes
    curves |= {'X25519', 'ed25519'}
    _openssl_get_supported_curves._curves = curves
    return curves


def use_legacy_cryptography_decorator():
    """
    The decorator utils.register_interface was removed in version 38.0.0. Keep using it
    if the decorator exists, inherit from `ec.EllipticCurve` otherwise.
    """
    return hasattr(utils, "register_interface") and callable(utils.register_interface)


if use_legacy_cryptography_decorator():
    @utils.register_interface(ec.EllipticCurve)
    class BrainpoolP256R1(object):
        name = 'brainpoolP256r1'
        key_size = 256


    @utils.register_interface(ec.EllipticCurve)  # noqa: E303
    class BrainpoolP384R1(object):
        name = 'brainpoolP384r1'
        key_size = 384


    @utils.register_interface(ec.EllipticCurve)  # noqa: E303
    class BrainpoolP512R1(object):
        name = 'brainpoolP512r1'
        key_size = 512


    @utils.register_interface(ec.EllipticCurve)  # noqa: E303
    class X25519(object):
        name = 'X25519'
        key_size = 256


    @utils.register_interface(ec.EllipticCurve)  # noqa: E303
    class Ed25519(object):
        name = 'ed25519'
        key_size = 256
else:
    class BrainpoolP256R1(ec.EllipticCurve):
        name = 'brainpoolP256r1'
        key_size = 256


    class BrainpoolP384R1(ec.EllipticCurve):  # noqa: E303
        name = 'brainpoolP384r1'
        key_size = 384


    class BrainpoolP512R1(ec.EllipticCurve):  # noqa: E303
        name = 'brainpoolP512r1'
        key_size = 512


    class X25519(ec.EllipticCurve):  # noqa: E303
        name = 'X25519'
        key_size = 256


    class Ed25519(ec.EllipticCurve):  # noqa: E303
        name = 'ed25519'
        key_size = 256


# add these curves to the _CURVE_TYPES list
for curve in [BrainpoolP256R1, BrainpoolP384R1, BrainpoolP512R1, X25519, Ed25519]:
    if curve.name not in ec._CURVE_TYPES and curve.name in _openssl_get_supported_curves():
        ec._CURVE_TYPES[curve.name] = curve