Synch'd metadata transformation files from /c.
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 18 May 2005 04:17:28 +0000 (04:17 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 18 May 2005 04:17:28 +0000 (04:17 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@1512 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/schemas/metadata_v12_to_v11.xsl [new file with mode: 0644]
src/schemas/metadata_v12_to_v13.xsl [new file with mode: 0644]
src/schemas/metadata_v13_to_v12.xsl [new file with mode: 0644]
src/schemas/trust_v12_to_v11.xsl [new file with mode: 0644]
src/schemas/trust_v13_to_v12.xsl [new file with mode: 0644]

diff --git a/src/schemas/metadata_v12_to_v11.xsl b/src/schemas/metadata_v12_to_v11.xsl
new file mode 100644 (file)
index 0000000..13301be
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+       v12_to_v11.xsl
+       
+       XSL stylesheet converting a Shibboleth 1.2 sites metadata file into the equivalent for
+       Shibboleth 1.1.
+
+       Author: Ian A. Young <ian@iay.org.uk>
+
+       $Id$
+-->
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:shibb10="urn:mace:shibboleth:1.0"
+       xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       exclude-result-prefixes="shibb10">
+       
+       <!--
+               Version information for this file.  Remember to peel off the dollar signs
+               before dropping the text into another versioned file.
+       -->
+       <xsl:param name="cvsId">$Id$</xsl:param>
+
+       <!--
+               Add a comment to the start of the output file.
+       -->
+       <xsl:template match="/">
+               <xsl:comment>
+                       <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
+                       <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
+                       <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
+                       <xsl:text>&#10;</xsl:text>
+               </xsl:comment>
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <!--Force UTF-8 encoding for the output.-->
+       <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
+
+       <!--
+               shibb10:SiteGroup is the root element for the sites file.  Process it by copying across everything except DestinationSite elements.
+       -->
+       <xsl:template match="shibb10:SiteGroup">
+               <xsl:copy>
+                       <xsl:attribute name="xsi:schemaLocation">
+                               <xsl:text>urn:mace:shibboleth:1.0 shibboleth.xsd</xsl:text>
+                       </xsl:attribute>
+                       <xsl:apply-templates select="@Name|text()|comment()|shibb10:OriginSite"/>
+               </xsl:copy>
+       </xsl:template>
+
+       <!--By default, copy text blocks, comments and attributes unchanged.-->
+       <xsl:template match="text()|comment()|@*">
+               <xsl:copy/>
+       </xsl:template>
+
+       <!--By default, copy all elements from the input to the output, along with their attributes and contents.-->
+       <xsl:template match="*">
+               <xsl:copy>
+                       <xsl:apply-templates select="node()|@*"/>
+               </xsl:copy>
+       </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/schemas/metadata_v12_to_v13.xsl b/src/schemas/metadata_v12_to_v13.xsl
new file mode 100644 (file)
index 0000000..d27e20d
--- /dev/null
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+       v12_to_v13.xsl
+       
+       XSL stylesheet converting a Shibboleth 1.2 sites file into the equivalent for
+       Shibboleth 1.3, which is based on the SAML 1.1 profile of the SAML 2.0
+       metadata format.  No attempt is made to incorporate the separate trust
+       data used by Shibboleth 1.2.
+       
+       Author: Ian A. Young <ian@iay.org.uk>
+
+       $Id$
+-->
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+       xmlns:shib="urn:mace:shibboleth:1.0"
+       xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
+       exclude-result-prefixes="shib">
+
+       <!--
+               Version information for this file.  Remember to peel off the dollar signs
+               before dropping the text into another versioned file.
+       -->
+       <xsl:param name="cvsId">$Id$</xsl:param>
+
+       <!--
+               Add a comment to the start of the output file.
+       -->
+       <xsl:template match="/">
+               <xsl:comment>
+                       <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
+                       <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
+                       <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
+                       <xsl:text>&#10;</xsl:text>
+               </xsl:comment>
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <!--Force UTF-8 encoding for the output.-->
+       <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
+
+       <!--
+               SiteGroup is the root element for the sites file.  The corresponding element in the new format file
+               is an EntitiesDescriptor.
+       -->
+       <xsl:template match="shib:SiteGroup">
+               <EntitiesDescriptor Name="{@Name}">
+                       <xsl:attribute name="xsi:schemaLocation">
+                               <xsl:text>urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd </xsl:text>
+                               <xsl:text>urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd </xsl:text>
+                               <xsl:text>http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd</xsl:text>
+                       </xsl:attribute>
+                       <!--
+                               Pass through text blocks and comments, and any shib elements.
+                               These may be: OriginSite, DestinationSite or nested SiteGroup.
+                       -->
+                       <xsl:apply-templates select="text()|comment()|shib:*"/>
+               </EntitiesDescriptor>
+       </xsl:template>
+
+       <!--
+               Map OriginSite to an EntityDescriptor with a particular format.
+       -->
+       <xsl:template match="shib:OriginSite">
+               <EntityDescriptor entityID="{@Name}">
+                       <!--
+                               Copy through comments and text blocks at the start of the output element.
+                               This means we don't lose comments, but there is no way to guarantee they will
+                               come out "in the right place".
+                       -->
+                       <xsl:apply-templates select="text()|comment()"/>
+                       <!--
+                               Map HandleService and AttributeAuthority.  We need to pass in the (possibly empty)
+                               set of Domain elements as a parameter.
+                       -->
+                       <xsl:apply-templates select="shib:HandleService|shib:AttributeAuthority">
+                               <xsl:with-param name="Domain" select="shib:Domain"/>
+                       </xsl:apply-templates>
+                       <xsl:call-template name="Alias"/>
+                       <xsl:apply-templates select="shib:Contact"/>
+               </EntityDescriptor>
+       </xsl:template>
+       
+       <!--
+               Map HandleService to IDPSSODescriptor.
+       -->
+       <xsl:template match="shib:HandleService">
+               <xsl:param name="Domain"/>
+               <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
+                       <!--
+                               Extensions appears iff there is something to put in it.
+                       -->
+                       <xsl:if test="boolean($Domain)">
+                               <Extensions>
+                                       <xsl:apply-templates select="$Domain"/>
+                               </Extensions>
+                       </xsl:if>
+                       <KeyDescriptor use="signing">
+                               <ds:KeyInfo>
+                                       <ds:KeyName>
+                                               <xsl:value-of select="@Name"/>
+                                       </ds:KeyName>
+                               </ds:KeyInfo>
+                       </KeyDescriptor>
+                       <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
+                               Location="{@Location}"/>
+               </IDPSSODescriptor>
+       </xsl:template>
+
+       <!--
+               Map AttributeAuthority to AttributeAuthorityDescriptor.
+       -->
+       <xsl:template match="shib:AttributeAuthority">
+               <xsl:param name="Domain"/>
+               <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+                       <!--
+                               Extensions appears iff there is something to put in it.
+                       -->
+                       <xsl:if test="boolean($Domain)">
+                               <Extensions>
+                                       <xsl:apply-templates select="$Domain"/>
+                               </Extensions>
+                       </xsl:if>
+                       <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding"
+                               Location="{@Location}"/>
+               </AttributeAuthorityDescriptor>
+       </xsl:template>
+       
+       <!--
+               Map Domain to a Scope extension.
+       -->
+       <xsl:template match="shib:Domain">
+               <shibmeta:Scope>
+                       <xsl:apply-templates select="@regexp"/>
+                       <xsl:value-of select="."/>
+               </shibmeta:Scope>
+       </xsl:template>
+       
+       <!--
+               Map DestinationSite to an EntityDescriptor with a particular format.
+       -->
+       <xsl:template match="shib:DestinationSite">
+               <EntityDescriptor entityID="{@Name}">
+                       <!--
+                               Copy through comments and text blocks at the start of the output element.
+                               This means we don't lose comments, but there is no way to guarantee they will
+                               come out "in the right place".
+                       -->
+                       <xsl:apply-templates select="text()|comment()"/>
+                       <!--
+                               Generate IDPSSODescriptor.
+                       -->
+                       <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
+                               <!--
+                                       Map @ErrorURL (if present) to @errorURL
+                               -->
+                               <xsl:apply-templates select="@ErrorURL"/>
+                               <!--
+                                       Map AttributeRequester elements to KeyDescriptor elements.
+                               -->
+                               <xsl:apply-templates select="shib:AttributeRequester"/>
+                               <!--
+                                       Map the AssertionConsumerServiceURL elements to
+                                       AssertionConsumerService elements.  The latter require unique
+                                       integer indices, so do this by looping over them and using
+                                       position in the loop to generate each index.
+                               -->
+                               <xsl:for-each select="shib:AssertionConsumerServiceURL">
+                                       <xsl:apply-templates select=".">
+                                               <xsl:with-param name="index" select="position()-1"/>
+                                       </xsl:apply-templates>
+                               </xsl:for-each>
+                       </SPSSODescriptor>
+                       <xsl:call-template name="Alias"/>
+                       <xsl:apply-templates select="shib:Contact"/>
+               </EntityDescriptor>
+       </xsl:template>
+
+       <!--
+               Map @ErrorURL to @errorURL
+       -->
+       <xsl:template match="@ErrorURL">
+               <xsl:attribute name="errorURL"><xsl:value-of select="."/></xsl:attribute>
+       </xsl:template>
+
+       <!--
+               Map AttributeRequester to KeyDescriptor.
+       -->
+       <xsl:template match="shib:AttributeRequester">
+               <KeyDescriptor>
+                       <ds:KeyInfo>
+                               <ds:KeyName>
+                                       <xsl:value-of select="@Name"/>
+                               </ds:KeyName>
+                       </ds:KeyInfo>
+               </KeyDescriptor>
+       </xsl:template>
+
+       <!--
+               Map AssertionConsumerServiceURL to AssertionConsumerService.
+       -->
+       <xsl:template match="shib:AssertionConsumerServiceURL">
+               <xsl:param name="index"/>
+               <AssertionConsumerService index="{$index}"
+                       Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="{@Location}"
+               />
+       </xsl:template>
+
+       <!--
+               Named template to map a set of Alias elements to a corresponding Organization.
+       -->
+       <xsl:template name="Alias">
+               <xsl:if test="boolean(shib:Alias)">
+                       <Organization>
+                               <xsl:apply-templates select="shib:Alias" mode="OrganizationName"/>
+                               <xsl:apply-templates select="shib:Alias" mode="OrganizationDisplayName"/>
+                               <xsl:apply-templates select="shib:Alias" mode="OrganizationURL"/>
+                       </Organization>
+               </xsl:if>
+       </xsl:template>
+
+       <!--
+               Map Alias to OrganizationName
+       -->
+       <xsl:template match="shib:Alias" mode="OrganizationName">
+               <OrganizationName>
+                       <xsl:call-template name="copyXmlLang"/>
+                       <xsl:value-of select="."/>
+               </OrganizationName>
+       </xsl:template>
+
+       <!--
+               Map Alias to OrganizationDisplayName
+       -->
+       <xsl:template match="shib:Alias" mode="OrganizationDisplayName">
+               <OrganizationDisplayName>
+                       <xsl:call-template name="copyXmlLang"/>
+                       <xsl:value-of select="."/>
+               </OrganizationDisplayName>
+       </xsl:template>
+
+       <!--
+               Map Alias to OrganizationURL
+       -->
+       <xsl:template match="shib:Alias" mode="OrganizationURL">
+               <OrganizationURL>
+                       <xsl:call-template name="copyXmlLang"/>
+                       <!-- there is nothing to map, but the URL is mandatory -->
+                       <xsl:text>http://www.example.com/</xsl:text>
+               </OrganizationURL>
+       </xsl:template>
+
+       <!--
+               Copy an xml:lang attribute, or default to "en" if none present.
+       -->
+       <xsl:template name="copyXmlLang">
+               <xsl:if test="boolean(@xml:lang)">
+                       <xsl:attribute name="xml:lang"><xsl:value-of select="@xml:lang"/></xsl:attribute>
+               </xsl:if>
+               <xsl:if test="not(boolean(@xml:lang))">
+                       <xsl:attribute name="xml:lang">en</xsl:attribute>
+               </xsl:if>
+       </xsl:template>
+
+       <!--
+               Map Contact to ContactPerson
+       -->
+       <xsl:template match="shib:Contact">
+               <ContactPerson contactType="{@Type}">
+                       <!--
+                               There is no real mapping for the Name attribute, so we rather arbitrarily
+                               dump that into GivenName rather than trying to split it into a GivenName and
+                               a SurName or something complicated like that.
+                       -->
+                       <GivenName>
+                               <xsl:value-of select="@Name"/>
+                       </GivenName>
+                       <!--
+                               E-mail address, but only if it was present in the original.
+                       -->
+                       <xsl:apply-templates select="@Email" mode="Contact"/>
+               </ContactPerson>
+       </xsl:template>
+
+       <!--
+               E-mail address for Contact
+       -->
+       <xsl:template match="@Email" mode="Contact">
+               <EmailAddress>
+                       <xsl:value-of select="."/>
+               </EmailAddress>
+       </xsl:template>
+
+       <!--
+               By default, copy referenced attributes through unchanged.
+       -->
+       <xsl:template match="@*">
+               <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
+       </xsl:template>
+
+       <!--
+               By default, copy comments through to the output unchanged, but strip extra text.
+       -->
+       <xsl:template match="comment()">
+               <xsl:copy/>
+       </xsl:template>
+       <xsl:template match="text()"/>
+
+</xsl:stylesheet>
+
diff --git a/src/schemas/metadata_v13_to_v12.xsl b/src/schemas/metadata_v13_to_v12.xsl
new file mode 100644 (file)
index 0000000..33ad50b
--- /dev/null
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+       v13_to_v12_sites.xsl
+       
+       XSL stylesheet converting a SAML 2 metadata file describing a Shibboleth
+       1.3 federation into the equivalent Shibboleth 1.2 sites file.
+       
+       Author: Ian A. Young <ian@iay.org.uk>
+
+       $Id$
+-->
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+       xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0"
+       xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="urn:mace:shibboleth:1.0"
+       exclude-result-prefixes="shibmeta md ds">
+
+       <!--
+               Version information for this file.  Remember to peel off the dollar signs
+               before dropping the text into another versioned file.
+       -->
+       <xsl:param name="cvsId">$Id$</xsl:param>
+
+       <!--
+               Add a comment to the start of the output file.
+       -->
+       <xsl:template match="/">
+               <xsl:comment>
+                       <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
+                       <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
+                       <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
+                       <xsl:text>&#10;</xsl:text>
+               </xsl:comment>
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <!--Force UTF-8 encoding for the output.-->
+       <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
+
+       <!--
+               Selectively strip empty text nodes from the input.
+       -->
+       <xsl:strip-space elements="md:EntityDescriptor"/>
+       
+       <!--
+               Map EntitiesDescriptor to SiteGroup
+       -->
+       <xsl:template match="md:EntitiesDescriptor">
+               <SiteGroup Name="{@Name}">
+                       <xsl:attribute name="xsi:schemaLocation">
+                               <xsl:text>urn:mace:shibboleth:1.0 shibboleth.xsd</xsl:text>
+                       </xsl:attribute>
+                       <!--
+                               Pass through text blocks and comments, and interesting elements.
+                               These may be: EntityDescriptor or nested EntitiesDescriptor.
+                       -->
+                       <xsl:apply-templates select="text()|comment()|md:EntityDescriptor|md:EntitiesDescriptor"/>
+               </SiteGroup>
+       </xsl:template>
+
+       <!--
+               Map EntityDescriptor to whichever of OriginSite and/or DestinationSite apply.
+       -->
+       <xsl:template match="md:EntityDescriptor">
+               <xsl:if test="md:IDPSSODescriptor">
+                       <xsl:call-template name="OriginSite"/>
+               </xsl:if>
+               <xsl:if test="md:SPSSODescriptor">
+                       <xsl:call-template name="DestinationSite"/>
+               </xsl:if>
+       </xsl:template>
+
+       <!--
+               Map appropriate EntityDescriptor to OriginSite
+       -->
+       <xsl:template name="OriginSite">
+               <OriginSite Name="{@entityID}">
+                       <!-- ErrorURL attribute -->
+                       <xsl:apply-templates select="md:IDPSSODescriptor/@errorURL"/>
+
+                       <!--
+                               Copy through all comments at the start of the output element.
+                               This means we don't lose comments, but there is no way to guarantee they will
+                               come out "in the right place".
+                       -->
+                       <xsl:apply-templates select="descendant::comment()"/>
+
+                       <!--    Alias elements -->
+                       <xsl:apply-templates select="md:Organization"/>
+
+                       <!-- Contact elements -->
+                       <xsl:apply-templates select="md:ContactPerson"/>
+
+                       <!-- HandleService elements -->
+                       <xsl:apply-templates select="md:IDPSSODescriptor"/>
+
+                       <!-- AttributeAuthority elements -->
+                       <xsl:apply-templates select="md:AttributeAuthorityDescriptor/md:AttributeService"/>
+
+                       <!--
+                               Domain elements
+                               
+                               These may come from Scope elements under either of two md elements.  We pass
+                               through only the ones from the AttributeAuthorityDescriptor as we know that 1.2
+                               sites don't have scopes associated with the SSO.
+                       -->
+                       <xsl:apply-templates select="md:AttributeAuthorityDescriptor/md:Extensions/shibmeta:Scope"/>
+
+               </OriginSite>
+       </xsl:template>
+
+       <!--
+               Map IDPSSODescriptor to HandleService
+       -->
+       <xsl:template match="md:IDPSSODescriptor">
+               <HandleService Name="{md:KeyDescriptor/ds:KeyInfo/ds:KeyName}"
+                       Location="{md:SingleSignOnService/@Location}" 
+               />
+       </xsl:template>
+
+       <!--
+               Map AttributeService to AttributeAuthority
+       -->
+       <xsl:template match="md:AttributeService">
+               <!-- pull out the host component of the location, after the // and before the next / -->
+               <xsl:param name="host" select="substring-before(substring-after(@Location, '//'), '/')"/>
+               <AttributeAuthority Location="{@Location}">
+                       <xsl:attribute name="Name">
+                               <xsl:choose>
+                                       <!-- take off a trailing :port from the host, if present -->
+                                       <xsl:when test="substring-before($host, ':') != ''">
+                                               <xsl:value-of select="substring-before($host, ':')"/>
+                                       </xsl:when>
+                                       <!-- otherwise if the port is absent we just use the host unchanged -->
+                                       <xsl:otherwise>
+                                               <xsl:value-of select="$host"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:attribute>
+               </AttributeAuthority>
+       </xsl:template>
+
+       <!--
+               Map Scope to Domain
+       -->
+       <xsl:template match="shibmeta:Scope">
+               <Domain>
+                       <xsl:apply-templates select="@regexp"/>
+                       <xsl:value-of select="."/>
+               </Domain>
+       </xsl:template>
+
+       <!--
+               Map appropriate EntityDescriptor to DestinationSite
+       -->
+       <xsl:template name="DestinationSite">
+               <DestinationSite Name="{@entityID}">
+                       <!-- ErrorURL attribute -->
+                       <xsl:apply-templates select="md:SPSSODescriptor/@errorURL"/>
+
+                       <!--
+                               Copy through all comments at the start of the output element.
+                               This means we don't lose comments, but there is no way to guarantee they will
+                               come out "in the right place".
+                       -->
+                       <xsl:apply-templates select="descendant::comment()"/>
+
+                       <!--    Alias elements -->
+                       <xsl:apply-templates select="md:Organization"/>
+
+                       <!-- Contact elements -->
+                       <xsl:apply-templates select="md:ContactPerson"/>
+
+                       <!-- AssertionConsumerServiceURL elements -->
+                       <xsl:apply-templates
+                               select="md:SPSSODescriptor/md:AssertionConsumerService[@Binding='urn:oasis:names:tc:SAML:1.0:profiles:browser-post']"/>
+
+                       <!-- AttributeRequester elements -->
+                       <xsl:apply-templates select="md:SPSSODescriptor/md:KeyDescriptor/ds:KeyInfo/ds:KeyName"/>
+               </DestinationSite>
+       </xsl:template>
+
+       <!--
+               Map AssertionConsumerService to AssertionConsumerServiceURL
+       -->
+       <xsl:template match="md:AssertionConsumerService">
+               <AssertionConsumerServiceURL Location="{@Location}"/>
+       </xsl:template>
+
+       <!--
+               Map ds:KeyName to AttributeRequester
+       -->
+       <xsl:template match="ds:KeyName">
+               <AttributeRequester Name="{.}"/>
+       </xsl:template>
+       
+       <!--
+               Map Organization to a sequence of Alias elements.
+
+               The common case is that there are exactly one of each of OrganizationName and
+               OrganizationDisplayName, and that they are equal.  In that case, just convert the
+               OrganizationDisplayName into an Alias.  Otherwise, convert them all.
+       -->
+       <xsl:template match="md:Organization">
+               <xsl:param name="nName" select="count(md:OrganizationName)"/>
+               <xsl:param name="nDisp" select="count(md:OrganizationDisplayName)"/>
+               <xsl:choose>
+                       <xsl:when test="$nName=1 and $nDisp=1 and md:OrganizationName = md:OrganizationDisplayName">
+                               <xsl:apply-templates select="md:OrganizationDisplayName"/>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:apply-templates select="md:OrganizationName"/>
+                               <xsl:apply-templates select="md:OrganizationDisplayName"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!--
+               Map OrganizationName or OrganizationDisplayName to Alias
+       -->
+       <xsl:template match="md:OrganizationName|md:OrganizationDisplayName">
+               <Alias>
+                       <xsl:if test="@xml:lang != 'en'">
+                               <xsl:apply-templates select="@xml:lang"/>
+                       </xsl:if>
+                       <xsl:value-of select="."/>
+               </Alias>
+       </xsl:template>
+
+       <!--
+               Map Contact to ContactPerson
+               
+               Cope with:
+                       * absence of optional EmailAddress
+                       * malformed EmailAddress (no mailto:)
+                       * mixtures of GivenName and SurName
+       -->
+       <xsl:template match="md:ContactPerson">
+               <Contact Type="{@contactType}">
+                       <!-- Email attribute -->
+                       <xsl:choose>
+                               <xsl:when test="starts-with(md:EmailAddress, 'mailto:')">
+                                       <xsl:attribute name="Email">
+                                               <xsl:value-of select="substring-after(md:EmailAddress, 'mailto:')"/>
+                                       </xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="md:EmailAddress">
+                                       <xsl:attribute name="Email">
+                                               <xsl:value-of select="md:EmailAddress"/>
+                                       </xsl:attribute>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <!-- omit Email attribute if in doubt -->
+                               </xsl:otherwise>
+                       </xsl:choose>
+                       <!-- Name attribute -->
+                       <xsl:choose>
+                               <xsl:when test="md:GivenName and md:SurName">
+                                       <xsl:attribute name="Name"><xsl:value-of select="concat(md:GivenName, ' ', md:SurName)"/></xsl:attribute>
+                               </xsl:when>
+                               <xsl:when test="md:GivenName">
+                                       <xsl:attribute name="Name"><xsl:value-of select="md:GivenName"/></xsl:attribute>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:attribute name="Name">Nobody</xsl:attribute>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </Contact>
+       </xsl:template>
+       
+       <!--
+               Map @errorURL to @ErrorURL
+       -->
+       <xsl:template match="@errorURL">
+               <xsl:attribute name="ErrorURL"><xsl:value-of select="."/></xsl:attribute>
+       </xsl:template>
+
+       <!--
+               By default, copy referenced attributes through unchanged.
+       -->
+       <xsl:template match="@*">
+               <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
+       </xsl:template>
+
+       <!--
+               By default, copy comments through to the output unchanged, but strip extra text.
+       -->
+       <xsl:template match="comment()">
+               <xsl:copy/>
+       </xsl:template>
+       <xsl:template match="text()"/>
+
+</xsl:stylesheet>
+
diff --git a/src/schemas/trust_v12_to_v11.xsl b/src/schemas/trust_v12_to_v11.xsl
new file mode 100644 (file)
index 0000000..b444ea6
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+       v12_to_v11_trust.xsl
+       
+       XSL stylesheet converting a Shibboleth 1.2 trust metadata file into the equivalent for
+       Shibboleth 1.1.
+
+       Author: Ian A. Young <ian@iay.org.uk>
+
+       $Id$
+-->
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:shibb10="urn:mace:shibboleth:1.0"
+       xmlns:trust10="urn:mace:shibboleth:trust:1.0"
+       xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+       xmlns="urn:mace:shibboleth:1.0"
+       exclude-result-prefixes="shibb10 trust10">
+       
+       <!--
+               Version information for this file.  Remember to peel off the dollar signs
+               before dropping the text into another versioned file.
+       -->
+       <xsl:param name="cvsId">$Id$</xsl:param>
+
+       <!--
+               Add a comment to the start of the output file.
+       -->
+       <xsl:template match="/">
+               <xsl:comment>
+                       <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
+                       <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
+                       <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
+                       <xsl:text>&#10;</xsl:text>
+               </xsl:comment>
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <!--Force UTF-8 encoding for the output.-->
+       <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
+
+       <!--trust10:Trust is the root element for the trust file.  Process it by changing the default namespace used and recursing.-->
+       <xsl:template match="trust10:Trust">
+               <Trust>
+                       <!-- <xsl:apply-templates select="@*"/> -->
+                       <xsl:apply-templates/>
+               </Trust>
+       </xsl:template>
+
+       <!--trust10:KeyAuthority appears in the trust file, and needs its namespace changing.  After that, we need to reorder its nested elements a little.-->
+       <xsl:template match="trust10:KeyAuthority">
+               <KeyAuthority>
+                       <xsl:apply-templates select="ds:KeyInfo"/>
+                       <Subject>
+                               <xsl:value-of select="ds:KeyName"/>
+                       </Subject>
+               </KeyAuthority>
+       </xsl:template>
+
+       <!--
+               Generic recursive copy for ds:* elements.
+               
+               This works better than an xsl:copy-of because it does not copy across spurious
+               namespace nodes.
+       -->
+       <xsl:template match="ds:*">
+               <xsl:element name="{name()}">
+                       <xsl:apply-templates select="ds:* | text() | comment() | @*"/>
+               </xsl:element>
+       </xsl:template>
+
+       <!--By default, copy text blocks, comments and attributes unchanged.-->
+       <xsl:template match="text()|comment()|@*">
+               <xsl:copy/>
+       </xsl:template>
+
+       <!--By default, copy all elements from the input to the output, along with their attributes and contents.-->
+       <xsl:template match="*">
+               <xsl:copy>
+                       <xsl:apply-templates select="node()|@*"/>
+               </xsl:copy>
+       </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/src/schemas/trust_v13_to_v12.xsl b/src/schemas/trust_v13_to_v12.xsl
new file mode 100644 (file)
index 0000000..242e593
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+       v13_to_v12_trust.xsl
+       
+       XSL stylesheet converting a SAML 2 metadata file describing a Shibboleth
+       1.3 federation into the equivalent Shibboleth 1.2 trust file.
+       
+       Author: Ian A. Young <ian@iay.org.uk>
+
+       $Id$
+-->
+<xsl:stylesheet version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+       xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0"
+       xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="urn:mace:shibboleth:trust:1.0"
+       exclude-result-prefixes="shibmeta md">
+
+       <!--
+               Version information for this file.  Remember to peel off the dollar signs
+               before dropping the text into another versioned file.
+       -->
+       <xsl:param name="cvsId">$Id$</xsl:param>
+
+       <!--
+               Add a comment to the start of the output file.
+       -->
+       <xsl:template match="/">
+               <xsl:comment>
+                       <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
+                       <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
+                       <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
+                       <xsl:text>&#10;</xsl:text>
+               </xsl:comment>
+               <Trust>
+                       <xsl:attribute name="xsi:schemaLocation">
+                               <xsl:text>urn:mace:shibboleth:trust:1.0 shibboleth-trust-1.0.xsd </xsl:text>
+                               <xsl:text>http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd</xsl:text>
+                       </xsl:attribute>
+                       <xsl:apply-templates/>
+               </Trust>
+       </xsl:template>
+
+       <!--Force UTF-8 encoding for the output.-->
+       <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
+
+       <!--
+               Extract a KeyAuthority extension from an EntitiesDescriptor.
+       -->
+       <xsl:template match="md:EntitiesDescriptor">
+       
+               <!-- extract KeyAuthority metadata, if any -->
+               <xsl:if test="md:Extensions/shibmeta:KeyAuthority/ds:KeyInfo">
+                       <xsl:apply-templates select="md:Extensions/shibmeta:KeyAuthority">
+                               <xsl:with-param name="name" select="@Name"/>
+                       </xsl:apply-templates>
+               </xsl:if>
+
+               <!-- proceed to nested EntitiesDescriptor and EntityDescriptor elements -->
+               <xsl:apply-templates select="md:EntitiesDescriptor | md:EntityDescriptor"/>
+       </xsl:template>
+
+       <!--
+               Extract a KeyAuthority extension from an EntityDescriptor.
+       -->
+       <xsl:template match="md:EntityDescriptor">
+               <!-- extract KeyAuthority metadata, if any -->
+               <xsl:if test="md:Extensions/shibmeta:KeyAuthority/ds:KeyInfo">
+                       <xsl:apply-templates select="md:Extensions/shibmeta:KeyAuthority">
+                               <xsl:with-param name="name" select="@entityID"/>
+                       </xsl:apply-templates>
+               </xsl:if>
+       </xsl:template>
+
+       <!--
+               Map shibmeta:KeyAuthority to trust:KeyAuthority
+       -->
+       <xsl:template match="shibmeta:KeyAuthority">
+               <xsl:param name="name"/>
+               <KeyAuthority>
+                       <!-- copy across VerifyDepth attribute if present -->
+                       <xsl:apply-templates select="@VerifyDepth"/>
+
+                       <!-- generate KeyName -->
+                       <ds:KeyName>
+                               <xsl:value-of select="$name"/>
+                       </ds:KeyName>
+
+                       <!-- generate single output KeyInfo element -->
+                       <ds:KeyInfo>
+                               <!-- extract the insides of all KeyInfo elements in the input -->
+                               <xsl:apply-templates select="text() | comment() | ds:KeyInfo/* | ds:KeyInfo/comment() | ds:KeyInfo/text()"/>
+                       </ds:KeyInfo>
+               </KeyAuthority>
+       </xsl:template>
+
+       <!--
+               Generic recursive copy for ds:* elements.
+               
+               This works better than an xsl:copy-of because it does not copy across spurious
+               namespace nodes.
+       -->
+       <xsl:template match="ds:*">
+               <xsl:element name="{name()}">
+                       <xsl:apply-templates select="ds:* | text() | comment() | @*"/>
+               </xsl:element>
+       </xsl:template>
+
+       <!--
+               By default, copy referenced attributes through unchanged.
+       -->
+       <xsl:template match="@*">
+               <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
+       </xsl:template>
+
+       <!--
+               By default, copy comments and text nodes through to the output unchanged.
+       -->
+       <xsl:template match="text()|comment()">
+               <xsl:copy/>
+       </xsl:template>
+
+</xsl:stylesheet>
+