Skip to content

Commit 917ac46

Browse files
v1.0.9
v1.0.9
2 parents 04ff2d1 + aef292a commit 917ac46

21 files changed

+9751
-16
lines changed

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
standard-imghdr~=3.13.0
22
requests~=2.32.2
3-
PGPy~=0.6
3+
cryptography>=3.3.2
4+
pyasn1

sendsafely/Package.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import os
44
import re
55

6+
from .pgpy import PGPMessage
67
import requests
78
import cryptography
89
major, minor, patch = [int(x, 10) for x in cryptography.__version__.split('.')]
910
if major < 41:
1011
from cryptography import CryptographyDeprecationWarning
1112
else:
1213
from cryptography.utils import CryptographyDeprecationWarning
13-
from pgpy import PGPMessage
1414
from sendsafely.Progress import Progress
1515
import warnings
1616

sendsafely/SendSafely.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
import warnings
44

55
import requests
6-
import pgpy
76
import cryptography
87
major, minor, patch = [int(x, 10) for x in cryptography.__version__.split('.')]
98
if major < 41:
109
from cryptography import CryptographyDeprecationWarning
1110
else:
1211
from cryptography.utils import CryptographyDeprecationWarning
13-
from pgpy import PGPMessage
14-
from pgpy.constants import KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm, PubKeyAlgorithm
12+
from .pgpy import PGPMessage, PGPUID, PGPKey
13+
from .pgpy.constants import KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm, PubKeyAlgorithm
1514
from sendsafely.Package import Package
1615
from sendsafely.exceptions import GetPackagesException, GetUserInformationException, TrustedDeviceException, \
1716
DeletePackageException, GetPackageInformationFailedException, GetKeycodeFailedException
@@ -74,13 +73,13 @@ def generate_trusted_device_key_pair(self, description):
7473
:return: The response, including key pair
7574
"""
7675
email = self.get_user_information()["email"]
77-
key = pgpy.PGPKey.new(pgpy.constants.PubKeyAlgorithm.RSAEncryptOrSign, 2048)
78-
uid = pgpy.PGPUID.new('Trusted Browser', email=email)
76+
key = PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 2048)
77+
uid = PGPUID.new('Trusted Browser', email=email)
7978
key.add_uid(uid=uid, usage={KeyFlags.Sign, KeyFlags.Certify},
8079
hashes=[HashAlgorithm.SHA256],
8180
ciphers=[SymmetricKeyAlgorithm.AES256],
8281
compression=[CompressionAlgorithm.Uncompressed])
83-
subkey = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 2048)
82+
subkey = PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 2048)
8483
key.add_subkey(subkey, usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage})
8584
public_key = str(key.pubkey)
8685
endpoint = "/public-key"
@@ -140,7 +139,7 @@ def get_package_keycode(self, package_id, public_key_id=None, private_key=None):
140139
if keycode_json['response'] == 'FAIL':
141140
raise GetKeycodeFailedException(details=str(keycode))
142141

143-
key_pair = pgpy.PGPKey.from_blob(str(private_key))[0]
142+
key_pair = PGPKey.from_blob(str(private_key))[0]
144143
keycode_message = PGPMessage.from_blob(keycode)
145144
decrypted_keycode = key_pair.decrypt(keycode_message).message
146145
return {"keyCode": decrypted_keycode}

sendsafely/pgpy/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
""" PGPy :: Pretty Good Privacy for Python
2+
"""
3+
4+
from .pgp import PGPKey
5+
from .pgp import PGPKeyring
6+
from .pgp import PGPMessage
7+
from .pgp import PGPSignature
8+
from .pgp import PGPUID
9+
10+
__all__ = ['constants',
11+
'errors',
12+
'PGPKey',
13+
'PGPKeyring',
14+
'PGPMessage',
15+
'PGPSignature',
16+
'PGPUID', ]

sendsafely/pgpy/_curves.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
""" _curves.py
2+
specify some additional curves that OpenSSL provides but cryptography doesn't explicitly expose
3+
"""
4+
5+
from cryptography import utils
6+
7+
from cryptography.hazmat.primitives.asymmetric import ec
8+
9+
from cryptography.hazmat.bindings.openssl.binding import Binding
10+
11+
__all__ = tuple()
12+
13+
# TODO: investigate defining additional curves using EC_GROUP_new_curve
14+
# https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography#Defining_Curves
15+
16+
17+
def _openssl_get_supported_curves():
18+
if hasattr(_openssl_get_supported_curves, '_curves'):
19+
return _openssl_get_supported_curves._curves
20+
21+
# use cryptography's cffi bindings to get an array of curve names
22+
b = Binding()
23+
cn = b.lib.EC_get_builtin_curves(b.ffi.NULL, 0)
24+
cs = b.ffi.new('EC_builtin_curve[]', cn)
25+
b.lib.EC_get_builtin_curves(cs, cn)
26+
27+
# store the result so we don't have to do all of this every time
28+
curves = { b.ffi.string(b.lib.OBJ_nid2sn(c.nid)).decode('utf-8') for c in cs }
29+
# Ed25519 and X25519 are always present in cryptography>=2.6
30+
# The python cryptography lib provides a different interface for these curves,
31+
# so they are handled differently in the ECDHPriv/Pub and EdDSAPriv/Pub classes
32+
curves |= {'X25519', 'ed25519'}
33+
_openssl_get_supported_curves._curves = curves
34+
return curves
35+
36+
37+
def use_legacy_cryptography_decorator():
38+
"""
39+
The decorator utils.register_interface was removed in version 38.0.0. Keep using it
40+
if the decorator exists, inherit from `ec.EllipticCurve` otherwise.
41+
"""
42+
return hasattr(utils, "register_interface") and callable(utils.register_interface)
43+
44+
45+
if use_legacy_cryptography_decorator():
46+
@utils.register_interface(ec.EllipticCurve)
47+
class BrainpoolP256R1(object):
48+
name = 'brainpoolP256r1'
49+
key_size = 256
50+
51+
52+
@utils.register_interface(ec.EllipticCurve) # noqa: E303
53+
class BrainpoolP384R1(object):
54+
name = 'brainpoolP384r1'
55+
key_size = 384
56+
57+
58+
@utils.register_interface(ec.EllipticCurve) # noqa: E303
59+
class BrainpoolP512R1(object):
60+
name = 'brainpoolP512r1'
61+
key_size = 512
62+
63+
64+
@utils.register_interface(ec.EllipticCurve) # noqa: E303
65+
class X25519(object):
66+
name = 'X25519'
67+
key_size = 256
68+
69+
70+
@utils.register_interface(ec.EllipticCurve) # noqa: E303
71+
class Ed25519(object):
72+
name = 'ed25519'
73+
key_size = 256
74+
else:
75+
class BrainpoolP256R1(ec.EllipticCurve):
76+
name = 'brainpoolP256r1'
77+
key_size = 256
78+
79+
80+
class BrainpoolP384R1(ec.EllipticCurve): # noqa: E303
81+
name = 'brainpoolP384r1'
82+
key_size = 384
83+
84+
85+
class BrainpoolP512R1(ec.EllipticCurve): # noqa: E303
86+
name = 'brainpoolP512r1'
87+
key_size = 512
88+
89+
90+
class X25519(ec.EllipticCurve): # noqa: E303
91+
name = 'X25519'
92+
key_size = 256
93+
94+
95+
class Ed25519(ec.EllipticCurve): # noqa: E303
96+
name = 'ed25519'
97+
key_size = 256
98+
99+
100+
# add these curves to the _CURVE_TYPES list
101+
for curve in [BrainpoolP256R1, BrainpoolP384R1, BrainpoolP512R1, X25519, Ed25519]:
102+
if curve.name not in ec._CURVE_TYPES and curve.name in _openssl_get_supported_curves():
103+
ec._CURVE_TYPES[curve.name] = curve

0 commit comments

Comments
 (0)