x690sample DEFINITIONS ::= BEGIN -- This is taken from Appendix A of X.690. The same module is used by all -- X.690 series specifications of ASN.1 Encoding Rules. -- -- This doesn't exercise every feature, like OPTIONAL, not really DEFAULT, not -- EXPLICIT tagging, extensibility markers, etc., but it exercises some hard -- ones like SET and IMPLICIT tagging. -- -- Because we don't yet have an option to add a namespace prefix to generated -- symbols, to avoid conflicts with rfc2459's Name we're prefixing the type -- names here manually. -- -- WARNING: The encoding rules used for the sample encoding given in Appendix A -- of X.690, and used in lib/asn1/check-gen.c, is not specified in -- X.690! It seems very likely that it is neither CER nor DER but BER -- because the tags in the X690SamplePersonnelRecord (a SET { ... }) -- are not in canonical order: -- -- APPL CONS tag 0 = 133 bytes [0] -- APPL CONS tag 1 = 16 bytes [1] -- UNIV PRIM VisibleString = "John" -- UNIV PRIM VisibleString = "P" -- UNIV PRIM VisibleString = "Smith" -- -> CONTEXT CONS tag 0 = 10 bytes [0] -- UNIV PRIM VisibleString = "Director" -- -> APPL PRIM tag 2 = 1 bytes [2] IMPLICIT content -- ... -- -- The canonical ordering of members in SET { ... } types is by tag, -- with UNIVERSAL tags before APPLICATION tags, those before CONTEXT, -- and those before PRIVATE, and within each class from lowest to -- highest numeric tag value. See X.680, section 8.6, which is -- referenced from X.690, section 10.3. -- -- Here we can see that the `title` member should come _after_ the -- `number` member, but it does not. -- -- Our test relies on our compiler producing the same test data when -- encoding the structure that the given test data decodes to. That -- works here only because our compiler does NOT sort SET { ... } -- members as it should (since we always produce DER). -- -- Sorting SET members in the compiler is hard currently because we -- don't parse imported modules, so we don't know the tags of imported -- types, so we can only sort at run-time, which we don't do. -- -- There is an obvious workaround, however: sort the SET { ... } -- definition manually! X690SamplePersonnelRecord ::= [APPLICATION 0] IMPLICIT SET { name X690SampleName, title [0] VisibleString, number X690SampleEmployeeNumber, dateOfHire [1] X690SampleDate, nameOfSpouse [2] X690SampleName, -- Heimdal's ASN.1 compiler doesn't handle DEFAULT values for types for -- which it doesn't support literal values. children [3] IMPLICIT SEQUENCE OF X690SampleChildInformation -- DEFAULT {} } X690SampleChildInformation ::= SET { name X690SampleName, dateOfBirth [0] X690SampleDate } X690SampleName ::= [APPLICATION 1] IMPLICIT SEQUENCE { givenName VisibleString, initial VisibleString, familyName VisibleString } -- Range added for test convenience. X690SampleEmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) X690SampleDate::= [APPLICATION 3] IMPLICIT VisibleString --YYYYMMDD -- The following is value syntax for the above, but Heimdal's ASN.1 compiler -- does not yet support value syntax for anything other than OIDs, booleans, -- integers, and UTF-8 strings: -- -- { name { givenName "John", initial "P", familyName "Smith" }, -- title "Director", -- number 51, -- dateOfHire "19710917", -- nameOfSpouse {givenName "Mary", initial "T", familyName "Smith" }, -- children { -- {name {givenName "Ralph", initial "T", familyName "Smith" }, -- dateOfBirth "19571111"}, -- {name {givenName "Susan", initial "B", familyName "Jones" }, -- I dateOfBirth "19590717"} -- } -- } -- -- The encoding of this value is supposed to be (all hex) (adapted from X.690 -- Appendix A): -- -- 60818561101A044A6F686E1A01501A05536D697468A00A1A084469726563746F -- 72420133A10A43083139373130393137A21261101A044D6172791A01541A0553 -- 6D697468A342311F61111A0552616C70681A01541A05536D697468A00A430831 -- 39353731313131311F61111A05537573616E1A01421A05536D697468A00A4308 -- 3139353930373137 -- -- And a rough visualization of this is (adapted from X.690 Appendix A): -- -- T L -- 60 8185 # 3 -- Name -- T L -- 61 10 # 2 -- T L "John" -- 1A 04 4A6F686E # 6 -- T L "P" -- 1A 01 50 # 3 -- T L "Smith" -- 1A 05 536D697468 # 7 -- Title -- T L T L "Director" -- A0 0A 1A 08 4469726563746F72 #12 -- Emp. # -- 42 01 33 # 3 -- Date of hire -- A1 0A 43 08 3139373130393137 #12 -- Spouse -- A2 12 # 2 -- Name -- 61 10 # 2 -- 1A 04 4D617279 # 6 -- 1A 01 54 # 3 -- 1A 05 536D697468 # 7 -- Children -- A3 42 # 2 -- 31 1F # 2 -- Name -- 61 11 1A 05 52616C7068 # 9 -- 1A 01 54 # 3 -- 1A 05 536D697468 # 7 -- DoB -- A0 0A 43 08 3139353731313131 #12 -- 31 1F # 2 bytes -- 61 11 1A 05 537573616E # 9 bytes -- 1A 01 42 # 3 bytes -- 1A 05 536D697468 # 7 bytes -- A0 0A 43 08 3139353930373137 #12 bytes -- -- Our asn1_print program dumps this as follows, which looks correct: -- -- APPL CONS tag 0 = 133 bytes [0] -- APPL CONS tag 1 = 16 bytes [1] -- UNIV PRIM VisibleString = "John" -- UNIV PRIM VisibleString = "P" -- UNIV PRIM VisibleString = "Smith" -- CONTEXT CONS tag 0 = 10 bytes [0] -- UNIV PRIM VisibleString = "Director" -- APPL PRIM tag 2 = 1 bytes [2] IMPLICIT content -- CONTEXT CONS tag 1 = 10 bytes [1] -- APPL PRIM tag 3 = 8 bytes [3] IMPLICIT content -- CONTEXT CONS tag 2 = 18 bytes [2] -- APPL CONS tag 1 = 16 bytes [1] -- UNIV PRIM VisibleString = "Mary" -- UNIV PRIM VisibleString = "T" -- UNIV PRIM VisibleString = "Smith" -- CONTEXT CONS tag 3 = 66 bytes [3] -- UNIV CONS Set = 31 bytes { -- APPL CONS tag 1 = 17 bytes [1] -- UNIV PRIM VisibleString = "Ralph" -- UNIV PRIM VisibleString = "T" -- UNIV PRIM VisibleString = "Smith" -- CONTEXT CONS tag 0 = 10 bytes [0] -- APPL PRIM tag 3 = 8 bytes [3] IMPLICIT content -- } -- UNIV CONS Set = 31 bytes { -- APPL CONS tag 1 = 17 bytes [1] -- UNIV PRIM VisibleString = "Susan" -- UNIV PRIM VisibleString = "B" -- UNIV PRIM VisibleString = "Smith" -- CONTEXT CONS tag 0 = 10 bytes [0] -- APPL PRIM tag 3 = 8 bytes [3] IMPLICIT content -- } END