tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

asn1.js (221246B)


      1 /*
      2 * Copyright (c) 2014, GMO GlobalSign
      3 * Copyright (c) 2015, Peculiar Ventures
      4 * All rights reserved.
      5 *
      6 * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
      7 *
      8 * Redistribution and use in source and binary forms, with or without modification, 
      9 * are permitted provided that the following conditions are met:
     10 *
     11 * 1. Redistributions of source code must retain the above copyright notice, 
     12 *    this list of conditions and the following disclaimer.
     13 *
     14 * 2. Redistributions in binary form must reproduce the above copyright notice, 
     15 *    this list of conditions and the following disclaimer in the documentation 
     16 *    and/or other materials provided with the distribution.
     17 *
     18 * 3. Neither the name of the copyright holder nor the names of its contributors 
     19 *    may be used to endorse or promote products derived from this software without 
     20 *    specific prior written permission.
     21 *
     22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
     23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
     24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
     25 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
     26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
     27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
     28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
     29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
     30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
     31 * OF SUCH DAMAGE. 
     32 *
     33 */
     34 (
     35 function(in_window)
     36 {
     37    //**************************************************************************************
     38    // #region Declaration of global variables 
     39    //**************************************************************************************
     40    // #region "org" namespace 
     41    if(typeof in_window.org === "undefined")
     42        in_window.org = {};
     43    else
     44    {
     45        if(typeof in_window.org !== "object")
     46            throw new Error("Name org already exists and it's not an object");
     47    }
     48    // #endregion 
     49 
     50    // #region "org.pkijs" namespace 
     51    if(typeof in_window.org.pkijs === "undefined")
     52        in_window.org.pkijs = {};
     53    else
     54    {
     55        if(typeof in_window.org.pkijs !== "object")
     56            throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
     57    }
     58    // #endregion 
     59 
     60    // #region "org.pkijs.asn1" namespace 
     61    if(typeof in_window.org.pkijs.asn1 === "undefined")
     62        in_window.org.pkijs.asn1 = {};
     63    else
     64    {
     65        if(typeof in_window.org.pkijs.asn1 !== "object")
     66            throw new Error("Name org.pkijs.asn1 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.asn1));
     67    }
     68    // #endregion 
     69 
     70    // #region "local" namespace 
     71    var local = {};
     72    // #endregion   
     73    //**************************************************************************************
     74    // #endregion 
     75    //**************************************************************************************
     76    // #region Aux-functions 
     77    //**************************************************************************************
     78    function util_frombase(input_buffer, input_base)
     79    {
     80        /// <summary>Convert number from 2^base to 2^10</summary>
     81        /// <param name="input_buffer" type="Uint8Array">Array of bytes representing the number to convert</param>
     82        /// <param name="input_base" type="Number">The base of initial number</param>
     83 
     84        var result = 0; 
     85 
     86        for(var i = (input_buffer.length - 1); i >= 0; i-- )
     87            result += input_buffer[(input_buffer.length - 1) - i] * Math.pow(2, input_base * i);
     88 
     89        return result;
     90    }
     91    //**************************************************************************************
     92    function util_tobase(value, base, reserved)
     93    {
     94        /// <summary>Convert number from 2^10 to 2^base</summary>
     95        /// <param name="value" type="Number">The number to convert</param>
     96        /// <param name="base" type="Number">The base for 2^base</param>
     97        /// <param name="reserved" type="Number">Pre-defined number of bytes in output array (-1 = limited by function itself)</param>
     98 
     99        reserved = reserved || (-1);
    100 
    101        var result = 0;
    102        var biggest = Math.pow(2, base);
    103 
    104        for(var i = 1; i < 8; i++)
    105        {
    106            if(value < biggest)
    107            {
    108                var ret_buf;
    109 
    110                if( reserved < 0 )
    111                {
    112                    ret_buf = new ArrayBuffer(i);
    113                    result = i;
    114                }
    115                else
    116                {
    117                    if(reserved < i)
    118                        return (new ArrayBuffer(0));
    119 
    120                    ret_buf = new ArrayBuffer(reserved);
    121 
    122                    result = reserved;
    123                }
    124 
    125                var ret_view = new Uint8Array(ret_buf);
    126 
    127                for(var j = ( i - 1 ); j >= 0; j-- )
    128                {
    129                    var basis = Math.pow(2, j * base);
    130 
    131                    ret_view[ result - j - 1 ] = Math.floor( value / basis );
    132                    value -= ( ret_view[ result - j - 1 ] ) * basis;
    133                }
    134 
    135                return ret_buf;
    136            }
    137 
    138            biggest *= Math.pow(2, base);
    139        }
    140    }
    141    //**************************************************************************************
    142    function util_encode_tc(value)
    143    {
    144        /// <summary>Encode integer value to "two complement" format</summary>
    145        /// <param name="value" type="Number">Value to encode</param>
    146 
    147        var mod_value = (value < 0) ? (value * (-1)) : value;
    148        var big_int = 128;
    149 
    150        for(var i = 1; i < 8; i++) 
    151        {
    152            if( mod_value <= big_int )
    153            {
    154                if( value < 0 )
    155                {
    156                    var small_int = big_int - mod_value;
    157 
    158                    var ret_buf = util_tobase( small_int, 8, i );
    159                    var ret_view = new Uint8Array(ret_buf);
    160 
    161                    ret_view[ 0 ] |= 0x80;
    162 
    163                    return ret_buf;
    164                }
    165                else
    166                {
    167                    var ret_buf = util_tobase( mod_value, 8, i );
    168                    var ret_view = new Uint8Array(ret_buf);
    169 
    170                    if( ret_view[ 0 ] & 0x80 )
    171                    {
    172                        var temp_buf = util_copybuf(ret_buf);
    173                        var temp_view = new Uint8Array(temp_buf);
    174 
    175                        ret_buf = new ArrayBuffer( ret_buf.byteLength + 1 );
    176                        ret_view = new Uint8Array(ret_buf);
    177 
    178                        for(var k = 0; k < temp_buf.byteLength; k++)
    179                            ret_view[k + 1] = temp_view[k];
    180 
    181                        ret_view[0] = 0x00;
    182                    }
    183 
    184                    return ret_buf;
    185                }
    186            }
    187 
    188            big_int *= Math.pow(2, 8);
    189        }
    190 
    191        return (new ArrayBuffer(0));
    192    }
    193    //**************************************************************************************
    194    function util_decode_tc()
    195    {
    196        /// <summary>Decoding of "two complement" values</summary>
    197        /// <remarks>The function must be called in scope of instance of "hex_block" class ("value_hex" and "warnings" properties must be present)</remarks>
    198 
    199        var buf = new Uint8Array(this.value_hex);
    200 
    201        if(this.value_hex.byteLength >= 2)
    202        {
    203            var condition_1 = (buf[0] == 0xFF) && (buf[1] & 0x80);
    204            var condition_2 = (buf[0] == 0x00) && ((buf[1] & 0x80) == 0x00);
    205 
    206            if(condition_1 || condition_2)
    207                this.warnings.push("Needlessly long format");
    208        }
    209 
    210        // #region Create big part of the integer
    211        var big_int_buffer = new ArrayBuffer(this.value_hex.byteLength);
    212        var big_int_view = new Uint8Array(big_int_buffer);
    213        for(var i = 0; i < this.value_hex.byteLength; i++)
    214            big_int_view[i] = 0;
    215 
    216        big_int_view[0] = (buf[0] & 0x80); // mask only the biggest bit
    217 
    218        var big_int = util_frombase(big_int_view, 8);
    219        // #endregion   
    220 
    221        // #region Create small part of the integer 
    222        var small_int_buffer = new ArrayBuffer(this.value_hex.byteLength);
    223        var small_int_view = new Uint8Array(small_int_buffer);
    224        for(var j = 0; j < this.value_hex.byteLength; j++)
    225            small_int_view[j] = buf[j];
    226 
    227        small_int_view[0] &= 0x7F; // mask biggest bit
    228 
    229        var small_int = util_frombase(small_int_view, 8);
    230        // #endregion 
    231 
    232        return (small_int - big_int);
    233    }
    234    //**************************************************************************************
    235    function util_copybuf(input_buffer)
    236    {
    237        /// <summary>Creating a copy of input ArrayBuffer</summary>
    238        /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
    239 
    240        if(check_buffer_params(input_buffer, 0, input_buffer.byteLength) === false)
    241            return (new ArrayBuffer(0));
    242 
    243        var input_view = new Uint8Array(input_buffer);
    244 
    245        var ret_buf = new ArrayBuffer(input_buffer.byteLength);
    246        var ret_view = new Uint8Array(ret_buf);
    247 
    248        for(var i = 0; i < input_buffer.byteLength; i++)
    249            ret_view[i] = input_view[i];
    250 
    251        return ret_buf;
    252    }
    253    //**************************************************************************************
    254    function util_copybuf_offset(input_buffer, input_offset, input_length)
    255    {
    256        /// <summary>Creating a copy of input ArrayBuffer</summary>
    257        /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
    258 
    259        if(check_buffer_params(input_buffer, input_offset, input_length) === false)
    260            return (new ArrayBuffer(0));
    261 
    262        var input_view = new Uint8Array(input_buffer, input_offset, input_length);
    263 
    264        var ret_buf = new ArrayBuffer(input_length);
    265        var ret_view = new Uint8Array(ret_buf);
    266 
    267        for(var i = 0; i < input_length; i++)
    268            ret_view[i] = input_view[i];
    269 
    270        return ret_buf;
    271    }
    272    //**************************************************************************************
    273    function util_concatbuf(input_buf1, input_buf2)
    274    {
    275        /// <summary>Concatenate two ArrayBuffers</summary>
    276        /// <param name="input_buf1" type="ArrayBuffer">First ArrayBuffer (first part of concatenated array)</param>
    277        /// <param name="input_buf2" type="ArrayBuffer">Second ArrayBuffer (second part of concatenated array)</param>
    278 
    279        var input_view1 = new Uint8Array(input_buf1);
    280        var input_view2 = new Uint8Array(input_buf2);
    281 
    282        var ret_buf = new ArrayBuffer(input_buf1.byteLength + input_buf2.byteLength);
    283        var ret_view = new Uint8Array(ret_buf);
    284 
    285        for(var i = 0; i < input_buf1.byteLength; i++)
    286            ret_view[i] = input_view1[i];
    287 
    288        for(var j = 0; j < input_buf2.byteLength; j++)
    289            ret_view[input_buf1.byteLength + j] = input_view2[j];
    290 
    291        return ret_buf;
    292    }
    293    //**************************************************************************************
    294    function check_buffer_params(input_buffer, input_offset, input_length)
    295    {
    296        if((input_buffer instanceof ArrayBuffer) === false)
    297        {
    298            this.error = "Wrong parameter: input_buffer must be \"ArrayBuffer\"";
    299            return false;
    300        }
    301 
    302        if(input_buffer.byteLength === 0)
    303        {
    304            this.error = "Wrong parameter: input_buffer has zero length";
    305            return false;
    306        }
    307 
    308        if(input_offset < 0)
    309        {
    310            this.error = "Wrong parameter: input_offset less than zero";
    311            return false;
    312        }
    313 
    314        if(input_length < 0)
    315        {
    316            this.error = "Wrong parameter: input_length less than zero";
    317            return false;
    318        }
    319 
    320        if((input_buffer.byteLength - input_offset - input_length) < 0)
    321        {
    322            this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
    323            return false;
    324        }
    325 
    326        return true;
    327    }
    328    //**************************************************************************************
    329    function to_hex_codes(input_buffer, input_offset, input_lenght)
    330    {
    331        if(check_buffer_params(input_buffer, input_offset, input_lenght) === false)
    332            return "";
    333 
    334        var result = "";
    335 
    336        var int_buffer = new Uint8Array(input_buffer, input_offset, input_lenght);
    337        
    338        for(var i = 0; i < int_buffer.length; i++)
    339        {
    340            var str = int_buffer[i].toString(16).toUpperCase();
    341            result = result + ((str.length === 1) ? " 0" : " ") + str;
    342        }
    343 
    344        return result;
    345    }
    346    //**************************************************************************************
    347    // #endregion 
    348    //**************************************************************************************
    349    // #region Declaration of base block class 
    350    //**************************************************************************************
    351    local.base_block =
    352    function()
    353    {
    354        /// <summary>General class of all ASN.1 blocks</summary>
    355 
    356        if(arguments[0] instanceof Object)
    357        {
    358            this.block_length = in_window.org.pkijs.getValue(arguments[0], "block_length", 0);
    359            this.error = in_window.org.pkijs.getValue(arguments[0], "error", new String());
    360            this.warnings = in_window.org.pkijs.getValue(arguments[0], "warnings", new Array());
    361            if("value_before_decode" in arguments[0])
    362                this.value_before_decode = util_copybuf(arguments[0].value_before_decode);
    363            else
    364                this.value_before_decode = new ArrayBuffer(0);
    365        }
    366        else
    367        {
    368            this.block_length = 0;
    369            this.error = new String();
    370            this.warnings = new Array();
    371            /// <field>Copy of the value of incoming ArrayBuffer done before decoding</field>
    372            this.value_before_decode = new ArrayBuffer(0);
    373        }
    374    };
    375    //**************************************************************************************
    376    local.base_block.prototype.block_name =
    377    function()
    378    {
    379        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
    380 
    381        return "base_block";
    382    };
    383    //**************************************************************************************
    384    local.base_block.prototype.toJSON =
    385    function()
    386    {
    387        /// <summary>Convertion for the block to JSON object</summary>
    388 
    389        return {
    390            block_name: local.base_block.prototype.block_name.call(this),
    391            block_length: this.block_length,
    392            error: this.error,
    393            warnings: this.warnings,
    394            value_before_decode: in_window.org.pkijs.bufferToHexCodes(this.value_before_decode, 0, this.value_before_decode.byteLength)
    395        };
    396    };
    397    //**************************************************************************************
    398    // #endregion 
    399    //**************************************************************************************
    400    // #region Declaration of hex block class 
    401    //**************************************************************************************
    402    local.hex_block =
    403    function()
    404    {
    405        /// <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>
    406 
    407        local.base_block.call(this, arguments[0]);
    408 
    409        if(arguments[0] instanceof Object)
    410        {
    411            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
    412            if("value_hex" in arguments[0])
    413                this.value_hex = util_copybuf(arguments[0].value_hex);
    414            else
    415                this.value_hex = new ArrayBuffer(0);
    416        }
    417        else
    418        {
    419            this.is_hex_only = false;
    420            this.value_hex = new ArrayBuffer(0);
    421        }
    422    };
    423    //**************************************************************************************
    424    local.hex_block.prototype = new local.base_block();
    425    local.hex_block.constructor = local.hex_block;
    426    //**************************************************************************************
    427    local.hex_block.prototype.block_name =
    428    function()
    429    {
    430        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
    431 
    432        return "hex_block";
    433    };
    434    //**************************************************************************************
    435    local.hex_block.prototype.fromBER =
    436    function(input_buffer, input_offset, input_length)
    437    {
    438        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
    439        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
    440        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
    441        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
    442 
    443        // #region Basic check for parameters 
    444        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
    445            return (-1);
    446        // #endregion 
    447 
    448        // #region Getting Uint8Array from ArrayBuffer 
    449        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
    450        // #endregion 
    451 
    452        // #region Initial checks 
    453        if(int_buffer.length == 0)
    454        {
    455            this.warnings.push("Zero buffer length");
    456            return input_offset;
    457        }
    458        // #endregion 
    459 
    460        // #region Copy input buffer to internal buffer 
    461        this.value_hex = new ArrayBuffer(input_length);
    462        var view = new Uint8Array(this.value_hex);
    463 
    464        for(var i = 0; i < int_buffer.length; i++)
    465            view[i] = int_buffer[i];
    466        // #endregion 
    467 
    468        this.block_length = input_length;
    469 
    470        return (input_offset + input_length);
    471    };
    472    //**************************************************************************************
    473    local.hex_block.prototype.toBER =
    474    function(size_only)
    475    {
    476        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
    477        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
    478 
    479        if(typeof size_only === "undefined")
    480            size_only = false;
    481 
    482        if(this.is_hex_only !== true)
    483        {
    484            this.error = "Flag \"is_hex_only\" is not set, abort";
    485            return (new ArrayBuffer(0));
    486        }
    487 
    488        var ret_buf = new ArrayBuffer(this.value_hex.byteLength);
    489 
    490        if(size_only === true)
    491            return ret_buf;
    492 
    493        var ret_view = new Uint8Array(ret_buf);
    494        var cur_view = new Uint8Array(this.value_hex);
    495 
    496        for(var i = 0; i < cur_view.length; i++)
    497            ret_view[i] = cur_view[i];
    498 
    499        return ret_buf;
    500    };
    501    //**************************************************************************************
    502    local.hex_block.prototype.toJSON =
    503    function()
    504    {
    505        /// <summary>Convertion for the block to JSON object</summary>
    506 
    507        var _object = local.base_block.prototype.toJSON.call(this);
    508 
    509        _object.block_name = local.hex_block.prototype.block_name.call(this);
    510        _object.is_hex_only = this.is_hex_only;
    511        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
    512 
    513        return _object;
    514    };
    515    //**************************************************************************************
    516    // #endregion 
    517    //**************************************************************************************
    518    // #region Declaration of identification block class 
    519    //**************************************************************************************
    520    local.identification_block =
    521    function()
    522    {
    523        /// <summary>Base class of ASN.1 "identification block"</summary>
    524 
    525        local.hex_block.call(this, arguments[0]);
    526 
    527        this.tag_class = (-1);
    528        this.tag_number = (-1);
    529        this.is_constructed = false;
    530 
    531        if(arguments[0] instanceof Object)
    532        {
    533            if("id_block" in arguments[0])
    534            {
    535                // #region Properties from hex_block class 
    536                this.is_hex_only = in_window.org.pkijs.getValue(arguments[0].id_block, "is_hex_only", false);
    537                this.value_hex = in_window.org.pkijs.getValue(arguments[0].id_block, "value_hex", new ArrayBuffer(0));
    538                // #endregion   
    539 
    540                this.tag_class = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_class", (-1));
    541                this.tag_number = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_number", (-1));
    542                this.is_constructed = in_window.org.pkijs.getValue(arguments[0].id_block, "is_constructed", false);
    543            }
    544        }
    545    };
    546    //**************************************************************************************
    547    local.identification_block.prototype = new local.hex_block();
    548    local.identification_block.constructor = local.identification_block;
    549    //**************************************************************************************
    550    local.identification_block.prototype.block_name =
    551    function()
    552    {
    553        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
    554 
    555        return "identification_block";
    556    };
    557    //**************************************************************************************
    558    local.identification_block.prototype.toBER =
    559    function(size_only)
    560    {
    561        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
    562        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
    563 
    564        if(typeof size_only === "undefined")
    565            size_only = false;
    566 
    567        var first_octet = 0;
    568 
    569        switch(this.tag_class)
    570        {
    571            case 1:
    572                first_octet |= 0x00; // UNIVERSAL
    573                break;
    574            case 2:
    575                first_octet |= 0x40; // APPLICATION
    576                break;
    577            case 3:
    578                first_octet |= 0x80; // CONTEXT-SPECIFIC
    579                break;
    580            case 4:
    581                first_octet |= 0xC0; // PRIVATE
    582                break;
    583            default:
    584                this.error = "Unknown tag class";
    585                return (new ArrayBuffer(0));
    586        }
    587 
    588        if(this.is_constructed)
    589            first_octet |= 0x20;
    590 
    591        if((this.tag_number < 31) && (!this.is_hex_only))
    592        {
    593            var ret_buf = new ArrayBuffer(1);
    594            var ret_view = new Uint8Array(ret_buf);
    595 
    596            if(!size_only)
    597            {
    598                var number = this.tag_number;
    599                number &= 0x1F;
    600                first_octet |= number;
    601 
    602                ret_view[0] = first_octet;
    603            }
    604 
    605            return ret_buf;
    606        }
    607        else
    608        {
    609            if(this.is_hex_only === false)
    610            {
    611                var encoded_buf = util_tobase(this.tag_number, 7);
    612                var encoded_view = new Uint8Array(encoded_buf);
    613                var size = encoded_buf.byteLength;
    614 
    615                var ret_buf = new ArrayBuffer(size + 1);
    616                var ret_view = new Uint8Array(ret_buf);
    617 
    618                ret_view[0] = (first_octet | 0x1F);
    619 
    620                if(!size_only)
    621                {
    622                    for(var i = 0; i < (size - 1) ; i++)
    623                        ret_view[i + 1] = encoded_view[i] | 0x80;
    624 
    625                    ret_view[size] = encoded_view[size - 1];
    626                }
    627 
    628                return ret_buf;
    629            }
    630            else
    631            {
    632                var ret_buf = new ArrayBuffer(this.value_hex.byteLength + 1);
    633                var ret_view = new Uint8Array(ret_buf);
    634 
    635                ret_view[0] = (first_octet | 0x1F);
    636 
    637                if(size_only === false)
    638                {
    639                    var cur_view = new Uint8Array(this.value_hex);
    640 
    641                    for(var i = 0; i < (cur_view.length - 1); i++)
    642                        ret_view[i + 1] = cur_view[i] | 0x80;
    643 
    644                    ret_view[this.value_hex.byteLength] = cur_view[cur_view.length - 1];
    645                }
    646 
    647                return ret_buf;
    648            }
    649        }
    650    };
    651    //**************************************************************************************
    652    local.identification_block.prototype.fromBER =
    653    function(input_buffer, input_offset, input_length)
    654    {
    655        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
    656        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
    657        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
    658        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
    659 
    660        // #region Basic check for parameters 
    661        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
    662            return (-1);
    663        // #endregion 
    664 
    665        // #region Getting Uint8Array from ArrayBuffer 
    666        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
    667        // #endregion 
    668 
    669        // #region Initial checks 
    670        if(int_buffer.length == 0)
    671        {
    672            this.error = "Zero buffer length";
    673            return (-1);
    674        }
    675        // #endregion 
    676 
    677        // #region Find tag class 
    678        var tag_class_mask = int_buffer[0] & 0xC0;
    679 
    680        switch(tag_class_mask)
    681        {
    682            case 0x00:
    683                this.tag_class = (1); // UNIVERSAL
    684                break;
    685            case 0x40:
    686                this.tag_class = (2); // APPLICATION
    687                break;
    688            case 0x80:
    689                this.tag_class = (3); // CONTEXT-SPECIFIC
    690                break;
    691            case 0xC0:
    692                this.tag_class = (4); // PRIVATE
    693                break;
    694            default:
    695                this.error = "Unknown tag class";
    696                return ( -1 );
    697        }
    698        // #endregion 
    699 
    700        // #region Find it's constructed or not 
    701        this.is_constructed = (int_buffer[0] & 0x20) == 0x20;
    702        // #endregion 
    703 
    704        // #region Find tag number 
    705        this.is_hex_only = false;
    706 
    707        var tag_number_mask = int_buffer[0] & 0x1F;
    708 
    709        // #region Simple case (tag number < 31)
    710        if(tag_number_mask != 0x1F) 
    711        {
    712            this.tag_number = (tag_number_mask);
    713            this.block_length = 1;
    714        }
    715            // #endregion 
    716        // #region Tag number bigger or equal to 31 
    717        else
    718        {
    719            var count = 1;
    720 
    721            this.value_hex = new ArrayBuffer(255);
    722            var tag_number_buffer_max_length = 255;
    723            var int_tag_number_buffer = new Uint8Array(this.value_hex);
    724 
    725            while(int_buffer[count] & 0x80)
    726            {
    727                int_tag_number_buffer[count - 1] = int_buffer[count] & 0x7F;
    728                count++;
    729 
    730                if(count >= int_buffer.length)
    731                {
    732                    this.error = "End of input reached before message was fully decoded";
    733                    return (-1);
    734                }
    735 
    736                // #region In case if tag number length is greater than 255 bytes (rare but possible case)
    737                if(count == tag_number_buffer_max_length)
    738                {
    739                    tag_number_buffer_max_length += 255;
    740 
    741                    var temp_buffer = new ArrayBuffer(tag_number_buffer_max_length);
    742                    var temp_buffer_view = new Uint8Array(temp_buffer);
    743 
    744                    for(var i = 0; i < int_tag_number_buffer.length; i++)
    745                        temp_buffer_view[i] = int_tag_number_buffer[i];
    746 
    747                    this.value_hex = new ArrayBuffer(tag_number_buffer_max_length);
    748                    int_tag_number_buffer = new Uint8Array(this.value_hex);
    749                }
    750                // #endregion 
    751            }
    752 
    753            this.block_length = (count + 1);
    754            int_tag_number_buffer[count - 1] = int_buffer[count] & 0x7F; // Write last byte to buffer
    755 
    756            // #region Cut buffer 
    757            var temp_buffer = new ArrayBuffer(count);
    758            var temp_buffer_view = new Uint8Array(temp_buffer);
    759            for(var i = 0; i < count; i++)
    760                temp_buffer_view[i] = int_tag_number_buffer[i];
    761 
    762            this.value_hex = new ArrayBuffer(count);
    763            int_tag_number_buffer = new Uint8Array(this.value_hex);
    764            int_tag_number_buffer.set(temp_buffer_view);
    765            // #endregion 
    766 
    767            // #region Try to convert long tag number to short form 
    768            if(this.block_length <= 9)
    769                this.tag_number = util_frombase(int_tag_number_buffer, 7);
    770            else
    771            {
    772                this.is_hex_only = true;
    773                this.warnings.push("Tag too long, represented as hex-coded");
    774            }
    775            // #endregion 
    776        }
    777        // #endregion 
    778        // #endregion 
    779 
    780        // #region Check if constructed encoding was using for primitive type 
    781        if(((this.tag_class == 1)) &&
    782            (this.is_constructed))
    783        {
    784            switch(this.tag_number)
    785            {
    786                case 1:  // BOOLEAN
    787                case 2:  // REAL
    788                case 5:  // NULL
    789                case 6:  // OBJECT IDENTIFIER
    790                case 9:  // REAL
    791                case 14: // TIME
    792                case 23:
    793                case 24:
    794                case 31:
    795                case 32:
    796                case 33:
    797                case 34:
    798                    this.error = "Constructed encoding used for primitive type";
    799                    return (-1);
    800                default:
    801                    ;
    802            }
    803        }
    804        // #endregion 
    805 
    806        return ( input_offset + this.block_length ); // Return current offset in input buffer
    807    };
    808    //**************************************************************************************
    809    local.identification_block.prototype.toJSON =
    810    function()
    811    {
    812        /// <summary>Convertion for the block to JSON object</summary>
    813 
    814        var _object = local.hex_block.prototype.toJSON.call(this);
    815 
    816        _object.block_name = local.identification_block.prototype.block_name.call(this);
    817        _object.tag_class = this.tag_class;
    818        _object.tag_number = this.tag_number;
    819        _object.is_constructed = this.is_constructed;
    820 
    821        return _object;
    822    };
    823    //**************************************************************************************
    824    // #endregion 
    825    //**************************************************************************************
    826    // #region Declaration of length block class 
    827    //**************************************************************************************
    828    local.length_block =
    829    function()
    830    {
    831        /// <summary>Base class of ASN.1 "length block"</summary>
    832 
    833        local.base_block.call(this, arguments[0]);
    834 
    835        this.is_indefinite_form = false;
    836        this.long_form_used = false;
    837        this.length = (0);
    838 
    839        if(arguments[0] instanceof Object)
    840        {
    841            if("len_block" in arguments[0])
    842            {
    843                this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0].len_block, "is_indefinite_form", false);
    844                this.long_form_used = in_window.org.pkijs.getValue(arguments[0].len_block, "long_form_used", false);
    845                this.length = in_window.org.pkijs.getValue(arguments[0].len_block, "length", 0);
    846            }
    847        }
    848    };
    849    //**************************************************************************************
    850    local.length_block.prototype = new local.base_block();
    851    local.length_block.constructor = local.length_block;
    852    //**************************************************************************************
    853    local.length_block.prototype.block_name =
    854    function()
    855    {
    856        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
    857 
    858        return "length_block";
    859    };
    860    //**************************************************************************************
    861    local.length_block.prototype.fromBER =
    862    function(input_buffer, input_offset, input_length)
    863    {
    864        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
    865        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
    866        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
    867        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
    868 
    869        // #region Basic check for parameters 
    870        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
    871            return (-1);
    872        // #endregion 
    873 
    874        // #region Getting Uint8Array from ArrayBuffer 
    875        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
    876        // #endregion 
    877 
    878        // #region Initial checks 
    879        if(int_buffer.length == 0)
    880        {
    881            this.error = "Zero buffer length";
    882            return (-1);
    883        }
    884 
    885        if(int_buffer[0] == 0xFF)
    886        {
    887            this.error = "Length block 0xFF is reserved by standard";
    888            return (-1);
    889        }
    890        // #endregion 
    891 
    892        // #region Check for length form type 
    893        this.is_indefinite_form = int_buffer[0] == 0x80;
    894        // #endregion 
    895 
    896        // #region Stop working in case of indefinite length form 
    897        if(this.is_indefinite_form == true)
    898        {
    899            this.block_length = 1;
    900            return (input_offset + this.block_length);
    901        }
    902        // #endregion 
    903 
    904        // #region Check is long form of length encoding using 
    905        this.long_form_used = !!(int_buffer[0] & 0x80);
    906        // #endregion 
    907 
    908        // #region Stop working in case of short form of length value 
    909        if(this.long_form_used == false)
    910        {
    911            this.length = (int_buffer[0]);
    912            this.block_length = 1;
    913            return (input_offset + this.block_length);
    914        }
    915        // #endregion 
    916 
    917        // #region Calculate length value in case of long form 
    918        var count = int_buffer[0] & 0x7F;
    919 
    920        if(count > 8) // Too big length value
    921        {
    922            this.error = "Too big integer";
    923            return (-1);
    924        }
    925 
    926        if((count + 1) > int_buffer.length)
    927        {
    928            this.error = "End of input reached before message was fully decoded";
    929            return (-1);
    930        }
    931 
    932        var length_buffer_view = new Uint8Array(count);
    933 
    934        for(var i = 0; i < count; i++)
    935            length_buffer_view[i] = int_buffer[i + 1];
    936 
    937        if(length_buffer_view[count - 1] == 0x00)
    938            this.warnings.push("Needlessly long encoded length");
    939 
    940        this.length = util_frombase(length_buffer_view, 8);
    941 
    942        if(this.long_form_used && (this.length <= 127))
    943            this.warnings.push("Unneccesary usage of long length form");
    944 
    945        this.block_length = count + 1;
    946        // #endregion 
    947 
    948        return (input_offset + this.block_length); // Return current offset in input buffer
    949    };
    950    //**************************************************************************************
    951    local.length_block.prototype.toBER =
    952    function(size_only)
    953    {
    954        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
    955        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
    956 
    957        if(typeof size_only === "undefined")
    958            size_only = false;
    959 
    960        if(this.length > 127)
    961            this.long_form_used = true;
    962 
    963        if(this.is_indefinite_form)
    964        {
    965            var ret_buf = new ArrayBuffer(1);
    966 
    967            if(size_only === false)
    968            {
    969                var ret_view = new Uint8Array(ret_buf);
    970                ret_view[0] = 0x80;
    971            }
    972 
    973            return ret_buf;
    974        }
    975 
    976        if(this.long_form_used === true)
    977        {
    978            var encoded_buf = util_tobase(this.length, 8);
    979 
    980            if(encoded_buf.byteLength > 127)
    981            {
    982                this.error = "Too big length";
    983                return (new ArrayBuffer(0));
    984            }
    985 
    986            var ret_buf = new ArrayBuffer(encoded_buf.byteLength + 1);
    987 
    988            if(size_only === true)
    989                return ret_buf;
    990 
    991            var encoded_view = new Uint8Array(encoded_buf);
    992            var ret_view = new Uint8Array(ret_buf);
    993 
    994            ret_view[0] = encoded_buf.byteLength | 0x80;
    995 
    996            for(var i = 0; i < encoded_buf.byteLength; i++)
    997                ret_view[i + 1] = encoded_view[i];
    998 
    999            return ret_buf;
   1000        }
   1001        else
   1002        {
   1003            var ret_buf = new ArrayBuffer(1);
   1004 
   1005            if(size_only === false)
   1006            {
   1007                var ret_view = new Uint8Array(ret_buf);
   1008 
   1009                ret_view[0] = this.length;
   1010            }
   1011 
   1012            return ret_buf;
   1013        }
   1014 
   1015        return (new ArrayBuffer(0));
   1016    };
   1017    //**************************************************************************************
   1018    local.length_block.prototype.toJSON =
   1019    function()
   1020    {
   1021        /// <summary>Convertion for the block to JSON object</summary>
   1022 
   1023        var _object = local.base_block.prototype.toJSON.call(this);
   1024 
   1025        _object.block_name = local.length_block.prototype.block_name.call(this);
   1026        _object.is_indefinite_form = this.is_indefinite_form;
   1027        _object.long_form_used = this.long_form_used;
   1028        _object.length = this.length;
   1029 
   1030        return _object;
   1031    };
   1032    //**************************************************************************************
   1033    // #endregion 
   1034    //**************************************************************************************
   1035    // #region Declaration of value block class 
   1036    //**************************************************************************************
   1037    local.value_block =
   1038    function()
   1039    {
   1040        /// <summary>Generic class of ASN.1 "value block"</summary>
   1041        local.base_block.call(this, arguments[0]);
   1042    };
   1043    //**************************************************************************************
   1044    local.value_block.prototype = new local.base_block();
   1045    local.value_block.constructor = local.value_block;
   1046    //**************************************************************************************
   1047    local.value_block.prototype.block_name =
   1048    function()
   1049    {
   1050        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1051 
   1052        return "value_block";
   1053    };
   1054    //**************************************************************************************
   1055    local.value_block.prototype.toJSON =
   1056    function()
   1057    {
   1058        /// <summary>Convertion for the block to JSON object</summary>
   1059 
   1060        var _object = local.base_block.prototype.toJSON.call(this);
   1061 
   1062        _object.block_name = local.value_block.prototype.block_name.call(this);
   1063 
   1064        return _object;
   1065    };
   1066    //**************************************************************************************
   1067    // #endregion 
   1068    //**************************************************************************************
   1069    // #region Declaration of basic ASN.1 block class 
   1070    //**************************************************************************************
   1071    in_window.org.pkijs.asn1.ASN1_block =
   1072    function()
   1073    {
   1074        /// <summary>Base class of ASN.1 block (identification block + length block + value block)</summary>
   1075 
   1076        local.base_block.call(this, arguments[0]);
   1077 
   1078        if(arguments[0] instanceof Object)
   1079        {
   1080            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
   1081            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
   1082 
   1083            if("primitive_schema" in arguments[0])
   1084                this.primitive_schema = arguments[0].primitive_schema;
   1085        }
   1086 
   1087        this.id_block = new local.identification_block(arguments[0]);
   1088        this.len_block = new local.length_block(arguments[0]);
   1089        this.value_block = new local.value_block(arguments[0]);
   1090    };
   1091    //**************************************************************************************
   1092    in_window.org.pkijs.asn1.ASN1_block.prototype = new local.base_block();
   1093    in_window.org.pkijs.asn1.ASN1_block.constructor = in_window.org.pkijs.asn1.ASN1_block;
   1094    //**************************************************************************************
   1095    in_window.org.pkijs.asn1.ASN1_block.prototype.block_name =
   1096    function()
   1097    {
   1098        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1099 
   1100        return "ASN1_block";
   1101    };
   1102    //**************************************************************************************
   1103    in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER =
   1104    function(input_buffer, input_offset, input_length)
   1105    {
   1106        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1107        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1108        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1109        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1110 
   1111        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   1112        if(result_offset == (-1))
   1113        {
   1114            this.error = this.value_block.error;
   1115            return result_offset;
   1116        }
   1117 
   1118        if(this.id_block.error.length == 0)
   1119            this.block_length += this.id_block.block_length;
   1120 
   1121        if(this.len_block.error.length == 0)
   1122            this.block_length += this.len_block.block_length;
   1123 
   1124        if(this.value_block.error.length == 0)
   1125            this.block_length += this.value_block.block_length;
   1126 
   1127        return result_offset;
   1128    };
   1129    //**************************************************************************************
   1130    in_window.org.pkijs.asn1.ASN1_block.prototype.toBER =
   1131    function(size_only)
   1132    {
   1133        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1134        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1135 
   1136        if(typeof size_only === "undefined")
   1137            size_only = false;
   1138 
   1139        var ret_buf;
   1140 
   1141        var id_block_buf = this.id_block.toBER(size_only);
   1142        var value_block_size_buf = this.value_block.toBER(true);
   1143 
   1144        this.len_block.length = value_block_size_buf.byteLength;
   1145        var len_block_buf = this.len_block.toBER(size_only);
   1146 
   1147        ret_buf = util_concatbuf(id_block_buf, len_block_buf);
   1148 
   1149        var value_block_buf;
   1150 
   1151        if(size_only === false)
   1152            value_block_buf = this.value_block.toBER(size_only);
   1153        else
   1154            value_block_buf = new ArrayBuffer(this.len_block.length);
   1155 
   1156        ret_buf = util_concatbuf(ret_buf, value_block_buf);
   1157 
   1158        if(this.len_block.is_indefinite_form === true)
   1159        {
   1160            var indef_buf = new ArrayBuffer(2);
   1161 
   1162            if(size_only === false)
   1163            {
   1164                var indef_view = new Uint8Array(indef_buf);
   1165 
   1166                indef_view[0] = 0x00;
   1167                indef_view[1] = 0x00;
   1168            }
   1169 
   1170            ret_buf = util_concatbuf(ret_buf, indef_buf);
   1171        }
   1172 
   1173        return ret_buf;
   1174    };
   1175    //**************************************************************************************
   1176    in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON =
   1177    function()
   1178    {
   1179        /// <summary>Convertion for the block to JSON object</summary>
   1180 
   1181        var _object = local.base_block.prototype.toJSON.call(this);
   1182 
   1183        _object.block_name = in_window.org.pkijs.asn1.ASN1_block.prototype.block_name.call(this);
   1184        _object.id_block = this.id_block.toJSON();
   1185        _object.len_block = this.len_block.toJSON();
   1186        _object.value_block = this.value_block.toJSON();
   1187 
   1188        if("name" in this)
   1189            _object.name = this.name;
   1190        if("optional" in this)
   1191            _object.optional = this.optional;
   1192        if("primitive_schema" in this)
   1193            _object.primitive_schema = this.primitive_schema.toJSON();
   1194 
   1195        return _object;
   1196    };
   1197    //**************************************************************************************
   1198    // #endregion 
   1199    //**************************************************************************************
   1200    // #region Declaration of basic block for all PRIMITIVE types 
   1201    //**************************************************************************************
   1202    local.ASN1_PRIMITIVE_value_block =
   1203    function()
   1204    {
   1205        /// <summary>Base class of ASN.1 value block for primitive values (non-constructive encoding)</summary>
   1206 
   1207        local.value_block.call(this, arguments[0]);
   1208 
   1209        if(arguments[0] instanceof Object)
   1210        {
   1211            // #region Variables from "hex_block" class 
   1212            if("value_hex" in arguments[0])
   1213                this.value_hex = util_copybuf(arguments[0].value_hex);
   1214            else
   1215                this.value_hex = new ArrayBuffer(0);
   1216 
   1217            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", true);
   1218            // #endregion 
   1219        }
   1220        else
   1221        {
   1222            // #region Variables from "hex_block" class 
   1223            this.value_hex = new ArrayBuffer(0);
   1224            this.is_hex_only = true;
   1225            // #endregion 
   1226        }
   1227    };
   1228    //**************************************************************************************
   1229    local.ASN1_PRIMITIVE_value_block.prototype = new local.value_block();
   1230    local.ASN1_PRIMITIVE_value_block.constructor = local.ASN1_PRIMITIVE_value_block;
   1231    //**************************************************************************************
   1232    local.ASN1_PRIMITIVE_value_block.prototype.fromBER =
   1233    function(input_buffer, input_offset, input_length)
   1234    {
   1235        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1236        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1237        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1238        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1239 
   1240        // #region Basic check for parameters 
   1241        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
   1242            return (-1);
   1243        // #endregion 
   1244 
   1245        // #region Getting Uint8Array from ArrayBuffer 
   1246        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   1247        // #endregion 
   1248 
   1249        // #region Initial checks 
   1250        if(int_buffer.length == 0)
   1251        {
   1252            this.warnings.push("Zero buffer length");
   1253            return input_offset;
   1254        }
   1255        // #endregion 
   1256 
   1257        // #region Copy input buffer into internal buffer 
   1258        this.value_hex = new ArrayBuffer(int_buffer.length);
   1259        var value_hex_view = new Uint8Array(this.value_hex);
   1260 
   1261        for(var i = 0; i < int_buffer.length; i++)
   1262            value_hex_view[i] = int_buffer[i];
   1263        // #endregion 
   1264 
   1265        this.block_length = input_length;
   1266 
   1267        return (input_offset + input_length);
   1268    };
   1269    //**************************************************************************************
   1270    local.ASN1_PRIMITIVE_value_block.prototype.toBER =
   1271    function(size_only)
   1272    {
   1273        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1274        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1275 
   1276        return util_copybuf(this.value_hex);
   1277    };
   1278    //**************************************************************************************
   1279    local.ASN1_PRIMITIVE_value_block.prototype.block_name =
   1280    function()
   1281    {
   1282        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1283 
   1284        return "ASN1_PRIMITIVE_value_block";
   1285    };
   1286    //**************************************************************************************
   1287    local.ASN1_PRIMITIVE_value_block.prototype.toJSON =
   1288    function()
   1289    {
   1290        /// <summary>Convertion for the block to JSON object</summary>
   1291 
   1292        var _object = local.value_block.prototype.toJSON.call(this);
   1293 
   1294        _object.block_name = local.ASN1_PRIMITIVE_value_block.prototype.block_name.call(this);
   1295        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
   1296        _object.is_hex_only = this.is_hex_only;
   1297 
   1298        return _object;
   1299    };
   1300    //**************************************************************************************
   1301    in_window.org.pkijs.asn1.ASN1_PRIMITIVE =
   1302    function()
   1303    {
   1304        /// <summary>Base class of ASN.1 block for primitive values (non-constructive encoding)</summary>
   1305 
   1306        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   1307 
   1308        this.id_block.is_constructed = false;
   1309        this.value_block = new local.ASN1_PRIMITIVE_value_block(arguments[0]);
   1310    };
   1311    //**************************************************************************************
   1312    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   1313    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.constructor = in_window.org.pkijs.asn1.ASN1_PRIMITIVE;
   1314    //**************************************************************************************
   1315    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.block_name =
   1316    function()
   1317    {
   1318        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1319 
   1320        return "PRIMITIVE";
   1321    };
   1322    //**************************************************************************************
   1323    in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.toJSON =
   1324    function()
   1325    {
   1326        /// <summary>Convertion for the block to JSON object</summary>
   1327 
   1328        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   1329 
   1330        _object.block_name = in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.block_name.call(this);
   1331 
   1332        return _object;
   1333    };
   1334    //**************************************************************************************
   1335    // #endregion 
   1336    //**************************************************************************************
   1337    // #region Declaration of basic block for all CONSTRUCTED types 
   1338    //**************************************************************************************
   1339    local.ASN1_CONSTRUCTED_value_block =
   1340    function()
   1341    {
   1342        /// <summary>Base class of ASN.1 value block for constructive values (constructive encoding)</summary>
   1343 
   1344        local.value_block.call(this, arguments[0]);
   1345 
   1346        if(arguments[0] instanceof Object)
   1347        {
   1348            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new Array());
   1349            this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0], "is_indefinite_form", false);
   1350        }
   1351        else
   1352        {
   1353            this.value = new Array();
   1354            this.is_indefinite_form = false;
   1355        }
   1356    };
   1357    //**************************************************************************************
   1358    local.ASN1_CONSTRUCTED_value_block.prototype = new local.value_block();
   1359    local.ASN1_CONSTRUCTED_value_block.constructor = local.ASN1_CONSTRUCTED_value_block;
   1360    //**************************************************************************************
   1361    local.ASN1_CONSTRUCTED_value_block.prototype.fromBER =
   1362    function(input_buffer, input_offset, input_length)
   1363    {
   1364        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1365        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1366        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1367        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1368 
   1369        // #region Store initial offset and length 
   1370        var initial_offset = input_offset;
   1371        var initial_length = input_length;
   1372        // #endregion 
   1373 
   1374        // #region Basic check for parameters 
   1375        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
   1376            return (-1);
   1377        // #endregion 
   1378 
   1379        // #region Getting Uint8Array from ArrayBuffer 
   1380        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   1381        // #endregion 
   1382 
   1383        // #region Initial checks 
   1384        if(int_buffer.length == 0)
   1385        {
   1386            this.warnings.push("Zero buffer length");
   1387            return input_offset;
   1388        }
   1389        // #endregion 
   1390 
   1391        // #region Aux function 
   1392        function check_len(_indefinite_length, _length)
   1393        {
   1394            if(_indefinite_length == true)
   1395                return 1;
   1396 
   1397            return _length;
   1398        }
   1399        // #endregion 
   1400 
   1401        var current_offset = input_offset;
   1402 
   1403        while(check_len(this.is_indefinite_form, input_length) > 0)
   1404        {
   1405            var return_object = fromBER_raw(input_buffer, current_offset, input_length);
   1406            if(return_object.offset == (-1))
   1407            {
   1408                this.error = return_object.result.error;
   1409                this.warnings.concat(return_object.result.warnings);
   1410                return (-1);
   1411            }
   1412 
   1413            current_offset = return_object.offset;
   1414 
   1415            this.block_length += return_object.result.block_length;
   1416            input_length -= return_object.result.block_length;
   1417 
   1418            this.value.push(return_object.result);
   1419 
   1420            if((this.is_indefinite_form == true) && (return_object.result.block_name() == in_window.org.pkijs.asn1.EOC.prototype.block_name()))
   1421                break;
   1422        }
   1423 
   1424        if(this.is_indefinite_form == true)
   1425        {
   1426            if(this.value[this.value.length - 1].block_name() == in_window.org.pkijs.asn1.EOC.prototype.block_name())
   1427                this.value.pop();
   1428            else
   1429                this.warnings.push("No EOC block encoded");
   1430        }
   1431 
   1432        // #region Copy "input_buffer" to "value_before_decode" 
   1433        this.value_before_decode = util_copybuf_offset(input_buffer, initial_offset, initial_length);
   1434        // #endregion 
   1435 
   1436        return current_offset;
   1437    };
   1438    //**************************************************************************************
   1439    local.ASN1_CONSTRUCTED_value_block.prototype.toBER =
   1440    function(size_only)
   1441    {
   1442        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1443        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1444 
   1445        if(typeof size_only === "undefined")
   1446            size_only = false;
   1447 
   1448        var ret_buf = new ArrayBuffer(0);
   1449 
   1450        for(var i = 0; i < this.value.length; i++)
   1451        {
   1452            var value_buf = this.value[i].toBER(size_only);
   1453            ret_buf = util_concatbuf(ret_buf, value_buf);
   1454        }
   1455 
   1456        return ret_buf;
   1457    };
   1458    //**************************************************************************************
   1459    local.ASN1_CONSTRUCTED_value_block.prototype.block_name =
   1460    function()
   1461    {
   1462        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1463 
   1464        return "ASN1_CONSTRUCTED_value_block";
   1465    };
   1466    //**************************************************************************************
   1467    local.ASN1_CONSTRUCTED_value_block.prototype.toJSON =
   1468    function()
   1469    {
   1470        /// <summary>Convertion for the block to JSON object</summary>
   1471 
   1472        var _object = local.value_block.prototype.toJSON.call(this);
   1473 
   1474        _object.block_name = local.ASN1_CONSTRUCTED_value_block.prototype.block_name.call(this);
   1475        _object.is_indefinite_form = this.is_indefinite_form;
   1476        _object.value = new Array();
   1477        for(var i = 0; i < this.value.length; i++)
   1478            _object.value.push(this.value[i].toJSON());
   1479 
   1480        return _object;
   1481    };
   1482    //**************************************************************************************
   1483    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED =
   1484    function()
   1485    {
   1486        /// <summary>Base class of ASN.1 block for constructive values (constructive encoding)</summary>
   1487 
   1488        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   1489 
   1490        this.id_block.is_constructed = true;
   1491        this.value_block = new local.ASN1_CONSTRUCTED_value_block(arguments[0]);
   1492    };
   1493    //**************************************************************************************
   1494    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   1495    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.constructor = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED;
   1496    //**************************************************************************************
   1497    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.block_name =
   1498    function()
   1499    {
   1500        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1501 
   1502        return "CONSTRUCTED";
   1503    };
   1504    //**************************************************************************************
   1505    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.fromBER =
   1506    function(input_buffer, input_offset, input_length)
   1507    {
   1508        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1509        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1510        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1511        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1512 
   1513        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
   1514 
   1515        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   1516        if(result_offset == (-1))
   1517        {
   1518            this.error = this.value_block.error;
   1519            return result_offset;
   1520        }
   1521 
   1522        if(this.id_block.error.length == 0)
   1523            this.block_length += this.id_block.block_length;
   1524 
   1525        if(this.len_block.error.length == 0)
   1526            this.block_length += this.len_block.block_length;
   1527 
   1528        if(this.value_block.error.length == 0)
   1529            this.block_length += this.value_block.block_length;
   1530 
   1531        return result_offset;
   1532    };
   1533    //**************************************************************************************
   1534    in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON =
   1535    function()
   1536    {
   1537        /// <summary>Convertion for the block to JSON object</summary>
   1538 
   1539        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   1540 
   1541        _object.block_name = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.block_name.call(this);
   1542 
   1543        return _object;
   1544    };
   1545    //**************************************************************************************
   1546    // #endregion 
   1547    //**************************************************************************************
   1548    // #region Declaration of ASN.1 EOC type class
   1549    //**************************************************************************************
   1550    local.EOC_value_block =
   1551    function()
   1552    {
   1553        local.value_block.call(this, arguments[0]);
   1554    };
   1555    //**************************************************************************************
   1556    local.EOC_value_block.prototype = new local.value_block();
   1557    local.EOC_value_block.constructor = local.EOC_value_block;
   1558    //**************************************************************************************
   1559    local.EOC_value_block.prototype.fromBER =
   1560    function(input_buffer, input_offset, input_length)
   1561    {
   1562        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1563        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1564        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1565        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1566 
   1567        // #region There is no "value block" for EOC type and we need to return the same offset 
   1568        return input_offset;
   1569        // #endregion 
   1570    };
   1571    //**************************************************************************************
   1572    local.EOC_value_block.prototype.toBER =
   1573    function(size_only)
   1574    {
   1575        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1576        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1577 
   1578        return (new ArrayBuffer(0));
   1579    };
   1580    //**************************************************************************************
   1581    local.EOC_value_block.prototype.block_name =
   1582    function()
   1583    {
   1584        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1585 
   1586        return "EOC_value_block";
   1587    };
   1588    //**************************************************************************************
   1589    local.EOC_value_block.prototype.toJSON =
   1590    function()
   1591    {
   1592        /// <summary>Convertion for the block to JSON object</summary>
   1593 
   1594        var _object = local.value_block.prototype.toJSON.call(this);
   1595 
   1596        _object.block_name = local.EOC_value_block.prototype.block_name.call(this);
   1597 
   1598        return _object;
   1599    };
   1600    //**************************************************************************************
   1601    in_window.org.pkijs.asn1.EOC =
   1602    function()
   1603    {
   1604        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   1605 
   1606        this.value_block = new local.EOC_value_block();
   1607 
   1608        this.id_block.tag_class = 1; // UNIVERSAL
   1609        this.id_block.tag_number = 0; // EOC
   1610    };
   1611    //**************************************************************************************
   1612    in_window.org.pkijs.asn1.EOC.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   1613    in_window.org.pkijs.asn1.EOC.constructor = local.EOC_value_block;
   1614    //**************************************************************************************
   1615    in_window.org.pkijs.asn1.EOC.prototype.block_name =
   1616    function()
   1617    {
   1618        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1619 
   1620        return "END_OF_CONTENT";
   1621    };
   1622    //**************************************************************************************
   1623    in_window.org.pkijs.asn1.EOC.prototype.toJSON =
   1624    function()
   1625    {
   1626        /// <summary>Convertion for the block to JSON object</summary>
   1627 
   1628        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   1629 
   1630        _object.block_name = in_window.org.pkijs.asn1.EOC.prototype.block_name.call(this);
   1631 
   1632        return _object;
   1633    };
   1634    //**************************************************************************************
   1635    // #endregion 
   1636    //**************************************************************************************
   1637    // #region Declaration of ASN.1 BOOLEAN type class
   1638    //**************************************************************************************
   1639    local.BOOLEAN_value_block =
   1640    function()
   1641    {
   1642        local.value_block.call(this, arguments[0]);
   1643 
   1644        if(arguments[0] instanceof Object)
   1645        {
   1646            this.value = in_window.org.pkijs.getValue(arguments[0], "value", false);
   1647 
   1648            // #region Variables from hex_block class 
   1649            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
   1650            if("value_hex" in arguments[0])
   1651                this.value_hex = util_copybuf(arguments[0].value_hex);
   1652            else
   1653            {
   1654                this.value_hex = new ArrayBuffer(1);
   1655                if(this.value === true)
   1656                {
   1657                    var view = new Uint8Array(this.value_hex);
   1658                    view[0] = 0xFF;
   1659                }
   1660            }
   1661            // #endregion 
   1662        }
   1663        else
   1664        {
   1665            this.value = false;
   1666 
   1667            // #region Variables from hex_block class 
   1668            this.is_hex_only = false;
   1669            this.value_hex = new ArrayBuffer(1);
   1670            // #endregion 
   1671        }
   1672    };
   1673    //**************************************************************************************
   1674    local.BOOLEAN_value_block.prototype = new local.value_block();
   1675    local.BOOLEAN_value_block.constructor = local.BOOLEAN_value_block;
   1676    //**************************************************************************************
   1677    local.BOOLEAN_value_block.prototype.fromBER =
   1678    function(input_buffer, input_offset, input_length)
   1679    {
   1680        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1681        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1682        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1683        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1684 
   1685        // #region Basic check for parameters 
   1686        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
   1687            return (-1);
   1688        // #endregion 
   1689 
   1690        // #region Getting Uint8Array from ArrayBuffer 
   1691        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   1692        // #endregion 
   1693 
   1694        if(input_length > 1)
   1695            this.warnings.push("BOOLEAN value encoded in more then 1 octet");
   1696 
   1697        this.value = int_buffer[0] != 0x00;
   1698 
   1699        this.is_hex_only = true;
   1700 
   1701        // #region Copy input buffer to internal array 
   1702        this.value_hex = new ArrayBuffer(int_buffer.length);
   1703        var view = new Uint8Array(this.value_hex);
   1704 
   1705        for(var i = 0; i < int_buffer.length; i++)
   1706            view[i] = int_buffer[i];
   1707        // #endregion 
   1708 
   1709        this.block_length = input_length;
   1710 
   1711        return (input_offset + input_length);
   1712    };
   1713    //**************************************************************************************
   1714    local.BOOLEAN_value_block.prototype.toBER =
   1715    function(size_only)
   1716    {
   1717        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1718        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1719 
   1720        if(typeof size_only === "undefined")
   1721            size_only = false;
   1722 
   1723        return this.value_hex;
   1724    };
   1725    //**************************************************************************************
   1726    local.BOOLEAN_value_block.prototype.block_name =
   1727    function()
   1728    {
   1729        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1730 
   1731        return "BOOLEAN_value_block";
   1732    };
   1733    //**************************************************************************************
   1734    local.BOOLEAN_value_block.prototype.toJSON =
   1735    function()
   1736    {
   1737        /// <summary>Convertion for the block to JSON object</summary>
   1738 
   1739        var _object = local.value_block.prototype.toJSON.call(this);
   1740 
   1741        _object.block_name = local.BOOLEAN_value_block.prototype.block_name.call(this);
   1742        _object.value = this.value;
   1743        _object.is_hex_only = this.is_hex_only;
   1744        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
   1745 
   1746        return _object;
   1747    };
   1748    //**************************************************************************************
   1749    in_window.org.pkijs.asn1.BOOLEAN =
   1750    function()
   1751    {
   1752        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   1753 
   1754        this.value_block = new local.BOOLEAN_value_block(arguments[0]);
   1755 
   1756        this.id_block.tag_class = 1; // UNIVERSAL
   1757        this.id_block.tag_number = 1; // BOOLEAN
   1758    };
   1759    //**************************************************************************************
   1760    in_window.org.pkijs.asn1.BOOLEAN.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   1761    in_window.org.pkijs.asn1.BOOLEAN.constructor = local.BOOLEAN_value_block;
   1762    //**************************************************************************************
   1763    in_window.org.pkijs.asn1.BOOLEAN.prototype.block_name =
   1764    function()
   1765    {
   1766        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1767 
   1768        return "BOOLEAN";
   1769    };
   1770    //**************************************************************************************
   1771    in_window.org.pkijs.asn1.BOOLEAN.prototype.toJSON =
   1772    function()
   1773    {
   1774        /// <summary>Convertion for the block to JSON object</summary>
   1775 
   1776        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   1777 
   1778        _object.block_name = in_window.org.pkijs.asn1.BOOLEAN.prototype.block_name.call(this);
   1779 
   1780        return _object;
   1781    };
   1782    //**************************************************************************************
   1783    // #endregion 
   1784    //**************************************************************************************
   1785    // #region Declaration of ASN.1 SEQUENCE and SET type classes
   1786    //**************************************************************************************
   1787    in_window.org.pkijs.asn1.SEQUENCE =
   1788    function()
   1789    {
   1790        in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.call(this, arguments[0]);
   1791 
   1792        this.id_block.tag_class = 1; // UNIVERSAL
   1793        this.id_block.tag_number = 16; // SEQUENCE
   1794    };
   1795    //**************************************************************************************
   1796    in_window.org.pkijs.asn1.SEQUENCE.prototype = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
   1797    in_window.org.pkijs.asn1.SEQUENCE.constructor = in_window.org.pkijs.asn1.SEQUENCE;
   1798    //**************************************************************************************
   1799    in_window.org.pkijs.asn1.SEQUENCE.prototype.block_name =
   1800    function()
   1801    {
   1802        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1803 
   1804        return "SEQUENCE";
   1805    };
   1806    //**************************************************************************************
   1807    in_window.org.pkijs.asn1.SEQUENCE.prototype.toJSON =
   1808    function()
   1809    {
   1810        /// <summary>Convertion for the block to JSON object</summary>
   1811 
   1812        var _object = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON.call(this);
   1813 
   1814        _object.block_name = in_window.org.pkijs.asn1.SEQUENCE.prototype.block_name.call(this);
   1815 
   1816        return _object;
   1817    };
   1818    //**************************************************************************************
   1819    in_window.org.pkijs.asn1.SET =
   1820    function()
   1821    {
   1822        in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.call(this, arguments[0]);
   1823 
   1824        this.id_block.tag_class = 1; // UNIVERSAL
   1825        this.id_block.tag_number = 17; // SET
   1826    };
   1827    //**************************************************************************************
   1828    in_window.org.pkijs.asn1.SET.prototype = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
   1829    in_window.org.pkijs.asn1.SET.constructor = in_window.org.pkijs.asn1.SET;
   1830    //**************************************************************************************
   1831    in_window.org.pkijs.asn1.SET.prototype.block_name =
   1832    function()
   1833    {
   1834        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1835 
   1836        return "SET";
   1837    };
   1838    //**************************************************************************************
   1839    in_window.org.pkijs.asn1.SET.prototype.toJSON =
   1840    function()
   1841    {
   1842        /// <summary>Convertion for the block to JSON object</summary>
   1843 
   1844        var _object = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.toJSON.call(this);
   1845 
   1846        _object.block_name = in_window.org.pkijs.asn1.SET.prototype.block_name.call(this);
   1847 
   1848        return _object;
   1849    };
   1850    //**************************************************************************************
   1851    // #endregion 
   1852    //**************************************************************************************
   1853    // #region Declaration of ASN.1 NULL type class 
   1854    //**************************************************************************************
   1855    in_window.org.pkijs.asn1.NULL =
   1856    function()
   1857    {
   1858        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   1859 
   1860        this.id_block.tag_class = 1; // UNIVERSAL
   1861        this.id_block.tag_number = 5; // NULL
   1862    };
   1863    //**************************************************************************************
   1864    in_window.org.pkijs.asn1.NULL.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   1865    in_window.org.pkijs.asn1.NULL.constructor = in_window.org.pkijs.asn1.NULL;
   1866    //**************************************************************************************
   1867    in_window.org.pkijs.asn1.NULL.prototype.block_name =
   1868    function()
   1869    {
   1870        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   1871 
   1872        return "NULL";
   1873    };
   1874    //**************************************************************************************
   1875    in_window.org.pkijs.asn1.NULL.prototype.fromBER =
   1876    function(input_buffer, input_offset, input_length)
   1877    {
   1878        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1879        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1880        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1881        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1882 
   1883        if(this.len_block.length > 0)
   1884            this.warnings.push("Non-zero length of value block for NULL type");
   1885 
   1886        if(this.id_block.error.length === 0)
   1887            this.block_length += this.id_block.block_length;
   1888 
   1889        if(this.len_block.error.length === 0)
   1890            this.block_length += this.len_block.block_length;
   1891 
   1892        this.block_length += input_length;
   1893 
   1894        return (input_offset + input_length);
   1895    };
   1896    //**************************************************************************************
   1897    in_window.org.pkijs.asn1.NULL.prototype.toBER =
   1898    function(size_only)
   1899    {
   1900        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   1901        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   1902 
   1903        if(typeof size_only === "undefined")
   1904            size_only = false;
   1905 
   1906        var ret_buf = new ArrayBuffer(2);
   1907 
   1908        if(size_only === true)
   1909            return ret_buf;
   1910 
   1911        var ret_view = new Uint8Array(ret_buf);
   1912        ret_view[0] = 0x05;
   1913        ret_view[1] = 0x00;
   1914 
   1915        return ret_buf;
   1916    };
   1917    //**************************************************************************************
   1918    in_window.org.pkijs.asn1.NULL.prototype.toJSON =
   1919    function()
   1920    {
   1921        /// <summary>Convertion for the block to JSON object</summary>
   1922 
   1923        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   1924 
   1925        _object.block_name = in_window.org.pkijs.asn1.NULL.prototype.block_name.call(this);
   1926 
   1927        return _object;
   1928    };
   1929    //**************************************************************************************
   1930    // #endregion 
   1931    //**************************************************************************************
   1932    // #region Declaration of ASN.1 OCTETSTRING type class 
   1933    //**************************************************************************************
   1934    local.OCTETSTRING_value_block =
   1935    function()
   1936    {
   1937        /// <param name="input_value_hex" type="ArrayBuffer"></param>
   1938        /// <param name="input_value" type="Array"></param>
   1939        /// <param name="input_constructed" type="Boolean"></param>
   1940        /// <remarks>Value for the OCTETSTRING may be as hex, as well as a constructed value.</remarks>
   1941        /// <remarks>Constructed values consists of other OCTETSTRINGs</remarks>
   1942 
   1943        local.ASN1_CONSTRUCTED_value_block.call(this, arguments[0]);
   1944 
   1945        if(arguments[0] instanceof Object)
   1946        {
   1947            this.is_constructed = in_window.org.pkijs.getValue(arguments[0], "is_constructed", false);
   1948 
   1949            // #region Variables from hex_block type 
   1950            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
   1951            if("value_hex" in arguments[0])
   1952                this.value_hex = util_copybuf(arguments[0].value_hex);
   1953            else
   1954                this.value_hex = new ArrayBuffer(0);
   1955            // #endregion 
   1956        }
   1957        else
   1958        {
   1959            this.is_constructed = false;
   1960 
   1961            // #region Variables from hex_block type 
   1962            this.is_hex_only = false;
   1963            this.value_hex = new ArrayBuffer(0);
   1964            // #endregion 
   1965        }
   1966    };
   1967    //**************************************************************************************
   1968    local.OCTETSTRING_value_block.prototype = new local.ASN1_CONSTRUCTED_value_block();
   1969    local.OCTETSTRING_value_block.constructor = local.OCTETSTRING_value_block;
   1970    //**************************************************************************************
   1971    local.OCTETSTRING_value_block.prototype.fromBER =
   1972    function(input_buffer, input_offset, input_length)
   1973    {
   1974        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   1975        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   1976        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   1977        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   1978 
   1979        var result_offset = 0;
   1980 
   1981        if(this.is_constructed == true)
   1982        {
   1983            this.is_hex_only = false;
   1984 
   1985            result_offset = local.ASN1_CONSTRUCTED_value_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   1986            if(result_offset == (-1))
   1987                return result_offset;
   1988 
   1989            for(var i = 0; i < this.value.length; i++)
   1990            {
   1991                var current_block_name = this.value[i].block_name();
   1992 
   1993                if(current_block_name == in_window.org.pkijs.asn1.EOC.prototype.block_name())
   1994                {
   1995                    if(this.is_indefinite_form == true)
   1996                        break;
   1997                    else
   1998                    {
   1999                        this.error = "EOC is unexpected, OCTET STRING may consists of OCTET STRINGs only";
   2000                        return (-1);
   2001                    }
   2002                }
   2003 
   2004                if(current_block_name != in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name())
   2005                {
   2006                    this.error = "OCTET STRING may consists of OCTET STRINGs only";
   2007                    return (-1);
   2008                }
   2009            }
   2010        }
   2011        else
   2012        {
   2013            this.is_hex_only = true;
   2014 
   2015            result_offset = local.hex_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   2016            this.block_length = input_length;
   2017        }
   2018 
   2019        return result_offset;
   2020    };
   2021    //**************************************************************************************
   2022    local.OCTETSTRING_value_block.prototype.toBER =
   2023    function(size_only)
   2024    {
   2025        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   2026        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   2027 
   2028        if(typeof size_only === "undefined")
   2029            size_only = false;
   2030 
   2031        if(this.is_constructed === true)
   2032            return local.ASN1_CONSTRUCTED_value_block.prototype.toBER.call(this, size_only);
   2033        else
   2034        {
   2035            var ret_buf = new ArrayBuffer(this.value_hex.byteLength);
   2036 
   2037            if(size_only === true)
   2038                return ret_buf;
   2039 
   2040            if(this.value_hex.byteLength == 0)
   2041                return ret_buf;
   2042 
   2043            ret_buf = util_copybuf(this.value_hex);
   2044 
   2045            return ret_buf;
   2046        }
   2047 
   2048        return (new ArrayBuffer(0));
   2049    };
   2050    //**************************************************************************************
   2051    local.OCTETSTRING_value_block.prototype.block_name =
   2052    function()
   2053    {
   2054        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2055 
   2056        return "OCTETSTRING_value_block";
   2057    };
   2058    //**************************************************************************************
   2059    local.OCTETSTRING_value_block.prototype.toJSON =
   2060    function()
   2061    {
   2062        /// <summary>Convertion for the block to JSON object</summary>
   2063 
   2064        var _object = local.ASN1_CONSTRUCTED_value_block.prototype.toJSON.call(this);
   2065 
   2066        _object.block_name = local.OCTETSTRING_value_block.prototype.block_name.call(this);
   2067        _object.is_constructed = this.is_constructed;
   2068        _object.is_hex_only = this.is_hex_only;
   2069        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
   2070 
   2071        return _object;
   2072    };
   2073    //**************************************************************************************
   2074    in_window.org.pkijs.asn1.OCTETSTRING =
   2075    function()
   2076    {
   2077        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   2078 
   2079        this.value_block = new local.OCTETSTRING_value_block(arguments[0]);
   2080 
   2081        this.id_block.tag_class = 1; // UNIVERSAL
   2082        this.id_block.tag_number = 4; // OCTETSTRING
   2083    };
   2084    //**************************************************************************************
   2085    in_window.org.pkijs.asn1.OCTETSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   2086    in_window.org.pkijs.asn1.OCTETSTRING.constructor = in_window.org.pkijs.asn1.OCTETSTRING;
   2087    //**************************************************************************************
   2088    in_window.org.pkijs.asn1.OCTETSTRING.prototype.fromBER =
   2089    function(input_buffer, input_offset, input_length)
   2090    {
   2091        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2092        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2093        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2094        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2095 
   2096        this.value_block.is_constructed = this.id_block.is_constructed;
   2097        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
   2098 
   2099        // #region Ability to encode empty OCTET STRING 
   2100        if(input_length == 0)
   2101        {
   2102            if(this.id_block.error.length == 0)
   2103                this.block_length += this.id_block.block_length;
   2104 
   2105            if(this.len_block.error.length == 0)
   2106                this.block_length += this.len_block.block_length;
   2107 
   2108            return input_offset;
   2109        }
   2110        // #endregion 
   2111 
   2112        return in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   2113    };
   2114    //**************************************************************************************
   2115    in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name =
   2116    function()
   2117    {
   2118        return "OCTETSTRING";
   2119    };
   2120    //**************************************************************************************
   2121    in_window.org.pkijs.asn1.OCTETSTRING.prototype.toJSON =
   2122    function()
   2123    {
   2124        /// <summary>Convertion for the block to JSON object</summary>
   2125 
   2126        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   2127 
   2128        _object.block_name = in_window.org.pkijs.asn1.OCTETSTRING.prototype.block_name.call(this);
   2129 
   2130        return _object;
   2131    };
   2132    //**************************************************************************************
   2133    in_window.org.pkijs.asn1.OCTETSTRING.prototype.isEqual =
   2134    function(octetString)
   2135    {
   2136        /// <summaryChecking that two OCTETSTRINGs are equal></summary>
   2137        /// <param name="octetString" type="in_window.org.pkijs.asn1.OCTETSTRING">The OCTETSTRING to compare with</param>
   2138 
   2139        // #region Check input type 
   2140        if((octetString instanceof in_window.org.pkijs.asn1.OCTETSTRING) == false)
   2141            return false;
   2142        // #endregion 
   2143 
   2144        // #region Compare two JSON strings 
   2145        if(JSON.stringify(this) != JSON.stringify(octetString))
   2146            return false;
   2147        // #endregion 
   2148 
   2149        return true;
   2150    };
   2151    //**************************************************************************************
   2152    // #endregion 
   2153    //**************************************************************************************
   2154    // #region Declaration of ASN.1 BITSTRING type class
   2155    //**************************************************************************************
   2156    local.BITSTRING_value_block =
   2157    function()
   2158    {
   2159        local.ASN1_CONSTRUCTED_value_block.call(this, arguments[0]);
   2160 
   2161        if(arguments[0] instanceof Object)
   2162        {
   2163            this.unused_bits = in_window.org.pkijs.getValue(arguments[0], "unused_bits", 0);
   2164            this.is_constructed = in_window.org.pkijs.getValue(arguments[0], "is_constructed", false);
   2165 
   2166            // #region Variables from hex_block type 
   2167            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
   2168 
   2169            if("value_hex" in arguments[0])
   2170                this.value_hex = util_copybuf(arguments[0].value_hex);
   2171            else
   2172                this.value_hex = new ArrayBuffer(0);
   2173 
   2174            this.block_length = this.value_hex.byteLength;
   2175            // #endregion 
   2176        }
   2177        else
   2178        {
   2179            this.unused_bits = 0;
   2180            this.is_constructed = false;
   2181 
   2182            // #region Variables from hex_block type 
   2183            this.is_hex_only = false;
   2184            this.value_hex = new ArrayBuffer(0);
   2185            // #endregion 
   2186        }
   2187    };
   2188    //**************************************************************************************
   2189    local.BITSTRING_value_block.prototype = new local.ASN1_CONSTRUCTED_value_block();
   2190    local.BITSTRING_value_block.constructor = local.BITSTRING_value_block;
   2191    //**************************************************************************************
   2192    local.BITSTRING_value_block.prototype.fromBER =
   2193    function(input_buffer, input_offset, input_length)
   2194    {
   2195        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2196        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2197        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2198        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2199 
   2200        // #region Ability to decode zero-length BITSTRING value 
   2201        if(input_length == 0)
   2202            return input_offset;
   2203        // #endregion 
   2204 
   2205        var result_offset = (-1);
   2206 
   2207        // #region If the BISTRING supposed to be a constructed value 
   2208        if(this.is_constructed == true)
   2209        {
   2210            result_offset = local.ASN1_CONSTRUCTED_value_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   2211            if(result_offset == (-1))
   2212                return result_offset;
   2213 
   2214            for(var i = 0; i < this.value.length; i++)
   2215            {
   2216                var current_block_name = this.value[i].block_name();
   2217 
   2218                if(current_block_name == in_window.org.pkijs.asn1.EOC.prototype.block_name())
   2219                {
   2220                    if(this.is_indefinite_form == true)
   2221                        break;
   2222                    else
   2223                    {
   2224                        this.error = "EOC is unexpected, BIT STRING may consists of BIT STRINGs only";
   2225                        return (-1);
   2226                    }
   2227                }
   2228 
   2229                if(current_block_name != in_window.org.pkijs.asn1.BITSTRING.prototype.block_name())
   2230                {
   2231                    this.error = "BIT STRING may consists of BIT STRINGs only";
   2232                    return (-1);
   2233                }
   2234 
   2235                if((this.unused_bits > 0) && (this.value[i].unused_bits > 0))
   2236                {
   2237                    this.error = "Usign of \"unused bits\" inside constructive BIT STRING allowed for least one only";
   2238                    return (-1);
   2239                }
   2240                else
   2241                {
   2242                    this.unused_bits = this.value[i].unused_bits;
   2243                    if(this.unused_bits > 7)
   2244                    {
   2245                        this.error = "Unused bits for BITSTRING must be in range 0-7";
   2246                        return (-1);
   2247                    }
   2248                }
   2249            }
   2250 
   2251            return result_offset;
   2252        }
   2253            // #endregion 
   2254        // #region If the BITSTRING supposed to be a primitive value
   2255        else
   2256        {
   2257            // #region Basic check for parameters 
   2258            if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
   2259                return (-1);
   2260            // #endregion 
   2261 
   2262            var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   2263 
   2264            this.unused_bits = int_buffer[0];
   2265            if(this.unused_bits > 7)
   2266            {
   2267                this.error = "Unused bits for BITSTRING must be in range 0-7";
   2268                return (-1);
   2269            }
   2270 
   2271            // #region Copy input buffer to internal buffer 
   2272            this.value_hex = new ArrayBuffer(int_buffer.length - 1);
   2273            var view = new Uint8Array(this.value_hex);
   2274            for(var i = 0; i < (input_length - 1) ; i++)
   2275                view[i] = int_buffer[i + 1];
   2276            // #endregion 
   2277 
   2278            this.block_length = int_buffer.length;
   2279 
   2280            return (input_offset + input_length);
   2281        }
   2282        // #endregion 
   2283    };
   2284    //**************************************************************************************
   2285    local.BITSTRING_value_block.prototype.toBER =
   2286    function(size_only)
   2287    {
   2288        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   2289        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   2290 
   2291        if(typeof size_only === "undefined")
   2292            size_only = false;
   2293 
   2294        if(this.is_constructed === true)
   2295            return local.ASN1_CONSTRUCTED_value_block.prototype.toBER.call(this, size_only);
   2296        else
   2297        {
   2298            if(size_only === true)
   2299                return (new ArrayBuffer(this.value_hex.byteLength + 1));
   2300 
   2301            if(this.value_hex.byteLength == 0)
   2302                return (new ArrayBuffer(0));
   2303 
   2304            var cur_view = new Uint8Array(this.value_hex);
   2305 
   2306            var ret_buf = new ArrayBuffer(this.value_hex.byteLength + 1);
   2307            var ret_view = new Uint8Array(ret_buf);
   2308 
   2309            ret_view[0] = this.unused_bits;
   2310 
   2311            for(var i = 0; i < this.value_hex.byteLength; i++)
   2312                ret_view[i + 1] = cur_view[i];
   2313 
   2314            return ret_buf;
   2315        }
   2316 
   2317        return (new ArrayBuffer(0));
   2318    };
   2319    //**************************************************************************************
   2320    local.BITSTRING_value_block.prototype.block_name =
   2321    function()
   2322    {
   2323        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2324 
   2325        return "BITSTRING_value_block";
   2326    };
   2327    //**************************************************************************************
   2328    local.BITSTRING_value_block.prototype.toJSON =
   2329    function()
   2330    {
   2331        /// <summary>Convertion for the block to JSON object</summary>
   2332 
   2333        var _object = local.ASN1_CONSTRUCTED_value_block.prototype.toJSON.call(this);
   2334 
   2335        _object.block_name = local.BITSTRING_value_block.prototype.block_name.call(this);
   2336        _object.unused_bits = this.unused_bits;
   2337        _object.is_constructed = this.is_constructed;
   2338        _object.is_hex_only = this.is_hex_only;
   2339        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
   2340 
   2341        return _object;
   2342    };
   2343    //**************************************************************************************
   2344    in_window.org.pkijs.asn1.BITSTRING =
   2345    function()
   2346    {
   2347        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   2348 
   2349        this.value_block = new local.BITSTRING_value_block(arguments[0]);
   2350 
   2351        this.id_block.tag_class = 1; // UNIVERSAL
   2352        this.id_block.tag_number = 3; // BITSTRING
   2353    };
   2354    //**************************************************************************************
   2355    in_window.org.pkijs.asn1.BITSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   2356    in_window.org.pkijs.asn1.BITSTRING.constructor = in_window.org.pkijs.asn1.BITSTRING;
   2357    //**************************************************************************************
   2358    in_window.org.pkijs.asn1.BITSTRING.prototype.block_name =
   2359    function()
   2360    {
   2361        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2362 
   2363        return "BITSTRING";
   2364    };
   2365    //**************************************************************************************
   2366    in_window.org.pkijs.asn1.BITSTRING.prototype.fromBER =
   2367    function(input_buffer, input_offset, input_length)
   2368    {
   2369        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2370        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2371        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2372        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2373 
   2374        // #region Ability to encode empty BITSTRING 
   2375        if(input_length == 0)
   2376            return input_offset;
   2377        // #endregion 
   2378 
   2379        this.value_block.is_constructed = this.id_block.is_constructed;
   2380        this.value_block.is_indefinite_form = this.len_block.is_indefinite_form;
   2381 
   2382        return in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   2383    };
   2384    //**************************************************************************************
   2385    in_window.org.pkijs.asn1.BITSTRING.prototype.toJSON =
   2386    function()
   2387    {
   2388        /// <summary>Convertion for the block to JSON object</summary>
   2389 
   2390        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   2391 
   2392        _object.block_name = in_window.org.pkijs.asn1.BITSTRING.prototype.block_name.call(this);
   2393 
   2394        return _object;
   2395    };
   2396    //**************************************************************************************
   2397    // #endregion 
   2398    //**************************************************************************************
   2399    // #region Declaration of ASN.1 INTEGER type class 
   2400    //**************************************************************************************
   2401    local.INTEGER_value_block =
   2402    function()
   2403    {
   2404        local.value_block.call(this, arguments[0]);
   2405 
   2406        if(arguments[0] instanceof Object)
   2407        {
   2408            this.value_dec = in_window.org.pkijs.getValue(arguments[0], "value", 0);
   2409 
   2410            // #region Variables from hex_block type 
   2411            this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false);
   2412            if("value_hex" in arguments[0])
   2413            {
   2414                this.value_hex = util_copybuf(arguments[0].value_hex);
   2415 
   2416                if(this.value_hex.byteLength >= 4) // Dummy's protection
   2417                    this.is_hex_only = true;
   2418                else
   2419                    this.value_dec = util_decode_tc.call(this);
   2420            }
   2421            else
   2422                this.value_hex = util_encode_tc(this.value_dec);
   2423            // #endregion 
   2424        }
   2425        else
   2426        {
   2427            this.value_dec = 0;
   2428 
   2429            // #region Variables from hex_block type 
   2430            this.is_hex_only = false;
   2431            this.value_hex = new ArrayBuffer(0);
   2432            // #endregion 
   2433        }
   2434    };
   2435    //**************************************************************************************
   2436    local.INTEGER_value_block.prototype = new local.value_block();
   2437    local.INTEGER_value_block.constructor = local.INTEGER_value_block;
   2438    //**************************************************************************************
   2439    local.INTEGER_value_block.prototype.fromBER =
   2440    function(input_buffer, input_offset, input_length)
   2441    {
   2442        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2443        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2444        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2445        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2446 
   2447        var result_offset = local.hex_block.prototype.fromBER.call(this, input_buffer, input_offset, input_length);
   2448        if(result_offset == (-1))
   2449            return result_offset;
   2450 
   2451        if(this.value_hex.byteLength > 4) // In JavaScript we can effectively work with 32-bit integers only
   2452        {
   2453            this.warnings.push("Too big INTEGER for decoding, hex only");
   2454            this.is_hex_only = true;
   2455        }
   2456        else
   2457            this.value_dec = util_decode_tc.call(this);
   2458 
   2459        this.block_length = input_length;
   2460 
   2461        return (input_offset + input_length);
   2462    };
   2463    //**************************************************************************************
   2464    local.INTEGER_value_block.prototype.toBER =
   2465    function(size_only)
   2466    {
   2467        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   2468        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   2469 
   2470        if(typeof size_only === "undefined")
   2471            size_only = false;
   2472 
   2473        if(this.is_hex_only === false)
   2474        {
   2475            var encoded_buf = util_encode_tc(this.value_dec);
   2476            if(encoded_buf.byteLength == 0)
   2477            {
   2478                this.error = "Error during encoding INTEGER value";
   2479                return (new ArrayBuffer(0));
   2480            }
   2481 
   2482            return util_copybuf(encoded_buf);
   2483        }
   2484        else
   2485            return util_copybuf(this.value_hex);
   2486 
   2487        return (new ArrayBuffer(0));
   2488    };
   2489    //**************************************************************************************
   2490    local.INTEGER_value_block.prototype.block_name =
   2491    function()
   2492    {
   2493        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2494 
   2495        return "INTEGER_value_block";
   2496    };
   2497    //**************************************************************************************
   2498    local.INTEGER_value_block.prototype.toJSON =
   2499    function()
   2500    {
   2501        /// <summary>Convertion for the block to JSON object</summary>
   2502 
   2503        var _object = local.value_block.prototype.toJSON.call(this);
   2504 
   2505        _object.block_name = local.INTEGER_value_block.prototype.block_name.call(this);
   2506        _object.value_dec = this.value_dec;
   2507        _object.is_hex_only = this.is_hex_only;
   2508        _object.value_hex = in_window.org.pkijs.bufferToHexCodes(this.value_hex, 0, this.value_hex.byteLength);
   2509 
   2510        return _object;
   2511    };
   2512    //**************************************************************************************
   2513    in_window.org.pkijs.asn1.INTEGER =
   2514    function()
   2515    {
   2516        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   2517 
   2518        this.value_block = new local.INTEGER_value_block(arguments[0]);
   2519 
   2520        this.id_block.tag_class = 1; // UNIVERSAL
   2521        this.id_block.tag_number = 2; // INTEGER
   2522    };
   2523    //**************************************************************************************
   2524    in_window.org.pkijs.asn1.INTEGER.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   2525    in_window.org.pkijs.asn1.INTEGER.constructor = in_window.org.pkijs.asn1.INTEGER;
   2526    //**************************************************************************************
   2527    in_window.org.pkijs.asn1.INTEGER.prototype.block_name =
   2528    function()
   2529    {
   2530        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2531 
   2532        return "INTEGER";
   2533    };
   2534    //**************************************************************************************
   2535    in_window.org.pkijs.asn1.INTEGER.prototype.isEqual =
   2536    function()
   2537    {
   2538        /// <summary>Compare two INTEGER object, or INTEGER and ArrayBuffer objects</summary>
   2539        /// <returns type="Boolean"></returns>
   2540 
   2541        if(arguments[0] instanceof in_window.org.pkijs.asn1.INTEGER)
   2542        {
   2543            if(this.value_block.is_hex_only && arguments[0].value_block.is_hex_only) // Compare two ArrayBuffers
   2544                return in_window.org.pkijs.isEqual_buffer(this.value_block.value_hex, arguments[0].value_block.value_hex);
   2545            else
   2546            {
   2547                if(this.value_block.is_hex_only === arguments[0].value_block.is_hex_only)
   2548                    return (this.value_block.value_dec == arguments[0].value_block.value_dec);
   2549                else
   2550                    return false;
   2551            }
   2552        }
   2553        else
   2554        {
   2555            if(arguments[0] instanceof ArrayBuffer)
   2556                return in_window.org.pkijs.isEqual_buffer(this.value_block.value_hex, arguments[0]);
   2557            else
   2558                return false;
   2559        }
   2560 
   2561        return false;
   2562    };
   2563    //**************************************************************************************
   2564    in_window.org.pkijs.asn1.INTEGER.prototype.toJSON =
   2565    function()
   2566    {
   2567        /// <summary>Convertion for the block to JSON object</summary>
   2568 
   2569        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   2570 
   2571        _object.block_name = in_window.org.pkijs.asn1.INTEGER.prototype.block_name.call(this);
   2572 
   2573        return _object;
   2574    };
   2575    //**************************************************************************************
   2576    // #endregion 
   2577    //**************************************************************************************
   2578    // #region Declaration of ASN.1 ENUMERATED type class 
   2579    //**************************************************************************************
   2580    in_window.org.pkijs.asn1.ENUMERATED =
   2581    function()
   2582    {
   2583        in_window.org.pkijs.asn1.INTEGER.call(this, arguments[0]);
   2584 
   2585        this.id_block.tag_class = 1; // UNIVERSAL
   2586        this.id_block.tag_number = 10; // ENUMERATED
   2587    };
   2588    //**************************************************************************************
   2589    in_window.org.pkijs.asn1.ENUMERATED.prototype = new in_window.org.pkijs.asn1.INTEGER();
   2590    in_window.org.pkijs.asn1.ENUMERATED.constructor = in_window.org.pkijs.asn1.ENUMERATED;
   2591    //**************************************************************************************
   2592    in_window.org.pkijs.asn1.ENUMERATED.prototype.block_name =
   2593    function()
   2594    {
   2595        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2596 
   2597        return "ENUMERATED";
   2598    };
   2599    //**************************************************************************************
   2600    in_window.org.pkijs.asn1.ENUMERATED.prototype.toJSON =
   2601    function()
   2602    {
   2603        /// <summary>Convertion for the block to JSON object</summary>
   2604 
   2605        var _object = in_window.org.pkijs.asn1.INTEGER.prototype.toJSON.call(this);
   2606 
   2607        _object.block_name = in_window.org.pkijs.asn1.ENUMERATED.prototype.block_name.call(this);
   2608 
   2609        return _object;
   2610    };
   2611    //**************************************************************************************
   2612    // #endregion 
   2613    //**************************************************************************************
   2614    // #region Declaration of ASN.1 OBJECT IDENTIFIER type class 
   2615    //**************************************************************************************
   2616    local.SID_value_block =
   2617    function()
   2618    {
   2619        local.hex_block.call(this, arguments[0]);
   2620 
   2621        if(arguments[0] instanceof Object)
   2622        {
   2623            this.value_dec = in_window.org.pkijs.getValue(arguments[0], "value_dec", -1);
   2624            this.is_first_sid = in_window.org.pkijs.getValue(arguments[0], "is_first_sid", false);
   2625        }
   2626        else
   2627        {
   2628            this.value_dec = (-1);
   2629            this.is_first_sid = false;
   2630        }
   2631    };
   2632    //**************************************************************************************
   2633    local.SID_value_block.prototype = new local.hex_block();
   2634    local.SID_value_block.constructor = local.SID_value_block;
   2635    //**************************************************************************************
   2636    local.SID_value_block.prototype.block_name =
   2637    function()
   2638    {
   2639        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2640 
   2641        return "sid_block";
   2642    };
   2643    //**************************************************************************************
   2644    local.SID_value_block.prototype.fromBER =
   2645    function(input_buffer, input_offset, input_length)
   2646    {
   2647        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2648        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2649        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2650        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2651 
   2652        if(input_length == 0)
   2653            return input_offset;
   2654 
   2655        // #region Basic check for parameters 
   2656        if(check_buffer_params.call(this, input_buffer, input_offset, input_length) === false)
   2657            return (-1);
   2658        // #endregion 
   2659 
   2660        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   2661 
   2662        this.value_hex = new ArrayBuffer(input_length);
   2663        var view = new Uint8Array(this.value_hex);
   2664 
   2665        for(var i = 0; i < input_length; i++)
   2666        {
   2667            view[i] = int_buffer[i] & 0x7F;
   2668 
   2669            this.block_length++;
   2670 
   2671            if((int_buffer[i] & 0x80) == 0x00)
   2672                break;
   2673        }
   2674 
   2675        // #region Ajust size of value_hex buffer 
   2676        var temp_value_hex = new ArrayBuffer(this.block_length);
   2677        var temp_view = new Uint8Array(temp_value_hex);
   2678 
   2679        for(var i = 0; i < this.block_length; i++)
   2680            temp_view[i] = view[i];
   2681 
   2682        this.value_hex = util_copybuf(temp_value_hex);
   2683        view = new Uint8Array(this.value_hex);
   2684        // #endregion   
   2685 
   2686        if((int_buffer[this.block_length - 1] & 0x80) != 0x00)
   2687        {
   2688            this.error = "End of input reached before message was fully decoded";
   2689            return (-1);
   2690        }
   2691 
   2692        if(view[0] == 0x00)
   2693            this.warnings.push("Needlessly long format of SID encoding");
   2694 
   2695        if(this.block_length <= 8)
   2696            this.value_dec = util_frombase(view, 7);
   2697        else
   2698        {
   2699            this.is_hex_only = true;
   2700            this.warnings.push("Too big SID for decoding, hex only");
   2701        }
   2702 
   2703        return (input_offset + this.block_length);
   2704    };
   2705    //**************************************************************************************
   2706    local.SID_value_block.prototype.toBER =
   2707    function(size_only)
   2708    {
   2709        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   2710        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   2711 
   2712        if(typeof size_only === "undefined")
   2713            size_only = false;
   2714 
   2715        if(this.is_hex_only)
   2716        {
   2717            if(size_only === true)
   2718                return (new ArrayBuffer(this.value_hex.byteLength));
   2719 
   2720            var cur_view = new Uint8Array(this.value_hex);
   2721 
   2722            var ret_buf = new ArrayBuffer(this.block_length);
   2723            var ret_view = new Uint8Array(ret_buf);
   2724 
   2725            for(var i = 0; i < (this.block_length - 1) ; i++)
   2726                ret_view[i] = cur_view[i] | 0x80;
   2727 
   2728            ret_view[this.block_length - 1] = cur_view[this.block_length - 1];
   2729 
   2730            return ret_buf;
   2731        }
   2732        else
   2733        {
   2734            var encoded_buf = util_tobase(this.value_dec, 7);
   2735            if(encoded_buf.byteLength === 0)
   2736            {
   2737                this.error = "Error during encoding SID value";
   2738                return (new ArrayBuffer(0));
   2739            }
   2740 
   2741            var ret_buf = new ArrayBuffer(encoded_buf.byteLength);
   2742 
   2743            if(size_only === false)
   2744            {
   2745                var encoded_view = new Uint8Array(encoded_buf);
   2746                var ret_view = new Uint8Array(ret_buf);
   2747 
   2748                for(var i = 0; i < (encoded_buf.byteLength - 1) ; i++)
   2749                    ret_view[i] = encoded_view[i] | 0x80;
   2750 
   2751                ret_view[encoded_buf.byteLength - 1] = encoded_view[encoded_buf.byteLength - 1];
   2752            }
   2753 
   2754            return ret_buf;
   2755        }
   2756    };
   2757    //**************************************************************************************
   2758    local.SID_value_block.prototype.toString =
   2759    function()
   2760    {
   2761        var result = "";
   2762 
   2763        if(this.is_hex_only === true)
   2764            result = to_hex_codes(this.value_hex);
   2765        else
   2766        {
   2767            if(this.is_first_sid)
   2768            {
   2769                var sid_value = this.value_dec;
   2770 
   2771                if(this.value_dec <= 39)
   2772                    result = "0.";
   2773                else
   2774                {
   2775                    if(this.value_dec <= 79)
   2776                    {
   2777                        result = "1.";
   2778                        sid_value -= 40;
   2779                    }
   2780                    else
   2781                    {
   2782                        result = "2.";
   2783                        sid_value -= 80;
   2784                    }
   2785                }
   2786 
   2787                result = result + sid_value.toString();
   2788            }
   2789            else
   2790                result = this.value_dec.toString();
   2791        }
   2792 
   2793        return result;
   2794    };
   2795    //**************************************************************************************
   2796    local.SID_value_block.prototype.toJSON =
   2797    function()
   2798    {
   2799        /// <summary>Convertion for the block to JSON object</summary>
   2800 
   2801        var _object = local.hex_block.prototype.toJSON.call(this);
   2802 
   2803        _object.block_name = local.SID_value_block.prototype.block_name.call(this);
   2804        _object.value_dec = this.value_dec;
   2805        _object.is_first_sid = this.is_first_sid;
   2806 
   2807        return _object;
   2808    };
   2809    //**************************************************************************************
   2810    local.OID_value_block =
   2811    function()
   2812    {
   2813        local.value_block.call(this, arguments[0]);
   2814 
   2815        this.value = new Array();
   2816 
   2817        if(arguments[0] instanceof Object)
   2818            this.fromString(in_window.org.pkijs.getValue(arguments[0], "value", ""));
   2819    };
   2820    //**************************************************************************************
   2821    local.OID_value_block.prototype = new local.value_block();
   2822    local.OID_value_block.constructor = local.OID_value_block;
   2823    //**************************************************************************************
   2824    local.OID_value_block.prototype.fromBER =
   2825    function(input_buffer, input_offset, input_length)
   2826    {
   2827        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   2828        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   2829        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   2830        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   2831 
   2832        var result_offset = input_offset;
   2833 
   2834        while(input_length > 0)
   2835        {
   2836            var sid_block = new local.SID_value_block();
   2837            result_offset = sid_block.fromBER(input_buffer, result_offset, input_length);
   2838            if(result_offset == (-1))
   2839            {
   2840                this.block_length = 0;
   2841                this.error = sid_block.error;
   2842                return result_offset;
   2843            }
   2844 
   2845            if(this.value.length == 0)
   2846                sid_block.is_first_sid = true;
   2847 
   2848            this.block_length += sid_block.block_length;
   2849            input_length -= sid_block.block_length;
   2850 
   2851            this.value.push(sid_block);
   2852        }
   2853 
   2854        return result_offset;
   2855    };
   2856    //**************************************************************************************
   2857    local.OID_value_block.prototype.toBER =
   2858    function(size_only)
   2859    {
   2860        /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary>
   2861        /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
   2862 
   2863        if(typeof size_only === "undefined")
   2864            size_only = false;
   2865 
   2866        var ret_buf = new ArrayBuffer(0);
   2867 
   2868        for(var i = 0; i < this.value.length; i++)
   2869        {
   2870            var value_buf = this.value[i].toBER(size_only);
   2871            if(value_buf.byteLength === 0)
   2872            {
   2873                this.error = this.value[i].error;
   2874                return (new ArrayBuffer(0));
   2875            }
   2876 
   2877            ret_buf = util_concatbuf(ret_buf, value_buf);
   2878        }
   2879 
   2880        return ret_buf;
   2881    };
   2882    //**************************************************************************************
   2883    local.OID_value_block.prototype.fromString =
   2884    function(str)
   2885    {
   2886        this.value = new Array(); // Clear existing SID values
   2887 
   2888        var pos1 = 0;
   2889        var pos2 = 0;
   2890 
   2891        var sid = "";
   2892 
   2893        var flag = false;
   2894 
   2895        do
   2896        {
   2897            pos2 = str.indexOf('.', pos1);
   2898            if(pos2 === (-1))
   2899                sid = str.substr(pos1);
   2900            else
   2901                sid = str.substr(pos1, pos2 - pos1);
   2902 
   2903            pos1 = pos2 + 1;
   2904 
   2905            if(flag)
   2906            {
   2907                var sid_block = this.value[0];
   2908 
   2909                var plus = 0;
   2910 
   2911                switch(sid_block.value_dec)
   2912                {
   2913                    case 0:
   2914                        break;
   2915                    case 1:
   2916                        plus = 40;
   2917                        break;
   2918                    case 2:
   2919                        plus = 80;
   2920                        break;
   2921                    default:
   2922                        this.value = new Array(); // clear SID array
   2923                        return false; // ???
   2924                }
   2925 
   2926                var parsedSID = parseInt(sid, 10);
   2927                if(isNaN(parsedSID))
   2928                    return true;
   2929 
   2930                sid_block.value_dec = parsedSID + plus;
   2931 
   2932                flag = false;
   2933            }
   2934            else
   2935            {
   2936                var sid_block = new local.SID_value_block();
   2937                sid_block.value_dec = parseInt(sid, 10);
   2938                if(isNaN(sid_block.value_dec))
   2939                    return true;
   2940 
   2941                if(this.value.length === 0)
   2942                {
   2943                    sid_block.is_first_sid = true;
   2944                    flag = true;
   2945                }
   2946 
   2947                this.value.push(sid_block);
   2948            }
   2949 
   2950        } while(pos2 !== (-1));
   2951 
   2952        return true;
   2953    };
   2954    //**************************************************************************************
   2955    local.OID_value_block.prototype.toString =
   2956    function()
   2957    {
   2958        var result = "";
   2959        var is_hex_only = false;
   2960 
   2961        for(var i = 0; i < this.value.length; i++)
   2962        {
   2963            is_hex_only = this.value[i].is_hex_only;
   2964 
   2965            var sid_str = this.value[i].toString();
   2966 
   2967            if(i !== 0)
   2968                result = result + ".";
   2969 
   2970            if(is_hex_only)
   2971            {
   2972                sid_str = "{" + sid_str + "}";
   2973 
   2974                if(this.value[i].is_first_sid)
   2975                    result = "2.{" + sid_str + " - 80}";
   2976                else
   2977                    result = result + sid_str;
   2978            }
   2979            else
   2980                result = result + sid_str;
   2981        }
   2982 
   2983        return result;
   2984    };
   2985    //**************************************************************************************
   2986    local.OID_value_block.prototype.block_name =
   2987    function()
   2988    {
   2989        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   2990 
   2991        return "OID_value_block";
   2992    };
   2993    //**************************************************************************************
   2994    local.OID_value_block.prototype.toJSON =
   2995    function()
   2996    {
   2997        /// <summary>Convertion for the block to JSON object</summary>
   2998 
   2999        var _object = local.value_block.prototype.toJSON.call(this);
   3000 
   3001        _object.block_name = local.OID_value_block.prototype.block_name.call(this);
   3002        _object.value = local.OID_value_block.prototype.toString.call(this);
   3003        _object.sid_array = new Array();
   3004        for(var i = 0; i < this.value.length; i++)
   3005            _object.sid_array.push(this.value[i].toJSON());
   3006 
   3007        return _object;
   3008    };
   3009    //**************************************************************************************
   3010    in_window.org.pkijs.asn1.OID =
   3011    function()
   3012    {
   3013        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   3014 
   3015        this.value_block = new local.OID_value_block(arguments[0]);
   3016 
   3017        this.id_block.tag_class = 1; // UNIVERSAL
   3018        this.id_block.tag_number = 6; // OBJECT IDENTIFIER
   3019    };
   3020    //**************************************************************************************
   3021    in_window.org.pkijs.asn1.OID.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   3022    in_window.org.pkijs.asn1.OID.constructor = in_window.org.pkijs.asn1.OID;
   3023    //**************************************************************************************
   3024    in_window.org.pkijs.asn1.OID.prototype.block_name =
   3025    function()
   3026    {
   3027        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3028 
   3029        return "OID";
   3030    };
   3031    //**************************************************************************************
   3032    in_window.org.pkijs.asn1.OID.prototype.toJSON =
   3033    function()
   3034    {
   3035        /// <summary>Convertion for the block to JSON object</summary>
   3036 
   3037        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   3038 
   3039        _object.block_name = in_window.org.pkijs.asn1.OID.prototype.block_name.call(this);
   3040 
   3041        return _object;
   3042    };
   3043    //**************************************************************************************
   3044    // #endregion   
   3045    //**************************************************************************************
   3046    // #region Declaration of all string's classes 
   3047    //**************************************************************************************
   3048    local.UTF8STRING_value_block =
   3049    function()
   3050    {
   3051        local.hex_block.call(this, arguments[0]);
   3052 
   3053        this.is_hex_only = true;
   3054        this.value = ""; // String representation of decoded ArrayBuffer
   3055    };
   3056    //**************************************************************************************
   3057    local.UTF8STRING_value_block.prototype = new local.hex_block();
   3058    local.UTF8STRING_value_block.constructor = local.UTF8STRING_value_block;
   3059    //**************************************************************************************
   3060    local.UTF8STRING_value_block.prototype.block_name =
   3061    function()
   3062    {
   3063        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3064 
   3065        return "UTF8STRING_value_block";
   3066    };
   3067    //**************************************************************************************
   3068    local.UTF8STRING_value_block.prototype.toJSON =
   3069    function()
   3070    {
   3071        /// <summary>Convertion for the block to JSON object</summary>
   3072 
   3073        var _object = local.hex_block.prototype.toJSON.call(this);
   3074 
   3075        _object.block_name = local.UTF8STRING_value_block.prototype.block_name.call(this);
   3076        _object.value = this.value;
   3077 
   3078        return _object;
   3079    };
   3080    //**************************************************************************************
   3081    in_window.org.pkijs.asn1.UTF8STRING =
   3082    function()
   3083    {
   3084        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   3085 
   3086        this.value_block = new local.UTF8STRING_value_block();
   3087 
   3088        if(arguments[0] instanceof Object)
   3089        {
   3090            if("value" in arguments[0])
   3091                in_window.org.pkijs.asn1.UTF8STRING.prototype.fromString.call(this,arguments[0].value);
   3092        }
   3093 
   3094        this.id_block.tag_class = 1; // UNIVERSAL
   3095        this.id_block.tag_number = 12; // UTF8STRING
   3096    };
   3097    //**************************************************************************************
   3098    in_window.org.pkijs.asn1.UTF8STRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   3099    in_window.org.pkijs.asn1.UTF8STRING.constructor = in_window.org.pkijs.asn1.UTF8STRING;
   3100    //**************************************************************************************
   3101    in_window.org.pkijs.asn1.UTF8STRING.prototype.block_name =
   3102    function()
   3103    {
   3104        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3105 
   3106        return "UTF8STRING";
   3107    };
   3108    //**************************************************************************************
   3109    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBER =
   3110    function(input_buffer, input_offset, input_length)
   3111    {
   3112        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   3113        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   3114        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   3115        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   3116 
   3117        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   3118        if(result_offset == (-1))
   3119        {
   3120            this.error = this.value_block.error;
   3121            return result_offset;
   3122        }
   3123 
   3124        in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
   3125 
   3126        if(this.id_block.error.length == 0)
   3127            this.block_length += this.id_block.block_length;
   3128 
   3129        if(this.len_block.error.length == 0)
   3130            this.block_length += this.len_block.block_length;
   3131 
   3132        if(this.value_block.error.length == 0)
   3133            this.block_length += this.value_block.block_length;
   3134 
   3135        return result_offset;
   3136    };
   3137    //**************************************************************************************
   3138    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromBuffer =
   3139    function(input_buffer)
   3140    {
   3141        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
   3142        this.value_block.value = String.fromCharCode.apply(null, new Uint8Array(input_buffer));
   3143 
   3144        try
   3145        {
   3146            this.value_block.value = decodeURIComponent(escape(this.value_block.value));
   3147        }
   3148        catch(ex)
   3149        {
   3150            this.warnings.push("Error during \"decodeURIComponent\": " + ex + ", using raw string");
   3151        }
   3152    };
   3153    //**************************************************************************************
   3154    in_window.org.pkijs.asn1.UTF8STRING.prototype.fromString =
   3155    function(input_string)
   3156    {
   3157        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
   3158 
   3159        var str = unescape(encodeURIComponent(input_string));
   3160        var str_len = str.length;
   3161 
   3162        this.value_block.value_hex = new ArrayBuffer(str_len);
   3163        var view = new Uint8Array(this.value_block.value_hex);
   3164 
   3165        for(var i = 0; i < str_len; i++)
   3166            view[i] = str.charCodeAt(i);
   3167 
   3168        this.value_block.value = input_string;
   3169    };
   3170    //**************************************************************************************
   3171    in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON =
   3172    function()
   3173    {
   3174        /// <summary>Convertion for the block to JSON object</summary>
   3175 
   3176        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   3177 
   3178        _object.block_name = in_window.org.pkijs.asn1.UTF8STRING.prototype.block_name.call(this);
   3179 
   3180        return _object;
   3181    };
   3182    //**************************************************************************************
   3183    local.BMPSTRING_value_block =
   3184    function()
   3185    {
   3186        local.hex_block.call(this, arguments[0]);
   3187 
   3188        this.is_hex_only = true;
   3189        this.value = "";
   3190    };
   3191    //**************************************************************************************
   3192    local.BMPSTRING_value_block.prototype = new local.hex_block();
   3193    local.BMPSTRING_value_block.constructor = local.BMPSTRING_value_block;
   3194    //**************************************************************************************
   3195    local.BMPSTRING_value_block.prototype.block_name =
   3196    function()
   3197    {
   3198        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3199 
   3200        return "BMPSTRING_value_block";
   3201    };
   3202    //**************************************************************************************
   3203    local.BMPSTRING_value_block.prototype.toJSON =
   3204    function()
   3205    {
   3206        /// <summary>Convertion for the block to JSON object</summary>
   3207 
   3208        var _object = local.hex_block.prototype.toJSON.call(this);
   3209 
   3210        _object.block_name = local.BMPSTRING_value_block.prototype.block_name.call(this);
   3211        _object.value = this.value;
   3212 
   3213        return _object;
   3214    };
   3215    //**************************************************************************************
   3216    in_window.org.pkijs.asn1.BMPSTRING =
   3217    function()
   3218    {
   3219        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   3220 
   3221        this.value_block = new local.BMPSTRING_value_block();
   3222 
   3223        if(arguments[0] instanceof Object)
   3224        {
   3225            if("value" in arguments[0])
   3226                in_window.org.pkijs.asn1.BMPSTRING.prototype.fromString.call(this, arguments[0].value);
   3227        }
   3228 
   3229        this.id_block.tag_class = 1; // UNIVERSAL
   3230        this.id_block.tag_number = 30; // BMPSTRING
   3231    };
   3232    //**************************************************************************************
   3233    in_window.org.pkijs.asn1.BMPSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   3234    in_window.org.pkijs.asn1.BMPSTRING.constructor = in_window.org.pkijs.asn1.BMPSTRING;
   3235    //**************************************************************************************
   3236    in_window.org.pkijs.asn1.BMPSTRING.prototype.block_name =
   3237    function()
   3238    {
   3239        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3240 
   3241        return "BMPSTRING";
   3242    };
   3243    //**************************************************************************************
   3244    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBER =
   3245    function(input_buffer, input_offset, input_length)
   3246    {
   3247        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   3248        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   3249        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   3250        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   3251 
   3252        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   3253        if(result_offset == (-1))
   3254        {
   3255            this.error = this.value_block.error;
   3256            return result_offset;
   3257        }
   3258 
   3259        in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
   3260 
   3261        if(this.id_block.error.length == 0)
   3262            this.block_length += this.id_block.block_length;
   3263 
   3264        if(this.len_block.error.length == 0)
   3265            this.block_length += this.len_block.block_length;
   3266 
   3267        if(this.value_block.error.length == 0)
   3268            this.block_length += this.value_block.block_length;
   3269 
   3270        return result_offset;
   3271    };
   3272    //**************************************************************************************
   3273    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromBuffer =
   3274    function(input_buffer)
   3275    {
   3276        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
   3277 
   3278        var copy_buffer = in_window.org.pkijs.copyBuffer(input_buffer);
   3279 
   3280        var value_view = new Uint8Array(copy_buffer);
   3281 
   3282        for(var i = 0; i < value_view.length; i = i + 2)
   3283        {
   3284            var temp = value_view[i];
   3285 
   3286            value_view[i] = value_view[i + 1];
   3287            value_view[i + 1] = temp;
   3288        }
   3289 
   3290        this.value_block.value = String.fromCharCode.apply(null, new Uint16Array(copy_buffer));
   3291    };
   3292    //**************************************************************************************
   3293    in_window.org.pkijs.asn1.BMPSTRING.prototype.fromString =
   3294    function(input_string)
   3295    {
   3296        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
   3297 
   3298        var str_length = input_string.length;
   3299 
   3300        this.value_block.value_hex = new ArrayBuffer(str_length * 2);
   3301        var value_hex_view = new Uint8Array(this.value_block.value_hex);
   3302 
   3303        for(var i = 0; i < str_length; i++)
   3304        {
   3305            var code_buf = util_tobase(input_string.charCodeAt(i), 8);
   3306            var code_view = new Uint8Array(code_buf);
   3307            if(code_view.length > 2)
   3308                continue;
   3309 
   3310            var dif = 2 - code_view.length;
   3311 
   3312            for(var j = (code_view.length - 1) ; j >= 0; j--)
   3313                value_hex_view[i * 2 + j + dif] = code_view[j];
   3314        }
   3315 
   3316        this.value_block.value = input_string;
   3317    };
   3318    //**************************************************************************************
   3319    in_window.org.pkijs.asn1.BMPSTRING.prototype.toJSON =
   3320    function()
   3321    {
   3322        /// <summary>Convertion for the block to JSON object</summary>
   3323 
   3324        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   3325 
   3326        _object.block_name = in_window.org.pkijs.asn1.BMPSTRING.prototype.block_name.call(this);
   3327 
   3328        return _object;
   3329    };
   3330    //**************************************************************************************
   3331    local.UNIVERSALSTRING_value_block =
   3332    function()
   3333    {
   3334        local.hex_block.call(this, arguments[0]);
   3335 
   3336        this.is_hex_only = true;
   3337        this.value = "";
   3338    };
   3339    //**************************************************************************************
   3340    local.UNIVERSALSTRING_value_block.prototype = new local.hex_block();
   3341    local.UNIVERSALSTRING_value_block.constructor = local.UNIVERSALSTRING_value_block;
   3342    //**************************************************************************************
   3343    local.UNIVERSALSTRING_value_block.prototype.block_name =
   3344    function()
   3345    {
   3346        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3347 
   3348        return "UNIVERSALSTRING_value_block";
   3349    };
   3350    //**************************************************************************************
   3351    local.UNIVERSALSTRING_value_block.prototype.toJSON =
   3352    function()
   3353    {
   3354        /// <summary>Convertion for the block to JSON object</summary>
   3355 
   3356        var _object = local.hex_block.prototype.toJSON.call(this);
   3357 
   3358        _object.block_name = local.UNIVERSALSTRING_value_block.prototype.block_name.call(this);
   3359        _object.value = this.value;
   3360 
   3361        return _object;
   3362    };
   3363    //**************************************************************************************
   3364    in_window.org.pkijs.asn1.UNIVERSALSTRING =
   3365    function()
   3366    {
   3367        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   3368 
   3369        this.value_block = new local.UNIVERSALSTRING_value_block();
   3370 
   3371        if(arguments[0] instanceof Object)
   3372        {
   3373            if("value" in arguments[0])
   3374                in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromString.call(this, arguments[0].value);
   3375        }
   3376 
   3377        this.id_block.tag_class = 1; // UNIVERSAL
   3378        this.id_block.tag_number = 28; // UNIVERSALSTRING
   3379    };
   3380    //**************************************************************************************
   3381    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   3382    in_window.org.pkijs.asn1.UNIVERSALSTRING.constructor = in_window.org.pkijs.asn1.UNIVERSALSTRING;
   3383    //**************************************************************************************
   3384    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.block_name =
   3385    function()
   3386    {
   3387        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3388 
   3389        return "UNIVERSALSTRING";
   3390    };
   3391    //**************************************************************************************
   3392    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBER =
   3393    function(input_buffer, input_offset, input_length)
   3394    {
   3395        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   3396        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   3397        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   3398        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   3399 
   3400        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   3401        if(result_offset == (-1))
   3402        {
   3403            this.error = this.value_block.error;
   3404            return result_offset;
   3405        }
   3406 
   3407        in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBuffer.call(this, this.value_block.value_hex);
   3408 
   3409        if(this.id_block.error.length == 0)
   3410            this.block_length += this.id_block.block_length;
   3411 
   3412        if(this.len_block.error.length == 0)
   3413            this.block_length += this.len_block.block_length;
   3414 
   3415        if(this.value_block.error.length == 0)
   3416            this.block_length += this.value_block.block_length;
   3417 
   3418        return result_offset;
   3419    };
   3420    //**************************************************************************************
   3421    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromBuffer =
   3422    function(input_buffer)
   3423    {
   3424        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
   3425 
   3426        var copy_buffer = in_window.org.pkijs.copyBuffer(input_buffer);
   3427 
   3428        var value_view = new Uint8Array(copy_buffer);
   3429 
   3430        for(var i = 0; i < value_view.length; i = i + 4)
   3431        {
   3432            value_view[i] = value_view[i + 3];
   3433            value_view[i + 1] = value_view[i + 2];
   3434            value_view[i + 2] = 0x00;
   3435            value_view[i + 3] = 0x00;
   3436        }
   3437 
   3438        this.value_block.value = String.fromCharCode.apply(null, new Uint32Array(copy_buffer));
   3439    };
   3440    //**************************************************************************************
   3441    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.fromString =
   3442    function(input_string)
   3443    {
   3444        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
   3445 
   3446        var str_length = input_string.length;
   3447 
   3448        this.value_block.value_hex = new ArrayBuffer(str_length * 4);
   3449        var value_hex_view = new Uint8Array(this.value_block.value_hex);
   3450 
   3451        for(var i = 0; i < str_length; i++)
   3452        {
   3453            var code_buf = util_tobase(input_string.charCodeAt(i), 8);
   3454            var code_view = new Uint8Array(code_buf);
   3455            if(code_view.length > 4)
   3456                continue;
   3457 
   3458            var dif = 4 - code_view.length;
   3459 
   3460            for(var j = (code_view.length - 1) ; j >= 0; j--)
   3461                value_hex_view[i*4 + j + dif] = code_view[j];
   3462        }
   3463 
   3464        this.value_block.value = input_string;
   3465    };
   3466    //**************************************************************************************
   3467    in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.toJSON =
   3468    function()
   3469    {
   3470        /// <summary>Convertion for the block to JSON object</summary>
   3471 
   3472        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   3473 
   3474        _object.block_name = in_window.org.pkijs.asn1.UNIVERSALSTRING.prototype.block_name.call(this);
   3475 
   3476        return _object;
   3477    };
   3478    //**************************************************************************************
   3479    local.SIMPLESTRING_value_block =
   3480    function()
   3481    {
   3482        local.hex_block.call(this, arguments[0]);
   3483 
   3484        /// <field type="String">Native string representation</field>
   3485        this.value = "";
   3486        this.is_hex_only = true;
   3487    };
   3488    //**************************************************************************************
   3489    local.SIMPLESTRING_value_block.prototype = new local.hex_block();
   3490    local.SIMPLESTRING_value_block.constructor = local.SIMPLESTRING_value_block;
   3491    //**************************************************************************************
   3492    local.SIMPLESTRING_value_block.prototype.block_name =
   3493    function()
   3494    {
   3495        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3496 
   3497        return "SIMPLESTRING_value_block";
   3498    };
   3499    //**************************************************************************************
   3500    local.SIMPLESTRING_value_block.prototype.toJSON =
   3501    function()
   3502    {
   3503        /// <summary>Convertion for the block to JSON object</summary>
   3504 
   3505        var _object = local.hex_block.prototype.toJSON.call(this);
   3506 
   3507        _object.block_name = local.SIMPLESTRING_value_block.prototype.block_name.call(this);
   3508        _object.value = this.value;
   3509 
   3510        return _object;
   3511    };
   3512    //**************************************************************************************
   3513    local.SIMPLESTRING_block =
   3514    function()
   3515    {
   3516        in_window.org.pkijs.asn1.ASN1_block.call(this, arguments[0]);
   3517 
   3518        this.value_block = new local.SIMPLESTRING_value_block();
   3519 
   3520        if(arguments[0] instanceof Object)
   3521        {
   3522            if("value" in arguments[0])
   3523                local.SIMPLESTRING_block.prototype.fromString.call(this, arguments[0].value);
   3524        }
   3525    };
   3526    //**************************************************************************************
   3527    local.SIMPLESTRING_block.prototype = new in_window.org.pkijs.asn1.ASN1_block();
   3528    local.SIMPLESTRING_block.constructor = local.SIMPLESTRING_block;
   3529    //**************************************************************************************
   3530    local.SIMPLESTRING_block.prototype.block_name =
   3531    function()
   3532    {
   3533        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3534 
   3535        return "SIMPLESTRING";
   3536    };
   3537    //**************************************************************************************
   3538    local.SIMPLESTRING_block.prototype.fromBER =
   3539    function(input_buffer, input_offset, input_length)
   3540    {
   3541        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   3542        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   3543        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   3544        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   3545 
   3546        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   3547        if(result_offset == (-1))
   3548        {
   3549            this.error = this.value_block.error;
   3550            return result_offset;
   3551        }
   3552 
   3553        local.SIMPLESTRING_block.prototype.fromBuffer.call(this, this.value_block.value_hex);
   3554 
   3555        if(this.id_block.error.length == 0)
   3556            this.block_length += this.id_block.block_length;
   3557 
   3558        if(this.len_block.error.length == 0)
   3559            this.block_length += this.len_block.block_length;
   3560 
   3561        if(this.value_block.error.length == 0)
   3562            this.block_length += this.value_block.block_length;
   3563 
   3564        return result_offset;
   3565    };
   3566    //**************************************************************************************
   3567    local.SIMPLESTRING_block.prototype.fromBuffer =
   3568    function(input_buffer)
   3569    {
   3570        /// <param name="input_buffer" type="ArrayBuffer">Array with encoded string</param>
   3571 
   3572        this.value_block.value = String.fromCharCode.apply(null, new Uint8Array(input_buffer));
   3573    };
   3574    //**************************************************************************************
   3575    local.SIMPLESTRING_block.prototype.fromString =
   3576    function(input_string)
   3577    {
   3578        /// <param name="input_string" type="String">String with UNIVERSALSTRING value</param>
   3579        var str_len = input_string.length;
   3580 
   3581        this.value_block.value_hex = new ArrayBuffer(str_len);
   3582        var view = new Uint8Array(this.value_block.value_hex);
   3583 
   3584        for(var i = 0; i < str_len; i++)
   3585            view[i] = input_string.charCodeAt(i);
   3586 
   3587        this.value_block.value = input_string;
   3588    };
   3589    //**************************************************************************************
   3590    local.SIMPLESTRING_block.prototype.toJSON =
   3591    function()
   3592    {
   3593        /// <summary>Convertion for the block to JSON object</summary>
   3594 
   3595        var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
   3596 
   3597        _object.block_name = local.SIMPLESTRING_block.prototype.block_name.call(this);
   3598 
   3599        return _object;
   3600    };
   3601    //**************************************************************************************
   3602    in_window.org.pkijs.asn1.NUMERICSTRING =
   3603    function()
   3604    {
   3605        local.SIMPLESTRING_block.call(this, arguments[0]);
   3606 
   3607        this.id_block.tag_class = 1; // UNIVERSAL
   3608        this.id_block.tag_number = 18; // NUMERICSTRING
   3609    };
   3610    //**************************************************************************************
   3611    in_window.org.pkijs.asn1.NUMERICSTRING.prototype = new local.SIMPLESTRING_block();
   3612    in_window.org.pkijs.asn1.NUMERICSTRING.constructor = in_window.org.pkijs.asn1.NUMERICSTRING;
   3613    //**************************************************************************************
   3614    in_window.org.pkijs.asn1.NUMERICSTRING.prototype.block_name =
   3615    function()
   3616    {
   3617        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3618 
   3619        return "NUMERICSTRING";
   3620    };
   3621    //**************************************************************************************
   3622    in_window.org.pkijs.asn1.NUMERICSTRING.prototype.toJSON =
   3623    function()
   3624    {
   3625        /// <summary>Convertion for the block to JSON object</summary>
   3626 
   3627        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3628 
   3629        _object.block_name = in_window.org.pkijs.asn1.NUMERICSTRING.prototype.block_name.call(this);
   3630 
   3631        return _object;
   3632    };
   3633    //**************************************************************************************
   3634    in_window.org.pkijs.asn1.PRINTABLESTRING =
   3635    function()
   3636    {
   3637        local.SIMPLESTRING_block.call(this, arguments[0]);
   3638 
   3639        this.id_block.tag_class = 1; // UNIVERSAL
   3640        this.id_block.tag_number = 19; // PRINTABLESTRING
   3641    };
   3642    //**************************************************************************************
   3643    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype = new local.SIMPLESTRING_block();
   3644    in_window.org.pkijs.asn1.PRINTABLESTRING.constructor = in_window.org.pkijs.asn1.PRINTABLESTRING;
   3645    //**************************************************************************************
   3646    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.block_name =
   3647    function()
   3648    {
   3649        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3650 
   3651        return "PRINTABLESTRING";
   3652    };
   3653    //**************************************************************************************
   3654    in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.toJSON =
   3655    function()
   3656    {
   3657        /// <summary>Convertion for the block to JSON object</summary>
   3658 
   3659        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3660 
   3661        _object.block_name = in_window.org.pkijs.asn1.PRINTABLESTRING.prototype.block_name.call(this);
   3662 
   3663        return _object;
   3664    };
   3665    //**************************************************************************************
   3666    in_window.org.pkijs.asn1.TELETEXSTRING =
   3667    function()
   3668    {
   3669        local.SIMPLESTRING_block.call(this, arguments[0]);
   3670 
   3671        this.id_block.tag_class = 1; // UNIVERSAL
   3672        this.id_block.tag_number = 20; // TELETEXSTRING
   3673    };
   3674    //**************************************************************************************
   3675    in_window.org.pkijs.asn1.TELETEXSTRING.prototype = new local.SIMPLESTRING_block();
   3676    in_window.org.pkijs.asn1.TELETEXSTRING.constructor = in_window.org.pkijs.asn1.TELETEXSTRING;
   3677    //**************************************************************************************
   3678    in_window.org.pkijs.asn1.TELETEXSTRING.prototype.block_name =
   3679    function()
   3680    {
   3681        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3682 
   3683        return "TELETEXSTRING";
   3684    };
   3685    //**************************************************************************************
   3686    in_window.org.pkijs.asn1.TELETEXSTRING.prototype.toJSON =
   3687    function()
   3688    {
   3689        /// <summary>Convertion for the block to JSON object</summary>
   3690 
   3691        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3692 
   3693        _object.block_name = in_window.org.pkijs.asn1.TELETEXSTRING.prototype.block_name.call(this);
   3694 
   3695        return _object;
   3696    };
   3697    //**************************************************************************************
   3698    in_window.org.pkijs.asn1.VIDEOTEXSTRING =
   3699    function()
   3700    {
   3701        local.SIMPLESTRING_block.call(this, arguments[0]);
   3702 
   3703        this.id_block.tag_class = 1; // UNIVERSAL
   3704        this.id_block.tag_number = 21; // VIDEOTEXSTRING
   3705    };
   3706    //**************************************************************************************
   3707    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype = new local.SIMPLESTRING_block();
   3708    in_window.org.pkijs.asn1.VIDEOTEXSTRING.constructor = in_window.org.pkijs.asn1.VIDEOTEXSTRING;
   3709    //**************************************************************************************
   3710    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.block_name =
   3711    function()
   3712    {
   3713        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3714 
   3715        return "VIDEOTEXSTRING";
   3716    };
   3717    //**************************************************************************************
   3718    in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.toJSON =
   3719    function()
   3720    {
   3721        /// <summary>Convertion for the block to JSON object</summary>
   3722 
   3723        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3724 
   3725        _object.block_name = in_window.org.pkijs.asn1.VIDEOTEXSTRING.prototype.block_name.call(this);
   3726 
   3727        return _object;
   3728    };
   3729    //**************************************************************************************
   3730    in_window.org.pkijs.asn1.IA5STRING =
   3731    function()
   3732    {
   3733        local.SIMPLESTRING_block.call(this, arguments[0]);
   3734 
   3735        this.id_block.tag_class = 1; // UNIVERSAL
   3736        this.id_block.tag_number = 22; // IA5STRING
   3737    };
   3738    //**************************************************************************************
   3739    in_window.org.pkijs.asn1.IA5STRING.prototype = new local.SIMPLESTRING_block();
   3740    in_window.org.pkijs.asn1.IA5STRING.constructor = in_window.org.pkijs.asn1.IA5STRING;
   3741    //**************************************************************************************
   3742    in_window.org.pkijs.asn1.IA5STRING.prototype.block_name =
   3743    function()
   3744    {
   3745        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3746 
   3747        return "IA5STRING";
   3748    };
   3749    //**************************************************************************************
   3750    in_window.org.pkijs.asn1.IA5STRING.prototype.toJSON =
   3751    function()
   3752    {
   3753        /// <summary>Convertion for the block to JSON object</summary>
   3754 
   3755        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3756 
   3757        _object.block_name = in_window.org.pkijs.asn1.IA5STRING.prototype.block_name.call(this);
   3758 
   3759        return _object;
   3760    };
   3761    //**************************************************************************************
   3762    in_window.org.pkijs.asn1.GRAPHICSTRING =
   3763    function()
   3764    {
   3765        local.SIMPLESTRING_block.call(this, arguments[0]);
   3766 
   3767        this.id_block.tag_class = 1; // UNIVERSAL
   3768        this.id_block.tag_number = 25; // GRAPHICSTRING
   3769    };
   3770    //**************************************************************************************
   3771    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype = new local.SIMPLESTRING_block();
   3772    in_window.org.pkijs.asn1.GRAPHICSTRING.constructor = in_window.org.pkijs.asn1.GRAPHICSTRING;
   3773    //**************************************************************************************
   3774    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.block_name =
   3775    function()
   3776    {
   3777        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3778 
   3779        return "GRAPHICSTRING";
   3780    };
   3781    //**************************************************************************************
   3782    in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.toJSON =
   3783    function()
   3784    {
   3785        /// <summary>Convertion for the block to JSON object</summary>
   3786 
   3787        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3788 
   3789        _object.block_name = in_window.org.pkijs.asn1.GRAPHICSTRING.prototype.block_name.call(this);
   3790 
   3791        return _object;
   3792    };
   3793    //**************************************************************************************
   3794    in_window.org.pkijs.asn1.VISIBLESTRING =
   3795    function()
   3796    {
   3797        local.SIMPLESTRING_block.call(this, arguments[0]);
   3798 
   3799        this.id_block.tag_class = 1; // UNIVERSAL
   3800        this.id_block.tag_number = 26; // VISIBLESTRING
   3801    };
   3802    //**************************************************************************************
   3803    in_window.org.pkijs.asn1.VISIBLESTRING.prototype = new local.SIMPLESTRING_block();
   3804    in_window.org.pkijs.asn1.VISIBLESTRING.constructor = in_window.org.pkijs.asn1.VISIBLESTRING;
   3805    //**************************************************************************************
   3806    in_window.org.pkijs.asn1.VISIBLESTRING.prototype.block_name =
   3807    function()
   3808    {
   3809        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3810 
   3811        return "VISIBLESTRING";
   3812    };
   3813    //**************************************************************************************
   3814    in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON =
   3815    function()
   3816    {
   3817        /// <summary>Convertion for the block to JSON object</summary>
   3818 
   3819        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3820 
   3821        _object.block_name = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.block_name.call(this);
   3822 
   3823        return _object;
   3824    };
   3825    //**************************************************************************************
   3826    in_window.org.pkijs.asn1.GENERALSTRING =
   3827    function()
   3828    {
   3829        local.SIMPLESTRING_block.call(this, arguments[0]);
   3830 
   3831        this.id_block.tag_class = 1; // UNIVERSAL
   3832        this.id_block.tag_number = 27; // GENERALSTRING
   3833    };
   3834    //**************************************************************************************
   3835    in_window.org.pkijs.asn1.GENERALSTRING.prototype = new local.SIMPLESTRING_block();
   3836    in_window.org.pkijs.asn1.GENERALSTRING.constructor = in_window.org.pkijs.asn1.GENERALSTRING;
   3837    //**************************************************************************************
   3838    in_window.org.pkijs.asn1.GENERALSTRING.prototype.block_name =
   3839    function()
   3840    {
   3841        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3842 
   3843        return "GENERALSTRING";
   3844    };
   3845    //**************************************************************************************
   3846    in_window.org.pkijs.asn1.GENERALSTRING.prototype.toJSON =
   3847    function()
   3848    {
   3849        /// <summary>Convertion for the block to JSON object</summary>
   3850 
   3851        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3852 
   3853        _object.block_name = in_window.org.pkijs.asn1.GENERALSTRING.prototype.block_name.call(this);
   3854 
   3855        return _object;
   3856    };
   3857    //**************************************************************************************
   3858    in_window.org.pkijs.asn1.CHARACTERSTRING =
   3859    function()
   3860    {
   3861        local.SIMPLESTRING_block.call(this, arguments[0]);
   3862 
   3863        this.id_block.tag_class = 1; // UNIVERSAL
   3864        this.id_block.tag_number = 29; // CHARACTERSTRING
   3865    };
   3866    //**************************************************************************************
   3867    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype = new local.SIMPLESTRING_block();
   3868    in_window.org.pkijs.asn1.CHARACTERSTRING.constructor = in_window.org.pkijs.asn1.CHARACTERSTRING;
   3869    //**************************************************************************************
   3870    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.block_name =
   3871    function()
   3872    {
   3873        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   3874 
   3875        return "CHARACTERSTRING";
   3876    };
   3877    //**************************************************************************************
   3878    in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.toJSON =
   3879    function()
   3880    {
   3881        /// <summary>Convertion for the block to JSON object</summary>
   3882 
   3883        var _object = local.SIMPLESTRING_block.prototype.toJSON.call(this);
   3884 
   3885        _object.block_name = in_window.org.pkijs.asn1.CHARACTERSTRING.prototype.block_name.call(this);
   3886 
   3887        return _object;
   3888    };
   3889    //**************************************************************************************
   3890    // #endregion 
   3891    //**************************************************************************************
   3892    // #region Declaration of all date and time classes 
   3893    //**************************************************************************************
   3894    in_window.org.pkijs.asn1.UTCTIME =
   3895    function()
   3896    {
   3897        in_window.org.pkijs.asn1.VISIBLESTRING.call(this, arguments[0]);
   3898 
   3899        this.year = 0;
   3900        this.month = 0;
   3901        this.day = 0;
   3902        this.hour = 0;
   3903        this.minute = 0;
   3904        this.second = 0;
   3905 
   3906        // #region Create UTCTIME from ASN.1 UTC string value 
   3907        if((arguments[0] instanceof Object) && ("value" in arguments[0]))
   3908        {
   3909            in_window.org.pkijs.asn1.UTCTIME.prototype.fromString.call(this, arguments[0].value);
   3910 
   3911            this.value_block.value_hex = new ArrayBuffer(arguments[0].value.length);
   3912            var view = new Uint8Array(this.value_block.value_hex);
   3913 
   3914            for(var i = 0; i < arguments[0].value.length; i++)
   3915                view[i] = arguments[0].value.charCodeAt(i);
   3916        }
   3917        // #endregion 
   3918        // #region Create UTCTIME from JavaScript Date type 
   3919        if((arguments[0] instanceof Object) && ("value_date" in arguments[0]))
   3920        {
   3921            in_window.org.pkijs.asn1.UTCTIME.prototype.fromDate.call(this, arguments[0].value_date);
   3922            this.value_block.value_hex = in_window.org.pkijs.asn1.UTCTIME.prototype.toBuffer.call(this);
   3923        }
   3924        // #endregion 
   3925 
   3926        this.id_block.tag_class = 1; // UNIVERSAL
   3927        this.id_block.tag_number = 23; // UTCTIME
   3928    };
   3929    //**************************************************************************************
   3930    in_window.org.pkijs.asn1.UTCTIME.prototype = new in_window.org.pkijs.asn1.VISIBLESTRING();
   3931    in_window.org.pkijs.asn1.UTCTIME.constructor = in_window.org.pkijs.asn1.UTCTIME;
   3932    //**************************************************************************************
   3933    in_window.org.pkijs.asn1.UTCTIME.prototype.fromBER =
   3934    function(input_buffer, input_offset, input_length)
   3935    {
   3936        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   3937        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   3938        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   3939        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   3940 
   3941        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   3942        if(result_offset == (-1))
   3943        {
   3944            this.error = this.value_block.error;
   3945            return result_offset;
   3946        }
   3947 
   3948        in_window.org.pkijs.asn1.UTCTIME.prototype.fromBuffer.call(this, this.value_block.value_hex);
   3949 
   3950        if(this.id_block.error.length == 0)
   3951            this.block_length += this.id_block.block_length;
   3952 
   3953        if(this.len_block.error.length == 0)
   3954            this.block_length += this.len_block.block_length;
   3955 
   3956        if(this.value_block.error.length == 0)
   3957            this.block_length += this.value_block.block_length;
   3958 
   3959        return result_offset;
   3960    };
   3961    //**************************************************************************************
   3962    in_window.org.pkijs.asn1.UTCTIME.prototype.fromBuffer =
   3963    function(input_buffer)
   3964    {
   3965        in_window.org.pkijs.asn1.UTCTIME.prototype.fromString.call(this, String.fromCharCode.apply(null, new Uint8Array(input_buffer)));
   3966    };
   3967    //**************************************************************************************
   3968    in_window.org.pkijs.asn1.UTCTIME.prototype.toBuffer =
   3969    function()
   3970    {
   3971        var str = in_window.org.pkijs.asn1.UTCTIME.prototype.toString.call(this);
   3972 
   3973        var buffer = new ArrayBuffer(str.length);
   3974        var view = new Uint8Array(buffer);
   3975 
   3976        for(var i = 0; i < str.length; i++)
   3977            view[i] = str.charCodeAt(i);
   3978 
   3979        return buffer;
   3980    };
   3981    //**************************************************************************************
   3982    in_window.org.pkijs.asn1.UTCTIME.prototype.fromDate =
   3983    function(input_date)
   3984    {
   3985        /// <summary>Create "UTCTime" ASN.1 type from JavaScript "Date" type</summary>
   3986 
   3987        this.year = input_date.getUTCFullYear();
   3988        this.month = input_date.getUTCMonth() + 1;
   3989        this.day = input_date.getUTCDate();
   3990        this.hour = input_date.getUTCHours();
   3991        this.minute = input_date.getUTCMinutes();
   3992        this.second = input_date.getUTCSeconds();
   3993    };
   3994    //**************************************************************************************
   3995    in_window.org.pkijs.asn1.UTCTIME.prototype.toDate =
   3996    function()
   3997    {
   3998        return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)));
   3999    };
   4000    //**************************************************************************************
   4001    in_window.org.pkijs.asn1.UTCTIME.prototype.fromString =
   4002    function(input_string)
   4003    {
   4004        /// <summary>Create "UTCTime" ASN.1 type from JavaScript "String" type</summary>
   4005 
   4006        // #region Parse input string 
   4007        var parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig;
   4008        var parser_array = parser.exec(input_string);
   4009        if(parser_array === null)
   4010        {
   4011            this.error = "Wrong input string for convertion";
   4012            return;
   4013        }
   4014        // #endregion 
   4015 
   4016        // #region Store parsed values 
   4017        var year = parseInt(parser_array[1], 10);
   4018        if(year >= 50)
   4019            this.year = 1900 + year;
   4020        else
   4021            this.year = 2000 + year;
   4022 
   4023        this.month = parseInt(parser_array[2], 10);
   4024        this.day = parseInt(parser_array[3], 10);
   4025        this.hour = parseInt(parser_array[4], 10);
   4026        this.minute = parseInt(parser_array[5], 10);
   4027        this.second = parseInt(parser_array[6], 10);
   4028        // #endregion 
   4029    };
   4030    //**************************************************************************************
   4031    in_window.org.pkijs.asn1.UTCTIME.prototype.toString =
   4032    function()
   4033    {
   4034        var output_array = new Array(7);
   4035 
   4036        output_array[0] = in_window.org.pkijs.padNumber(((this.year < 2000) ? (this.year - 1900) : (this.year - 2000)), 2);
   4037        output_array[1] = in_window.org.pkijs.padNumber(this.month, 2);
   4038        output_array[2] = in_window.org.pkijs.padNumber(this.day, 2);
   4039        output_array[3] = in_window.org.pkijs.padNumber(this.hour, 2);
   4040        output_array[4] = in_window.org.pkijs.padNumber(this.minute, 2);
   4041        output_array[5] = in_window.org.pkijs.padNumber(this.second, 2);
   4042        output_array[6] = "Z";
   4043 
   4044        return output_array.join('');
   4045    };
   4046    //**************************************************************************************
   4047    in_window.org.pkijs.asn1.UTCTIME.prototype.block_name =
   4048    function()
   4049    {
   4050        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4051 
   4052        return "UTCTIME";
   4053    };
   4054    //**************************************************************************************
   4055    in_window.org.pkijs.asn1.UTCTIME.prototype.toJSON =
   4056    function()
   4057    {
   4058        /// <summary>Convertion for the block to JSON object</summary>
   4059 
   4060        var _object = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON.call(this);
   4061 
   4062        _object.block_name = in_window.org.pkijs.asn1.UTCTIME.prototype.block_name.call(this);
   4063        _object.year = this.year;
   4064        _object.month = this.month;
   4065        _object.day = this.day;
   4066        _object.hour = this.hour;
   4067        _object.minute = this.minute;
   4068        _object.second = this.second;
   4069 
   4070        return _object;
   4071    };
   4072    //**************************************************************************************
   4073    in_window.org.pkijs.asn1.GENERALIZEDTIME =
   4074    function()
   4075    {
   4076        in_window.org.pkijs.asn1.VISIBLESTRING.call(this, arguments[0]);
   4077 
   4078        this.year = 0;
   4079        this.month = 0;
   4080        this.day = 0;
   4081        this.hour = 0;
   4082        this.minute = 0;
   4083        this.second = 0;
   4084        this.millisecond = 0;
   4085 
   4086        // #region Create GeneralizedTime from ASN.1 string value 
   4087        if((arguments[0] instanceof Object) && ("value" in arguments[0]))
   4088        {
   4089            in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString.call(this, arguments[0].value);
   4090 
   4091            this.value_block.value_hex = new ArrayBuffer(arguments[0].value.length);
   4092            var view = new Uint8Array(this.value_block.value_hex);
   4093 
   4094            for(var i = 0; i < arguments[0].value.length; i++)
   4095                view[i] = arguments[0].value.charCodeAt(i);
   4096        }
   4097        // #endregion 
   4098        // #region Create GeneralizedTime from JavaScript Date type 
   4099        if((arguments[0] instanceof Object) && ("value_date" in arguments[0]))
   4100        {
   4101            in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromDate.call(this, arguments[0].value_date);
   4102            this.value_block.value_hex = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toBuffer.call(this);
   4103        }
   4104        // #endregion 
   4105 
   4106        this.id_block.tag_class = 1; // UNIVERSAL
   4107        this.id_block.tag_number = 24; // GENERALIZEDTIME
   4108    };
   4109    //**************************************************************************************
   4110    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype = new in_window.org.pkijs.asn1.VISIBLESTRING();
   4111    in_window.org.pkijs.asn1.GENERALIZEDTIME.constructor = in_window.org.pkijs.asn1.GENERALIZEDTIME;
   4112    //**************************************************************************************
   4113    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBER =
   4114    function(input_buffer, input_offset, input_length)
   4115    {
   4116        /// <summary>Base function for converting block from BER encoded array of bytes</summary>
   4117        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param>
   4118        /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param>
   4119        /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
   4120 
   4121        var result_offset = this.value_block.fromBER(input_buffer, input_offset, (this.len_block.is_indefinite_form == true) ? input_length : this.len_block.length);
   4122        if(result_offset == (-1))
   4123        {
   4124            this.error = this.value_block.error;
   4125            return result_offset;
   4126        }
   4127 
   4128        in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBuffer.call(this, this.value_block.value_hex);
   4129 
   4130        if(this.id_block.error.length == 0)
   4131            this.block_length += this.id_block.block_length;
   4132 
   4133        if(this.len_block.error.length == 0)
   4134            this.block_length += this.len_block.block_length;
   4135 
   4136        if(this.value_block.error.length == 0)
   4137            this.block_length += this.value_block.block_length;
   4138 
   4139        return result_offset;
   4140    };
   4141    //**************************************************************************************
   4142    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromBuffer =
   4143    function(input_buffer)
   4144    {
   4145        in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString.call(this, String.fromCharCode.apply(null, new Uint8Array(input_buffer)));
   4146    };
   4147    //**************************************************************************************
   4148    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toBuffer =
   4149    function()
   4150    {
   4151        var str = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toString.call(this);
   4152 
   4153        var buffer = new ArrayBuffer(str.length);
   4154        var view = new Uint8Array(buffer);
   4155 
   4156        for(var i = 0; i < str.length; i++)
   4157            view[i] = str.charCodeAt(i);
   4158 
   4159        return buffer;
   4160    };
   4161    //**************************************************************************************
   4162    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromDate =
   4163    function(input_date)
   4164    {
   4165        /// <summary>Create "GeneralizedTime" ASN.1 type from JavaScript "Date" type</summary>
   4166 
   4167        this.year = input_date.getUTCFullYear();
   4168        this.month = input_date.getUTCMonth();
   4169        this.day = input_date.getUTCDate();
   4170        this.hour = input_date.getUTCHours();
   4171        this.minute = input_date.getUTCMinutes();
   4172        this.second = input_date.getUTCSeconds();
   4173        this.millisecond = input_date.getUTCMilliseconds();
   4174    };
   4175    //**************************************************************************************
   4176    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toDate =
   4177    function()
   4178    {
   4179        return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)));
   4180    };
   4181    //**************************************************************************************
   4182    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.fromString =
   4183    function(input_string)
   4184    {
   4185        /// <summary>Create "GeneralizedTime" ASN.1 type from JavaScript "String" type</summary>
   4186 
   4187        // #region Initial variables 
   4188        var isUTC = false;
   4189 
   4190        var timeString = "";
   4191        var dateTimeString = "";
   4192        var fractionPart = 0;
   4193 
   4194        var parser;
   4195 
   4196        var hourDifference = 0;
   4197        var minuteDifference = 0;
   4198        // #endregion 
   4199 
   4200        // #region Convert as UTC time 
   4201        if(input_string[input_string.length - 1] == "Z")
   4202        {
   4203            timeString = input_string.substr(0, input_string.length - 1);
   4204 
   4205            isUTC = true;
   4206        }
   4207        // #endregion 
   4208        // #region Convert as local time 
   4209        else
   4210        {
   4211            var number = new Number(input_string[input_string.length - 1]);
   4212 
   4213            if(isNaN(number.valueOf()))
   4214                throw new Error("Wrong input string for convertion");
   4215 
   4216            timeString = input_string;
   4217        }
   4218        // #endregion 
   4219 
   4220        // #region Check that we do not have a "+" and "-" symbols inside UTC time 
   4221        if(isUTC)
   4222        {
   4223            if(timeString.indexOf("+") != (-1))
   4224                throw new Error("Wrong input string for convertion");
   4225 
   4226            if(timeString.indexOf("-") != (-1))
   4227                throw new Error("Wrong input string for convertion");
   4228        }
   4229        // #endregion 
   4230        // #region Get "UTC time difference" in case of local time
   4231        else
   4232        {
   4233            var multiplier = 1;
   4234            var differencePosition = timeString.indexOf("+");
   4235            var differenceString = "";
   4236 
   4237            if(differencePosition == (-1))
   4238            {
   4239                differencePosition = timeString.indexOf("-");
   4240                multiplier = (-1);
   4241            }
   4242 
   4243            if(differencePosition != (-1))
   4244            {
   4245                differenceString = timeString.substr(differencePosition + 1);
   4246                timeString = timeString.substr(0, differencePosition);
   4247 
   4248                if((differenceString.length != 2) && (differenceString.length != 4))
   4249                    throw new Error("Wrong input string for convertion");
   4250 
   4251                var number = new Number(differenceString.substr(0, 2));
   4252 
   4253                if(isNaN(number.valueOf()))
   4254                    throw new Error("Wrong input string for convertion");
   4255 
   4256                hourDifference = multiplier * number;
   4257 
   4258                if(differenceString.length == 4)
   4259                {
   4260                    number = new Number(differenceString.substr(2, 2));
   4261 
   4262                    if(isNaN(number.valueOf()))
   4263                        throw new Error("Wrong input string for convertion");
   4264 
   4265                    minuteDifference = multiplier * number;
   4266                }
   4267            }
   4268        }
   4269        // #endregion 
   4270 
   4271        // #region Get position of fraction point 
   4272        var fractionPointPosition = timeString.indexOf("."); // Check for "full stop" symbol
   4273        if(fractionPointPosition == (-1))
   4274            fractionPointPosition = timeString.indexOf(","); // Check for "comma" symbol
   4275        // #endregion 
   4276 
   4277        // #region Get fraction part 
   4278        if(fractionPointPosition != (-1))
   4279        {
   4280            var fractionPartCheck = new Number("0" + timeString.substr(fractionPointPosition));
   4281 
   4282            if(isNaN(fractionPartCheck.valueOf()))
   4283                throw new Error("Wrong input string for convertion");
   4284 
   4285            fractionPart = fractionPartCheck.valueOf();
   4286 
   4287            dateTimeString = timeString.substr(0, fractionPointPosition);
   4288        }
   4289        else
   4290            dateTimeString = timeString;
   4291        // #endregion 
   4292 
   4293        // #region Parse internal date 
   4294        switch(true)
   4295        {
   4296            case (dateTimeString.length == 8): // "YYYYMMDD"
   4297                parser = /(\d{4})(\d{2})(\d{2})/ig;
   4298                if(fractionPointPosition !== (-1))
   4299                    throw new Error("Wrong input string for convertion"); // Here we should not have a "fraction point"
   4300                break;
   4301            case (dateTimeString.length == 10): // "YYYYMMDDHH"
   4302                parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig;
   4303 
   4304                if(fractionPointPosition !== (-1))
   4305                {
   4306                    var fractionResult = 60 * fractionPart;
   4307                    this.minute = Math.floor(fractionResult);
   4308 
   4309                    fractionResult = 60 * (fractionResult - this.minute);
   4310                    this.second = Math.floor(fractionResult);
   4311 
   4312                    fractionResult = 1000 * (fractionResult - this.second);
   4313                    this.millisecond = Math.floor(fractionResult);
   4314                }
   4315                break;
   4316            case (dateTimeString.length == 12): // "YYYYMMDDHHMM"
   4317                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
   4318 
   4319                if(fractionPointPosition !== (-1))
   4320                {
   4321                    var fractionResult = 60 * fractionPart;
   4322                    this.second = Math.floor(fractionResult);
   4323 
   4324                    fractionResult = 1000 * (fractionResult - this.second);
   4325                    this.millisecond = Math.floor(fractionResult);
   4326                }
   4327                break;
   4328            case (dateTimeString.length == 14): // "YYYYMMDDHHMMSS"
   4329                parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
   4330 
   4331                if(fractionPointPosition !== (-1))
   4332                {
   4333                    var fractionResult = 1000 * fractionPart;
   4334                    this.millisecond = Math.floor(fractionResult);
   4335                }
   4336                break;
   4337            default:
   4338                throw new Error("Wrong input string for convertion");
   4339        }
   4340        // #endregion 
   4341 
   4342        // #region Put parsed values at right places 
   4343        var parser_array = parser.exec(dateTimeString);
   4344        if(parser_array == null)
   4345            throw new Error("Wrong input string for convertion");
   4346 
   4347        for(var j = 1; j < parser_array.length; j++)
   4348        {
   4349            switch(j)
   4350            {
   4351                case 1:
   4352                    this.year = parseInt(parser_array[j], 10);
   4353                    break;
   4354                case 2:
   4355                    this.month = parseInt(parser_array[j], 10) - 1; // In JavaScript we have month range as "0 - 11"
   4356                    break;
   4357                case 3:
   4358                    this.day = parseInt(parser_array[j], 10);
   4359                    break;
   4360                case 4:
   4361                    this.hour = parseInt(parser_array[j], 10) + hourDifference;
   4362                    break;
   4363                case 5:
   4364                    this.minute = parseInt(parser_array[j], 10) + minuteDifference;
   4365                    break;
   4366                case 6:
   4367                    this.second = parseInt(parser_array[j], 10);
   4368                    break;
   4369                default:
   4370                    throw new Error("Wrong input string for convertion");
   4371            }
   4372        }
   4373        // #endregion 
   4374 
   4375        // #region Get final date 
   4376        if(isUTC == false)
   4377        {
   4378            var tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
   4379 
   4380            this.year = tempDate.getUTCFullYear();
   4381            this.month = tempDate.getUTCMonth();
   4382            this.day = tempDate.getUTCDay();
   4383            this.hour = tempDate.getUTCHours();
   4384            this.minute = tempDate.getUTCMinutes();
   4385            this.second = tempDate.getUTCSeconds();
   4386            this.millisecond = tempDate.getUTCMilliseconds();
   4387        }
   4388        // #endregion 
   4389    };
   4390    //**************************************************************************************
   4391    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toString =
   4392    function()
   4393    {
   4394        var output_array = new Array();
   4395 
   4396        output_array.push(in_window.org.pkijs.padNumber(this.year, 4));
   4397        output_array.push(in_window.org.pkijs.padNumber(this.month, 2));
   4398        output_array.push(in_window.org.pkijs.padNumber(this.day, 2));
   4399        output_array.push(in_window.org.pkijs.padNumber(this.hour, 2));
   4400        output_array.push(in_window.org.pkijs.padNumber(this.minute, 2));
   4401        output_array.push(in_window.org.pkijs.padNumber(this.second, 2));
   4402        if(this.millisecond != 0)
   4403        {
   4404            output_array.push(".");
   4405            output_array.push(in_window.org.pkijs.padNumber(this.millisecond, 3));
   4406        }
   4407        output_array.push("Z");
   4408 
   4409        return output_array.join('');
   4410    };
   4411    //**************************************************************************************
   4412    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.block_name =
   4413    function()
   4414    {
   4415        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4416 
   4417        return "GENERALIZEDTIME";
   4418    };
   4419    //**************************************************************************************
   4420    in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.toJSON =
   4421    function()
   4422    {
   4423        /// <summary>Convertion for the block to JSON object</summary>
   4424 
   4425        var _object = in_window.org.pkijs.asn1.VISIBLESTRING.prototype.toJSON.call(this);
   4426 
   4427        _object.block_name = in_window.org.pkijs.asn1.GENERALIZEDTIME.prototype.block_name.call(this);
   4428        _object.year = this.year;
   4429        _object.month = this.month;
   4430        _object.day = this.day;
   4431        _object.hour = this.hour;
   4432        _object.minute = this.minute;
   4433        _object.second = this.second;
   4434        _object.millisecond = this.millisecond;
   4435 
   4436        return _object;
   4437    };
   4438    //**************************************************************************************
   4439    in_window.org.pkijs.asn1.DATE =
   4440    function()
   4441    {
   4442        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
   4443 
   4444        this.id_block.tag_class = 1; // UNIVERSAL
   4445        this.id_block.tag_number = 31; // DATE
   4446    };
   4447    //**************************************************************************************
   4448    in_window.org.pkijs.asn1.DATE.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
   4449    in_window.org.pkijs.asn1.DATE.constructor = in_window.org.pkijs.asn1.DATE;
   4450    //**************************************************************************************
   4451    in_window.org.pkijs.asn1.DATE.prototype.block_name =
   4452    function()
   4453    {
   4454        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4455 
   4456        return "DATE";
   4457    };
   4458    //**************************************************************************************
   4459    in_window.org.pkijs.asn1.DATE.prototype.toJSON =
   4460    function()
   4461    {
   4462        /// <summary>Convertion for the block to JSON object</summary>
   4463 
   4464        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
   4465 
   4466        _object.block_name = in_window.org.pkijs.asn1.DATE.prototype.block_name.call(this);
   4467 
   4468        return _object;
   4469    };
   4470    //**************************************************************************************
   4471    in_window.org.pkijs.asn1.TIMEOFDAY =
   4472    function()
   4473    {
   4474        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
   4475 
   4476        this.id_block.tag_class = 1; // UNIVERSAL
   4477        this.id_block.tag_number = 32; // TIMEOFDAY
   4478    };
   4479    //**************************************************************************************
   4480    in_window.org.pkijs.asn1.TIMEOFDAY.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
   4481    in_window.org.pkijs.asn1.TIMEOFDAY.constructor = in_window.org.pkijs.asn1.TIMEOFDAY;
   4482    //**************************************************************************************
   4483    in_window.org.pkijs.asn1.TIMEOFDAY.prototype.block_name =
   4484    function()
   4485    {
   4486        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4487 
   4488        return "TIMEOFDAY";
   4489    };
   4490    //**************************************************************************************
   4491    in_window.org.pkijs.asn1.TIMEOFDAY.prototype.toJSON =
   4492    function()
   4493    {
   4494        /// <summary>Convertion for the block to JSON object</summary>
   4495 
   4496        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
   4497 
   4498        _object.block_name = in_window.org.pkijs.asn1.TIMEOFDAY.prototype.block_name.call(this);
   4499 
   4500        return _object;
   4501    };
   4502    //**************************************************************************************
   4503    in_window.org.pkijs.asn1.DATETIME =
   4504    function()
   4505    {
   4506        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
   4507 
   4508        this.id_block.tag_class = 1; // UNIVERSAL
   4509        this.id_block.tag_number = 33; // DATETIME
   4510    };
   4511    //**************************************************************************************
   4512    in_window.org.pkijs.asn1.DATETIME.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
   4513    in_window.org.pkijs.asn1.DATETIME.constructor = in_window.org.pkijs.asn1.DATETIME;
   4514    //**************************************************************************************
   4515    in_window.org.pkijs.asn1.DATETIME.prototype.block_name =
   4516    function()
   4517    {
   4518        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4519 
   4520        return "DATETIME";
   4521    };
   4522    //**************************************************************************************
   4523    in_window.org.pkijs.asn1.DATETIME.prototype.toJSON =
   4524    function()
   4525    {
   4526        /// <summary>Convertion for the block to JSON object</summary>
   4527 
   4528        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
   4529 
   4530        _object.block_name = in_window.org.pkijs.asn1.DATETIME.prototype.block_name.call(this);
   4531 
   4532        return _object;
   4533    };
   4534    //**************************************************************************************
   4535    in_window.org.pkijs.asn1.DURATION =
   4536    function()
   4537    {
   4538        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
   4539 
   4540        this.id_block.tag_class = 1; // UNIVERSAL
   4541        this.id_block.tag_number = 34; // DURATION
   4542    };
   4543    //**************************************************************************************
   4544    in_window.org.pkijs.asn1.DURATION.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
   4545    in_window.org.pkijs.asn1.DURATION.constructor = in_window.org.pkijs.asn1.DURATION;
   4546    //**************************************************************************************
   4547    in_window.org.pkijs.asn1.DURATION.prototype.block_name =
   4548    function()
   4549    {
   4550        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4551 
   4552        return "DURATION";
   4553    };
   4554    //**************************************************************************************
   4555    in_window.org.pkijs.asn1.DURATION.prototype.toJSON =
   4556    function()
   4557    {
   4558        /// <summary>Convertion for the block to JSON object</summary>
   4559 
   4560        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
   4561 
   4562        _object.block_name = in_window.org.pkijs.asn1.DURATION.prototype.block_name.call(this);
   4563 
   4564        return _object;
   4565    };
   4566    //**************************************************************************************
   4567    in_window.org.pkijs.asn1.TIME =
   4568    function()
   4569    {
   4570        in_window.org.pkijs.asn1.UTF8STRING.call(this, arguments[0]);
   4571 
   4572        this.id_block.tag_class = 1; // UNIVERSAL
   4573        this.id_block.tag_number = 14; // TIME
   4574    };
   4575    //**************************************************************************************
   4576    in_window.org.pkijs.asn1.TIME.prototype = new in_window.org.pkijs.asn1.UTF8STRING();
   4577    in_window.org.pkijs.asn1.TIME.constructor = in_window.org.pkijs.asn1.TIME;
   4578    //**************************************************************************************
   4579    in_window.org.pkijs.asn1.TIME.prototype.block_name =
   4580    function()
   4581    {
   4582        /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
   4583 
   4584        return "TIME";
   4585    };
   4586    //**************************************************************************************
   4587    in_window.org.pkijs.asn1.TIME.prototype.toJSON =
   4588    function()
   4589    {
   4590        /// <summary>Convertion for the block to JSON object</summary>
   4591 
   4592        var _object = in_window.org.pkijs.asn1.UTF8STRING.prototype.toJSON.call(this);
   4593 
   4594        _object.block_name = in_window.org.pkijs.asn1.TIME.prototype.block_name.call(this);
   4595 
   4596        return _object;
   4597    };
   4598    //**************************************************************************************
   4599    // #endregion 
   4600    //**************************************************************************************
   4601    // #region Declaration of special ASN.1 schema type CHOICE 
   4602    //**************************************************************************************
   4603    in_window.org.pkijs.asn1.CHOICE =
   4604    function()
   4605    {
   4606        if(arguments[0] instanceof Object)
   4607        {
   4608            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new Array()); // Array of ASN.1 types for make a choice from
   4609            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
   4610        }
   4611    };
   4612    //**************************************************************************************
   4613    // #endregion 
   4614    //**************************************************************************************
   4615    // #region Declaration of special ASN.1 schema type ANY 
   4616    //**************************************************************************************
   4617    in_window.org.pkijs.asn1.ANY =
   4618    function()
   4619    {
   4620        if(arguments[0] instanceof Object)
   4621        {
   4622            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
   4623            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
   4624        }
   4625    };
   4626    //**************************************************************************************
   4627    // #endregion 
   4628    //**************************************************************************************
   4629    // #region Declaration of special ASN.1 schema type REPEATED 
   4630    //**************************************************************************************
   4631    in_window.org.pkijs.asn1.REPEATED =
   4632    function()
   4633    {
   4634        if(arguments[0] instanceof Object)
   4635        {
   4636            this.name = in_window.org.pkijs.getValue(arguments[0], "name", "");
   4637            this.optional = in_window.org.pkijs.getValue(arguments[0], "optional", false);
   4638            this.value = in_window.org.pkijs.getValue(arguments[0], "value", new in_window.org.pkijs.asn1.ANY());
   4639            this.local = in_window.org.pkijs.getValue(arguments[0], "local", false); // Could local or global array to store elements
   4640        }
   4641    };
   4642    //**************************************************************************************
   4643    // #endregion 
   4644    //**************************************************************************************
   4645    // #region Major ASN.1 BER decoding function
   4646    //**************************************************************************************
   4647    function fromBER_raw(input_buffer, input_offset, input_length)
   4648    {
   4649        var incoming_offset = input_offset; // Need to store initial offset since "input_offset" is changing in the function
   4650 
   4651        // #region Local function changing a type for ASN.1 classes 
   4652        function local_change_type(input_object, new_type)
   4653        {
   4654            if(input_object instanceof new_type)
   4655                return input_object;
   4656 
   4657            var new_object = new new_type();
   4658            new_object.id_block = input_object.id_block;
   4659            new_object.len_block = input_object.len_block;
   4660            new_object.warnings = input_object.warnings;
   4661            new_object.value_before_decode = util_copybuf(input_object.value_before_decode);
   4662 
   4663            return new_object;
   4664        }
   4665        // #endregion 
   4666 
   4667        // #region Create a basic ASN.1 type since we need to return errors and warnings from the function 
   4668        var return_object = new in_window.org.pkijs.asn1.ASN1_block();
   4669        // #endregion 
   4670 
   4671        // #region Basic check for parameters 
   4672        if(check_buffer_params(input_buffer, input_offset, input_length) === false)
   4673        {
   4674            return_object.error = "Wrong input parameters";
   4675            return {
   4676                offset: (-1),
   4677                result: return_object
   4678            };
   4679        }
   4680        // #endregion 
   4681 
   4682        // #region Getting Uint8Array from ArrayBuffer 
   4683        var int_buffer = new Uint8Array(input_buffer, input_offset, input_length);
   4684        // #endregion 
   4685 
   4686        // #region Initial checks 
   4687        if(int_buffer.length == 0)
   4688        {
   4689            this.error = "Zero buffer length";
   4690            return {
   4691                offset: (-1),
   4692                result: return_object
   4693            };
   4694        }
   4695        // #endregion 
   4696 
   4697        // #region Decode indentifcation block of ASN.1 BER structure 
   4698        var result_offset = return_object.id_block.fromBER(input_buffer, input_offset, input_length);
   4699        return_object.warnings.concat(return_object.id_block.warnings);
   4700        if(result_offset == (-1))
   4701        {
   4702            return_object.error = return_object.id_block.error;
   4703            return {
   4704                offset: (-1),
   4705                result: return_object
   4706            };
   4707        }
   4708 
   4709        input_offset = result_offset;
   4710        input_length -= return_object.id_block.block_length;
   4711        // #endregion 
   4712 
   4713        // #region Decode length block of ASN.1 BER structure 
   4714        result_offset = return_object.len_block.fromBER(input_buffer, input_offset, input_length);
   4715        return_object.warnings.concat(return_object.len_block.warnings);
   4716        if(result_offset == (-1))
   4717        {
   4718            return_object.error = return_object.len_block.error;
   4719            return {
   4720                offset: (-1),
   4721                result: return_object
   4722            };
   4723        }
   4724 
   4725        input_offset = result_offset;
   4726        input_length -= return_object.len_block.block_length;
   4727        // #endregion 
   4728 
   4729        // #region Check for usign indefinite length form in encoding for primitive types 
   4730        if((return_object.id_block.is_constructed == false) &&
   4731           (return_object.len_block.is_indefinite_form == true))
   4732        {
   4733            return_object.error = new String("Indefinite length form used for primitive encoding form");
   4734            return {
   4735                offset: (-1),
   4736                result: return_object
   4737            };
   4738        }
   4739        // #endregion 
   4740 
   4741        // #region Switch ASN.1 block type 
   4742        var new_asn1_type = in_window.org.pkijs.asn1.ASN1_block;
   4743 
   4744        switch(return_object.id_block.tag_class)
   4745        {
   4746            // #region UNIVERSAL 
   4747            case 1: 
   4748                // #region Check for reserved tag numbers 
   4749                if((return_object.id_block.tag_number >= 37) &&
   4750                   (return_object.id_block.is_hex_only == false))
   4751                {
   4752                    return_object.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard";
   4753                    return {
   4754                        offset: (-1),
   4755                        result: return_object
   4756                    };
   4757                }
   4758                // #endregion 
   4759 
   4760                switch(return_object.id_block.tag_number)
   4761                {
   4762                    // #region EOC type 
   4763                    case 0:
   4764                        // #region Check for EOC type 
   4765                        if((return_object.id_block.is_constructed == true) &&
   4766                           (return_object.len_block.length > 0))
   4767                        {
   4768                            return_object.error = "Type [UNIVERSAL 0] is reserved";
   4769                            return {
   4770                                offset: (-1),
   4771                                result: return_object
   4772                            };
   4773                        }
   4774                        // #endregion 
   4775 
   4776                        new_asn1_type = in_window.org.pkijs.asn1.EOC;
   4777 
   4778                        break;
   4779                        // #endregion 
   4780                    // #region BOOLEAN type 
   4781                    case 1:
   4782                        new_asn1_type = in_window.org.pkijs.asn1.BOOLEAN;
   4783                        break;
   4784                    // #endregion 
   4785                    // #region INTEGER type 
   4786                    case 2:
   4787                        new_asn1_type = in_window.org.pkijs.asn1.INTEGER;
   4788                        break;
   4789                    // #endregion 
   4790                    // #region BITSTRING type 
   4791                    case 3:
   4792                        new_asn1_type = in_window.org.pkijs.asn1.BITSTRING;
   4793                        break;
   4794                    // #endregion 
   4795                    // #region OCTETSTRING type 
   4796                    case 4:
   4797                        new_asn1_type = in_window.org.pkijs.asn1.OCTETSTRING;
   4798                        break;
   4799                    // #endregion 
   4800                    // #region NULL type 
   4801                    case 5:
   4802                        new_asn1_type = in_window.org.pkijs.asn1.NULL;
   4803                        break;
   4804                    // #endregion 
   4805                    // #region OBJECT IDENTIFIER type 
   4806                    case 6:
   4807                        new_asn1_type = in_window.org.pkijs.asn1.OID;
   4808                        break;
   4809                    // #endregion 
   4810                    // #region ENUMERATED type 
   4811                    case 10:
   4812                        new_asn1_type = in_window.org.pkijs.asn1.ENUMERATED;
   4813                        break;
   4814                    // #endregion 
   4815                    // #region UTF8STRING type 
   4816                    case 12:
   4817                        new_asn1_type = in_window.org.pkijs.asn1.UTF8STRING;
   4818                        break;
   4819                    // #endregion 
   4820                    // #region TIME type 
   4821                    case 14:
   4822                        new_asn1_type = in_window.org.pkijs.asn1.TIME;
   4823                        break;
   4824                    // #endregion 
   4825                    // #region ASN.1 reserved type 
   4826                    case 15:
   4827                        return_object.error = "[UNIVERSAL 15] is reserved by ASN.1 standard";
   4828                        return {
   4829                            offset: (-1),
   4830                            result: return_object
   4831                        };
   4832                        break;
   4833                    // #endregion 
   4834                    // #region SEQUENCE type 
   4835                    case 16:
   4836                        new_asn1_type = in_window.org.pkijs.asn1.SEQUENCE;
   4837                        break;
   4838                    // #endregion 
   4839                    // #region SET type 
   4840                    case 17:
   4841                        new_asn1_type = in_window.org.pkijs.asn1.SET;
   4842                        break;
   4843                    // #endregion 
   4844                    // #region NUMERICSTRING type 
   4845                    case 18:
   4846                        new_asn1_type = in_window.org.pkijs.asn1.NUMERICSTRING;
   4847                        break;
   4848                    // #endregion 
   4849                    // #region PRINTABLESTRING type 
   4850                    case 19:
   4851                        new_asn1_type = in_window.org.pkijs.asn1.PRINTABLESTRING;
   4852                        break;
   4853                    // #endregion 
   4854                    // #region TELETEXSTRING type 
   4855                    case 20:
   4856                        new_asn1_type = in_window.org.pkijs.asn1.TELETEXSTRING;
   4857                        break;
   4858                    // #endregion 
   4859                    // #region VIDEOTEXSTRING type 
   4860                    case 21:
   4861                        new_asn1_type = in_window.org.pkijs.asn1.VIDEOTEXSTRING;
   4862                        break;
   4863                    // #endregion 
   4864                    // #region IA5STRING type 
   4865                    case 22:
   4866                        new_asn1_type = in_window.org.pkijs.asn1.IA5STRING;
   4867                        break;
   4868                    // #endregion 
   4869                    // #region UTCTIME type 
   4870                    case 23:
   4871                        new_asn1_type = in_window.org.pkijs.asn1.UTCTIME;
   4872                        break;
   4873                    // #endregion 
   4874                    // #region GENERALIZEDTIME type 
   4875                    case 24:
   4876                        new_asn1_type = in_window.org.pkijs.asn1.GENERALIZEDTIME;
   4877                        break;
   4878                    // #endregion 
   4879                    // #region GRAPHICSTRING type 
   4880                    case 25:
   4881                        new_asn1_type = in_window.org.pkijs.asn1.GRAPHICSTRING;
   4882                        break;
   4883                    // #endregion 
   4884                    // #region VISIBLESTRING type 
   4885                    case 26:
   4886                        new_asn1_type = in_window.org.pkijs.asn1.VISIBLESTRING;
   4887                        break;
   4888                    // #endregion 
   4889                    // #region GENERALSTRING type 
   4890                    case 27:
   4891                        new_asn1_type = in_window.org.pkijs.asn1.GENERALSTRING;
   4892                        break;
   4893                    // #endregion 
   4894                    // #region UNIVERSALSTRING type 
   4895                    case 28:
   4896                        new_asn1_type = in_window.org.pkijs.asn1.UNIVERSALSTRING;
   4897                        break;
   4898                    // #endregion 
   4899                    // #region CHARACTERSTRING type 
   4900                    case 29:
   4901                        new_asn1_type = in_window.org.pkijs.asn1.CHARACTERSTRING;
   4902                        break;
   4903                    // #endregion 
   4904                    // #region BMPSTRING type 
   4905                    case 30:
   4906                        new_asn1_type = in_window.org.pkijs.asn1.BMPSTRING;
   4907                        break;
   4908                    // #endregion 
   4909                    // #region DATE type 
   4910                    case 31:
   4911                        new_asn1_type = in_window.org.pkijs.asn1.DATE;
   4912                        break;
   4913                    // #endregion 
   4914                    // #region TIMEOFDAY type 
   4915                    case 32:
   4916                        new_asn1_type = in_window.org.pkijs.asn1.TIMEOFDAY;
   4917                        break;
   4918                    // #endregion 
   4919                    // #region DATE-TIME type 
   4920                    case 33:
   4921                        new_asn1_type = in_window.org.pkijs.asn1.DATETIME;
   4922                        break;
   4923                    // #endregion 
   4924                    // #region DURATION type 
   4925                    case 34:
   4926                        new_asn1_type = in_window.org.pkijs.asn1.DURATION;
   4927                        break;
   4928                    // #endregion 
   4929                    // #region default 
   4930                    default:
   4931                        {
   4932                            var new_object;
   4933 
   4934                            if(return_object.id_block.is_constructed == true)
   4935                                new_object = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED();
   4936                            else
   4937                                new_object = new in_window.org.pkijs.asn1.ASN1_PRIMITIVE();
   4938 
   4939                            new_object.id_block = return_object.id_block;
   4940                            new_object.len_block = return_object.len_block;
   4941                            new_object.warnings = return_object.warnings;
   4942 
   4943                            return_object = new_object;
   4944 
   4945                            result_offset = return_object.fromBER(input_buffer, input_offset, input_length);
   4946                        }
   4947                    // #endregion 
   4948                }
   4949                break;
   4950            // #endregion 
   4951            // #region All other tag classes 
   4952            case 2: // APPLICATION
   4953            case 3: // CONTEXT-SPECIFIC
   4954            case 4: // PRIVATE
   4955            default:
   4956                {
   4957                    if(return_object.id_block.is_constructed == true)
   4958                        new_asn1_type = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED;
   4959                    else
   4960                        new_asn1_type = in_window.org.pkijs.asn1.ASN1_PRIMITIVE;
   4961                }
   4962            // #endregion 
   4963        }
   4964        // #endregion 
   4965 
   4966        // #region Change type and perform BER decoding 
   4967        return_object = local_change_type(return_object, new_asn1_type);
   4968        result_offset = return_object.fromBER(input_buffer, input_offset, (return_object.len_block.is_indefinite_form == true) ? input_length : return_object.len_block.length);
   4969        // #endregion 
   4970 
   4971        // #region Coping incoming buffer for entire ASN.1 block 
   4972        return_object.value_before_decode = util_copybuf_offset(input_buffer, incoming_offset, return_object.block_length);
   4973        // #endregion 
   4974 
   4975        return {
   4976            offset: result_offset,
   4977            result: return_object
   4978        };
   4979    }
   4980    //**************************************************************************************
   4981    in_window.org.pkijs.fromBER = 
   4982    function(input_buffer)
   4983    {
   4984        /// <summary>Major function for decoding ASN.1 BER array into internal library structuries</summary>
   4985        /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array of bytes</param>
   4986 
   4987        if(input_buffer.byteLength == 0)
   4988        {
   4989            var result = new in_window.org.pkijs.asn1.ASN1_block();
   4990            result.error = "Input buffer has zero length";
   4991 
   4992            return {
   4993                offset: (-1),
   4994                result: result
   4995            };
   4996        }
   4997 
   4998        return fromBER_raw(input_buffer, 0, input_buffer.byteLength);
   4999    };
   5000    //**************************************************************************************
   5001    // #endregion 
   5002    //**************************************************************************************
   5003    // #region Major scheme verification function 
   5004    //**************************************************************************************
   5005    in_window.org.pkijs.compareSchema =
   5006    function(root, input_asn1_data, input_asn1_schema)
   5007    {
   5008        // #region Special case for CHOICE schema element type 
   5009        if(input_asn1_schema instanceof in_window.org.pkijs.asn1.CHOICE)
   5010        {
   5011            var choice_result = false;
   5012 
   5013            for(var j = 0; j < input_asn1_schema.value.length; j++)
   5014            {
   5015                var result = in_window.org.pkijs.compareSchema(root, input_asn1_data, input_asn1_schema.value[j]);
   5016                if(result.verified === true)
   5017                    return {
   5018                        verified: true,
   5019                        result: root
   5020                    };
   5021            }
   5022 
   5023            if(choice_result === false)
   5024            {
   5025                var _result = {
   5026                    verified: false,
   5027                    result: {
   5028                        error: "Wrong values for CHOICE type"
   5029                    }
   5030                };
   5031 
   5032                if(input_asn1_schema.hasOwnProperty('name'))
   5033                    _result.name = input_asn1_schema.name;
   5034 
   5035                return _result;
   5036            }
   5037        }
   5038        // #endregion 
   5039 
   5040        // #region Special case for ANY schema element type 
   5041        if(input_asn1_schema instanceof in_window.org.pkijs.asn1.ANY)
   5042        {
   5043            // #region Add named component of ASN.1 schema 
   5044            if(input_asn1_schema.hasOwnProperty('name'))
   5045                root[input_asn1_schema.name] = input_asn1_data;
   5046            // #endregion 
   5047 
   5048            return {
   5049                verified: true,
   5050                result: root
   5051            };
   5052        }
   5053        // #endregion 
   5054 
   5055        // #region Initial check 
   5056        if((root instanceof Object) === false)
   5057            return {
   5058                verified: false,
   5059                result: { error: "Wrong root object" }
   5060            };
   5061 
   5062        if((input_asn1_data instanceof Object) === false)
   5063            return {
   5064                verified: false,
   5065                result: { error: "Wrong ASN.1 data" }
   5066            };
   5067 
   5068        if((input_asn1_schema instanceof Object) === false)
   5069            return {
   5070                verified: false,
   5071                result: { error: "Wrong ASN.1 schema" }
   5072            };
   5073 
   5074        if(('id_block' in input_asn1_schema) === false)
   5075            return {
   5076                verified: false,
   5077                result: { error: "Wrong ASN.1 schema" }
   5078            };
   5079        // #endregion 
   5080 
   5081        // #region Comparing id_block properties in ASN.1 data and ASN.1 schema 
   5082        // #region Encode and decode ASN.1 schema id_block 
   5083        /// <remarks>This encoding/decoding is neccessary because could be an errors in schema definition</remarks>
   5084        if(('fromBER' in input_asn1_schema.id_block) === false)
   5085            return {
   5086                verified: false,
   5087                result: { error: "Wrong ASN.1 schema" }
   5088            };
   5089 
   5090        if(('toBER' in input_asn1_schema.id_block) === false)
   5091            return {
   5092                verified: false,
   5093                result: { error: "Wrong ASN.1 schema" }
   5094            };
   5095 
   5096        var encoded_id = input_asn1_schema.id_block.toBER(false);
   5097        if(encoded_id.byteLength === 0)
   5098            return {
   5099                verified: false,
   5100                result: { error: "Error encoding id_block for ASN.1 schema" }
   5101            };
   5102 
   5103        var decoded_offset = input_asn1_schema.id_block.fromBER(encoded_id, 0, encoded_id.byteLength);
   5104        if(decoded_offset === (-1))
   5105            return {
   5106                verified: false,
   5107                result: { error: "Error decoding id_block for ASN.1 schema" }
   5108            };
   5109        // #endregion 
   5110 
   5111        // #region tag_class 
   5112        if(input_asn1_schema.id_block.hasOwnProperty('tag_class') === false)
   5113            return {
   5114                verified: false,
   5115                result: { error: "Wrong ASN.1 schema" }
   5116            };
   5117 
   5118        if(input_asn1_schema.id_block.tag_class !== input_asn1_data.id_block.tag_class)
   5119            return {
   5120                verified: false,
   5121                result: root
   5122            };
   5123        // #endregion 
   5124        // #region tag_number 
   5125        if(input_asn1_schema.id_block.hasOwnProperty('tag_number') === false)
   5126            return {
   5127                verified: false,
   5128                result: { error: "Wrong ASN.1 schema" }
   5129            };
   5130 
   5131        if(input_asn1_schema.id_block.tag_number !== input_asn1_data.id_block.tag_number)
   5132            return {
   5133                verified: false,
   5134                result: root
   5135            };
   5136        // #endregion 
   5137        // #region is_constructed 
   5138        if(input_asn1_schema.id_block.hasOwnProperty('is_constructed') === false)
   5139            return {
   5140                verified: false,
   5141                result: { error: "Wrong ASN.1 schema" }
   5142            };
   5143 
   5144        if(input_asn1_schema.id_block.is_constructed !== input_asn1_data.id_block.is_constructed)
   5145            return {
   5146                verified: false,
   5147                result: root
   5148            };
   5149        // #endregion 
   5150        // #region is_hex_only 
   5151        if(('is_hex_only' in input_asn1_schema.id_block) === false) // Since 'is_hex_only' is an inhirited property
   5152            return {
   5153                verified: false,
   5154                result: { error: "Wrong ASN.1 schema" }
   5155            };
   5156 
   5157        if(input_asn1_schema.id_block.is_hex_only !== input_asn1_data.id_block.is_hex_only)
   5158            return {
   5159                verified: false,
   5160                result: root
   5161            };
   5162        // #endregion 
   5163        // #region value_hex 
   5164        if(input_asn1_schema.id_block.is_hex_only === true)
   5165        {
   5166            if(('value_hex' in input_asn1_schema.id_block) === false) // Since 'value_hex' is an inhirited property
   5167                return {
   5168                    verified: false,
   5169                    result: { error: "Wrong ASN.1 schema" }
   5170                };
   5171 
   5172            var schema_view = new Uint8Array(input_asn1_schema.id_block.value_hex);
   5173            var asn1_view = new Uint8Array(input_asn1_data.id_block.value_hex);
   5174 
   5175            if(schema_view.length !== asn1_view.length)
   5176                return {
   5177                    verified: false,
   5178                    result: root
   5179                };
   5180 
   5181            for(var i = 0; i < schema_view.length; i++)
   5182            {
   5183                if(schema_view[i] !== asn1_view[1])
   5184                    return {
   5185                        verified: false,
   5186                        result: root
   5187                    };
   5188            }
   5189        }
   5190        // #endregion 
   5191        // #endregion 
   5192 
   5193        // #region Add named component of ASN.1 schema 
   5194        if(input_asn1_schema.hasOwnProperty('name'))
   5195        {
   5196            input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5197            if(input_asn1_schema.name !== "")
   5198                root[input_asn1_schema.name] = input_asn1_data;
   5199        }
   5200        // #endregion 
   5201 
   5202        // #region Getting next ASN.1 block for comparition 
   5203        if(input_asn1_schema.id_block.is_constructed === true)
   5204        {
   5205            var admission = 0;
   5206            var result = { verified: false };
   5207 
   5208            var max_length = input_asn1_schema.value_block.value.length;
   5209 
   5210            if(max_length > 0)
   5211            {
   5212                if(input_asn1_schema.value_block.value[0] instanceof in_window.org.pkijs.asn1.REPEATED)
   5213                    max_length = input_asn1_data.value_block.value.length;
   5214            }
   5215 
   5216            // #region Special case when constructive value has no elements 
   5217            if(max_length === 0)
   5218                return {
   5219                    verified: true,
   5220                    result: root
   5221                };
   5222            // #endregion 
   5223 
   5224            // #region Special case when "input_asn1_data" has no values and "input_asn1_schema" has all optional values
   5225            if((input_asn1_data.value_block.value.length === 0) && 
   5226               (input_asn1_schema.value_block.value.length !== 0))
   5227            {
   5228                var _optional = true;
   5229 
   5230                for(var i = 0; i < input_asn1_schema.value_block.value.length; i++)
   5231                    _optional = _optional && (input_asn1_schema.value_block.value[i].optional || false);
   5232 
   5233                if(_optional === true)
   5234                {
   5235                    return {
   5236                        verified: true,
   5237                        result: root
   5238                    };
   5239                }
   5240                else
   5241                {
   5242                    // #region Delete early added name of block 
   5243                    if(input_asn1_schema.hasOwnProperty('name'))
   5244                    {
   5245                        input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5246                        if(input_asn1_schema.name !== "")
   5247                            delete root[input_asn1_schema.name];
   5248                    }
   5249                    // #endregion 
   5250 
   5251                    root.error = "Inconsistent object length";
   5252 
   5253                    return {
   5254                        verified: false,
   5255                        result: root
   5256                    };
   5257                }
   5258            }
   5259            // #endregion 
   5260 
   5261            for(var i = 0; i < max_length; i++)
   5262            {
   5263                // #region Special case when there is an "optional" element of ASN.1 schema at the end 
   5264                if((i - admission) >= input_asn1_data.value_block.value.length)
   5265                {
   5266                    if(input_asn1_schema.value_block.value[i].optional === false)
   5267                    {
   5268                        var _result = {
   5269                            verified: false,
   5270                            result: root
   5271                        };
   5272 
   5273                        root.error = "Inconsistent length between ASN.1 data and schema";
   5274 
   5275                        // #region Delete early added name of block 
   5276                        if(input_asn1_schema.hasOwnProperty('name'))
   5277                        {
   5278                            input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5279                            if(input_asn1_schema.name !== "")
   5280                            {
   5281                                delete root[input_asn1_schema.name];
   5282                                _result.name = input_asn1_schema.name;
   5283                            }
   5284                        }
   5285                        // #endregion 
   5286 
   5287                        return _result;
   5288                    }
   5289                }
   5290                    // #endregion 
   5291                else
   5292                {
   5293                    // #region Special case for REPEATED type of ASN.1 schema element 
   5294                    if(input_asn1_schema.value_block.value[0] instanceof in_window.org.pkijs.asn1.REPEATED)
   5295                    {
   5296                        result = in_window.org.pkijs.compareSchema(root, input_asn1_data.value_block.value[i], input_asn1_schema.value_block.value[0].value);
   5297                        if(result.verified === false)
   5298                        {
   5299                            if(input_asn1_schema.value_block.value[0].optional === true)
   5300                                admission++;
   5301                            else
   5302                            {
   5303                                // #region Delete early added name of block 
   5304                                if(input_asn1_schema.hasOwnProperty('name'))
   5305                                {
   5306                                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5307                                    if(input_asn1_schema.name !== "")
   5308                                        delete root[input_asn1_schema.name];
   5309                                }
   5310                                // #endregion 
   5311 
   5312                                return result;
   5313                            }
   5314                        }
   5315 
   5316                        if(("name" in input_asn1_schema.value_block.value[0]) && (input_asn1_schema.value_block.value[0].name.length > 0))
   5317                        {
   5318                            var array_root = {};
   5319 
   5320                            if(("local" in input_asn1_schema.value_block.value[0]) && (input_asn1_schema.value_block.value[0].local === true))
   5321                                array_root = input_asn1_data;
   5322                            else
   5323                                array_root = root;
   5324 
   5325                            if(typeof array_root[input_asn1_schema.value_block.value[0].name] === "undefined")
   5326                                array_root[input_asn1_schema.value_block.value[0].name] = new Array();
   5327 
   5328                            array_root[input_asn1_schema.value_block.value[0].name].push(input_asn1_data.value_block.value[i]);
   5329                        }
   5330                    }
   5331                        // #endregion 
   5332                    else
   5333                    {
   5334                        result = in_window.org.pkijs.compareSchema(root, input_asn1_data.value_block.value[i - admission], input_asn1_schema.value_block.value[i]);
   5335                        if(result.verified === false)
   5336                        {
   5337                            if(input_asn1_schema.value_block.value[i].optional === true)
   5338                                admission++;
   5339                            else
   5340                            {
   5341                                // #region Delete early added name of block 
   5342                                if(input_asn1_schema.hasOwnProperty('name'))
   5343                                {
   5344                                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5345                                    if(input_asn1_schema.name !== "")
   5346                                        delete root[input_asn1_schema.name];
   5347                                }
   5348                                // #endregion 
   5349 
   5350                                return result;
   5351                            }
   5352                        }
   5353                    }
   5354                }
   5355            }
   5356 
   5357            if(result.verified === false) // The situation may take place if last element is "optional" and verification failed
   5358            {
   5359                var _result = {
   5360                    verified: false,
   5361                    result: root
   5362                };
   5363 
   5364                // #region Delete early added name of block 
   5365                if(input_asn1_schema.hasOwnProperty('name'))
   5366                {
   5367                    input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5368                    if(input_asn1_schema.name !== "")
   5369                    {
   5370                        delete root[input_asn1_schema.name];
   5371                        _result.name = input_asn1_schema.name;
   5372                    }
   5373                }
   5374                // #endregion 
   5375 
   5376                return _result;
   5377            }
   5378 
   5379            return {
   5380                verified: true,
   5381                result: root
   5382            };
   5383        }
   5384        // #endregion 
   5385        // #region Ability to parse internal value for primitive-encoded value (value of OCTETSTRING, for example)
   5386        else
   5387        {
   5388            if( ("primitive_schema" in input_asn1_schema) &&
   5389                ("value_hex" in input_asn1_data.value_block) )
   5390            {
   5391                // #region Decoding of raw ASN.1 data 
   5392                var asn1 = in_window.org.pkijs.fromBER(input_asn1_data.value_block.value_hex);
   5393                if(asn1.offset === (-1))
   5394                {
   5395                    var _result = {
   5396                        verified: false,
   5397                        result: asn1.result
   5398                    };
   5399 
   5400                    // #region Delete early added name of block 
   5401                    if(input_asn1_schema.hasOwnProperty('name'))
   5402                    {
   5403                        input_asn1_schema.name = input_asn1_schema.name.replace(/^\s+|\s+$/g, '');
   5404                        if(input_asn1_schema.name !== "")
   5405                        {
   5406                            delete root[input_asn1_schema.name];
   5407                            _result.name = input_asn1_schema.name;
   5408                        }
   5409                    }
   5410                    // #endregion 
   5411 
   5412                    return _result;
   5413                }
   5414                // #endregion 
   5415 
   5416                return in_window.org.pkijs.compareSchema(root, asn1.result, input_asn1_schema.primitive_schema);
   5417            }
   5418            else
   5419                return {
   5420                    verified: true,
   5421                    result: root
   5422                };
   5423        }
   5424        // #endregion 
   5425    };
   5426    //**************************************************************************************
   5427    in_window.org.pkijs.verifySchema =
   5428    function(input_buffer, input_schema)
   5429    {
   5430        // #region Initial check 
   5431        if((input_schema instanceof Object) === false)
   5432            return {
   5433                verified: false,
   5434                result: { error: "Wrong ASN.1 schema type" }
   5435            };
   5436        // #endregion 
   5437 
   5438        // #region Decoding of raw ASN.1 data 
   5439        var asn1 = in_window.org.pkijs.fromBER(input_buffer);
   5440        if(asn1.offset === (-1))
   5441            return {
   5442                verified: false,
   5443                result: asn1.result
   5444            };
   5445        // #endregion 
   5446 
   5447        // #region Compare ASN.1 struct with input schema 
   5448        return in_window.org.pkijs.compareSchema(asn1.result, asn1.result, input_schema);
   5449        // #endregion 
   5450    };
   5451    //**************************************************************************************
   5452    // #endregion 
   5453    //**************************************************************************************
   5454    // #region Major function converting JSON to ASN.1 objects 
   5455    //**************************************************************************************
   5456    in_window.org.pkijs.fromJSON = 
   5457    function(json)
   5458    {
   5459        /// <summary>Converting from JSON to ASN.1 objects</summary>
   5460        /// <param name="json" type="String|Object">JSON string or object to convert to ASN.1 objects</param>
   5461    };
   5462    //**************************************************************************************
   5463    // #endregion 
   5464    //**************************************************************************************
   5465 }
   5466 )(typeof exports !== "undefined" ? exports : window);