def generate_name_id(value, sp_nq, sp_format, cert=None, debug=False): """ Generates a nameID. :param value: fingerprint :type: string :param sp_nq: SP Name Qualifier :type: string :param sp_format: SP Format :type: string :param cert: IdP Public Cert to encrypt the nameID :type: string :param debug: Activate the xmlsec debug :type: bool :returns: DOMElement | XMLSec nameID :rtype: string """ doc = Document() name_id_container = doc.createElementNS(OneLogin_Saml2_Constants.NS_SAML, 'container') name_id_container.setAttribute("xmlns:saml", OneLogin_Saml2_Constants.NS_SAML) name_id = doc.createElement('saml:NameID') name_id.setAttribute('SPNameQualifier', sp_nq) name_id.setAttribute('Format', sp_format) name_id.appendChild(doc.createTextNode(value)) name_id_container.appendChild(name_id) if cert is not None: xml = name_id_container.toxml() elem = fromstring(xml) xmlsec.initialize() if debug: xmlsec.set_error_callback(print_xmlsec_errors) # Load the public cert mngr = xmlsec.KeysMngr() file_cert = OneLogin_Saml2_Utils.write_temp_file(cert) key_data = xmlsec.Key.load(file_cert.name, xmlsec.KeyDataFormatCertPem, None) key_data.name = basename(file_cert.name) mngr.addKey(key_data) file_cert.close() # Prepare for encryption enc_data = EncData(xmlsec.TransformAes128Cbc, type=xmlsec.TypeEncElement) enc_data.ensureCipherValue() key_info = enc_data.ensureKeyInfo() # enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaPkcs1) enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaOaep) enc_key.ensureCipherValue() # Encrypt! enc_ctx = xmlsec.EncCtx(mngr) enc_ctx.encKey = xmlsec.Key.generate(xmlsec.KeyDataAes, 128, xmlsec.KeyDataTypeSession) edata = enc_ctx.encryptXml(enc_data, elem[0]) newdoc = parseString(etree.tostring(edata)) if newdoc.hasChildNodes(): child = newdoc.firstChild child.removeAttribute('xmlns') child.removeAttribute('xmlns:saml') child.setAttribute('xmlns:xenc', OneLogin_Saml2_Constants.NS_XENC) child.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS) nodes = newdoc.getElementsByTagName("*") for node in nodes: if node.tagName == 'ns0:KeyInfo': node.tagName = 'dsig:KeyInfo' node.removeAttribute('xmlns:ns0') node.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS) else: node.tagName = 'xenc:' + node.tagName encrypted_id = newdoc.createElement('saml:EncryptedID') encrypted_data = newdoc.replaceChild(encrypted_id, newdoc.firstChild) encrypted_id.appendChild(encrypted_data) return newdoc.saveXML(encrypted_id) else: return doc.saveXML(name_id)
def generate_name_id(value, sp_nq, sp_format=None, cert=None, debug=False, nq=None): """ Generates a nameID. :param value: fingerprint :type: string :param sp_nq: SP Name Qualifier :type: string :param sp_format: SP Format :type: string :param cert: IdP Public Cert to encrypt the nameID :type: string :param debug: Activate the xmlsec debug :type: bool :param nq: IDP Name Qualifier :type: string :returns: DOMElement | XMLSec nameID :rtype: string """ doc = Document() name_id_container = doc.createElementNS( OneLogin_Saml2_Constants.NS_SAML, 'container') name_id_container.setAttribute("xmlns:saml", OneLogin_Saml2_Constants.NS_SAML) name_id = doc.createElement('saml:NameID') if sp_nq is not None: name_id.setAttribute('SPNameQualifier', sp_nq) if nq is not None: name_id.setAttribute('NameQualifier', nq) if sp_format is not None: name_id.setAttribute('Format', sp_format) name_id.appendChild(doc.createTextNode(value)) name_id_container.appendChild(name_id) if cert is not None: xml = name_id_container.toxml() elem = fromstring(xml) error_callback_method = None if debug: error_callback_method = print_xmlsec_errors xmlsec.set_error_callback(error_callback_method) # Load the public cert mngr = xmlsec.KeysMngr() file_cert = OneLogin_Saml2_Utils.write_temp_file(cert) key_data = xmlsec.Key.load(file_cert.name, xmlsec.KeyDataFormatCertPem, None) key_data.name = basename(file_cert.name) mngr.addKey(key_data) file_cert.close() # Prepare for encryption enc_data = EncData(xmlsec.TransformAes128Cbc, type=xmlsec.TypeEncElement) enc_data.ensureCipherValue() key_info = enc_data.ensureKeyInfo() # enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaPkcs1) enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaOaep) enc_key.ensureCipherValue() # Encrypt! enc_ctx = xmlsec.EncCtx(mngr) enc_ctx.encKey = xmlsec.Key.generate(xmlsec.KeyDataAes, 128, xmlsec.KeyDataTypeSession) edata = enc_ctx.encryptXml(enc_data, elem[0]) newdoc = parseString( tostring(edata, encoding='unicode').encode('utf-8')) if newdoc.hasChildNodes(): child = newdoc.firstChild child.removeAttribute('xmlns') child.removeAttribute('xmlns:saml') child.setAttribute('xmlns:xenc', OneLogin_Saml2_Constants.NS_XENC) child.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS) nodes = newdoc.getElementsByTagName("*") for node in nodes: if node.tagName == 'ns0:KeyInfo': node.tagName = 'dsig:KeyInfo' node.removeAttribute('xmlns:ns0') node.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS) else: node.tagName = 'xenc:' + node.tagName encrypted_id = newdoc.createElement('saml:EncryptedID') encrypted_data = newdoc.replaceChild(encrypted_id, newdoc.firstChild) encrypted_id.appendChild(encrypted_data) return newdoc.saveXML(encrypted_id) else: return doc.saveXML(name_id)
class XpathXml: def __init__(self, xmlFile=None, xmlRoot=None): from xml.dom.minidom import parse, Document, parseString self._xmlDoc = Document() if (xmlFile == None or xmlFile == "") else\ (parse(xmlFile) if os.path.exists(xmlFile) else parseString(xmlFile)) if xmlRoot != None: self._xmlDoc.appendChild(self.CreateNode(xmlRoot)) def getNode(self, xpath, isGlobal=False, refNode=None): jpath = XmlOperation.XpathToJson(xpath, "{'Index':1}") if refNode == None: refNode = self._xmlDoc if isGlobal: attrs = [ attr for attr in jpath.keys() if (attr != "Index" and attr != 'ClassName') ] expIndex = jpath['Index'] actIndex = 0 for curDoml in refNode.getElementsByTagName(jpath['ClassName']): isFound = True for attName in attrs: if curDoml.getAttribute(attName) != jpath[attName]: isFound = False break if isFound: actIndex += 1 if actIndex == expIndex: return curDoml return None curDoml = refNode while curDoml != None: expNode = jpath['ClassName'] expIndex = jpath['Index'] actIndex = 0 for tempDom in curDoml.childNodes: if tempDom.nodeName == expNode: actIndex += 1 if actIndex == expIndex: break if actIndex == expIndex: curDoml = tempDom else: curDoml = None try: jpath = jpath['Child'] except: break return curDoml def getNodeContent(self, node, attName=None, refNode=None): from xml.dom.minidom import Element if refNode != None and type(node) != Element: node = self.GetNode(node, False, refNode) if node == None: return if attName == None or attName.length() == 0: return node.childNodes[0].nodeValue else: attNode = node.getAttribute(attName) if attNode != None: return attNode.nodeValue def getChildNodes(self, pXpath, refNode=None): from xml.dom.minidom import Element fNode = pXpath if type(pXpath) == Element else self.GetNode( pXpath, False, refNode) return [ tempNode for tempNode in fNode.childNodes if type(tempNode) == Element ] def getChildren(self, pXpath, attName, seperator, *childXpaths): children = [] if seperator == None: seperator = "" for tempNode in self.GetChildNodes(pXpath): childContent = None for childXpath in childXpaths: cNode = self.GetNode(childXpath, False, tempNode) if cNode != None: if childContent == None: childContent = "" else: childContent += seperator nodeValue = self.GetNodeContent(cNode, attName) if nodeValue != None: childContent += nodeValue if childContent != None: children.append(childContent) return children def createNode(self, nodeName, nodeContent=None, **eleAttrs): ele = self._xmlDoc.createElement(nodeName) if nodeContent != None: ele.appendChild(self._xmlDoc.createTextNode(nodeContent)) for attName in eleAttrs.keys(): attVal = eleAttrs[attName] if attVal != None: ele.setAttribute(attName, attVal) return ele def setNode(self, xpath, isGlobal=False, nodeContent=None, nodeName=None, **eleAttrs): tNode = self.GetNode(xpath, isGlobal) if tNode != None: if nodeName != None: tNode.appendChild( self.CreateNode(nodeName, nodeContent, **eleAttrs)) else: if nodeContent != None: tempContent = self._xmlDoc.createTextNode(str(nodeContent)) if len(tNode.childNodes) > 0: tNode.childNodes[0] = tempContent else: tNode.appendChild(tempContent) for attName in eleAttrs: tNode.setAttribute(attName, eleAttrs[attName]) return True return False def removeNode(self, xpath, isGlobal=False, delNext=None): tNode = self.GetNode(xpath, isGlobal) if tNode != None: pNode = tNode.parentNode.childNodes if delNext != None: nIndex = pNode.index(tNode) for delIndex in range(nIndex, len(pNode)): if pNode[delIndex].nodeName == delNext: pNode.__delitem__(delIndex) break pNode.remove(tNode) return True return False def saveTo(self, filePath): with codecs.open(filePath, mode='w', encoding="utf-8") as fileHandle: fileHandle.write(str(self)) def __str__(self): return self._xmlDoc.saveXML(None)