A RELAX NG Schema for XML Signature Syntax and Processing

Editor's Draft 16 July 2008

$Revision: 1.7 $ $Date: 2008/07/16 18:04:37 $

This version:
http://www.w3.org/TR/2008/WD-xmldsig-relaxng-20080716/
Latest version:
http://www.w3.org/TR/xmldsig-relaxng/
Editor:
Thomas Roessler, W3C

Abstract

This Note serves to publish a RELAX NG schema for XML Signature [XMLDSIG].

Status of this Document

This document is an editors' copy that has no official standing.

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

Table of Contents

1 Overview
2 Acknowledgements
3 Schema
    3.1 Schema in RELAX NG XML Syntax
    3.2 Schema in Relax NG Compact Syntax
4 References


1 Overview

The XML Signature specification [XMLDSIG] includes a normative XML schema and an informative DTD. Upon popular request, this Note includes a non-normative RELAX NG [RELAXNG] schema for the document format.

2 Acknowledgements

The schema presented in this Note was originally prepared by Joseph Reagle, then affiliated with W3C.

3 Schema

The schema included with this Note is also available as a separate XML file and in RELAX NG compact syntax.

3.1 Schema in RELAX NG XML Syntax

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <!--
    Relax NG Grammar for XML Signatures
    Namespace: http://www.w3.org/2000/09/xmldsig#
    $Revision: 1.7 $ on $Date: 2008/07/16 18:04:37 $ by $Author: roessler $
    
    Copyright 2001 The Internet Society and W3C (Massachusetts Institute
    of Technology, Institut National de Recherche en Informatique et en
    Automatique, Keio University). All Rights Reserved.
    http://www.w3.org/Consortium/Legal/
    
    This document is governed by the W3C Software License [1] as described
    in the FAQ [2].
    
    [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
    [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
    
    Constructed by hand from xmldsig-core-schema.xsd by
    Norman.Walsh@marklogic.com on 5 May 2008.
    
    Notes:
    
    You must not use the RELAX NG DTD Compatibility features with this
    grammar. DTD Compatibility features, ID type attributes, and
    wildcard attributes are mutually exclusive.
    
    The definition for the Signature element includes a SignatureType
    pattern. The rest of the patterns are "inline". This is a matter of
    style. I constructed only one "type" pattern as an example of the
    style, not because it's significant in the Signature pattern.
  -->
  <start>
    <ref name="Signature"/>
  </start>
  <!-- Start Signature -->
  <define name="SignatureType">
    <optional>
      <attribute name="Id">
        <data type="ID"/>
      </attribute>
    </optional>
    <ref name="SignedInfo"/>
    <ref name="SignatureValue"/>
    <optional>
      <ref name="KeyInfo"/>
    </optional>
    <zeroOrMore>
      <ref name="Object"/>
    </zeroOrMore>
  </define>
  <define name="Signature">
    <element name="ds:Signature">
      <ref name="SignatureType"/>
    </element>
  </define>
  <define name="SignatureValue">
    <element name="ds:SignatureValue">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <data type="base64Binary"/>
    </element>
  </define>
  <!-- Start SignedInfo -->
  <define name="SignedInfo">
    <element name="ds:SignedInfo">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <ref name="CanonicalizationMethod"/>
      <ref name="SignatureMethod"/>
      <oneOrMore>
        <ref name="Reference"/>
      </oneOrMore>
    </element>
  </define>
  <define name="CanonicalizationMethod">
    <element name="ds:CanonicalizationMethod">
      <attribute name="Algorithm">
        <data type="anyURI"/>
      </attribute>
      <zeroOrMore>
        <choice>
          <text/>
          <ref name="anyElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="SignatureMethod">
    <element name="ds:SignatureMethod">
      <attribute name="Algorithm">
        <data type="anyURI"/>
      </attribute>
      <zeroOrMore>
        <choice>
          <text/>
          <ref name="HMACOutputLength"/>
          <ref name="anyOtherElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <!-- Start Reference -->
  <define name="Reference">
    <element name="ds:Reference">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="URI">
          <data type="anyURI"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="Type">
          <data type="anyURI"/>
        </attribute>
      </optional>
      <optional>
        <ref name="Transforms"/>
      </optional>
      <ref name="DigestMethod"/>
      <ref name="DigestValue"/>
    </element>
  </define>
  <define name="Transforms">
    <element name="ds:Transforms">
      <oneOrMore>
        <ref name="Transform"/>
      </oneOrMore>
    </element>
  </define>
  <define name="Transform">
    <element name="ds:Transform">
      <attribute name="Algorithm">
        <data type="anyURI"/>
      </attribute>
      <zeroOrMore>
        <choice>
          <ref name="anyOtherElement"/>
          <ref name="XPath"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="XPath">
    <element name="ds:XPath">
      <data type="string"/>
    </element>
  </define>
  <!-- End Reference -->
  <define name="DigestMethod">
    <element name="ds:DigestMethod">
      <attribute name="Algorithm">
        <data type="anyURI"/>
      </attribute>
      <zeroOrMore>
        <ref name="anyOtherElement"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="DigestValue">
    <element name="ds:DigestValue">
      <ref name="DigestValueType"/>
    </element>
  </define>
  <define name="DigestValueType">
    <data type="base64Binary"/>
  </define>
  <!-- End SignedInfo -->
  <!-- Start KeyInfo -->
  <define name="KeyInfo">
    <element name="ds:KeyInfo">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <choice>
          <text/>
          <ref name="KeyName"/>
          <ref name="KeyValue"/>
          <ref name="RetrievalMethod"/>
          <ref name="X509Data"/>
          <ref name="PGPData"/>
          <ref name="SPKIData"/>
          <ref name="MgmtData"/>
          <ref name="anyOtherElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="KeyName">
    <element name="ds:KeyName">
      <data type="string"/>
    </element>
  </define>
  <define name="MgmtData">
    <element name="ds:MgmtData">
      <data type="string"/>
    </element>
  </define>
  <define name="KeyValue">
    <element name="ds:KeyValue">
      <zeroOrMore>
        <choice>
          <text/>
          <ref name="DSAKeyValue"/>
          <ref name="RSAKeyValue"/>
          <ref name="anyOtherElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="RetrievalMethod">
    <element name="ds:RetrievalMethod">
      <attribute name="URI">
        <data type="anyURI"/>
      </attribute>
      <optional>
        <attribute name="Type">
          <data type="anyURI"/>
        </attribute>
      </optional>
      <optional>
        <ref name="Transforms"/>
      </optional>
    </element>
  </define>
  <!-- Start X509Data -->
  <define name="X509Data">
    <element name="ds:X509Data">
      <zeroOrMore>
        <choice>
          <ref name="X509IssuerSerial"/>
          <ref name="X509SKI"/>
          <ref name="X509SubjectName"/>
          <ref name="X509Certificate"/>
          <ref name="X509CRL"/>
          <ref name="anyOtherElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="X509IssuerSerial">
    <element name="ds:X509IssuerSerial">
      <ref name="X509IssuerName"/>
      <ref name="X509SerialNumber"/>
    </element>
  </define>
  <define name="X509IssuerName">
    <element name="ds:X509IssuerName">
      <data type="string"/>
    </element>
  </define>
  <define name="X509SerialNumber">
    <element name="ds:X509SerialNumber">
      <data type="integer"/>
    </element>
  </define>
  <define name="X509SKI">
    <element name="ds:X509SKI">
      <data type="base64Binary"/>
    </element>
  </define>
  <define name="X509SubjectName">
    <element name="ds:X509SubjectName">
      <data type="string"/>
    </element>
  </define>
  <define name="X509Certificate">
    <element name="ds:X509Certificate">
      <data type="base64Binary"/>
    </element>
  </define>
  <define name="X509CRL">
    <element name="ds:X509CRL">
      <data type="base64Binary"/>
    </element>
  </define>
  <!-- End X509Data -->
  <!-- Begin PGPData -->
  <define name="PGPData">
    <element name="ds:PGPData">
      <choice>
        <group>
          <ref name="PGPKeyID"/>
          <optional>
            <ref name="PGPKeyPacket"/>
          </optional>
          <zeroOrMore>
            <ref name="anyOtherElement"/>
          </zeroOrMore>
        </group>
        <group>
          <ref name="PGPKeyPacket"/>
          <zeroOrMore>
            <ref name="anyOtherElement"/>
          </zeroOrMore>
        </group>
      </choice>
    </element>
  </define>
  <define name="PGPKeyID">
    <element name="ds:PGPKeyID">
      <data type="base64Binary"/>
    </element>
  </define>
  <define name="PGPKeyPacket">
    <element name="ds:PGPKeyPacket">
      <data type="base64Binary"/>
    </element>
  </define>
  <!-- End PGPData -->
  <!-- Begin SPKIData -->
  <define name="SPKIData">
    <element name="ds:SPKIData">
      <oneOrMore>
        <ref name="SPKISexp"/>
        <zeroOrMore>
          <ref name="anyOtherElement"/>
        </zeroOrMore>
      </oneOrMore>
    </element>
  </define>
  <define name="SPKISexp">
    <element name="ds:SPKISexp">
      <data type="base64Binary"/>
    </element>
  </define>
  <!-- End SPKIData -->
  <!-- End KeyInfo -->
  <!-- Start Object (Manifest, SignatureProperty) -->
  <define name="Object">
    <element name="ds:Object">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MimeType">
          <data type="string"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="Encoding">
          <data type="anyURI"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="anyElement"/>
          <text/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="Manifest">
    <element name="ds:Manifest">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <oneOrMore>
        <ref name="Reference"/>
      </oneOrMore>
    </element>
  </define>
  <define name="SignatureProperties">
    <element name="ds:SignatureProperties">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <oneOrMore>
        <ref name="SignatureProperty"/>
      </oneOrMore>
    </element>
  </define>
  <define name="SignatureProperty">
    <element name="ds:SignatureProperty">
      <optional>
        <attribute name="Id">
          <data type="ID"/>
        </attribute>
      </optional>
      <attribute name="Target">
        <data type="anyURI"/>
      </attribute>
      <oneOrMore>
        <ref name="anyOtherElement"/>
      </oneOrMore>
    </element>
  </define>
  <!-- End Object (Manifest, SignatureProperty) -->
  <!-- Start Algorithm Parameters -->
  <define name="HMACOutputLength">
    <element name="ds:HMACOutputLength">
      <data type="integer"/>
    </element>
  </define>
  <!-- Start KeyValue Element-types -->
  <define name="DSAKeyValue">
    <element name="ds:DSAKeyValue">
      <optional>
        <ref name="P"/>
        <ref name="Q"/>
      </optional>
      <optional>
        <ref name="G"/>
      </optional>
      <ref name="Y"/>
      <optional>
        <ref name="J"/>
      </optional>
      <optional>
        <ref name="Seed"/>
        <ref name="PgenCounter"/>
      </optional>
    </element>
  </define>
  <define name="P">
    <element name="ds:P">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="Q">
    <element name="ds:Q">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="G">
    <element name="ds:G">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="Y">
    <element name="ds:Y">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="J">
    <element name="ds:J">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="Seed">
    <element name="ds:Seed">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="PgenCounter">
    <element name="ds:PgenCounter">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="CryptoBinary">
    <data type="base64Binary"/>
  </define>
  <define name="RSAKeyValue">
    <element name="ds:RSAKeyValue">
      <ref name="Modulus"/>
      <ref name="Exponent"/>
    </element>
  </define>
  <define name="Modulus">
    <element name="ds:Modulus">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <define name="Exponent">
    <element name="ds:Exponent">
      <ref name="CryptoBinary"/>
    </element>
  </define>
  <!-- End KeyValue Element-types -->
  <!-- End Signature -->
  <!-- Definitions for the *any* wild card and the *any other* wildcard -->
  <define name="anyAttribute">
    <attribute>
      <anyName/>
    </attribute>
  </define>
  <define name="anyElement">
    <element>
      <anyName/>
      <zeroOrMore>
        <choice>
          <ref name="anyAttribute"/>
          <text/>
          <ref name="anyElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="anyOtherElement">
    <element>
      <anyName>
        <except>
          <nsName ns="http://www.w3.org/2000/09/xmldsig#"/>
        </except>
      </anyName>
      <zeroOrMore>
        <choice>
          <ref name="anyAttribute"/>
          <text/>
          <ref name="anyOtherElement"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
</grammar>
<!-- EOF -->

3.2 Schema in Relax NG Compact Syntax

namespace ds = "http://www.w3.org/2000/09/xmldsig#"

# Relax NG Grammar for XML Signatures
# Namespace: http://www.w3.org/2000/09/xmldsig#
# $Revision: 1.7 $ on $Date: 2008/07/16 18:04:37 $ by $Author: roessler $
#
# Copyright 2001 The Internet Society and W3C (Massachusetts Institute
# of Technology, Institut National de Recherche en Informatique et en
# Automatique, Keio University). All Rights Reserved.
# http://www.w3.org/Consortium/Legal/
#
# This document is governed by the W3C Software License [1] as described
# in the FAQ [2].
#
# [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
# [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
#
# Constructed by hand from xmldsig-core-schema.xsd by
# Norman.Walsh@marklogic.com on 5 May 2008.
#
# Notes:
#
# You must not use the RELAX NG DTD Compatibility features with this
# grammar. DTD Compatibility features, ID type attributes, and
# wildcard attributes are mutually exclusive.
#
# The definition for the Signature element includes a SignatureType
# pattern. The rest of the patterns are "inline". This is a matter of
# style. I constructed only one "type" pattern as an example of the
# style, not because it's significant in the Signature pattern.

start = Signature

# Start Signature

SignatureType = 
   attribute Id { xsd:ID }?,
   SignedInfo,
   SignatureValue,
   KeyInfo?,
   Object*

Signature = element ds:Signature {
   SignatureType
}

SignatureValue = element ds:SignatureValue {
   attribute Id { xsd:ID }?,
   xsd:base64Binary
}

# Start SignedInfo

SignedInfo = element ds:SignedInfo {
   attribute Id { xsd:ID }?,
   CanonicalizationMethod,
   SignatureMethod,
   Reference+
}

CanonicalizationMethod = element ds:CanonicalizationMethod {
   attribute Algorithm { xsd:anyURI },
   (text | anyElement)*
}

SignatureMethod = element ds:SignatureMethod {
   attribute Algorithm { xsd:anyURI },
   (text | HMACOutputLength | anyOtherElement)*
}

# Start Reference

Reference = element ds:Reference {
   attribute Id { xsd:ID }?,
   attribute URI { xsd:anyURI }?,
   attribute Type { xsd:anyURI }?,
   Transforms?,
   DigestMethod,
   DigestValue
}

Transforms = element ds:Transforms {
   Transform+
}

Transform = element ds:Transform {
   attribute Algorithm { xsd:anyURI },
   (anyOtherElement | XPath)*
}

XPath = element ds:XPath {
   xsd:string
}

# End Reference

DigestMethod = element ds:DigestMethod {
   attribute Algorithm { xsd:anyURI },
   anyOtherElement*
}

DigestValue = element ds:DigestValue {
   DigestValueType
}

DigestValueType = xsd:base64Binary

# End SignedInfo

# Start KeyInfo

KeyInfo = element ds:KeyInfo {
   attribute Id { xsd:ID }?,
   (text | KeyName | KeyValue
    | RetrievalMethod | X509Data | PGPData | SPKIData | MgmtData
    | anyOtherElement)*
}

KeyName = element ds:KeyName { xsd:string }

MgmtData = element ds:MgmtData { xsd:string }

KeyValue = element ds:KeyValue {
   (text | DSAKeyValue | RSAKeyValue | anyOtherElement)*
}

RetrievalMethod = element ds:RetrievalMethod {
   attribute URI { xsd:anyURI },
   attribute Type { xsd:anyURI }?,
   Transforms?
}

# Start X509Data

X509Data = element ds:X509Data {
   (X509IssuerSerial | X509SKI | X509SubjectName | X509Certificate | X509CRL
    | anyOtherElement)*
}

X509IssuerSerial = element ds:X509IssuerSerial {
   X509IssuerName,
   X509SerialNumber
}

X509IssuerName = element ds:X509IssuerName { xsd:string }

X509SerialNumber = element ds:X509SerialNumber { xsd:integer }

X509SKI = element ds:X509SKI { xsd:base64Binary }

X509SubjectName = element ds:X509SubjectName { xsd:string }

X509Certificate = element ds:X509Certificate { xsd:base64Binary }

X509CRL = element ds:X509CRL { xsd:base64Binary }

# End X509Data

# Begin PGPData

PGPData = element ds:PGPData {
   ((PGPKeyID,PGPKeyPacket?,anyOtherElement*)
    | (PGPKeyPacket,anyOtherElement*))
}

PGPKeyID = element ds:PGPKeyID { xsd:base64Binary }

PGPKeyPacket = element ds:PGPKeyPacket { xsd:base64Binary  }

# End PGPData

# Begin SPKIData

SPKIData = element ds:SPKIData {
   (SPKISexp,anyOtherElement*)+
}

SPKISexp = element ds:SPKISexp { xsd:base64Binary }

# End SPKIData

# End KeyInfo

# Start Object (Manifest, SignatureProperty)

Object = element ds:Object {
   attribute Id { xsd:ID }?,
   attribute MimeType { xsd:string }?,
   attribute Encoding { xsd:anyURI }?,
   (anyElement|text)*
}

Manifest = element ds:Manifest {
   attribute Id { xsd:ID }?,
   Reference+
}

SignatureProperties = element ds:SignatureProperties {
   attribute Id { xsd:ID }?,
   SignatureProperty+
}
   
SignatureProperty = element ds:SignatureProperty {
   attribute Id { xsd:ID }?,
   attribute Target { xsd:anyURI },
   anyOtherElement+
}

# End Object (Manifest, SignatureProperty)

# Start Algorithm Parameters

HMACOutputLength = element ds:HMACOutputLength {
   xsd:integer
}

# Start KeyValue Element-types

DSAKeyValue = element ds:DSAKeyValue {
   (P,Q)?, G?, Y, J?, (Seed, PgenCounter)?
}

P = element ds:P { CryptoBinary }
Q = element ds:Q { CryptoBinary }
G = element ds:G { CryptoBinary }
Y = element ds:Y { CryptoBinary }
J = element ds:J { CryptoBinary }
Seed = element ds:Seed { CryptoBinary }
PgenCounter = element ds:PgenCounter { CryptoBinary }

CryptoBinary = xsd:base64Binary

RSAKeyValue = element ds:RSAKeyValue {
   Modulus,
   Exponent
}

Modulus = element ds:Modulus { CryptoBinary }
Exponent = element ds:Exponent { CryptoBinary }

# End KeyValue Element-types

# End Signature

# Definitions for the *any* wild card and the *any other* wildcard

anyAttribute = attribute * { text }

anyElement = element * { (anyAttribute | text | anyElement)* }

anyOtherElement = element * - ds:* { (anyAttribute | text | anyOtherElement)* }

# EOF


4 References

RELAXNG
Information technology - Document Schema Definition Language (DSDL) - Part 2: Regular-grammar-based validation - RELAX NG., International Organization for Standardization (ISO) ISO/IEC 19757-2:2003.
XMLDSIG
XML-Signature Syntax and Processing, D. Eastlake, J. R., D. Solo, M. Bartel, J. Boyer , B. Fox , E. Simon. W3C Recommendation, 12 February 2002, http://www.w3.org/TR/xmldsig-core/.