source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/AttAuthority/server-config.tac @ 2510

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/AttAuthority/server-config.tac@2510
Revision 2510, 6.7 KB checked in by pjkersha, 13 years ago (diff)

ndg.security.server/ndg/security/server/AttAuthority/server-config.tac:
fix to caCertFilePathList input to SignatureHandler?. Correctly initialise
if not set.

ndg.security.server/ndg/security/server/AttAuthority/init.py:
Corrected error message text for where a user is not registered or no
mapping is available: ref. userId rather than AC holder DN to allow for the
case in DEWS where a userId distinct from a Proxy cert. DN is used.

ndg.security.test/ndg/security/test/AttAuthority/AttAuthorityClientTest.py:
added test8GetMappedAttCertStressTest test for WebSphere? integration tests.
It makes multiple calls with different ACs input to check for errors in
signature or verification.

ndg.security.test/ndg/security/test/AttAuthority/attAuthorityClientTest.cfg:
added additional config params for the above.

ndg.security.test/ndg/security/test/MyProxy/myProxyProperties.xml and
ndg.security.test/ndg/security/test/MyProxy/myProxyClientTest.cfg:
switched cert ID of test machine.

ndg.security.common/ndg/security/common/X509.py:

  • new X509Cert methods asDER and asPEM to convert to these formats.

toString now calls to asPEM

  • new class X509Stack to wrap M2Crypto.X509.X509_Stack. This includes an

extra method, verifyCertChain, to verify a chain of trust in the certs
contained in the stack.

  • standalone function, X509StackParseFromDER, wraps

M2Crypto.X509.new_stack_from_der

  • fix to X500DN class to enable correct parsing of proxy certificate DNs.

These have multiple CN entries. These are represented by changing the CN
dict entry to a tuple when initialised.

ndg.security.common/ndg/security/common/wsSecurity.py: changes to enable
handling of certificate chains in WSSE BinarySecurityToken? elements. This
will enable use of proxy certificates with signatures as their chain of
trust is proxy cert -> user cert -> CA cert rather than just cert -> CA cert.

types.

BinarySecurityToken? ValueType? to use

  • SignatureHandler?.init includes new signingCertChain keyword.
  • signingCertChain attribute of class enables setting of an X509Stack object

to assign to BinarySecurityToken?.

then Base 64 encode rather than converting into PEM and then having to
strip BEGIN CERT / END CERT delimiters.

to enable check of Canonicalization - REMOVE in future check in.

BinarySecurityToken? ValueTypes? - 'X509PKIPathv1', 'X509' and 'X509v3'

Line 
1#!/usr/bin/env python
2"""NDG Security Attribute Authority .tac file
3
4This file enables the Attribute Authority web service to be
5called under the Twisted framework
6
7NERC Data Grid Project
8
9@author P J Kershaw 17/11/06
10
11@copyright (C) 2007 CCLRC & NERC
12
13@license This software may be distributed under the terms of the Q Public
14License, version 1.0 or later.
15"""
16import os
17
18from ZSI.twisted.WSresource import WSResource
19from twisted.application import service, internet
20from twisted.web.server import Site
21from twisted.web.resource import Resource
22
23from ndg.security.server.AttAuthority.AttAuthority_services_server import \
24        AttAuthorityService
25
26from ndg.security.server.AttAuthority import AttAuthority, \
27        AttAuthorityAccessDenied
28       
29from ndg.security.common.wsSecurity import WSSecurityHandlerChainFactory, \
30        WSSecurityHandler, SignatureHandler
31
32from ndg.security.common.X509 import X509Cert, X509CertRead
33
34
35class AttAuthorityServiceSub(AttAuthorityService, WSResource):
36
37    # Add WS-Security handlers
38    factory = WSSecurityHandlerChainFactory
39
40    def __init__(self):
41        WSResource.__init__(self)
42         
43        # Initialize Attribute Authority class - property file will be
44        # picked up from default location under $NDG_DIR directory
45        self.aa = AttAuthority()
46
47
48    def soap_getAttCert(self, ps, **kw):
49        request, response = AttAuthorityService.soap_getAttCert(self, ps)
50       
51        # Derive designated holder cert differently according to whether
52        # a signed message is expected from the client
53        if srv.aa['useSignatureHandler']:
54            # Get certificate corresponding to private key that signed the
55            # message - i.e. the user's proxy
56            holderCert = WSSecurityHandler.signatureHandler.verifyingCert
57        else:
58            # No signature from client - they must instead provide the
59            # designated holder cert via the UserCert input
60            holderCert = request.UserCert
61           
62        try:   
63                attCert = self.aa.getAttCert(userId=request.UserId,
64                                         holderCert=holderCert,
65                                         userAttCert=request.UserAttCert) 
66                response.AttCert = attCert.toString()
67               
68        except AttAuthorityAccessDenied, e:
69            response.Msg = str(e)
70                       
71        return request, response
72
73
74    def soap_getHostInfo(self, ps, **kw):
75        request, response = AttAuthorityService.soap_getHostInfo(self, ps)
76       
77        response.Hostname = srv.aa.hostInfo.keys()[0]
78        response.LoginURI = srv.aa.hostInfo[response.Hostname]['loginURI']
79        response.AaURI = srv.aa.hostInfo[response.Hostname]['aaURI']
80
81        return request, response
82
83
84    def soap_getTrustedHostInfo(self, ps, **kw):
85        request, response = \
86                        AttAuthorityService.soap_getTrustedHostInfo(self, ps)
87       
88        trustedHostInfo = srv.aa.getTrustedHostInfo(role=request.Role)
89
90                # Convert ready for serialization
91        trustedHosts = []
92        for hostname, hostInfo in trustedHostInfo.items():
93            trustedHost = response.new_trustedHosts()
94                       
95            trustedHost.Hostname = hostname
96            trustedHost.AaURI = hostInfo['aaURI']
97            trustedHost.LoginURI = hostInfo['loginURI']
98            trustedHost.RoleList = hostInfo['role']
99                       
100            trustedHosts.append(trustedHost)
101                       
102        response.TrustedHosts = trustedHosts
103               
104        return request, response
105
106
107    def soap_getX509Cert(self, ps, **kw):
108        request, response = AttAuthorityService.soap_getX509Cert(self, ps)
109       
110        x509Cert = X509CertRead(srv.aa['certFile'])
111        response.X509Cert = x509Cert.toString()
112        return request, response
113
114
115root = Resource()
116
117# Create Service
118srv = AttAuthorityServiceSub()
119
120if srv.aa['useSignatureHandler']:
121    # Initialise WS-Security signature handler passing Attribute Authority
122    # public and private keys
123    caCertFile = srv.aa.get('caCertFile')
124    if caCertFile:
125        caCertFilePathList = (caCertFile,) 
126    else:
127                caCertFilePathList = None
128   
129    WSSecurityHandler.signatureHandler = SignatureHandler(\
130                                verifyingCertFilePath=srv.aa['clntCertFile'],
131                                signingCertFilePath=srv.aa['certFile'],
132                                signingPriKeyFilePath=srv.aa['keyFile'],
133                                signingPriKeyPwd=srv.aa['keyPwd'],
134                                caCertFilePathList=caCertFilePathList)
135
136# Add Service to Attribute Authority branch
137root.putChild('AttributeAuthority', srv)
138siteFactory = Site(root)
139
140if srv.aa['useSSL']:
141        # Use SSL connection
142#       from twisted.internet import ssl
143#       
144#       # Nb. ssl.DefaultOpenSSLContextFactory requires pyOpenSSL
145#       ctxFactory = ssl.DefaultOpenSSLContextFactory(srv.aa['sslKeyFile'],
146#                                                                                                 srv.aa['sslCertFile'])
147#       port = internet.SSLServer(srv.aa['portNum'], siteFactory, ctxFactory)
148
149        # Using M2Crypto ...
150    os.putenv("OPENSSL_ALLOW_PROXY_CERTS", "1")
151
152    import twisted.protocols.policies as policies
153    from M2Crypto import SSL
154    from M2Crypto.SSL import TwistedProtocolWrapper
155    from M2Crypto.SSL.TwistedProtocolWrapper import TLSProtocolWrapper
156
157    siteFactory.startTLS = True
158    siteFactory.sslChecker = SSL.Checker.Checker()
159
160        # TODO: Python ssl client seems to require SSL vers 2 is this a security
161        # risk?
162    ctx = SSL.Context(protocol='sslv23')
163    ctx.set_cipher_list("NULL-MD5:ALL:!ADH:!EXP:@STRENGTH")
164    ctx.load_cert(srv.aa['sslCertFile'], 
165                          srv.aa['sslKeyFile'],
166                          callback=lambda *args, **kw: srv.aa['sslKeyPwd'])
167                         
168    ctx.set_allow_unknown_ca(False)
169
170    # TODO: resolve check - verify_peer setting fails with
171    # BIOError: 'no certificate returned' error 18
172#    ctx.set_verify(SSL.verify_peer, 10)
173    ctx.set_verify(SSL.verify_client_once, 1)
174
175    ctx.load_verify_locations(cafile=os.path.basename(srv.aa['caCertFile']), 
176                                                  capath=os.path.dirname(srv.aa['caCertFile']))
177
178    class ContextFactory:
179        def getContext(self):
180            return ctx
181
182    factory = policies.WrappingFactory(siteFactory)
183    factory.protocol.TLS = True
184    factory.protocol = lambda factory, wrappedProtocol: \
185        TLSProtocolWrapper(factory,
186                           wrappedProtocol,
187                           startPassThrough=0,
188                           client=0,
189                           contextFactory=ContextFactory(),
190                           postConnectionCheck=None)
191
192    siteFactory = factory
193   
194    port = internet.TCPServer(srv.aa['portNum'], siteFactory)
195    port.CERTFILE = srv.aa['sslCertFile']
196    port.KEYFILE = srv.aa['sslKeyFile']
197    root.__class__.server = port
198else:   
199        # Non-SSL
200        port = internet.TCPServer(srv.aa['portNum'], siteFactory)
201
202application = service.Application("AttributeAuthorityContainer")
203port.setServiceParent(application)
204       
Note: See TracBrowser for help on using the repository browser.