Changeset 1526
 Timestamp:
 20/09/06 17:18:33 (13 years ago)
 Location:
 TI12security/trunk/python/Tests/xmlsec
 Files:

 1 added
 1 edited
Legend:
 Unmodified
 Added
 Removed

TI12security/trunk/python/Tests/xmlsec/WSSecurity/wsSecurity.py
r1510 r1526 23 23 24 24 # For shared key encryption 25 from Crypto.Cipher import AES 25 from Crypto.Cipher import AES, DES3 26 26 import os 27 27 … … 50 50 # associated note 51 51 from xml.dom.ext.reader.PyExpat import Reader 52 53 54 class _ENCRYPTION(ENCRYPTION): 55 '''Derived from ENCRYPTION class to add in extra 'tripledescbc'  is this 56 any different to 'descbc'? ENCRYPTION class implies that it is the same 57 because it's assigned to 'BLOCK_3DES' ??''' 58 BLOCK_TRIPLEDES = "http://www.w3.org/2001/04/xmlenc#tripledescbc" 52 59 53 60 … … 393 400 class EncryptionHandler(object): 394 401 """Encrypt/Decrypt SOAP messages using WSSecurity""" 395 402 403 # Map namespace URIs to Crypto algorithm module and mode 404 cryptoAlg = \ 405 { 406 _ENCRYPTION.WRAP_AES256: {'module': AES, 407 'mode': AES.MODE_ECB, 408 'blockSize': 16}, 409 410 # CBC (Cipher Block Chaining) modes 411 _ENCRYPTION.BLOCK_AES256: {'module': AES, 412 'mode': AES.MODE_CBC, 413 'blockSize': 16}, 414 415 _ENCRYPTION.BLOCK_TRIPLEDES: {'module': DES3, 416 'mode': DES3.MODE_CBC, 417 'blockSize': 8} 418 } 419 420 396 421 def __init__(self, 397 422 certFilePath=None, 398 423 priKeyFilePath=None, 399 424 priKeyPwd=None, 400 chkSecurityTokRef=False): 425 chkSecurityTokRef=False, 426 encrNS=_ENCRYPTION.BLOCK_AES256): 401 427 402 428 self.__certFilePath = certFilePath … … 405 431 406 432 self.__chkSecurityTokRef = chkSecurityTokRef 407 408 433 434 # Algorithm for shared key encryption 435 try: 436 self.__encrAlg = self.cryptoAlg[encrNS] 437 438 except KeyError: 439 raise EncryptionError, \ 440 'Input encryption algorithm namespace "%s" is not supported' % encrNS 441 442 self.__encrNS = encrNS 443 444 409 445 def encrypt(self, soapWriter): 410 446 """Encrypt an outbound SOAP message … … 418 454 419 455 soapWriter.dom.setNamespaceAttribute('wsse', OASIS.WSSE) 420 soapWriter.dom.setNamespaceAttribute('xenc', ENCRYPTION.BASE)456 soapWriter.dom.setNamespaceAttribute('xenc', _ENCRYPTION.BASE) 421 457 soapWriter.dom.setNamespaceAttribute('ds', DSIG.BASE) 422 458 … … 427 463 wsseElem.node.setAttribute('SOAPENV:mustUnderstand', "1") 428 464 429 encrKeyElem = wsseElem.createAppendElement( ENCRYPTION.BASE,465 encrKeyElem = wsseElem.createAppendElement(_ENCRYPTION.BASE, 430 466 'EncryptedKey') 431 467 432 468 # Encryption method used to encrypt the shared key 433 keyEncrMethodElem = encrKeyElem.createAppendElement( ENCRYPTION.BASE,469 keyEncrMethodElem = encrKeyElem.createAppendElement(_ENCRYPTION.BASE, 434 470 'EncryptionMethod') 435 471 436 472 keyEncrMethodElem.node.setAttribute('Algorithm', 437 ENCRYPTION.KT_RSA_1_5)473 _ENCRYPTION.KT_RSA_1_5) 438 474 439 475 … … 461 497 462 498 # References to what has been encrypted 463 encrKeyCiphDataElem = encrKeyElem.createAppendElement(ENCRYPTION.BASE, 464 'CipherData') 499 encrKeyCiphDataElem = encrKeyElem.createAppendElement( 500 _ENCRYPTION.BASE, 501 'CipherData') 465 502 466 503 encrKeyCiphValElem = encrKeyCiphDataElem.createAppendElement( 467 468 504 _ENCRYPTION.BASE, 505 'CipherValue') 469 506 470 507 # References to what has been encrypted 471 refListElem = encrKeyElem.createAppendElement( ENCRYPTION.BASE,508 refListElem = encrKeyElem.createAppendElement(_ENCRYPTION.BASE, 472 509 'ReferenceList') 473 510 474 dataRefElem = refListElem.createAppendElement( ENCRYPTION.BASE,511 dataRefElem = refListElem.createAppendElement(_ENCRYPTION.BASE, 475 512 'DataReference') 476 513 dataRefElem.node.setAttribute('URI', "#encrypted") … … 478 515 479 516 # Add Encrypted data to SOAP body 480 encrDataElem = soapWriter.body.createAppendElement( ENCRYPTION.BASE,517 encrDataElem = soapWriter.body.createAppendElement(_ENCRYPTION.BASE, 481 518 'EncryptedData') 482 519 encrDataElem.node.setAttribute('Id', 'encrypted') 483 encrDataElem.node.setAttribute('Type', ENCRYPTION.BASE)520 encrDataElem.node.setAttribute('Type', _ENCRYPTION.BASE) 484 521 485 522 # Encryption method used to encrypt the target data 486 dataEncrMethodElem = encrDataElem.createAppendElement( ENCRYPTION.BASE,487 'EncryptionMethod')488 489 dataEncrMethodElem.node.setAttribute('Algorithm',490 ENCRYPTION.WRAP_AES256)523 dataEncrMethodElem = encrDataElem.createAppendElement( 524 _ENCRYPTION.BASE, 525 'EncryptionMethod') 526 527 dataEncrMethodElem.node.setAttribute('Algorithm', self.__encrNS) 491 528 492 529 # Cipher data 493 ciphDataElem = encrDataElem.createAppendElement( ENCRYPTION.BASE,530 ciphDataElem = encrDataElem.createAppendElement(_ENCRYPTION.BASE, 494 531 'CipherData') 495 532 496 ciphValueElem = ciphDataElem.createAppendElement( ENCRYPTION.BASE,533 ciphValueElem = ciphDataElem.createAppendElement(_ENCRYPTION.BASE, 497 534 'CipherValue') 498 535 … … 502 539 data = dataElem.toxml() 503 540 504 # AES algorithm requires data length to be a multiple of 16  pad as 505 # required 506 modData = len(data) % 16 507 nPad = modData and 16  modData or 0 508 data += ' '*nPad 509 510 # Encrypt required elements 511 sharedKey = os.urandom(32) 512 encryptedData = AES.new(sharedKey, AES.MODE_ECB).encrypt(data) 541 # Pad data to nearest multiple of encryption algorithm's block size 542 modData = len(data) % self.__encrAlg['blockSize'] 543 nPad = modData and self.__encrAlg['blockSize']  modData or 0 544 545 # PAd with random junk but ... 546 data += os.urandom(nPad1) 547 548 # Last byte should be number of padding bytes 549 # (http://www.w3.org/TR/xmlenccore/#secAlgBlock) 550 data += chr(nPad) 551 552 # Generate shared key and input vector  for testing use hardcoded 553 # values to allow later comparison 554 sharedKey = os.urandom(self.__encrAlg['blockSize']) 555 iv = os.urandom(self.__encrAlg['blockSize']) 556 557 alg = self.__encrAlg['module'].new(sharedKey, 558 self.__encrAlg['mode'], 559 iv) 560 561 # Encrypt required elements  prepend input vector 562 encryptedData = alg.encrypt(iv + data) 513 563 dataCiphValue = base64.encodestring(encryptedData).strip() 514 564 … … 543 593 processorNss = \ 544 594 { 545 'xenc': ENCRYPTION.BASE,595 'xenc': _ENCRYPTION.BASE, 546 596 'ds': DSIG.BASE, 547 597 'wsu': WSU.UTILITY, … … 585 635 keyAlgorithm = keyEncrMethodNode.getAttributeNodeNS(None, 586 636 "Algorithm").value 587 if keyAlgorithm != ENCRYPTION.KT_RSA_1_5:637 if keyAlgorithm != _ENCRYPTION.KT_RSA_1_5: 588 638 raise DecryptionError, \ 589 639 'Encryption algorithm for wrapped key is "%s", expecting "%s"' % \ 590 (keyAlgorithm, ENCRYPTION.KT_RSA_1_5)640 (keyAlgorithm, _ENCRYPTION.KT_RSA_1_5) 591 641 592 642 … … 598 648 contextNode=encrKeyNode, 599 649 context=ctxt) 600 # Look for ds:X509* elements to check against X.509 cert input 650 # TODO: Look for ds:X509* elements to check against X.509 cert 651 # input 601 652 602 653 … … 636 687 dataAlgorithm = dataEncrMethodNode.getAttributeNodeNS(None, 637 688 "Algorithm").value 638 if dataAlgorithm != ENCRYPTION.WRAP_AES256: 689 try: 690 # Match algorithm name to Crypto module 691 CryptoAlg = self.cryptoAlg[dataAlgorithm] 692 693 except KeyError: 639 694 raise DecryptionError, \ 640 'Encryption algorithm for data is "%s", expecting"%s"' % \641 (keyAlgorithm, ENCRYPTION.WRAP_AES256)695 'Encryption algorithm for data is "%s", supported algorithms are:\n "%s"' % \ 696 (keyAlgorithm, "\n".join(self.cryptoAlg.keys())) 642 697 643 698 # Get Data … … 648 703 encryptedData = base64.decodestring(dataCiphVal) 649 704 650 aes = AES.new(sharedKey, AES.MODE_ECB) 651 decryptedData = aes.decrypt(encryptedData) 652 705 alg = CryptoAlg['module'].new(sharedKey, CryptoAlg['mode']) 706 decryptedData = alg.decrypt(encryptedData) 707 708 # Strip prefix  assume is block size 709 decryptedData = decryptedData[CryptoAlg['blockSize']:] 710 711 # Strip any padding suffix  Last byte should be number of padding 712 # bytes 713 # (http://www.w3.org/TR/xmlenccore/#secAlgBlock) 714 lastChar = decryptedData[1] 715 nPad = ord(lastChar) 716 717 # Sanity check  there may be no padding at all  the last byte 718 # being the end of the encrypted XML? 719 # 720 # TODO: are there better sanity checks than this?! 721 if nPad < CryptoAlg['blockSize'] and nPad > 0 and \ 722 lastChar != '\n' and lastChar != '>': 723 724 # Follow http://www.w3.org/TR/xmlenccore/#secAlgBlock  725 # last byte gives number of padding bytes 726 decryptedData = decryptedData[:nPad] 727 728 653 729 # Parse the encrypted data  inherit from Reader as a fudge to 654 730 # enable relevant namespaces to be added prior to parse
Note: See TracChangeset
for help on using the changeset viewer.