RFC 4910

Robust XML Encoding Rules (RXER) for Abstract Syntax Notation One (ASN.1)

📅 published July 2007, from ietf

🎀 RFC 4910: Robust XML Encoding Rules (RXER) for ASN.1 🎀

Okay bestie, so this one is from July 2007 🌸. It's written by S. Legg (from eB2Bcom) and D. Prager, and it's labeled Experimental 🧪. That means it's a trial protocol, not an official Internet standard. The header doesn't list any Obsoletes or Updates, so it doesn't replace or change any other RFC. The "Network Working Group" is the IETF group that published it 💅.

Status of This Memo ✨

This memo describes an Experimental Protocol for the Internet community, which means it's not an Internet standard of any kind 🧪. The authors want feedback and ideas for making it better, and anyone can freely share it with no limits 💖.

Copyright (C) The IETF Trust (2007).

Abstract 🦋

This document defines a set of ASN.1 encoding rules called the Robust XML Encoding Rules, or RXER 🎀. They take any ASN.1 data type and turn its values into an XML representation 💅. It also defines how to make a canonical RXER encoding, which is the one-true-version of that output 👑.

Table of Contents 📚

   1. Introduction ....................................................3
   2. Conventions .....................................................4
   3. Definitions .....................................................5
   4. Additional Basic Types ..........................................6
      4.1. The Markup Type ............................................6
           4.1.1. Self-Containment ....................................9
           4.1.2. Normalization for Canonical Encoding Rules .........12
      4.2. The AnyURI Type ...........................................13
      4.3. The NCName Type ...........................................14
      4.4. The Name Type .............................................14
      4.5. The QName Type ............................................14
   5. Expanded Names for ASN.1 Types .................................15
   6. Encoding Rules .................................................17
      6.1. Identifiers ...............................................19
      6.2. Component Encodings .......................................20
           6.2.1. Referenced Components ..............................20
           6.2.2. Element Components .................................20
                  6.2.2.1. Namespace Properties for Elements .........22
                  6.2.2.2. Namespace Prefixes for Element Names ......24
           6.2.3. Attribute Components ...............................25
                  6.2.3.1. Namespace Prefixes for Attribute Names ....26
           6.2.4. Unencapsulated Components ..........................26
           6.2.5. Examples ...........................................27
      6.3. Standalone Encodings ......................................28
      6.4. Embedded ASN.1 Values .....................................28
      6.5. Type Referencing Notations ................................32
      6.6. TypeWithConstraint, SEQUENCE OF Type, and SET OF Type .....33
      6.7. Character Data Translations ...............................34
           6.7.1. Restricted Character String Types ..................35
           6.7.2. BIT STRING .........................................36
           6.7.3. BOOLEAN ............................................38
           6.7.4. ENUMERATED .........................................38
           6.7.5. GeneralizedTime ....................................39
           6.7.6. INTEGER ............................................41
           6.7.7. NULL ...............................................42
           6.7.8. ObjectDescriptor ...................................43
           6.7.9. OBJECT IDENTIFIER and RELATIVE-OID .................43
           6.7.10. OCTET STRING ......................................43
           6.7.11. QName .............................................44
                  6.7.11.1. Namespace Prefixes for Qualified Names ...44
           6.7.12. REAL ..............................................45
           6.7.13. UTCTime ...........................................46
           6.7.14. CHOICE as UNION ...................................47
           6.7.15. SEQUENCE OF as LIST ...............................50
      6.8. Combining Types ...........................................50
           6.8.1. CHARACTER STRING ...................................51
           6.8.2. CHOICE .............................................51
           6.8.3. EMBEDDED PDV .......................................52
           6.8.4. EXTERNAL ...........................................52
           6.8.5. INSTANCE OF ........................................52
           6.8.6. SEQUENCE and SET ...................................52
           6.8.7. SEQUENCE OF and SET OF .............................54
           6.8.8. Extensible Combining Types .........................55
                  6.8.8.1. Unknown Elements in Extensions ............55
                  6.8.8.2. Unknown Attributes in Extensions ..........59
      6.9. Open Type .................................................60
      6.10. Markup ...................................................61
      6.11. Namespace Prefixes for CRXER .............................63
      6.12. Serialization ............................................65
           6.12.1. Non-Canonical Serialization .......................65
           6.12.2. Canonical Serialization ...........................68
           6.12.3. Unicode Normalization in XML Version 1.1 ..........70
      6.13. Syntax-Based Canonicalization ............................70
   7. Transfer Syntax Identifiers ....................................71
      7.1. RXER Transfer Syntax ......................................71
      7.2. CRXER Transfer Syntax .....................................71
   8. Relationship to XER ............................................71
   9. Security Considerations ........................................73
   10. Acknowledgements ..............................................74
   11. IANA Considerations ...........................................75
   12. References ....................................................75
      12.1. Normative References .....................................75
      12.2. Informative References ...................................77
   Appendix A. Additional Basic Definitions Module ...................78

1. Introduction ✨

Okay so this doc defines the Robust XML Encoding Rules (RXER) for ASN.1 [X.680] 🎀. RXER takes an ASN.1 value and produces an XML representation of it, following [XML10][XML11] 💖.

Here's the vibe: an ASN.1 value is kind of like the content and attributes of an XML element, or sometimes just one attribute's value 🦋. An RXER encoding is the well-formed and valid content and attributes of an element (or an attribute value) in an XML document, and that document has to follow XML namespaces [XMLNS10][XMLNS11] 💅. Simple types like PrintableString, INTEGER, and BOOLEAN become character data or attribute values 🌸. The combining types (SET, SEQUENCE, SET OF, SEQUENCE OF, and CHOICE) become element content and attributes 🧚. The names of those attributes and child elements usually come from the identifiers of the components in the combining type definitions, so elements and attributes line up with the NamedType notation ✨.

RXER leaves some formatting up to the encoder 🍓. That means one ASN.1 value can have more than one RXER encoding, and that's totally allowed 🙈. But this doc also defines a restricted version called the Canonical Robust XML Encoding Rules (CRXER), and CRXER gives you exactly one unique encoding for each value 👑. Obviously a CRXER encoding is also a valid RXER encoding 💜. The CRXER rules are sprinkled in between the RXER rules, so keep an eye out 👀.

Also, "ASN.1 value" does not mean a Basic Encoding Rules (BER) [X.690] encoding 🙅‍♀️. The ASN.1 value is an abstract idea that doesn't depend on any particular encoding, and BER is just one of the ways to encode it 💫. This doc is simply a different way to encode the same value 🦋.

A separate doc [RXEREI] defines encoding instructions [X.680-1] you can put in an ASN.1 spec to tweak how RXER encodes values 💅. For example, you can make a component of a combining type show up as an attribute instead of a child element 🎀. An older ASN.1 spec won't have any RXER encoding instructions, so you can ignore any mention of them in this doc when you're working with those specs 🙌. And encoding instructions meant for other encoding rules have no effect on RXER encodings at all 🫶.

2. Conventions 📝

Here's how the key words work in this doc 🔥. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" are meant exactly as described in BCP 14, RFC 2119 [BCP14] 🌈. The key word "OPTIONAL" is only ever used with its ASN.1 meaning 💅.

A reference to an ASN.1 production [X.680] (like Type or NamedType) just means the text in an ASN.1 spec that matches that production 📚.

RXER uses definitions from the XML Information Set (Infoset) [INFOSET] 🧠. Property names of information items are shown in square brackets, like [local name] 🎀. Literal values of Infoset properties are wrapped in double quotes, but the quotes themselves aren't part of the value 💖. From here on, "information item" gets shortened to "item", so "element information item" becomes "element item" ✨. When the doc just says "element" or "attribute" (no "item"), it means the actual thing in an XML document, not the information item 🦋.

Literal character strings used in an RXER encoding are shown in double quotes, but again, the quotes aren't part of the value and don't show up in the encoding 🌸.

This doc uses the prefix asnx: (from [XMLNS10][XMLNS11]) for the namespace name urn:ietf:params:xml:ns:asnx 🧚. It uses the prefix xs: for http://www.w3.org/2001/XMLSchema, and xsi: for http://www.w3.org/2001/XMLSchema-instance 💅. In real life, though, any valid namespace prefixes are fine in non-canonical RXER encodings 🙌. CRXER prefixes are generated in a predictable way instead 👑.

The encoding instructions [X.680-1] named in this spec are the RXER encoding instructions from [RXEREI] 🎀.

Whenever this doc talks about the Markup, AnyURI, NCName, Name, and QName ASN.1 types, it means the ones described in Section 4 and gathered into the AdditionalBasicDefinitions module in Appendix A 🌈. Any rules tied to those references don't apply to types with the same names that show up in other ASN.1 modules 🙈.

Code points for characters [UCS][UNICODE] are written in the Unicode style U+n, where n is four to six hexadecimal digits 🔤. For example, the space character is U+0020 🍓.

3. Definitions ✨

Okay bestie, let's get into the vocab. These definitions are the foundation for everything else, so I'm being extra careful with them. 🎀

White space character: A white space character is a space (U+0020), tab (U+0009), carriage return (U+000D), or line feed (U+000A) character. 🫶

White space: White space is a sequence of one or more white space characters. Simple, but iconic. 💅

Line break: A line break is any sequence of characters that is normalized to a line feed by XML End-of-Line Handling [XML10][XML11]. 🦋

Serialized white space: Serialized white space is a sequence of one or more white space characters and/or line breaks. So it's basically white space plus line breaks, mixed together. 🌸

Declaring the default namespace: A namespace declaration attribute item is declaring the default namespace if the [prefix] of the attribute item has no value, the [local name] of the attribute item is xmlns and the [normalized value] is not empty. This is the "I'm setting the default" move. 👑

Undeclaring the default namespace: A namespace declaration attribute item is undeclaring the default namespace if the [prefix] of the attribute item has no value, the [local name] of the attribute item is xmlns and the [normalized value] is empty (i.e., xmlns=""). So it's the same thing, but with an empty value. Iykyk. 🙈

Canonical namespace prefix: A canonical namespace prefix is an NCName [XMLNS10] beginning with the letter 'n' (U+006E) followed by a non-negative number string. A non-negative number string is either the digit character '0' (U+0030), or a non-zero decimal digit character (U+0031-U+0039) followed by zero, one, or more of the decimal digit characters '0' to '9' (U+0030-U+0039). Ngl this one is giving precision. 🧚

For convenience, a CHOICE type where the ChoiceType is subject to a UNION encoding instruction will be referred to as a UNION type, and a SEQUENCE OF type where the SequenceOfType is subject to a LIST encoding instruction will be referred to as a LIST type. So a UNION type is just a shorter nickname, and so is a LIST type. Easy nicknames, main character energy. ✨


4. Additional Basic Types

This section defines an ASN.1 type for representing markup in abstract values, as well as basic types that are useful in encoding instructions [RXEREI] and other related specifications [ASN.X]. Basically it's the toolbox section. 🧰

The ASN.1 definitions in this section are consolidated in the AdditionalBasicDefinitions ASN.1 module in Appendix A. So if you want all of them in one place, go to Appendix A. 💜

4.1. The Markup Type

A value of the Markup ASN.1 type holds the [prefix], [attributes], [namespace attributes], and [children] of an element item, i.e., the content and attributes of an element. Think of it as the whole element, packaged up. 🎀

RXER has special provisions for encoding values of the Markup type (see Section 6.10). For other encoding rules, a value of the Markup type is encoded according to the following ASN.1 type definition (with AUTOMATIC TAGS):

   Markup ::= CHOICE {
       text    SEQUENCE {
           prolog      UTF8String (SIZE(1..MAX)) OPTIONAL,
           prefix      NCName OPTIONAL,
           attributes  UTF8String (SIZE(1..MAX)) OPTIONAL,
           content     UTF8String (SIZE(1..MAX)) OPTIONAL
       }
   }

The text alternative of the Markup CHOICE type provides for the [prefix], [attributes], [namespace attributes], and [children] of an element item to be represented as serialized XML using the UTF-8 character encoding [UTF-8]. So it's the XML, written out as text, in UTF-8. 🌈

Aside: The CHOICE allows for one or more alternative compact representations of the content and attributes of an element to be supported in a future specification. So there could be more options later, bestie. 🔥

With respect to some element item whose content and attributes are represented by a value of the text alternative of the Markup type:

(1) the prolog component of the value contains text that, after line break normalization, conforms to the XML prolog production [XML10][XML11],

(2) the prefix component is absent if the [prefix] of the element item has no value; otherwise, the prefix component contains the [prefix] of the element item,

(3) the attributes component of the value contains an XML serialization of the [attributes] and [namespace attributes] of the element item, if any, with each attribute separated from the next by serialized white space, and

(4) the content component is absent if the [children] property of the element item is empty; otherwise, the content component of the value contains an XML serialization of the [children] of the element item.

All the components of a value of the Markup type MUST use the same version of XML, either version 1.0 [XML10] or version 1.1 [XML11]. If XML version 1.1 is used, then the prolog component MUST be present and MUST have an XMLDecl for version 1.1. If the prolog component is absent, then XML version 1.0 is assumed. So no mixing versions, and 1.0 is the default if there's no prolog. 🦋

If the prefix component is present, then there MUST be a namespace declaration attribute in the attributes component that defines that namespace prefix (since an element whose content and attributes are described by a value of Markup is required to be self-contained; see Section 4.1.1). Basically, if you bring a prefix, you have to bring its declaration too. 🎀

Note that the prefix component is critically related to the NamedType that has Markup as its type. If a Markup value is extracted from one enclosing abstract value and embedded in another enclosing abstract value (i.e., becomes associated with a different NamedType), then the prefix may no longer be appropriate, in which case it will need to be revised. It may also be necessary to add another namespace declaration attribute to the attributes component so as to declare a new namespace prefix. So if you move a Markup value somewhere new, the prefix might need a glow-up. 💅

Leading and/or trailing serialized white space is permitted in the attributes component. A value of the attributes component consisting only of serialized white space (i.e., no actual attributes) is permitted. So extra spaces are allowed, even if there are no attributes at all. 🌸

The attributes and content components MAY contain entity references [XML10][XML11]. If any entity references are used (other than references to the predefined entities), then the prolog component MUST be present and MUST contain entity declarations for those entities in the internal or external subset of the document type definition. So you can use entities, but if they're not predefined, you need to declare them in the prolog. No surprise entities, periodt. 🙈

Example

Given the following ASN.1 module:

   MyModule DEFINITIONS
   AUTOMATIC TAGS ::= BEGIN

   Message ::= SEQUENCE {
       messageType   INTEGER,
       messageValue  Markup
   }

   ENCODING-CONTROL RXER

       TARGET-NAMESPACE "http://example.com/ns/MyModule"

       COMPONENT message Message
           -- a top-level NamedType

   END

consider the following XML document:

   <?xml version='1.0'?>
   <!DOCTYPE message [
       <!ENTITY TRUE 'true'>
   ]>
   <message>
    <messageType>1</messageType>
    <messageValue xmlns:ns="http://www.example.com/ABD"
                  ns:foo="1" bar="0">
     <this>&TRUE;</this>
     <that/>

    </messageValue>
   </message>

A Markup value corresponding to the content and attributes of the <messageValue> element is, in ASN.1 value notation [X.680] (where "lf" represents the line feed character):

   text:{
       prolog     { "<?xml version='1.0'?>", lf,
                    "<!DOCTYPE message [", lf,
                    "    <!ENTITY TRUE 'true'>", lf,
                    "]>", lf },
       attributes { " xmlns:ns=""http://www.example.com/ABD""",
                    lf,
                    "               ns:foo=""1"" bar=""0""" },
       content    { lf,
                    "  <this>&TRUE;</this>", lf,
                    "  <that/>", lf, " " }
   }

The following Markup value is an equivalent representation of the content and attributes of the <messageValue> element:

   text:{
       attributes {
                    "bar=""0"" ns:foo=""1"" ",
                    "xmlns:ns=""http://www.example.com/ABD""" },
       content    { lf,
                    "  <this>true</this>", lf,
                    "  <that/>", lf, " " }
   }

Two versions, same vibe: the second one just swaps the entity for its value. ✨

By itself, the Markup ASN.1 type imposes no data type restriction on the markup contained by its values and is therefore analogous to the XML Schema anyType [XSD1]. So on its own, it accepts basically anything. Wild, but that's the point. 🌈

There is no ASN.1 basic notation that can directly impose the constraint that the markup represented by a value of the Markup type must conform to the markup allowed by a specific type definition. However, certain encoding instructions (i.e., the reference encoding instructions [RXEREI]) have been defined to have this effect. So if you want that restriction, you'll need those encoding instructions to get it. 🧚

4.1.1. Self-Containment ✨

okay bestie, so an element, its attributes, and its content (including any descendent elements) can contain qualified names [XMLNS10][XMLNS11] 💅. They can show up as element and attribute names, inside attribute values, and as character data. Which namespace prefix maps to which namespace name is potentially decided by the namespace declaration attributes on the ancestor elements. In Infoset land, those get inherited as namespace items in the [in-scope namespaces] 🦋

here's the tea 🫖 when you have a Markup value and you don't fully know the data type of the element item, you can't be 100% sure which of the namespace items inherited from the [in-scope namespaces] of the [parent] element item actually matter for reading the Markup value 😭. The safe and easy move would be to assume ALL of them matter and keep every single one inside the Markup value. Then, when you re-encode the Markup value, any retained namespace items that aren't in the [in-scope namespaces] of the enclosing element item in the new encoding could be made to show up by outputting matching namespace declaration attribute items in the [namespace attributes] of that enclosing element item 🌸

from the receiver's side of the new encoding, this makes the set of attribute items in the [namespace attributes] represented by the Markup value bigger 📈

and it gets worse 🙈 there's no guarantee the sender of the new encoding recreated the original namespace declaration attributes on the ancestors. So the [in-scope namespaces] of the enclosing element item will probably have new namespace declarations, which the receiver will keep and pass along in the [namespace attributes] when it re-encodes the Markup value in turn.

this unbounded growth in the set of attribute items in the [namespace attributes] totally defeats any attempt at a canonical encoding 💀

that's why we have the principle of self-containment 🧚 An element item (the subject element item) is self-contained if the constraints of Namespaces in XML 1.0 [XMLNS10] are satisfied (basically, prefixes are properly declared) AND none of the following bindings are determined by a namespace declaration attribute item in the [namespace attributes] of an ancestor element item of the subject element item:

  1. the binding between the [prefix] and [namespace name] of the subject element item,
  2. the binding between the [prefix] and [namespace name] of any descendant element item of the subject element item,
  3. the binding between the [prefix] and [namespace name] of any attribute item in the [attributes] of the subject element item or the [attributes] of any descendant element item of the subject element item,
  4. the binding between the namespace prefix and namespace name of any qualified name in the [normalized value] of any attribute item in the [attributes] of the subject element item or the [attributes] of any descendant element item of the subject element item, or
  5. the binding between the namespace prefix and namespace name of any qualified name represented by a series of character items (ignoring processing instruction and comment items) in the [children] of the subject element item or the [children] of any descendant element item of the subject element item.
Aside: If an element is self-contained, then separating the element from its parent does not change the semantic interpretation of its name and any names in its content and attributes. 🫶

now the strict part 🔥 A supposedly self-contained element in a received RXER encoding that is in fact NOT self-contained SHALL be treated as an ASN.1 constraint violation 🚨

Aside: ASN.1 does not require an encoding with a constraint violation to be immediately rejected. However, the constraint violation must be reported at some point, possibly in a separate validation step. 🍓

implementors, listen up 👂 an RXER decoder can detect SOME violations of self-containment, but not all. For example, it can catch element and attribute names that depend on namespace declarations in the ancestors of a supposedly self-contained element. Similarly, where type information is available, it can catch qualified names in character data that depend on the namespace declarations of ancestor elements. BUT type information isn't always available, so some qualified names will slip past the constraint checking 🙃 So the onus is on the creator of the original encoding to make sure the element items that are required to be self-contained really ARE completely self-contained 🎀

an element item whose content and attributes are described by a value of the Markup type MUST be self-contained 👑

Aside: The procedures in Section 6 take account of the requirements for self-containment, so an RXER encoder following these procedures will not create violations of self-containment. ✨

4.1.2. Normalization for Canonical Encoding Rules 🌈

so implementations get some latitude in how they represent the content and attributes of an element as an abstract value of the Markup type 🦋 part of the reason is that an Infoset can have different equivalent serializations. For example, the order of attributes, and how much and what kind of white space sits between attributes, don't matter to the Infoset representation. The content can also include one or more elements that correspond to an ASN.1 top-level NamedType or have a data type that is an ASN.1 type. For those elements, you only need to preserve the abstract value, and one abstract value can have different Infoset representations 💖

these two traits mean that when an RXER encoded value of the Markup type gets decoded, the components of the recovered Markup value might not match the original value exactly, character for character. The recovered value will still be semantically equivalent though ✨

BUT 😬 canonical ASN.1 encoding rules like the Distinguished Encoding Rules (DER) and the Canonical Encoding Rules (CER) [X.690] encode Markup values according to the ASN.1 definition of the Markup type, and they depend on character-for-character preservation of string values. That requirement can be handled if Markup values get normalized when they're encoded using a set of canonical encoding rules 🧁

Aside: The RXER encoding and decoding of a Markup value might change the character string components of the value from the perspective of BER, but there will be a single, repeatable encoding for DER. 💜

a value of the Markup type will appear as the content and attributes of an element in an RXER encoding. When that value is encoded using a set of ASN.1 canonical encoding rules OTHER than CRXER, the components of the text alternative of the value MUST be normalized as follows, by reference to the element as it would appear in a CRXER encoding 🫶

  1. The value of the prolog component SHALL be the XMLDecl <?xml version="1.1"?> with no other leading or trailing characters.
  2. If the element's name is unprefixed in the CRXER encoding, then the prefix component SHALL be absent. Otherwise, the value of the prefix component SHALL be the prefix of the element's name in the CRXER encoding.
  3. Take the character string representing the element's attributes, including namespace declarations, in the CRXER encoding. If the first attribute is a namespace declaration that undeclares the default namespace (i.e., xmlns=""), then remove it. Remove any leading space characters. If the resulting character string is empty, then the attributes component SHALL be absent. Otherwise, the value of the attributes component SHALL be the resulting character string.
Aside: Note that the attributes of an element can change if an RXER encoding is re-encoded in CRXER. 🦋
  1. If the element has no characters between the start-tag and end-tag [XML11] in the CRXER encoding, then the content component SHALL be absent. Otherwise, the value of the content component SHALL be identical to the character string in the CRXER encoding bounded by the element's start-tag and end-tag.
Aside: A consequence of invoking the CRXER encoding is that any nested element corresponding to an ASN.1 top-level NamedType, or indeed the element itself, will be normalized according to its ASN.1 value rather than its Infoset representation. The same goes for an element whose data type is an ASN.1 type. Section 6.4 describes how these situations can arise. 🌸
Aside: It is only through values of the Markup type that processing instructions and comments can appear in CRXER encodings. 🧚

if an application uses DER but has NO knowledge of RXER, then it won't know to normalize values of the Markup type 🙈 If RXER gets deployed into an environment containing applications like that, then Markup values SHOULD be normalized, even when encoding using non-canonical encoding rules. 🔥


4.2. The AnyURI Type 🌷

a value of the AnyURI ASN.1 type is a character string conforming to the format of a Uniform Resource Identifier (URI) [URI] 🌐

AnyURI ::= UTF8String (CONSTRAINED BY
            { -- conforms to the format of a URI -- })

4.3. The NCName Type 🍑

a value of the NCName ASN.1 type is a character string conforming to the NCName production of Namespaces in XML 1.0 [XMLNS10] 🦋

NCName ::= UTF8String (CONSTRAINED BY
               { -- conforms to the NCName production of
                 -- Namespaces in XML 1.0 -- })
Aside: The NCName production for Namespaces in XML 1.1 [XMLNS11] allows a wider range of characters than the NCName production for Namespaces in XML 1.0. The NCName type for ASN.1 is currently restricted to the characters allowed by Namespaces in XML 1.0, though this may change in a future specification of RXER. 💅

4.4. The Name Type 💜

a value of the Name ASN.1 type is a character string conforming to the Name production of XML version 1.0 [XML10] ✨

Name ::= UTF8String (CONSTRAINED BY
               { -- conforms to the Name production of XML -- })

4.5. The QName Type 👑

a value of the QName ASN.1 type describes an expanded name [XMLNS10], which shows up as a qualified name [XMLNS10] in an RXER encoding 🎀

RXER has special provisions for encoding values of the QName type (see Section 6.7.11). For other encoding rules, a value of the Qname type is encoded according to the following ASN.1 type definition (with AUTOMATIC TAGS) 🧚

QName ::= SEQUENCE {
    namespace-name  AnyURI OPTIONAL,
    local-name      NCName
}

the namespace-name component holds the namespace name of the expanded name. If the namespace name of the expanded name has no value, then the namespace-name component is absent. 🌈

Aside: A namespace name can be associated with ASN.1 types and top-level NamedType instances by using the TARGET-NAMESPACE encoding instruction. 🦋

the local-name component holds the local name of the expanded name. 💖

5. Expanded Names for ASN.1 Types 🎀

okay so a TypeAssignment in ASN.1 links a typereference to a Type 💖 For RXER and Abstract Syntax Notation X (ASN.X) [ASN.X], a TypeAssignment also counts as associating an expanded name [XMLNS10] with the Type. The local name of that expanded name is the typereference on the left-hand side of the TypeAssignment. If the target namespace [RXEREI] of the ASN.1 module where the TypeAssignment is defined is not absent, then the namespace name of the expanded name is that target namespace. Otherwise, the namespace name of the expanded name has no value ✨

A Type that is a BuiltinType or ReferencedType matching one of the productions in Table 1 is treated as a reference to a built-in ASN.1 type. These built-in types get expanded names too 🌸 In each case, the local name is whatever Table 1 says, and the namespace name is "urn:ietf:params:xml:ns:asnx".

Table 1: Local Names for Built-in Types

   +------------------------------------+-------------------+
   | ASN.1 Production                   | Local Name        |
   +====================================+===================+
   | BitStringType                      |                   |
   |    without a NamedBitList          | BIT-STRING        |
   +------------------------------------+-------------------+
   | BooleanType                        | BOOLEAN           |
   +------------------------------------+-------------------+
   | CharacterStringType                |                   |
   |    RestrictedCharacterStringType   |                   |
   |       BMPString                    | BMPString         |
   |       GeneralString                | GeneralString     |
   |       GraphicString                | GraphicString     |
   |       IA5String                    | IA5String         |
   |       ISO646String                 | ISO646String      |
   |       NumericString                | NumericString     |
   |       PrintableString              | PrintableString   |
   |       TeletexString                | TeletexString     |
   |       T61String                    | T61String         |
   |       UniversalString              | UniversalString   |
   |       UTF8String                   | UTF8String        |
   |       VideotexString               | VideotexString    |
   |       VisibleString                | VisibleString     |
   |    UnrestrictedCharacterStringType | CHARACTER-STRING  |
   +------------------------------------+-------------------+
   | EmbeddedPDVType                    | EMBEDDED-PDV      |
   | ExternalType                       | EXTERNAL          |
   +------------------------------------+-------------------+
   | IntegerType                        |                   |
   |    without a NamedNumberList       | INTEGER           |
   +------------------------------------+-------------------+
   | NullType                           | NULL              |
   | ObjectIdentifierType               | OBJECT-IDENTIFIER |
   | OctetStringType                    | OCTET-STRING      |
   | RealType                           | REAL              |
   | RelativeOIDType                    | RELATIVE-OID      |
   +------------------------------------+-------------------+
   | UsefulType                         |                   |
   |    GeneralizedTime                 | GeneralizedTime   |
   |    UTCTime                         | UTCTime           |
   |    ObjectDescriptor                | ObjectDescriptor  |
   +------------------------------------+-------------------+

When the expanded name for an ASN.1 type gets used in an RXER encoding, it shows up as a qualified name [XMLNS10][XMLNS11]. The namespace prefix for that qualified name is decided according to Section 6.7.11.1 🦋

If a compatible XML Schema translation of an ASN.1 specification is provided (see Section 6.4), then that schema SHOULD associate the same expanded name with the XML Schema translation of an ASN.1 type 💅

Definition (namespace-qualified reference): An ASN.1 Type is a namespace-qualified reference if one of the following applies:

(1) the Type is a typereference (not a DummyReference) or an ExternalTypeReference in a DefinedType in a ReferencedType, the ASN.1 module in which the referenced type is defined has a TARGET-NAMESPACE encoding instruction, the referenced type is not directly or indirectly an open type [X.681], and the referenced type is not directly or indirectly the Markup type (Section 4.1), or

(2) the Type is a BuiltinType or ReferencedType that is one of the productions in Table 1.

The type definition referenced by a namespace-qualified reference will have an expanded name with a value for the namespace name 👑


6. Encoding Rules 🧚

With RXER, ASN.1 abstract values are treated uniformly as analogous to the content and attributes of an element, or just an attribute value. They are not complete elements or attributes in their own right. Elements and attributes in an RXER encoding are defined by ASN.1 NamedType notation. Since elements are the fundamental discrete structures of an XML document, the idea of a NamedType having a value that can be encoded is useful for descriptive purposes (particularly for describing the RXER encoding of values of the ASN.1 combining types). There is no conceptual basis in X.680 [X.680] for talking about the value of a NamedType, or its encoding, so the terminology is introduced here 🌈

Definition (value of a NamedType): An abstract value of the Type in a NamedType is also a value of that NamedType. The RXER encoding of the value of a NamedType is the RXER encoding of the abstract value of the Type encapsulated according to the definition of that NamedType.

This document does not refer to a value of a NamedType as being an abstract value, so as to stay consistent with X.680. An abstract value is exclusively a value of an ASN.1 type 🫶

A complete ASN.1 encoding is traditionally the encoding of an abstract value, but it is more natural to think of an XML document as being the RXER encoding of a value of a NamedType (because an XML document has a single root element that contains all the other elements and attributes). The ASN.1 basic notation does not allow a NamedType to appear on its own, outside of an enclosing combining type. That is, the basic notation does not have a concept analogous to a global element or attribute definition. However, an ASN.1 specification may use an RXER encoding control section [RXEREI] to define global elements and attributes using the NamedType notation. A NamedType that is not contained in an ASN.1 type definition is called a top-level NamedType [RXEREI]. Thus, an RXER encoding would typically be described as the encoding of a value of a top-level NamedType 🍓

Section 6.2 describes how a value of a NamedType is encoded. Section 6.3 defines an alternative method for encoding the document element of an XML document when a top-level NamedType is not specified. Section 6.4 describes how the encodings of ASN.1 values can be embedded in an XML document where the other parts of the document are validated by an XML Schema 💜

The RXER encoding of an abstract value, or the encoding of a value of a NamedType, is described as a translation into a synthetic Infoset, which is then serialized as XML. This separation has been chosen for descriptive convenience and is not intended to impose any particular architecture on RXER implementations. An RXER encoder is free to encode an ASN.1 value directly to XML, provided the result is equivalent to following the two stage procedure described in this document ✨

The process of translating an abstract value into an Infoset is described as producing either:

(1) a string of characters that either becomes part of the [normalized value] of an attribute item or becomes character items among the [children] of an enclosing element item, or

(2) a collection of zero or more attribute items contributing to the [attributes] of an enclosing element item, plus a series of zero or more character, element, processing instruction (PI), or comment items contributing to the [children] of the enclosing element item.

NamedType notation in the ASN.1 specification controls whether the translation of an abstract value is encapsulated in an element item or in an attribute item 🌸

Sections 6.5 to 6.10 describe the translation of abstract values into an Infoset for each of the ASN.1 type notations. Section 6.11 describes post-processing of namespace prefixes for CRXER encodings. Section 6.12 specifies how the Infoset translation is serialized as XML 🦋

This specification assumes that the COMPONENTS OF transformation specified in X.680, Clause 24.4 [X.680] has already been applied to all relevant types.

Examples of RXER encodings in the following sections use a <value> start-tag and </value> end-tag to hold attributes and delimit the content. These start-tags and end-tags are for illustration only and are not part of the encoding of an abstract value. In normal use, the name of the enclosing element is provided by the context of the type of the abstract value, e.g., a NamedType in an enclosing SEQUENCE type 💅

An RXER decoder is a conforming XML processor [XML10][XML11] 👑

6.1. Identifiers

An identifier, as defined in ASN.1 notation (Clause 11.3 of X.680 [X.680]), is a character string that begins with a Latin lowercase letter (U+0061-U+007A) and is followed by zero, one or more Latin letters (U+0041-U+005A, U+0061-U+007A), decimal digits (U+0030-U+0039), and hyphens (U+002D). A hyphen is not permitted to be the last character, and a hyphen is not permitted to be followed by another hyphen. The case of letters in an identifier is always significant 🔥

ASN.1 identifiers are used for the [local name] of attribute and element items, and may also appear in the character data content of elements or the values of attributes. RXER encoding instructions can be used to substitute an NCName [XMLNS10] for an identifier 🫶

6.2. Component Encodings

The translation of the value of a NamedType is the translation of the abstract value of the Type of the NamedType, encapsulated according to the definition of that NamedType. This section specifies the form of this encapsulation 🌈

6.2.1. Referenced Components

A value of a NamedType that is subject to a COMPONENT-REF encoding instruction is translated as a value of the top-level NamedType referenced by the encoding instruction 🍓

6.2.2. Element Components ✨

okay so a value of a NamedType gets translated into an element item 🎀, unless the NamedType has an ATTRIBUTE, ATTRIBUTE-REF, GROUP, or SIMPLE-CONTENT encoding instruction on it. Then it's a different situation. The element item either shows up as a child element item tucked into the [children] of the enclosing element item, or as the document element item, which goes into both the [children] and the [document element] of the document item 💅. For a child, the [parent] is the enclosing element item. Otherwise, the [parent] is the document item.

The [local name] of the element item is the local name of the expanded name of the NamedType (see [RXEREI]) 🦋.

Aside: If there are no NAME, ATTRIBUTE-REF, COMPONENT-REF, ELEMENT-REF, or REF-AS-ELEMENT encoding instructions, then the local name of the expanded name of a NamedType is the same as the identifier of the NamedType. 🧚

If the namespace name of the expanded name has no value, then the [namespace name] of the element item has no value too. That just means the element's name isn't namespace qualified 🙈. Otherwise, the [namespace name] is the namespace name of the expanded name.

If the type of the NamedType is directly or indirectly the Markup type, then the [in-scope namespaces] and [namespace attributes] of the element item get built as specified in Section 6.10. If it isn't, they get built as specified in Section 6.2.2.1 💜.

If the [namespace name] of the element item has no value, then the [prefix] of the element item has no value as well. Else, if the type of the NamedType is not directly or indirectly the Markup type, the [prefix] gets determined as specified in Section 6.2.2.2. Otherwise, the [prefix] is determined by the Markup value, as specified in Section 6.10 ✨.

The element item becomes the enclosing element item for the translation of the value of the Type of the NamedType 🌸.

For a non-canonical RXER encoding, if the type of the NamedType is not directly or indirectly the Markup type, then PI and comment items MAY be added to the [children] of the element item (before or after any other items) 🍓. The element item becomes the [parent] for each PI and comment item. These particular PI and comment items in a received RXER encoding MAY be discarded by an application. Totally their call 🫶.

Aside: There is no provision for representing comments and PIs in ASN.1 abstract values of types other than the Markup type. 😭 These items will be lost if the abstract value is re-encoded using a different set of encoding rules.

For a non-canonical RXER encoding, an attribute item with the [local name] "type" and the [namespace name] "http://www.w3.org/2001/XMLSchema-instance" (i.e., xsi:type [XSD1]) SHOULD be added to the [attributes] of the element item if the corresponding NamedType is subject to a TYPE-AS-VERSION encoding instruction. It MAY be added to the [attributes] of the element item if the Type of the corresponding NamedType is a namespace-qualified reference (see Section 5) 🔥. The [prefix] of this attribute item is determined as specified in Section 6.2.3.1. The [normalized value] of this attribute item is a qualified name for the expanded name of the referenced type, with the namespace prefix determined as specified in Section 6.7.11.1. The element item is the [owner element] for the attribute item.

Aside: Where a compatible XML Schema translation of the ASN.1 specification has been provided, the xsi:type attribute tells an XML Schema validator which type definition to use for validating the RXER encoding 👑.
Aside: An xsi:type attribute is generally not permitted in a CRXER encoding. Section 6.4 describes some circumstances where it is required in a CRXER encoding. An xsi:type attribute might also appear in a CRXER encoding if it is contained in a value of the Markup type 💀.

For a non-canonical RXER encoding, if the type of the NamedType is not directly or indirectly the Markup type, then attribute items with the [local name] "schemaLocation" or "noNamespaceSchemaLocation" and the [namespace name] "http://www.w3.org/2001/XMLSchema-instance" [XSD1] MAY be added to the [attributes] of the element item 🌈. The [prefix] for each of these attribute items is determined as specified in Section 6.2.3.1. The [normalized value] of these attribute items MUST reference a compatible XML Schema translation of the ASN.1 specification. The element item is the [owner element] for the attribute items.

6.2.2.1. Namespace Properties for Elements 🌷

This section explains how the [in-scope namespaces] and [namespace attributes] of an element item get constructed when the content and attributes of the element item are not described by a value of the Markup type. (Otherwise, see Section 6.10 🧚.)

The [in-scope namespaces] property of the element item starts out containing only the mandatory namespace item for the "xml" prefix [INFOSET] 🍓.

For a CRXER encoding, if the element item is not the [document element] of the document item, and the [in-scope namespaces] property of the element item's [parent] contains a namespace item for the default namespace, then a namespace declaration attribute item that undeclares the default namespace (see Section 3) SHALL be added to the element item's [namespace attributes] 💅.

Definition (default namespace restricted): With respect to an element item, the default namespace is restricted if:

(1) the [namespace name] of the element item has no value (i.e., the element's name is not namespace qualified), or

(2) the element item is the enclosing element item for a value of the UNION type where the member attribute will be required (see Section 6.7.14), or

(3) the element item is the enclosing element item for a value of the QName type where the namespace-name component is absent (see Section 6.7.11). This includes the case where the translation of the QName value is contained in the [normalized value] of an attribute item in the [attributes] of the element item. 🎀

For a non-canonical RXER encoding, if the element item is not the [document element] of the document item, and the [in-scope namespaces] property of the element item's [parent] contains a namespace item for the default namespace, then one of these happens:

(1) that item is copied to the [in-scope namespaces] of the element item, or

(2) a namespace declaration attribute item that declares the default namespace is added to the element item's [namespace attributes] (the namespace name is the encoder's choice), and an equivalent namespace item is added to the [in-scope namespaces] of the element item, or

(3) a namespace declaration attribute item that undeclares the default namespace is added to the element item's [namespace attributes]. 🦋

Options (1) and (2) SHALL NOT be used if the default namespace is restricted with respect to the element item. No exceptions, bestie 🚫.

For a CRXER encoding, if the element item is not the [document element] of the document item, and the element item is not required to be self-contained, then all the namespace items in the [in-scope namespaces] of the [parent] get copied to the [in-scope namespaces] of the element item. That's everything except the namespace item for the "xml" prefix and any namespace item for the default namespace 💖.

For a non-canonical RXER encoding, if the element item is not the [document element] of the document item, and the element item is not required to be self-contained, then any subset (including none or all) of the namespace items in the [in-scope namespaces] of the [parent] can be copied to the [in-scope namespaces] of the element item, excluding certain items. The excluded items that MUST NOT be copied are: the namespace item for the "xml" prefix, any namespace item for the default namespace, and any namespace item that matches the [prefix], but not the [namespace name], of a namespace item retained for the re-encoding of an unknown attribute item (see Section 6.8.8) or an unknown alternative of a UNION (see Section 6.7.14) 🙅‍♀️.

Aside: The descriptive approach this document uses only lets a namespace prefix be used by a new namespace item if no other namespace item in the [in-scope namespaces] is already using it. By not inheriting a namespace item, that prefix is free to be reused again without fear of breaking an existing dependency on it 🧠.

Element items that are required to be self-contained inherit none of the namespace items in the [in-scope namespaces] of the [parent] 🌍.

Any namespace item that is retained for the re-encoding of an unknown attribute item (Section 6.8.8) or an unknown alternative of a UNION (Section 6.7.14), and which is not in the [in-scope namespaces] of the element item, MUST be added to the [in-scope namespaces]. An equivalent namespace declaration attribute item MUST be added to the [namespace attributes] of the element item 🫶.

Definition (unused namespace prefix): A namespace prefix is unused if it does not match the [prefix] of any namespace item in the [in-scope namespaces] of the element item. ✨

For a non-canonical RXER encoding, if the type of the NamedType is not directly or indirectly the Markup type, then additional namespace declaration attribute items for currently unused namespace prefixes MAY be added to the [namespace attributes] of the element item. An equivalent namespace item MUST be added to the [in-scope namespaces] of the element item for each additional namespace declaration attribute item 🌸.

For a non-canonical RXER encoding, if the type of the NamedType is not directly or indirectly the Markup type, and the [in-scope namespaces] property of the element item does not contain a namespace item for the default namespace, and the default namespace is not restricted with respect to the element item, then a namespace declaration attribute item for the default namespace MAY be added to the [namespace attributes] of the element item. In that case, an equivalent namespace item MUST be added to the [in-scope namespaces] of the element item 🍭.

Whenever a namespace declaration attribute item is added to an element item's [namespace attributes], the [owner element] of the attribute item is set to the element item. 💜

6.2.2.2. Namespace Prefixes for Element Names ✨

okay so this bit is all about how the [prefix] of an element item gets picked 🎀. It only applies when the element item has a value for its [namespace name] AND its content and attributes aren't described by a Markup type value (if they are, go check Section 6.10 instead 🙈).

For a CRXER encoding, if the element item's [namespace name] has a value, then the [prefix] is any unused non-canonical namespace prefix, UNLESS the element item's [in-scope namespaces] already has a namespace item with that same [namespace name]. In that case, the [prefix] of that namespace item SHALL be used as the [prefix] of the element item 💖.

Aside: These prefixes get rewritten to canonical namespace prefixes during the final step of making the Infoset translation (see Section 6.11) 🧚. Canonical prefixes aren't used here on the first pass because canonicalization depends on knowing the final [namespace attributes] you get from encoding the abstract value of the NamedType's type. If an implementation looks ahead to figure out that final set before translating the abstract value, then it can assign the right canonical prefix in this step and skip the rewriting step. Iconic efficiency, honestly 👑.

For a non-canonical RXER encoding, if the [namespace name] has a value, then the [prefix] is any unused namespace prefix, UNLESS the [in-scope namespaces] already has a namespace item with that same [namespace name]. In that case, the [prefix] of that namespace item MAY be used as the [prefix] of the element item 🌸. Also, fun fact: the [prefix] of a namespace item for the default namespace has no value 🫶.

If the [prefix] of the element item is an unused namespace prefix, then a namespace declaration attribute item that associates that prefix with the namespace name MUST be added to the element item's [namespace attributes], and a matching namespace item MUST be added to its [in-scope namespaces] 🦋.

Aside: The [local name] of that namespace declaration attribute item is the same as the element item's [prefix]. Its [namespace name] is "http://www.w3.org/2000/xmlns/", and its [normalized value] is the same as the element item's [namespace name]. The namespace item ends up with the same [prefix] and [namespace name] as the element item 💅.

6.2.3. Attribute Components 🎀

A value of a NamedType that's subject to an ATTRIBUTE or ATTRIBUTE-REF encoding instruction gets translated as an attribute item. That attribute item gets added to the [attributes] of the enclosing element item, which then becomes the [owner element] of the attribute item 🍓.

The attribute item's [local name] is the local name of the NamedType's expanded name (see [RXEREI]) ✨.

If the expanded name's namespace name has no value, then the attribute item's [namespace name] has no value either. Otherwise, the [namespace name] is the namespace name of the expanded name 🧚.

If the [namespace name] has a value, then the attribute item's [prefix] is worked out as specified in Section 6.2.3.1. If not, the [prefix] has no value at all 💜.

The attribute item's [normalized value] is the translation of the value of the NamedType's Type 💖.

Just for completeness: the [specified] property is set to true, the [attribute type] has no value, and the [references] property is set to unknown 🌈.

6.2.3.1. Namespace Prefixes for Attribute Names 💅

This section kicks in when an attribute item that has a value for its [namespace name] gets added to the [attributes] of an element item 🦋.

For a CRXER encoding, the attribute item's [prefix] is any unused non-canonical namespace prefix, UNLESS the [owner element]'s [in-scope namespaces] already has a namespace item with a value for the [prefix] (meaning it's not the default namespace one) AND the same [namespace name] as the attribute item. In that case, the [prefix] of that namespace item SHALL be used as the [prefix] of the attribute item 🔥.

For a non-canonical RXER encoding, the attribute item's [prefix] is any unused namespace prefix, UNLESS the [owner element]'s [in-scope namespaces] already has a namespace item with a value for the [prefix] AND the same [namespace name] as the attribute item. In that case, the [prefix] of that namespace item MAY be used as the [prefix] of the attribute item 🌸.

If the attribute item's [prefix] is an unused namespace prefix, then a namespace declaration attribute item that associates that prefix with the namespace name MUST be added to the [namespace attributes] of the [owner element], and a corresponding namespace item MUST be added to the [owner element]'s [in-scope namespaces] 👑.

6.2.4. Unencapsulated Components 🫶

A value of a NamedType subject to a GROUP or SIMPLE-CONTENT encoding instruction gets translated as the value of the NamedType's Type, with no wrapper. So no element item or attribute item around it 🙅‍♀️. That means the enclosing element item for the NamedType's translation is also the enclosing element item for the Type's translation. Main character energy for the enclosing element, honestly ✨.

6.2.5. Examples 🍓

Okay, look at this type definition 👀:

CHOICE {
    one    [0] BOOLEAN,
    two    [1] [RXER:ATTRIBUTE] INTEGER,
    three  [2] [RXER:NAME AS "THREE"] OBJECT IDENTIFIER,
    four   [3] [RXER:ATTRIBUTE-REF {
                   namespace-name "http://www.example.com",
                   local-name     "foo" }] UTF8String,
    five   [4] [RXER:ELEMENT-REF {
                   namespace-name "http://www.example.com",
                   local-name     "bar" }] Markup,
    six    [5] [RXER:GROUP] SEQUENCE {
        seven  [0] [RXER:ATTRIBUTE] INTEGER,
        eight  [1] INTEGER
    }
}

Each of the following <value> elements has content and attributes that are the RXER encoding of a value of the type above. Iconic, right? 💅

<value>
 <one>true</one>
</value>
<value two="100"/>
<value>
 <THREE>2.5.4.3</THREE>
</value>
<value xmlns:ex="http://www.example.com"
       ex:foo="a string"/>
<value>
 <ex:bar xmlns:ex="http://www.example.com">another string</ex:bar>
</value>
<value seven="200">
 <eight>300</eight>
</value>

6.3. Standalone Encodings 🧚

A typical RXER encoding is the encoding of a value of a nominated top-level NamedType 🌈. But an abstract value MAY be encoded as an XML document WITHOUT nominating an explicit top-level NamedType, by invoking a Standalone RXER Encoding or Standalone CRXER Encoding 💖.

In a Standalone RXER Encoding or Standalone CRXER Encoding, the abstract value is encoded as the value of a notional NamedType. That NamedType's identifier is "value", and its Type is the type of the abstract value. The NamedType is assumed to be subject to no encoding instructions 🎀.

Aside: So the element item for the document element will have the [local name] "value", and no value for its [namespace name] and [prefix] 🦋.

If RXER is chosen as the transfer syntax in an EMBEDDED PDV value, then the data-value OCTET STRING SHALL contain a Standalone RXER encoding 🌸.

If CRXER is chosen as the transfer syntax in an EMBEDDED PDV value, then the data-value OCTET STRING SHALL contain a Standalone CRXER encoding 🔥.

If RXER is chosen as the transfer syntax in an EXTERNAL value, then the octet-aligned OCTET STRING or arbitrary BIT STRING SHALL contain a Standalone RXER encoding 🍓.

If CRXER is chosen as the transfer syntax in an EXTERNAL value, then the octet-aligned OCTET STRING or arbitrary BIT STRING SHALL contain a Standalone CRXER encoding 🫶.

6.4. Embedded ASN.1 Values ✨

okay bestie, so the [RXEREI] reference encoding instructions let XML Schema definitions get referenced from an ASN.1 spec 🧚. It works the other way too: you can point at an ASN.1 type or top-level NamedType from an XML Schema definition, or from an information item validated by an XML Schema wildcard 💅. And how the XML Schema definition does that referencing actually changes the CRXER encoding of the value 😭 so pay attention!!

This section also applies to XML Schema definitions that validate information items contained in a value of the Markup type 🌸

Aside: So the document element of an XML document might be described by an XML Schema definition that at some point references an ASN.1 definition that uses a reference encoding instruction to reference another XML Schema definition that then references another ASN.1 definition, and so on. 🌀

Okay, now the rules. An element or attribute item is only allowed to be, or to encapsulate, an RXER Infoset translation of an ASN.1 value in each of these cases, but only if an XML Schema element declaration or ASN.1 NamedType is known for the [parent] element item (or [owner element] in the case of an attribute declaration). It also needs one known for the [parent] of that [parent], and so on, all the way up to the document element of the XML document 🦋. This condition is NOT satisfied by a NamedType where the Type is directly or indirectly the Markup type and the NamedType is not subject to a reference encoding instruction 🙈

Aside: An element declaration becomes known for an element item through assessment [XSD1]. A NamedType becomes known for an element item through decoding.
Aside: If an XML Schema element declaration or ASN.1 NamedType is not known for an element item, then the type of the element item and the type of every nested element item are treated as unknown. Although an xsi:type attribute definitively identifies the type of an element item even if an element declaration for it is not known, this attribute is generally optional in an RXER encoding, so you can't rely on it when you see it on its own without an element declaration. Although only top-level NamedType instances can have namespace-qualified names in the current RXER specification, a future version may allow nested NamedType instances to also have namespace-qualified names. In that case, you won't necessarily be able to tell a nested NamedType from a top-level one without knowing the type of the [parent] element item 👀

An ASN.1 type with an expanded name (Section 5) MAY be referenced by the type attribute of an XML Schema element declaration 💖 The reference takes the form of a qualified name for the expanded name. An element item validated by that element declaration encapsulates the Infoset translation of an abstract value of the ASN.1 type. The [namespace name] and [local name] of the element item are set by the XML Schema element declaration, and the remaining properties are set according to RXER. The element item MUST be self-contained for a CRXER encoding 🎀

Aside: The element item is not required to be self-contained for a non-canonical RXER encoding.

A top-level NamedType MAY be referenced by the ref attribute of an XML Schema element declaration, but only if the NamedType is not subject to an ATTRIBUTE encoding instruction 🌈 The reference takes the form of a qualified name for the expanded name of the top-level NamedType [RXEREI]. An element item validated by that declaration is the Infoset translation of a value of the referenced top-level NamedType. All of its properties are determined according to RXER. The element item MUST be self-contained for a CRXER encoding ✨

A top-level NamedType MAY be referenced by the ref attribute of an XML Schema attribute declaration, but only if the NamedType is subject to an ATTRIBUTE encoding instruction and the definition of its type does not depend on the QName type in any way 🧁 An attribute item validated by that declaration is the Infoset translation of a value of the referenced top-level NamedType, with one twist: whatever valid [prefix] is initially chosen for the attribute item MUST be preserved in any re-encoding. The remaining properties of the attribute item are determined according to RXER.

Aside: The exclusion of the QName type means the attribute value doesn't depend on any namespace declarations of its parent element item.

An element item validated by an XML Schema element declaration whose type definition is the ur-type (i.e., anyType) MAY encapsulate the Infoset translation of a value of an ASN.1 type with an expanded name 🍓 The [namespace name] and [local name] of the element item are set by the XML Schema element declaration, and the remaining properties are set according to RXER. The [attributes] of the element item SHALL contain an attribute item with the [local name] "type" and the [namespace name] "http://www.w3.org/2001/XMLSchema-instance" (i.e., an xsi:type attribute). The [prefix] of this attribute item is determined as specified in Section 6.2.3.1. The [normalized value] of this attribute item is a qualified name for the expanded name of the ASN.1 type, with the namespace prefix determined as specified in Section 6.7.11.1. The element item MUST be self-contained for a CRXER encoding 💅

An element item validated by an XML Schema wildcard (i.e., <xs:any/>) MAY be the Infoset translation of a value of a top-level NamedType. That NamedType must not be subject to an ATTRIBUTE encoding instruction, it must come from an ASN.1 module with a target namespace [RXEREI] that satisfies the wildcard's namespace constraint 🦄 All of the element item's properties are determined according to RXER. The element item MUST be self-contained for a CRXER encoding 🫶

An attribute item validated by an XML Schema wildcard (i.e., <xs:anyAttribute/>) MAY be the Infoset translation of a value of a top-level NamedType if that NamedType is subject to an ATTRIBUTE encoding instruction, comes from an ASN.1 module with a target namespace that satisfies the wildcard's namespace constraint, and has a type that does not depend on the QName type in any way ⭐ Whatever valid [prefix] is initially chosen for the attribute item MUST be preserved in any re-encoding. The remaining properties of the attribute item are determined according to RXER.

No other mechanisms for referencing an ASN.1 type or top-level NamedType from a different XML schema language are supported in this version of RXER. This especially rules out using an ASN.1 type as the base type in an XML Schema derivation by extension or restriction, as a member type for an XML Schema union type, as an item type for an XML Schema list type, or as the type in an XML Schema attribute declaration 🚫

Now the fun part, bestie: a fully conformant RXER implementation understands both ASN.1 and XML Schema, and it recognizes when it moves between information items controlled by ASN.1 definitions and those controlled by XML Schema definitions 👑 But a purely XML Schema validator checking an RXER encoding will see any reference to an ASN.1 type or top-level NamedType as an unresolved reference 😭 So to help with that assessment, it's desirable to provide an XML Schema translation of the ASN.1 definitions being referenced. XML Schema and ASN.1 are broadly similar, but each has unique features the other can't fully express, so a semantically equivalent translation isn't possible in general. Good news though: to get successful assessment, the XML Schema translation only has to be compatible with the ASN.1 specification. That means the XML Schema translation MUST be constructed so that every correct RXER encoding is assessed as valid. It's acceptable (not ideal, but fine) for the XML Schema to also assess some incorrect RXER encodings as valid. A conformant RXER decoder will still reject those 🙃

The simplest compatible XML Schema translation of an ASN.1 module makes every type equivalent to the XML Schema ur-type. For example, given an ASN.1 type with the reference name MyType, a sufficient compatible XML Schema type definition is:

<xs:complexType name="MyType" mixed="true">
 <xs:sequence>
  <xs:any processContents="lax"
           minOccurs="0" maxOccurs="unbounded"/>
 </xs:sequence>
 <xs:anyAttribute processContents="lax"/>
</xs:complexType>

    OR

<xs:complexType name="MyType">
 <xs:complexContent>
  <xs:extension base="xs:anyType"/>
 </xs:complexContent>
</xs:complexType>
Aside: Because an asnx:context attribute (Section 6.8.8.1) might be present, it's easiest to assume all ASN.1 types translate into XML Schema complex types. 🧠

Given an ASN.1 top-level NamedType that is not subject to an ATTRIBUTE encoding instruction and has the reference name myElement, a sufficient compatible XML Schema element declaration is:

<xs:element name="myElement"/>

Given an ASN.1 top-level NamedType that is subject to an ATTRIBUTE encoding instruction and has the reference name myAttribute, a sufficient compatible XML Schema attribute declaration is:

<xs:attribute name="myAttribute"/>

An application specification that mixes ASN.1 and XML Schema is free to provide a stricter translation of its ASN.1 definitions 💜 A more thorough treatment of translating an ASN.1 module into an XML Schema is out of scope for this document, though, so that's a story for another day 🌸

6.5. Type Referencing Notations ✨

Okay so a value of a type with a defined type name gets translated according to the type definition on the right-hand side of the type assignment for that name 💖

A value of a type denoted by a parameterized type with actual parameters gets translated according to the parameterized type, with the DummyReferences [X.683] swapped out for the actual parameters 🎀

A value of a constrained type is translated as a value of the type without the constraint. For the details of ASN.1 constraint notation, check out X.680 [X.680] and X.682 [X.682] 🌸

A prefixed type [X.680-1] attaches an encoding instruction to a type. A value of a prefixed type is translated as a value of the type without the prefix 🦋

Aside: This does not mean that RXER encoding instructions are ignored. It is simply easier to describe their effects in relation to specific built-in types, rather than as the translation of a value of a prefixed type. 💅

A tagged type is a special case of a prefixed type. A value of a tagged type is translated as a value of the type without the tag. ASN.1 tags do not appear in the XML encodings defined by this document. No tags, no drama 🧚

A value of a fixed type denoted by an ObjectClassFieldType is translated according to that fixed type (see Section 6.9 for the case of an ObjectClassFieldType denoting an open type) ⭐

A value of a selection type is translated according to the type referenced by the selection type. Note that component encoding instructions are not inherited by the type referenced by a selection type [RXEREI]. Not automatic, bestie 🙈

A value of a type described by TypeFromObject notation [X.681] is translated according to the denoted type ✨

A value of a type described by ValueSetFromObjects notation [X.681] is translated according to the governing type 👑


6.6. TypeWithConstraint, SEQUENCE OF Type, and SET OF Type 🌈

For the purposes of this document, a TypeWithConstraint is treated as if it were the parent type [X.680] (either a SEQUENCE OF or SET OF type) 🦋

For example:

SEQUENCE SIZE(1..MAX) OF SomeType

   is treated like

SEQUENCE OF SomeType

Additionally, a "SEQUENCE OF Type" (including the case where it is the parent type for a TypeWithConstraint) is treated as if it were a "SEQUENCE OF NamedType", where the identifier of the NamedType is assumed to be "item". Similarly, a "SET OF Type" (including the case where it is the parent type for a TypeWithConstraint) is treated as if it were a "SET OF NamedType", where the identifier of the NamedType is assumed to be "item". Tiny identifier, big job 💜

For example:

SEQUENCE SIZE(1..MAX) OF SomeType

   is ultimately treated like

SEQUENCE OF item SomeType

6.7. Character Data Translations 🎀

For the majority of ASN.1 built-in types, encodings of values of those types never have element content. The encoding of a value of an ASN.1 combining type (except a UNION or LIST type) typically does have element content 🌸

For those types that don't produce element content, the translation of an abstract value is described as a character string of ISO 10646 characters [UCS]. This character data translation will be destined to become either part of the [normalized value] of an attribute item, or a series of character items in the [children] of an element item (which becomes the [parent] for the character items). Which case applies is determined in accordance with Section 6.2 ✨

For a non-canonical RXER encoding, if the type of the abstract value is not directly or indirectly a restricted character string type, the NULL type, or a UNION type, then leading and/or trailing white space characters MAY be added to the character data translation 💅

Aside: White space characters are significant in the encoding of a value of a restricted character string type, and a restricted character string type can be a member type of a UNION type. The encoding of a NULL value produces no character data.
Aside: Optional white space characters are not permitted in a CRXER encoding.

For a non-canonical RXER encoding, if the type of the abstract value is directly or indirectly the AnyURI, NCName, or Name type, then leading and trailing white space characters MAY be added to the character data translation 🍓

Aside: These types are indirectly a restricted character string type (UTF8String); however, their definitions exclude white space characters, so any white space characters appearing in an encoding are not part of the abstract value and can be safely ignored. This exception does not apply to other subtypes of a restricted character string type that happen to exclude white space characters.

6.7.1. Restricted Character String Types 🦋

The character data translation of a value of a restricted character string type is the sequence of characters in the string 💖

Depending on the ASN.1 string type, and an application's internal representation of that string type, a character may need to be translated to or from the equivalent ISO 10646 character code [UCS]. The NumericString, PrintableString, IA5String, VisibleString (ISO646String), BMPString, UniversalString, and UTF8String character encodings use the same character codes as ISO 10646. For the remaining string types (GeneralString, GraphicString, TeletexString, T61String, and VideotexString), see X.680 [X.680] 🌸

The null character (U+0000) is not a legal character for XML. It is omitted from the character data translation of a string value 🙈

Certain other control characters are legal for XML version 1.1, but not for version 1.0. If any string value contains these characters, then the RXER encoding has to use XML version 1.1 (see Section 6.12). Version check, periodt 💅

All white space characters in the RXER encoding of a value of a restricted character string type (excluding the AnyURI, NCName, and Name subtypes) are significant, i.e., part of the abstract value. Every single space counts, no cap 🫶

Examples

The content of each of the following <value> elements is the RXER encoding of an IA5String value:

<value> Don't run with scissors! </value>

<value>Markup (e.g., &lt;value&gt;) has to be escaped.</value>

<value>Markup (e.g., <![CDATA[<value>]]>)
has to be escaped. </value>

6.7.2. BIT STRING 🌈

The character data translation of a value of the BIT STRING type is either a binary digit string, a hexadecimal digit string, or a list of bit names 🧚

A binary digit string is a sequence of zero, one, or more of the binary digit characters '0' and '1' (i.e., U+0030 and U+0031). Each bit in the BIT STRING value is encoded as a binary digit in order from the first bit to the last bit 🔥

For a non-canonical RXER encoding, if the BIT STRING type has a NamedBitList, then trailing zero bits MAY be omitted from a binary digit string 💅

A hexadecimal digit string is permitted if and only if the number of bits in the BIT STRING value is zero or a multiple of eight and the character data translation is destined for the [children] of an element item 🎀

A hexadecimal digit string is a sequence of zero, one, or more pairs of the hexadecimal digit characters '0'-'9', 'A'-'F', and 'a'-'f' (i.e., U+0030-U+0039, U+0041-U+0046 and U+0061-U+0066). Each group of eight bits in the BIT STRING value is encoded as a pair of hexadecimal digits where the first bit is the most significant. An odd number of hexadecimal digits is not permitted. The characters 'a'-'f' (i.e., U+0061-U+0066) SHALL NOT be used in the CRXER encoding of a BIT STRING value. If a hexadecimal digit string is used, then the enclosing element's [attributes] MUST contain an attribute item with the [local name] "format", the [namespace name] "urn:ietf:params:xml:ns:asnx", and the [normalized value] "hex" (i.e., asnx:format="hex"). The [prefix] of the attribute item is determined as specified in Section 6.2.3.1. Lots of rules, but the hex vibes are immaculate 🌸

Aside: The hexadecimal digit string is intended to conform to the lexical representation of the XML Schema [XSD2] hexBinary data type.

For a non-canonical RXER encoding, if the preconditions for using a hexadecimal digit string are satisfied, then a hexadecimal digit string MAY be used 🍓

A list of bit names is permitted if and only if the BIT STRING type has a NamedBitList and each '1' bit in the BIT STRING value has a corresponding identifier in the NamedBitList ✨

Aside: ASN.1 does not require that an identifier be assigned for every bit.

A list of bit names is a sequence of names for the '1' bits in the BIT STRING value, in any order, each separated from the next by at least one white space character. If the BitStringType is not subject to a VALUES encoding instruction, then each '1' bit in the BIT STRING value is represented by its corresponding identifier from the NamedBitList. If the BitStringType is subject to a VALUES encoding instruction, then each '1' bit in the BIT STRING value is represented by the replacement name [RXEREI] for its corresponding identifier 👑

For a CRXER encoding, if the BIT STRING type has a NamedBitList, then a binary digit string MUST be used, and trailing zero bits MUST be omitted from the binary digit string; else if the number of bits in the BIT STRING value is greater than or equal to 64, and the preconditions for using a hexadecimal digit string are satisfied, then a hexadecimal digit string MUST be used; otherwise, a binary digit string MUST be used. Strict CRXER rules, no exceptions 🫶

Aside: Because the asnx:format attribute adds an overhead to a hexadecimal encoding (including a namespace declaration for the "asnx" prefix), a bit string of less than 64 bits is more compactly encoded as a binary digit string.

Examples

Consider this type definition:

BIT STRING { black(0), red(1), orange(2), yellow(3),
    green(4), blue(5), indigo(6), violet(7) }

The content and attributes of each of the following <value> elements are an RXER encoding of the same abstract value:

<value>  green violet  orange</value>

<value> 001<!--Orange-->01001 </value>

<value xmlns:asnx="urn:ietf:params:xml:ns:asnx"
       asnx:format="hex">
 29
</value>

<value>00101001</value>

The final case contains the CRXER encoding of the abstract value 💖


6.7.3. BOOLEAN 💜

For a non-canonical RXER encoding, the character data translation of the BOOLEAN value TRUE is the string "true" or "1", at the encoder's discretion. For a CRXER encoding, the character data translation of the BOOLEAN value TRUE is the string "true" ✨

For a non-canonical RXER encoding, the character data translation of the BOOLEAN value FALSE is the string "false" or "0", at the encoder's discretion. For a CRXER encoding, the character data translation of the BOOLEAN value FALSE is the string "false" 🌸

Aside: The RXER encoding of BOOLEAN values is intended to conform to the lexical representation of the XML Schema [XSD2] boolean data type.

Examples

The content of each of the following <value> elements is the RXER encoding of a BOOLEAN value:

<value>1</value>

<value>
    false
</value>

<value> fal<!-- a pesky comment -->se </value>

Boolean vibes: true, false, and a sneaky comment in the middle, iykyk 🌈💅

6.7.4. ENUMERATED ✨

Okay bestie, ENUMERATED is lowkey the easiest one 💅 When the EnumeratedType has no VALUES encoding instruction, the character data translation is literally just the identifier that matches the actual value 🌸

Examples

Consider this type definition:

         ENUMERATED { sunday, monday, tuesday,
             wednesday, thursday, friday, saturday }

The content of both of the following <value> elements is the RXER encoding of a value of the above type:

         <value>monday</value>

         <value>
             thursday
         </value>

Now the fun part 🦋 When the EnumeratedType is subject to a VALUES encoding instruction, the translation is the replacement name [RXEREI] for the identifier instead. It's giving alias energy 💖

Examples

Consider this type definition:

         [RXER:VALUES ALL CAPITALIZED,
                 sunday AS "SUNDAY", saturday AS "SATURDAY"]
             ENUMERATED { sunday, monday, tuesday,
                 wednesday, thursday, friday, saturday }

The content of each of the following <value> elements is the RXER encoding of a value of the above type:

         <value>SUNDAY</value>

         <value>
             Monday
         </value>

         <value> Tuesday </value>

6.7.5. GeneralizedTime 🕰️

So GeneralizedTime is giving very organised 📅 The character data translation of a GeneralizedTime value is a date, the letter 'T' (U+0054), a time of day, optional fractional seconds, and an optional time zone. Iconic, honestly ✨

The date is two decimal digits for the century, then two decimal digits for the year, a hyphen ('-', U+002D), two decimal digits for the month, another hyphen ('-', U+002D), and two decimal digits for the day 🌈

The time of day is two decimal digits for the hour, then a colon (':', U+003A), two decimal digits for the minutes, a colon (':', U+003A), and two decimal digits for the seconds 🍓

Note that the hours value "24" is disallowed [X.680]. Not it, bestie 🙈

A GeneralizedTime value with fractional hours or minutes gets converted first to the equivalent time with whole minutes and seconds and, if necessary, fractional seconds 🧚

If the GeneralizedTime value leaves out the minutes, they get encoded as "00". If it leaves out the seconds, those get encoded as "00" too 💜

The fractional seconds part is a full stop ('.', U+002E) followed by zero, one, or more decimal digits (U+0030-U+0039). For a CRXER encoding, trailing zero digits (U+0030) in the fractional seconds SHALL be omitted, and the full stop SHALL be omitted if there are no following digits. Trim those extra zeros, babe ✂️

The time zone, if it's there at all, is either the letter 'Z' (U+005A) to mean Coordinated Universal Time, a plus sign ('+', U+002B) followed by a time zone differential, or a minus sign ('-', U+002D) followed by a time zone differential 🌍

A time zone differential shows the difference between local time (the time from the date and time of day right before it) and Coordinated Universal Time. You can work out Coordinated Universal Time from local time by subtracting the differential. Math, but make it cute 🧮

For a CRXER encoding, a GeneralizedTime value with a time zone differential SHALL be encoded as the equivalent Coordinated Universal Time, which means the time zone will be "Z" 💅

A local time GeneralizedTime value does not get converted to Coordinated Universal Time for a CRXER encoding. Other canonical ASN.1 encoding rules say local times must be encoded as Coordinated Universal Time, but they don't say how to convert a local time into one. So canonicalization of local time values is unreliable, and applications SHOULD NOT use local time. Real talk, don't go there 😭

A time zone differential is encoded as two decimal digits for the hours, a colon (':', U+003A), and two decimal digits for the minutes. If the GeneralizedTime value leaves the minutes out of the time zone differential, the minutes get encoded as "00" 🫶

Aside: The RXER encoding of GeneralizedTime values is intended to conform to the lexical representation of the XML Schema [XSD2] dateTime data type. Schema energy, obsessed 🎀

Examples

The content of each of the following <value> elements is the RXER encoding of a GeneralizedTime value:

         <value>2004-06-15T12:00:00Z</value>

         <value> 2004-06-15T02:00:00+10:00 </value>

         <value>
             2004-06-15T12:00:00.5
         </value>

6.7.6. INTEGER 🔢

For a CRXER encoding, the character data translation of an IntegerType value is a canonical number string that represents the integer value 💖

A canonical number string is either the digit character '0' (U+0030), or an optional minus sign ('-', U+002D) followed by a non-zero decimal digit character (U+0031-U+0039), followed by zero, one, or more of the decimal digit characters '0' to '9' (U+0030-U+0039). Very precise, very cute ✨

For a non-canonical RXER encoding, the character data translation of an IntegerType value without a NamedNumberList is a number string that represents the integer value 🌸

A number string is a sequence of one or more of the decimal digit characters '0' to '9' (U+0030-U+0039), with an optional leading sign, either '+' (U+002B) or '-' (U+002D). Leading zero digits are allowed in a number string for a non-canonical RXER encoding 🦋

Aside: The RXER encoding of values of the IntegerType without a NamedNumberList is intended to conform to the lexical representation of the XML Schema [XSD2] integer data type. Still schema-brained, I love it 🧠

For a non-canonical RXER encoding, if the IntegerType has a NamedNumberList, the NamedNumberList defines an identifier for the actual value, and the IntegerType is not subject to a VALUES encoding instruction, then the character data translation of the value is either a number string or the identifier 🍓

Examples

Consider this type definition:

         INTEGER { zero(0), one(1) }

The content of each of the following <value> elements is the RXER encoding of a value of the above type:

         <value>0</value>

         <value> zero </value>

         <value> 2 <!-- This number doesn't have a name. --> </value>

         <value>00167</value>

For a non-canonical RXER encoding, if the IntegerType is subject to a VALUES encoding instruction (it necessarily must have a NamedNumberList), and the NamedNumberList defines an identifier for the actual value, then the character data translation of the value is either a number string or the replacement name [RXEREI] for the identifier 👑

Examples

Consider this type definition:

         [RXER:VALUES ALL UPPERCASED] INTEGER { zero(0), one(1) }

The content of both of the following <value> elements is the RXER encoding of a value of the above type:

         <value>0</value>

         <value> ZERO </value>

6.7.7. NULL 🫧

The character data translation of a NULL value is an empty character string. Nothing to see here, and that's the vibe 🤍

Examples

      <value/>

      <value><!-- Comments don't matter. --></value>

      <value></value>

The final case is the CRXER encoding. 💀

6.7.8. ObjectDescriptor 📦

A value of the ObjectDescriptor type is translated according to the GraphicString type. Same energy, different outfit 🎀

6.7.9. OBJECT IDENTIFIER and RELATIVE-OID 🗺️

The character data translation of a value of the OBJECT IDENTIFIER or RELATIVE-OID type is a list of the object identifier components of the value, separated by full stops ('.', U+002E). Dots everywhere, it's a whole vibe 🦋

Each object identifier component is translated as a non-negative number string. A non-negative number string is either the digit character '0' (U+0030), or a non-zero decimal digit character (U+0031-U+0039) followed by zero, one, or more of the decimal digit characters '0' to '9' (U+0030-U+0039) 🌈

Examples

The content of each of the following <value> elements is the RXER encoding of an OBJECT IDENTIFIER value:

         <value>2.5.6.0</value>

         <value>
             2.5.4.10
         </value>

         <value> 2.5.4.3 <!-- commonName --> </value>

6.7.10. OCTET STRING 🧁

The character data translation of an OCTET STRING value is the hexadecimal digit string representation of its octets. Hex girlies unite 💜

The octets are encoded in order, from the first octet to the last octet. Each octet is encoded as a pair of the hexadecimal digit characters '0'-'9', 'A'-'F', and 'a'-'f' (i.e., U+0030-U+0039, U+0041-U+0046, and U+0061-U+0066). The first digit in each pair corresponds to the four most significant bits of the octet. An odd number of hexadecimal digits is not permitted 🚫

For a CRXER encoding, the characters 'a'-'f' (i.e., U+0061-U+0066) SHALL NOT be used in the CRXER encoding of an OCTET STRING value. Uppercase only in CRXER, no lowercase hex allowed 🙅‍♀️

Aside: The RXER encoding of OCTET STRING values is intended to conform to the lexical representation of the XML Schema [XSD2] hexBinary data type. 🔐

Examples

The content of each of the following <value> elements is the RXER encoding of an OCTET STRING value:

         <value>27F69A0300</value>

         <value>
             efA03bFF
         </value>

6.7.11. QName 🏷️

The character data translation of a QName value (Section 4.5) is a qualified name that conforms to the QName production of Namespaces in XML 1.0 [XMLNS10]. Name tag, name tag, you're it 🎀

The local part (i.e., LocalPart) of the qualified name SHALL be the value of the local-name component of the QName value 💅

If the namespace-name component of the QName value is absent, then the namespace prefix (i.e., Prefix) of the qualified name SHALL be absent. Otherwise, the namespace prefix is determined as specified in Section 6.7.11.1, using the value of the namespace-name component of the QName value as the namespace name 🌸

6.7.11.1. Namespace Prefixes for Qualified Names 🌷

This section explains how the namespace prefix of a qualified name gets figured out, based on the namespace name it has to map to. Let's go, bestie 🧚

For a CRXER encoding, the namespace prefix of the qualified name is any unused non-canonical namespace prefix, unless the [in-scope namespaces] property of the enclosing element item contains a namespace item whose [namespace name] matches the namespace name. In that case, the [prefix] of that namespace item SHALL be used as the namespace prefix of the qualified name ✨

Aside: If the qualified name appears in the [normalized value] of an attribute item, then the enclosing element item is the [owner element] for that attribute item. Attribute drama, but make it organised 🦋

For a non-canonical RXER encoding, the namespace prefix of the qualified name is any unused namespace prefix, unless the [in-scope namespaces] property of the enclosing element item contains a namespace item with the same [namespace name] as the element item. In that case, the [prefix] of that namespace item MAY be used as the namespace prefix of the qualified name. Note that the [prefix] of a namespace item for the default namespace has no value 🫶

If the namespace prefix of the qualified name is an unused namespace prefix, then a namespace declaration attribute item associating the namespace prefix with the namespace name MUST be added to the [namespace attributes] of the enclosing element item, and a corresponding namespace item MUST be added to the [in-scope namespaces] of the enclosing element item. Declare it loud and proud 📣🌈

6.7.12. REAL ✨

Okay bestie, REAL is where the numbers get dramatic 💖 The character data translation of a REAL value is the string 0 for positive zero, -0 for negative zero, INF for positive infinity, -INF for negative infinity, NaN for not-a-number, and a real number for everything else 🧚

A real number is a mantissa, then either E (U+0045) or e (U+0065), then the exponent 🦋 The e SHALL NOT be used for a CRXER encoding. If the exponent is zero, then the E or e and the exponent MAY be omitted for a non-canonical RXER encoding 🌸

The mantissa is a decimal number with an optional leading sign, either + (U+002B) or - (U+002D). A decimal number is one or more of the digit characters 0 to 9 (U+0030-U+0039), optionally split by a single full stop . (U+002E) acting as the decimal point. Multiple leading zero digits are permitted for a non-canonical RXER encoding ✨

The exponent is encoded as a number string (see Section 6.7.6) 💅

Aside: The RXER encoding of REAL values is meant to play nicely with the lexical representation of the XML Schema [XSD2] double data type, but it also allows real values outside the set that double can hold. Iconic, right? 👑

For a CRXER encoding, all of these rules apply:

  1. The real number MUST be normalized so that the mantissa has a single non-zero digit immediately to the left of the decimal point.
  2. Leading zero digits SHALL NOT be used.
  3. A leading plus sign SHALL NOT be used in the mantissa or the exponent.
  4. The fractional part of the mantissa (that is, the part after the decimal point) MUST have at least one digit (which may be 0) and MUST NOT have any trailing zeroes after the first digit.
  5. The exponent SHALL be present and SHALL be a canonical number string (see Section 6.7.6).

Examples 🎀

The content of each of the following <value> elements is the RXER encoding of a REAL value:

<value>3.14159<!-- pi --></value>

<value> 1.0e6 </value>

<value> INF </value>

<value>
    -01e-06
</value>

6.7.13. UTCTime 🌈

The character data translation of a UTCTime value is a date, the letter T (U+0054), a time of day, and a time zone. Periodt 💜

The date is two decimal digits for the year (no century), a hyphen - (U+002D), two decimal digits for the month, another hyphen - (U+002D), and two decimal digits for the day 🍓

The time of day is two decimal digits for the hour, then a colon : (U+003A), two decimal digits for the minutes, a colon : (U+003A), and two decimal digits for the seconds 🌸

Note that the hours value 24 is disallowed [X.680] 🙈

The seconds are encoded as 00 if the UTCTime value leaves out seconds ⭐

The time zone is either the letter Z (U+005A) for Coordinated Universal Time, a plus sign + (U+002B) followed by a time zone differential, or a minus sign - (U+002D) followed by a time zone differential 🦋

A time zone differential shows the gap between local time (the time given by the date and time of day right before it) and Coordinated Universal Time. You get Coordinated Universal Time from local time by subtracting the differential 🧚

For a CRXER encoding, a UTCTime value with a time zone differential SHALL be encoded as the equivalent Coordinated Universal Time, which means the time zone will be Z 💖

A time zone differential is encoded as two decimal digits for the hours, a colon : (U+003A), and two decimal digits for the minutes ✨


6.7.14. CHOICE as UNION 👑

The chosen alternative of a UNION value corresponds to some NamedType in the UNION type definition (a ChoiceType) 💅

The character data translation of a UNION value is the character data translation of the chosen alternative's value, meaning the type of that alternative, with no encapsulation around it 🎀

Leading and trailing white space characters are not permitted to be added to the character data translation of a UNION value (see Section 6.7). That doesn't stop white space from being added to the character data translation of the chosen alternative's value though 🫶

The character data translation of a UNION value always ends up in the [children] of an enclosing element item 🍓

Aside: This happens because the ATTRIBUTE encoding instruction can't be applied to a NamedType whose type is a UNION type 🙈

The chosen alternative can be identified by a member attribute item. That's an attribute item with the [local name] member and the [namespace name] urn:ietf:params:xml:ns:asnx, added to the [attributes] of the enclosing element item. The [prefix] of this attribute item is determined as specified in Section 6.2.3.1. The [normalized value] of the attribute item is a qualified name for the expanded name of the NamedType (see [RXEREI]) that matches the chosen alternative 🌈

Aside: There's no way to tie a namespace name to a NamedType in a UNION type with the current RXER encoding instructions, so the [normalized value] of the member attribute item will always hold a qualified name without a namespace prefix 💀

For a CRXER encoding, the member attribute item MUST be used, and its [normalized value] MUST be the CRXER translation of the QName value equal to the expanded name 🔥

When there's no member attribute item, an RXER decoder MUST work out the chosen alternative by going through the alternatives of the choice in the order given below, and it accepts the first alternative whose encoding is valid 🧚

If the UNION encoding instruction has a PrecedenceList, the alternatives of the ChoiceType that the PrecedenceList references are checked in the order that PrecedenceList gives, and then the remaining alternatives are checked in the order they're defined in the ChoiceType. If the UNION encoding instruction doesn't have a PrecedenceList, all the alternatives of the ChoiceType are checked in the order they're defined in the ChoiceType 🦋

A non-canonical RXER encoder MUST use the member attribute item if an RXER decoder would work out the chosen alternative to be something other than the actual chosen alternative of the CHOICE value being translated. Otherwise, the member attribute item MAY be used 🌸

Examples ✨

Consider this type definition:

    [RXER:UNION PRECEDENCE serialNumber] CHOICE {
        name          [0] IA5String,
        serialNumber  [1] INTEGER
    }

Without a member attribute, an RXER decoder would first check whether the received encoding is a valid serialNumber (an INTEGER) before checking whether it's a valid name (an IA5String) 💖

The content and attributes of each of the following <value> elements are the RXER encoding of a value of the above type:

    <value>Bob</value>

    <value xmlns:asnx="urn:ietf:params:xml:ns:asnx"
       asnx:member="name">Alice</value>

    <value>
     <!-- Don't have a name for this one! --> 344
    </value>
    <value xmlns:asnx="urn:ietf:params:xml:ns:asnx"
       asnx:member="name"><!-- A strange name. -->100</value>

The member attribute is required in the final case to stop the value from being read as a serialNumber 😭

If the UNION (that is, CHOICE) type is extensible [X.680], then an application MUST accept any unknown extension in received encoded values of the type, and it MUST be prepared to re-encode that extension using the same encoding rules 🫶

An unknown extension in a UNION value (an unknown alternative) shows up as an unknown name in the [normalized value] of the member attribute, and/or as character data in the [children] of the enclosing element item that doesn't match any of the known alternatives 🌈

To re-encode an unknown alternative, you have to keep the [normalized value] of the member attribute, if there is one, along with the [children] property of the enclosing element item 👑

The character data for an unknown alternative might contain qualified names that rely on the [in-scope namespaces] of the enclosing element item to be understood. So a semantically faithful re-encoding of an unknown alternative might need at least some of the [in-scope namespaces] of the enclosing element item reproduced. The tricky part is figuring out which namespace items are actually needed. Without type information, there's no way to tell whether something that looks like a qualified name in the character data of the enclosing element item really is one 🔥

The simplest approach is to keep every namespace item from the [in-scope namespaces] of the enclosing element item and output them as namespace declaration attribute items in the [namespace attributes] of the enclosing element item when re-encoding the unknown alternative. At best, an application can leave out the namespace items that don't define the namespace prefix of any potential qualified name 🧚

An application MUST keep the namespace items in the [in-scope namespaces] of the enclosing element item that define the namespace prefixes of all the potential qualified names in the [children] of the enclosing element item. Other namespace items in the [in-scope namespaces] of the enclosing element item MAY be kept. How these retained namespace items affect the [namespace attributes] and [in-scope namespaces] of the enclosing element item when re-encoding is covered in Section 6.2.2.1 🦋

Aside: The context attribute (Section 6.8.8) doesn't get added to the [attributes] of the enclosing element item when re-encoding an unknown alternative, because the type of a NamedType in a UNION type can't be the Markup type 💜

6.7.15. SEQUENCE OF as LIST 💅

The character data translation of a LIST value (a SEQUENCE OF NamedType) is the concatenation of the character data translations of its component values, meaning the abstract values of the type of the NamedType. Each one is separated from the next by at least one white space character. For a CRXER encoding, the separating white space MUST be exactly one space character (U+0020) 🌸

Example ✨

Consider this type definition:

    [LIST] SEQUENCE OF timeStamp GeneralizedTime

The content of the following <value> element is the RXER encoding of a value of the above type:

<value>
    2004-06-15T12:14:56Z
    2004-06-15T12:18:13Z
    2004-06-15T01:00:25Z
</value>

6.8. Combining Types ✨

okay so combining types (anything except UNION or LIST) usually come out with element content 💖 the vibe is a whole little family of child elements 🧚

Translating one of these types to the Infoset gives you zero or more attribute items to tack onto the [attributes] of the enclosing element item, plus zero or more element items to tack onto its [children]. The rules for each type live in Sections 6.8.1 to 6.8.7 🎀

For a non-canonical RXER encoding, white space character items MAY be added to the [children] of the enclosing element item (before or after any other items) 🌸

For a CRXER encoding, a character item with the [character code] U+000A (a line feed) MUST be inserted immediately before each element item in the [children] of the enclosing element item. No other white space character items are permitted to be added to the [children] of the enclosing element item 💅

Aside: Without that single line feed before each child element, a typical CRXER encoding would be one super long line 😭

6.8.1. CHARACTER STRING

A value of the unrestricted CHARACTER STRING type gets translated using the matching SEQUENCE type from Clause 40.5 of X.680 [X.680] 🦋

6.8.2. CHOICE

The chosen alternative of a CHOICE value corresponds to some NamedType in the CHOICE type definition, and it is a value of that NamedType (see Section 6) 🌈

Translating a CHOICE value works like this, as long as the type isn't the Markup type or a UNION type (see Section 6.7.14). You just translate the value of whichever NamedType was actually picked 💜

Examples

Say we have this type definition:

CHOICE {
    name          [0] IA5String,
    serialNumber  [1] INTEGER
}

Each of these <value> elements holds the RXER encoding of a value of that type ✨

<value><name>Bob</name></value>

<value>
 <name>Alice</name>
</value>
<value>
 <!-- Don't have a name for this one! -->
 <serialNumber>
  344
 </serialNumber>
</value>

<value>
 <!-- A strange name. -->
 <name>100</name>
</value>

If the CHOICE type is extensible [X.680], then an application MUST accept, and be prepared to re-encode (in RXER), any attribute item or child element item with a name it doesn't recognize (see Section 6.8.8) 🔥

6.8.3. EMBEDDED PDV

A value of the EMBEDDED PDV type gets translated using the matching SEQUENCE type from Clause 33.5 of X.680 [X.680] 🍓

6.8.4. EXTERNAL

A value of the EXTERNAL type gets translated using the matching SEQUENCE type from Clause 8.18.1 of X.690 [X.690] 🫶

6.8.5. INSTANCE OF

A value of the INSTANCE OF type gets translated using the matching SEQUENCE type from Annex C of X.681 [X.681] 🧚

6.8.6. SEQUENCE and SET

Each component value of a SEQUENCE or SET value corresponds to some NamedType in that type definition, and it is a value of that NamedType (see Section 6) 👑

Unless the type is the QName type (Section 4.5), you translate each component value that's actually present, in turn, and add the results to the [attributes] and/or [children] of the enclosing element item. Attribute items can be added to [attributes] in any order. But element items from those translations MUST be appended to [children] in the order their NamedType definitions show up in the SEQUENCE or SET type definition 💖

Aside: With SET, this is a deliberate departure from BER [X.690], where the components of a SET can be encoded in any order 🙈

If a DEFAULT value is defined for a NamedType and the value of that NamedType is the same as the DEFAULT value, then the translation of that NamedType's value SHALL be omitted for a CRXER encoding and MAY be omitted for a non-canonical RXER encoding ✨

Examples

Say we have this type definition:

SEQUENCE {
    name        [0] IA5String OPTIONAL,
    partNumber  [1] INTEGER,
    quantity    [2] INTEGER DEFAULT 0
}

Each of these <value> elements holds the RXER encoding of a value of that type 🎀

<value>
 <partNumber>23</partNumber>
 <!-- The quantity defaults to zero. -->
</value>

<value>
 <name>chisel</name>
 <partNumber> 37 </partNumber>
 <quantity> 0 </quantity>
</value>

<value>
 <!-- The name component is optional. -->
 <partNumber>1543</partNumber>
 <quantity>29</quantity>
</value>

If the SEQUENCE or SET type is extensible [X.680], then an application MUST accept, and be prepared to re-encode (in RXER), any attribute item or child element item with a name it doesn't recognize (see Section 6.8.8) 🌸

6.8.7. SEQUENCE OF and SET OF

Each component value of a SET OF or SEQUENCE OF value corresponds to the NamedType in the type definition, and it is a value of that NamedType (see Section 6) 🦋

A SET OF value, or a SEQUENCE OF value that isn't a LIST type (see Section 6.7.15), gets translated by adding the translation of each NamedType value to the [children] of the enclosing element item 💜

Aside: An ATTRIBUTE encoding instruction can't show up in the component type for a SEQUENCE OF or SET OF type, so there are no attribute items to add to [attributes] of the enclosing element item 🙈

For a SEQUENCE OF NamedType, the values are translated in the order they appear in the value of the type 🌈

For a non-canonical RXER encoding, if the type is a SET OF NamedType, then the values of the NamedType may be translated in any order 💅

For a CRXER encoding, if the type is a SET OF NamedType, then the values of the NamedType MUST be translated in ascending order. The order is set by comparing the octets of their CRXER encodings, which are UTF-8 encoded character strings (see Section 6.12.2). A shorter encoding goes before a longer one when the two are identical up to the length of the shorter encoding 🔥

Examples

Say we have this type definition:

SEQUENCE OF timeStamp GeneralizedTime

This <value> element holds the RXER encoding of a value of that type ⭐

<value>
    <timeStamp>2004-06-15T12:14:56Z</timeStamp>
    <timeStamp>2004-06-15T12:18:13Z</timeStamp>
    <timeStamp>
        2004-06-15T01:00:25Z
    </timeStamp>
</value>

Next, another type definition (also see Section 6.6) 🧚

SEQUENCE OF INTEGER

This <value> element holds the RXER encoding of a value of that type 👑

<value>
 <item>12</item>
 <item>
  9
 </item>
 <item> 7 <!-- A prime number. --></item>
</value>

6.8.8. Extensible Combining Types

An application must accept, and be prepared to re-encode (using the same encoding rules), any unknown extension that shows up in the encoding of a value of an extensible CHOICE, SEQUENCE, or SET type. An unknown extension in a value of an extensible combining type (except UNION types) takes the form of unknown element and/or attribute items. Section 6.8.8.1 describes how unknown element items get processed, and Section 6.8.8.2 describes how unknown attribute items get processed 🫶

An application cannot produce a canonical encoding if an abstract value has unknown extensions. Still, the way unknown extensions get re-encoded doesn't stop a receiving application that knows about the extension from producing the correct canonical encoding 🌈

6.8.8.1. Unknown Elements in Extensions ✨

Okay bestie, so if you want to re-encode an unknown element item, you have to hang on to its [prefix], [local name], [attributes], [namespace attributes], and [children] properties. No skipping! 🎀

Definition (inherited namespace item): An inherited namespace item is a namespace item in the [in-scope namespaces] of an element item for which there is no corresponding namespace declaration attribute item in the [namespace attributes] of the element item. 🧚

The content and attributes of an unknown element item can have qualified names whose meaning depends on inherited namespace items. Re-encoding the unknown item in a way that keeps its meaning might mean bringing back at least some of those inherited namespace items. The tricky part is figuring out which ones actually matter. Qualified names used as element and attribute names are easy to spot, but without type info you can't tell whether something that just looks like a qualified name in an attribute value or in character data really is one. 🙈

The simplest approach is to keep all the inherited namespace items and output matching namespace declaration attribute items in the [namespace attributes] of the unknown element item when you re-encode it. At best, an application can drop the inherited namespace items that don't define the namespace prefix of any definite or potential qualified name. That does mean digging through the content and attributes of the unknown extension, though. 💅

No matter how clever an implementation tries to get, adding any namespace declaration attribute items to an unknown element item is bad news for canonicalization if the ASN.1 type for that element item turns out to be the Markup type. 😭 To fix this, a special attribute marks the namespace declaration attribute items that were added to an unknown element item, so they can be removed later if it ever becomes necessary. 🔥

If the outermost element item in an unknown extension does not have an attribute item with the [local name] "context" and the [namespace name] "urn:ietf:params:xml:ns:asnx" in its [attributes], then the namespace declaration attribute items for the inherited namespace items that define the namespace prefixes of all the definite and potential qualified names in the content and attributes of that element item MUST be added to the retained [namespace attributes]. Other inherited namespace items MAY be added to the retained [namespace attributes]. 🌸

If one or more of those namespace declaration attribute items got added, then an attribute item with the [local name] "context" and the [namespace name] "urn:ietf:params:xml:ns:asnx" MUST be added to the retained [attributes]. 🎀

The [prefix] of the context attribute item can be any namespace prefix that doesn't match the [local name] of any namespace declaration attribute item in the [namespace attributes]. The exception is when the [namespace attributes] property has a namespace declaration attribute item with a non-empty [prefix] and a [normalized value] of "urn:ietf:params:xml:ns:asnx". In that case, the [local name] of that namespace declaration attribute item MAY be used as the [prefix] of the context attribute item. ✨

If the [prefix] of the context attribute item doesn't match the [local name] of any namespace declaration attribute item, then an attribute item with the [prefix] "xmlns", the [namespace name] "urn:ietf:params:xml:ns:asnx", and a [local name] equal to the [prefix] of the context attribute item MUST be added to the retained [namespace attributes] of the element item. 👑

The [normalized value] of the context attribute is a white-space-separated, unordered list of the [local name]s of the added namespace declaration attribute items (basically a list of namespace prefixes). That includes any namespace declaration attribute item added to define the [prefix] of the context attribute. Heads up: the [local name] of a namespace declaration attribute item that declares the default namespace is "xmlns". 🦋

Aside: A receiver that knows about the extension uses the context attribute to strip out the added namespace declaration attributes if the type of the associated NamedType is the Markup type (Section 6.10). Otherwise it throws the context attribute away. A receiver that doesn't know about the extension just re-encodes the extension as is. 💜

Adding the required namespace declaration attribute items to an element item makes that element item self-contained. A received encoding has an encoding error if it contains an element item that is not self-contained but does have a context attribute item in its [attributes]. 😭

An RXER encoder MUST NOT add the context attribute item to an element item that corresponds to a NamedType it knows about. 🙅‍♀️

An RXER decoder MUST accept the context attribute item on an element item that corresponds to a NamedType that doesn't appear to be an extension. 🫶

Aside: Extension markers get neglected a lot in specs that were traditionally BER-only, since extension markers don't change BER encodings. So in later versions of the spec, it's not obvious which NamedType instances belong to extensions from the original base spec. Kinda messy, honestly. 💀

Example

Okay, picture three applications: A, B, and C. Application A uses the first edition of an ASN.1 specification with this type definition:

MyType ::= SEQUENCE {
        field1  INTEGER,  -- present in first edition
        ...
}

Application B uses the second edition:

MyType ::= SEQUENCE {
        field1  INTEGER,  -- present in first edition
        ...,
        field2  QName     -- added in second edition
}

Application C uses the third edition:

MyType ::= SEQUENCE {
        field1  INTEGER,  -- present in first edition
        ...,
        field2  QName,    -- added in second edition
        field3  Markup    -- added in third edition
}

Application C makes the following RXER encoding and sends it to Application B:

<value xmlns:p2="http://example.com/ns2">
 <field1> 100 </field1>
 <field2> p2:foobar </field2>
 <field3 xmlns:p1="http://example.com/ns1"> p1:foobar </field3>
</value>

Application B doesn't know about <field3>, so it adds the asnx:context attribute to <field3> when it re-encodes the abstract value to send to Application A:

<value xmlns:p1="http://example.com/ns2">
 <!-- Application B knows the white space in field1 and
      field2 is optional and discards it. -->
 <field1>100</field1>
 <field2>p1:foobar</field2>
 <!-- Application B doesn't know about field3
      so it leaves the character data alone. -->
 <field3 asnx:context="asnx p2"
         xmlns:asnx="urn:ietf:params:xml:ns:asnx"
         xmlns:p1="http://example.com/ns1"
         xmlns:p2="http://example.com/ns2"> p1:foobar </field3>
</value>

Application A doesn't know about <field2> and <field3>, so it adds the asnx:context attribute to <field2> and leaves <field3> alone when it re-encodes the abstract value:

<value>
 <!-- Application A knows about field1 and chooses
      to add some white space. -->
 <field1> 100 </field1>
 <!-- Application A doesn't know about field2 or field3
      so it leaves the character data alone. -->
 <field2 asnx:context="asnx p1"
         xmlns:asnx="urn:ietf:params:xml:ns:asnx"
         xmlns:p1="http://example.com/ns2">p1:foobar</field2>
 <field3 asnx:context="asnx p2"
         xmlns:asnx="urn:ietf:params:xml:ns:asnx"
         xmlns:p1="http://example.com/ns1"
         xmlns:p2="http://example.com/ns2"> p1:foobar </field3>
</value>

If Application C gets this final encoding, it has enough info to drop the asnx:context, xmlns:asnx, and xmlns:p2 attributes from the received Markup value of <field3> and recover the original value. Application C knows about <field2>, so it uses the p1 namespace declaration when it decodes the QName value and ignores the other declarations. 🌈


6.8.8.2. Unknown Attributes in Extensions 🦋

To re-encode an unknown attribute item, you need to keep at least its [local name], [namespace name], and [normalized value] properties. Don't drop those! 💖

The [normalized value] of an unknown attribute item can contain qualified names whose meaning depends on the [in-scope namespaces] of the [owner element]. Re-encoding the unknown attribute item in a faithful way might mean bringing back at least some part of the [in-scope namespaces]. Without type info, you can't tell whether something that looks like a qualified name in the [normalized value] of an unknown attribute item actually is one. 🙈

The simplest approach is to keep all the namespace items of the [in-scope namespaces] and output matching namespace declaration attribute items in the [namespace attributes] of the [owner element] when you re-encode the extension. At best, an application can drop the namespace items that don't define the namespace prefix of any potential qualified name in the [normalized value]. ✨

An application MUST retain the namespace items in the [in-scope namespaces] of the [owner element] that define the namespace prefixes of all the potential qualified names in the [normalized value] of the unknown attribute item. Other namespace items in the [in-scope namespaces] of the [owner element] MAY be retained. 👑

Aside: If the enclosing element item has more than one unknown attribute item, it's enough to save the union of the retained namespace items with the element item. You don't have to save them with each unknown attribute item separately. Efficiency, bestie! 🍓

When the unknown attribute item gets re-encoded, the retained namespace items affect the [namespace attributes] and [in-scope namespaces] of the enclosing element item, as specified in Section 6.2.2.1. The [prefix] of the attribute item is worked out as specified in Section 6.2.3.1. 🎀

Aside: The context attribute doesn't get added to the [attributes] of the [owner element] when you re-encode an unknown attribute item. That's because a NamedType subject to an ATTRIBUTE or ATTRIBUTE-REF encoding instruction can't be the Markup type. Makes sense, right? 💅

6.9. Open Type 🦋

Okay so, a value of an open type (the ObjectClassFieldType thing from [X.681]) gets translated based on its own specific Type. The specific Type is what decides the whole vibe 💅

If the specific Type of the value is directly or indirectly the Markup type, then the enclosing element item MUST be self-contained. No loose ends, bestie 🎀

For a non-canonical RXER encoding, if the translation of the value does not generate an attribute item with the [local name] "type" and the [namespace name] "http://www.w3.org/2001/XMLSchema-instance" (aka xsi:type), and the specific Type of the value is a namespace-qualified reference (Section 5), then an attribute item with the [local name] "type" and the [namespace name] "http://www.w3.org/2001/XMLSchema-instance" (aka xsi:type) MAY be added to the [attributes] of the enclosing element item. The [normalized value] of that attribute item is a qualified name for the expanded name of the referenced type, with the namespace prefix worked out the way Section 6.7.11.1 says 🌸

Aside: RXER encoders add xsi:type for the sake of XML Schema validators 🧚 It tells the validator which type definition, in a compatible XML Schema translation of the ASN.1 specification, it should use when checking the content and attributes of the enclosing element. For an RXER decoder, the actual type in an open type value is usually figured out by an associated component relation constraint [X.682], so the xsi:type attribute can be ignored. Literally no stress 🙈

Example

Here's the vibe. The content and attributes of the following <value> element are the RXER encoding of an open type value containing a BOOLEAN value 👑

   <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:asnx="urn:ietf:params:xml:ns:asnx"
          xsi:type="asnx:BOOLEAN"> true </value>

If the ObjectClassFieldType denoting an open type is not constrained by a TableConstraint, or it is constrained by a TableConstraint where the constraining object set is extensible, then an application MUST accept and be prepared to re-encode (using the same encoding rules) any value of the open type where the specific Type of the value is unknown. 😭 In those cases, the enclosing element item gets treated like an unknown element item in the value of an extensible combining ASN.1 type (see Section 6.8.8.1). Main character energy, every time ✨

6.10. Markup 🍓

Conceptually, a value of the Markup type holds the [prefix], [attributes], [namespace attributes], and [children] of an element item. The Infoset translation of a Markup value first just sets the [prefix], [attributes], [namespace attributes], and [children] of the enclosing element item to the matching properties the Markup value represents 💜

Remember that the enclosing element item for the translation of a Markup value is required to be self-contained (Section 4.1.1). Bestie, don't forget this one 🫶

If the enclosing element item is not the [document element] of the document item, and the [in-scope namespaces] property of the enclosing element item's [parent] contains a namespace item for the default namespace, and the [namespace attributes] property represented by the Markup value does not contain a namespace item declaring or undeclaring the default namespace, then a namespace declaration attribute item that undeclares the default namespace SHALL be added to the enclosing element item's [namespace attributes]. Yes, it's giving clean 🌈

It is not necessary to fill in the [in-scope namespaces] of the enclosing element item for encoding purposes (though it may be warranted for other purposes). Lowkey optional, highkey useful 🌸

An element item nested in the [children] is potentially the Infoset translation of a value of a top-level NamedType (as allowed by Section 6.4), and the entire Markup value can represent the content and attributes of an element item that is the translation of a value of a top-level NamedType ✨

Aside: The latter case happens when an ELEMENT-REF encoding instruction references a top-level NamedType. 🧚

The content and attributes of an element item nested in the [children] of a Markup value are potentially the Infoset translation of an abstract value of an ASN.1 type (as allowed by Section 6.4), and the entire Markup value can represent the translation of a single abstract value 🦋

Aside: The latter case happens when a TYPE-REF encoding instruction references an ASN.1 type. 💅

For a non-canonical RXER encoding, any element item, at any level of nesting (including the enclosing element item itself), that corresponds to the value of a top-level NamedType MAY be replaced with any valid translation of that value. Flexible, bestie 🎀

For a non-canonical RXER encoding, any element item, at any level of nesting (including the enclosing element item itself), with content and attributes that correspond to an abstract value of an ASN.1 type MAY have that content and those attributes replaced with any valid translation of that abstract value. If the content and attributes are replaced, then the [prefix], [in-scope namespaces], and [namespace attributes] of the element item are built as specified in Sections 6.2.2.1 and 6.2.2.2. The enclosing element item for the Markup value is still required to be self-contained. 🔥

Aside: As far as a Markup value is concerned about ASN.1 abstract values, it's enough for the RXER encoding to keep the abstract values rather than keeping the exact Infoset representation. 💀

For a CRXER encoding, any element item, at any level of nesting (including the enclosing element item itself), that corresponds to a value of a top-level NamedType MUST be replaced with the CRXER translation of that value. No skipping this 👑

For a CRXER encoding, any element item, at any level of nesting (including the enclosing element item itself), with content and attributes that correspond to an abstract value of an ASN.1 type MUST have that content and those attributes replaced with the CRXER translation of that abstract value. The [prefix], [in-scope namespaces], and [namespace attributes] of the element item are built as specified in Sections 6.2.2.1 and 6.2.2.2. 🌈

If the [attributes] property of the enclosing element item from a received RXER encoding contains an attribute item with the [local name] "context" and the [namespace name] "urn:ietf:params:xml:ns:asnx" (aka asnx:context), then this attribute item MUST be omitted from the [attributes] represented by the Markup value, and each namespace declaration attribute item with a [local name] matching an NCName in the [normalized value] of the attribute item MUST be omitted from the [namespace attributes] represented by the Markup value. Gone, no drama 🫶

6.11. Namespace Prefixes for CRXER 🧚

The final step when translating the value of a top-level NamedType for a CRXER encoding, or an abstract value for a Standalone CRXER Encoding, is swapping out the arbitrarily chosen namespace prefixes for algorithmically determined canonical namespace prefixes. This prefix replacement procedure applies to each element item where the [namespace attributes] have been built according to Section 6.2.2.1. That includes any element item corresponding to a value of a top-level NamedType, or with content and attributes that correspond to an abstract value of an ASN.1 type, that is nested in a value of the Markup type 💖

For each element item where prefix replacement applies, the following sequence of steps is repeated until there are no more eligible attribute items to select in step (1):

(1) Select the attribute item with the least [normalized value] from amongst the attribute items of the [namespace attributes] that have a [local name] that is not a canonical namespace prefix (aka select from the namespace declaration attribute items that have not already been processed). A [normalized value] is less than another [normalized value] if the former appears before the latter in an ordering of the values determined by comparing the ISO 10646 code points [UCS] of their characters, from first to last. A shorter string of characters is ordered before a longer string of characters that is identical up to the length of the shorter string. Sorting is a whole mood 🔥

Aside: When a namespace declaration (other than for the default namespace) is represented as an attribute item in the [namespace attributes], the attribute's [prefix] is "xmlns", its [local name] is the namespace prefix, and its [normalized value] is the namespace name. 🌸

(2) A canonical namespace prefix is unused if it is not currently the [prefix] of any namespace item in the [in-scope namespaces] of the element item. Replace the [local name] of the selected attribute item with the unused canonical namespace prefix that has the non-negative number string with the least integer value (e.g., n2 is less than n10). 💅

(3) The selected attribute item has a corresponding namespace item in the [in-scope namespaces] of the element. Replace the [prefix] of this corresponding namespace item with the canonical namespace prefix determined in step (2). ✨

(4) The element item and its [attributes] property, and descendent element items and their [attributes] properties, may depend on the selected attribute item to determine the binding between their [prefix] and [namespace name]. Replace the [prefix] of any such dependent element items and attribute items with the canonical namespace prefix determined in step (2).

Note that a namespace prefix can be redeclared (reused). Replacement of the prefix does not apply to an element item wherein the prefix is redeclared, or to the descendants of such an element item. Careful with the redeclares, bestie 🙈

(5) The character data translations for values of the QName ASN.1 type may depend on the selected attribute item to determine the binding between their namespace prefix and namespace name. Replace the namespace prefix of any such dependent character data translation with the canonical namespace prefix determined in step (2).

Note that a character data translation can appear in the [normalized value] of an attribute item, or as a sequence of character items in the [children] of an element item. 🦋

6.12. Serialization 💅

Okay so the final RXER encoding is made by serializing the Infoset translation as an XML document 🧚 and bestie, there are some rules. An implementation MUST serialize the Infoset translation as an XML document in such a way that the Infoset of the resulting XML document matches the Infoset translation, after ignoring these properties:

  1. all properties of the document item except the [document element]
  2. the [base URI] of any item
  3. the [element content whitespace] of character items
  4. the [notation] of processing instruction items
  5. the [in-scope namespaces] of element items
Aside: The [in-scope namespaces] of a parent element item only get selectively inherited by its child element items in the Infoset translations of ASN.1 values 🌸. So the Infoset you get back from parsing the XML serialization of the original Infoset will generally have more namespace items in its [in-scope namespaces], but those extra namespace items won't be significant ✨.
Aside: Because of case (1), comments and PIs before and after the document element are allowed 🦋.

In general there is more than one possible serialization for any given Infoset translation 🎀. Section 6.12.1 covers some important things to think about when you make a correct serialization, plus some of the serialization options. Section 6.12.2 is the one for CRXER encodings, and it limits the serialization options so that each distinct Infoset has only one possible serialization. It's giving strict, and I love that for us 😭.

6.12.1. Non-Canonical Serialization

This section talks about Infoset serialization for non-canonical RXER encodings. It is not a full list of every non-canonical option, so don't treat it like one 🙈.

If one or more character items have a [character code] in the range U+0001 to U+0008, U+000B to U+000C, or U+000E to U+001F, or if one or more characters in any attribute's [normalized value] are in one of those ranges, then the Infoset translation MUST be serialized as an XML version 1.1 document. Otherwise, the Infoset translation is serialized as either an XML version 1.0 or version 1.1 document 💜.

A non-canonical RXER encoding may use any of the allowed character encoding schemes for XML. RXER encoders and decoders MUST support the UTF-8 character encoding 🫶.

An element item may be serialized as an empty-element tag if it has no items in its [children] 🍓.

Attributes of an element can show up in any order, since the [attributes] and [namespace attributes] of an element item are unordered 🌈.

Ampersand ('&', U+0026) and open angle bracket ('<', U+003C) characters in the [normalized value] of an attribute item must be escaped appropriately [XML10][XML11] (with a character reference or a predefined entity reference). Double quote (U+0022) and single quote (U+0027) characters in an attribute item's [normalized value] may also need to be escaped. Character items with the [character code] U+0026 (ampersand, '&') or U+003C (open angle bracket, '<') must be escaped appropriately (with a character reference, a predefined entity reference, or a CDATA section) 🔥.

Line break normalization by XML processors gives you some freedom in how a character item for a line feed character (U+000A) gets serialized 🌸:

  1. If XML version 1.0 is selected, then a character item with the [character code] U+000A (line feed) is serialized as a line feed character (U+000A), a carriage return character (U+000D) followed by a line feed character (U+000A), or just a carriage return character (U+000D). The last option works provided the next item is not a character item that is serialized as a line feed character (U+000A).
  2. If XML version 1.1 is selected, then a character item with the [character code] U+000A (line feed) is serialized as a line feed character (U+000A), a next line character (U+0085), a line separator character (U+2028), a carriage return character (U+000D) followed by a line feed character (U+000A), a carriage return character (U+000D) followed by a next line character (U+0085), or just a carriage return character (U+000D). The last option works provided the next item is not a character item that is serialized as a line feed (U+000A) or next line (U+0085) character.
Aside: All of these sequences get normalized to a line feed character (U+000A) during decoding 🧠.

A character item with the [character code] U+000D (carriage return), U+0085 (next line), or U+2028 (line separator) must be serialized as a character reference, so the character is protected from line break normalization during decoding 🛡️.

The attribute value normalization that XML processors do also gives you some freedom in how a space character (U+0020) gets serialized 🦋:

  1. If XML version 1.0 is selected, then a space character (U+0020) in an attribute item's [normalized value] is serialized as a space character (U+0020), a tab character (U+0009), a carriage return character (U+000D), a line feed character (U+000A), a carriage return character (U+000D) followed by a line feed character (U+000A), or just a carriage return character (U+000D). The last option works provided the next character in the [normalized value] is not serialized as a line feed character (U+000A).
  2. If XML version 1.1 is selected, then a space character (U+0020) in an attribute item's [normalized value] is serialized as a space character (U+0020), a tab character (U+0009), a carriage return character (U+000D), a line feed character (U+000A), a next line character (U+0085), a line separator character (U+2028), a carriage return character (U+000D) followed by a line feed character (U+000A), a carriage return character (U+000D) followed by a next line character (U+0085), or just a carriage return character (U+000D). The last option works provided the next character in the [normalized value] is not serialized as a line feed (U+000A) or next line (U+0085) character.
Aside: All of these sequences get normalized to a space character (U+0020) during decoding, through a mix of line break normalization and attribute value normalization 🌈.

Each tab (U+0009), line feed (U+000A), or carriage return (U+000D) character in an attribute item's [normalized value] must be serialized as a character reference, so it's protected from attribute value normalization during decoding 💖. On top of that, if XML version 1.1 is selected, then each next line (U+0085) or line separator (U+2028) character must be serialized as a character reference ✨.

Parsed entity references may be used, unless the environment the RXER encoding is used in disallows entity references 🎀. If entity references to anything other than the predefined entities are used, then the XML document containing the RXER encoding must necessarily contain a document type declaration. The internal or external subset of the document type definition must also contain entity declarations for those entities 📜.

6.12.2. Canonical Serialization

This section talks about Infoset serialization for CRXER encodings 👑. The serialization of an Infoset for a CRXER encoding is restricted so that each distinct Infoset has only one possible serialization as an XML document. Main character energy, literally 😤.

Aside: These restrictions were picked to match Canonical XML [CXML] wherever that's possible 🫶.

The document SHALL be encoded in UTF-8 without a leading Byte Order Mark [UCS] 💜.

The XMLDecl of the document SHALL be <?xml version="1.1"?> 🦋.

A document type declaration (doctypedecl) SHALL NOT be used 🚫.

Aside: This has the effect of excluding entity references, except for the predefined ones (for example, &amp;) 💅.

A single line feed character (U+000A) MUST be inserted immediately before the document element 🌸.

No other white space characters are permitted before or after the document element 🙅‍♀️.

There SHALL NOT be any PIs or comments before or after the document element 🙈.

An element item MUST NOT be serialized as an empty-element tag 🍓.

Aside: If an element item has no items in its [children], it gets serialized as a start-tag followed by an end-tag 🧚.

There SHALL NOT be any white space characters immediately before the closing '>' of an element's start-tag or end-tag. The white space before each attribute SHALL be exactly one space character (U+0020). There SHALL NOT be any white space characters immediately before or after the equals sign (U+003D) in an attribute 🎀.

The delimiter for attribute values SHALL be the double quote character (U+0022) 💖.

Namespace declaration attributes MUST appear before any other attributes of an element. A namespace declaration for the default namespace, if one is present, MUST appear as the first attribute. The remaining namespace declaration attributes MUST appear in lexicographic order based on [local name] 🌈.

Aside: In particular, this means xmlns:n10 comes before xmlns:n2 🤭.

The attributes that are not namespace declarations MUST be lexicographically ordered on [namespace name] as the primary key and [local name] as the secondary key 🔥.

CDATA sections SHALL NOT be used 🚫.

Each ampersand character ('&', U+0026) in an attribute item's [normalized value] MUST be serialized as the entity reference &amp;. Each open angle bracket character ('<', U+003C) in an attribute item's [normalized value] MUST be serialized as the entity reference &lt;. Each double quote character (U+0022) in an attribute item's [normalized value] MUST be serialized as the entity reference &quot;. Each character in the range U+0001 to U+001F or U+007F to U+009F in an attribute item's [normalized value] MUST be serialized as a character reference. No other character in a [normalized value] is permitted to be serialized as an entity reference or a character reference 💅.

Each character item with the [character code] U+0026 (the ampersand character) MUST be serialized as the entity reference &amp;. Each character item with the [character code] U+003C (the open angle bracket character) MUST be serialized as the entity reference &lt;. Each character item with the [character code] U+003E (the closing angle bracket character) MUST be serialized as the entity reference &gt;. Each character item with a [character code] in the range U+0001 to U+0008, U+000B to U+001F, or U+007F to U+009F MUST be serialized as a character reference. No other character item is permitted to be serialized as an entity reference or a character reference 🫧.

Character references, where they're allowed, SHALL use uppercase hexadecimal with no leading zeroes. For example, the carriage return character is represented as &#xD; 🌸.

A space character (U+0020) in an attribute item's [normalized value] MUST be serialized as a single U+0020 character ✨.

A character item with the [character code] U+000A MUST be serialized as a single U+000A character 🍓.

The white space separating the [target] and [content] in the serialization of a processing instruction item SHALL be exactly one space character (U+0020) 🧚.

Aside: A processing instruction or comment can only appear in a CRXER encoding if it's embedded in a Markup value 🦋.

6.12.3. Unicode Normalization in XML Version 1.1 ✨

okay so XML Version 1.1 recommends (not requires, just recommends 🙄) that text be normalized to Unicode Normalization Form C [UNICODE]. ASN.1 has no matching rule for abstract values of string types, and ASN.1 canonical encoding rules rely on the code points of characters being kept exactly as they are. so two rules, two different vibes 💅

to keep everybody happy, applications SHOULD normalize abstract values of ASN.1 character string types to Unicode Normalization Form C at the time the values are created 🌸 but they MUST NOT normalize a previously decoded abstract value of an ASN.1 character string type before re-encoding it 🚫 an application can still normalize a decoded value for other stuff though, like showing it to a user. that's totally fine 🫶

6.13. Syntax-Based Canonicalization 🦋

ASN.1 encoding rules are built to preserve abstract values, but they're not built to preserve every little detail of each transfer syntax that gets used. for RXER, that means the Infoset representation of an abstract value isn't necessarily kept when the value is decoded and re-encoded (no matter which encoding rules you use) 😭 but syntax-based canonicalization for XML documents (like Canonical XML [CXML]) depends on the Infoset of an XML document staying the same. so if an XML document contains an RXER encoding of an ASN.1 abstract value, its Infoset can change when that value gets decoded and re-encoded, and that messes up the Canonical XML representation 💀 extra normalization is needed if RXER is going to be used in places where syntax-based canonicalization is happening. it's giving "extra steps, but make it safe" ✨

before syntax-based canonicalization gets applied to an XML document, any element items in the document's Infoset that match the value of an ASN.1 top-level NamedType, or that have content and attributes matching an ASN.1 abstract value, MUST be replaced by the translation of that value according to CRXER 🎀

if an application uses Canonical XML but doesn't know anything about RXER, then it won't know to normalize RXER encodings 🙈 so if RXER gets deployed into an environment with apps like that, the Infoset translation for CRXER SHOULD be used for all RXER encodings. bestie, this is a lot of "make sure everyone's on the same page" energy 🧚

7. Transfer Syntax Identifiers 🍓

7.1. RXER Transfer Syntax 💜

xmled.org got the following OBJECT IDENTIFIER assigned to identify the Robust XML Encoding Rules 👑 it's under an arc that the Internet Assigned Numbers Authority (IANA) gave to xmled.org:

{ iso(1) identified-organization(3) dod(6)
  internet(1) private(4) enterprise(1)
  xmled(21472) asnx(1) encoding(1) rxer(0) }

this OBJECT IDENTIFIER would be used, for example, to describe the transfer syntax for an RXER encoded data-value in an EMBEDDED PDV value. the OID is the ID card for RXER ✨

7.2. CRXER Transfer Syntax 🌈

same deal here: xmled.org got the following OBJECT IDENTIFIER assigned to identify the Canonical Robust XML Encoding Rules, under an arc IANA gave to xmled.org 🦋

{ iso(1) identified-organization(3) dod(6)
  internet(1) private(4) enterprise(1)
  xmled(21472) asnx(1) encoding(1) crxer(1) }

this OBJECT IDENTIFIER would be used, for example, to describe the transfer syntax for a CRXER encoded data-value in an EMBEDDED PDV value. so RXER is rxer(0) and CRXER is crxer(1), same family, different siblings 👯‍♀️

8. Relationship to XER 🎀

RXER and the XML Encoding Rules (XER) [X.693] are separate, totally different, and incompatible ASN.1 encoding rules for making XML markup out of ASN.1 abstract values. they are not the same thing, no cap 🙅‍♀️ so RXER is unrelated to the XML value notation of X.680 [X.680].

this section walks through some of the big differences between RXER and XER 🔍

there are basically two flavours of XER: BASIC-XER (which has a canonical form called CANONICAL-XER) and EXTENDED-XER. the big difference is that EXTENDED-XER uses XER encoding instructions, but BASIC-XER (and so CANONICAL-XER too) ignores them 😭 EXTENDED-XER doesn't have a canonical variant. when something is shared by BASIC-XER and EXTENDED-XER, it'll just be called a characteristic of XER 💅

elements and attributes are the basic building blocks of an XML document, obviously 💖 schema languages for XML usually have a way to describe, name, and reference global (top-level) elements and attributes. global type definitions are more of a handy shortcut for defining what goes inside elements and attributes. traditional ASN.1 can define global types (and other global stuff that helps define types), but there's nothing like a global element or attribute definition. the main difference between RXER and XER is how that gap gets handled 🧚

with XER, type definitions are also treated as element definitions by default, or as attribute definitions if there's an XER ATTRIBUTE encoding instruction. sometimes an anonymous Type is needed to define an element, which is how you get weird element names like <BOOLEAN> and <SEQUENCE> 💀 NamedType notation also defines local elements, and there are some curious cases in EXTENDED-XER where NamedType notation can define a global type. so under XER, types can be defined with either Type or NamedType notation, and elements and attributes can also be defined with either one. it's a lot, bestie 🙈

with RXER, types are only defined by Type notation, and elements and attributes are only defined by NamedType notation. global element and attribute definitions are possible thanks to top-level NamedType notation in an RXER encoding control section ✨

RXER, with its clean split between Type notation for types and NamedType notation for elements and attributes, is a better starting point than XER for turning an ASN.1 specification into an XML representation (that's ASN.X [ASN.X]) or a compatible XML Schema. in those, type, element, and attribute definitions are also very separate things 🫶

there's usually a requirement on ASN.1 applications to stay backward compatible with encodings made by earlier versions. those encodings are typically BER. even with that backward-compatibility constraint, spec writers still have plenty of room to rewrite the older spec. for example, they can rename types, pull an in-line type definition out as a defined type (or the reverse), or swap a type definition for an equivalent parameterized reference 🦋 these changes don't change any BER, DER, CER [X.690], Packed Encoding Rules (PER) [X.691], or Generic String Encoding Rules (GSER) [GSER] encodings, so spec writers have felt free to make them to tidy things up 💅 but they can change the names of elements in the XER encoding, because XER uses types as element definitions 😭 RXER encodings are immune to that problem, so RXER encodings are more stable than XER encodings across revisions of an ASN.1 specification. that's literally why there's a first 'R' in RXER 👑 this is a huge win for interoperability 🌸

RXER has special handling for encoding values of the QName and Markup types. QName holds qualified names, and Markup can hold arbitrary untyped markup 💜 XER doesn't recognise any special types like these, but you can get the same effects as RXER's QName and Markup types by using XER encoding instructions. since CANONICAL-XER ignores encoding instructions, under XER an application can either support qualified names and untyped markup, or support canonical XML encodings, but not both 🙃 CRXER, on the other hand, has canonicalization rules for qualified names and for Markup ✨ also, EXTENDED-XER doesn't deal with normalizing untyped data for other ASN.1 canonical encoding rules (like DER; see Section 4.1.2) or with normalizing XML encodings for syntax-based canonicalization (like Canonical XML; see Section 6.13) 💀

both EXTENDED-XER and RXER use encoding instructions to define attributes, union types, list types, and more. since CANONICAL-XER ignores encoding instructions, under XER an application has to choose between using attributes, union types, list types, and so on, or supporting canonical XML encodings 😭 CRXER is different: its canonicalization rules cover all the encoding instructions for RXER 🎀

9. Security Considerations 🔐

RXER doesn't necessarily let the exact BER octet encoding of values of the TeletexString, VideotexString, GraphicString, or GeneralString types be rebuilt. so a transformation from DER to RXER and back to DER might not give you the original DER encoding back 😱 this happens because DER doesn't normalize values of these string types well enough. for example, a character in a TeletexString value that matches a specific ISO 10646 character can be encoded for BER in lots of different ways, and those ways look exactly the same in an RXER re-encoding of the TeletexString value. DER doesn't require any one of those character encodings over the others 🙈

because of all that, RXER MUST NOT be used to re-encode, for storage or transmission, ASN.1 abstract values whose original DER or CER encoding has to be recoverable, when their type definitions involve the TeletexString, VideotexString, GraphicString, or GeneralString type. that recovery is needed to verify digital signatures, so in those cases, protocols ought to use DER or a DER-reversible encoding 🚨 in other cases where ASN.1 canonical encoding rules are used, values of the Markup type must be normalized as described in Section 4.1.2.

a transformation from CRXER to BER and back to CRXER does reproduce the original CRXER encoding ✨ so it's safe to use BER, DER, or CER to re-encode ASN.1 abstract values whose original CRXER encoding has to be recoverable 🫶

digital signatures can also be calculated on the Canonical XML representation of an XML document. if RXER encodings show up in those documents, then applications must normalize the encodings as described in Section 6.13 🔥

the null character (U+0000) can't be represented in XML, so it can't be sent in an RXER encoding. null characters in abstract values of ASN.1 string types will get dropped if the values are RXER encoded 💀 so RXER MUST NOT be used by applications that attach significance to the null character. this one's a big deal, bestie 🚫

when interpreting security-sensitive fields, especially fields used to grant or deny access, implementations MUST ensure that any comparisons are done on the underlying abstract value, no matter which encoding was used 🔒 comparisons of Markup values MUST operate as though the values have been normalized as specified in Section 4.1.2. no shortcuts, no vibes-only checks, periodt 💅

10. Acknowledgements 🌷

the technology in this document is the product of a research project that Adacel Technologies Limited and Deakin University started together, and then eB2Bcom refined and finished 👏 big thanks to all the brains behind it 🫶

11. IANA Considerations 📋

the IANA registered a new XML namespace according to RFC 3688 [XMLREG]. here are the details, bestie:

URI:  urn:ietf:params:xml:ns:asnx
Registrant Contact:  Steven Legg <steven.legg@eb2bcom.com>
XML:  None

12. References 📚

12.1. Normative References 📚

okay so this is where the spec shows its receipts 💅 these are the normative references, the documents this one leans on, all listed with their full details 🫶

  • [BCP14] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 3629, November 2003.
  • [XMLREG] Mealling, M., "The IETF XML Registry", RFC 3688, January 2004.
  • [URI] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", STD 66, RFC 3986, January 2005.
  • [RXEREI] Legg, S., "Encoding Instructions for the Robust XML Encoding Rules (RXER)", RFC 4911, July 2007.
  • [ASN.X] Legg, S., "Abstract Syntax Notation X (ASN.X)", RFC 4912, July 2007.
  • [X.680] ITU-T Recommendation X.680 (07/02) | ISO/IEC 8824-1, Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation.
  • [X.680-1] ITU-T Recommendation X.680 (2002) Amendment 1 (10/03) | ISO/IEC 8824-1:2002/Amd 1:2004, Support for EXTENDED-XER.
  • [X.681] ITU-T Recommendation X.681 (07/02) | ISO/IEC 8824-2, Information technology - Abstract Syntax Notation One (ASN.1): Information object specification.
  • [X.682] ITU-T Recommendation X.682 (07/02) | ISO/IEC 8824-3, Information technology - Abstract Syntax Notation One (ASN.1): Constraint specification.
  • [X.683] ITU-T Recommendation X.683 (07/02) | ISO/IEC 8824-4, Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications.
  • [X.690] ITU-T Recommendation X.690 (07/02) | ISO/IEC 8825-1, Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).
  • [UCS] ISO/IEC 10646-1:2000, Information technology - Universal Multiple-Octet Coded Character Set (UCS) - Part 1: Architecture and Basic Multilingual Plane.
  • [UNICODE] The Unicode Consortium, "The Unicode Standard, Version 4.0", Boston, MA, Addison-Wesley Developers Press, 2003. ISBN 0-321-18578-1.
  • [XML10] Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E. and F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fourth Edition)", W3C Recommendation, http://www.w3.org/TR/2006/REC-xml-20060816, August 2006.
  • [XML11] Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., Yergeau, F., and J. Cowan, "Extensible Markup Language (XML) 1.1 (Second Edition)", W3C Recommendation, http://www.w3.org/TR/2006/REC-xml11-20060816, August 2006.
  • [XMLNS10] Bray, T., Hollander, D., Layman, A., and R. Tobin, "Namespaces in XML 1.0 (Second Edition)", W3C Recommendation, http://www.w3.org/TR/2006/REC-xml-names-20060816, August 2006.
  • [XMLNS11] Bray, T., Hollander, D., Layman, A. and R. Tobin, "Namespaces in XML 1.1 (Second Edition)", W3C Recommendation, http://www.w3.org/TR/2006/REC-xml-names11-20060816, August 2006.
  • [INFOSET] Cowan, J. and R. Tobin, "XML Information Set (Second Edition)", W3C Recommendation, http://www.w3.org/TR/2004/REC-xml-infoset-20040204, February 2004.
  • [XSD1] Thompson, H., Beech, D., Maloney, M. and N. Mendelsohn, "XML Schema Part 1: Structures Second Edition", W3C Recommendation, http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/, October 2004.

12.2. Informative References 🌸

these ones are the extra reading: good background, not the core rules 🧚

  • [GSER] Legg, S., "Generic String Encoding Rules (GSER) for ASN.1 Types", RFC 3641, October 2003.
  • [X.691] ITU-T Recommendation X.691 (07/02) | ISO/IEC 8825-4:2002, Information technology - ASN.1 encoding rules: Specification of Packed Encoding Rules (PER).
  • [X.693] ITU-T Recommendation X.693 (12/01) | ISO/IEC 8825-4:2002, Information technology - ASN.1 encoding rules: XML encoding rules (XER).
  • [XSD2] Biron, P. and A. Malhotra, "XML Schema Part 2: Datatypes Second Edition", W3C Recommendation, http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/, October 2004.
  • [CXML] Boyer, J., "Canonical XML Version 1.0", W3C Recommendation, http://www.w3.org/TR/2001/REC-xml-c14n-20010315, March 2001.

Appendix A. Additional Basic Definitions Module 🎀

okay this appendix is the ASN.1 module itself, and it's normative (so it counts just like the main text 👑). here's the whole thing, copied exactly 💜

AdditionalBasicDefinitions
    { iso(1) identified-organization(3) dod(6)
      internet(1) private(4) enterprise(1)
      xmled(21472) asnx(1) module(0) basic(0) }

   -- Copyright (C) The IETF Trust (2007).  This version of
   -- this ASN.1 module is part of RFC 4910; see the RFC itself
   -- for full legal notices.
   --
   -- Regarding this ASN.1 module or any portion of it, the authors
   -- make no guarantees and are not responsible for any damage
   -- resulting from its use.  The authors grant irrevocable permission
   -- to anyone to use, modify, and distribute it in any way that does
   -- not diminish the rights of anyone else to use, modify, and
   -- distribute it, provided that redistributed derivative works do
   -- not contain misleading author or version information.
   -- Derivative works need not be licensed under similar terms.

   DEFINITIONS
   RXER INSTRUCTIONS
   AUTOMATIC TAGS
   EXTENSIBILITY IMPLIED ::= BEGIN

   Markup ::= CHOICE {
       text    SEQUENCE {
           prolog      UTF8String (SIZE(1..MAX)) OPTIONAL,
           prefix      NCName OPTIONAL,
           attributes  UTF8String (SIZE(1..MAX)) OPTIONAL,
           content     UTF8String (SIZE(1..MAX)) OPTIONAL
       }
   }

   AnyURI ::= UTF8String (CONSTRAINED BY
                  { -- conforms to the format of a URI -- })

   NCName ::= UTF8String (CONSTRAINED BY
                  { -- conforms to the NCName production of
                    -- Namespaces in XML 1.0 -- })

   Name ::= UTF8String (CONSTRAINED BY
                  { -- conforms to the Name production of XML -- })

   QName ::= SEQUENCE {
       namespace-name  AnyURI OPTIONAL,
       local-name      NCName
   }

   ENCODING-CONTROL RXER

       TARGET-NAMESPACE "urn:ietf:params:xml:ns:asnx" PREFIX "asnx"

       COMPONENT context [ATTRIBUTE] [LIST] SEQUENCE OF prefix NCName

   END

Authors' Addresses 🦋

the two authors and where to find them ✨

Dr. Steven Legg
eB2Bcom
Suite 3, Woodhouse Corporate Centre
935 Station Street
Box Hill North, Victoria 3129
AUSTRALIA

Phone: +61 3 9896 7830
Fax:   +61 3 9896 7801
EMail: steven.legg@eb2bcom.com

Dr. Daniel Prager

EMail: dap@austhink.com

Copyright (C) The IETF Trust (2007).

this document is subject to the rights, licenses and restrictions in BCP 78, and except as set out there, the authors keep all their rights 💜

this document and the info in it are provided on an "AS IS" basis, and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Intellectual Property 💎

the IETF doesn't take a side on whether any IPR claims about this tech are valid or how far they reach, and it hasn't independently gone hunting for any either 🙈 the procedures for rights in RFC documents are in BCP 78 and BCP 79.

copies of IPR disclosures sent to the IETF Secretariat, plus any assurances of licenses or results of attempts to get a general license for implementers or users, can be found in the IETF online IPR repository at http://www.ietf.org/ipr.

the IETF also invites anyone to flag any copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to implement this standard. send that info to ietf-ipr@ietf.org 📬


Acknowledgement 🌈

funding for the RFC Editor function is currently provided by the Internet Society 🫶

📦 where this page comes from