Bug 1244960 - FIDO u2f NSSToken (Part 2): Use Attestation Certificates r?keeler draft
authorJ.C. Jones <jjones@mozilla.com>
Mon, 28 Mar 2016 18:55:52 -0700
changeset 352084 c1006e362201e771b42fd82dc557d4e6861425c2
parent 352083 7726ce532c75043e416c042c62e276c9083accf4
child 352085 8d6430bafde9338ea7c501436e020f0c3e5d9c96
push id15608
push userjjones@mozilla.com
push dateFri, 15 Apr 2016 16:33:37 +0000
reviewerskeeler
bugs1244960
milestone48.0a1
Bug 1244960 - FIDO u2f NSSToken (Part 2): Use Attestation Certificates r?keeler - Add an ephemeral self-signed Attestation Cert to NSSToken - A new one is generated at each call to Register; this is allowed by the protocol, and avoids fingerprinting if the NSSToken is in use. - This now passes at https://u2fdemo.appspot.com/ MozReview-Commit-ID: Aq61MuX9oSD
dom/u2f/tests/mochitest.ini
dom/u2f/tests/pkijs/LICENSE
dom/u2f/tests/pkijs/README
dom/u2f/tests/pkijs/asn1.js
dom/u2f/tests/pkijs/common.js
dom/u2f/tests/pkijs/x509_schema.js
dom/u2f/tests/pkijs/x509_simpl.js
dom/u2f/tests/test_frame.html
dom/u2f/tests/test_frame_register_sign.html
--- a/dom/u2f/tests/mochitest.ini
+++ b/dom/u2f/tests/mochitest.ini
@@ -10,12 +10,16 @@ support-files =
   test_frame_appid_facet_subdomain.html
   facet/facetList.txt
   facet/facetList-good
   facet/facetList-good^headers^
   facet/facetList-no_overlap
   facet/facetList-no_overlap^headers^
   facet/facetList-invalid_format
   facet/facetList-invalid_format^headers^
+  pkijs/common.js
+  pkijs/asn1.js
+  pkijs/x509_schema.js
+  pkijs/x509_simpl.js
 
 [test_util_methods.html]
 [test_no_token.html]
 [test_frame.html]
new file mode 100644
--- /dev/null
+++ b/dom/u2f/tests/pkijs/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, GMO GlobalSign
+Copyright (c) 2015, Peculiar Ventures
+All rights reserved.
+
+Author 2014-2015, Yury Strozhevsky
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/dom/u2f/tests/pkijs/README
@@ -0,0 +1,1 @@
+PKIjs and ASN1js are from https://pkijs.org/ and https://asn1js.org/.
\ No newline at end of file
new file mode 100755
--- /dev/null
+++ b/dom/u2f/tests/pkijs/asn1.js
@@ -0,0 +1,5466 @@
+/*
+ * Copyright (c) 2014, GMO GlobalSign
+ * Copyright (c) 2015, Peculiar Ventures
+ * All rights reserved.
+ *
+ * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE. 
+ *
+ */
+(
+function(in_window)
+{
+    //**************************************************************************************
+    // #region Declaration of global variables 
+    //**************************************************************************************
+    // #region "org" namespace 
+    if(typeof in_window.org === "undefined")
+        in_window.org = {};
+    else
+    {
+        if(typeof in_window.org !== "object")
+            throw new Error("Name org already exists and it's not an object");
+    }
+    // #endregion 
+
+    // #region "org.pkijs" namespace 
+    if(typeof in_window.org.pkijs === "undefined")
+        in_window.org.pkijs = {};
+    else
+    {
+        if(typeof in_window.org.pkijs !== "object")
+            throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
+    }
+    // #endregion 
+
+    // #region "org.pkijs.asn1" namespace 
+    if(typeof in_window.org.pkijs.asn1 === "undefined")
+        in_window.org.pkijs.asn1 = {};
+    else
+    {
+        if(typeof in_window.org.pkijs.asn1 !== "object")
+            throw new Error("Name org.pkijs.asn1 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.asn1));
+    }
+    // #endregion 
+
+    // #region "local" namespace 
+    var local = {};
+    // #endregion   
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Aux-functions 
+    //**************************************************************************************
+    function util_frombase(input_buffer, input_base)
+    {
+        /// <summary>Convert number from 2^base to 2^10</summary>
+        /// <param name="input_buffer" type="Uint8Array">Array of bytes representing the number to convert</param>
+        /// <param name="input_base" type="Number">The base of initial number</param>
+
+        var result = 0; 
+
+        for(var i = (input_buffer.length - 1); i >= 0; i-- )
+            result += input_buffer[(input_buffer.length - 1) - i] * Math.pow(2, input_base * i);
+
+        return result;
+    }
+    //**************************************************************************************
+    function util_tobase(value, base, reserved)
+    {
+        /// <summary>Convert number from 2^10 to 2^base</summary>
+        /// <param name="value" type="Number">The number to convert</param>
+        /// <param name="base" type="Number">The base for 2^base</param>
+        /// <param name="reserved" type="Number">Pre-defined number of bytes in output array (-1 = limited by function itself)</param>
+
+        reserved = reserved || (-1);
+
+        var result = 0;
+        var biggest = Math.pow(2, base);
+
+        for(var i = 1; i < 8; i++)
+        {
+            if(value < biggest)
+            {
+                var ret_buf;
+
+                if( reserved < 0 )
+                {
+                    ret_buf = new ArrayBuffer(i);
+                    result = i;
+                }
+                else
+                {
+                    if(reserved < i)
+                        return (new ArrayBuffer(0));
+
+                    ret_buf = new ArrayBuffer(reserved);
+
+                    result = reserved;
+                }
+
+                var ret_view = new Uint8Array(ret_buf);
+
+                for(var j = ( i - 1 ); j >= 0; j-- )
+                {
+                    var basis = Math.pow(2, j * base);
+
+                    ret_view[ result - j - 1 ] = Math.floor( value / basis );
+                    value -= ( ret_view[ result - j - 1 ] ) * basis;
+                }
+
+                return ret_buf;
+            }
+
+            biggest *= Math.pow(2, base);
+        }
+    }
+    //**************************************************************************************
+    function util_encode_tc(value)
+    {
+        /// <summary>Encode integer value to "two complement" format</summary>
+        /// <param name="value" type="Number">Value to encode</param>
+
+        var mod_value = (value < 0) ? (value * (-1)) : value;
+        var big_int = 128;
+
+        for(var i = 1; i < 8; i++) 
+        {
+            if( mod_value <= big_int )
+            {
+                if( value < 0 )
+                {
+                    var small_int = big_int - mod_value;
+
+                    var ret_buf = util_tobase( small_int, 8, i );
+                    var ret_view = new Uint8Array(ret_buf);
+
+                    ret_view[ 0 ] |= 0x80;
+
+                    return ret_buf;
+                }
+                else
+                {
+                    var ret_buf = util_tobase( mod_value, 8, i );
+                    var ret_view = new Uint8Array(ret_buf);
+
+                    if( ret_view[ 0 ] & 0x80 )
+                    {
+                        var temp_buf = util_copybuf(ret_buf);
+                        var temp_view = new Uint8Array(temp_buf);
+
+                        ret_buf = new ArrayBuffer( ret_buf.byteLength + 1 );
+                        ret_view = new Uint8Array(ret_buf);
+
+                        for(var k = 0; k < temp_buf.byteLength; k++)
+                            ret_view[k + 1] = temp_view[k];
+
+                        ret_view[0] = 0x00;
+                    }
+
+                    return ret_buf;
+                }
+            }
+
+            big_int *= Math.pow(2, 8);
+        }
+
+        return (new ArrayBuffer(0));
+    }
+    //**************************************************************************************
+    function util_decode_tc()
+    {
+        /// <summary>Decoding of "two complement" values</summary>
+        /// <remarks>The function must be called in scope of instance of "hex_block" class ("value_hex" and "warnings" properties must be present)</remarks>
+
+        var buf = new Uint8Array(this.value_hex);
+
+        if(this.value_hex.byteLength >= 2)
+        {
+            var condition_1 = (buf[0] == 0xFF) && (buf[1] & 0x80);
+            var condition_2 = (buf[0] == 0x00) && ((buf[1] & 0x80) == 0x00);
+
+            if(condition_1 || condition_2)
+                this.warnings.push("Needlessly long format");
+        }
+
+        // #region Create big part of the integer
+        var big_int_buffer = new ArrayBuffer(this.value_hex.byteLength);
+        var big_int_view = new Uint8Array(big_int_buffer);
+        for(var i = 0; i < this.value_hex.byteLength; i++)
+            big_int_view[i] = 0;
+
+        big_int_view[0] = (buf[0] & 0x80); // mask only the biggest bit
+
+        var big_int = util_frombase(big_int_view, 8);
+        // #endregion   
+
+        // #region Create small part of the integer 
+        var small_int_buffer = new ArrayBuffer(this.value_hex.byteLength);
+        var small_int_view = new Uint8Array(small_int_buffer);
+        for(var j = 0; j < this.value_hex.byteLength; j++)
+            small_int_view[j] = buf[j];
+
+        small_int_view[0] &= 0x7F; // mask biggest bit
+
+        var small_int = util_frombase(small_int_view, 8);
+        // #endregion 
+
+        return (small_int - big_int);
+    }
+    //**************************************************************************************
+    function util_copybuf(input_buffer)
+    {
+        /// <summary>Creating a copy of input ArrayBuffer</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
+
+        if(check_buffer_params(input_buffer, 0, input_buffer.byteLength) === false)
+            return (new ArrayBuffer(0));
+
+        var input_view = new Uint8Array(input_buffer);
+
+        var ret_buf = new ArrayBuffer(input_buffer.byteLength);
+        var ret_view = new Uint8Array(ret_buf);
+
+        for(var i = 0; i < input_buffer.byteLength; i++)
+            ret_view[i] = input_view[i];
+
+        return ret_buf;
+    }
+    //**************************************************************************************
+    function util_copybuf_offset(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Creating a copy of input ArrayBuffer</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
+
+        if(check_buffer_params(input_buffer, input_offset, input_length) === false)
+            return (new ArrayBuffer(0));
+
+        var input_view = new Uint8Array(input_buffer, input_offset, input_length);
+
+        var ret_buf = new ArrayBuffer(input_length);
+        var ret_view = new Uint8Array(ret_buf);
+
+        for(var i = 0; i < input_length; i++)
+            ret_view[i] = input_view[i];
+
+        return ret_buf;
+    }
+    //**************************************************************************************
+    function util_concatbuf(input_buf1, input_buf2)
+    {
+        /// <summary>Concatenate two ArrayBuffers</summary>
+        /// <param name="input_buf1" type="ArrayBuffer">First ArrayBuffer (first part of concatenated array)</param>
+        /// <param name="input_buf2" type="ArrayBuffer">Second ArrayBuffer (second part of concatenated array)</param>
+
+        var input_view1 = new Uint8Array(input_buf1);
+        var input_view2 = new Uint8Array(input_buf2);
+
+        var ret_buf = new ArrayBuffer(input_buf1.byteLength + input_buf2.byteLength);
+        var ret_view = new Uint8Array(ret_buf);
+
+        for(var i = 0; i < input_buf1.byteLength; i++)
+            ret_view[i] = input_view1[i];
+
+        for(var j = 0; j < input_buf2.byteLength; j++)
+            ret_view[input_buf1.byteLength + j] = input_view2[j];
+
+        return ret_buf;
+    }
+    //**************************************************************************************
+    function check_buffer_params(input_buffer, input_offset, input_length)
+    {
+        if((input_buffer instanceof ArrayBuffer) === false)
+        {
+            this.error = "Wrong parameter: input_buffer must be \"ArrayBuffer\"";
+            return false;
+        }
+
+        if(input_buffer.byteLength === 0)
+        {
+            this.error = "Wrong parameter: input_buffer has zero length";
+            return false;
+        }
+
+        if(input_offset < 0)
+        {
+            this.error = "Wrong parameter: input_offset less than zero";
+            return false;
+        }
+
+        if(input_length < 0)
+        {
+            this.error = "Wrong parameter: input_length less than zero";
+            return false;
+        }
+
+        if((input_buffer.byteLength - input_offset - input_length) < 0)
+        {
+            this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
+            return false;
+        }
+
+        return true;
+    }
+    //**************************************************************************************
+    function to_hex_codes(input_buffer, input_offset, input_lenght)
+    {
+        if(check_buffer_params(input_buffer, input_offset, input_lenght) === false)
+            return "";
+
+        var result = "";
+
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_lenght);
+        
+        for(var i = 0; i < int_buffer.length; i++)
+        {
+            var str = int_buffer[i].toString(16).toUpperCase();
+            result = result + ((str.length === 1) ? " 0" : " ") + str;
+        }
+
+        return result;
+    }
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of base block class 
+    //**************************************************************************************
+    local.base_block =
+    function()
+    {
+        /// <summary>General class of all ASN.1 blocks</summary>
+
+        if(arguments[0] instanceof Object)
+        {
+            this.block_length = in_window.org.pkijs.getValue(arguments[0], "block_length", 0);
+            this.error = in_window.org.pkijs.getValue(arguments[0], "error", new String());
+            this.warnings = in_window.org.pkijs.getValue(arguments[0], "warnings", new Array());
+            if("value_before_decode" in arguments[0])
+                this.value_before_decode = util_copybuf(arguments[0].value_before_decode);
+            else
+                this.value_before_decode = new ArrayBuffer(0);
+        }
+        else
+        {
+            this.block_length = 0;
+            this.error = new String();
+            this.warnings = new Array();
+            /// <field>Copy of the value of incoming ArrayBuffer done before decoding</field>
+            this.value_before_decode = new ArrayBuffer(0);
+        }
+    };
+    //**************************************************************************************
+    local.base_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "base_block";
+    };
+    //**************************************************************************************
+    local.base_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        return {
+            block_name: local.base_block.prototype.block_name.call(this),
+            block_length: this.block_length,
+            error: this.error,
+            warnings: this.warnings,
+            value_before_decode: in_window.org.pkijs.bufferToHexCodes(this.value_before_decode, 0, this.value_before_decode.byteLength)
+        };
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of hex block class 
+    //**************************************************************************************
+    local.hex_block =
+    function()
+    {
+        /// <summary>Descendant of "base_block" with internal ArrayBuffer. Need to have it in case it is not possible to store ASN.1 value in native formats</summary>
+
+        local.base_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
+            if("value_hex" in arguments[0])
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+            else
+                this.value_hex = new ArrayBuffer(0);
+        }
+        else
+        {
+            this.is_hex_only = false;
+            this.value_hex = new ArrayBuffer(0);
+        }
+    };
+    //**************************************************************************************
+    local.hex_block.prototype = new local.base_block();
+    local.hex_block.constructor = local.hex_block;
+    //**************************************************************************************
+    local.hex_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "hex_block";
+    };
+    //**************************************************************************************
+    local.hex_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.warnings.push("Zero buffer length");
+            return input_offset;
+        }
+        // #endregion 
+
+        // #region Copy input buffer to internal buffer 
+        this.value_hex = new ArrayBuffer(input_length);
+        var view = new Uint8Array(this.value_hex);
+
+        for(var i = 0; i < int_buffer.length; i++)
+            view[i] = int_buffer[i];
+        // #endregion 
+
+        this.block_length = input_length;
+
+        return (input_offset + input_length);
+    };
+    //**************************************************************************************
+    local.hex_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.is_hex_only !== true)
+        {
+            this.error = "Flag \"is_hex_only\" is not set, abort";
+            return (new ArrayBuffer(0));
+        }
+
+        var ret_buf = new ArrayBuffer(this.value_hex.byteLength);
+
+        if(size_only === true)
+            return ret_buf;
+
+        var ret_view = new Uint8Array(ret_buf);
+        var cur_view = new Uint8Array(this.value_hex);
+
+        for(var i = 0; i < cur_view.length; i++)
+            ret_view[i] = cur_view[i];
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    local.hex_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.base_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.hex_block.prototype.block_name.call(this);
+        _object.is_hex_only = this.is_hex_only;
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of identification block class 
+    //**************************************************************************************
+    local.identification_block =
+    function()
+    {
+        /// <summary>Base class of ASN.1 "identification block"</summary>
+
+        local.hex_block.call(this, arguments[0]);
+
+        this.tag_class = (-1);
+        this.tag_number = (-1);
+        this.is_constructed = false;
+
+        if(arguments[0] instanceof Object)
+        {
+            if("id_block" in arguments[0])
+            {
+                // #region Properties from hex_block class 
+                this.is_hex_only = in_window.org.pkijs.getValue(arguments[0].id_block, "is_hex_only", false);
+                this.value_hex = in_window.org.pkijs.getValue(arguments[0].id_block, "value_hex", new ArrayBuffer(0));
+                // #endregion   
+
+                this.tag_class = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_class", (-1));
+                this.tag_number = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_number", (-1));
+                this.is_constructed = in_window.org.pkijs.getValue(arguments[0].id_block, "is_constructed", false);
+            }
+        }
+    };
+    //**************************************************************************************
+    local.identification_block.prototype = new local.hex_block();
+    local.identification_block.constructor = local.identification_block;
+    //**************************************************************************************
+    local.identification_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "identification_block";
+    };
+    //**************************************************************************************
+    local.identification_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        var first_octet = 0;
+
+        switch(this.tag_class)
+        {
+            case 1:
+                first_octet |= 0x00; // UNIVERSAL
+                break;
+            case 2:
+                first_octet |= 0x40; // APPLICATION
+                break;
+            case 3:
+                first_octet |= 0x80; // CONTEXT-SPECIFIC
+                break;
+            case 4:
+                first_octet |= 0xC0; // PRIVATE
+                break;
+            default:
+                this.error = "Unknown tag class";
+                return (new ArrayBuffer(0));
+        }
+
+        if(this.is_constructed)
+            first_octet |= 0x20;
+
+        if((this.tag_number < 31) && (!this.is_hex_only))
+        {
+            var ret_buf = new ArrayBuffer(1);
+            var ret_view = new Uint8Array(ret_buf);
+
+            if(!size_only)
+            {
+                var number = this.tag_number;
+                number &= 0x1F;
+                first_octet |= number;
+
+                ret_view[0] = first_octet;
+            }
+
+            return ret_buf;
+        }
+        else
+        {
+            if(this.is_hex_only === false)
+            {
+                var encoded_buf = util_tobase(this.tag_number, 7);
+                var encoded_view = new Uint8Array(encoded_buf);
+                var size = encoded_buf.byteLength;
+
+                var ret_buf = new ArrayBuffer(size + 1);
+                var ret_view = new Uint8Array(ret_buf);
+
+                ret_view[0] = (first_octet | 0x1F);
+
+                if(!size_only)
+                {
+                    for(var i = 0; i < (size - 1) ; i++)
+                        ret_view[i + 1] = encoded_view[i] | 0x80;
+
+                    ret_view[size] = encoded_view[size - 1];
+                }
+
+                return ret_buf;
+            }
+            else
+            {
+                var ret_buf = new ArrayBuffer(this.value_hex.byteLength + 1);
+                var ret_view = new Uint8Array(ret_buf);
+
+                ret_view[0] = (first_octet | 0x1F);
+
+                if(size_only === false)
+                {
+                    var cur_view = new Uint8Array(this.value_hex);
+
+                    for(var i = 0; i < (cur_view.length - 1); i++)
+                        ret_view[i + 1] = cur_view[i] | 0x80;
+
+                    ret_view[this.value_hex.byteLength] = cur_view[cur_view.length - 1];
+                }
+
+                return ret_buf;
+            }
+        }
+    };
+    //**************************************************************************************
+    local.identification_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.error = "Zero buffer length";
+            return (-1);
+        }
+        // #endregion 
+
+        // #region Find tag class 
+        var tag_class_mask = int_buffer[0] & 0xC0;
+
+        switch(tag_class_mask)
+        {
+            case 0x00:
+                this.tag_class = (1); // UNIVERSAL
+                break;
+            case 0x40:
+                this.tag_class = (2); // APPLICATION
+                break;
+            case 0x80:
+                this.tag_class = (3); // CONTEXT-SPECIFIC
+                break;
+            case 0xC0:
+                this.tag_class = (4); // PRIVATE
+                break;
+            default:
+                this.error = "Unknown tag class";
+                return ( -1 );
+        }
+        // #endregion 
+
+        // #region Find it's constructed or not 
+        this.is_constructed = (int_buffer[0] & 0x20) == 0x20;
+        // #endregion 
+
+        // #region Find tag number 
+        this.is_hex_only = false;
+
+        var tag_number_mask = int_buffer[0] & 0x1F;
+
+        // #region Simple case (tag number < 31)
+        if(tag_number_mask != 0x1F) 
+        {
+            this.tag_number = (tag_number_mask);
+            this.block_length = 1;
+        }
+            // #endregion 
+        // #region Tag number bigger or equal to 31 
+        else
+        {
+            var count = 1;
+
+            this.value_hex = new ArrayBuffer(255);
+            var tag_number_buffer_max_length = 255;
+            var int_tag_number_buffer = new Uint8Array(this.value_hex);
+
+            while(int_buffer[count] & 0x80)
+            {
+                int_tag_number_buffer[count - 1] = int_buffer[count] & 0x7F;
+                count++;
+
+                if(count >= int_buffer.length)
+                {
+                    this.error = "End of input reached before message was fully decoded";
+                    return (-1);
+                }
+
+                // #region In case if tag number length is greater than 255 bytes (rare but possible case)
+                if(count == tag_number_buffer_max_length)
+                {
+                    tag_number_buffer_max_length += 255;
+
+                    var temp_buffer = new ArrayBuffer(tag_number_buffer_max_length);
+                    var temp_buffer_view = new Uint8Array(temp_buffer);
+
+                    for(var i = 0; i < int_tag_number_buffer.length; i++)
+                        temp_buffer_view[i] = int_tag_number_buffer[i];
+
+                    this.value_hex = new ArrayBuffer(tag_number_buffer_max_length);
+                    int_tag_number_buffer = new Uint8Array(this.value_hex);
+                }
+                // #endregion 
+            }
+
+            this.block_length = (count + 1);
+            int_tag_number_buffer[count - 1] = int_buffer[count] & 0x7F; // Write last byte to buffer
+
+            // #region Cut buffer 
+            var temp_buffer = new ArrayBuffer(count);
+            var temp_buffer_view = new Uint8Array(temp_buffer);
+            for(var i = 0; i < count; i++)
+                temp_buffer_view[i] = int_tag_number_buffer[i];
+
+            this.value_hex = new ArrayBuffer(count);
+            int_tag_number_buffer = new Uint8Array(this.value_hex);
+            int_tag_number_buffer.set(temp_buffer_view);
+            // #endregion 
+
+            // #region Try to convert long tag number to short form 
+            if(this.block_length <= 9)
+                this.tag_number = util_frombase(int_tag_number_buffer, 7);
+            else
+            {
+                this.is_hex_only = true;
+                this.warnings.push("Tag too long, represented as hex-coded");
+            }
+            // #endregion 
+        }
+        // #endregion 
+        // #endregion 
+
+        // #region Check if constructed encoding was using for primitive type 
+        if(((this.tag_class == 1)) &&
+            (this.is_constructed))
+        {
+            switch(this.tag_number)
+            {
+                case 1:  // BOOLEAN
+                case 2:  // REAL
+                case 5:  // NULL
+                case 6:  // OBJECT IDENTIFIER
+                case 9:  // REAL
+                case 14: // TIME
+                case 23:
+                case 24:
+                case 31:
+                case 32:
+                case 33:
+                case 34:
+                    this.error = "Constructed encoding used for primitive type";
+                    return (-1);
+                default:
+                    ;
+            }
+        }
+        // #endregion 
+
+        return ( input_offset + this.block_length ); // Return current offset in input buffer
+    };
+    //**************************************************************************************
+    local.identification_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.identification_block.prototype.block_name.call(this);
+        _object.tag_class = this.tag_class;
+        _object.tag_number = this.tag_number;
+        _object.is_constructed = this.is_constructed;
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of length block class 
+    //**************************************************************************************
+    local.length_block =
+    function()
+    {
+        /// <summary>Base class of ASN.1 "length block"</summary>
+
+        local.base_block.call(this, arguments[0]);
+
+        this.is_indefinite_form = false;
+        this.long_form_used = false;
+        this.length = (0);
+
+        if(arguments[0] instanceof Object)
+        {
+            if("len_block" in arguments[0])
+            {
+                this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0].len_block, "is_indefinite_form", false);
+                this.long_form_used = in_window.org.pkijs.getValue(arguments[0].len_block, "long_form_used", false);
+                this.length = in_window.org.pkijs.getValue(arguments[0].len_block, "length", 0);
+            }
+        }
+    };
+    //**************************************************************************************
+    local.length_block.prototype = new local.base_block();
+    local.length_block.constructor = local.length_block;
+    //**************************************************************************************
+    local.length_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "length_block";
+    };
+    //**************************************************************************************
+    local.length_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.error = "Zero buffer length";
+            return (-1);
+        }
+
+        if(int_buffer[0] == 0xFF)
+        {
+            this.error = "Length block 0xFF is reserved by standard";
+            return (-1);
+        }
+        // #endregion 
+
+        // #region Check for length form type 
+        this.is_indefinite_form = int_buffer[0] == 0x80;
+        // #endregion 
+
+        // #region Stop working in case of indefinite length form 
+        if(this.is_indefinite_form == true)
+        {
+            this.block_length = 1;
+            return (input_offset + this.block_length);
+        }
+        // #endregion 
+
+        // #region Check is long form of length encoding using 
+        this.long_form_used = !!(int_buffer[0] & 0x80);
+        // #endregion 
+
+        // #region Stop working in case of short form of length value 
+        if(this.long_form_used == false)
+        {
+            this.length = (int_buffer[0]);
+            this.block_length = 1;
+            return (input_offset + this.block_length);
+        }
+        // #endregion 
+
+        // #region Calculate length value in case of long form 
+        var count = int_buffer[0] & 0x7F;
+
+        if(count > 8) // Too big length value
+        {
+            this.error = "Too big integer";
+            return (-1);
+        }
+
+        if((count + 1) > int_buffer.length)
+        {
+            this.error = "End of input reached before message was fully decoded";
+            return (-1);
+        }
+
+        var length_buffer_view = new Uint8Array(count);
+
+        for(var i = 0; i < count; i++)
+            length_buffer_view[i] = int_buffer[i + 1];
+
+        if(length_buffer_view[count - 1] == 0x00)
+            this.warnings.push("Needlessly long encoded length");
+
+        this.length = util_frombase(length_buffer_view, 8);
+
+        if(this.long_form_used && (this.length <= 127))
+            this.warnings.push("Unneccesary usage of long length form");
+
+        this.block_length = count + 1;
+        // #endregion 
+
+        return (input_offset + this.block_length); // Return current offset in input buffer
+    };
+    //**************************************************************************************
+    local.length_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.length > 127)
+            this.long_form_used = true;
+
+        if(this.is_indefinite_form)
+        {
+            var ret_buf = new ArrayBuffer(1);
+
+            if(size_only === false)
+            {
+                var ret_view = new Uint8Array(ret_buf);
+                ret_view[0] = 0x80;
+            }
+
+            return ret_buf;
+        }
+
+        if(this.long_form_used === true)
+        {
+            var encoded_buf = util_tobase(this.length, 8);
+
+            if(encoded_buf.byteLength > 127)
+            {
+                this.error = "Too big length";
+                return (new ArrayBuffer(0));
+            }
+
+            var ret_buf = new ArrayBuffer(encoded_buf.byteLength + 1);
+
+            if(size_only === true)
+                return ret_buf;
+
+            var encoded_view = new Uint8Array(encoded_buf);
+            var ret_view = new Uint8Array(ret_buf);
+
+            ret_view[0] = encoded_buf.byteLength | 0x80;
+
+            for(var i = 0; i < encoded_buf.byteLength; i++)
+                ret_view[i + 1] = encoded_view[i];
+
+            return ret_buf;
+        }
+        else
+        {
+            var ret_buf = new ArrayBuffer(1);
+
+            if(size_only === false)
+            {
+                var ret_view = new Uint8Array(ret_buf);
+
+                ret_view[0] = this.length;
+            }
+
+            return ret_buf;
+        }
+
+        return (new ArrayBuffer(0));
+    };
+    //**************************************************************************************
+    local.length_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.base_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.length_block.prototype.block_name.call(this);
+        _object.is_indefinite_form = this.is_indefinite_form;
+        _object.long_form_used = this.long_form_used;
+        _object.length = this.length;
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of value block class 
+    //**************************************************************************************
+    local.value_block =
+    function()
+    {
+        /// <summary>Generic class of ASN.1 "value block"</summary>
+        local.base_block.call(this, arguments[0]);
+    };
+    //**************************************************************************************
+    local.value_block.prototype = new local.base_block();
+    local.value_block.constructor = local.value_block;
+    //**************************************************************************************
+    local.value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "value_block";
+    };
+    //**************************************************************************************
+    local.value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.base_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.value_block.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of basic ASN.1 block class 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block =
+    function()
+    {
+        /// <summary>Base class of ASN.1 block (identification block + length block + value block)</summary>
+
+        local.base_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
+            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
+
+            if("primitive_schema" in arguments[0])
+                this.primitive_schema = arguments[0].primitive_schema;
+        }
+
+        this.id_block = new local.identification_block(arguments[0]);
+        this.len_block = new local.length_block(arguments[0]);
+        this.value_block = new local.value_block(arguments[0]);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block.prototype = new local.base_block();
+    in_window.org.pkijs.asn1.ASN1_block.constructor = in_window.org.pkijs.asn1.ASN1_block;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "ASN1_block";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        var ret_buf;
+
+        var id_block_buf = this.id_block.toBER(size_only);
+        var value_block_size_buf = this.value_block.toBER(true);
+
+        this.len_block.length = value_block_size_buf.byteLength;
+        var len_block_buf = this.len_block.toBER(size_only);
+
+        ret_buf = util_concatbuf(id_block_buf, len_block_buf);
+
+        var value_block_buf;
+
+        if(size_only === false)
+            value_block_buf = this.value_block.toBER(size_only);
+        else
+            value_block_buf = new ArrayBuffer(this.len_block.length);
+
+        ret_buf = util_concatbuf(ret_buf, value_block_buf);
+
+        if(this.len_block.is_indefinite_form === true)
+        {
+            var indef_buf = new ArrayBuffer(2);
+
+            if(size_only === false)
+            {
+                var indef_view = new Uint8Array(indef_buf);
+
+                indef_view[0] = 0x00;
+                indef_view[1] = 0x00;
+            }
+
+            ret_buf = util_concatbuf(ret_buf, indef_buf);
+        }
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.base_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.ASN1_block.prototype.block_name.call(this);
+        _object.id_block = this.id_block.toJSON();
+        _object.len_block = this.len_block.toJSON();
+        _object.value_block = this.value_block.toJSON();
+
+        if("name" in this)
+            _object.name = this.name;
+        if("optional" in this)
+            _object.optional = this.optional;
+        if("primitive_schema" in this)
+            _object.primitive_schema = this.primitive_schema.toJSON();
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of basic block for all PRIMITIVE types 
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block =
+    function()
+    {
+        /// <summary>Base class of ASN.1 value block for primitive values (non-constructive encoding)</summary>
+
+        local.value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            // #region Variables from "hex_block" class 
+            if("value_hex" in arguments[0])
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+            else
+                this.value_hex = new ArrayBuffer(0);
+
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", true);
+            // #endregion 
+        }
+        else
+        {
+            // #region Variables from "hex_block" class 
+            this.value_hex = new ArrayBuffer(0);
+            this.is_hex_only = true;
+            // #endregion 
+        }
+    };
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block.prototype = new local.value_block();
+    local.ASN1_PRIMITIVE_value_block.constructor = local.ASN1_PRIMITIVE_value_block;
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.warnings.push("Zero buffer length");
+            return input_offset;
+        }
+        // #endregion 
+
+        // #region Copy input buffer into internal buffer 
+        this.value_hex = new ArrayBuffer(int_buffer.length);
+        var value_hex_view = new Uint8Array(this.value_hex);
+
+        for(var i = 0; i < int_buffer.length; i++)
+            value_hex_view[i] = int_buffer[i];
+        // #endregion 
+
+        this.block_length = input_length;
+
+        return (input_offset + input_length);
+    };
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        return util_copybuf(this.value_hex);
+    };
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "ASN1_PRIMITIVE_value_block";
+    };
+    //**************************************************************************************
+    local.ASN1_PRIMITIVE_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.ASN1_PRIMITIVE_value_block.prototype.block_name.call(this);
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+        _object.is_hex_only = this.is_hex_only;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_PRIMITIVE =
+    function()
+    {
+        /// <summary>Base class of ASN.1 block for primitive values (non-constructive encoding)</summary>
+
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.id_block.is_constructed = false;
+        this.value_block = new local.ASN1_PRIMITIVE_value_block(arguments[0]);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.constructor = in_window.org.pkijs.asn1.ASN1_PRIMITIVE;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "PRIMITIVE";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of basic block for all CONSTRUCTED types 
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block =
+    function()
+    {
+        /// <summary>Base class of ASN.1 value block for constructive values (constructive encoding)</summary>
+
+        local.value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new Array());
+            this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0], "is_indefinite_form", false);
+        }
+        else
+        {
+            this.value = new Array();
+            this.is_indefinite_form = false;
+        }
+    };
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block.prototype = new local.value_block();
+    local.ASN1_CONSTRUCTED_value_block.constructor = local.ASN1_CONSTRUCTED_value_block;
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Store initial offset and length 
+        var initial_offset = input_offset;
+        var initial_length = input_length;
+        // #endregion 
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.warnings.push("Zero buffer length");
+            return input_offset;
+        }
+        // #endregion 
+
+        // #region Aux function 
+        function check_len(_indefinite_length, _length)
+        {
+            if(_indefinite_length == true)
+                return 1;
+
+            return _length;
+        }
+        // #endregion 
+
+        var current_offset = input_offset;
+
+        while(check_len(this.is_indefinite_form, input_length) > 0)
+        {
+            var return_object = fromBER_raw(input_buffer, current_offset, input_length);
+            if(return_object.offset == (-1))
+            {
+                this.error = return_object.result.error;
+                this.warnings.concat(return_object.result.warnings);
+                return (-1);
+            }
+
+            current_offset = return_object.offset;
+
+            this.block_length += return_object.result.block_length;
+            input_length -= return_object.result.block_length;
+
+            this.value.push(return_object.result);
+
+            if((this.is_indefinite_form == true) && (return_object.result.block_name() == in_window.org.pkijs.asn1.EOC.prototype.block_name()))
+                break;
+        }
+
+        if(this.is_indefinite_form == true)
+        {
+            if(this.value[this.value.length - 1].block_name() == in_window.org.pkijs.asn1.EOC.prototype.block_name())
+                this.value.pop();
+            else
+                this.warnings.push("No EOC block encoded");
+        }
+
+        // #region Copy "input_buffer" to "value_before_decode" 
+        this.value_before_decode = util_copybuf_offset(input_buffer, initial_offset, initial_length);
+        // #endregion 
+
+        return current_offset;
+    };
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        var ret_buf = new ArrayBuffer(0);
+
+        for(var i = 0; i < this.value.length; i++)
+        {
+            var value_buf = this.value[i].toBER(size_only);
+            ret_buf = util_concatbuf(ret_buf, value_buf);
+        }
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "ASN1_CONSTRUCTED_value_block";
+    };
+    //**************************************************************************************
+    local.ASN1_CONSTRUCTED_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.ASN1_CONSTRUCTED_value_block.prototype.block_name.call(this);
+        _object.is_indefinite_form = this.is_indefinite_form;
+        _object.value = new Array();
+        for(var i = 0; i < this.value.length; i++)
+            _object.value.push(this.value[i].toJSON());
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED =
+    function()
+    {
+        /// <summary>Base class of ASN.1 block for constructive values (constructive encoding)</summary>
+
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.id_block.is_constructed = true;
+        this.value_block = new local.ASN1_CONSTRUCTED_value_block(arguments[0]);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.constructor = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "CONSTRUCTED";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 EOC type class
+    //**************************************************************************************
+    local.EOC_value_block =
+    function()
+    {
+        local.value_block.call(this, arguments[0]);
+    };
+    //**************************************************************************************
+    local.EOC_value_block.prototype = new local.value_block();
+    local.EOC_value_block.constructor = local.EOC_value_block;
+    //**************************************************************************************
+    local.EOC_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region There is no "value block" for EOC type and we need to return the same offset 
+        return input_offset;
+        // #endregion 
+    };
+    //**************************************************************************************
+    local.EOC_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        return (new ArrayBuffer(0));
+    };
+    //**************************************************************************************
+    local.EOC_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "EOC_value_block";
+    };
+    //**************************************************************************************
+    local.EOC_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.EOC_value_block.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.EOC =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.EOC_value_block();
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 0; // EOC
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.EOC.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.EOC.constructor = local.EOC_value_block;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.EOC.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "END_OF_CONTENT";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.EOC.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.EOC.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 BOOLEAN type class
+    //**************************************************************************************
+    local.BOOLEAN_value_block =
+    function()
+    {
+        local.value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.value = in_window.org.pkijs.getValue(arguments[0], "value", false);
+
+            // #region Variables from hex_block class 
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
+            if("value_hex" in arguments[0])
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+            else
+            {
+                this.value_hex = new ArrayBuffer(1);
+                if(this.value === true)
+                {
+                    var view = new Uint8Array(this.value_hex);
+                    view[0] = 0xFF;
+                }
+            }
+            // #endregion 
+        }
+        else
+        {
+            this.value = false;
+
+            // #region Variables from hex_block class 
+            this.is_hex_only = false;
+            this.value_hex = new ArrayBuffer(1);
+            // #endregion 
+        }
+    };
+    //**************************************************************************************
+    local.BOOLEAN_value_block.prototype = new local.value_block();
+    local.BOOLEAN_value_block.constructor = local.BOOLEAN_value_block;
+    //**************************************************************************************
+    local.BOOLEAN_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        if(input_length > 1)
+            this.warnings.push("BOOLEAN value encoded in more then 1 octet");
+
+        this.value = int_buffer[0] != 0x00;
+
+        this.is_hex_only = true;
+
+        // #region Copy input buffer to internal array 
+        this.value_hex = new ArrayBuffer(int_buffer.length);
+        var view = new Uint8Array(this.value_hex);
+
+        for(var i = 0; i < int_buffer.length; i++)
+            view[i] = int_buffer[i];
+        // #endregion 
+
+        this.block_length = input_length;
+
+        return (input_offset + input_length);
+    };
+    //**************************************************************************************
+    local.BOOLEAN_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        return this.value_hex;
+    };
+    //**************************************************************************************
+    local.BOOLEAN_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BOOLEAN_value_block";
+    };
+    //**************************************************************************************
+    local.BOOLEAN_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.BOOLEAN_value_block.prototype.block_name.call(this);
+        _object.value = this.value;
+        _object.is_hex_only = this.is_hex_only;
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BOOLEAN =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.BOOLEAN_value_block(arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 1; // BOOLEAN
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BOOLEAN.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.BOOLEAN.constructor = local.BOOLEAN_value_block;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BOOLEAN.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BOOLEAN";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BOOLEAN.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.BOOLEAN.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 SEQUENCE and SET type classes
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SEQUENCE =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 16; // SEQUENCE
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SEQUENCE.prototype = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
+    in_window.org.pkijs.asn1.SEQUENCE.constructor = in_window.org.pkijs.asn1.SEQUENCE;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SEQUENCE.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "SEQUENCE";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SEQUENCE.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.SEQUENCE.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SET =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 17; // SET
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SET.prototype = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
+    in_window.org.pkijs.asn1.SET.constructor = in_window.org.pkijs.asn1.SET;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SET.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "SET";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.SET.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.SET.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 NULL type class 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 5; // NULL
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.NULL.constructor = in_window.org.pkijs.asn1.NULL;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "NULL";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        if(this.len_block.length > 0)
+            this.warnings.push("Non-zero length of value block for NULL type");
+
+        if(this.id_block.error.length === 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length === 0)
+            this.block_length += this.len_block.block_length;
+
+        this.block_length += input_length;
+
+        return (input_offset + input_length);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        var ret_buf = new ArrayBuffer(2);
+
+        if(size_only === true)
+            return ret_buf;
+
+        var ret_view = new Uint8Array(ret_buf);
+        ret_view[0] = 0x05;
+        ret_view[1] = 0x00;
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NULL.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.NULL.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 OCTETSTRING type class 
+    //**************************************************************************************
+    local.OCTETSTRING_value_block =
+    function()
+    {
+        /// <param name="input_value_hex" type="ArrayBuffer"></param>
+        /// <param name="input_value" type="Array"></param>
+        /// <param name="input_constructed" type="Boolean"></param>
+        /// <remarks>Value for the OCTETSTRING may be as hex, as well as a constructed value.</remarks>
+        /// <remarks>Constructed values consists of other OCTETSTRINGs</remarks>
+
+        local.ASN1_CONSTRUCTED_value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.is_constructed = in_window.org.pkijs.getValue(arguments[0], "is_constructed", false);
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
+            if("value_hex" in arguments[0])
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+            else
+                this.value_hex = new ArrayBuffer(0);
+            // #endregion 
+        }
+        else
+        {
+            this.is_constructed = false;
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = false;
+            this.value_hex = new ArrayBuffer(0);
+            // #endregion 
+        }
+    };
+    //**************************************************************************************
+    local.OCTETSTRING_value_block.prototype = new local.ASN1_CONSTRUCTED_value_block();
+    local.OCTETSTRING_value_block.constructor = local.OCTETSTRING_value_block;
+    //**************************************************************************************
+    local.OCTETSTRING_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = 0;
+
+        if(this.is_constructed == true)
+        {
+            this.is_hex_only = false;
+
+            result_offset = local.ASN1_CONSTRUCTED_value_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+            if(result_offset == (-1))
+                return result_offset;
+
+            for(var i = 0; i < this.value.length; i++)
+            {
+                var current_block_name = this.value[i].block_name();
+
+                if(current_block_name == in_window.org.pkijs.asn1.EOC.prototype.block_name())
+                {
+                    if(this.is_indefinite_form == true)
+                        break;
+                    else
+                    {
+                        this.error = "EOC is unexpected, OCTET STRING may consists of OCTET STRINGs only";
+                        return (-1);
+                    }
+                }
+
+                if(current_block_name != in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name())
+                {
+                    this.error = "OCTET STRING may consists of OCTET STRINGs only";
+                    return (-1);
+                }
+            }
+        }
+        else
+        {
+            this.is_hex_only = true;
+
+            result_offset = local.hex_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+            this.block_length = input_length;
+        }
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    local.OCTETSTRING_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.is_constructed === true)
+            return local.ASN1_CONSTRUCTED_value_block.prototype.toBER.call(this, size_only);
+        else
+        {
+            var ret_buf = new ArrayBuffer(this.value_hex.byteLength);
+
+            if(size_only === true)
+                return ret_buf;
+
+            if(this.value_hex.byteLength == 0)
+                return ret_buf;
+
+            ret_buf = util_copybuf(this.value_hex);
+
+            return ret_buf;
+        }
+
+        return (new ArrayBuffer(0));
+    };
+    //**************************************************************************************
+    local.OCTETSTRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "OCTETSTRING_value_block";
+    };
+    //**************************************************************************************
+    local.OCTETSTRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.ASN1_CONSTRUCTED_value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.OCTETSTRING_value_block.prototype.block_name.call(this);
+        _object.is_constructed = this.is_constructed;
+        _object.is_hex_only = this.is_hex_only;
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.OCTETSTRING_value_block(arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 4; // OCTETSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.OCTETSTRING.constructor = in_window.org.pkijs.asn1.OCTETSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        this.value_block.is_constructed = this.id_block.is_constructed;
+        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
+
+        // #region Ability to encode empty OCTET STRING 
+        if(input_length == 0)
+        {
+            if(this.id_block.error.length == 0)
+                this.block_length += this.id_block.block_length;
+
+            if(this.len_block.error.length == 0)
+                this.block_length += this.len_block.block_length;
+
+            return input_offset;
+        }
+        // #endregion 
+
+        return in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name =
+    function()
+    {
+        return "OCTETSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OCTETSTRING.prototype.isEqual =
+    function(octetString)
+    {
+        /// <summaryChecking that two OCTETSTRINGs are equal></summary>
+        /// <param name="octetString" type="in_window.org.pkijs.asn1.OCTETSTRING">The OCTETSTRING to compare with</param>
+
+        // #region Check input type 
+        if((octetString instanceof in_window.org.pkijs.asn1.OCTETSTRING) == false)
+            return false;
+        // #endregion 
+
+        // #region Compare two JSON strings 
+        if(JSON.stringify(this) != JSON.stringify(octetString))
+            return false;
+        // #endregion 
+
+        return true;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 BITSTRING type class
+    //**************************************************************************************
+    local.BITSTRING_value_block =
+    function()
+    {
+        local.ASN1_CONSTRUCTED_value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.unused_bits = in_window.org.pkijs.getValue(arguments[0], "unused_bits", 0);
+            this.is_constructed = in_window.org.pkijs.getValue(arguments[0], "is_constructed", false);
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
+
+            if("value_hex" in arguments[0])
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+            else
+                this.value_hex = new ArrayBuffer(0);
+
+            this.block_length = this.value_hex.byteLength;
+            // #endregion 
+        }
+        else
+        {
+            this.unused_bits = 0;
+            this.is_constructed = false;
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = false;
+            this.value_hex = new ArrayBuffer(0);
+            // #endregion 
+        }
+    };
+    //**************************************************************************************
+    local.BITSTRING_value_block.prototype = new local.ASN1_CONSTRUCTED_value_block();
+    local.BITSTRING_value_block.constructor = local.BITSTRING_value_block;
+    //**************************************************************************************
+    local.BITSTRING_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Ability to decode zero-length BITSTRING value 
+        if(input_length == 0)
+            return input_offset;
+        // #endregion 
+
+        var result_offset = (-1);
+
+        // #region If the BISTRING supposed to be a constructed value 
+        if(this.is_constructed == true)
+        {
+            result_offset = local.ASN1_CONSTRUCTED_value_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+            if(result_offset == (-1))
+                return result_offset;
+
+            for(var i = 0; i < this.value.length; i++)
+            {
+                var current_block_name = this.value[i].block_name();
+
+                if(current_block_name == in_window.org.pkijs.asn1.EOC.prototype.block_name())
+                {
+                    if(this.is_indefinite_form == true)
+                        break;
+                    else
+                    {
+                        this.error = "EOC is unexpected, BIT STRING may consists of BIT STRINGs only";
+                        return (-1);
+                    }
+                }
+
+                if(current_block_name != in_window.org.pkijs.asn1.BITSTRING.prototype.block_name())
+                {
+                    this.error = "BIT STRING may consists of BIT STRINGs only";
+                    return (-1);
+                }
+
+                if((this.unused_bits > 0) && (this.value[i].unused_bits > 0))
+                {
+                    this.error = "Usign of \"unused bits\" inside constructive BIT STRING allowed for least one only";
+                    return (-1);
+                }
+                else
+                {
+                    this.unused_bits = this.value[i].unused_bits;
+                    if(this.unused_bits > 7)
+                    {
+                        this.error = "Unused bits for BITSTRING must be in range 0-7";
+                        return (-1);
+                    }
+                }
+            }
+
+            return result_offset;
+        }
+            // #endregion 
+        // #region If the BITSTRING supposed to be a primitive value
+        else
+        {
+            // #region Basic check for parameters 
+            if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+                return (-1);
+            // #endregion 
+
+            var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+
+            this.unused_bits = int_buffer[0];
+            if(this.unused_bits > 7)
+            {
+                this.error = "Unused bits for BITSTRING must be in range 0-7";
+                return (-1);
+            }
+
+            // #region Copy input buffer to internal buffer 
+            this.value_hex = new ArrayBuffer(int_buffer.length - 1);
+            var view = new Uint8Array(this.value_hex);
+            for(var i = 0; i < (input_length - 1) ; i++)
+                view[i] = int_buffer[i + 1];
+            // #endregion 
+
+            this.block_length = int_buffer.length;
+
+            return (input_offset + input_length);
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    local.BITSTRING_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.is_constructed === true)
+            return local.ASN1_CONSTRUCTED_value_block.prototype.toBER.call(this, size_only);
+        else
+        {
+            if(size_only === true)
+                return (new ArrayBuffer(this.value_hex.byteLength + 1));
+
+            if(this.value_hex.byteLength == 0)
+                return (new ArrayBuffer(0));
+
+            var cur_view = new Uint8Array(this.value_hex);
+
+            var ret_buf = new ArrayBuffer(this.value_hex.byteLength + 1);
+            var ret_view = new Uint8Array(ret_buf);
+
+            ret_view[0] = this.unused_bits;
+
+            for(var i = 0; i < this.value_hex.byteLength; i++)
+                ret_view[i + 1] = cur_view[i];
+
+            return ret_buf;
+        }
+
+        return (new ArrayBuffer(0));
+    };
+    //**************************************************************************************
+    local.BITSTRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BITSTRING_value_block";
+    };
+    //**************************************************************************************
+    local.BITSTRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.ASN1_CONSTRUCTED_value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.BITSTRING_value_block.prototype.block_name.call(this);
+        _object.unused_bits = this.unused_bits;
+        _object.is_constructed = this.is_constructed;
+        _object.is_hex_only = this.is_hex_only;
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BITSTRING =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.BITSTRING_value_block(arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 3; // BITSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BITSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.BITSTRING.constructor = in_window.org.pkijs.asn1.BITSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BITSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BITSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BITSTRING.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        // #region Ability to encode empty BITSTRING 
+        if(input_length == 0)
+            return input_offset;
+        // #endregion 
+
+        this.value_block.is_constructed = this.id_block.is_constructed;
+        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
+
+        return in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BITSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.BITSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 INTEGER type class 
+    //**************************************************************************************
+    local.INTEGER_value_block =
+    function()
+    {
+        local.value_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.value_dec = in_window.org.pkijs.getValue(arguments[0], "value", 0);
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
+            if("value_hex" in arguments[0])
+            {
+                this.value_hex = util_copybuf(arguments[0].value_hex);
+
+                if(this.value_hex.byteLength >= 4) // Dummy's protection
+                    this.is_hex_only = true;
+                else
+                    this.value_dec = util_decode_tc.call(this);
+            }
+            else
+                this.value_hex = util_encode_tc(this.value_dec);
+            // #endregion 
+        }
+        else
+        {
+            this.value_dec = 0;
+
+            // #region Variables from hex_block type 
+            this.is_hex_only = false;
+            this.value_hex = new ArrayBuffer(0);
+            // #endregion 
+        }
+    };
+    //**************************************************************************************
+    local.INTEGER_value_block.prototype = new local.value_block();
+    local.INTEGER_value_block.constructor = local.INTEGER_value_block;
+    //**************************************************************************************
+    local.INTEGER_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = local.hex_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
+        if(result_offset == (-1))
+            return result_offset;
+
+        if(this.value_hex.byteLength > 4) // In JavaScript we can effectively work with 32-bit integers only
+        {
+            this.warnings.push("Too big INTEGER for decoding, hex only");
+            this.is_hex_only = true;
+        }
+        else
+            this.value_dec = util_decode_tc.call(this);
+
+        this.block_length = input_length;
+
+        return (input_offset + input_length);
+    };
+    //**************************************************************************************
+    local.INTEGER_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.is_hex_only === false)
+        {
+            var encoded_buf = util_encode_tc(this.value_dec);
+            if(encoded_buf.byteLength == 0)
+            {
+                this.error = "Error during encoding INTEGER value";
+                return (new ArrayBuffer(0));
+            }
+
+            return util_copybuf(encoded_buf);
+        }
+        else
+            return util_copybuf(this.value_hex);
+
+        return (new ArrayBuffer(0));
+    };
+    //**************************************************************************************
+    local.INTEGER_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "INTEGER_value_block";
+    };
+    //**************************************************************************************
+    local.INTEGER_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.INTEGER_value_block.prototype.block_name.call(this);
+        _object.value_dec = this.value_dec;
+        _object.is_hex_only = this.is_hex_only;
+        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.INTEGER =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.INTEGER_value_block(arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 2; // INTEGER
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.INTEGER.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.INTEGER.constructor = in_window.org.pkijs.asn1.INTEGER;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.INTEGER.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "INTEGER";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.INTEGER.prototype.isEqual =
+    function()
+    {
+        /// <summary>Compare two INTEGER object, or INTEGER and ArrayBuffer objects</summary>
+        /// <returns type="Boolean"></returns>
+
+        if(arguments[0] instanceof in_window.org.pkijs.asn1.INTEGER)
+        {
+            if(this.value_block.is_hex_only && arguments[0].value_block.is_hex_only) // Compare two ArrayBuffers
+                return in_window.org.pkijs.isEqual_buffer(this.value_block.value_hex, arguments[0].value_block.value_hex);
+            else
+            {
+                if(this.value_block.is_hex_only === arguments[0].value_block.is_hex_only)
+                    return (this.value_block.value_dec == arguments[0].value_block.value_dec);
+                else
+                    return false;
+            }
+        }
+        else
+        {
+            if(arguments[0] instanceof ArrayBuffer)
+                return in_window.org.pkijs.isEqual_buffer(this.value_block.value_hex, arguments[0]);
+            else
+                return false;
+        }
+
+        return false;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.INTEGER.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.INTEGER.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 ENUMERATED type class 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ENUMERATED =
+    function()
+    {
+        in_window.org.pkijs.asn1.INTEGER.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 10; // ENUMERATED
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ENUMERATED.prototype = new in_window.org.pkijs.asn1.INTEGER();
+    in_window.org.pkijs.asn1.ENUMERATED.constructor = in_window.org.pkijs.asn1.ENUMERATED;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ENUMERATED.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "ENUMERATED";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ENUMERATED.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.INTEGER.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.ENUMERATED.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of ASN.1 OBJECT IDENTIFIER type class 
+    //**************************************************************************************
+    local.SID_value_block =
+    function()
+    {
+        local.hex_block.call(this, arguments[0]);
+
+        if(arguments[0] instanceof Object)
+        {
+            this.value_dec = in_window.org.pkijs.getValue(arguments[0], "value_dec", -1);
+            this.is_first_sid = in_window.org.pkijs.getValue(arguments[0], "is_first_sid", false);
+        }
+        else
+        {
+            this.value_dec = (-1);
+            this.is_first_sid = false;
+        }
+    };
+    //**************************************************************************************
+    local.SID_value_block.prototype = new local.hex_block();
+    local.SID_value_block.constructor = local.SID_value_block;
+    //**************************************************************************************
+    local.SID_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "sid_block";
+    };
+    //**************************************************************************************
+    local.SID_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        if(input_length == 0)
+            return input_offset;
+
+        // #region Basic check for parameters 
+        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
+            return (-1);
+        // #endregion 
+
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+
+        this.value_hex = new ArrayBuffer(input_length);
+        var view = new Uint8Array(this.value_hex);
+
+        for(var i = 0; i < input_length; i++)
+        {
+            view[i] = int_buffer[i] & 0x7F;
+
+            this.block_length++;
+
+            if((int_buffer[i] & 0x80) == 0x00)
+                break;
+        }
+
+        // #region Ajust size of value_hex buffer 
+        var temp_value_hex = new ArrayBuffer(this.block_length);
+        var temp_view = new Uint8Array(temp_value_hex);
+
+        for(var i = 0; i < this.block_length; i++)
+            temp_view[i] = view[i];
+
+        this.value_hex = util_copybuf(temp_value_hex);
+        view = new Uint8Array(this.value_hex);
+        // #endregion   
+
+        if((int_buffer[this.block_length - 1] & 0x80) != 0x00)
+        {
+            this.error = "End of input reached before message was fully decoded";
+            return (-1);
+        }
+
+        if(view[0] == 0x00)
+            this.warnings.push("Needlessly long format of SID encoding");
+
+        if(this.block_length <= 8)
+            this.value_dec = util_frombase(view, 7);
+        else
+        {
+            this.is_hex_only = true;
+            this.warnings.push("Too big SID for decoding, hex only");
+        }
+
+        return (input_offset + this.block_length);
+    };
+    //**************************************************************************************
+    local.SID_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        if(this.is_hex_only)
+        {
+            if(size_only === true)
+                return (new ArrayBuffer(this.value_hex.byteLength));
+
+            var cur_view = new Uint8Array(this.value_hex);
+
+            var ret_buf = new ArrayBuffer(this.block_length);
+            var ret_view = new Uint8Array(ret_buf);
+
+            for(var i = 0; i < (this.block_length - 1) ; i++)
+                ret_view[i] = cur_view[i] | 0x80;
+
+            ret_view[this.block_length - 1] = cur_view[this.block_length - 1];
+
+            return ret_buf;
+        }
+        else
+        {
+            var encoded_buf = util_tobase(this.value_dec, 7);
+            if(encoded_buf.byteLength === 0)
+            {
+                this.error = "Error during encoding SID value";
+                return (new ArrayBuffer(0));
+            }
+
+            var ret_buf = new ArrayBuffer(encoded_buf.byteLength);
+
+            if(size_only === false)
+            {
+                var encoded_view = new Uint8Array(encoded_buf);
+                var ret_view = new Uint8Array(ret_buf);
+
+                for(var i = 0; i < (encoded_buf.byteLength - 1) ; i++)
+                    ret_view[i] = encoded_view[i] | 0x80;
+
+                ret_view[encoded_buf.byteLength - 1] = encoded_view[encoded_buf.byteLength - 1];
+            }
+
+            return ret_buf;
+        }
+    };
+    //**************************************************************************************
+    local.SID_value_block.prototype.toString =
+    function()
+    {
+        var result = "";
+
+        if(this.is_hex_only === true)
+            result = to_hex_codes(this.value_hex);
+        else
+        {
+            if(this.is_first_sid)
+            {
+                var sid_value = this.value_dec;
+
+                if(this.value_dec <= 39)
+                    result = "0.";
+                else
+                {
+                    if(this.value_dec <= 79)
+                    {
+                        result = "1.";
+                        sid_value -= 40;
+                    }
+                    else
+                    {
+                        result = "2.";
+                        sid_value -= 80;
+                    }
+                }
+
+                result = result + sid_value.toString();
+            }
+            else
+                result = this.value_dec.toString();
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    local.SID_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.SID_value_block.prototype.block_name.call(this);
+        _object.value_dec = this.value_dec;
+        _object.is_first_sid = this.is_first_sid;
+
+        return _object;
+    };
+    //**************************************************************************************
+    local.OID_value_block =
+    function()
+    {
+        local.value_block.call(this, arguments[0]);
+
+        this.value = new Array();
+
+        if(arguments[0] instanceof Object)
+            this.fromString(in_window.org.pkijs.getValue(arguments[0], "value", ""));
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype = new local.value_block();
+    local.OID_value_block.constructor = local.OID_value_block;
+    //**************************************************************************************
+    local.OID_value_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = input_offset;
+
+        while(input_length > 0)
+        {
+            var sid_block = new local.SID_value_block();
+            result_offset = sid_block.fromBER(input_buffer, result_offset, input_length);
+            if(result_offset == (-1))
+            {
+                this.block_length = 0;
+                this.error = sid_block.error;
+                return result_offset;
+            }
+
+            if(this.value.length == 0)
+                sid_block.is_first_sid = true;
+
+            this.block_length += sid_block.block_length;
+            input_length -= sid_block.block_length;
+
+            this.value.push(sid_block);
+        }
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype.toBER =
+    function(size_only)
+    {
+        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
+        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
+
+        if(typeof size_only === "undefined")
+            size_only = false;
+
+        var ret_buf = new ArrayBuffer(0);
+
+        for(var i = 0; i < this.value.length; i++)
+        {
+            var value_buf = this.value[i].toBER(size_only);
+            if(value_buf.byteLength === 0)
+            {
+                this.error = this.value[i].error;
+                return (new ArrayBuffer(0));
+            }
+
+            ret_buf = util_concatbuf(ret_buf, value_buf);
+        }
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype.fromString =
+    function(str)
+    {
+        this.value = new Array(); // Clear existing SID values
+
+        var pos1 = 0;
+        var pos2 = 0;
+
+        var sid = "";
+
+        var flag = false;
+
+        do
+        {
+            pos2 = str.indexOf('.', pos1);
+            if(pos2 === (-1))
+                sid = str.substr(pos1);
+            else
+                sid = str.substr(pos1, pos2 - pos1);
+
+            pos1 = pos2 + 1;
+
+            if(flag)
+            {
+                var sid_block = this.value[0];
+
+                var plus = 0;
+
+                switch(sid_block.value_dec)
+                {
+                    case 0:
+                        break;
+                    case 1:
+                        plus = 40;
+                        break;
+                    case 2:
+                        plus = 80;
+                        break;
+                    default:
+                        this.value = new Array(); // clear SID array
+                        return false; // ???
+                }
+
+                var parsedSID = parseInt(sid, 10);
+                if(isNaN(parsedSID))
+                    return true;
+
+                sid_block.value_dec = parsedSID + plus;
+
+                flag = false;
+            }
+            else
+            {
+                var sid_block = new local.SID_value_block();
+                sid_block.value_dec = parseInt(sid, 10);
+                if(isNaN(sid_block.value_dec))
+                    return true;
+
+                if(this.value.length === 0)
+                {
+                    sid_block.is_first_sid = true;
+                    flag = true;
+                }
+
+                this.value.push(sid_block);
+            }
+
+        } while(pos2 !== (-1));
+
+        return true;
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype.toString =
+    function()
+    {
+        var result = "";
+        var is_hex_only = false;
+
+        for(var i = 0; i < this.value.length; i++)
+        {
+            is_hex_only = this.value[i].is_hex_only;
+
+            var sid_str = this.value[i].toString();
+
+            if(i !== 0)
+                result = result + ".";
+
+            if(is_hex_only)
+            {
+                sid_str = "{" + sid_str + "}";
+
+                if(this.value[i].is_first_sid)
+                    result = "2.{" + sid_str + " - 80}";
+                else
+                    result = result + sid_str;
+            }
+            else
+                result = result + sid_str;
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "OID_value_block";
+    };
+    //**************************************************************************************
+    local.OID_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.value_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.OID_value_block.prototype.block_name.call(this);
+        _object.value = local.OID_value_block.prototype.toString.call(this);
+        _object.sid_array = new Array();
+        for(var i = 0; i < this.value.length; i++)
+            _object.sid_array.push(this.value[i].toJSON());
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OID =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.OID_value_block(arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 6; // OBJECT IDENTIFIER
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OID.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.OID.constructor = in_window.org.pkijs.asn1.OID;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OID.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "OID";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.OID.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.OID.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion   
+    //**************************************************************************************
+    // #region Declaration of all string's classes 
+    //**************************************************************************************
+    local.UTF8STRING_value_block =
+    function()
+    {
+        local.hex_block.call(this, arguments[0]);
+
+        this.is_hex_only = true;
+        this.value = ""; // String representation of decoded ArrayBuffer
+    };
+    //**************************************************************************************
+    local.UTF8STRING_value_block.prototype = new local.hex_block();
+    local.UTF8STRING_value_block.constructor = local.UTF8STRING_value_block;
+    //**************************************************************************************
+    local.UTF8STRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "UTF8STRING_value_block";
+    };
+    //**************************************************************************************
+    local.UTF8STRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.UTF8STRING_value_block.prototype.block_name.call(this);
+        _object.value = this.value;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.UTF8STRING_value_block();
+
+        if(arguments[0] instanceof Object)
+        {
+            if("value" in arguments[0])
+                in_window.org.pkijs.asn1.UTF8STRING.prototype.fromString.call(this,arguments[0].value);
+        }
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 12; // UTF8STRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.UTF8STRING.constructor = in_window.org.pkijs.asn1.UTF8STRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "UTF8STRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
+        this.value_block.value = String.fromCharCode.apply(null, new Uint8Array(input_buffer));
+
+        try
+        {
+            this.value_block.value = decodeURIComponent(escape(this.value_block.value));
+        }
+        catch(ex)
+        {
+            this.warnings.push("Error during \"decodeURIComponent\": " + ex + ", using raw string");
+        }
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromString =
+    function(input_string)
+    {
+        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
+
+        var str = unescape(encodeURIComponent(input_string));
+        var str_len = str.length;
+
+        this.value_block.value_hex = new ArrayBuffer(str_len);
+        var view = new Uint8Array(this.value_block.value_hex);
+
+        for(var i = 0; i < str_len; i++)
+            view[i] = str.charCodeAt(i);
+
+        this.value_block.value = input_string;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.UTF8STRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    local.BMPSTRING_value_block =
+    function()
+    {
+        local.hex_block.call(this, arguments[0]);
+
+        this.is_hex_only = true;
+        this.value = "";
+    };
+    //**************************************************************************************
+    local.BMPSTRING_value_block.prototype = new local.hex_block();
+    local.BMPSTRING_value_block.constructor = local.BMPSTRING_value_block;
+    //**************************************************************************************
+    local.BMPSTRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BMPSTRING_value_block";
+    };
+    //**************************************************************************************
+    local.BMPSTRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.BMPSTRING_value_block.prototype.block_name.call(this);
+        _object.value = this.value;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.BMPSTRING_value_block();
+
+        if(arguments[0] instanceof Object)
+        {
+            if("value" in arguments[0])
+                in_window.org.pkijs.asn1.BMPSTRING.prototype.fromString.call(this, arguments[0].value);
+        }
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 30; // BMPSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.BMPSTRING.constructor = in_window.org.pkijs.asn1.BMPSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "BMPSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
+
+        var copy_buffer = in_window.org.pkijs.copyBuffer(input_buffer);
+
+        var value_view = new Uint8Array(copy_buffer);
+
+        for(var i = 0; i < value_view.length; i = i + 2)
+        {
+            var temp = value_view[i];
+
+            value_view[i] = value_view[i + 1];
+            value_view[i + 1] = temp;
+        }
+
+        this.value_block.value = String.fromCharCode.apply(null, new Uint16Array(copy_buffer));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromString =
+    function(input_string)
+    {
+        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
+
+        var str_length = input_string.length;
+
+        this.value_block.value_hex = new ArrayBuffer(str_length * 2);
+        var value_hex_view = new Uint8Array(this.value_block.value_hex);
+
+        for(var i = 0; i < str_length; i++)
+        {
+            var code_buf = util_tobase(input_string.charCodeAt(i), 8);
+            var code_view = new Uint8Array(code_buf);
+            if(code_view.length > 2)
+                continue;
+
+            var dif = 2 - code_view.length;
+
+            for(var j = (code_view.length - 1) ; j >= 0; j--)
+                value_hex_view[i * 2 + j + dif] = code_view[j];
+        }
+
+        this.value_block.value = input_string;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.BMPSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.BMPSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    local.UNIVERSALSTRING_value_block =
+    function()
+    {
+        local.hex_block.call(this, arguments[0]);
+
+        this.is_hex_only = true;
+        this.value = "";
+    };
+    //**************************************************************************************
+    local.UNIVERSALSTRING_value_block.prototype = new local.hex_block();
+    local.UNIVERSALSTRING_value_block.constructor = local.UNIVERSALSTRING_value_block;
+    //**************************************************************************************
+    local.UNIVERSALSTRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "UNIVERSALSTRING_value_block";
+    };
+    //**************************************************************************************
+    local.UNIVERSALSTRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.UNIVERSALSTRING_value_block.prototype.block_name.call(this);
+        _object.value = this.value;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.UNIVERSALSTRING_value_block();
+
+        if(arguments[0] instanceof Object)
+        {
+            if("value" in arguments[0])
+                in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromString.call(this, arguments[0].value);
+        }
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 28; // UNIVERSALSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.constructor = in_window.org.pkijs.asn1.UNIVERSALSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "UNIVERSALSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
+
+        var copy_buffer = in_window.org.pkijs.copyBuffer(input_buffer);
+
+        var value_view = new Uint8Array(copy_buffer);
+
+        for(var i = 0; i < value_view.length; i = i + 4)
+        {
+            value_view[i] = value_view[i + 3];
+            value_view[i + 1] = value_view[i + 2];
+            value_view[i + 2] = 0x00;
+            value_view[i + 3] = 0x00;
+        }
+
+        this.value_block.value = String.fromCharCode.apply(null, new Uint32Array(copy_buffer));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromString =
+    function(input_string)
+    {
+        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
+
+        var str_length = input_string.length;
+
+        this.value_block.value_hex = new ArrayBuffer(str_length * 4);
+        var value_hex_view = new Uint8Array(this.value_block.value_hex);
+
+        for(var i = 0; i < str_length; i++)
+        {
+            var code_buf = util_tobase(input_string.charCodeAt(i), 8);
+            var code_view = new Uint8Array(code_buf);
+            if(code_view.length > 4)
+                continue;
+
+            var dif = 4 - code_view.length;
+
+            for(var j = (code_view.length - 1) ; j >= 0; j--)
+                value_hex_view[i*4 + j + dif] = code_view[j];
+        }
+
+        this.value_block.value = input_string;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_value_block =
+    function()
+    {
+        local.hex_block.call(this, arguments[0]);
+
+        /// <field type="String">Native string representation</field>
+        this.value = "";
+        this.is_hex_only = true;
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_value_block.prototype = new local.hex_block();
+    local.SIMPLESTRING_value_block.constructor = local.SIMPLESTRING_value_block;
+    //**************************************************************************************
+    local.SIMPLESTRING_value_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "SIMPLESTRING_value_block";
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_value_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.hex_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.SIMPLESTRING_value_block.prototype.block_name.call(this);
+        _object.value = this.value;
+
+        return _object;
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block =
+    function()
+    {
+        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
+
+        this.value_block = new local.SIMPLESTRING_value_block();
+
+        if(arguments[0] instanceof Object)
+        {
+            if("value" in arguments[0])
+                local.SIMPLESTRING_block.prototype.fromString.call(this, arguments[0].value);
+        }
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype = new in_window.org.pkijs.asn1.ASN1_block();
+    local.SIMPLESTRING_block.constructor = local.SIMPLESTRING_block;
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "SIMPLESTRING";
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        local.SIMPLESTRING_block.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
+
+        this.value_block.value = String.fromCharCode.apply(null, new Uint8Array(input_buffer));
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype.fromString =
+    function(input_string)
+    {
+        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
+        var str_len = input_string.length;
+
+        this.value_block.value_hex = new ArrayBuffer(str_len);
+        var view = new Uint8Array(this.value_block.value_hex);
+
+        for(var i = 0; i < str_len; i++)
+            view[i] = input_string.charCodeAt(i);
+
+        this.value_block.value = input_string;
+    };
+    //**************************************************************************************
+    local.SIMPLESTRING_block.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
+
+        _object.block_name = local.SIMPLESTRING_block.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NUMERICSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 18; // NUMERICSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NUMERICSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.NUMERICSTRING.constructor = in_window.org.pkijs.asn1.NUMERICSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NUMERICSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "NUMERICSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.NUMERICSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.NUMERICSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.PRINTABLESTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 19; // PRINTABLESTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.PRINTABLESTRING.constructor = in_window.org.pkijs.asn1.PRINTABLESTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "PRINTABLESTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TELETEXSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 20; // TELETEXSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TELETEXSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.TELETEXSTRING.constructor = in_window.org.pkijs.asn1.TELETEXSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TELETEXSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "TELETEXSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TELETEXSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.TELETEXSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VIDEOTEXSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 21; // VIDEOTEXSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.VIDEOTEXSTRING.constructor = in_window.org.pkijs.asn1.VIDEOTEXSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "VIDEOTEXSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.IA5STRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 22; // IA5STRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.IA5STRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.IA5STRING.constructor = in_window.org.pkijs.asn1.IA5STRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.IA5STRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "IA5STRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.IA5STRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.IA5STRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GRAPHICSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 25; // GRAPHICSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.GRAPHICSTRING.constructor = in_window.org.pkijs.asn1.GRAPHICSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "GRAPHICSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VISIBLESTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 26; // VISIBLESTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VISIBLESTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.VISIBLESTRING.constructor = in_window.org.pkijs.asn1.VISIBLESTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VISIBLESTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "VISIBLESTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 27; // GENERALSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.GENERALSTRING.constructor = in_window.org.pkijs.asn1.GENERALSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "GENERALSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.GENERALSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.CHARACTERSTRING =
+    function()
+    {
+        local.SIMPLESTRING_block.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 29; // CHARACTERSTRING
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype = new local.SIMPLESTRING_block();
+    in_window.org.pkijs.asn1.CHARACTERSTRING.constructor = in_window.org.pkijs.asn1.CHARACTERSTRING;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "CHARACTERSTRING";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of all date and time classes 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME =
+    function()
+    {
+        in_window.org.pkijs.asn1.VISIBLESTRING.call(this, arguments[0]);
+
+        this.year = 0;
+        this.month = 0;
+        this.day = 0;
+        this.hour = 0;
+        this.minute = 0;
+        this.second = 0;
+
+        // #region Create UTCTIME from ASN.1 UTC string value 
+        if((arguments[0] instanceof Object) && ("value" in arguments[0]))
+        {
+            in_window.org.pkijs.asn1.UTCTIME.prototype.fromString.call(this, arguments[0].value);
+
+            this.value_block.value_hex = new ArrayBuffer(arguments[0].value.length);
+            var view = new Uint8Array(this.value_block.value_hex);
+
+            for(var i = 0; i < arguments[0].value.length; i++)
+                view[i] = arguments[0].value.charCodeAt(i);
+        }
+        // #endregion 
+        // #region Create UTCTIME from JavaScript Date type 
+        if((arguments[0] instanceof Object) && ("value_date" in arguments[0]))
+        {
+            in_window.org.pkijs.asn1.UTCTIME.prototype.fromDate.call(this, arguments[0].value_date);
+            this.value_block.value_hex = in_window.org.pkijs.asn1.UTCTIME.prototype.toBuffer.call(this);
+        }
+        // #endregion 
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 23; // UTCTIME
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype = new in_window.org.pkijs.asn1.VISIBLESTRING();
+    in_window.org.pkijs.asn1.UTCTIME.constructor = in_window.org.pkijs.asn1.UTCTIME;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        in_window.org.pkijs.asn1.UTCTIME.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        in_window.org.pkijs.asn1.UTCTIME.prototype.fromString.call(this, String.fromCharCode.apply(null, new Uint8Array(input_buffer)));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.toBuffer =
+    function()
+    {
+        var str = in_window.org.pkijs.asn1.UTCTIME.prototype.toString.call(this);
+
+        var buffer = new ArrayBuffer(str.length);
+        var view = new Uint8Array(buffer);
+
+        for(var i = 0; i < str.length; i++)
+            view[i] = str.charCodeAt(i);
+
+        return buffer;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.fromDate =
+    function(input_date)
+    {
+        /// <summary>Create "UTCTime" ASN.1 type from JavaScript "Date" type</summary>
+
+        this.year = input_date.getUTCFullYear();
+        this.month = input_date.getUTCMonth() + 1;
+        this.day = input_date.getUTCDate();
+        this.hour = input_date.getUTCHours();
+        this.minute = input_date.getUTCMinutes();
+        this.second = input_date.getUTCSeconds();
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.toDate =
+    function()
+    {
+        return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.fromString =
+    function(input_string)
+    {
+        /// <summary>Create "UTCTime" ASN.1 type from JavaScript "String" type</summary>
+
+        // #region Parse input string 
+        var parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig;
+        var parser_array = parser.exec(input_string);
+        if(parser_array === null)
+        {
+            this.error = "Wrong input string for convertion";
+            return;
+        }
+        // #endregion 
+
+        // #region Store parsed values 
+        var year = parseInt(parser_array[1], 10);
+        if(year >= 50)
+            this.year = 1900 + year;
+        else
+            this.year = 2000 + year;
+
+        this.month = parseInt(parser_array[2], 10);
+        this.day = parseInt(parser_array[3], 10);
+        this.hour = parseInt(parser_array[4], 10);
+        this.minute = parseInt(parser_array[5], 10);
+        this.second = parseInt(parser_array[6], 10);
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.toString =
+    function()
+    {
+        var output_array = new Array(7);
+
+        output_array[0] = in_window.org.pkijs.padNumber(((this.year < 2000) ? (this.year - 1900) : (this.year - 2000)), 2);
+        output_array[1] = in_window.org.pkijs.padNumber(this.month, 2);
+        output_array[2] = in_window.org.pkijs.padNumber(this.day, 2);
+        output_array[3] = in_window.org.pkijs.padNumber(this.hour, 2);
+        output_array[4] = in_window.org.pkijs.padNumber(this.minute, 2);
+        output_array[5] = in_window.org.pkijs.padNumber(this.second, 2);
+        output_array[6] = "Z";
+
+        return output_array.join('');
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "UTCTIME";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.UTCTIME.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.UTCTIME.prototype.block_name.call(this);
+        _object.year = this.year;
+        _object.month = this.month;
+        _object.day = this.day;
+        _object.hour = this.hour;
+        _object.minute = this.minute;
+        _object.second = this.second;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME =
+    function()
+    {
+        in_window.org.pkijs.asn1.VISIBLESTRING.call(this, arguments[0]);
+
+        this.year = 0;
+        this.month = 0;
+        this.day = 0;
+        this.hour = 0;
+        this.minute = 0;
+        this.second = 0;
+        this.millisecond = 0;
+
+        // #region Create GeneralizedTime from ASN.1 string value 
+        if((arguments[0] instanceof Object) && ("value" in arguments[0]))
+        {
+            in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString.call(this, arguments[0].value);
+
+            this.value_block.value_hex = new ArrayBuffer(arguments[0].value.length);
+            var view = new Uint8Array(this.value_block.value_hex);
+
+            for(var i = 0; i < arguments[0].value.length; i++)
+                view[i] = arguments[0].value.charCodeAt(i);
+        }
+        // #endregion 
+        // #region Create GeneralizedTime from JavaScript Date type 
+        if((arguments[0] instanceof Object) && ("value_date" in arguments[0]))
+        {
+            in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromDate.call(this, arguments[0].value_date);
+            this.value_block.value_hex = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toBuffer.call(this);
+        }
+        // #endregion 
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 24; // GENERALIZEDTIME
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype = new in_window.org.pkijs.asn1.VISIBLESTRING();
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.constructor = in_window.org.pkijs.asn1.GENERALIZEDTIME;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBER =
+    function(input_buffer, input_offset, input_length)
+    {
+        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
+        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
+        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
+
+        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
+        if(result_offset == (-1))
+        {
+            this.error = this.value_block.error;
+            return result_offset;
+        }
+
+        in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBuffer.call(this, this.value_block.value_hex);
+
+        if(this.id_block.error.length == 0)
+            this.block_length += this.id_block.block_length;
+
+        if(this.len_block.error.length == 0)
+            this.block_length += this.len_block.block_length;
+
+        if(this.value_block.error.length == 0)
+            this.block_length += this.value_block.block_length;
+
+        return result_offset;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBuffer =
+    function(input_buffer)
+    {
+        in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString.call(this, String.fromCharCode.apply(null, new Uint8Array(input_buffer)));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toBuffer =
+    function()
+    {
+        var str = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toString.call(this);
+
+        var buffer = new ArrayBuffer(str.length);
+        var view = new Uint8Array(buffer);
+
+        for(var i = 0; i < str.length; i++)
+            view[i] = str.charCodeAt(i);
+
+        return buffer;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromDate =
+    function(input_date)
+    {
+        /// <summary>Create "GeneralizedTime" ASN.1 type from JavaScript "Date" type</summary>
+
+        this.year = input_date.getUTCFullYear();
+        this.month = input_date.getUTCMonth();
+        this.day = input_date.getUTCDate();
+        this.hour = input_date.getUTCHours();
+        this.minute = input_date.getUTCMinutes();
+        this.second = input_date.getUTCSeconds();
+        this.millisecond = input_date.getUTCMilliseconds();
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toDate =
+    function()
+    {
+        return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString =
+    function(input_string)
+    {
+        /// <summary>Create "GeneralizedTime" ASN.1 type from JavaScript "String" type</summary>
+
+        // #region Initial variables 
+        var isUTC = false;
+
+        var timeString = "";
+        var dateTimeString = "";
+        var fractionPart = 0;
+
+        var parser;
+
+        var hourDifference = 0;
+        var minuteDifference = 0;
+        // #endregion 
+
+        // #region Convert as UTC time 
+        if(input_string[input_string.length - 1] == "Z")
+        {
+            timeString = input_string.substr(0, input_string.length - 1);
+
+            isUTC = true;
+        }
+        // #endregion 
+        // #region Convert as local time 
+        else
+        {
+            var number = new Number(input_string[input_string.length - 1]);
+
+            if(isNaN(number.valueOf()))
+                throw new Error("Wrong input string for convertion");
+
+            timeString = input_string;
+        }
+        // #endregion 
+
+        // #region Check that we do not have a "+" and "-" symbols inside UTC time 
+        if(isUTC)
+        {
+            if(timeString.indexOf("+") != (-1))
+                throw new Error("Wrong input string for convertion");
+
+            if(timeString.indexOf("-") != (-1))
+                throw new Error("Wrong input string for convertion");
+        }
+        // #endregion 
+        // #region Get "UTC time difference" in case of local time
+        else
+        {
+            var multiplier = 1;
+            var differencePosition = timeString.indexOf("+");
+            var differenceString = "";
+
+            if(differencePosition == (-1))
+            {
+                differencePosition = timeString.indexOf("-");
+                multiplier = (-1);
+            }
+
+            if(differencePosition != (-1))
+            {
+                differenceString = timeString.substr(differencePosition + 1);
+                timeString = timeString.substr(0, differencePosition);
+
+                if((differenceString.length != 2) && (differenceString.length != 4))
+                    throw new Error("Wrong input string for convertion");
+
+                var number = new Number(differenceString.substr(0, 2));
+
+                if(isNaN(number.valueOf()))
+                    throw new Error("Wrong input string for convertion");
+
+                hourDifference = multiplier * number;
+
+                if(differenceString.length == 4)
+                {
+                    number = new Number(differenceString.substr(2, 2));
+
+                    if(isNaN(number.valueOf()))
+                        throw new Error("Wrong input string for convertion");
+
+                    minuteDifference = multiplier * number;
+                }
+            }
+        }
+        // #endregion 
+
+        // #region Get position of fraction point 
+        var fractionPointPosition = timeString.indexOf("."); // Check for "full stop" symbol
+        if(fractionPointPosition == (-1))
+            fractionPointPosition = timeString.indexOf(","); // Check for "comma" symbol
+        // #endregion 
+
+        // #region Get fraction part 
+        if(fractionPointPosition != (-1))
+        {
+            var fractionPartCheck = new Number("0" + timeString.substr(fractionPointPosition));
+
+            if(isNaN(fractionPartCheck.valueOf()))
+                throw new Error("Wrong input string for convertion");
+
+            fractionPart = fractionPartCheck.valueOf();
+
+            dateTimeString = timeString.substr(0, fractionPointPosition);
+        }
+        else
+            dateTimeString = timeString;
+        // #endregion 
+
+        // #region Parse internal date 
+        switch(true)
+        {
+            case (dateTimeString.length == 8): // "YYYYMMDD"
+                parser = /(\d{4})(\d{2})(\d{2})/ig;
+                if(fractionPointPosition !== (-1))
+                    throw new Error("Wrong input string for convertion"); // Here we should not have a "fraction point"
+                break;
+            case (dateTimeString.length == 10): // "YYYYMMDDHH"
+                parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig;
+
+                if(fractionPointPosition !== (-1))
+                {
+                    var fractionResult = 60 * fractionPart;
+                    this.minute = Math.floor(fractionResult);
+
+                    fractionResult = 60 * (fractionResult - this.minute);
+                    this.second = Math.floor(fractionResult);
+
+                    fractionResult = 1000 * (fractionResult - this.second);
+                    this.millisecond = Math.floor(fractionResult);
+                }
+                break;
+            case (dateTimeString.length == 12): // "YYYYMMDDHHMM"
+                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
+
+                if(fractionPointPosition !== (-1))
+                {
+                    var fractionResult = 60 * fractionPart;
+                    this.second = Math.floor(fractionResult);
+
+                    fractionResult = 1000 * (fractionResult - this.second);
+                    this.millisecond = Math.floor(fractionResult);
+                }
+                break;
+            case (dateTimeString.length == 14): // "YYYYMMDDHHMMSS"
+                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
+
+                if(fractionPointPosition !== (-1))
+                {
+                    var fractionResult = 1000 * fractionPart;
+                    this.millisecond = Math.floor(fractionResult);
+                }
+                break;
+            default:
+                throw new Error("Wrong input string for convertion");
+        }
+        // #endregion 
+
+        // #region Put parsed values at right places 
+        var parser_array = parser.exec(dateTimeString);
+        if(parser_array == null)
+            throw new Error("Wrong input string for convertion");
+
+        for(var j = 1; j < parser_array.length; j++)
+        {
+            switch(j)
+            {
+                case 1:
+                    this.year = parseInt(parser_array[j], 10);
+                    break;
+                case 2:
+                    this.month = parseInt(parser_array[j], 10) - 1; // In JavaScript we have month range as "0 - 11"
+                    break;
+                case 3:
+                    this.day = parseInt(parser_array[j], 10);
+                    break;
+                case 4:
+                    this.hour = parseInt(parser_array[j], 10) + hourDifference;
+                    break;
+                case 5:
+                    this.minute = parseInt(parser_array[j], 10) + minuteDifference;
+                    break;
+                case 6:
+                    this.second = parseInt(parser_array[j], 10);
+                    break;
+                default:
+                    throw new Error("Wrong input string for convertion");
+            }
+        }
+        // #endregion 
+
+        // #region Get final date 
+        if(isUTC == false)
+        {
+            var tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
+
+            this.year = tempDate.getUTCFullYear();
+            this.month = tempDate.getUTCMonth();
+            this.day = tempDate.getUTCDay();
+            this.hour = tempDate.getUTCHours();
+            this.minute = tempDate.getUTCMinutes();
+            this.second = tempDate.getUTCSeconds();
+            this.millisecond = tempDate.getUTCMilliseconds();
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toString =
+    function()
+    {
+        var output_array = new Array();
+
+        output_array.push(in_window.org.pkijs.padNumber(this.year, 4));
+        output_array.push(in_window.org.pkijs.padNumber(this.month, 2));
+        output_array.push(in_window.org.pkijs.padNumber(this.day, 2));
+        output_array.push(in_window.org.pkijs.padNumber(this.hour, 2));
+        output_array.push(in_window.org.pkijs.padNumber(this.minute, 2));
+        output_array.push(in_window.org.pkijs.padNumber(this.second, 2));
+        if(this.millisecond != 0)
+        {
+            output_array.push(".");
+            output_array.push(in_window.org.pkijs.padNumber(this.millisecond, 3));
+        }
+        output_array.push("Z");
+
+        return output_array.join('');
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "GENERALIZEDTIME";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.block_name.call(this);
+        _object.year = this.year;
+        _object.month = this.month;
+        _object.day = this.day;
+        _object.hour = this.hour;
+        _object.minute = this.minute;
+        _object.second = this.second;
+        _object.millisecond = this.millisecond;
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATE =
+    function()
+    {
+        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 31; // DATE
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATE.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
+    in_window.org.pkijs.asn1.DATE.constructor = in_window.org.pkijs.asn1.DATE;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATE.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "DATE";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATE.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.DATE.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIMEOFDAY =
+    function()
+    {
+        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 32; // TIMEOFDAY
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIMEOFDAY.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
+    in_window.org.pkijs.asn1.TIMEOFDAY.constructor = in_window.org.pkijs.asn1.TIMEOFDAY;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIMEOFDAY.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "TIMEOFDAY";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIMEOFDAY.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.TIMEOFDAY.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATETIME =
+    function()
+    {
+        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 33; // DATETIME
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATETIME.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
+    in_window.org.pkijs.asn1.DATETIME.constructor = in_window.org.pkijs.asn1.DATETIME;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATETIME.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "DATETIME";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DATETIME.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.DATETIME.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DURATION =
+    function()
+    {
+        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 34; // DURATION
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DURATION.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
+    in_window.org.pkijs.asn1.DURATION.constructor = in_window.org.pkijs.asn1.DURATION;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DURATION.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "DURATION";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.DURATION.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.DURATION.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIME =
+    function()
+    {
+        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
+
+        this.id_block.tag_class = 1; // UNIVERSAL
+        this.id_block.tag_number = 14; // TIME
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIME.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
+    in_window.org.pkijs.asn1.TIME.constructor = in_window.org.pkijs.asn1.TIME;
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIME.prototype.block_name =
+    function()
+    {
+        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
+
+        return "TIME";
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.TIME.prototype.toJSON =
+    function()
+    {
+        /// <summary>Convertion for the block to JSON object</summary>
+
+        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
+
+        _object.block_name = in_window.org.pkijs.asn1.TIME.prototype.block_name.call(this);
+
+        return _object;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of special ASN.1 schema type CHOICE 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.CHOICE =
+    function()
+    {
+        if(arguments[0] instanceof Object)
+        {
+            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new Array()); // Array of ASN.1 types for make a choice from
+            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
+        }
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of special ASN.1 schema type ANY 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.ANY =
+    function()
+    {
+        if(arguments[0] instanceof Object)
+        {
+            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
+            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
+        }
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of special ASN.1 schema type REPEATED 
+    //**************************************************************************************
+    in_window.org.pkijs.asn1.REPEATED =
+    function()
+    {
+        if(arguments[0] instanceof Object)
+        {
+            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
+            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
+            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new in_window.org.pkijs.asn1.ANY());
+            this.local = in_window.org.pkijs.getValue(arguments[0], "local", false); // Could local or global array to store elements
+        }
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Major ASN.1 BER decoding function
+    //**************************************************************************************
+    function fromBER_raw(input_buffer, input_offset, input_length)
+    {
+        var incoming_offset = input_offset; // Need to store initial offset since "input_offset" is changing in the function
+
+        // #region Local function changing a type for ASN.1 classes 
+        function local_change_type(input_object, new_type)
+        {
+            if(input_object instanceof new_type)
+                return input_object;
+
+            var new_object = new new_type();
+            new_object.id_block = input_object.id_block;
+            new_object.len_block = input_object.len_block;
+            new_object.warnings = input_object.warnings;
+            new_object.value_before_decode = util_copybuf(input_object.value_before_decode);
+
+            return new_object;
+        }
+        // #endregion 
+
+        // #region Create a basic ASN.1 type since we need to return errors and warnings from the function 
+        var return_object = new in_window.org.pkijs.asn1.ASN1_block();
+        // #endregion 
+
+        // #region Basic check for parameters 
+        if(check_buffer_params(input_buffer, input_offset, input_length) === false)
+        {
+            return_object.error = "Wrong input parameters";
+            return {
+                offset: (-1),
+                result: return_object
+            };
+        }
+        // #endregion 
+
+        // #region Getting Uint8Array from ArrayBuffer 
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
+        // #endregion 
+
+        // #region Initial checks 
+        if(int_buffer.length == 0)
+        {
+            this.error = "Zero buffer length";
+            return {
+                offset: (-1),
+                result: return_object
+            };
+        }
+        // #endregion 
+
+        // #region Decode indentifcation block of ASN.1 BER structure 
+        var result_offset = return_object.id_block.fromBER(input_buffer, input_offset, input_length);
+        return_object.warnings.concat(return_object.id_block.warnings);
+        if(result_offset == (-1))
+        {
+            return_object.error = return_object.id_block.error;
+            return {
+                offset: (-1),
+                result: return_object
+            };
+        }
+
+        input_offset = result_offset;
+        input_length -= return_object.id_block.block_length;
+        // #endregion 
+
+        // #region Decode length block of ASN.1 BER structure 
+        result_offset = return_object.len_block.fromBER(input_buffer, input_offset, input_length);
+        return_object.warnings.concat(return_object.len_block.warnings);
+        if(result_offset == (-1))
+        {
+            return_object.error = return_object.len_block.error;
+            return {
+                offset: (-1),
+                result: return_object
+            };
+        }
+
+        input_offset = result_offset;
+        input_length -= return_object.len_block.block_length;
+        // #endregion 
+
+        // #region Check for usign indefinite length form in encoding for primitive types 
+        if((return_object.id_block.is_constructed == false) &&
+           (return_object.len_block.is_indefinite_form == true))
+        {
+            return_object.error = new String("Indefinite length form used for primitive encoding form");
+            return {
+                offset: (-1),
+                result: return_object
+            };
+        }
+        // #endregion 
+
+        // #region Switch ASN.1 block type 
+        var new_asn1_type = in_window.org.pkijs.asn1.ASN1_block;
+
+        switch(return_object.id_block.tag_class)
+        {
+            // #region UNIVERSAL 
+            case 1: 
+                // #region Check for reserved tag numbers 
+                if((return_object.id_block.tag_number >= 37) &&
+                   (return_object.id_block.is_hex_only == false))
+                {
+                    return_object.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard";
+                    return {
+                        offset: (-1),
+                        result: return_object
+                    };
+                }
+                // #endregion 
+
+                switch(return_object.id_block.tag_number)
+                {
+                    // #region EOC type 
+                    case 0:
+                        // #region Check for EOC type 
+                        if((return_object.id_block.is_constructed == true) &&
+                           (return_object.len_block.length > 0))
+                        {
+                            return_object.error = "Type [UNIVERSAL 0] is reserved";
+                            return {
+                                offset: (-1),
+                                result: return_object
+                            };
+                        }
+                        // #endregion 
+
+                        new_asn1_type = in_window.org.pkijs.asn1.EOC;
+
+                        break;
+                        // #endregion 
+                    // #region BOOLEAN type 
+                    case 1:
+                        new_asn1_type = in_window.org.pkijs.asn1.BOOLEAN;
+                        break;
+                    // #endregion 
+                    // #region INTEGER type 
+                    case 2:
+                        new_asn1_type = in_window.org.pkijs.asn1.INTEGER;
+                        break;
+                    // #endregion 
+                    // #region BITSTRING type 
+                    case 3:
+                        new_asn1_type = in_window.org.pkijs.asn1.BITSTRING;
+                        break;
+                    // #endregion 
+                    // #region OCTETSTRING type 
+                    case 4:
+                        new_asn1_type = in_window.org.pkijs.asn1.OCTETSTRING;
+                        break;
+                    // #endregion 
+                    // #region NULL type 
+                    case 5:
+                        new_asn1_type = in_window.org.pkijs.asn1.NULL;
+                        break;
+                    // #endregion 
+                    // #region OBJECT IDENTIFIER type 
+                    case 6:
+                        new_asn1_type = in_window.org.pkijs.asn1.OID;
+                        break;
+                    // #endregion 
+                    // #region ENUMERATED type 
+                    case 10:
+                        new_asn1_type = in_window.org.pkijs.asn1.ENUMERATED;
+                        break;
+                    // #endregion 
+                    // #region UTF8STRING type 
+                    case 12:
+                        new_asn1_type = in_window.org.pkijs.asn1.UTF8STRING;
+                        break;
+                    // #endregion 
+                    // #region TIME type 
+                    case 14:
+                        new_asn1_type = in_window.org.pkijs.asn1.TIME;
+                        break;
+                    // #endregion 
+                    // #region ASN.1 reserved type 
+                    case 15:
+                        return_object.error = "[UNIVERSAL 15] is reserved by ASN.1 standard";
+                        return {
+                            offset: (-1),
+                            result: return_object
+                        };
+                        break;
+                    // #endregion 
+                    // #region SEQUENCE type 
+                    case 16:
+                        new_asn1_type = in_window.org.pkijs.asn1.SEQUENCE;
+                        break;
+                    // #endregion 
+                    // #region SET type 
+                    case 17:
+                        new_asn1_type = in_window.org.pkijs.asn1.SET;
+                        break;
+                    // #endregion 
+                    // #region NUMERICSTRING type 
+                    case 18:
+                        new_asn1_type = in_window.org.pkijs.asn1.NUMERICSTRING;
+                        break;
+                    // #endregion 
+                    // #region PRINTABLESTRING type 
+                    case 19:
+                        new_asn1_type = in_window.org.pkijs.asn1.PRINTABLESTRING;
+                        break;
+                    // #endregion 
+                    // #region TELETEXSTRING type 
+                    case 20:
+                        new_asn1_type = in_window.org.pkijs.asn1.TELETEXSTRING;
+                        break;
+                    // #endregion 
+                    // #region VIDEOTEXSTRING type 
+                    case 21:
+                        new_asn1_type = in_window.org.pkijs.asn1.VIDEOTEXSTRING;
+                        break;
+                    // #endregion 
+                    // #region IA5STRING type 
+                    case 22:
+                        new_asn1_type = in_window.org.pkijs.asn1.IA5STRING;
+                        break;
+                    // #endregion 
+                    // #region UTCTIME type 
+                    case 23:
+                        new_asn1_type = in_window.org.pkijs.asn1.UTCTIME;
+                        break;
+                    // #endregion 
+                    // #region GENERALIZEDTIME type 
+                    case 24:
+                        new_asn1_type = in_window.org.pkijs.asn1.GENERALIZEDTIME;
+                        break;
+                    // #endregion 
+                    // #region GRAPHICSTRING type 
+                    case 25:
+                        new_asn1_type = in_window.org.pkijs.asn1.GRAPHICSTRING;
+                        break;
+                    // #endregion 
+                    // #region VISIBLESTRING type 
+                    case 26:
+                        new_asn1_type = in_window.org.pkijs.asn1.VISIBLESTRING;
+                        break;
+                    // #endregion 
+                    // #region GENERALSTRING type 
+                    case 27:
+                        new_asn1_type = in_window.org.pkijs.asn1.GENERALSTRING;
+                        break;
+                    // #endregion 
+                    // #region UNIVERSALSTRING type 
+                    case 28:
+                        new_asn1_type = in_window.org.pkijs.asn1.UNIVERSALSTRING;
+                        break;
+                    // #endregion 
+                    // #region CHARACTERSTRING type 
+                    case 29:
+                        new_asn1_type = in_window.org.pkijs.asn1.CHARACTERSTRING;
+                        break;
+                    // #endregion 
+                    // #region BMPSTRING type 
+                    case 30:
+                        new_asn1_type = in_window.org.pkijs.asn1.BMPSTRING;
+                        break;
+                    // #endregion 
+                    // #region DATE type 
+                    case 31:
+                        new_asn1_type = in_window.org.pkijs.asn1.DATE;
+                        break;
+                    // #endregion 
+                    // #region TIMEOFDAY type 
+                    case 32:
+                        new_asn1_type = in_window.org.pkijs.asn1.TIMEOFDAY;
+                        break;
+                    // #endregion 
+                    // #region DATE-TIME type 
+                    case 33:
+                        new_asn1_type = in_window.org.pkijs.asn1.DATETIME;
+                        break;
+                    // #endregion 
+                    // #region DURATION type 
+                    case 34:
+                        new_asn1_type = in_window.org.pkijs.asn1.DURATION;
+                        break;
+                    // #endregion 
+                    // #region default 
+                    default:
+                        {
+                            var new_object;
+
+                            if(return_object.id_block.is_constructed == true)
+                                new_object = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
+                            else
+                                new_object = new in_window.org.pkijs.asn1.ASN1_PRIMITIVE();
+
+                            new_object.id_block = return_object.id_block;
+                            new_object.len_block = return_object.len_block;
+                            new_object.warnings = return_object.warnings;
+
+                            return_object = new_object;
+
+                            result_offset = return_object.fromBER(input_buffer, input_offset, input_length);
+                        }
+                    // #endregion 
+                }
+                break;
+            // #endregion 
+            // #region All other tag classes 
+            case 2: // APPLICATION
+            case 3: // CONTEXT-SPECIFIC
+            case 4: // PRIVATE
+            default:
+                {
+                    if(return_object.id_block.is_constructed == true)
+                        new_asn1_type = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED;
+                    else
+                        new_asn1_type = in_window.org.pkijs.asn1.ASN1_PRIMITIVE;
+                }
+            // #endregion 
+        }
+        // #endregion 
+
+        // #region Change type and perform BER decoding 
+        return_object = local_change_type(return_object, new_asn1_type);
+        result_offset = return_object.fromBER(input_buffer, input_offset, (return_object.len_block.is_indefinite_form == true) ? input_length : return_object.len_block.length);
+        // #endregion 
+
+        // #region Coping incoming buffer for entire ASN.1 block 
+        return_object.value_before_decode = util_copybuf_offset(input_buffer, incoming_offset, return_object.block_length);
+        // #endregion 
+
+        return {
+            offset: result_offset,
+            result: return_object
+        };
+    }
+    //**************************************************************************************
+    in_window.org.pkijs.fromBER = 
+    function(input_buffer)
+    {
+        /// <summary>Major function for decoding ASN.1 BER array into internal library structuries</summary>
+        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array of bytes</param>
+
+        if(input_buffer.byteLength == 0)
+        {
+            var result = new in_window.org.pkijs.asn1.ASN1_block();
+            result.error = "Input buffer has zero length";
+
+            return {
+                offset: (-1),
+                result: result
+            };
+        }
+
+        return fromBER_raw(input_buffer, 0, input_buffer.byteLength);
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Major scheme verification function 
+    //**************************************************************************************
+    in_window.org.pkijs.compareSchema =
+    function(root, input_asn1_data, input_asn1_schema)
+    {
+        // #region Special case for CHOICE schema element type 
+        if(input_asn1_schema instanceof in_window.org.pkijs.asn1.CHOICE)
+        {
+            var choice_result = false;
+
+            for(var j = 0; j < input_asn1_schema.value.length; j++)
+            {
+                var result = in_window.org.pkijs.compareSchema(root, input_asn1_data, input_asn1_schema.value[j]);
+                if(result.verified === true)
+                    return {
+                        verified: true,
+                        result: root
+                    };
+            }
+
+            if(choice_result === false)
+            {
+                var _result = {
+                    verified: false,
+                    result: {
+                        error: "Wrong values for CHOICE type"
+                    }
+                };
+
+                if(input_asn1_schema.hasOwnProperty('name'))
+                    _result.name = input_asn1_schema.name;
+
+                return _result;
+            }
+        }
+        // #endregion 
+
+        // #region Special case for ANY schema element type 
+        if(input_asn1_schema instanceof in_window.org.pkijs.asn1.ANY)
+        {
+            // #region Add named component of ASN.1 schema 
+            if(input_asn1_schema.hasOwnProperty('name'))
+                root[input_asn1_schema.name] = input_asn1_data;
+            // #endregion 
+
+            return {
+                verified: true,
+                result: root
+            };
+        }
+        // #endregion 
+
+        // #region Initial check 
+        if((root instanceof Object) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong root object" }
+            };
+
+        if((input_asn1_data instanceof Object) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 data" }
+            };
+
+        if((input_asn1_schema instanceof Object) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(('id_block' in input_asn1_schema) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+        // #endregion 
+
+        // #region Comparing id_block properties in ASN.1 data and ASN.1 schema 
+        // #region Encode and decode ASN.1 schema id_block 
+        /// <remarks>This encoding/decoding is neccessary because could be an errors in schema definition</remarks>
+        if(('fromBER' in input_asn1_schema.id_block) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(('toBER' in input_asn1_schema.id_block) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        var encoded_id = input_asn1_schema.id_block.toBER(false);
+        if(encoded_id.byteLength === 0)
+            return {
+                verified: false,
+                result: { error: "Error encoding id_block for ASN.1 schema" }
+            };
+
+        var decoded_offset = input_asn1_schema.id_block.fromBER(encoded_id, 0, encoded_id.byteLength);
+        if(decoded_offset === (-1))
+            return {
+                verified: false,
+                result: { error: "Error decoding id_block for ASN.1 schema" }
+            };
+        // #endregion 
+
+        // #region tag_class 
+        if(input_asn1_schema.id_block.hasOwnProperty('tag_class') === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(input_asn1_schema.id_block.tag_class !== input_asn1_data.id_block.tag_class)
+            return {
+                verified: false,
+                result: root
+            };
+        // #endregion 
+        // #region tag_number 
+        if(input_asn1_schema.id_block.hasOwnProperty('tag_number') === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(input_asn1_schema.id_block.tag_number !== input_asn1_data.id_block.tag_number)
+            return {
+                verified: false,
+                result: root
+            };
+        // #endregion 
+        // #region is_constructed 
+        if(input_asn1_schema.id_block.hasOwnProperty('is_constructed') === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(input_asn1_schema.id_block.is_constructed !== input_asn1_data.id_block.is_constructed)
+            return {
+                verified: false,
+                result: root
+            };
+        // #endregion 
+        // #region is_hex_only 
+        if(('is_hex_only' in input_asn1_schema.id_block) === false) // Since 'is_hex_only' is an inhirited property
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema" }
+            };
+
+        if(input_asn1_schema.id_block.is_hex_only !== input_asn1_data.id_block.is_hex_only)
+            return {
+                verified: false,
+                result: root
+            };
+        // #endregion 
+        // #region value_hex 
+        if(input_asn1_schema.id_block.is_hex_only === true)
+        {
+            if(('value_hex' in input_asn1_schema.id_block) === false) // Since 'value_hex' is an inhirited property
+                return {
+                    verified: false,
+                    result: { error: "Wrong ASN.1 schema" }
+                };
+
+            var schema_view = new Uint8Array(input_asn1_schema.id_block.value_hex);
+            var asn1_view = new Uint8Array(input_asn1_data.id_block.value_hex);
+
+            if(schema_view.length !== asn1_view.length)
+                return {
+                    verified: false,
+                    result: root
+                };
+
+            for(var i = 0; i < schema_view.length; i++)
+            {
+                if(schema_view[i] !== asn1_view[1])
+                    return {
+                        verified: false,
+                        result: root
+                    };
+            }
+        }
+        // #endregion 
+        // #endregion 
+
+        // #region Add named component of ASN.1 schema 
+        if(input_asn1_schema.hasOwnProperty('name'))
+        {
+            input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+            if(input_asn1_schema.name !== "")
+                root[input_asn1_schema.name] = input_asn1_data;
+        }
+        // #endregion 
+
+        // #region Getting next ASN.1 block for comparition 
+        if(input_asn1_schema.id_block.is_constructed === true)
+        {
+            var admission = 0;
+            var result = { verified: false };
+
+            var max_length = input_asn1_schema.value_block.value.length;
+
+            if(max_length > 0)
+            {
+                if(input_asn1_schema.value_block.value[0] instanceof in_window.org.pkijs.asn1.REPEATED)
+                    max_length = input_asn1_data.value_block.value.length;
+            }
+
+            // #region Special case when constructive value has no elements 
+            if(max_length === 0)
+                return {
+                    verified: true,
+                    result: root
+                };
+            // #endregion 
+
+            // #region Special case when "input_asn1_data" has no values and "input_asn1_schema" has all optional values
+            if((input_asn1_data.value_block.value.length === 0) && 
+               (input_asn1_schema.value_block.value.length !== 0))
+            {
+                var _optional = true;
+
+                for(var i = 0; i < input_asn1_schema.value_block.value.length; i++)
+                    _optional = _optional && (input_asn1_schema.value_block.value[i].optional || false);
+
+                if(_optional === true)
+                {
+                    return {
+                        verified: true,
+                        result: root
+                    };
+                }
+                else
+                {
+                    // #region Delete early added name of block 
+                    if(input_asn1_schema.hasOwnProperty('name'))
+                    {
+                        input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                        if(input_asn1_schema.name !== "")
+                            delete root[input_asn1_schema.name];
+                    }
+                    // #endregion 
+
+                    root.error = "Inconsistent object length";
+
+                    return {
+                        verified: false,
+                        result: root
+                    };
+                }
+            }
+            // #endregion 
+
+            for(var i = 0; i < max_length; i++)
+            {
+                // #region Special case when there is an "optional" element of ASN.1 schema at the end 
+                if((i - admission) >= input_asn1_data.value_block.value.length)
+                {
+                    if(input_asn1_schema.value_block.value[i].optional === false)
+                    {
+                        var _result = {
+                            verified: false,
+                            result: root
+                        };
+
+                        root.error = "Inconsistent length between ASN.1 data and schema";
+
+                        // #region Delete early added name of block 
+                        if(input_asn1_schema.hasOwnProperty('name'))
+                        {
+                            input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                            if(input_asn1_schema.name !== "")
+                            {
+                                delete root[input_asn1_schema.name];
+                                _result.name = input_asn1_schema.name;
+                            }
+                        }
+                        // #endregion 
+
+                        return _result;
+                    }
+                }
+                    // #endregion 
+                else
+                {
+                    // #region Special case for REPEATED type of ASN.1 schema element 
+                    if(input_asn1_schema.value_block.value[0] instanceof in_window.org.pkijs.asn1.REPEATED)
+                    {
+                        result = in_window.org.pkijs.compareSchema(root, input_asn1_data.value_block.value[i], input_asn1_schema.value_block.value[0].value);
+                        if(result.verified === false)
+                        {
+                            if(input_asn1_schema.value_block.value[0].optional === true)
+                                admission++;
+                            else
+                            {
+                                // #region Delete early added name of block 
+                                if(input_asn1_schema.hasOwnProperty('name'))
+                                {
+                                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                                    if(input_asn1_schema.name !== "")
+                                        delete root[input_asn1_schema.name];
+                                }
+                                // #endregion 
+
+                                return result;
+                            }
+                        }
+
+                        if(("name" in input_asn1_schema.value_block.value[0]) && (input_asn1_schema.value_block.value[0].name.length > 0))
+                        {
+                            var array_root = {};
+
+                            if(("local" in input_asn1_schema.value_block.value[0]) && (input_asn1_schema.value_block.value[0].local === true))
+                                array_root = input_asn1_data;
+                            else
+                                array_root = root;
+
+                            if(typeof array_root[input_asn1_schema.value_block.value[0].name] === "undefined")
+                                array_root[input_asn1_schema.value_block.value[0].name] = new Array();
+
+                            array_root[input_asn1_schema.value_block.value[0].name].push(input_asn1_data.value_block.value[i]);
+                        }
+                    }
+                        // #endregion 
+                    else
+                    {
+                        result = in_window.org.pkijs.compareSchema(root, input_asn1_data.value_block.value[i - admission], input_asn1_schema.value_block.value[i]);
+                        if(result.verified === false)
+                        {
+                            if(input_asn1_schema.value_block.value[i].optional === true)
+                                admission++;
+                            else
+                            {
+                                // #region Delete early added name of block 
+                                if(input_asn1_schema.hasOwnProperty('name'))
+                                {
+                                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                                    if(input_asn1_schema.name !== "")
+                                        delete root[input_asn1_schema.name];
+                                }
+                                // #endregion 
+
+                                return result;
+                            }
+                        }
+                    }
+                }
+            }
+
+            if(result.verified === false) // The situation may take place if last element is "optional" and verification failed
+            {
+                var _result = {
+                    verified: false,
+                    result: root
+                };
+
+                // #region Delete early added name of block 
+                if(input_asn1_schema.hasOwnProperty('name'))
+                {
+                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                    if(input_asn1_schema.name !== "")
+                    {
+                        delete root[input_asn1_schema.name];
+                        _result.name = input_asn1_schema.name;
+                    }
+                }
+                // #endregion 
+
+                return _result;
+            }
+
+            return {
+                verified: true,
+                result: root
+            };
+        }
+        // #endregion 
+        // #region Ability to parse internal value for primitive-encoded value (value of OCTETSTRING, for example)
+        else
+        {
+            if( ("primitive_schema" in input_asn1_schema) &&
+                ("value_hex" in input_asn1_data.value_block) )
+            {
+                // #region Decoding of raw ASN.1 data 
+                var asn1 = in_window.org.pkijs.fromBER(input_asn1_data.value_block.value_hex);
+                if(asn1.offset === (-1))
+                {
+                    var _result = {
+                        verified: false,
+                        result: asn1.result
+                    };
+
+                    // #region Delete early added name of block 
+                    if(input_asn1_schema.hasOwnProperty('name'))
+                    {
+                        input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
+                        if(input_asn1_schema.name !== "")
+                        {
+                            delete root[input_asn1_schema.name];
+                            _result.name = input_asn1_schema.name;
+                        }
+                    }
+                    // #endregion 
+
+                    return _result;
+                }
+                // #endregion 
+
+                return in_window.org.pkijs.compareSchema(root, asn1.result, input_asn1_schema.primitive_schema);
+            }
+            else
+                return {
+                    verified: true,
+                    result: root
+                };
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.verifySchema =
+    function(input_buffer, input_schema)
+    {
+        // #region Initial check 
+        if((input_schema instanceof Object) === false)
+            return {
+                verified: false,
+                result: { error: "Wrong ASN.1 schema type" }
+            };
+        // #endregion 
+
+        // #region Decoding of raw ASN.1 data 
+        var asn1 = in_window.org.pkijs.fromBER(input_buffer);
+        if(asn1.offset === (-1))
+            return {
+                verified: false,
+                result: asn1.result
+            };
+        // #endregion 
+
+        // #region Compare ASN.1 struct with input schema 
+        return in_window.org.pkijs.compareSchema(asn1.result, asn1.result, input_schema);
+        // #endregion 
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Major function converting JSON to ASN.1 objects 
+    //**************************************************************************************
+    in_window.org.pkijs.fromJSON = 
+    function(json)
+    {
+        /// <summary>Converting from JSON to ASN.1 objects</summary>
+        /// <param name="json" type="String|Object">JSON string or object to convert to ASN.1 objects</param>
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+}
+)(typeof exports !== "undefined" ? exports : window);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/u2f/tests/pkijs/common.js
@@ -0,0 +1,1542 @@
+/*
+ * Copyright (c) 2014, GMO GlobalSign
+ * Copyright (c) 2015, Peculiar Ventures
+ * All rights reserved.
+ *
+ * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE. 
+ *
+ */
+(
+function(in_window)
+{
+    //**************************************************************************************
+    // #region Declaration of global variables 
+    //**************************************************************************************
+    // #region "org" namespace 
+    if(typeof in_window.org === "undefined")
+        in_window.org = {};
+    else
+    {
+        if(typeof in_window.org !== "object")
+            throw new Error("Name org already exists and it's not an object");
+    }
+    // #endregion 
+
+    // #region "org.pkijs" namespace 
+    if(typeof in_window.org.pkijs === "undefined")
+        in_window.org.pkijs = {};
+    else
+    {
+        if(typeof in_window.org.pkijs !== "object")
+            throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
+    }
+    // #endregion 
+
+    // #region "local" namespace 
+    var local = {};
+    // #endregion   
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Settings for "crypto engine" 
+    //**************************************************************************************
+    local.engine = {
+        name: "none",
+        crypto: null,
+        subtle: null
+    };
+
+    if(typeof window != "undefined")
+    {
+        if("crypto" in window)
+        {
+            var engineName = "webcrypto";
+            var cryptoObject = window.crypto;
+            var subtleObject = null;
+
+            // Apple Safari support
+            if("webkitSubtle" in window.crypto)
+                subtleObject = window.crypto.webkitSubtle;
+
+            if("subtle" in window.crypto)
+                subtleObject = window.crypto.subtle;
+
+            local.engine = {
+                name: engineName,
+                crypto: cryptoObject,
+                subtle: subtleObject
+            };
+        }
+    }
+    //**************************************************************************************
+    in_window.org.pkijs.setEngine =
+    function(name, crypto, subtle)
+    {
+        /// <summary>Setting the global "crypto engine" parameters</summary>
+        /// <param name="name" type="String">Auxiliary name for "crypto engine"</param>
+        /// <param name="crypto" type="Object">Object handling all root cryptographic requests (in fact currently it must handle only "getRandomValues")</param>
+        /// <param name="subtle" type="Object">Object handling all main cryptographic requests</param>
+
+        local.engine = {
+            name: name,
+            crypto: crypto,
+            subtle: subtle
+        };
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getEngine =
+    function()
+    {
+        return local.engine;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Declaration of common functions 
+    //**************************************************************************************
+    in_window.org.pkijs.emptyObject =
+    function()
+    {
+        this.toJSON = function()
+        {
+            return {};
+        };
+        this.toSchema = function()
+        {
+            return {};
+        };
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getNames =
+    function(arg)
+    {
+        /// <summary>Get correct "names" array for all "schema" objects</summary>
+
+        var names = {};
+
+        if(arg instanceof Object)
+            names = (arg.names || {});
+
+        return names;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.inheriteObjectFields =
+    function(from)
+    {
+        for(var i in from.prototype)
+        {
+            if(typeof from.prototype[i] === "function")
+                continue;
+
+            this[i] = from.prototype[i];
+        }
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getUTCDate =
+    function(date)
+    {
+        /// <summary>Making UTC date from local date</summary>
+        /// <param name="date" type="Date">Date to convert from</param>
+
+        var current_date = date;
+        return new Date(current_date.getTime() + (current_date.getTimezoneOffset() * 60000));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.padNumber =
+    function(input_number, full_length)
+    {
+        var str = input_number.toString(10);
+        var dif = full_length - str.length;
+
+        var padding = new Array(dif);
+        for(var i = 0; i < dif; i++)
+            padding[i] = '0';
+
+        var padding_string = padding.join('');
+
+        return padding_string.concat(str);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getValue =
+    function(args, item, default_value)
+    {
+        if(item in args)
+            return args[item];
+        else
+            return default_value;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.isEqual_view =
+    function(input_view1, input_view2)
+    {
+        /// <summary>Compare two Uint8Arrays</summary>
+        /// <param name="input_view1" type="Uint8Array">First Uint8Array for comparision</param>
+        /// <param name="input_view2" type="Uint8Array">Second Uint8Array for comparision</param>
+
+        if(input_view1.length !== input_view2.length)
+            return false;
+
+        for(var i = 0; i < input_view1.length; i++)
+        {
+            if(input_view1[i] != input_view2[i])
+                return false;
+        }
+
+        return true;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.isEqual_buffer =
+    function(input_buffer1, input_buffer2)
+    {
+        /// <summary>Compare two array buffers</summary>
+        /// <param name="input_buffer1" type="ArrayBuffer">First ArrayBuffer for comparision</param>
+        /// <param name="input_buffer2" type="ArrayBuffer">Second ArrayBuffer for comparision</param>
+
+        if(input_buffer1.byteLength != input_buffer2.byteLength)
+            return false;
+
+        var view1 = new Uint8Array(input_buffer1);
+        var view2 = new Uint8Array(input_buffer2);
+
+        return in_window.org.pkijs.isEqual_view(view1, view2);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.concat_buffers =
+    function(input_buf1, input_buf2)
+    {
+        /// <summary>Concatenate two ArrayBuffers</summary>
+        /// <param name="input_buf1" type="ArrayBuffer">First ArrayBuffer (first part of concatenated array)</param>
+        /// <param name="input_buf2" type="ArrayBuffer">Second ArrayBuffer (second part of concatenated array)</param>
+
+        var input_view1 = new Uint8Array(input_buf1);
+        var input_view2 = new Uint8Array(input_buf2);
+
+        var ret_buf = new ArrayBuffer(input_buf1.byteLength + input_buf2.byteLength);
+        var ret_view = new Uint8Array(ret_buf);
+
+        for(var i = 0; i < input_buf1.byteLength; i++)
+            ret_view[i] = input_view1[i];
+
+        for(var j = 0; j < input_buf2.byteLength; j++)
+            ret_view[input_buf1.byteLength + j] = input_view2[j];
+
+        return ret_buf;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.copyBuffer =
+    function(input_buffer)
+    {
+        var result = new ArrayBuffer(input_buffer.byteLength);
+
+        var resultView = new Uint8Array(result);
+        var inputView = new Uint8Array(input_buffer);
+
+        for(var i = 0; i < inputView.length; i++)
+            resultView[i] = inputView[i];
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getCrypto =
+    function()
+    {
+        var crypto_temp;
+
+        if(local.engine.subtle !== null)
+            crypto_temp = local.engine.subtle;
+
+        return crypto_temp;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.stringPrep =
+    function(input_string)
+    {
+        /// <summary>String preparation function. In a future here will be realization of algorithm from RFC4518.</summary>
+        /// <param name="input_string" type="String">JavaScript string. As soon as for each ASN.1 string type we have a specific transformation function here we will work with pure JavaScript string</param>
+        /// <returns type="String">Formated string</returns>
+
+        var result = input_string.replace(/^\s+|\s+$/g, ""); // Trim input string
+        result = result.replace(/\s+/g, " "); // Change all sequence of SPACE down to SPACE char
+        result = result.toLowerCase();
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.bufferToHexCodes =
+    function(input_buffer, input_offset, input_lenght)
+    {
+        var result = "";
+
+        var int_buffer = new Uint8Array(input_buffer, input_offset, input_lenght);
+
+        for(var i = 0; i < int_buffer.length; i++)
+        {
+            var str = int_buffer[i].toString(16).toUpperCase();
+            result = result + ((str.length === 1) ? "0" : "") + str;
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.bufferFromHexCodes =
+    function(hexString)
+    {
+        /// <summary>Create an ArrayBuffer from string having hexdecimal codes</summary>
+        /// <param name="hexString" type="String">String to create ArrayBuffer from</param>
+
+        // #region Initial variables 
+        var stringLength = hexString.length;
+
+        var resultBuffer = new ArrayBuffer(stringLength >> 1);
+        var resultView = new Uint8Array(resultBuffer);
+
+        var hex_map = {};
+
+        hex_map['0'] = 0x00;
+        hex_map['1'] = 0x01;
+        hex_map['2'] = 0x02;
+        hex_map['3'] = 0x03;
+        hex_map['4'] = 0x04;
+        hex_map['5'] = 0x05;
+        hex_map['6'] = 0x06;
+        hex_map['7'] = 0x07;
+        hex_map['8'] = 0x08;
+        hex_map['9'] = 0x09;
+        hex_map['A'] = 0x0A;
+        hex_map['a'] = 0x0A;
+        hex_map['B'] = 0x0B;
+        hex_map['b'] = 0x0B;
+        hex_map['C'] = 0x0C;
+        hex_map['c'] = 0x0C;
+        hex_map['D'] = 0x0D;
+        hex_map['d'] = 0x0D;
+        hex_map['E'] = 0x0E;
+        hex_map['e'] = 0x0E;
+        hex_map['F'] = 0x0F;
+        hex_map['f'] = 0x0F;
+
+        var j = 0;
+        var temp = 0x00;
+        // #endregion 
+
+        // #region Convert char-by-char 
+        for(var i = 0; i < stringLength; i++)
+        {
+            if(!(i % 2))
+                temp = hex_map[hexString.charAt(i)] << 4;
+            else
+            {
+                temp |= hex_map[hexString.charAt(i)];
+
+                resultView[j] = temp;
+                j++;
+            }
+        }
+        // #endregion 
+
+        return resultBuffer;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getRandomValues =
+    function(view)
+    {
+        /// <param name="view" type="Uint8Array">New array which gives a length for random value</param>
+
+        if(local.engine.crypto !== null)
+            return local.engine.crypto.getRandomValues(view);
+        else
+            throw new Error("No support for Web Cryptography API");
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getAlgorithmParameters =
+    function(algorithmName, operation)
+    {
+        /// <param name="algorithmName" type="String">Algorithm name to get common parameters for</param>
+        /// <param name="operation" type="String">Kind of operation: "sign", "encrypt", "generatekey", "importkey", "exportkey", "verify"</param>
+
+        var result = {
+            algorithm: {},
+            usages: []
+        };
+
+        switch(algorithmName.toUpperCase())
+        {
+            case "RSASSA-PKCS1-V1_5":
+                switch(operation.toLowerCase())
+                {
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "RSASSA-PKCS1-v1_5",
+                                modulusLength: 2048,
+                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    case "verify":
+                    case "sign":
+                    case "importkey":
+                        result = {
+                            algorithm: {
+                                name: "RSASSA-PKCS1-v1_5",
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only
+                        };
+                        break;
+                    case "exportkey":
+                    default:
+                        return {
+                            algorithm: {
+                                name: "RSASSA-PKCS1-v1_5"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "RSA-PSS":
+                switch(operation.toLowerCase())
+                {
+                    case "sign":
+                    case "verify":
+                        result = {
+                            algorithm: {
+                                name: "RSA-PSS",
+                                hash: {
+                                    name: "SHA-1"
+                                },
+                                saltLength: 20
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "RSA-PSS",
+                                modulusLength: 2048,
+                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
+                                hash: {
+                                    name: "SHA-1"
+                                }
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    case "importkey":
+                        result = {
+                            algorithm: {
+                                name: "RSA-PSS",
+                                hash: {
+                                    name: "SHA-1"
+                                }
+                            },
+                            usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only
+                        };
+                        break;
+                    case "exportkey":
+                    default:
+                        return {
+                            algorithm: {
+                                name: "RSA-PSS"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "RSA-OAEP":
+                switch(operation.toLowerCase())
+                {
+                    case "encrypt":
+                    case "decrypt":
+                        result = {
+                            algorithm: {
+                                name: "RSA-OAEP"
+                            },
+                            usages: ["encrypt", "decrypt"]
+                        };
+                        break;
+                        break;
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "RSA-OAEP",
+                                modulusLength: 2048,
+                                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    case "importkey":
+                        result = {
+                            algorithm: {
+                                name: "RSA-OAEP",
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["encrypt"] // encrypt for "spki" and decrypt for "pkcs8"
+                        };
+                        break;
+                    case "exportkey":
+                    default:
+                        return {
+                            algorithm: {
+                                name: "RSA-OAEP"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "ECDSA":
+                switch(operation.toLowerCase())
+                {
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "ECDSA",
+                                namedCurve: "P-256"
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    case "importkey":
+                        result = {
+                            algorithm: {
+                                name: "ECDSA",
+                                namedCurve: "P-256"
+                            },
+                            usages: ["verify"] // "sign" for "pkcs8"
+                        };
+                        break;
+                    case "verify":
+                    case "sign":
+                        result = {
+                            algorithm: {
+                                name: "ECDSA",
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["sign"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "ECDSA"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "ECDH":
+                switch(operation.toLowerCase())
+                {
+                    case "exportkey":
+                    case "importkey":
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "ECDH",
+                                namedCurve: "P-256"
+                            },
+                            usages: ["deriveKey", "deriveBits"]
+                        };
+                        break;
+                    case "derivekey":
+                    case "derivebits":
+                        result = {
+                            algorithm: {
+                                name: "ECDH",
+                                namedCurve: "P-256",
+                                public: [] // Must be a "publicKey"
+                            },
+                            usages: ["encrypt", "decrypt"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "ECDH"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "AES-CTR":
+                switch(operation.toLowerCase())
+                {
+                    case "importkey":
+                    case "exportkey":
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "AES-CTR",
+                                length: 256
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    case "decrypt":
+                    case "encrypt":
+                        result = {
+                            algorithm: {
+                                name: "AES-CTR",
+                                counter: new Uint8Array(16),
+                                length: 10
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "AES-CTR"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "AES-CBC":
+                switch(operation.toLowerCase())
+                {
+                    case "importkey":
+                    case "exportkey":
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "AES-CBC",
+                                length: 256
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    case "decrypt":
+                    case "encrypt":
+                        result = {
+                            algorithm: {
+                                name: "AES-CBC",
+                                iv: in_window.org.pkijs.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "AES-CBC"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "AES-GCM":
+                switch(operation.toLowerCase())
+                {
+                    case "importkey":
+                    case "exportkey":
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "AES-GCM",
+                                length: 256
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    case "decrypt":
+                    case "encrypt":
+                        result = {
+                            algorithm: {
+                                name: "AES-GCM",
+                                iv: in_window.org.pkijs.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step
+                            },
+                            usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "AES-GCM"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "AES-KW":
+                switch(operation.toLowerCase())
+                {
+                    case "importkey":
+                    case "exportkey":
+                    case "generatekey":
+                    case "wrapkey":
+                    case "unwrapkey":
+                        result = {
+                            algorithm: {
+                                name: "AES-KW",
+                                length: 256
+                            },
+                            usages: ["wrapKey", "unwrapKey"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "AES-KW"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "HMAC":
+                switch(operation.toLowerCase())
+                {
+                    case "sign":
+                    case "verify":
+                        result = {
+                            algorithm: {
+                                name: "HMAC"
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    case "importkey":
+                    case "exportkey":
+                    case "generatekey":
+                        result = {
+                            algorithm: {
+                                name: "HMAC",
+                                length: 32,
+                                hash: {
+                                    name: "SHA-256"
+                                }
+                            },
+                            usages: ["sign", "verify"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "HMAC"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "HKDF":
+                switch(operation.toLowerCase())
+                {
+                    case "derivekey":
+                        result = {
+                            algorithm: {
+                                name: "HKDF",
+                                hash: "SHA-256",
+                                salt: new Uint8Array(),
+                                info: new Uint8Array()
+                            },
+                            usages: ["encrypt", "decrypt"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "HKDF"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            case "PBKDF2":
+                switch(operation.toLowerCase())
+                {
+                    case "derivekey":
+                        result = {
+                            algorithm: {
+                                name: "PBKDF2",
+                                hash: { name: "SHA-256" },
+                                salt: new Uint8Array(),
+                                iterations: 1000
+                            },
+                            usages: ["encrypt", "decrypt"]
+                        };
+                        break;
+                    default:
+                        return {
+                            algorithm: {
+                                name: "PBKDF2"
+                            },
+                            usages: []
+                        };
+                }
+                break;
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getOIDByAlgorithm =
+    function(algorithm)
+    {
+        /// <summary>Get OID for each specific WebCrypto algorithm</summary>
+        /// <param name="algorithm" type="Object">WebCrypto algorithm</param>
+
+        var result = "";
+
+        switch(algorithm.name.toUpperCase())
+        {
+            case "RSASSA-PKCS1-V1_5":
+                switch(algorithm.hash.name.toUpperCase())
+                {
+                    case "SHA-1":
+                        result = "1.2.840.113549.1.1.5";
+                        break;
+                    case "SHA-256":
+                        result = "1.2.840.113549.1.1.11";
+                        break;
+                    case "SHA-384":
+                        result = "1.2.840.113549.1.1.12";
+                        break;
+                    case "SHA-512":
+                        result = "1.2.840.113549.1.1.13";
+                        break;
+                    default:
+                }
+                break;
+            case "RSA-PSS":
+                result = "1.2.840.113549.1.1.10";
+                break;
+            case "RSA-OAEP":
+                result = "1.2.840.113549.1.1.7";
+                break;
+            case "ECDSA":
+                switch(algorithm.hash.name.toUpperCase())
+                {
+                    case "SHA-1":
+                        result = "1.2.840.10045.4.1";
+                        break;
+                    case "SHA-256":
+                        result = "1.2.840.10045.4.3.2";
+                        break;
+                    case "SHA-384":
+                        result = "1.2.840.10045.4.3.3";
+                        break;
+                    case "SHA-512":
+                        result = "1.2.840.10045.4.3.4";
+                        break;
+                    default:
+                }
+                break;
+            case "ECDH":
+                switch(algorithm.kdf.toUpperCase()) // Non-standard addition - hash algorithm of KDF function
+                {
+                    case "SHA-1":
+                        result = "1.3.133.16.840.63.0.2"; // dhSinglePass-stdDH-sha1kdf-scheme
+                        break;
+                    case "SHA-256":
+                        result = "1.3.132.1.11.1"; // dhSinglePass-stdDH-sha256kdf-scheme 
+                        break;
+                    case "SHA-384":
+                        result = "1.3.132.1.11.2"; // dhSinglePass-stdDH-sha384kdf-scheme
+                        break;
+                    case "SHA-512":
+                        result = "1.3.132.1.11.3"; // dhSinglePass-stdDH-sha512kdf-scheme
+                        break;
+                    default:
+                }
+                break;
+            case "AES-CTR":
+                break;
+            case "AES-CBC":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.2";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.22";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.42";
+                        break;
+                    default:
+                }
+                break;
+            case "AES-CMAC":
+                break;
+            case "AES-GCM":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.6";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.26";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.46";
+                        break;
+                    default:
+                }
+                break;
+            case "AES-CFB":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.4";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.24";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.44";
+                        break;
+                    default:
+                }
+                break;
+            case "AES-KW":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.5";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.25";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.45";
+                        break;
+                    default:
+                }
+                break;
+            case "HMAC":
+                switch(algorithm.hash.name.toUpperCase())
+                {
+                    case "SHA-1":
+                        result = "1.2.840.113549.2.7";
+                        break;
+                    case "SHA-256":
+                        result = "1.2.840.113549.2.9";
+                        break;
+                    case "SHA-384":
+                        result = "1.2.840.113549.2.10";
+                        break;
+                    case "SHA-512":
+                        result = "1.2.840.113549.2.11";
+                        break;
+                    default:
+                }
+                break;
+            case "DH":
+                result = "1.2.840.113549.1.9.16.3.5";
+                break;
+            case "SHA-1":
+                result = "1.3.14.3.2.26";
+                break;
+            case "SHA-256":
+                result = "2.16.840.1.101.3.4.2.1";
+                break;
+            case "SHA-384":
+                result = "2.16.840.1.101.3.4.2.2";
+                break;
+            case "SHA-512":
+                result = "2.16.840.1.101.3.4.2.3";
+                break;
+            case "CONCAT":
+                break;
+            case "HKDF":
+                break;
+            case "PBKDF2":
+                result = "1.2.840.113549.1.5.12";
+                break;
+            // #region Special case - OIDs for ECC curves 
+            case "P-256":
+                result = "1.2.840.10045.3.1.7";
+                break;
+            case "P-384":
+                result = "1.3.132.0.34";
+                break;
+            case "P-521":
+                result = "1.3.132.0.35";
+                break;
+            // #endregion 
+
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getAlgorithmByOID =
+    function(oid)
+    {
+        /// <summary>Get WebCrypto algorithm by wel-known OID</summary>
+        /// <param name="oid" type="String">Wel-known OID to search for</param>
+
+        var result = {};
+
+        switch(oid)
+        {
+            case "1.2.840.113549.1.1.5":
+                result = {
+                    name: "RSASSA-PKCS1-v1_5",
+                    hash: {
+                        name: "SHA-1"
+                    }
+                };
+                break;
+            case "1.2.840.113549.1.1.11":
+                result = {
+                    name: "RSASSA-PKCS1-v1_5",
+                    hash: {
+                        name: "SHA-256"
+                    }
+                };
+                break;
+            case "1.2.840.113549.1.1.12":
+                result = {
+                    name: "RSASSA-PKCS1-v1_5",
+                    hash: {
+                        name: "SHA-384"
+                    }
+                };
+                break;
+            case "1.2.840.113549.1.1.13":
+                result = {
+                    name: "RSASSA-PKCS1-v1_5",
+                    hash: {
+                        name: "SHA-512"
+                    }
+                };
+                break;
+            case "1.2.840.113549.1.1.10":
+                result = {
+                    name: "RSA-PSS"
+                };
+                break;
+            case "1.2.840.113549.1.1.7":
+                result = {
+                    name: "RSA-OAEP"
+                };
+                break;
+            case "1.2.840.10045.4.1":
+                result = {
+                    name: "ECDSA",
+                    hash: {
+                        name: "SHA-1"
+                    }
+                };
+                break;
+            case "1.2.840.10045.4.3.2":
+                result = {
+                    name: "ECDSA",
+                    hash: {
+                        name: "SHA-256"
+                    }
+                };
+                break;
+            case "1.2.840.10045.4.3.3":
+                result = {
+                    name: "ECDSA",
+                    hash: {
+                        name: "SHA-384"
+                    }
+                };
+                break;
+            case "1.2.840.10045.4.3.4":
+                result = {
+                    name: "ECDSA",
+                    hash: {
+                        name: "SHA-512"
+                    }
+                };
+                break;
+            case "1.3.133.16.840.63.0.2":
+                result = {
+                    name: "ECDH",
+                    kdf: "SHA-1"
+                };
+                break;
+            case "1.3.132.1.11.1":
+                result = {
+                    name: "ECDH",
+                    kdf: "SHA-256"
+                };
+                break;
+            case "1.3.132.1.11.2":
+                result = {
+                    name: "ECDH",
+                    kdf: "SHA-384"
+                };
+                break;
+            case "1.3.132.1.11.3":
+                result = {
+                    name: "ECDH",
+                    kdf: "SHA-512"
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.2":
+                result = {
+                    name: "AES-CBC",
+                    length: 128
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.22":
+                result = {
+                    name: "AES-CBC",
+                    length: 192
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.42":
+                result = {
+                    name: "AES-CBC",
+                    length: 256
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.6":
+                result = {
+                    name: "AES-GCM",
+                    length: 128
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.26":
+                result = {
+                    name: "AES-GCM",
+                    length: 192
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.46":
+                result = {
+                    name: "AES-GCM",
+                    length: 256
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.4":
+                result = {
+                    name: "AES-CFB",
+                    length: 128
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.24":
+                result = {
+                    name: "AES-CFB",
+                    length: 192
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.44":
+                result = {
+                    name: "AES-CFB",
+                    length: 256
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.5":
+                result = {
+                    name: "AES-KW",
+                    length: 128
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.25":
+                result = {
+                    name: "AES-KW",
+                    length: 192
+                };
+                break;
+            case "2.16.840.1.101.3.4.1.45":
+                result = {
+                    name: "AES-KW",
+                    length: 256
+                };
+                break;
+            case "1.2.840.113549.2.7":
+                result = {
+                    name: "HMAC",
+                    hash: {
+                        name: "SHA-1"
+                    }
+                };
+                break;
+            case "1.2.840.113549.2.9":
+                result = {
+                    name: "HMAC",
+                    hash: {
+                        name: "SHA-256"
+                    }
+                };
+                break;
+            case "1.2.840.113549.2.10":
+                result = {
+                    name: "HMAC",
+                    hash: {
+                        name: "SHA-384"
+                    }
+                };
+                break;
+            case "1.2.840.113549.2.11":
+                result = {
+                    name: "HMAC",
+                    hash: {
+                        name: "SHA-512"
+                    }
+                };
+                break;
+            case "1.2.840.113549.1.9.16.3.5":
+                result = {
+                    name: "DH"
+                };
+                break;
+            case "1.3.14.3.2.26":
+                result = {
+                    name: "SHA-1"
+                };
+                break;
+            case "2.16.840.1.101.3.4.2.1":
+                result = {
+                    name: "SHA-256"
+                };
+                break;
+            case "2.16.840.1.101.3.4.2.2":
+                result = {
+                    name: "SHA-384"
+                };
+                break;
+            case "2.16.840.1.101.3.4.2.3":
+                result = {
+                    name: "SHA-512"
+                };
+                break;
+            case "1.2.840.113549.1.5.12":
+                result = {
+                    name: "PBKDF2"
+                };
+                break;
+            // #region Special case - OIDs for ECC curves 
+            case "1.2.840.10045.3.1.7":
+                result = {
+                    name: "P-256"
+                };
+                break;
+            case "1.3.132.0.34":
+                result = {
+                    name: "P-384"
+                };
+                break;
+            case "1.3.132.0.35":
+                result = {
+                    name: "P-521"
+                };
+                break;
+            // #endregion 
+
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getHashAlgorithm =
+    function(signatureAlgorithm)
+    {
+        /// <summary>Getting hash algorithm by signature algorithm</summary>
+        /// <param name="signatureAlgorithm" type="in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER">Signature algorithm</param>
+
+        var result = "";
+
+        switch(signatureAlgorithm.algorithm_id)
+        {
+            case "1.2.840.10045.4.1": // ecdsa-with-SHA1
+            case "1.2.840.113549.1.1.5":
+                result = "SHA-1";
+                break;
+            case "1.2.840.10045.4.3.2": // ecdsa-with-SHA256
+            case "1.2.840.113549.1.1.11":
+                result = "SHA-256";
+                break;
+            case "1.2.840.10045.4.3.3": // ecdsa-with-SHA384
+            case "1.2.840.113549.1.1.12":
+                result = "SHA-384";
+                break;
+            case "1.2.840.10045.4.3.4": // ecdsa-with-SHA512
+            case "1.2.840.113549.1.1.13":
+                result = "SHA-512";
+                break;
+            case "1.2.840.113549.1.1.10": // RSA-PSS
+                {
+                    var params;
+
+                    try
+                    {
+                        params = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params({ schema: signatureAlgorithm.algorithm_params });
+                        if("hashAlgorithm" in params)
+                        {
+                            var algorithm = in_window.org.pkijs.getAlgorithmByOID(params.hashAlgorithm.algorithm_id);
+                            if(("name" in algorithm) === false)
+                                return "";
+
+                            result = algorithm.name;
+                        }
+                        else
+                            result = "SHA-1";
+                    }
+                    catch(ex)
+                    {
+                    }
+                }
+                break;
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.createCMSECDSASignature =
+    function(signatureBuffer)
+    {
+        /// <summary>Create CMS ECDSA signature from WebCrypto ECDSA signature</summary>
+        /// <param name="signatureBuffer" type="ArrayBuffer">WebCrypto result of "sign" function</param>
+
+        // #region Initial check for correct length 
+        if((signatureBuffer.byteLength % 2) != 0)
+            return new ArrayBuffer(0);
+        // #endregion 
+
+        // #region Initial variables 
+        var i = 0;
+        var length = signatureBuffer.byteLength / 2; // There are two equal parts inside incoming ArrayBuffer
+
+        var signatureView = new Uint8Array(signatureBuffer);
+
+        var r_buffer = new ArrayBuffer(length);
+        var r_view = new Uint8Array(r_buffer);
+        var r_corrected_buffer;
+        var r_corrected_view;
+
+        var s_buffer = new ArrayBuffer(length);
+        var s_view = new Uint8Array(s_buffer);
+        var s_corrected_buffer;
+        var s_corrected_view;
+        // #endregion   
+
+        // #region Get "r" part of ECDSA signature 
+        for(; i < length; i++)
+            r_view[i] = signatureView[i];
+
+        if(r_view[0] & 0x80)
+        {
+            r_corrected_buffer = new ArrayBuffer(length + 1);
+            r_corrected_view = new Uint8Array(r_corrected_buffer);
+
+            r_corrected_view[0] = 0x00;
+
+            for(var j = 0; j < length; j++)
+                r_corrected_view[j + 1] = r_view[j];
+        }
+        else
+        {
+            r_corrected_buffer = r_buffer;
+            r_corrected_view = r_view;
+        }
+        // #endregion 
+
+        // #region Get "s" part of ECDSA signature 
+        for(; i < signatureBuffer.byteLength; i++)
+            s_view[i - length] = signatureView[i];
+
+
+        if(s_view[0] & 0x80)
+        {
+            s_corrected_buffer = new ArrayBuffer(length + 1);
+            s_corrected_view = new Uint8Array(s_corrected_buffer);
+
+            s_corrected_view[0] = 0x00;
+
+            for(var j = 0; j < length; j++)
+                s_corrected_view[j + 1] = s_view[j];
+        }
+        else
+        {
+            s_corrected_buffer = s_buffer;
+            s_corrected_view = s_view;
+        }
+        // #endregion 
+
+        // #region Create ASN.1 structure of CMS ECDSA signature 
+        var r_integer = new in_window.org.pkijs.asn1.INTEGER();
+        r_integer.value_block.is_hex_only = true;
+        r_integer.value_block.value_hex = in_window.org.pkijs.copyBuffer(r_corrected_buffer);
+
+        var s_integer = new in_window.org.pkijs.asn1.INTEGER();
+        s_integer.value_block.is_hex_only = true;
+        s_integer.value_block.value_hex = in_window.org.pkijs.copyBuffer(s_corrected_buffer);
+
+        var asn1 = new in_window.org.pkijs.asn1.SEQUENCE({
+            value: [
+                r_integer,
+                s_integer
+            ]
+        });
+        // #endregion   
+
+        return asn1.toBER(false);
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.createECDSASignatureFromCMS =
+    function(cmsSignature)
+    {
+        /// <summary>Create a single ArrayBuffer from CMS ECDSA signature</summary>
+        /// <param name="cmsSignature" type="in_window.org.pkijs.asn1.SEQUENCE">ASN.1 SEQUENCE contains CMS ECDSA signature</param>
+
+        // #region Initial variables 
+        var length = 0;
+
+        var r_start = 0;
+        var s_start = 0;
+
+        var r_length = cmsSignature.value_block.value[0].value_block.value_hex.byteLength;
+        var s_length = cmsSignature.value_block.value[1].value_block.value_hex.byteLength;
+        // #endregion 
+
+        // #region Get length of final "ArrayBuffer" 
+        var r_view = new Uint8Array(cmsSignature.value_block.value[0].value_block.value_hex);
+        if((r_view[0] === 0x00) && (r_view[1] & 0x80))
+        {
+            length = r_length - 1;
+            r_start = 1;
+        }
+        else
+            length = r_length;
+
+        var s_view = new Uint8Array(cmsSignature.value_block.value[1].value_block.value_hex);
+        if((s_view[0] === 0x00) && (s_view[1] & 0x80))
+        {
+            length += s_length - 1;
+            s_start = 1;
+        }
+        else
+            length += s_length;
+        // #endregion 
+
+        // #region Copy values from CMS ECDSA signature 
+        var result = new ArrayBuffer(length);
+        var result_view = new Uint8Array(result);
+
+        for(var i = r_start; i < r_length; i++)
+            result_view[i - r_start] = r_view[i];
+
+        for(var i = s_start; i < s_length; i++)
+            result_view[i - s_start + r_length - r_start] = s_view[i];
+        // #endregion 
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getEncryptionAlgorithm =
+    function(algorithm)
+    {
+        /// <summary>Get encryption algorithm OID by WebCrypto algorithm's object</summary>
+        /// <param name="algorithm" type="WebCryptoAlgorithm">WebCrypto algorithm object</param>
+
+        var result = "";
+
+        switch(algorithm.name.toUpperCase())
+        {
+            case "AES-CBC":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.2";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.22";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.42";
+                        break;
+                    default:
+                }
+                break;
+            case "AES-GCM":
+                switch(algorithm.length)
+                {
+                    case 128:
+                        result = "2.16.840.1.101.3.4.1.6";
+                        break;
+                    case 192:
+                        result = "2.16.840.1.101.3.4.1.26";
+                        break;
+                    case 256:
+                        result = "2.16.840.1.101.3.4.1.46";
+                        break;
+                    default:
+                }
+                break;
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.getAlgorithmByEncryptionOID =
+    function(oid)
+    {
+        /// <summary>Get encryption algorithm name by OID</summary>
+        /// <param name="oid" type="String">OID of encryption algorithm</param>
+
+        var result = "";
+
+        switch(oid)
+        {
+            case "2.16.840.1.101.3.4.1.2":
+            case "2.16.840.1.101.3.4.1.22":
+            case "2.16.840.1.101.3.4.1.42":
+                result = "AES-CBC";
+                break;
+            case "2.16.840.1.101.3.4.1.6":
+            case "2.16.840.1.101.3.4.1.26":
+            case "2.16.840.1.101.3.4.1.46":
+                result = "AES-GCM";
+                break;
+            default:
+        }
+
+        return result;
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+}
+)(typeof exports !== "undefined" ? exports : window);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/u2f/tests/pkijs/x509_schema.js
@@ -0,0 +1,1889 @@
+/*
+ * Copyright (c) 2014, GMO GlobalSign
+ * Copyright (c) 2015, Peculiar Ventures
+ * All rights reserved.
+ *
+ * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE. 
+ *
+ */
+(
+function(in_window)
+{
+    //**************************************************************************************
+    // #region Declaration of global variables 
+    //**************************************************************************************
+    // #region "org" namespace 
+    if(typeof in_window.org === "undefined")
+        in_window.org = {};
+    else
+    {
+        if(typeof in_window.org !== "object")
+            throw new Error("Name org already exists and it's not an object");
+    }
+    // #endregion 
+
+    // #region "org.pkijs" namespace 
+    if(typeof in_window.org.pkijs === "undefined")
+        in_window.org.pkijs = {};
+    else
+    {
+        if(typeof in_window.org.pkijs !== "object")
+            throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
+    }
+    // #endregion 
+
+    // #region "org.pkijs.schema" namespace 
+    if(typeof in_window.org.pkijs.schema === "undefined")
+        in_window.org.pkijs.schema = {};
+    else
+    {
+        if(typeof in_window.org.pkijs.schema !== "object")
+            throw new Error("Name org.pkijs.schema already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.schema));
+    }
+    // #endregion 
+
+    // #region "org.pkijs.schema.x509" namespace 
+    if(typeof in_window.org.pkijs.schema.x509 === "undefined")
+        in_window.org.pkijs.schema.x509 = {};
+    else
+    {
+        if(typeof in_window.org.pkijs.schema.x509 !== "object")
+            throw new Error("Name org.pkijs.schema.x509 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.schema.x509));
+    }
+    // #endregion 
+
+    // #region "local" namespace 
+    var local = {};
+    // #endregion   
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "Time" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.TIME =
+    function(input_names, input_optional)
+    {
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+        var optional = (input_optional || false);
+
+        return (new in_window.org.pkijs.asn1.CHOICE({
+            optional: optional,
+            value: [
+                new in_window.org.pkijs.asn1.UTCTIME({ name: (names.utcTimeName || "") }),
+                new in_window.org.pkijs.asn1.GENERALIZEDTIME({ name: (names.generalTimeName || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for X.509 v3 certificate (RFC5280)
+    //**************************************************************************************
+    local.tbsCertificate =
+    function()
+    {
+        //TBSCertificate  ::=  SEQUENCE  {
+        //    version         [0]  EXPLICIT Version DEFAULT v1,
+        //    serialNumber         CertificateSerialNumber,
+        //    signature            AlgorithmIdentifier,
+        //    issuer               Name,
+        //    validity             Validity,
+        //    subject              Name,
+        //    subjectPublicKeyInfo SubjectPublicKeyInfo,
+        //    issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+        //                         -- If present, version MUST be v2 or v3
+        //    subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+        //                         -- If present, version MUST be v2 or v3
+        //    extensions      [3]  EXPLICIT Extensions OPTIONAL
+        //    -- If present, version MUST be v3
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || "tbsCertificate"),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                value: [
+                    new in_window.org.pkijs.asn1.INTEGER({ name: (names.tbsCertificate_version || "tbsCertificate.version") }) // EXPLICIT integer value
+                ]
+            }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.tbsCertificate_serialNumber || "tbsCertificate.serialNumber") }),
+                in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.signature || {
+                    names: {
+                        block_name: "tbsCertificate.signature"
+                    }
+                }),
+                in_window.org.pkijs.schema.RDN(names.issuer || {
+                    names: {
+                        block_name: "tbsCertificate.issuer"
+                    }
+                }),
+                new in_window.org.pkijs.asn1.SEQUENCE({
+                    name: (names.tbsCertificate_validity || "tbsCertificate.validity"),
+                    value: [
+                        in_window.org.pkijs.schema.TIME(names.not_before || {
+                            names: {
+                                utcTimeName: "tbsCertificate.notBefore",
+                                generalTimeName: "tbsCertificate.notBefore"
+                            }
+                        }),
+                        in_window.org.pkijs.schema.TIME(names.not_after || {
+                            names: {
+                                utcTimeName: "tbsCertificate.notAfter",
+                                generalTimeName: "tbsCertificate.notAfter"
+                            }
+                        })
+                    ]
+                }),
+                in_window.org.pkijs.schema.RDN(names.subject || {
+                    names: {
+                        block_name: "tbsCertificate.subject"
+                    }
+                }),
+                in_window.org.pkijs.schema.PUBLIC_KEY_INFO(names.subjectPublicKeyInfo || {
+                    names: {
+                        block_name: "tbsCertificate.subjectPublicKeyInfo"
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.tbsCertificate_issuerUniqueID ||"tbsCertificate.issuerUniqueID"),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                }), // IMPLICIT bistring value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.tbsCertificate_subjectUniqueID ||"tbsCertificate.subjectUniqueID"),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    }
+                }), // IMPLICIT bistring value
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 3 // [3]
+                    },
+                    value: [in_window.org.pkijs.schema.EXTENSIONS(names.extensions || {
+                        names: {
+                            block_name: "tbsCertificate.extensions"
+                        }
+                    })]
+                }) // EXPLICIT SEQUENCE value
+            ]
+        }));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.schema.CERT =
+    function()
+    {
+        //Certificate  ::=  SEQUENCE  {
+        //    tbsCertificate       TBSCertificate,
+        //    signatureAlgorithm   AlgorithmIdentifier,
+        //    signatureValue       BIT STRING  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                local.tbsCertificate(names.tbsCertificate),
+                in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.signatureAlgorithm || {
+                    names: {
+                        block_name: "signatureAlgorithm"
+                    }
+                }),
+                new in_window.org.pkijs.asn1.BITSTRING({ name: (names.signatureValue || "signatureValue") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for X.509 CRL (Certificate Revocation List)(RFC5280)  
+    //**************************************************************************************
+    local.tbsCertList =
+    function()
+    {
+        //TBSCertList  ::=  SEQUENCE  {
+        //    version                 Version OPTIONAL,
+        //                                 -- if present, MUST be v2
+        //    signature               AlgorithmIdentifier,
+        //    issuer                  Name,
+        //    thisUpdate              Time,
+        //    nextUpdate              Time OPTIONAL,
+        //    revokedCertificates     SEQUENCE OF SEQUENCE  {
+        //        userCertificate         CertificateSerialNumber,
+        //        revocationDate          Time,
+        //        crlEntryExtensions      Extensions OPTIONAL
+        //        -- if present, version MUST be v2
+        //    }  OPTIONAL,
+        //    crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+        //    -- if present, version MUST be v2
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || "tbsCertList"),
+            value: [
+                        new in_window.org.pkijs.asn1.INTEGER({
+                            optional: true,
+                            name: (names.tbsCertList_version || "tbsCertList.version"),
+                            value: 2
+                        }), // EXPLICIT integer value (v2)
+                        in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.signature || {
+                            names: {
+                                block_name: "tbsCertList.signature"
+                            }
+                        }),
+                        in_window.org.pkijs.schema.RDN(names.issuer || {
+                            names: {
+                                block_name: "tbsCertList.issuer"
+                            }
+                        }),
+                        in_window.org.pkijs.schema.TIME(names.tbsCertList_thisUpdate || {
+                            names: {
+                                utcTimeName: "tbsCertList.thisUpdate",
+                                generalTimeName: "tbsCertList.thisUpdate"
+                            }
+                        }),
+                        in_window.org.pkijs.schema.TIME(names.tbsCertList_thisUpdate || {
+                            names: {
+                                utcTimeName: "tbsCertList.nextUpdate",
+                                generalTimeName: "tbsCertList.nextUpdate"
+                            }
+                        }, true),
+                        new in_window.org.pkijs.asn1.SEQUENCE({
+                            optional: true,
+                            value: [
+                                new in_window.org.pkijs.asn1.REPEATED({
+                                    name: (names.tbsCertList_revokedCertificates || "tbsCertList.revokedCertificates"),
+                                    value: new in_window.org.pkijs.asn1.SEQUENCE({
+                                        value: [
+                                            new in_window.org.pkijs.asn1.INTEGER(),
+                                            in_window.org.pkijs.schema.TIME(),
+                                            in_window.org.pkijs.schema.EXTENSIONS({}, true)
+                                        ]
+                                    })
+                                })
+                            ]
+                        }),
+                        new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                            optional: true,
+                            id_block: {
+                                tag_class: 3, // CONTEXT-SPECIFIC
+                                tag_number: 0 // [0]
+                            },
+                            value: [in_window.org.pkijs.schema.EXTENSIONS(names.crlExtensions || {
+                                names: {
+                                    block_name: "tbsCertList.extensions"
+                                }
+                            })]
+                        }) // EXPLICIT SEQUENCE value
+                    ]
+        }));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.schema.CRL =
+    function()
+    {
+        //CertificateList  ::=  SEQUENCE  {
+        //    tbsCertList          TBSCertList,
+        //    signatureAlgorithm   AlgorithmIdentifier,
+        //    signatureValue       BIT STRING  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || "CertificateList"),
+            value: [
+                local.tbsCertList(arguments[0]),
+                in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.signatureAlgorithm || {
+                    names: {
+                        block_name: "signatureAlgorithm"
+                    }
+                }),
+                new in_window.org.pkijs.asn1.BITSTRING({ name: (names.signatureValue || "signatureValue") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for PKCS#10 certificate request 
+    //**************************************************************************************
+    local.CertificationRequestInfo =
+    function()
+    {
+        //CertificationRequestInfo ::= SEQUENCE {
+        //    version       INTEGER { v1(0) } (v1,...),
+        //    subject       Name,
+        //    subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+        //    attributes    [0] Attributes{{ CRIAttributes }}
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.CertificationRequestInfo || "CertificationRequestInfo"),
+            value: [
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.CertificationRequestInfo_version || "CertificationRequestInfo.version") }),
+                new in_window.org.pkijs.schema.RDN(names.subject || {
+                    names: {
+                        block_name: "CertificationRequestInfo.subject"
+                    }
+                }),
+                new in_window.org.pkijs.schema.PUBLIC_KEY_INFO({
+                    names: {
+                        block_name: "CertificationRequestInfo.subjectPublicKeyInfo"
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            optional: true, // Because OpenSSL makes wrong "attributes" field
+                            name: (names.CertificationRequestInfo_attributes || "CertificationRequestInfo.attributes"),
+                            value: in_window.org.pkijs.schema.ATTRIBUTE(names.attributes || {})
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.schema.PKCS10 =
+    function()
+    {
+        //CertificationRequest ::= SEQUENCE {
+        //    certificationRequestInfo CertificationRequestInfo,
+        //    signatureAlgorithm       AlgorithmIdentifier{{ SignatureAlgorithms }},
+        //    signature                BIT STRING
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            value: [
+                local.CertificationRequestInfo(names.certificationRequestInfo || {}),
+                new in_window.org.pkijs.asn1.SEQUENCE({
+                    name: (names.signatureAlgorithm || "signatureAlgorithm"),
+                    value: [
+                        new in_window.org.pkijs.asn1.OID(),
+                        new in_window.org.pkijs.asn1.ANY({ optional: true })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.BITSTRING({ name: (names.signatureValue || "signatureValue") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for PKCS#8 private key bag
+    //**************************************************************************************
+    in_window.org.pkijs.schema.PKCS8 =
+    function()
+    {
+        //PrivateKeyInfo ::= SEQUENCE {
+        //    version Version,
+        //    privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
+        //    privateKey PrivateKey,
+        //    attributes [0] Attributes OPTIONAL }
+        //
+        //Version ::= INTEGER {v1(0)} (v1,...)
+        //
+        //PrivateKey ::= OCTET STRING
+        //
+        //Attributes ::= SET OF Attribute
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            value: [
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.version || "") }),
+                in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.privateKeyAlgorithm || ""),
+                new in_window.org.pkijs.asn1.OCTETSTRING({ name: (names.privateKey || "") }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.attributes || ""),
+                            value: in_window.org.pkijs.schema.ATTRIBUTE()
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "GeneralName" type 
+    //**************************************************************************************
+    local.BuiltInStandardAttributes =
+    function(optional_flag)
+    {
+        //BuiltInStandardAttributes ::= SEQUENCE {
+        //    country-name                  CountryName OPTIONAL,
+        //    administration-domain-name    AdministrationDomainName OPTIONAL,
+        //    network-address           [0] IMPLICIT NetworkAddress OPTIONAL,
+        //    terminal-identifier       [1] IMPLICIT TerminalIdentifier OPTIONAL,
+        //    private-domain-name       [2] PrivateDomainName OPTIONAL,
+        //    organization-name         [3] IMPLICIT OrganizationName OPTIONAL,
+        //    numeric-user-identifier   [4] IMPLICIT NumericUserIdentifier OPTIONAL,
+        //    personal-name             [5] IMPLICIT PersonalName OPTIONAL,
+        //    organizational-unit-names [6] IMPLICIT OrganizationalUnitNames OPTIONAL }
+
+        if(typeof optional_flag === "undefined")
+            optional_flag = false;
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            optional: optional_flag,
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 2, // APPLICATION-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    name: (names.country_name || ""),
+                    value: [
+                        new in_window.org.pkijs.asn1.CHOICE({
+                            value: [
+                                new in_window.org.pkijs.asn1.NUMERICSTRING(),
+                                new in_window.org.pkijs.asn1.PRINTABLESTRING()
+                            ]
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 2, // APPLICATION-SPECIFIC
+                        tag_number: 2 // [2]
+                    },
+                    name: (names.administration_domain_name || ""),
+                    value: [
+                        new in_window.org.pkijs.asn1.CHOICE({
+                            value: [
+                                new in_window.org.pkijs.asn1.NUMERICSTRING(),
+                                new in_window.org.pkijs.asn1.PRINTABLESTRING()
+                            ]
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    name: (names.network_address || ""),
+                    is_hex_only: true
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    name: (names.terminal_identifier || ""),
+                    is_hex_only: true
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    },
+                    name: (names.private_domain_name || ""),
+                    value: [
+                        new in_window.org.pkijs.asn1.CHOICE({
+                            value: [
+                                new in_window.org.pkijs.asn1.NUMERICSTRING(),
+                                new in_window.org.pkijs.asn1.PRINTABLESTRING()
+                            ]
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 3 // [3]
+                    },
+                    name: (names.organization_name || ""),
+                    is_hex_only: true
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    optional: true,
+                    name: (names.numeric_user_identifier || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 4 // [4]
+                    },
+                    is_hex_only: true
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    name: (names.personal_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 5 // [5]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                            id_block: {
+                                tag_class: 3, // CONTEXT-SPECIFIC
+                                tag_number: 0 // [0]
+                            },
+                            is_hex_only: true
+                        }),
+                        new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                            optional: true,
+                            id_block: {
+                                tag_class: 3, // CONTEXT-SPECIFIC
+                                tag_number: 1 // [1]
+                            },
+                            is_hex_only: true
+                        }),
+                        new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                            optional: true,
+                            id_block: {
+                                tag_class: 3, // CONTEXT-SPECIFIC
+                                tag_number: 2 // [2]
+                            },
+                            is_hex_only: true
+                        }),
+                        new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                            optional: true,
+                            id_block: {
+                                tag_class: 3, // CONTEXT-SPECIFIC
+                                tag_number: 3 // [3]
+                            },
+                            is_hex_only: true
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    name: (names.organizational_unit_names || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 6 // [6]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            value: new in_window.org.pkijs.asn1.PRINTABLESTRING()
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    local.BuiltInDomainDefinedAttributes =
+    function(optional_flag)
+    {
+        if(typeof optional_flag === "undefined")
+            optional_flag = false;
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            optional: optional_flag,
+            value: [
+                new in_window.org.pkijs.asn1.PRINTABLESTRING(),
+                new in_window.org.pkijs.asn1.PRINTABLESTRING()
+            ]
+        }));
+    };
+    //**************************************************************************************
+    local.ExtensionAttributes =
+    function(optional_flag)
+    {
+        if(typeof optional_flag === "undefined")
+            optional_flag = false;
+
+        return (new in_window.org.pkijs.asn1.SET({
+            optional: optional_flag,
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    is_hex_only: true
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    value: [new in_window.org.pkijs.asn1.ANY()]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.schema.GENERAL_NAME =
+    function()
+    {
+        /// <remarks>By passing "names" array as an argument you can name each element of "GENERAL NAME" choice</remarks>
+
+        //GeneralName ::= CHOICE {
+        //    otherName                       [0]     OtherName,
+        //    rfc822Name                      [1]     IA5String,
+        //    dNSName                         [2]     IA5String,
+        //    x400Address                     [3]     ORAddress,
+        //    directoryName                   [4]     Name,
+        //    ediPartyName                    [5]     EDIPartyName,
+        //    uniformResourceIdentifier       [6]     IA5String,
+        //    iPAddress                       [7]     OCTET STRING,
+        //    registeredID                    [8]     OBJECT IDENTIFIER }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.CHOICE({
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    name: (names.block_name || ""),
+                    value: [
+                            new in_window.org.pkijs.asn1.OID(),
+                            new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                id_block: {
+                                    tag_class: 3, // CONTEXT-SPECIFIC
+                                    tag_number: 0 // [0]
+                                },
+                                value: [new in_window.org.pkijs.asn1.ANY()]
+                            })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.block_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.block_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 3 // [3]
+                    },
+                    name: (names.block_name || ""),
+                    value: [
+                            local.BuiltInStandardAttributes(false),
+                            local.BuiltInDomainDefinedAttributes(true),
+                            local.ExtensionAttributes(true)
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 4 // [4]
+                    },
+                    name: (names.block_name || ""),
+                    value: [in_window.org.pkijs.schema.RDN(names.directoryName || {})]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 5 // [5]
+                    },
+                    name: (names.block_name || ""),
+                    value: [
+                            new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                optional: true,
+                                id_block: {
+                                    tag_class: 3, // CONTEXT-SPECIFIC
+                                    tag_number: 0 // [0]
+                                },
+                                value: [
+                                    new in_window.org.pkijs.asn1.CHOICE({
+                                        value: [
+                                            new in_window.org.pkijs.asn1.TELETEXSTRING(),
+                                            new in_window.org.pkijs.asn1.PRINTABLESTRING(),
+                                            new in_window.org.pkijs.asn1.UNIVERSALSTRING(),
+                                            new in_window.org.pkijs.asn1.UTF8STRING(),
+                                            new in_window.org.pkijs.asn1.BMPSTRING()
+                                        ]
+                                    })
+                                ]
+                            }),
+                            new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                id_block: {
+                                    tag_class: 3, // CONTEXT-SPECIFIC
+                                    tag_number: 1 // [1]
+                                },
+                                value: [
+                                    new in_window.org.pkijs.asn1.CHOICE({
+                                        value: [
+                                            new in_window.org.pkijs.asn1.TELETEXSTRING(),
+                                            new in_window.org.pkijs.asn1.PRINTABLESTRING(),
+                                            new in_window.org.pkijs.asn1.UNIVERSALSTRING(),
+                                            new in_window.org.pkijs.asn1.UTF8STRING(),
+                                            new in_window.org.pkijs.asn1.BMPSTRING()
+                                        ]
+                                    })
+                                ]
+                            })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.block_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 6 // [6]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.block_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 7 // [7]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.block_name || ""),
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 8 // [8]
+                    }
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "AlgorithmIdentifier" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER =
+    function()
+    {
+        //AlgorithmIdentifier  ::=  SEQUENCE  {
+        //    algorithm               OBJECT IDENTIFIER,
+        //    parameters              ANY DEFINED BY algorithm OPTIONAL  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            optional: (names.optional || false),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.algorithmIdentifier || "") }),
+                new in_window.org.pkijs.asn1.ANY({ name: (names.algorithmParams || ""), optional: true })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "RSAPublicKey" type (RFC3447)
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.RSAPublicKey =
+    function()
+    {
+        //RSAPublicKey ::= SEQUENCE {
+        //    modulus           INTEGER,  -- n
+        //    publicExponent    INTEGER   -- e
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.modulus || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.publicExponent || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "OtherPrimeInfo" type (RFC3447) 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.OtherPrimeInfo =
+    function()
+    {
+        //OtherPrimeInfo ::= SEQUENCE {
+        //    prime             INTEGER,  -- ri
+        //    exponent          INTEGER,  -- di
+        //    coefficient       INTEGER   -- ti
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.prime || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.exponent || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.coefficient || "") })
+    ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "RSAPrivateKey" type (RFC3447)
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.RSAPrivateKey =
+    function()
+    {
+        //RSAPrivateKey ::= SEQUENCE {
+        //    version           Version,
+        //    modulus           INTEGER,  -- n
+        //    publicExponent    INTEGER,  -- e
+        //    privateExponent   INTEGER,  -- d
+        //    prime1            INTEGER,  -- p
+        //    prime2            INTEGER,  -- q
+        //    exponent1         INTEGER,  -- d mod (p-1)
+        //    exponent2         INTEGER,  -- d mod (q-1)
+        //    coefficient       INTEGER,  -- (inverse of q) mod p
+        //    otherPrimeInfos   OtherPrimeInfos OPTIONAL
+        //}
+        //
+        //OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.version || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.modulus || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.publicExponent || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.privateExponent || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.prime1 || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.prime2 || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.exponent1 || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.exponent2 || "") }),
+                new in_window.org.pkijs.asn1.INTEGER({ name: (names.coefficient || "") }),
+                new in_window.org.pkijs.asn1.SEQUENCE({
+                    optional: true,
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.otherPrimeInfos || ""),
+                            value: in_window.org.pkijs.schema.x509.OtherPrimeInfo(names.otherPrimeInfo || {})
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "RSASSA-PSS-params" type (RFC3447)
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.RSASSA_PSS_params =
+    function()
+    {
+        //RSASSA-PSS-params  ::=  SEQUENCE  {
+        //    hashAlgorithm      [0] HashAlgorithm DEFAULT sha1Identifier,
+        //    maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
+        //    saltLength         [2] INTEGER DEFAULT 20,
+        //    trailerField       [3] INTEGER DEFAULT 1  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    optional: true,
+                    value: [in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.hashAlgorithm || {})]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    optional: true,
+                    value: [in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.maskGenAlgorithm || {})]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    },
+                    optional: true,
+                    value: [new in_window.org.pkijs.asn1.INTEGER({ name: (names.saltLength || "") })]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 3 // [3]
+                    },
+                    optional: true,
+                    value: [new in_window.org.pkijs.asn1.INTEGER({ name: (names.trailerField || "") })]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "SubjectPublicKeyInfo" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.PUBLIC_KEY_INFO =
+    function()
+    {
+        //SubjectPublicKeyInfo  ::=  SEQUENCE  {
+        //    algorithm            AlgorithmIdentifier,
+        //    subjectPublicKey     BIT STRING  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER(names.algorithm || {}),
+                new in_window.org.pkijs.asn1.BITSTRING({ name: (names.subjectPublicKey || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "Attribute" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.ATTRIBUTE =
+    function()
+    {
+        // Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
+        //    type   ATTRIBUTE.&id({IOSet}),
+        //    values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.type || "") }),
+                new in_window.org.pkijs.asn1.SET({
+                    name: (names.set_name || ""),
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.values || ""),
+                            value: new in_window.org.pkijs.asn1.ANY()
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "AttributeTypeAndValue" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.ATTR_TYPE_AND_VALUE =
+    function()
+    {
+        //AttributeTypeAndValue ::= SEQUENCE {
+        //    type     AttributeType,
+        //    value    AttributeValue }
+        //
+        //AttributeType ::= OBJECT IDENTIFIER
+        //
+        //AttributeValue ::= ANY -- DEFINED BY AttributeType
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.type || "") }),
+                new in_window.org.pkijs.asn1.ANY({ name: (names.value || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "RelativeDistinguishedName" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.RDN =
+    function()
+    {
+        //RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+        //
+        //RelativeDistinguishedName ::=
+        //SET SIZE (1..MAX) OF AttributeTypeAndValue
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.repeated_sequence || ""),
+                    value: new in_window.org.pkijs.asn1.SET({
+                        value: [
+                            new in_window.org.pkijs.asn1.REPEATED({
+                                name: (names.repeated_set || ""),
+                                value: in_window.org.pkijs.schema.ATTR_TYPE_AND_VALUE(names.attr_type_and_value || {})
+                            })
+                        ]
+                    })
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "Extension" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.EXTENSION =
+    function()
+    {
+        //Extension  ::=  SEQUENCE  {
+        //    extnID      OBJECT IDENTIFIER,
+        //    critical    BOOLEAN DEFAULT FALSE,
+        //    extnValue   OCTET STRING
+        //}
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.extnID || "") }),
+                new in_window.org.pkijs.asn1.BOOLEAN({
+                    name: (names.critical || ""),
+                    optional: true
+                }),
+                new in_window.org.pkijs.asn1.OCTETSTRING({ name: (names.extnValue || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "Extensions" type (sequence of many Extension)
+    //**************************************************************************************
+    in_window.org.pkijs.schema.EXTENSIONS =
+    function(input_names, input_optional)
+    {
+        //Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+        var optional = input_optional || false;
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            optional: optional,
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.extensions || ""),
+                    value: in_window.org.pkijs.schema.EXTENSION(names.extension || {})
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "AuthorityKeyIdentifier" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.AuthorityKeyIdentifier =
+    function()
+    {
+        // AuthorityKeyIdentifier OID ::= 2.5.29.35
+        // 
+        //AuthorityKeyIdentifier ::= SEQUENCE {
+        //    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+        //    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+        //    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
+        //
+        //KeyIdentifier ::= OCTET STRING
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.keyIdentifier || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    value: [
+                            new in_window.org.pkijs.asn1.REPEATED({
+                                name: (names.authorityCertIssuer || ""),
+                                value: in_window.org.pkijs.schema.GENERAL_NAME()
+                            })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.authorityCertSerialNumber || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    }
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PrivateKeyUsagePeriod" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PrivateKeyUsagePeriod =
+    function()
+    {
+        // PrivateKeyUsagePeriod OID ::= 2.5.29.16
+        //
+        //PrivateKeyUsagePeriod ::= SEQUENCE {
+        //    notBefore       [0]     GeneralizedTime OPTIONAL,
+        //    notAfter        [1]     GeneralizedTime OPTIONAL }
+        //-- either notBefore or notAfter MUST be present
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.notBefore || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    }
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.notAfter || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "IssuerAltName" and "SubjectAltName" types of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.AltName =
+    function()
+    {
+        // SubjectAltName OID ::= 2.5.29.17
+        // IssuerAltName OID ::= 2.5.29.18
+        //
+        // AltName ::= GeneralNames
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.altNames || ""),
+                    value: in_window.org.pkijs.schema.GENERAL_NAME()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "SubjectDirectoryAttributes" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.SubjectDirectoryAttributes =
+    function()
+    {
+        // SubjectDirectoryAttributes OID ::= 2.5.29.9
+        //
+        //SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.attributes || ""),
+                    value: in_window.org.pkijs.schema.ATTRIBUTE()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "GeneralSubtree" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.GeneralSubtree =
+    function()
+    {
+        //GeneralSubtree ::= SEQUENCE {
+        //    base                    GeneralName,
+        //    minimum         [0]     BaseDistance DEFAULT 0,
+        //    maximum         [1]     BaseDistance OPTIONAL }
+        //
+        //BaseDistance ::= INTEGER (0..MAX)
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                in_window.org.pkijs.schema.GENERAL_NAME(names.base || ""),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [new in_window.org.pkijs.asn1.INTEGER({ name: (names.minimum || "") })]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    value: [new in_window.org.pkijs.asn1.INTEGER({ name: (names.maximum || "") })]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "NameConstraints" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.NameConstraints =
+    function()
+    {
+        // NameConstraints OID ::= 2.5.29.30
+        //
+        //NameConstraints ::= SEQUENCE {
+        //    permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+        //    excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.permittedSubtrees || ""),
+                            value: in_window.org.pkijs.schema.x509.GeneralSubtree()
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.excludedSubtrees || ""),
+                            value: in_window.org.pkijs.schema.x509.GeneralSubtree()
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "BasicConstraints" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.BasicConstraints =
+    function()
+    {
+        // BasicConstraints OID ::= 2.5.29.19
+        //
+        //BasicConstraints ::= SEQUENCE {
+        //    cA                      BOOLEAN DEFAULT FALSE,
+        //    pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.BOOLEAN({
+                    optional: true,
+                    name: (names.cA || "")
+                }),
+                new in_window.org.pkijs.asn1.INTEGER({
+                    optional: true,
+                    name: (names.pathLenConstraint || "")
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PolicyQualifierInfo" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PolicyQualifierInfo =
+    function()
+    {
+        //PolicyQualifierInfo ::= SEQUENCE {
+        //    policyQualifierId  PolicyQualifierId,
+        //    qualifier          ANY DEFINED BY policyQualifierId }
+        //
+        //id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
+        //id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
+        //id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
+        //
+        //PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.policyQualifierId || "") }),
+                new in_window.org.pkijs.asn1.ANY({ name: (names.qualifier || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PolicyInformation" type 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PolicyInformation =
+    function()
+    {
+        //PolicyInformation ::= SEQUENCE {
+        //    policyIdentifier   CertPolicyId,
+        //    policyQualifiers   SEQUENCE SIZE (1..MAX) OF
+        //    PolicyQualifierInfo OPTIONAL }
+        //
+        //CertPolicyId ::= OBJECT IDENTIFIER
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.policyIdentifier || "") }),
+                new in_window.org.pkijs.asn1.SEQUENCE({
+                    optional: true,
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.policyQualifiers || ""),
+                            value: in_window.org.pkijs.schema.x509.PolicyQualifierInfo()
+                        })
+                    ]
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "CertificatePolicies" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.CertificatePolicies =
+    function()
+    {
+        // CertificatePolicies OID ::= 2.5.29.32
+        //
+        //certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.certificatePolicies || ""),
+                    value: in_window.org.pkijs.schema.x509.PolicyInformation()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PolicyMapping" type
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PolicyMapping =
+    function()
+    {
+        //PolicyMapping ::= SEQUENCE {
+        //    issuerDomainPolicy      CertPolicyId,
+        //    subjectDomainPolicy     CertPolicyId }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.issuerDomainPolicy || "") }),
+                new in_window.org.pkijs.asn1.OID({ name: (names.subjectDomainPolicy || "") })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PolicyMappings" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PolicyMappings =
+    function()
+    {
+        // PolicyMappings OID ::= 2.5.29.33
+        //
+        //PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF PolicyMapping
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.mappings || ""),
+                    value: in_window.org.pkijs.schema.x509.PolicyMapping()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "PolicyConstraints" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.PolicyConstraints =
+    function()
+    {
+        // PolicyMappings OID ::= 2.5.29.36
+        //
+        //PolicyConstraints ::= SEQUENCE {
+        //    requireExplicitPolicy           [0] SkipCerts OPTIONAL,
+        //    inhibitPolicyMapping            [1] SkipCerts OPTIONAL }
+        //
+        //SkipCerts ::= INTEGER (0..MAX)
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.requireExplicitPolicy || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    }
+                }), // IMPLICIT integer value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.inhibitPolicyMapping || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                }) // IMPLICIT integer value
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "ExtKeyUsage" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.ExtKeyUsage =
+    function()
+    {
+        // ExtKeyUsage OID ::= 2.5.29.37
+        //
+        // ExtKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+
+        // KeyPurposeId ::= OBJECT IDENTIFIER
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.keyPurposes || ""),
+                    value: new in_window.org.pkijs.asn1.OID()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "DistributionPoint" type
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.DistributionPoint =
+    function()
+    {
+        //DistributionPoint ::= SEQUENCE {
+        //    distributionPoint       [0]     DistributionPointName OPTIONAL,
+        //    reasons                 [1]     ReasonFlags OPTIONAL,
+        //    cRLIssuer               [2]     GeneralNames OPTIONAL }
+        //
+        //DistributionPointName ::= CHOICE {
+        //    fullName                [0]     GeneralNames,
+        //    nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
+        //
+        //ReasonFlags ::= BIT STRING {
+        //    unused                  (0),
+        //    keyCompromise           (1),
+        //    cACompromise            (2),
+        //    affiliationChanged      (3),
+        //    superseded              (4),
+        //    cessationOfOperation    (5),
+        //    certificateHold         (6),
+        //    privilegeWithdrawn      (7),
+        //    aACompromise            (8) }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.CHOICE({
+                            value: [
+                                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                    name: (names.distributionPoint || ""),
+                                    optional: true,
+                                    id_block: {
+                                        tag_class: 3, // CONTEXT-SPECIFIC
+                                        tag_number: 0 // [0]
+                                    },
+                                    value: [
+                                        new in_window.org.pkijs.asn1.REPEATED({
+                                            name: (names.distributionPoint_names || ""),
+                                            value: in_window.org.pkijs.schema.GENERAL_NAME()
+                                        })
+                                    ]
+                                }),
+                                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                    name: (names.distributionPoint || ""),
+                                    optional: true,
+                                    id_block: {
+                                        tag_class: 3, // CONTEXT-SPECIFIC
+                                        tag_number: 1 // [1]
+                                    },
+                                    value: in_window.org.pkijs.schema.RDN().value_block.value
+                                })
+                            ]
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.reasons || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                }), // IMPLICIT bitstring value
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    name: (names.cRLIssuer || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.REPEATED({
+                            name: (names.cRLIssuer_names || ""),
+                            value: in_window.org.pkijs.schema.GENERAL_NAME()
+                        })
+                    ]
+                }) // IMPLICIT bitstring value
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "CRLDistributionPoints" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.CRLDistributionPoints =
+    function()
+    {
+        // CRLDistributionPoints OID ::= 2.5.29.31
+        //
+        //CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.distributionPoints || ""),
+                    value: in_window.org.pkijs.schema.x509.DistributionPoint()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "AccessDescription" type
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.AccessDescription =
+    function()
+    {
+        //AccessDescription  ::=  SEQUENCE {
+        //    accessMethod          OBJECT IDENTIFIER,
+        //    accessLocation        GeneralName  }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.OID({ name: (names.accessMethod || "") }),
+                in_window.org.pkijs.schema.GENERAL_NAME(names.accessLocation || "")
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "AuthorityInfoAccess" and "SubjectInfoAccess" types of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.InfoAccess =
+    function()
+    {
+        // AuthorityInfoAccess OID ::= 1.3.6.1.5.5.7.1.1
+        // SubjectInfoAccess OID ::= 1.3.6.1.5.5.7.1.11
+        //
+        //AuthorityInfoAccessSyntax  ::=
+        //SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.REPEATED({
+                    name: (names.accessDescriptions || ""),
+                    value: in_window.org.pkijs.schema.x509.AccessDescription()
+                })
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region ASN.1 schema definition for "IssuingDistributionPoint" type of extension 
+    //**************************************************************************************
+    in_window.org.pkijs.schema.x509.IssuingDistributionPoint =
+    function()
+    {
+        // IssuingDistributionPoint OID ::= 2.5.29.28
+        //
+        //IssuingDistributionPoint ::= SEQUENCE {
+        //    distributionPoint          [0] DistributionPointName OPTIONAL,
+        //    onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
+        //    onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
+        //    onlySomeReasons            [3] ReasonFlags OPTIONAL,
+        //    indirectCRL                [4] BOOLEAN DEFAULT FALSE,
+        //    onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+        //
+        //ReasonFlags ::= BIT STRING {
+        //    unused                  (0),
+        //    keyCompromise           (1),
+        //    cACompromise            (2),
+        //    affiliationChanged      (3),
+        //    superseded              (4),
+        //    cessationOfOperation    (5),
+        //    certificateHold         (6),
+        //    privilegeWithdrawn      (7),
+        //    aACompromise            (8) }
+
+        var names = in_window.org.pkijs.getNames(arguments[0]);
+
+        return (new in_window.org.pkijs.asn1.SEQUENCE({
+            name: (names.block_name || ""),
+            value: [
+                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 0 // [0]
+                    },
+                    value: [
+                        new in_window.org.pkijs.asn1.CHOICE({
+                            value: [
+                                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                    name: (names.distributionPoint || ""),
+                                    id_block: {
+                                        tag_class: 3, // CONTEXT-SPECIFIC
+                                        tag_number: 0 // [0]
+                                    },
+                                    value: [
+                                        new in_window.org.pkijs.asn1.REPEATED({
+                                            name: (names.distributionPoint_names || ""),
+                                            value: in_window.org.pkijs.schema.GENERAL_NAME()
+                                        })
+                                    ]
+                                }),
+                                new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
+                                    name: (names.distributionPoint || ""),
+                                    id_block: {
+                                        tag_class: 3, // CONTEXT-SPECIFIC
+                                        tag_number: 1 // [1]
+                                    },
+                                    value: in_window.org.pkijs.schema.RDN().value_block.value
+                                })
+                            ]
+                        })
+                    ]
+                }),
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.onlyContainsUserCerts || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 1 // [1]
+                    }
+                }), // IMPLICIT boolean value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.onlyContainsCACerts || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 2 // [2]
+                    }
+                }), // IMPLICIT boolean value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.onlySomeReasons || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 3 // [3]
+                    }
+                }), // IMPLICIT bitstring value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.indirectCRL || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 4 // [4]
+                    }
+                }), // IMPLICIT boolean value
+                new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
+                    name: (names.onlyContainsAttributeCerts || ""),
+                    optional: true,
+                    id_block: {
+                        tag_class: 3, // CONTEXT-SPECIFIC
+                        tag_number: 5 // [5]
+                    }
+                }) // IMPLICIT boolean value
+            ]
+        }));
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+}
+)(typeof exports !== "undefined" ? exports : window);
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/u2f/tests/pkijs/x509_simpl.js
@@ -0,0 +1,7239 @@
+/*
+ * Copyright (c) 2014, GMO GlobalSign
+ * Copyright (c) 2015, Peculiar Ventures
+ * All rights reserved.
+ *
+ * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE. 
+ *
+ */
+(
+function(in_window)
+{
+    //**************************************************************************************
+    // #region Declaration of global variables 
+    //**************************************************************************************
+    // #region "org" namespace 
+    if(typeof in_window.org === "undefined")
+        in_window.org = {};
+    else
+    {
+        if(typeof in_window.org !== "object")
+            throw new Error("Name org already exists and it's not an object");
+    }
+    // #endregion 
+
+    // #region "org.pkijs" namespace 
+    if(typeof in_window.org.pkijs === "undefined")
+        in_window.org.pkijs = {};
+    else
+    {
+        if(typeof in_window.org.pkijs !== "object")
+            throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
+    }
+    // #endregion 
+
+    // #region "org.pkijs.simpl" namespace 
+    if(typeof in_window.org.pkijs.simpl === "undefined")
+        in_window.org.pkijs.simpl = {};
+    else
+    {
+        if(typeof in_window.org.pkijs.simpl !== "object")
+            throw new Error("Name org.pkijs.simpl already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl));
+    }
+    // #endregion 
+
+    // #region "org.pkijs.simpl.x509" namespace 
+    if(typeof in_window.org.pkijs.simpl.x509 === "undefined")
+        in_window.org.pkijs.simpl.x509 = {};
+    else
+    {
+        if(typeof in_window.org.pkijs.simpl.x509 !== "object")
+            throw new Error("Name org.pkijs.simpl.x509 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl.x509));
+    }
+    // #endregion 
+
+    // #region "local" namespace 
+    var local = {};
+    // #endregion   
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Simplified structure for "Time" type
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.TIME =
+    function()
+    {
+        // #region Internal properties of the object 
+        this.type = 0; // 0 - UTCTime; 1 - GeneralizedTime; 2 - empty value
+        this.value = new Date(0, 0, 0);
+        // #endregion 
+
+        // #region If input argument array contains "schema" for this object 
+        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
+            in_window.org.pkijs.simpl.TIME.prototype.fromSchema.call(this, arguments[0].schema);
+        // #endregion 
+        // #region If input argument array contains "native" values for internal properties 
+        else
+        {
+            if(arguments[0] instanceof Object)
+            {
+                this.type = (arguments[0].type || 0);
+                this.value = (arguments[0].value || (new Date(0, 0, 0)));
+            }
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.TIME.prototype.fromSchema =
+    function(schema)
+    {
+        // #region Check the schema is valid 
+        var asn1 = in_window.org.pkijs.compareSchema(schema,
+            schema,
+            in_window.org.pkijs.schema.TIME({
+                names: {
+                    utcTimeName: "utcTimeName",
+                    generalTimeName: "generalTimeName"
+                }
+            })
+            );
+
+        if(asn1.verified === false)
+            throw new Error("Object's schema was not verified against input data for TIME");
+        // #endregion 
+
+        // #region Get internal properties from parsed schema 
+        if("utcTimeName" in asn1.result)
+        {
+            this.type = 0;
+            this.value = asn1.result.utcTimeName.toDate();
+        }
+        if("generalTimeName" in asn1.result)
+        {
+            this.type = 1;
+            this.value = asn1.result.generalTimeName.toDate();
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.TIME.prototype.toSchema =
+    function()
+    {
+        // #region Construct and return new ASN.1 schema for this object 
+        var result = {};
+
+        if(this.type === 0)
+            result = new in_window.org.pkijs.asn1.UTCTIME({ value_date: this.value });
+        if(this.type === 1)
+            result = new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.value });
+
+        return result;
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.TIME.prototype.toJSON =
+    function()
+    {
+        return {
+            type: this.type,
+            value: this.value
+        };
+    };
+    //**************************************************************************************
+    // #endregion 
+    //**************************************************************************************
+    // #region Simplified structure for "GeneralName" type 
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.GENERAL_NAME =
+    function()
+    {
+        // #region Internal properties of the object 
+        this.NameType = 9; // Name type - from a tagged value (0 for "otherName", 1 for "rfc822Name" etc.)
+        this.Name = {};
+        // #endregion 
+
+        // #region If input argument array contains "schema" for this object 
+        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
+            in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema.call(this, arguments[0].schema);
+        // #endregion 
+        // #region If input argument array contains "native" values for internal properties 
+        else
+        {
+            if(arguments[0] instanceof Object)
+            {
+                this.NameType = arguments[0].NameType || 9;
+                this.Name = arguments[0].Name || {};
+            }
+        }
+        // #endregion 
+    };
+    //**************************************************************************************
+    in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema =
+    function(schema)
+    {
+        // #region Check the schema is valid 
+        var asn1 = in_window.org.pkijs.compareSchema(schema,
+            schema,
+            in_window.org.pkijs.schema.GENERAL_NAME({
+                names: {
+                    block_name: "block_name",
+                    otherName: "otherName",
+                    rfc822Name: "rfc822Name",
+                    dNSName: "dNSName",
+                    x400Address: "x400Address",
+                    directoryName: {
+                            names: {
+                                block_name: "directoryName"
+                            }
+                        },
+                    ediPartyName: "ediPartyName",
+                    uniformResourceIdentifier: "uniformResourceIdentifier",
+                    iPAddress: "iPAddress",
+                    registeredID: "registeredID"
+                }
+            })
+            );
+
+        if(asn1.verified === false)
+            throw new Error("Object's schema was not verified against input data for GENERAL_NAME");
+        // #endregion 
+
+        // #region Get internal properties from parsed schema
+        this.NameType = asn1.result["block_name"].id_block.tag_number;
+
+        switch(this.NameType)
+        {
+            case 0: // otherName
+                this.Name = asn1.result["block_name"];
+                break;
+            case 1: // rfc822Name + dNSName +