5
5
6
6
import base64
7
7
import hashlib
8
+ import itertools
8
9
import logging
9
10
import os
10
11
import ssl
@@ -857,7 +858,8 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i
857
858
:param cert_type: The file type of the certificate
858
859
:param node_name: The name of the class that is signed
859
860
:param node_id: The identifier of the node
860
- :param id_attr: Should normally be one of 'id', 'Id' or 'ID'
861
+ :param id_attr: The attribute name for the identifier, normally one of
862
+ 'id','Id' or 'ID'
861
863
:return: Boolean True if the signature was correct otherwise False.
862
864
"""
863
865
if not isinstance (signedtext , six .binary_type ):
@@ -1350,67 +1352,60 @@ def decrypt_keys(self, enctext, keys=None, id_attr=''):
1350
1352
""" Decrypting an encrypted text by the use of a private key.
1351
1353
1352
1354
:param enctext: The encrypted text as a string
1355
+ :param keys: Keys to try to decrypt enctext with
1356
+ :param id_attr: The attribute name for the identifier, normally one of
1357
+ 'id','Id' or 'ID'
1353
1358
:return: The decrypted text
1354
1359
"""
1355
- _enctext = None
1356
-
1357
- if not id_attr :
1358
- id_attr = self .id_attr
1360
+ key_files = []
1359
1361
1360
1362
if not isinstance (keys , list ):
1361
1363
keys = [keys ]
1362
1364
1363
- if self .enc_key_files is not None :
1364
- for _enc_key_file in self .enc_key_files :
1365
- try :
1366
- _enctext = self .crypto .decrypt (enctext , _enc_key_file , id_attr )
1367
- except XmlsecError as e :
1368
- continue
1369
- else :
1370
- if _enctext :
1371
- return _enctext
1372
-
1373
- for _key in keys :
1374
- if _key is not None and len (_key .strip ()) > 0 :
1375
- if not isinstance (_key , six .binary_type ):
1376
- _key = str (_key ).encode ('ascii' )
1377
- _ , key_file = make_temp (_key , decode = False )
1378
- try :
1379
- _enctext = self .crypto .decrypt (enctext , key_file , id_attr )
1380
- except XmlsecError as e :
1381
- continue
1382
- else :
1383
- if _enctext :
1384
- return _enctext
1365
+ keys = [key for key in keys if key ]
1366
+ for key in keys :
1367
+ if not isinstance (key , six .binary_type ):
1368
+ key = key .encode ("ascii" )
1369
+ _ , key_file = make_temp (key , decode = False , delete = False )
1370
+ key_files .append (key_file )
1385
1371
1386
- return enctext
1372
+ try :
1373
+ dectext = self .decrypt (enctext , key_file = key_files , id_attr = id_attr )
1374
+ except DecryptError as e :
1375
+ raise
1376
+ else :
1377
+ return dectext
1378
+ finally :
1379
+ for key_file in key_files :
1380
+ os .unlink (key_file )
1387
1381
1388
1382
def decrypt (self , enctext , key_file = None , id_attr = '' ):
1389
1383
""" Decrypting an encrypted text by the use of a private key.
1390
1384
1391
1385
:param enctext: The encrypted text as a string
1392
1386
:return: The decrypted text
1393
1387
"""
1394
- _enctext = None
1395
-
1396
1388
if not id_attr :
1397
1389
id_attr = self .id_attr
1398
1390
1399
- if self .enc_key_files is not None :
1400
- for _enc_key_file in self .enc_key_files :
1401
- try :
1402
- _enctext = self .crypto .decrypt (enctext , _enc_key_file , id_attr )
1403
- except XmlsecError :
1404
- continue
1405
- else :
1406
- if _enctext is not None and len (_enctext ) > 0 :
1407
- return _enctext
1391
+ if not isinstance (key_file , list ):
1392
+ key_file = [key_file ]
1393
+
1394
+ key_files = [
1395
+ key for key in itertools .chain (key_file , self .enc_key_files ) if key
1396
+ ]
1397
+ for key_file in key_files :
1398
+ try :
1399
+ dectext = self .crypto .decrypt (enctext , key_file , id_attr )
1400
+ except XmlsecError as e :
1401
+ continue
1402
+ else :
1403
+ if dectext :
1404
+ return dectext
1408
1405
1409
- if key_file is not None and len (key_file .strip ()) > 0 :
1410
- _enctext = self .crypto .decrypt (enctext , key_file , id_attr )
1411
- if _enctext is not None and len (_enctext ) > 0 :
1412
- return _enctext
1413
- return enctext
1406
+ errmsg = "No key was able to decrypt the ciphertext. Keys tried: {keys}"
1407
+ errmsg = errmsg .format (keys = key_files )
1408
+ raise DecryptError (errmsg )
1414
1409
1415
1410
def verify_signature (self , signedtext , cert_file = None , cert_type = 'pem' , node_name = NODE_NAME , node_id = None , id_attr = '' ):
1416
1411
""" Verifies the signature of a XML document.
@@ -1420,7 +1415,8 @@ def verify_signature(self, signedtext, cert_file=None, cert_type='pem', node_nam
1420
1415
:param cert_type: The file type of the certificate
1421
1416
:param node_name: The name of the class that is signed
1422
1417
:param node_id: The identifier of the node
1423
- :param id_attr: Should normally be one of 'id', 'Id' or 'ID'
1418
+ :param id_attr: The attribute name for the identifier, normally one of
1419
+ 'id','Id' or 'ID'
1424
1420
:return: Boolean True if the signature was correct otherwise False.
1425
1421
"""
1426
1422
# This is only for testing purposes, otherwise when would you receive
@@ -1527,7 +1523,8 @@ def check_signature(self, item, node_name=NODE_NAME, origdoc=None, id_attr='', m
1527
1523
:param item: Parsed entity
1528
1524
:param node_name: The name of the node/class/element that is signed
1529
1525
:param origdoc: The original XML string
1530
- :param id_attr:
1526
+ :param id_attr: The attribute name for the identifier, normally one of
1527
+ 'id','Id' or 'ID'
1531
1528
:param must:
1532
1529
:return:
1533
1530
"""
0 commit comments