71
71
SIG = "{%s#}%s" % (ds .NAMESPACE , "Signature" )
72
72
73
73
RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
74
+ RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
75
+ RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
76
+ RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
77
+
74
78
RSA_1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5"
75
79
TRIPLE_DES_CBC = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"
76
80
XMLTAG = "<?xml version='1.0'?>"
@@ -313,7 +317,7 @@ def signed_instance_factory(instance, seccont, elements_to_sign=None):
313
317
signed_xml = "%s" % instance
314
318
for (node_name , nodeid ) in elements_to_sign :
315
319
signed_xml = seccont .sign_statement (
316
- signed_xml , class_name = node_name , node_id = nodeid )
320
+ signed_xml , node_name = node_name , node_id = nodeid )
317
321
318
322
#print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
319
323
#print "%s" % signed_xml
@@ -600,9 +604,9 @@ def verify(self, msg, sig, key):
600
604
601
605
SIGNER_ALGS = {
602
606
RSA_SHA1 : RSASigner (SHA ),
603
- "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" : RSASigner (SHA256 ),
604
- "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" : RSASigner (SHA384 ),
605
- "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" : RSASigner (SHA512 ),
607
+ RSA_SHA256 : RSASigner (SHA256 ),
608
+ RSA_SHA384 : RSASigner (SHA384 ),
609
+ RSA_SHA512 : RSASigner (SHA512 ),
606
610
}
607
611
608
612
REQ_ORDER = ["SAMLRequest" , "RelayState" , "SigAlg" ]
@@ -698,13 +702,14 @@ def version(self):
698
702
def encrypt (self , text , recv_key , template , key_type ):
699
703
raise NotImplementedError ()
700
704
701
- def encrypt_assertion (self , statement , recv_key , key_type , xpath = "" ):
705
+ def encrypt_assertion (self , statement , enc_key , template , key_type ,
706
+ node_xpath ):
702
707
raise NotImplementedError ()
703
708
704
709
def decrypt (self , enctext , key_file ):
705
710
raise NotImplementedError ()
706
711
707
- def sign_statement (self , statement , class_name , key_file , node_id ,
712
+ def sign_statement (self , statement , node_name , key_file , node_id ,
708
713
id_attr ):
709
714
raise NotImplementedError ()
710
715
@@ -764,26 +769,27 @@ def encrypt(self, text, recv_key, template, session_key_type, xpath=""):
764
769
return output
765
770
766
771
def encrypt_assertion (self , statement , enc_key , template ,
767
- key_type = "des-192" ):
772
+ key_type = "des-192" , node_xpath = None ):
768
773
"""
769
- --pubkey-cert-pem ../../example/idp2/pki/mycert.pem \
770
- --session-key des-192 --xml-data pre_saml2_assertion.xml \
771
- --node-xpath '/*[local-name()="Response"]/*[local-name(
772
- )="EncryptedAssertion"]/*[local-name()="Assertion"]' \
773
- enc-element-3des-kt-rsa1_5.tmpl > enc_3des_rsa_assertion.xml
774
+ Will encrypt an assertion
774
775
775
- :param statement:
776
- :param cert_file:
777
- :param cert_type:
778
- :return:
776
+ :param statement: A XML document that contains the assertion to encrypt
777
+ :param enc_key: File name of a file containing the encryption key
778
+ :param template: A template for the encryption part to be added.
779
+ :param key_type: The type of session key to use.
780
+ :return: The encrypted text
779
781
"""
782
+
780
783
statement = pre_encrypt_assertion (statement )
781
784
_ , fil = make_temp ("%s" % statement , decode = False , delete = False )
782
785
_ , tmpl = make_temp ("%s" % template , decode = False )
783
786
787
+ if not node_xpath :
788
+ node_xpath = ASSERT_XPATH
789
+
784
790
com_list = [self .xmlsec , "encrypt" , "--pubkey-cert-pem" , enc_key ,
785
791
"--session-key" , key_type , "--xml-data" , fil ,
786
- "--node-xpath" , ASSERT_XPATH ]
792
+ "--node-xpath" , node_xpath ]
787
793
788
794
(_stdout , _stderr , output ) = self ._run_xmlsec (
789
795
com_list , [tmpl ], exception = EncryptError , validate_output = False )
@@ -795,6 +801,13 @@ def encrypt_assertion(self, statement, enc_key, template,
795
801
return output
796
802
797
803
def decrypt (self , enctext , key_file ):
804
+ """
805
+
806
+ :param enctext: XML document containing an encrypted part
807
+ :param key_file: The key to use for the decryption
808
+ :return: The decrypted document
809
+ """
810
+
798
811
logger .debug ("Decrypt input len: %d" % len (enctext ))
799
812
_ , fil = make_temp ("%s" % enctext , decode = False )
800
813
@@ -806,13 +819,13 @@ def decrypt(self, enctext, key_file):
806
819
validate_output = False )
807
820
return output
808
821
809
- def sign_statement (self , statement , class_name , key_file , node_id ,
822
+ def sign_statement (self , statement , node_name , key_file , node_id ,
810
823
id_attr ):
811
824
"""
812
825
Sign an XML statement.
813
826
814
827
:param statement: The statement to be signed
815
- :param class_name : string like 'urn:oasis:names:...:Assertion'
828
+ :param node_name : string like 'urn:oasis:names:...:Assertion'
816
829
:param key_file: The file where the key can be found
817
830
:param node_id:
818
831
:param id_attr: The attribute name for the identifier, normally one of
@@ -824,7 +837,7 @@ def sign_statement(self, statement, class_name, key_file, node_id,
824
837
825
838
com_list = [self .xmlsec , "--sign" ,
826
839
"--privkey-pem" , key_file ,
827
- "--id-attr:%s" % id_attr , class_name ]
840
+ "--id-attr:%s" % id_attr , node_name ]
828
841
if node_id :
829
842
com_list .extend (["--node-id" , node_id ])
830
843
@@ -937,7 +950,7 @@ def version(self):
937
950
# better than static 0.0 here.
938
951
return "XMLSecurity 0.0"
939
952
940
- def sign_statement (self , statement , _class_name , key_file , node_id ,
953
+ def sign_statement (self , statement , node_name , key_file , node_id ,
941
954
_id_attr ):
942
955
"""
943
956
Sign an XML statement.
@@ -946,6 +959,7 @@ def sign_statement(self, statement, _class_name, key_file, node_id,
946
959
implementation are :
947
960
948
961
:param statement: XML as string
962
+ :param node_name: Name of the node to sign
949
963
:param key_file: xmlsec key_spec string(), filename,
950
964
"pkcs11://" URI or PEM data
951
965
:returns: Signed XML as string
@@ -1242,18 +1256,18 @@ def encrypt(self, text, recv_key="", template="", key_type=""):
1242
1256
1243
1257
return self .crypto .encrypt (text , recv_key , template , key_type )
1244
1258
1245
- def encrypt_assertion (self , statement , cert_file , cert_type = "pem" ):
1259
+ def encrypt_assertion (self , statement , enc_key , template ,
1260
+ key_type = "des-192" , node_xpath = None ):
1246
1261
"""
1247
- --pubkey-cert-pem ../../example/idp2/pki/mycert.pem \
1248
- --session-key des-192 --xml-data pre_saml2_assertion.xml \
1249
- --node-xpath '/*[local-name()="Response"]/*[local-name(
1250
- )="EncryptedAssertion"]/*[local-name()="Assertion"]' \
1251
- enc-element-3des-kt-rsa1_5.tmpl > enc_3des_rsa_assertion.xml
1252
- :param statement:
1253
- :param cert_file:
1254
- :param cert_type:
1255
- :return:
1262
+ Will encrypt an assertion
1263
+
1264
+ :param statement: A XML document that contains the assertion to encrypt
1265
+ :param enc_key: File name of a file containing the encryption key
1266
+ :param template: A template for the encryption part to be added.
1267
+ :param key_type: The type of session key to use.
1268
+ :return: The encrypted text
1256
1269
"""
1270
+ raise NotImplemented ()
1257
1271
1258
1272
def decrypt (self , enctext , key_file = None ):
1259
1273
""" Decrypting an encrypted text by the use of a private key.
@@ -1377,7 +1391,7 @@ def check_signature(self, item, node_name=NODE_NAME, origdoc=None,
1377
1391
"""
1378
1392
1379
1393
:param item: Parsed entity
1380
- :param node_name: The name of the class that is signed
1394
+ :param node_name: The name of the node/ class/element that is signed
1381
1395
:param origdoc: The original XML string
1382
1396
:param id_attr:
1383
1397
:param must:
@@ -1577,12 +1591,12 @@ def sign_statement_using_xmlsec(self, statement, **kwargs):
1577
1591
""" Deprecated function. See sign_statement(). """
1578
1592
return self .sign_statement (statement , ** kwargs )
1579
1593
1580
- def sign_statement (self , statement , class_name , key = None ,
1594
+ def sign_statement (self , statement , node_name , key = None ,
1581
1595
key_file = None , node_id = None , id_attr = "" ):
1582
1596
"""Sign a SAML statement.
1583
1597
1584
1598
:param statement: The statement to be signed
1585
- :param class_name : string like 'urn:oasis:names:...:Assertion'
1599
+ :param node_name : string like 'urn:oasis:names:...:Assertion'
1586
1600
:param key: The key to be used for the signing, either this or
1587
1601
:param key_file: The file where the key can be found
1588
1602
:param node_id:
@@ -1599,7 +1613,7 @@ def sign_statement(self, statement, class_name, key=None,
1599
1613
if not key and not key_file :
1600
1614
key_file = self .key_file
1601
1615
1602
- return self .crypto .sign_statement (statement , class_name , key_file ,
1616
+ return self .crypto .sign_statement (statement , node_name , key_file ,
1603
1617
node_id , id_attr )
1604
1618
1605
1619
def sign_assertion_using_xmlsec (self , statement , ** kwargs ):
@@ -1797,3 +1811,16 @@ def response_factory(sign=False, encrypt=False, **kwargs):
1797
1811
setattr (response , key , val )
1798
1812
1799
1813
return response
1814
+
1815
+ # ----------------------------------------------------------------------------
1816
+ if __name__ == '__main__' :
1817
+ import argparse
1818
+
1819
+ parser = argparse .ArgumentParser ()
1820
+ parser .add_argument ('-s' , '--list-sigalgs' , dest = 'listsigalgs' ,
1821
+ action = 'store_true' ,
1822
+ help = 'List implemented signature algorithms' )
1823
+ args = parser .parse_args ()
1824
+
1825
+ if args .listsigalgs :
1826
+ print '\n ' .join ([key for key , value in SIGNER_ALGS .items ()])
0 commit comments