<?xml version="1.0"?>

<!-- $Id: chat-message.xsd,v 1.7 2003/06/23 11:13:33 strauss Exp $
  -
  -->

<xsd:schema 
  targetNamespace="http://www.ibr.cs.tu-bs.de/chat-message"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://www.ibr.cs.tu-bs.de/chat-message"
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified" 
  xml:lang="en">

  <xsd:annotation>
    <xsd:documentation>
      This XML Schema defines the p2p-chat protocol messages.
    </xsd:documentation>
  </xsd:annotation>
 
  <!--
    -                              Types
    -->
      
  <xsd:simpleType name="UserIDType">
    <xsd:annotation>
      <xsd:documentation>
        Elements of this type represent a globally unique user
        identification. It has to contain a user name part followed by
        an @ character and a domain part. It is highly recommended to
        use the users valid Internet email address.  Note that it has
        to be treated case-insensitive.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,127}@[a-zA-Z0-9_\.\-]{1,128}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="MessageIDType">
    <xsd:annotation>
      <xsd:documentation>
        Elements of this type are used to form a unique identification
        for messages per user. The pair of a UserID and a MessageID
        builds a globally unique message identification. How the
        MessageID is actually built is an implementation issue. It
        might be a persistent counter incremented with each message
        generation, or it might be based on a timestamp, for example.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9@_\.\-]{1,256}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="TTLType">
    <xsd:annotation>
      <xsd:documentation>
        An integer time-to-live value. Note that the value range is
        restricted.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:int">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="32"/>
   </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="ChannelNameType">
    <xsd:annotation>
      <xsd:documentation>
        The name of a channel.  Note that it has to be treated
        case-insensitive.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,16}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="DomainNameType">
    <xsd:annotation>
      <xsd:documentation>
        A fully qualified domain name of a listening endpoint.
        Note that it has to be treated case-insensitive.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>

  <xsd:simpleType name="IPv4AddressType">
    <xsd:annotation>
      <xsd:documentation>
        An IPv4 address of a listening endpoint.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="PortNumberType">
    <xsd:annotation>
      <xsd:documentation>
        A TCP port number of a listening endpoint.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:int">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="65535"/>
   </xsd:restriction>
  </xsd:simpleType>

  <xsd:complexType name="PeerAddressType">
    <xsd:annotation>
      <xsd:documentation>
        A peer address consists of a hostname (or if a hostname
        is not available, an IPv4 address) and a TCP port number.
        This pair specifies a potential listening peer endpoint
        to which other peers might try to connect.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:choice>
        <xsd:element name="hostname" type="DomainNameType"/>
        <xsd:element name="ipaddress" type="IPv4AddressType"/>
      </xsd:choice>
      <xsd:element name="port" type="PortNumberType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="CertificateType">
    <xsd:annotation>
      <xsd:documentation>
        A certificate consists of the user id to which the certificate
        belongs and the certificate itself encoded in Base64.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="user" type="UserIDType"/>
      <xsd:element name="data" type="xsd:base64Binary"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:simpleType name="CipherType">
    <xsd:annotation>
      <xsd:documentation>
        A label to identify a symmetric cipher algorithm.  So far,
        just one (reasonable) cipher is defined, but others may be
        added in future revision of the protocol.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="NONE">
        <xsd:annotation>
          <xsd:documentation>
            No encryption.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="DES-CBC">
        <xsd:annotation>
          <xsd:documentation>
            64(56) bit DES in Cipher Block Chaining mode with PKCS #5
	    padding.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="SignType">
    <xsd:annotation>
      <xsd:documentation>
        A label to identify a message digest algorithm.  So far, just
        one algorithm is defined, but others may be added in future
        revision of the protocol.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="MD5">
        <xsd:annotation>
          <xsd:documentation>
            MD5 digest (encrypted with the senders private key).
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="SignatureType">
    <xsd:annotation>
      <xsd:documentation>
        A Base64 encoded signature. It is calculated for the
        concatenated UTF-8 encoded values (without attributes) of all
        child elements of the chat-message element in depth-first
        order.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:base64Binary"/>
  </xsd:simpleType>

  <xsd:complexType name="ChannelKeyType">
    <xsd:annotation>
      <xsd:documentation>
        A symmetric session key consists of the channel name to which
        the key belongs and an identification of the used cipher
        algorithm, and a number of key sub-elements each containing a
        channel member and the key data for that user encrypted with
        his/her public key and encoded in Base64.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="channel"    type="ChannelNameType"/>
      <xsd:element name="cipher"     type="CipherType"/>
      <xsd:element name="key" minOccurs="0" maxOccurs="unbounded">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="member" type="UserIDType"/>
            <xsd:element name="data"   type="xsd:base64Binary"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

  <!--
    -                   Root Element and Message Types
    -->
      
  <xsd:element name="chat-message">
    <xsd:annotation>
      <xsd:documentation>
        This is the root element. It represents a p2p-chat protocol
        message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:sequence>
        <xsd:choice>
          <xsd:element name="hello"          type="HelloMessage"/>
          <xsd:element name="quit"           type="QuitMessage"/>
          <xsd:element name="channel"        type="ChannelMessage"/>
          <xsd:element name="getpeers"       type="GetPeersMessage"/>
          <xsd:element name="peers"          type="PeersMessage"/>
          <xsd:element name="getcertificate" type="GetCertificateMessage"/>
          <xsd:element name="certificate"    type="CertificateMessage"/>
          <xsd:element name="getkey"         type="GetKeyMessage"/>
          <xsd:element name="key"            type="KeyMessage"/>
          <xsd:element name="message"        type="MessageMessage"/>
        </xsd:choice>
      </xsd:sequence>
      <xsd:attribute name="ttl"              type="TTLType" default="1"/>
      <xsd:attribute name="signtype"         type="SignType"/>
      <xsd:attribute name="signature"        type="SignatureType"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="HelloMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "hello" message is the first message sent by each peer of
        a newly established connection. The peer may send an informal
        greeting text.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="version"   type="xsd:int"/>
      <xsd:element name="greeting"  type="xsd:string" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="QuitMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "quit" message is sent by a peer as the last message
        before actively shutting down the connection. The peer SHOULD
        give an informal reason why the connection is shut down.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="reason"    type="xsd:string" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>
    
  <xsd:complexType name="ChannelMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "channel" message announces an active channel. The
        existance of the members element denotes a closed channel.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"          type="PeerAddressType"/>
      <xsd:element name="sender"        type="UserIDType"/>
      <xsd:element name="messageid"     type="MessageIDType"/>
      <xsd:element name="timestamp"     type="xsd:dateTime"/>
      <xsd:element name="channelname"   type="ChannelNameType"/>
      <xsd:element name="description"   type="xsd:string"/>
      <xsd:element name="members"       type="UserIDType"
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="GetPeersMessage">
    <xsd:annotation>
      <xsd:documentation>
        A peer may send a "getpeers" message to request a list of
        other peer addresses in order to extend its own list of
        potential connection peers.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="PeersMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node can make other nodes aware of a list of peer addresses
        through a "peers" message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="peer"      type="PeerAddressType" 
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="GetCertificateMessage">
    <xsd:annotation>
      <xsd:documentation>
        A peer may send a "getcertificate" message to request a
        certificate for a given user ID.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="user"      type="UserIDType"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="CertificateMessage">
    <xsd:annotation>
      <xsd:documentation>
        A peer can send a certificate encapsulated in
        a "certificate" message. It's not only the owner of
        the certificate who can send such a message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"        type="PeerAddressType"/>
      <xsd:element name="sender"      type="UserIDType"/>
      <xsd:element name="messageid"   type="MessageIDType"/>
      <xsd:element name="timestamp"   type="xsd:dateTime"/>
      <xsd:element name="certificate" type="CertificateType"/>
    </xsd:sequence>
  </xsd:complexType>
      
  <xsd:complexType name="GetKeyMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node may request a channel key for a given closed channel
        through a "getkey" message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"        type="PeerAddressType"/>      
      <xsd:element name="sender"      type="UserIDType"/>
      <xsd:element name="messageid"   type="MessageIDType"/>
      <xsd:element name="timestamp"   type="xsd:dateTime"/>
      <xsd:element name="channel"     type="ChannelNameType"/>
    </xsd:sequence>
  </xsd:complexType>
    
  <xsd:complexType name="KeyMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node can send a channel key encapsulated in a "key"
        message. The actual data parts of the key have to be encrypted
        with the according receivers' public keys. Its the duty of the
        sender of a "key" message to ensure that the public keys
        really belong the the receivers and that the receivers are
        really members of the channel.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>      
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="key"       type="ChannelKeyType"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="MessageMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "message" message carries the actual content of the chat
        message in its text element. If the iv attribute is present
	it is a message of a closed channel and uses the initialization
	vector given by the iv attribute.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="node"      type="PeerAddressType"/>      
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="channel"   type="ChannelNameType"/>
      <xsd:element name="text">
        <xsd:complexType>
          <xsd:simpleContent>
            <xsd:extension base="xsd:string">
              <xsd:attribute name="iv" type="xsd:base64Binary"/>
            </xsd:extension>
          </xsd:simpleContent>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>

</xsd:schema>

