Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  asn1.js

  Sprache: JAVA
 

/*
 * 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(thisthis.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(nullnew 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(thisthis.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(nullnew 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(thisthis.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(nullnew 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(thisthis.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(nullnew 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(thisthis.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(nullnew 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(thisthis.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(nullnew 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 functio
        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);

Messung V0.5 in Prozent
C=81 H=93 G=86

¤ Dauer der Verarbeitung: 0.164 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge