Changeset 7054 for TI12-security


Ignore:
Timestamp:
23/06/10 08:57:58 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 5: MyProxy? Web Service Interface

  • Tried adding HTML keygen interface to MyProxy? but it won't work because keygen uses a signed public key and challenge whereas MyProxy? logon requires a certificate request. The public key can be extracted from the request and a certificate request generated, but it can be signed because the private key is not available. MyProxy? returns with a certificate generation failure.
Location:
TI12-security/trunk/MyProxyWebService/myproxy/server
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/MyProxyWebService/myproxy/server/wsgi/middleware.py

    r6997 r7054  
    1616import httplib 
    1717import base64 
     18import re 
    1819 
    1920from webob import Request 
     
    331332            MyProxy server 
    332333            """   
    333             requestMethod = environ.get('REQUEST_METHOD')              
    334             if requestMethod != 'POST': 
     334            request = Request(environ) 
     335             
     336            requestMethod = environ.get('REQUEST_METHOD')                          
     337            certReqKey = self.__class__.CERT_REQ_POST_PARAM_KEYNAME 
     338             
     339            if requestMethod == 'POST': 
     340                pemCertReq = request.POST.get(certReqKey) 
     341                if pemCertReq is None: 
     342                    response = ("No %r form variable set in POST message" %  
     343                                certReqKey) 
     344                    log.error(response) 
     345                    raise HttpBasicAuthResponseException(response,  
     346                                                         httplib.BAD_REQUEST) 
     347             
     348                log.debug("cert req = %r", pemCertReq) 
     349                 
     350                # Expecting PEM encoded request 
     351                try: 
     352                    certReq = crypto.load_certificate_request( 
     353                                                            crypto.FILETYPE_PEM, 
     354                                                            pemCertReq) 
     355                except crypto.Error, e: 
     356                    log.error("Error loading input certificate request: %r",  
     357                              pemCertReq) 
     358                    raise HttpBasicAuthResponseException("Error loading input " 
     359                                                         "certificate request", 
     360                                                         httplib.BAD_REQUEST) 
     361                 
     362                # Convert to ASN1 format expect by logon client call 
     363                asn1CertReq = crypto.dump_certificate_request( 
     364                                                        crypto.FILETYPE_ASN1,  
     365                                                        certReq) 
     366                 
     367                # Alternative, GET method would set this variable, set to None 
     368                # here to correctly initialise MyProxy.logon call 
     369                pubKey = None 
     370                 
     371            elif requestMethod == 'GET': 
     372                # Interpret as a HTML keygen request.  See: 
     373                # https://developer.mozilla.org/en/HTML/Element/keygen 
     374                # A Netscape Signed Public Key and Challenge (SPKAC) is set as a 
     375                # query argument 
     376                spkac = request.GET.get(certReqKey) 
     377                if spkac is None: 
     378                    response = ("No %r query argument set in GET request" %  
     379                                certReqKey) 
     380                    log.error(response) 
     381                    raise HttpBasicAuthResponseException(response,  
     382                                                         httplib.BAD_REQUEST)  
     383                 
     384                # Remove any carriage returns to enable PyOpenSSL interface to 
     385                # correctly parse 
     386                strippedSpkac = ''.join(re.split('\s+', spkac)) 
     387                try: 
     388                    spki = crypto.NetscapeSPKI(strippedSpkac) 
     389                     
     390                except crypto.Error, e: 
     391                    log.error("Error loading input signed public key and " 
     392                              "challenge: %r", spkac) 
     393                    raise HttpBasicAuthResponseException("Error loading input " 
     394                                                         "Signed Public Key " 
     395                                                         "and challenge", 
     396                                                         httplib.BAD_REQUEST) 
     397                 
     398                # Extract public key  
     399                try: 
     400                    pubKey = spki.get_pubkey() 
     401                     
     402                except crypto.Error, e: 
     403                    log.error("Error extracting public key from input " 
     404                              "signed public key and challenge: %r", spkac) 
     405                    raise HttpBasicAuthResponseException("Error procesing " 
     406                                                         "input Signed Public " 
     407                                                         "Key and challenge", 
     408                                                         httplib.BAD_REQUEST) 
     409                     
     410                # Alternative, POST method would set this variable, set to None 
     411                # here to correctly initialise MyProxy.logon call 
     412                certReq = crypto.X509Req() 
     413                certReq.set_pubkey(pubKey) 
     414                asn1CertReq = crypto.dump_certificate_request( 
     415                                                        crypto.FILETYPE_ASN1,  
     416                                                        certReq) 
     417            else: 
    335418                response = "HTTP Request method not recognised" 
    336419                log.error("HTTP Request method %r not recognised",  
     
    338421                raise HttpBasicAuthResponseException(response,  
    339422                                                     httplib.METHOD_NOT_ALLOWED) 
    340              
    341             request = Request(environ) 
    342             certReqKey = self.__class__.CERT_REQ_POST_PARAM_KEYNAME 
    343             pemCertReq = request.POST.get(certReqKey) 
    344             if pemCertReq is None: 
    345                 response = "No %r form variable set" % certReqKey 
    346                 log.error(response) 
    347                 raise HttpBasicAuthResponseException(response,  
    348                                                      httplib.BAD_REQUEST) 
    349             log.debug("cert req = %r", pemCertReq) 
    350              
    351             # Expecting PEM encoded request 
    352             try: 
    353                 certReq = crypto.load_certificate_request(crypto.FILETYPE_PEM, 
    354                                                           pemCertReq) 
    355             except crypto.Error, e: 
    356                 log.error("Error loading input certificate request: %r",  
    357                           pemCertReq) 
    358                 raise HttpBasicAuthResponseException("Error loading input " 
    359                                                      "certificate request", 
    360                                                      httplib.BAD_REQUEST) 
    361                  
    362             # Convert to ASN1 format expect by logon client call 
    363             asn1CertReq = crypto.dump_certificate_request(crypto.FILETYPE_ASN1,  
    364                                                           certReq) 
    365              
     423 
    366424            try: 
    367425                credentials = self.myProxyClient.logon(username,  
Note: See TracChangeset for help on using the changeset viewer.