tags:

views:

463

answers:

3

Hello All,

I have to write an xml file using python standard modules (not using elementtree, lxml etc) The metadata is a SAML identity provider metadata and is of the form -

<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    entityID="http://wsa.saas.com"&gt;
<IDPSSODescriptor>
<KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
      <ds:X509Data><ds:X509Certificate>-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR
LlTxKnCrWAXftSm1rNtewTsF
-----END CERTIFICATE-----
</ds:X509Certificate></ds:X509Data>
    </ds:KeyInfo>
  </KeyDescriptor>

  <SingleSignOnService
    Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    Location="http://idp5/singleSignOn" />
</IDPSSODescriptor>
</EntityDescriptor>

My code at present does this -

>>> from xml.dom.minidom import Document
>>> doc = Document()
>>> entity_descriptor = doc.createElement("EntityDescriptor")
>>> doc.appendChild(entity_descriptor)
>>> entity_descriptor.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata')
>>> entity_descriptor.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion')
>>> entity_descriptor.setAttribute('xmlns:ds', 'hxxp://xxx.w3.org/2000/09/xmldsig#')
>>> entity_descriptor.setAttribute('entityID', 'hxxp://wsa.saas.com')
>>> idpssodescr = doc.createElement('IDPSSODescriptor')
>>> entity_descriptor.appendChild(idpssodescr)
>>> keydescr = doc.createElement('KeyDescriptor')
>>> keydescr.setAttribute('use', 'signing')
>>> idpssodescr.appendChild(keydescr)
>>> keyinfo = doc.createElement('ds:KeyInfo')
>>> keyinfo.setAttribute('xmlns:ds', 'http://xxx.w3.org/2000/09/xmldsig#')
>>> keydescr.appendChild(keyinfo)
>>> x509data = doc.createElement('ds:X509Data')
>>> keyinfo.appendChild(x509data)
>>> x509cert = doc.createElement('ds:X509Certificate')
>>> ptext = doc.createTextNode("This is a test!")
>>> x509cert.appendChild(ptext)
>>> x509data.appendChild(x509cert)
>>> sso = doc.createElement('SingleSignOnService')
>>> sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect')
>>> sso.setAttribute('Location', 'hxxx://idp5/singleSignOn')
>>> idpssodescr.appendChild(sso)
>>> print doc.toprettyxml(indent="  ")
<?xml version="1.0" ?>
<EntityDescriptor entityID="http://wsa.saas.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <IDPSSODescriptor>
    <KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
        <ds:X509Data>
          <ds:X509Certificate>
            This is a test!
          </ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://idp5/singleSignOn"/&gt;
  </IDPSSODescriptor>
</EntityDescriptor>

I am little confused with the certificate part. Original is <ds:X509Certificate>-----BEGIN CERTIFICATE---.....</ds:X509Certificate> and mine is:

 <ds:X509Certificate>
    This is the cert
 </ds:X509Certificate>

Sorry, I don't have much experience with XML. Is the code proper for the task intended.

Thanks.

+1  A: 

Well? What is your question? In these two lines:

>>> ptext = doc.createTextNode("This is a test!")
>>> x509cert.appendChild(ptext)

you are, indeed, creating a text node as a child of a node "<ds:X509Certificate>" . The contents of the text node are "This is a test!". If you want to have something else inserted as the text content, you must call .createTextNode with an appropriate argument.

EDIT (taking into account the OP's comment): No, it is not text content. In XML everything is a node. What you think is "text between the tags" is, actually, a text node.

shylent
A: 

No i mean setting the contents. Cant we directly set the node value instead of creating a text element and appending it?

A: 

Just for archiving, my earlier code was missing a small change, that is why the certificate was being rejected.

from xml.dom.minidom import Document
doc = Document()
entity_descriptor = doc.createElement("EntityDescriptor")
doc.appendChild(entity_descriptor)
entity_descriptor.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata')
entity_descriptor.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion')
entity_descriptor.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#')
entity_descriptor.setAttribute('entityID', 'http://wsa.saas.com')
idpssodescr = doc.createElement('IDPSSODescriptor')
idpssodescr.setAttribute('WantAuthnRequestsSigned', 'true')
idpssodescr.setAttribute('protocolSupportEnumeration',   
'urn:oasis:names:tc:SAML:2.0:protocol')
entity_descriptor.appendChild(idpssodescr)
keydescr = doc.createElement('KeyDescriptor')
keydescr.setAttribute('use', 'signing')
idpssodescr.appendChild(keydescr)
keyinfo = doc.createElement('ds:KeyInfo')
keyinfo.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#')
keydescr.appendChild(keyinfo)
x509data = doc.createElement('ds:X509Data')
keyinfo.appendChild(x509data)
x509cert = doc.createElement('ds:X509Certificate')

# Read the certificate from some file.
fp = file('idp.crt.pem', 'r')
s = ''
for i in fp.readlines():
    s+=''.join(i)


ptext = doc.createTextNode(s)
x509cert.appendChild(ptext)
x509data.appendChild(x509cert)
sso = doc.createElement('SingleSignOnService')
sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect')
sso.setAttribute('Location', 'http://idp5/singleSignOn')
idpssodescr.appendChild(sso)

print doc.toprettyxml(indent="  ")
<?xml version="1.0" ?>
<EntityDescriptor entityID="http://wsa.saas.com"  
xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09  
/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<IDPSSODescriptor WantAuthnRequestsSigned="true"    
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
  <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
    <ds:X509Data>
      <ds:X509Certificate>
        -----BEGIN CERTIFICATE-----
MIICfTCCAeagAwIBAgIJAPEn4h3J3p2dMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
BAYTAmFhMQswCQYDVQQKEwJhYTELMAkGA1UECxMCYWExCzAJBgNVBAMTAmFhMB4X
DTA5MTAxOTA4NTI1M1oXDTEwMTAxOTA4NTI1M1owNDELMAkGA1UEBhMCYWExCzAJ
BgNVBAoTAmFhMQswCQYDVQQLEwJhYTELMAkGA1UEAxMCYWEwgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBAMerInhZF/l0O0jmiD8M1lSSpHjFcT0peiwqWq+LZ8Ay
b6mcpnHdFVmHQaGtUt+6i+0NqKDppxnaVW4vOdYD64OlmSVrG+WzkYMAmE/0EzJN
A5pEA5ZK1w6MGo+IQLjrPDmm/qV6XrkARR2THjA2xKE8/L7s+VEJj/d+/CC8V7vP
AgMBAAGjgZYwgZMwHQYDVR0OBBYEFOHoipN0T0TNs1IwFkmTwLDtsV0gMGQGA1Ud
IwRdMFuAFOHoipN0T0TNs1IwFkmTwLDtsV0goTikNjA0MQswCQYDVQQGEwJhYTEL
MAkGA1UEChMCYWExCzAJBgNVBAsTAmFhMQswCQYDVQQDEwJhYYIJAPEn4h3J3p2d
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEANTQgpYm+OBZTTYbLkyBH
MQ9QygwgNWOQJ9hEbT0xpiL8xHXBTQdHJkMXD/PWzs1AyZShXsUwcKBaKgxyIsQj
a36poKPyfAYbfsg8xLyijMVXbsW7OlKN9FjapaZTnEvHfsMO8ITAad4a7RVWAYQ8
ucT7nO9OPFjOv8dwGsF5RVM=
-----END CERTIFICATE-----

      </ds:X509Certificate>
    </ds:X509Data>
  </ds:KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"   
Location="http://idp5/singleSignOn"/&gt;
</IDPSSODescriptor>
</EntityDescriptor>

x = open('metadata.xml', 'w')
doc.writexml(x, "   ", "", "\n", "UTF-8")
x.close()