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)
def _encrypt_assertion(unencrypted): # load the rsa key # Create and initialize keys manager, we use a simple list based # keys manager, implement your own KeysStore klass if you need # something more sophisticated # mngr = xmlsec.KeysMngr() # config = saml2idp_metadata.SAML2IDP_CONFIG # key = xmlsec.cryptoAppKeyLoad(config['public_key_file'], xmlsec.KeyDataFormatPem, None, None, None) # key.setName(config['public_key_file']) # # add the key to the manager # xmlsec.cryptoAppDefaultKeysMngrAdoptKey(mngr, key) # # # now encrypt the xml # doc = libxml2.parseDoc(unencrypted) # # Create encryption template to encrypt XML file and replace # # its content with encryption result # enc_data_node = xmlsec.TmplEncData(doc, xmlsec.transformAes128CbcId(), None, xmlsec.TypeEncElement, None, None) # # put encrypted data in the <enc:CipherValue/> node # enc_data_node.ensureCipherValue() # # add <dsig:KeyInfo/> # key_info_node = enc_data_node.ensureKeyInfo(None) # # Add <enc:EncryptedKey/> to store the encrypted session key # enc_key_node = key_info_node.addEncryptedKey(xmlsec.transformRsaPkcs1Id(), None, None, None) # # put encrypted key in the <enc:CipherValue/> node # enc_key_node.ensureCipherValue() # # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/> # key_info_node2 = enc_key_node.ensureKeyInfo(None) # # Set key name so we can lookup key when needed # key_info_node2.addKeyName(config['public_key_file']) # # Create encryption context # enc_ctx = xmlsec.EncCtx(mngr) # # Generate a Triple DES key # key = xmlsec.keyGenerate(xmlsec.keyDataDesId(), 192, xmlsec.KeyDataTypeSession) # enc_ctx.encKey = key # # Encrypt the data # enc_ctx.xmlEncrypt(enc_data_node, doc.getRootElement()) # # # Destroy all # key.destroy() # mngr.destroy() # enc_ctx.destroy() # enc_data_node.freeNode() # # doc.freeDoc() # return doc xmlsec.initialize() config = saml2idp_metadata.SAML2IDP_CONFIG mngr = xmlsec.KeysMngr() key = xmlsec.Key.load(config["public_key_file"], xmlsec.KeyDataFormatPem) key.name = basename(config["public_key_file"]) mngr.addKey(key) doc = fromstring(unencrypted) encData = EncData(xmlsec.TransformDes3Cbc, type=xmlsec.TypeEncElement) encData.ensureCipherValue() # target for encryption result keyInfo = encData.ensureKeyInfo() encKey = keyInfo.addEncryptedKey(xmlsec.TransformRsaPkcs1) encKey.ensureCipherValue() encKeyInfo = encKey.ensureKeyInfo() encKeyInfo.addKeyName(key.name) encCtx = xmlsec.EncCtx(mngr) encCtx.encKey = xmlsec.Key.generate(xmlsec.KeyDataDes, 192, xmlsec.KeyDataTypeSession) ed = encCtx.encryptXml(encData, doc) return tostring(ed.getroottree())