CCNx XML schema
This corresponds to the DTD ccnx.dtd.
ccnx.xsd
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd"> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- XXX xmlns:ccn="http://www.ccnx.org/content/schema/20090915" targetNamespace="http://www.ccnx.org/content/schema/20090915" elementFormDefault="unqualified" attributeFormDefault="unqualified" --> <xs:annotation> <xs:documentation xml:lang="en"> Content-Centric Networks data schema. </xs:documentation> </xs:annotation> <!-- Top-level objects that can appear in documents, messages, etc. --> <xs:element name="CCNProtocolDataUnit"/> <!-- FIXTHIS - needs a type --> <xs:element name="ContentObject" type="ContentObjectType"/> <xs:element name="CompleteName" type="CompleteNameType"/> <xs:element name="Collection" type="CollectionType"/> <xs:element name="Link" type="LinkType"/> <xs:element name="KeyValueSet" type="KeyValueSetType"/> <xs:element name="Header" type="HeaderType"/> <xs:element name="Interest" type="InterestType"/> <xs:element name="StatusResponse" type="StatusResponseType"/> <xs:complexType name="CollectionType"> <xs:sequence> <xs:element name="Link" type="LinkType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="LinkType"> <xs:sequence> <xs:element name="Name" type="NameType"/> <xs:element name="Label" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="LinkAuthenticator" type="LinkAuthenticatorType" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:complexType name="LinkAuthenticatorType"> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="1"> <xs:element name="PublisherPublicKeyDigest" type="DigestType"/> <xs:element name="PublisherCertificateDigest" type="DigestType"/> <xs:element name="PublisherIssuerKeyDigest" type="DigestType"/> <xs:element name="PublisherIssuerCertificateDigest" type="DigestType"/> </xs:choice> <xs:element name="NameComponentCount" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="Timestamp" type="TimestampType" minOccurs="0" maxOccurs="1"/> <xs:element name="Type" type="ContentType" minOccurs="0" maxOccurs="1"/> <xs:element name="ContentDigest" type="Base64BinaryType" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:complexType name="NameValueType"> <xs:sequence> <xs:element name="Name" type="NameType"/> </xs:sequence> </xs:complexType> <xs:complexType name="KeyValuePairType"> <xs:sequence> <xs:element name="Key" type="xs:string"/> <xs:choice> <xs:element name="IntegerValue" type="xs:integer"/> <xs:element name="DecimalValue" type="xs:decimal"/> <xs:element name="StringValue" type="xs:string"/> <xs:element name="BinaryValue" type="Base64BinaryType"/> <xs:element name="NameValue" type="NameValueType"/> </xs:choice> </xs:sequence> </xs:complexType> <!-- Maybe there is a way to drop a level of nesting... --> <xs:complexType name="KeyValueSetType"> <xs:sequence> <xs:element name="Entry" type="KeyValuePairType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="HeaderType"> <xs:sequence> <xs:element name="Start" type="xs:nonNegativeInteger"/> <xs:element name="Count" type="xs:nonNegativeInteger"/> <xs:element name="BlockSize" type="xs:nonNegativeInteger"/> <xs:element name="Length" type="xs:nonNegativeInteger"/> <xs:element name="ContentDigest" type="Base64BinaryType" minOccurs="0"/> <xs:element name="RootDigest" type="Base64BinaryType" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="NameType"> <xs:sequence> <xs:element name="Component" type="Base64BinaryType" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="Base64BinaryType"> <xs:simpleContent> <xs:extension base="xs:base64Binary"> <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/> </xs:extension> </xs:simpleContent> </xs:complexType> <!-- Binary representation of time, Unix time epoch, units 2**-12 sec --> <!-- The length limit limit of 6 bytes is not actually to be enforced, but it will be a loooooooong time before anyone cares. --> <xs:simpleType name="BinaryTime12"> <xs:restriction base="xs:base64Binary"> <xs:length value="6" fixed="true"/> </xs:restriction> </xs:simpleType> <xs:complexType name="TimestampType"> <xs:simpleContent> <xs:extension base="BinaryTime12"> <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/> </xs:extension> </xs:simpleContent> </xs:complexType> <!-- Binary representation of relative time, relative to "now" --> <xs:complexType name="FinegrainLifetimeType"> <xs:simpleContent> <xs:extension base="BinaryTime12"> <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/> </xs:extension> </xs:simpleContent> </xs:complexType> <!-- Note: SignedInfo was formerly known as ContentAuthenticator --> <xs:complexType name="SignedInfoType"> <xs:sequence> <xs:element name="PublisherPublicKeyDigest" type="DigestType"/> <xs:element name="Timestamp" type="TimestampType"/> <xs:element name="Type" type="ContentType" minOccurs="0" maxOccurs="1"/> <!-- The optional FreshnessSeconds indicates how many seconds a node should wait after the arrival of this ContentObject before marking it as stale. --> <xs:element name="FreshnessSeconds" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <!-- The optional FinalBlockID indicates the identifier of the final block in a sequence of fragments. It should be present in the final block itself, and may also be present in other fragments to provide advanced warning of the end to consumers. The value here should be equal to the last explicit Name Component of the final block. --> <xs:element name="FinalBlockID" type="Base64BinaryType" minOccurs="0" maxOccurs="1"/> <!-- A KeyLocator tells where to find the key to verify this content. This is signed, but may be omitted when the signer is really sure that everyone on the path can find the key. (In theory, does not need to be signed; you can't verify the signature over it until you have the key, and by then you know whether it was correct or not. Not signing it would also allow it to be replaced by updated information known to the forwarder. DoS attacks mounted by omitting it can be mounted whether it is signed or not; as can attacks mounted by modifying it maliciously.) The PublisherKeyID in the SignedInfo is what is used as the real fast selector to identify the signer of this content, not the locator. The reason for leaving the locator in the signed component of the packet is the risk of selective DOS attacks - if credentials attached to a key can be found only by locating it within a certain namespace, one could replace the publisher's locator with another that pointed to the same key but made it seem as if it lacked those credentials. --> <xs:element name="KeyLocator" type="KeyLocatorType" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <!-- Encapsulate some of the possible bits necessary to verify the mapping. --> <xs:complexType name="SignatureType"> <xs:sequence> <!-- We either need to include a digest algorithm or a signature algorithm here. X.509 uses a sigalg up front (and again in the signature), PKCS#7 and XML signature uses a digest up front. Most APIs require us to know the signature algorithm, not the digest algorithm, to begin the verification process. Putting the signature up front along with this algorithm forces us to store the signature till we need it, but allows us to not repeat the algorithm. Expressing just a digest algorithm forces us to assume that a given key can only be used for one algorithm (depending on how we encode the signature). Also, if we digest the content before including it in the signature, we need to know what digest algorithm to use. We either have to assume it's the same one as for the signature, or standard one (with a separate, elided expression of version to allow later change if this one is broken). Right now, take the theory that a) signature algorithms are likely less standard for us than digest algorithms. So specify a digest algorithm here to increase our options of eliding it (default = sha-256). b) for now, sign the content directly rather than re-hashing it, except for aggregated signatures. --> <xs:element name="DigestAlgorithm" type="xs:string" default="2.16.840.1.101.3.4.2.1" minOccurs="0" maxOccurs="1" /> <!-- A Witness is additional information necessary to verify the signature in some algorithms. For elements authenticated using a Merkle Hash Tree, the witness information would be the elements of the hash path through the tree. --> <xs:element name="Witness" type="Base64BinaryType" minOccurs="0" maxOccurs="1" /> <!-- The signature over the name, content authenticator, and content. --> <xs:element name="SignatureBits" type="Base64BinaryType"/> </xs:sequence> </xs:complexType> <xs:complexType name="ContentObjectType"> <xs:sequence> <!-- Signature over name, content authenticator, and the content. Place first to allow grouping of Signature+Name and Name+Authenticator for various applications. --> <xs:element name="Signature" type="SignatureType"/> <xs:element name="Name" type="NameType"/> <xs:element name="SignedInfo" type="SignedInfoType"/> <!-- The content to be signed. As there is no longer a proxy for (digest of) the content explicitly in the authenticator, you need the content itself to verify the signature. Because we generally need to compute the digest of the content anyway, we do so prior to signing. Given that, we either need to pick a standard digest algorithm for content and always use it (presumably SHA-256), at which point we need a version number for messages, in case SHA-256 is broken and we need to change. Or, we need to specify what digest to use in each message. --> <xs:element name="Content" type="Base64BinaryType"/> </xs:sequence> </xs:complexType> <!-- Sometimes we just need to talk about mappings (everything needed to authenticate a name) without the content itself. Since we have moved the proxy for the content out of the content authenticator, this information is no longer sufficient to authenticate the content. We will have to look carefully at where and how it is used. --> <xs:complexType name="CompleteNameType"> <xs:sequence> <xs:element name="Signature" type="SignatureType"/> <xs:element name="Name" type="NameType"/> <xs:element name="SignedInfo" type="SignedInfoType"/> </xs:sequence> </xs:complexType> <!-- XXX - figure out how to use this type instead of duplicating the choice inline. --> <xs:complexType name="PublisherDigestType"> <xs:choice> <xs:element name="PublisherPublicKeyDigest" type="DigestType"/> <xs:element name="PublisherCertificateDigest" type="DigestType"/> <xs:element name="PublisherIssuerKeyDigest" type="DigestType"/> <xs:element name="PublisherIssuerCertificateDigest" type="DigestType"/> </xs:choice> </xs:complexType> <xs:complexType name="InterestType"> <xs:sequence> <xs:element name="Name" type="NameType"/> <xs:element name="MinSuffixComponents" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="MaxSuffixComponents" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:choice minOccurs="0" maxOccurs="1"> <xs:element name="PublisherPublicKeyDigest" type="DigestType"/> <xs:element name="PublisherCertificateDigest" type="DigestType"/> <xs:element name="PublisherIssuerKeyDigest" type="DigestType"/> <xs:element name="PublisherIssuerCertificateDigest" type="DigestType"/> </xs:choice> <xs:element name="Exclude" type="ExcludeType" minOccurs="0" maxOccurs="1"/> <xs:element name="ChildSelector" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="AnswerOriginKind" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="Scope" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="InterestLifetime" type="FinegrainLifetimeType" minOccurs="0" maxOccurs="1"/> <xs:element name="Nonce" type="Base64BinaryType" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:complexType name="ExcludeType"> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="1"> <xs:element name="Any" type="EmptyType"/> <xs:element name="Bloom" type="Base64BinaryType"/> </xs:choice> <xs:sequence minOccurs="0" maxOccurs="unbounded"> <xs:element name="Component" type="Base64BinaryType"/> <xs:choice minOccurs="0" maxOccurs="1"> <xs:element name="Any" type="EmptyType"/> <xs:element name="Bloom" type="Base64BinaryType"/> </xs:choice> </xs:sequence> </xs:sequence> </xs:complexType> <xs:complexType name="EmptyType"> <xs:sequence/> </xs:complexType> <xs:complexType name="DigestType"> <xs:simpleContent> <xs:extension base="SHA256Digest"> <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="SHA256Digest"> <xs:restriction base="xs:base64Binary"> <!-- SHA-256 digest --> <xs:length value="32" fixed="true"/> </xs:restriction> </xs:simpleType> <xs:complexType name="ContentType"> <xs:simpleContent> <xs:extension base="ContentTypeType"> <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="ContentTypeType"> <xs:restriction base="xs:base64Binary"> <xs:length value="3" fixed="true"/> <xs:enumeration value="DATA"/> <!-- default when Type element is absent --> <xs:enumeration value="ENCR"/> <!-- content is encrypted --> <xs:enumeration value="GONE"/> <!-- whiteout marker --> <xs:enumeration value="KEY/"/> <!-- public key --> <xs:enumeration value="LINK"/> <!-- link --> <xs:enumeration value="NACK"/> <!-- no content at this time --> </xs:restriction> </xs:simpleType> <xs:complexType name="KeyLocatorType"> <xs:sequence> <xs:choice> <xs:element name="Key" type="Base64BinaryType"/> <xs:element name="Certificate" type="Base64BinaryType"/> <xs:element name="KeyName" type="KeyNameType"/> </xs:choice> </xs:sequence> </xs:complexType> <xs:complexType name="KeyNameType"> <xs:sequence> <xs:element name="Name" type="NameType"/> <xs:choice minOccurs="0" maxOccurs="1"> <xs:element name="PublisherPublicKeyDigest" type="DigestType"/> <xs:element name="PublisherCertificateDigest" type="DigestType"/> <xs:element name="PublisherIssuerKeyDigest" type="DigestType"/> <xs:element name="PublisherIssuerCertificateDigest" type="DigestType"/> </xs:choice> </xs:sequence> </xs:complexType> <xs:element name="FaceInstance" type="FaceInstanceType"/> <xs:complexType name="FaceInstanceType"> <xs:sequence> <xs:element name="Action" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="PublisherPublicKeyDigest" type="DigestType" minOccurs="0" maxOccurs="1"/> <xs:element name="FaceID" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="IPProto" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="Host" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="Port" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="MulticastInterface" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="MulticastTTL" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="FreshnessSeconds" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:element name="ForwardingEntry" type="ForwardingEntryType"/> <xs:complexType name="ForwardingEntryType"> <xs:sequence> <xs:element name="Action" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="Name" type="NameType" minOccurs="0" maxOccurs="1"/> <xs:element name="PublisherPublicKeyDigest" type="DigestType" minOccurs="0" maxOccurs="1"/> <xs:element name="FaceID" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="ForwardingFlags" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> <xs:element name="FreshnessSeconds" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <xs:complexType name="StatusResponseType"> <xs:sequence> <xs:element name="StatusCode" type="xs:nonNegativeInteger" minOccurs="1" maxOccurs="1"/> <xs:element name="StatusText" type="xs:string" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:schema>