Added SILC_ASN1_ANY_PRIMITIVE to encode/decode any pre-encoded
[silc.git] / lib / silcasn1 / silcasn1_decode.c
index 17354ac154d8601858ff8184488a3a00dda16991..34b93ca26ab182020458843602b5556469b3f439 100644 (file)
@@ -296,12 +296,19 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
     indef = (opts & SILC_ASN1_INDEFINITE ? TRUE : FALSE);
 
     /* By default UNIVERSAL is implied unless the following conditions
-       are met when CONTEXT will apply. */
+       are met when CONTEXT will apply.  For SILC_ASN1_TAG_ANY_PRIMITIVE
+       the class is changed only if flags dictate it. */
     if (ber_class == SILC_BER_CLASS_UNIVERSAL) {
-      if (tag != type ||
-         opts & SILC_ASN1_IMPLICIT ||
-         opts & SILC_ASN1_EXPLICIT)
-       ber_class = SILC_BER_CLASS_CONTEXT;
+      if (type == SILC_ASN1_TAG_ANY_PRIMITIVE) {
+       if (opts & SILC_ASN1_IMPLICIT ||
+           opts & SILC_ASN1_EXPLICIT)
+         ber_class = SILC_BER_CLASS_CONTEXT;
+      } else {
+       if (tag != type ||
+           opts & SILC_ASN1_IMPLICIT ||
+           opts & SILC_ASN1_EXPLICIT)
+         ber_class = SILC_BER_CLASS_CONTEXT;
+      }
     }
 
     /* Now decode a BER encoded block from the source buffer.  It must be
@@ -411,6 +418,16 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
          break;
        }
 
+      case SILC_ASN1_TAG_ANY_PRIMITIVE:
+       {
+         /* ANY_PRIMITIVE returns the raw data blob of any primitive type. */
+         SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, prim);
+
+         *prim = silc_buffer_srealloc_size(stack1, *prim, rdata_len);
+         silc_buffer_put(*prim, rdata, rdata_len);
+         break;
+       }
+
       case SILC_ASN1_TAG_SEQUENCE:
       case SILC_ASN1_TAG_SET:
        {