Skip to content

Commit 912a1b3

Browse files
committed
Use the new saml2.cryptography module
Replace AESCipher with the default symmetric method. Use the default key generation method to generate a key for the server. Warn about the use of aes attribute of authn.UsernamePasswordMako class. Hide cryptography details behind the saml2.cryptography module. Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent ab9e475 commit 912a1b3

File tree

4 files changed

+38
-40
lines changed

4 files changed

+38
-40
lines changed

src/saml2/authn.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import warnings
12
import logging
23
import six
34
import time
45
from saml2 import SAMLError
5-
from saml2.aes import AESCipher
6+
import saml2.cryptography.symmetric
67
from saml2.httputil import Response
78
from saml2.httputil import make_cookie
89
from saml2.httputil import Redirect
@@ -14,6 +15,7 @@
1415
__author__ = 'rolandh'
1516

1617
logger = logging.getLogger(__name__)
18+
warnings.simplefilter('default')
1719

1820

1921
class AuthnFailure(SAMLError):
@@ -120,7 +122,16 @@ def __init__(self, srv, mako_template, template_lookup, pwd, return_to):
120122
self.return_to = return_to
121123
self.active = {}
122124
self.query_param = "upm_answer"
123-
self.aes = AESCipher(self.srv.symkey.encode())
125+
self.symmetric = saml2.cryptography.symmetric.Default(srv.symkey)
126+
127+
@property
128+
def aes(self):
129+
_deprecation_msg = (
130+
'This attribute is deprecated. '
131+
'It will be removed in the next version. '
132+
'Use self.symmetric instead.')
133+
warnings.warn(_deprecation_msg, DeprecationWarning)
134+
return self.symmetric
124135

125136
def __call__(self, cookie=None, policy_url=None, logo_url=None,
126137
query="", **kwargs):
@@ -172,7 +183,7 @@ def verify(self, request, **kwargs):
172183
self._verify(_dict["password"][0], _dict["login"][0])
173184
timestamp = str(int(time.mktime(time.gmtime())))
174185
msg = "::".join([_dict["login"][0], timestamp])
175-
info = self.aes.encrypt(msg.encode())
186+
info = self.symmetric.encrypt(msg.encode())
176187
self.active[info] = timestamp
177188
cookie = make_cookie(self.cookie_name, info, self.srv.seed)
178189
return_to = create_return_url(self.return_to, _dict["query"][0],
@@ -192,7 +203,7 @@ def authenticated_as(self, cookie=None, **kwargs):
192203
info, timestamp = parse_cookie(self.cookie_name,
193204
self.srv.seed, cookie)
194205
if self.active[info] == timestamp:
195-
msg = self.aes.decrypt(info).decode()
206+
msg = self.symmetric.decrypt(info).decode()
196207
uid, _ts = msg.split("::")
197208
if timestamp == _ts:
198209
return {"uid": uid}

src/saml2/cert.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
from os.path import join
1010
from os import remove
1111

12-
from cryptography.hazmat.backends import default_backend
13-
from cryptography.x509 import load_pem_x509_certificate
12+
import saml2.cryptography.pki
1413

15-
backend = default_backend()
1614

1715
class WrongInput(Exception):
1816
pass
@@ -325,7 +323,8 @@ def verify(self, signing_cert_str, cert_str):
325323
cert_algorithm = cert_algorithm.decode('ascii')
326324
cert_str = cert_str.encode('ascii')
327325

328-
cert_crypto = load_pem_x509_certificate(cert_str, backend)
326+
cert_crypto = saml2.cryptography.pki.load_pem_x509_certificate(
327+
cert_str)
329328

330329
try:
331330
crypto.verify(ca_cert, cert_crypto.signature,

src/saml2/server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import six
1515
import threading
1616

17+
import saml2.cryptography.symmetric
1718
from saml2 import saml
1819
from saml2 import element_to_extension_element
1920
from saml2 import class_name
@@ -84,7 +85,10 @@ def __init__(self, config_file="", config=None, cache=None, stype="idp",
8485
self.cache = cache
8586
self.ticket = {}
8687
self.session_db = self.choose_session_storage()
87-
self.symkey = symkey
88+
if symkey:
89+
self.symkey = symkey.encode()
90+
else:
91+
self.symkey = saml2.cryptography.symmetric.Default.generate_key()
8892
self.seed = rndstr()
8993
self.lock = threading.Lock()
9094

src/saml2/sigver.py

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,8 @@
1919

2020
from future.backports.urllib.parse import urlencode
2121

22-
from cryptography.exceptions import InvalidSignature
23-
from cryptography.hazmat.backends import default_backend
24-
from cryptography.hazmat.primitives import hashes
25-
from cryptography.hazmat.primitives.asymmetric import rsa
26-
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
27-
from cryptography.hazmat.primitives.serialization import load_pem_private_key
28-
from cryptography.x509 import load_pem_x509_certificate
22+
import saml2.cryptography.asymmetric
23+
import saml2.cryptography.pki
2924

3025
from tempfile import NamedTemporaryFile
3126
from subprocess import Popen
@@ -75,8 +70,6 @@
7570
PREFIX1 = "<?xml version='1.0' encoding='UTF-8'?>"
7671
PREFIX2 = '<?xml version="1.0" encoding="UTF-8"?>'
7772

78-
backend = default_backend()
79-
8073

8174
class SigverError(SAMLError):
8275
pass
@@ -489,7 +482,7 @@ def base64_to_long(data):
489482

490483

491484
def extract_rsa_key_from_x509_cert(pem):
492-
cert = load_pem_x509_certificate(pem, backend)
485+
cert = saml2.cryptography.pki.load_pem_x509_certificate(pem)
493486
return cert.public_key()
494487

495488

@@ -499,7 +492,9 @@ def pem_format(key):
499492

500493

501494
def import_rsa_key_from_file(filename):
502-
return load_pem_private_key(read_file(filename, 'rb'), None, backend)
495+
data = read_file(filename, 'rb')
496+
key = saml2.cryptography.asymmetric.load_pem_private_key(data, None)
497+
return key
503498

504499

505500
def parse_xmlsec_output(output):
@@ -542,31 +537,20 @@ def __init__(self, digest, key=None):
542537
self.digest = digest
543538

544539
def sign(self, msg, key=None):
545-
if key is None:
546-
key = self.key
547-
548-
return key.sign(msg, PKCS1v15(), self.digest)
540+
return saml2.cryptography.asymmetric.key_sign(
541+
key or self.key, msg, self.digest)
549542

550543
def verify(self, msg, sig, key=None):
551-
if key is None:
552-
key = self.key
553-
554-
try:
555-
if isinstance(key, rsa.RSAPrivateKey):
556-
key = key.public_key()
557-
558-
key.verify(sig, msg, PKCS1v15(), self.digest)
559-
return True
560-
except InvalidSignature:
561-
return False
544+
return saml2.cryptography.asymmetric.key_verify(
545+
key or self.key, sig, msg, self.digest)
562546

563547

564548
SIGNER_ALGS = {
565-
SIG_RSA_SHA1: RSASigner(hashes.SHA1()),
566-
SIG_RSA_SHA224: RSASigner(hashes.SHA224()),
567-
SIG_RSA_SHA256: RSASigner(hashes.SHA256()),
568-
SIG_RSA_SHA384: RSASigner(hashes.SHA384()),
569-
SIG_RSA_SHA512: RSASigner(hashes.SHA512()),
549+
SIG_RSA_SHA1: RSASigner(saml2.cryptography.asymmetric.hashes.SHA1()),
550+
SIG_RSA_SHA224: RSASigner(saml2.cryptography.asymmetric.hashes.SHA224()),
551+
SIG_RSA_SHA256: RSASigner(saml2.cryptography.asymmetric.hashes.SHA256()),
552+
SIG_RSA_SHA384: RSASigner(saml2.cryptography.asymmetric.hashes.SHA384()),
553+
SIG_RSA_SHA512: RSASigner(saml2.cryptography.asymmetric.hashes.SHA512()),
570554
}
571555

572556
REQ_ORDER = ["SAMLRequest", "RelayState", "SigAlg"]

0 commit comments

Comments
 (0)