import xmlseclibs, cookielib, datetime from xml.dom import minidom from xml import xpath import xml.utils.iso8601 SAML_ASSERT_NS = 'urn:oasis:names:tc:SAML:1.0:assertion' INFOCARD_PRIVATE_KEY = '' def processCard(xmlToken): encdom = minidom.parseString(xmlToken) objenc = xmlseclibs.XMLSecEnc() encData = objenc.locateEncryptedData(encdom) if (not encData): # throw new Exception("Cannot locate Encrypted Data") print "Cannot locate Encrypted Data" return None objenc.setNode(encData) objenc.type = encData.getAttribute("Type") key = None objKey = objenc.locateKey() if (objKey): objKeyInfo = objenc.locateKeyInfo(objKey) if (objKeyInfo): if (objKeyInfo.isEncrypted): objencKey = objKeyInfo.encryptedCtx objKeyInfo.loadKey(INFOCARD_PRIVATE_KEY, True) key = objencKey.decryptKey(objKeyInfo) if ((not objKey) or (not key)): #throw new Exception("Error loading key to handle Decryption") return "Error loading key to handle Decryption" return None objKey.loadKey(key) token = None decrypt = objenc.decryptNode(objKey, False) if (decrypt): # we have the saml token so load er up token= minidom.parseString(decrypt) if (not token): #throw new Exception("Unable to decrypt token") print "Unable to decrypt token" return None # Validate the SAML token objXMLSecDSig = xmlseclibs.XMLSecurityDSig() objXMLSecDSig.idKeys['AssertionID'] = 'AssertionID' objDSig = objXMLSecDSig.locateSignature(token) # Canonicalize the signed info objXMLSecDSig.canonicalizeSignedInfo() retVal = None if (objDSig): retVal = objXMLSecDSig.validateReference() if (not retVal): #throw new Exception("SAML Validation Failed") return None key = None objKey = objXMLSecDSig.locateKey() if (objKey): objKeyInfo = xmlseclibs.XMLSecEnc.staticLocateKeyInfo(objKey, objDSig) if (objKeyInfo): # Handle any additional key processing such as encrypted keys here nop = 1 if (not objKey): #throw new Exception("Error loading key to handle Signature") print "Error loading key to handle Signature" return None retVal = objXMLSecDSig.verify(objKey) if (not retVal): #throw new Exception("Unable to validate Signature") print "Unable to validate Signature" return None return token # need work on ISO date checking - skip for now def checkDateConditions(start=None, end=None): currentTime = datetime.datetime.now() if (start): startTime = datetime.datetime.fromtimestamp(xml.utils.iso8601.parse(start)) # Allow for a 10 minute difference in Time d = datetime.timedelta(minutes=600) if ((not startTime) or ((startTime - d) > currentTime)): return False if (end): endTime = datetime.datetime.fromtimestamp(xml.utils.iso8601.parse(end)) if ((not endTime) or (endTime <= currentTime)): #return False return True #for testing return True def getAssertions(token): assertions = {} if (isinstance(token, minidom.Document)): xPath = xpath.CreateContext(token) xPath.setNamespaces({'mysaml' : SAML_ASSERT_NS}) query = '/mysaml:Assertion/mysaml:Conditions' nodelist = xpath.Evaluate(query, context=xPath) node = nodelist[0] if (node): start = node.getAttribute('NotBefore') end = node.getAttribute('NotOnOrAfter') if (not checkDateConditions(start, end)): return assertions query = '/mysaml:Assertion/mysaml:AttributeStatement/mysaml:Attribute' nodelist = xpath.Evaluate(query, context=xPath) for node in nodelist: name = node.getAttribute('AttributeName') if (name): value = '' for child in node.childNodes: if (child.localName == 'AttributeValue'): value = child.firstChild.data break assertions[name] = value return assertions