From 1ec5d6882e54ebfbfd0c0e10d0a782d6c05119ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Mon, 22 Mar 1999 21:49:51 +0100
Subject: [PATCH] New combined_tag tag mechanism.

Rev: lib/modules/Standards.pmod/ASN1.pmod/Decode.pmod:1.6
Rev: lib/modules/Standards.pmod/ASN1.pmod/Types.pmod:1.7
---
 .../Standards.pmod/ASN1.pmod/Decode.pmod      | 79 +++++++++++--------
 .../Standards.pmod/ASN1.pmod/Types.pmod       | 24 +++++-
 2 files changed, 69 insertions(+), 34 deletions(-)

diff --git a/lib/modules/Standards.pmod/ASN1.pmod/Decode.pmod b/lib/modules/Standards.pmod/ASN1.pmod/Decode.pmod
index 0922bcd63a..dc5e29df48 100644
--- a/lib/modules/Standards.pmod/ASN1.pmod/Decode.pmod
+++ b/lib/modules/Standards.pmod/ASN1.pmod/Decode.pmod
@@ -13,38 +13,53 @@
  * FIXME: Handling of implicit and explicit ASN.1 tagging, as well as
  * other context dependence, is next to non_existant. */
 
+import .Types;
+
 class primitive
 {
-  int tag;
-  string raw;
+  import .Types;
 
+  constant constructed = 0;  
+  int combined_tag;
+  string raw;
+  
   string get_der() { return raw; }
-
+  int get_combined_tag() { return combined_tag; }
+  int get_tag() { return extract_tag(combined_tag); }
+  int get_cls() { return extract_cls(combined_tag); }
+  
   void create(int t, string r)
     {
-      tag = t;
+      combined_tag = t;
       raw = r;
     }
 
   string debug_string() 
     {
-      return sprintf("primitive(%d)", tag);
+      return sprintf("primitive(%d)", combined_tag);
     }
 }
 
 class constructed
 {
-  int tag;
+  import .Types;
+  
+  constant constructed = 1;
+  int combined_tag;
+  
   string raw;
-  array contents;
+  array elements;
   
   string get_der() { return raw; }
+  int get_combined_tag() { return combined_tag; }
+  int get_tag() { return extract_tag(combined_tag); }
+  int get_cls() { return extract_cls(combined_tag); }
 
-  void create(int t, string r, array c)
+  void create(int t, string r, array e)
     {
-      tag = t;
+      combined_tag = t;
       raw = r;
-      contents = c;
+      elements = e;
     }
 }
 
@@ -74,8 +89,8 @@ object|mapping der_decode(object data, mapping types)
   werror(sprintf("contents: %O\n", contents));
 #endif
 
-  int tag = raw_tag & 0xdf; // Class and tag bits
-  
+  int tag = make_combined_tag(raw_tag >> 6, raw_tag & 0x1f);
+
   program p = types[tag];
   
   if (raw_tag & 0x20)
@@ -129,26 +144,28 @@ object|mapping der_decode(object data, mapping types)
   }
 }
 
-import .Types;
+#define U(x) make_combined_tag(0, (x))
+
+mapping universal_types =
+([ U(1) : asn1_boolean,
+   U(2) : asn1_integer,
+   U(3) : asn1_bit_string,
+   U(4) : asn1_octet_string,
+   U(5) : asn1_null,
+   U(6) : asn1_identifier,
+   // U(9) : asn1_real,
+   // U(10) : asn1_enumerated,
+#if constant(asn1_utf8_string)
+   U(12) : asn1_utf8_string,
+#endif
+   U(16) : asn1_sequence,
+   U(17) : asn1_set,
+   U(19) : asn1_printable_string,
+   U(20) : asn1_teletex_string,
+   U(23) : asn1_utc
+  ]);
 
 object|mapping simple_der_decode(string data)
 {
-  return der_decode(ADT.struct(data),
-		    ([ // 1 : asn1_boolean,
-		       2 : asn1_integer,
-		       3 : asn1_bit_string,
-		       4 : asn1_octet_string,
-		       5 : asn1_null,
-		       6 : asn1_identifier,
-		       // 9 : asn1_real,
-		       // 10 : asn1_enumerated,
-#if constant(asn1_utf8_string)
-   		       12 : asn1_utf8_string,
-#endif
-		       16 : asn1_sequence,
-		       17 : asn1_set,
-		       19 : asn1_printable_string,
-		       20 : asn1_teletex_string,
-		       23 : asn1_utc
-		    ]) );
+  return der_decode(ADT.struct(data), universal_types);
 }
diff --git a/lib/modules/Standards.pmod/ASN1.pmod/Types.pmod b/lib/modules/Standards.pmod/ASN1.pmod/Types.pmod
index 15de549b0a..96f0ef3558 100644
--- a/lib/modules/Standards.pmod/ASN1.pmod/Types.pmod
+++ b/lib/modules/Standards.pmod/ASN1.pmod/Types.pmod
@@ -11,6 +11,18 @@
 
 #define error(msg) throw( ({ msg, backtrace() }) )
 
+
+/* Combines tag and class as a single integer, in a somewhat arbitrary
+ * way. This works also for tags beyond 31 (although not for tags
+ * beyond 2^30. */
+
+#define MAKE_COMBINED_TAG(cls, tag) (((tag) << 2) | (cls))
+int make_combined_tag(int cls, int tag)
+{ return MAKE_COMBINED_TAG(cls, tag); }
+
+int extract_tag(int i) { return i >> 2; }
+int extract_cls(int i) { return i & 3; }
+
 class asn1_object
 {
   constant cls = 0;
@@ -21,7 +33,9 @@ class asn1_object
   
   int get_cls() { return cls; }
   int get_tag() { return tag; }
-
+  int get_combinded_tag()
+    { return make_combined_tag(get_tag(), get_cls()); }
+  
   string der;
   
   // Should be overridden by subclasses 
@@ -520,6 +534,8 @@ class meta_explicit
 {
   /* meta-instances handle a particular explicit tag and set of types */
   int real_tag;
+  int real_cls;
+  
   mapping valid_types;
 
   class `()
@@ -529,7 +545,8 @@ class meta_explicit
       constant constructed = 1;
       
       int get_tag() { return real_tag; }
-  
+      int get_cls() { return real_cls; }
+      
       object contents;
 
       object init(object o)
@@ -574,8 +591,9 @@ class meta_explicit
 	}
     }
   
-  void create(int tag, mapping|void types)
+  void create(int cls, int tag, mapping|void types)
     {
+      real_cls = cls;
       real_tag = tag;
       valid_types = types;
     }
-- 
GitLab