Changeset 1465
- Timestamp:
- 30/08/06 16:36:23 (14 years ago)
- Location:
- TI12-security/trunk/python/Tests/xmlsec/WS-Security
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/python/Tests/xmlsec/WS-Security/wsClient.py
r1454 r1465 1 1 #!/usr/bin/env python 2 2 3 import sys, socket 3 4 from ZSI import Binding, TCcompound, TC 4 5 from wsInterface import * … … 23 24 import pdb;pdb.set_trace() 24 25 print ' Sending: %s' % MESSAGE 25 txResp = binding.Send(None, 26 27 try: 28 txResp = binding.Send(None, 26 29 'echo', 27 30 echoRequest, 28 31 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/") 29 32 30 rxResp = binding.Receive(echoResponseWrapper(), 31 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/") 32 33 rxResp = binding.Receive(echoResponseWrapper(), 34 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/") 35 36 except socket.error, (errNum, errMsg): 37 print >>sys.stderr, "Socket error: %s" % errMsg 38 sys.exit(1) 39 33 40 if not isinstance(rxResp, echoResponse) and \ 34 41 not issubclass(echoResponse, rxResp.__class__): 35 raise TypeError, "%s incorrect response type" % rxResp.__class__ 42 print >>sys.stderr, "%s incorrect response type" % rxResp.__class__ 43 sys.exit(1) 36 44 37 45 print 'Response: %s' % rxResp._message -
TI12-security/trunk/python/Tests/xmlsec/WS-Security/wsSecurity.py
r1461 r1465 16 16 from ZSI.generate.pyclass import pyclass_type 17 17 18 from ZSI.wstools.Utility import DOMException, SplitQName 19 from ZSI.wstools.Utility import NamespaceError, MessageInterface, ElementProxy 20 18 21 # XML Parsing 19 22 from cStringIO import StringIO … … 24 27 from ZSI.wstools.c14n import Canonicalize 25 28 from xml.dom import Node 29 from xml.xpath.Context import Context 30 from xml import xpath 26 31 27 32 # Type codes for signature elements … … 64 69 65 70 def sign(self, soapWriter): 66 67 # Use wsse:TransformationParameters with ds:Transforms?? 68 msgTmpl = """<?xml version="1.0" encoding="UTF-8"?> 69 <!-- 70 SOAP Message with WSSE Signature 71 --> 72 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 73 xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" 74 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 75 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 76 <soapenv:Header> 77 <wsse:Security 78 xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext" 79 xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" 80 soapenv:mustUnderstand="1"> 81 <wsse:BinarySecurityToken 82 wsu:Id="binaryToken" 83 ValueType="wsse:X509v3" 84 EncodingType="wsse:Base64Binary"> 85 %s 86 </wsse:BinarySecurityToken> 87 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 88 <ds:SignedInfo> 89 <ds:CanonicalizationMethod 90 Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> 91 <ds:SignatureMethod 92 Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 93 </ds:SignedInfo> 94 <ds:SignatureValue>%s</ds:SignatureValue> 95 <ds:KeyInfo> 96 <wsse:SecurityTokenReference> 97 <wsse:Reference URI="#binaryToken"/> 98 </wsse:SecurityTokenReference> 99 </ds:KeyInfo> 100 </ds:Signature> 101 </wsse:Security> 102 </soapenv:Header> 103 <soapenv:Body xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" 104 wsu:Id="body"> 105 Hello, World! 106 </soapenv:Body> 107 </soapenv:Envelope>""" 108 109 71 '''Sign the message body and binary security token of a SOAP message 72 ''' 110 73 # Add X.509 cert as binary security token 111 74 x509Cert = X509.load_cert(self.__certFilePath) … … 116 79 x509CertStr = x509CertPat.findall(x509Cert.as_pem())[0] 117 80 118 # attrTypeCodeDict = \119 # {120 # (OASIS.UTILITY, 'Id'): ZSI.TC.String(),121 # 'ValueType': ZSI.TC.String(),122 # 'EncodingType': ZSI.TC.String()123 # }124 # binSecurityTokTC = \125 # getGlobalElemDecl(OASIS.WSSE, "BinarySecurityToken")126 #127 # binSecurityTokTC.attribute_typecode_dict.update(attrTypeCodeDict)128 #129 # securityTC = getGlobalElemDecl(OASIS.WSSE, "Security")130 # securityPyObj = securityTC.pyclass()131 # securityPyObj._any = []132 # securityPyObj._any.append(binSecurityTokTC.pyclass())133 #134 #soapWriter.serialize_header(securityPyObj, securityTC)135 81 136 82 # Namespaces for XPath searches … … 156 102 binSecTokElem.node.setAttribute('ValueType', "wsse:X509v3") 157 103 binSecTokElem.node.setAttribute('EncodingType', "wsse:Base64Binary") 158 binSecTokElem.createAppendTextNode(x509CertStr)159 104 160 105 # Add ID 161 106 binSecTokElem.node.setAttribute('wsu:Id', "binaryToken") 107 108 binSecTokElem.createAppendTextNode(x509CertStr) 109 162 110 163 111 signatureElem = wsseElem.createAppendElement(DSIG.BASE, 'Signature') … … 181 129 soapWriter.body.node.setAttribute('xmlns:wsu', WSU.UTILITY) 182 130 131 183 132 # 1) Reference Generation 184 133 # 185 134 # Find references 186 135 #idNodes = XPath.Compile('//*[@wsu:Id]').evaluate(docCtxt) 187 idElems = [ binSecTokElem, soapWriter.body]136 idElems = [soapWriter.body]#[binSecTokElem, soapWriter.body] 188 137 for idElem in idElems: 189 138 … … 192 141 193 142 # Canonicalize reference 194 c14nRef = idElem.canonicalize() 143 # c14nRef1 = idElem.canonicalize() 144 c14nRef = Canonicalize(idElem.node) 145 import pdb;pdb.set_trace() 146 # print "Equal? %s" % (c14nRef == c14nRef1) 147 print 'idElem' 148 print idElem 149 print 'c14nRef' 150 print c14nRef 195 151 196 152 # Calculate digest for reference and base 64 encode … … 199 155 digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 200 156 157 201 158 # Add a new reference element to SignedInfo 202 159 refElem = signedInfoElem.createAppendElement(DSIG.BASE, 203 160 'Reference') 204 161 refElem.node.setAttribute('URI', uri) 205 refElem.createAppendTextNode(digestValue) 162 163 # Use ds:Transforms or wsse:TransformationParameters? 164 tranformsElem = refElem.createAppendElement(DSIG.BASE, 165 'Transforms') 166 tranformElem = tranformsElem.createAppendElement(DSIG.BASE, 167 'Transform') 168 tranformElem.node.setAttribute('Algorithm', DSIG.C14N) 169 170 refElem.createAppendElement(DSIG.BASE, 'DigestMethod') 171 refElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 172 173 digestValueElem = refElem.createAppendElement(DSIG.BASE, 174 'DigestValue') 175 digestValueElem.createAppendTextNode(digestValue) 206 176 207 177 … … 249 219 250 220 # Check the signature 251 verify = bool(rsaPubKey.verify(signedInfoDigestValue, signatureValue))252 print soapWriter.dom.node.toprettyxml()253 254 from xml.dom.ext.reader.PyExpat import Reader255 Reader().fromString(str(soapWriter))256 import pdb;pdb.set_trace()257 258 259 def verify(self, soapWriter):221 # verify = bool(rsaPubKey.verify(signedInfoDigestValue, signatureValue)) 222 # print soapWriter.dom.node.toprettyxml() 223 # 224 # from xml.dom.ext.reader.PyExpat import Reader 225 # Reader().fromString(str(soapWriter)) 226 # import pdb;pdb.set_trace() 227 228 229 def verify(self, parsedSOAP): 260 230 """Verify signature""" 261 import pdb;pdb.set_trace() 262 return 263 # Parse file 264 doc = NonvalidatingReader.parseStream(StringIO(xmlTxt)) 265 266 # Set namespaces for XPath queries 231 232 element = ElementProxy(None, message=parsedSOAP.header) 267 233 processorNss = \ 268 234 { … … 270 236 'wsu': WSU.UTILITY, 271 237 'wsse': OASIS.WSSE, 272 'wsa': WSA200403.ADDRESS,273 238 'soapenv':"http://schemas.xmlsoap.org/soap/envelope/" 274 239 } 275 docCtxt = XPath.Context.Context(doc, processorNss=processorNss) 276 277 # Two stagfe process: reference validation followed by signature 240 ctxt = Context(parsedSOAP.dom, processorNss=processorNss) 241 242 243 signatureNodes = xpath.Evaluate('//ds:Signature', 244 contextNode=parsedSOAP.dom, 245 context=ctxt) 246 if len(signatureNodes) > 1: 247 raise Exception, 'Multiple ds:Signature elements found' 248 249 try: 250 signatureNodes = signatureNodes[0] 251 except: 252 # Message wasn't signed 253 return 254 255 # Two stage process: reference validation followed by signature 278 256 # validation 279 257 280 258 # 1) Reference Validation 281 refNodes = XPath.Compile('//ds:Reference').evaluate(docCtxt) 282 259 refNodes = xpath.Evaluate('//ds:Reference', 260 contextNode=parsedSOAP.dom, 261 context=ctxt) 262 283 263 # Make a lambda to pick out node child or children with a given 284 264 # name … … 316 296 # XPath reference 317 297 uriXPath = '//*[@wsu:Id="%s"]' % refURI[1:] 318 uriNode = XPath.Compile(uriXPath).evaluate(docCtxt)[0] 298 uriNode = xpath.Evaluate(uriXPath, 299 contextNode=parsedSOAP.dom, 300 context=ctxt)[0] 319 301 320 302 c14nRef = Canonicalize(uriNode, **kw) 303 import pdb;pdb.set_trace() 321 304 digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 322 305 … … 327 310 # Reference validates if the two digest values are the same 328 311 if digestValue != nodeDigestValue: 329 raise Exception, "DigestValues do not match: URI=%s" % uri330 331 312 raise Exception, 'Digest Values do not match for URI: "%s"' %\ 313 refURI 314 332 315 # 2) Signature Validation 333 signedInfoNode = XPath.Compile('//ds:SignedInfo').evaluate(docCtxt)[0] 316 signedInfoNode = xpath.Evaluate('//ds:SignedInfo', 317 contextNode=parsedSOAP.dom, 318 context=ctxt)[0] 334 319 335 320 # Get the canonicalization method - change later to check this and … … 349 334 # Get the signature value in order to check against the digest just 350 335 # calculated 351 signatureValueNode = \ 352 XPath.Compile('//ds:SignatureValue').evaluate(docCtxt)[0] 336 signatureValueNode = xpath.Evaluate('//ds:SignatureValue', 337 contextNode=parsedSOAP.dom, 338 context=ctxt)[0] 353 339 354 340 # Remove base 64 encoding … … 371 357 signatureValue)) 372 358 except RSA.RSAError: 373 verify = False 374 375 return verify 359 raise Exception, "Invalid Signature" 376 360 377 361 -
TI12-security/trunk/python/Tests/xmlsec/WS-Security/wsServer.py
r1461 r1465 2 2 3 3 import sys 4 import socket 5 6 # Web service interface 7 from ZSI import * 8 from ZSI.dispatch import SOAPRequestHandler, _client_binding 9 from ZSI.auth import _auth_tc, AUTH, ClientBinding 10 11 from BaseHTTPServer import HTTPServer 12 13 from wsSecurity import * 4 14 from wsInterface import * 5 15 6 16 17 #_________________________________________________________________________ 18 def echo(ps): 19 """example service simply returns message sent to it""" 20 21 import pdb;pdb.set_trace() 22 signatureHandler = SignatureHandler(\ 23 certFilePath='../../Junk-cert.pem', 24 priKeyFilePath='../../Junk-key.pem', 25 priKeyPwd=open('../../tmp2').read().strip()) 26 signatureHandler.verify(ps) 27 28 request = ps.Parse(echoRequestWrapper) 29 response = echoResponseWrapper() 30 response._message = request._message 31 32 return response 33 34 def _Dispatch(ps, modules, SendResponse, SendFault, docstyle=0, 35 nsdict={}, typesmodule=None, rpc=None, **kw): 36 '''Find a handler for the SOAP request in ps; search modules. 37 Call SendResponse or SendFault to send the reply back, appropriately. 38 39 Default Behavior -- Use "handler" method to parse request, and return 40 a self-describing request (w/typecode). 41 42 Other Behaviors: 43 docstyle -- Parse result into an XML typecode (DOM). Behavior, wrap result 44 in a body_root "Response" appended message. 45 46 rpc -- Specify RPC wrapper of result. Behavior, ignore body root (RPC Wrapper) 47 of request, parse all "parts" of message via individual typecodes. Expect 48 response pyobj w/typecode to represent the entire message (w/RPC Wrapper), 49 else pyobj w/o typecode only represents "parts" of message. 50 51 ''' 52 global _client_binding 53 try: 54 what = ps.body_root.localName 55 56 # See what modules have the element name. 57 if modules is None: 58 modules = ( sys.modules['__main__'], ) 59 60 handlers = [ getattr(m, what) for m in modules if hasattr(m, what) ] 61 if len(handlers) == 0: 62 raise TypeError("Unknown method " + what) 63 64 # Of those modules, see who's callable. 65 handlers = [ h for h in handlers if callable(h) ] 66 if len(handlers) == 0: 67 raise TypeError("Unimplemented method " + what) 68 if len(handlers) > 1: 69 raise TypeError("Multiple implementations found: " + `handlers`) 70 handler = handlers[0] 71 72 _client_binding = ClientBinding(ps) 73 if docstyle: 74 result = handler(ps.body_root) 75 tc = TC.XML(aslist=1, pname=what + 'Response') 76 elif rpc is None: 77 # Not using typesmodule, expect 78 # result to carry typecode 79 result = handler(ps) 80 if hasattr(result, 'typecode') is False: 81 raise TypeError("Expecting typecode in result") 82 tc = result.typecode 83 else: 84 data = _child_elements(ps.body_root) 85 if len(data) == 0: 86 arg = [] 87 else: 88 try: 89 try: 90 type = data[0].localName 91 tc = getattr(typesmodule, type).typecode 92 except Exception, e: 93 tc = TC.Any() 94 arg = [ tc.parse(e, ps) for e in data ] 95 except EvaluateException, e: 96 SendFault(FaultFromZSIException(e), **kw) 97 return 98 result = handler(*arg) 99 if hasattr(result, 'typecode'): 100 tc = result.typecode 101 else: 102 tc = TC.Any(aslist=1, pname=what + 'Response') 103 result = [ result ] 104 105 106 sw = SoapWriter(nsdict=nsdict) 107 108 sw.serialize(result, tc, rpc=rpc) 109 110 signatureHandler = SignatureHandler(\ 111 certFilePath='../../Junk-cert.pem', 112 priKeyFilePath='../../Junk-key.pem', 113 priKeyPwd=open('../../tmp2').read().strip()) 114 signatureHandler.sign(sw) 115 116 return SendResponse(str(sw), **kw) 117 118 except Exception, e: 119 # Something went wrong, send a fault. 120 return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw) 121 122 #_____________________________________________________________________________ 123 class EchoSOAPRequestHandler(SOAPRequestHandler): 124 """Implement to allow overloaded do_POST in order to handle WS-Security 125 for outbound messages""" 126 127 def do_POST(self): 128 """Override default to allow custom dispatch call""" 129 try: 130 ct = self.headers['content-type'] 131 if ct.startswith('multipart/'): 132 cid = resolvers.MIMEResolver(ct, self.rfile) 133 xml = cid.GetSOAPPart() 134 ps = ParsedSoap(xml, resolver=cid.Resolve) 135 else: 136 length = int(self.headers['content-length']) 137 ps = ParsedSoap(self.rfile.read(length)) 138 except ParseException, e: 139 self.send_fault(FaultFromZSIException(e)) 140 return 141 except Exception, e: 142 # Faulted while processing; assume it's in the header. 143 self.send_fault(FaultFromException(e, 1, sys.exc_info()[2])) 144 return 145 146 _Dispatch(ps, self.server.modules, self.send_xml, self.send_fault, 147 docstyle=self.server.docstyle, nsdict=self.server.nsdict, 148 typesmodule=self.server.typesmodule, rpc=self.server.rpc) 149 150 151 #_____________________________________________________________________________ 152 def AsServer(port=80, 153 modules=None, 154 docstyle=0, 155 nsdict={}, 156 typesmodule=None, 157 rpc=None, 158 **kw): 159 160 address = ('', port) 161 httpd = HTTPServer(address, EchoSOAPRequestHandler) 162 httpd.modules = modules 163 httpd.docstyle = docstyle 164 httpd.nsdict = nsdict 165 httpd.typesmodule = typesmodule 166 httpd.rpc = rpc 167 httpd.serve_forever() 168 169 170 171 ''' 7 172 def echo(ps): 8 173 frame = sys._getframe().f_back … … 14 179 15 180 return response 16 181 ''' 17 182 18 183 if __name__ == '__main__': 19 184 print "Server listening ..." 185 20 186 try: 21 dispatch.AsServer(port=8080)22 187 AsServer(port=8080) 188 23 189 except KeyboardInterrupt: 24 190 sys.exit(0) 191 192 except socket.error, e: 193 print >>sys.stderr, "Server socket error: %s" % e[1] 194 sys.exit(1) 195 196 # except Exception, e: 197 # print >>sys.stderr, "Server: %s" % e 198 # sys.exit(1)
Note: See TracChangeset
for help on using the changeset viewer.