tor-browser

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

x509_simpl.js (307934B)


      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.simpl" namespace 
     61    if(typeof in_window.org.pkijs.simpl === "undefined")
     62        in_window.org.pkijs.simpl = {};
     63    else
     64    {
     65        if(typeof in_window.org.pkijs.simpl !== "object")
     66            throw new Error("Name org.pkijs.simpl already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl));
     67    }
     68    // #endregion 
     69 
     70    // #region "org.pkijs.simpl.x509" namespace 
     71    if(typeof in_window.org.pkijs.simpl.x509 === "undefined")
     72        in_window.org.pkijs.simpl.x509 = {};
     73    else
     74    {
     75        if(typeof in_window.org.pkijs.simpl.x509 !== "object")
     76            throw new Error("Name org.pkijs.simpl.x509 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl.x509));
     77    }
     78    // #endregion 
     79 
     80    // #region "local" namespace 
     81    var local = {};
     82    // #endregion   
     83    //**************************************************************************************
     84    // #endregion 
     85    //**************************************************************************************
     86    // #region Simplified structure for "Time" type
     87    //**************************************************************************************
     88    in_window.org.pkijs.simpl.TIME =
     89    function()
     90    {
     91        // #region Internal properties of the object 
     92        this.type = 0; // 0 - UTCTime; 1 - GeneralizedTime; 2 - empty value
     93        this.value = new Date(0, 0, 0);
     94        // #endregion 
     95 
     96        // #region If input argument array contains "schema" for this object 
     97        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
     98            in_window.org.pkijs.simpl.TIME.prototype.fromSchema.call(this, arguments[0].schema);
     99        // #endregion 
    100        // #region If input argument array contains "native" values for internal properties 
    101        else
    102        {
    103            if(arguments[0] instanceof Object)
    104            {
    105                this.type = (arguments[0].type || 0);
    106                this.value = (arguments[0].value || (new Date(0, 0, 0)));
    107            }
    108        }
    109        // #endregion 
    110    };
    111    //**************************************************************************************
    112    in_window.org.pkijs.simpl.TIME.prototype.fromSchema =
    113    function(schema)
    114    {
    115        // #region Check the schema is valid 
    116        var asn1 = in_window.org.pkijs.compareSchema(schema,
    117            schema,
    118            in_window.org.pkijs.schema.TIME({
    119                names: {
    120                    utcTimeName: "utcTimeName",
    121                    generalTimeName: "generalTimeName"
    122                }
    123            })
    124            );
    125 
    126        if(asn1.verified === false)
    127            throw new Error("Object's schema was not verified against input data for TIME");
    128        // #endregion 
    129 
    130        // #region Get internal properties from parsed schema 
    131        if("utcTimeName" in asn1.result)
    132        {
    133            this.type = 0;
    134            this.value = asn1.result.utcTimeName.toDate();
    135        }
    136        if("generalTimeName" in asn1.result)
    137        {
    138            this.type = 1;
    139            this.value = asn1.result.generalTimeName.toDate();
    140        }
    141        // #endregion 
    142    };
    143    //**************************************************************************************
    144    in_window.org.pkijs.simpl.TIME.prototype.toSchema =
    145    function()
    146    {
    147        // #region Construct and return new ASN.1 schema for this object 
    148        var result = {};
    149 
    150        if(this.type === 0)
    151            result = new in_window.org.pkijs.asn1.UTCTIME({ value_date: this.value });
    152        if(this.type === 1)
    153            result = new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.value });
    154 
    155        return result;
    156        // #endregion 
    157    };
    158    //**************************************************************************************
    159    in_window.org.pkijs.simpl.TIME.prototype.toJSON =
    160    function()
    161    {
    162        return {
    163            type: this.type,
    164            value: this.value
    165        };
    166    };
    167    //**************************************************************************************
    168    // #endregion 
    169    //**************************************************************************************
    170    // #region Simplified structure for "GeneralName" type 
    171    //**************************************************************************************
    172    in_window.org.pkijs.simpl.GENERAL_NAME =
    173    function()
    174    {
    175        // #region Internal properties of the object 
    176        this.NameType = 9; // Name type - from a tagged value (0 for "otherName", 1 for "rfc822Name" etc.)
    177        this.Name = {};
    178        // #endregion 
    179 
    180        // #region If input argument array contains "schema" for this object 
    181        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    182            in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema.call(this, arguments[0].schema);
    183        // #endregion 
    184        // #region If input argument array contains "native" values for internal properties 
    185        else
    186        {
    187            if(arguments[0] instanceof Object)
    188            {
    189                this.NameType = arguments[0].NameType || 9;
    190                this.Name = arguments[0].Name || {};
    191            }
    192        }
    193        // #endregion 
    194    };
    195    //**************************************************************************************
    196    in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema =
    197    function(schema)
    198    {
    199        // #region Check the schema is valid 
    200        var asn1 = in_window.org.pkijs.compareSchema(schema,
    201            schema,
    202            in_window.org.pkijs.schema.GENERAL_NAME({
    203                names: {
    204                    block_name: "block_name",
    205                    otherName: "otherName",
    206                    rfc822Name: "rfc822Name",
    207                    dNSName: "dNSName",
    208                    x400Address: "x400Address",
    209                    directoryName: {
    210                            names: {
    211                                block_name: "directoryName"
    212                            }
    213                        },
    214                    ediPartyName: "ediPartyName",
    215                    uniformResourceIdentifier: "uniformResourceIdentifier",
    216                    iPAddress: "iPAddress",
    217                    registeredID: "registeredID"
    218                }
    219            })
    220            );
    221 
    222        if(asn1.verified === false)
    223            throw new Error("Object's schema was not verified against input data for GENERAL_NAME");
    224        // #endregion 
    225 
    226        // #region Get internal properties from parsed schema
    227        this.NameType = asn1.result["block_name"].id_block.tag_number;
    228 
    229        switch(this.NameType)
    230        {
    231            case 0: // otherName
    232                this.Name = asn1.result["block_name"];
    233                break;
    234            case 1: // rfc822Name + dNSName + uniformResourceIdentifier
    235            case 2:
    236            case 6:
    237                {
    238                    var value = asn1.result["block_name"];
    239 
    240                    value.id_block.tag_class = 1; // UNIVERSAL
    241                    value.id_block.tag_number = 22; // IA5STRING
    242 
    243                    var value_ber = value.toBER(false);
    244 
    245                    this.Name = in_window.org.pkijs.fromBER(value_ber).result.value_block.value;
    246                }
    247                break;
    248            case 3: // x400Address
    249                this.Name = asn1.result["block_name"];
    250                break;
    251            case 4: // directoryName
    252                this.Name = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["directoryName"] });
    253                break;
    254            case 5: // ediPartyName
    255                this.Name = asn1.result["ediPartyName"];
    256                break;
    257            case 7: // iPAddress
    258                this.Name = new in_window.org.pkijs.asn1.OCTETSTRING({ value_hex: asn1.result["block_name"].value_block.value_hex });
    259                break;
    260            case 8: // registeredID
    261                {
    262                    var value = asn1.result["block_name"];
    263 
    264                    value.id_block.tag_class = 1; // UNIVERSAL
    265                    value.id_block.tag_number = 6; // OID
    266 
    267                    var value_ber = value.toBER(false);
    268 
    269                    this.Name = in_window.org.pkijs.fromBER(value_ber).result.value_block.toString(); // Getting a string representation of the OID
    270                }
    271                break;
    272            default:
    273        }
    274        // #endregion 
    275    };
    276    //**************************************************************************************
    277    in_window.org.pkijs.simpl.GENERAL_NAME.prototype.toSchema =
    278    function(schema)
    279    {
    280        // #region Construct and return new ASN.1 schema for this object
    281        switch(this.NameType)
    282        {
    283            case 0:
    284            case 3:
    285            case 5:
    286                return new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    287                    id_block: {
    288                        tag_class: 3, // CONTEXT-SPECIFIC
    289                        tag_number: this.NameType
    290                    },
    291                    value: [
    292                        this.Name
    293                    ]
    294                });
    295 
    296                break;
    297            case 1:
    298            case 2:
    299            case 6:
    300                {
    301                    var value = new in_window.org.pkijs.asn1.IA5STRING({ value: this.Name });
    302 
    303                    value.id_block.tag_class = 3;
    304                    value.id_block.tag_number = this.NameType;
    305 
    306                    return value;
    307                }
    308                break;
    309            case 4:
    310                return new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    311                    id_block: {
    312                        tag_class: 3, // CONTEXT-SPECIFIC
    313                        tag_number: 4
    314                    },
    315                    value: [this.Name.toSchema()]
    316                });
    317                break;
    318            case 7:
    319                {
    320                    var value = this.Name;
    321 
    322                    value.id_block.tag_class = 3;
    323                    value.id_block.tag_number = this.NameType;
    324 
    325                    return value;
    326                }
    327                break;
    328            case 8:
    329                {
    330                    var value = new in_window.org.pkijs.asn1.OID({ value: this.Name });
    331 
    332                    value.id_block.tag_class = 3;
    333                    value.id_block.tag_number = this.NameType;
    334 
    335                    return value;
    336                }
    337                break;
    338            default:
    339                return in_window.org.pkijs.schema.GENERAL_NAME();
    340        }
    341        // #endregion 
    342    };
    343    //**************************************************************************************
    344    in_window.org.pkijs.simpl.GENERAL_NAME.prototype.toJSON =
    345    function()
    346    {
    347        var _object = {
    348            NameType: this.NameType
    349        };
    350 
    351        if((typeof this.Name) === "string")
    352            _object.Name = this.Name;
    353        else
    354            _object.Name = this.Name.toJSON();
    355 
    356        return _object;
    357    };
    358    //**************************************************************************************
    359    // #endregion 
    360    //**************************************************************************************
    361    // #region Simplified structure for "GeneralNames" type 
    362    //**************************************************************************************
    363    in_window.org.pkijs.simpl.GENERAL_NAMES =
    364    function()
    365    {
    366        // #region Internal properties of the object 
    367        this.names = new Array(); // Array of "org.pkijs.simpl.GENERAL_NAME"
    368        // #endregion 
    369 
    370        // #region If input argument array contains "schema" for this object 
    371        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    372            in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.fromSchema.call(this, arguments[0].schema);
    373        // #endregion 
    374        // #region If input argument array contains "native" values for internal properties 
    375        else
    376        {
    377            if(arguments[0] instanceof Object)
    378            {
    379                this.names = arguments[0].names || new Array(); // Array of "org.pkijs.simpl.GENERAL_NAME"
    380            }
    381        }
    382        // #endregion 
    383    };
    384    //**************************************************************************************
    385    in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.fromSchema =
    386    function(schema)
    387    {
    388        // #region Check the schema is valid 
    389        var asn1 = in_window.org.pkijs.compareSchema(schema,
    390            schema,
    391            new in_window.org.pkijs.asn1.SEQUENCE({
    392                value: [
    393                    new in_window.org.pkijs.asn1.REPEATED({
    394                        name: "names",
    395                        value: in_window.org.pkijs.schema.GENERAL_NAME()
    396                    })
    397                ]
    398            })
    399            );
    400 
    401        if(asn1.verified === false)
    402            throw new Error("Object's schema was not verified against input data for GENERAL_NAMES");
    403        // #endregion 
    404 
    405        // #region Get internal properties from parsed schema
    406        var n = asn1.result["names"];
    407 
    408        for(var i = 0; i < n.length; i++)
    409            this.names.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: n[i] }));
    410        // #endregion 
    411    };
    412    //**************************************************************************************
    413    in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.toSchema =
    414    function(schema)
    415    {
    416        // #region Construct and return new ASN.1 schema for this object
    417        var output_array = new Array();
    418 
    419        for(var i = 0; i < this.names.length; i++)
    420            output_array.push(this.names[i].toSchema());
    421 
    422        return (new in_window.org.pkijs.asn1.SEQUENCE({
    423            value: output_array
    424        }));
    425        // #endregion 
    426    };
    427    //**************************************************************************************
    428    in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.toJSON =
    429    function()
    430    {
    431        var _names = new Array();
    432 
    433        for(var i = 0; i < this.names.length; i++)
    434            _names.push(this.names[i].toJSON());
    435 
    436        return {
    437            names: _names
    438        };
    439    };
    440    //**************************************************************************************
    441    // #endregion 
    442    //**************************************************************************************
    443    // #region Simplified structure for "AlgorithmIdentifier" type 
    444    //**************************************************************************************
    445    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER =
    446    function()
    447    {
    448        // #region Internal properties of the object 
    449        this.algorithm_id = "";
    450        // OPTIONAL this.algorithm_params = new in_window.org.pkijs.asn1.NULL();
    451        // #endregion 
    452 
    453        // #region If input argument array contains "schema" for this object 
    454        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    455            in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.fromSchema.call(this, arguments[0].schema);
    456        // #endregion 
    457        // #region If input argument array contains "native" values for internal properties 
    458        else
    459        {
    460            if(arguments[0] instanceof Object)
    461            {
    462                this.algorithm_id = arguments[0].algorithm_id || "";
    463                if("algorithm_params" in arguments[0])
    464                    this.algorithm_params = arguments[0].algorithm_params;
    465            }
    466        }
    467        // #endregion 
    468    };
    469    //**************************************************************************************
    470    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.fromSchema =
    471    function(schema)
    472    {
    473        // #region Check the schema is valid 
    474        var asn1 = in_window.org.pkijs.compareSchema(schema,
    475            schema,
    476            in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER({ 
    477                names: {
    478                    algorithmIdentifier: "algorithm",
    479                    algorithmParams: "params"
    480                }
    481                })
    482            );
    483 
    484        if(asn1.verified === false)
    485            throw new Error("Object's schema was not verified against input data for ALGORITHM_IDENTIFIER");
    486        // #endregion 
    487 
    488        // #region Get internal properties from parsed schema 
    489        this.algorithm_id = asn1.result.algorithm.value_block.toString();
    490        if("params" in asn1.result)
    491            this.algorithm_params = asn1.result.params;
    492        // #endregion 
    493    };
    494    //**************************************************************************************
    495    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.toSchema =
    496    function()
    497    {
    498        // #region Create array for output sequence 
    499        var output_array = new Array();
    500 
    501        output_array.push(new in_window.org.pkijs.asn1.OID({ value: this.algorithm_id }));
    502        if("algorithm_params" in this)
    503            output_array.push(this.algorithm_params);
    504        // #endregion 
    505 
    506        // #region Construct and return new ASN.1 schema for this object 
    507        return (new in_window.org.pkijs.asn1.SEQUENCE({
    508            value: output_array
    509        }));
    510        // #endregion 
    511    };
    512    //**************************************************************************************
    513    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.getCommonName =
    514    function()
    515    {
    516    };
    517    //**************************************************************************************
    518    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.toJSON =
    519    function()
    520    {
    521        var _object = {
    522            algorithm_id: this.algorithm_id
    523        };
    524 
    525        if("algorithm_params" in this)
    526            _object.algorithm_params = this.algorithm_params.toJSON();
    527 
    528        return _object;
    529    };
    530    //**************************************************************************************
    531    in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.isEqual =
    532    function(algorithmIdentifier)
    533    {
    534        /// <summary>Check that two "ALGORITHM_IDENTIFIERs" are equal</summary>
    535        /// <param name="algorithmIdentifier" type="in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER">The algorithm identifier to compare with</param>
    536 
    537        // #region Check input type 
    538        if((algorithmIdentifier instanceof in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER) == false)
    539            return false;
    540        // #endregion 
    541 
    542        // #region Check "algorithm_id" 
    543        if(this.algorithm_id != algorithmIdentifier.algorithm_id)
    544            return false;
    545        // #endregion 
    546 
    547        // #region Check "algorithm_params" 
    548        if("algorithm_params" in this)
    549        {
    550            if("algorithm_params" in algorithmIdentifier)
    551            {
    552                return JSON.stringify(this.algorithm_params) == JSON.stringify(algorithmIdentifier.algorithm_params);
    553            }
    554            else
    555                return false;
    556        }
    557        else
    558        {
    559            if("algorithm_params" in algorithmIdentifier)
    560                return false;
    561        }
    562        // #endregion 
    563 
    564        return true;
    565    };
    566    //**************************************************************************************
    567    // #endregion 
    568    //**************************************************************************************
    569    // #region Simplified structure for "RSAPublicKey" type (RFC3447)
    570    //**************************************************************************************
    571    in_window.org.pkijs.simpl.x509.RSAPublicKey =
    572    function()
    573    {
    574        // #region Internal properties of the object 
    575        this.modulus = new in_window.org.pkijs.asn1.INTEGER();
    576        this.publicExponent = new in_window.org.pkijs.asn1.INTEGER();
    577        // #endregion 
    578 
    579        // #region If input argument array contains "schema" for this object 
    580        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    581            in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.fromSchema.call(this, arguments[0].schema);
    582        // #endregion 
    583        // #region If input argument array contains "native" values for internal properties 
    584        else
    585        {
    586            if(arguments[0] instanceof Object)
    587            {
    588                this.modulus = arguments[0].modulus || new in_window.org.pkijs.asn1.INTEGER();
    589                this.publicExponent = arguments[0].publicExponent || new in_window.org.pkijs.asn1.INTEGER();
    590            }
    591        }
    592        // #endregion 
    593    };
    594    //**************************************************************************************
    595    in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.fromSchema =
    596    function(schema)
    597    {
    598        // #region Check the schema is valid 
    599        var asn1 = in_window.org.pkijs.compareSchema(schema,
    600            schema,
    601            in_window.org.pkijs.schema.x509.RSAPublicKey({
    602                names: {
    603                    modulus: "modulus",
    604                    publicExponent: "publicExponent"
    605                }
    606            })
    607            );
    608 
    609        if(asn1.verified === false)
    610            throw new Error("Object's schema was not verified against input data for RSAPublicKey");
    611        // #endregion 
    612 
    613        // #region Get internal properties from parsed schema 
    614        this.modulus = asn1.result["modulus"];
    615        this.publicExponent = asn1.result["publicExponent"];
    616        // #endregion 
    617    };
    618    //**************************************************************************************
    619    in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.toSchema =
    620    function()
    621    {
    622        // #region Construct and return new ASN.1 schema for this object 
    623        return (new in_window.org.pkijs.asn1.SEQUENCE({
    624            value: [
    625                this.modulus,
    626                this.publicExponent
    627            ]
    628        }));
    629        // #endregion 
    630    };
    631    //**************************************************************************************
    632    in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.toJSON =
    633    function()
    634    {
    635        return {
    636            modulus: this.modulus.toJSON(),
    637            publicExponent: this.publicExponent.toJSON()
    638        };
    639    };
    640    //**************************************************************************************
    641    // #endregion 
    642    //**************************************************************************************
    643    // #region Simplified structure for "OtherPrimeInfo" type (RFC3447)
    644    //**************************************************************************************
    645    in_window.org.pkijs.simpl.x509.OtherPrimeInfo =
    646    function()
    647    {
    648        // #region Internal properties of the object 
    649        this.prime = new in_window.org.pkijs.asn1.INTEGER();
    650        this.exponent = new in_window.org.pkijs.asn1.INTEGER();
    651        this.coefficient = new in_window.org.pkijs.asn1.INTEGER();
    652        // #endregion 
    653 
    654        // #region If input argument array contains "schema" for this object 
    655        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    656            in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.fromSchema.call(this, arguments[0].schema);
    657        // #endregion 
    658        // #region If input argument array contains "native" values for internal properties 
    659        else
    660        {
    661            if(arguments[0] instanceof Object)
    662            {
    663                this.prime = arguments[0].prime || new in_window.org.pkijs.asn1.INTEGER();
    664                this.exponent = arguments[0].exponent || new in_window.org.pkijs.asn1.INTEGER();
    665                this.coefficient = arguments[0].coefficient || new in_window.org.pkijs.asn1.INTEGER();
    666            }
    667        }
    668        // #endregion 
    669    };
    670    //**************************************************************************************
    671    in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.fromSchema =
    672    function(schema)
    673    {
    674        // #region Check the schema is valid 
    675        var asn1 = in_window.org.pkijs.compareSchema(schema,
    676            schema,
    677            in_window.org.pkijs.schema.x509.OtherPrimeInfo({
    678                names: {
    679                    prime: "prime",
    680                    exponent: "exponent",
    681                    coefficient: "coefficient"
    682                }
    683            })
    684            );
    685 
    686        if(asn1.verified === false)
    687            throw new Error("Object's schema was not verified against input data for OtherPrimeInfo");
    688        // #endregion 
    689 
    690        // #region Get internal properties from parsed schema 
    691        this.prime = asn1.result["prime"];
    692        this.exponent = asn1.result["exponent"];
    693        this.coefficient = asn1.result["coefficient"];
    694        // #endregion 
    695    };
    696    //**************************************************************************************
    697    in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.toSchema =
    698    function()
    699    {
    700        // #region Construct and return new ASN.1 schema for this object 
    701        return (new in_window.org.pkijs.asn1.SEQUENCE({
    702            value: [
    703                this.prime,
    704                this.exponent,
    705                this.coefficient
    706            ]
    707        }));
    708        // #endregion 
    709    };
    710    //**************************************************************************************
    711    in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.toJSON =
    712    function()
    713    {
    714        return {
    715            prime: this.prime.toJSON(),
    716            exponent: this.exponent.toJSON(),
    717            coefficient: this.coefficient.toJSON()
    718        };
    719    };
    720    //**************************************************************************************
    721    // #endregion 
    722    //**************************************************************************************
    723    // #region Simplified structure for "RSAPrivateKey" type (RFC3447)
    724    //**************************************************************************************
    725    in_window.org.pkijs.simpl.x509.RSAPrivateKey =
    726    function()
    727    {
    728        // #region Internal properties of the object 
    729        this.version = 0;
    730        this.modulus = new in_window.org.pkijs.asn1.INTEGER();
    731        this.publicExponent = new in_window.org.pkijs.asn1.INTEGER();
    732        this.privateExponent = new in_window.org.pkijs.asn1.INTEGER();
    733        this.prime1 = new in_window.org.pkijs.asn1.INTEGER();
    734        this.prime2 = new in_window.org.pkijs.asn1.INTEGER();
    735        this.exponent1 = new in_window.org.pkijs.asn1.INTEGER();
    736        this.exponent2 = new in_window.org.pkijs.asn1.INTEGER();
    737        this.coefficient = new in_window.org.pkijs.asn1.INTEGER();
    738        // OPTIONAL this.otherPrimeInfos = new Array(); // Array of "OtherPrimeInfo"
    739        // #endregion 
    740 
    741        // #region If input argument array contains "schema" for this object 
    742        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    743            in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.fromSchema.call(this, arguments[0].schema);
    744        // #endregion 
    745        // #region If input argument array contains "native" values for internal properties 
    746        else
    747        {
    748            if(arguments[0] instanceof Object)
    749            {
    750                this.version = arguments[0].version || 0;
    751                this.modulus = arguments[0].modulus || new in_window.org.pkijs.asn1.INTEGER();
    752                this.publicExponent = arguments[0].publicExponent || new in_window.org.pkijs.asn1.INTEGER();
    753                this.privateExponent = arguments[0].privateExponent || new in_window.org.pkijs.asn1.INTEGER();
    754                this.prime1 = arguments[0].prime1 || new in_window.org.pkijs.asn1.INTEGER();
    755                this.prime2 = arguments[0].prime2 || new in_window.org.pkijs.asn1.INTEGER();
    756                this.exponent1 = arguments[0].exponent1 || new in_window.org.pkijs.asn1.INTEGER();
    757                this.exponent2 = arguments[0].exponent2 || new in_window.org.pkijs.asn1.INTEGER();
    758                this.coefficient = arguments[0].coefficient || new in_window.org.pkijs.asn1.INTEGER();
    759                if("otherPrimeInfos" in arguments[0])
    760                    this.otherPrimeInfos = arguments[0].otherPrimeInfos || new Array();
    761            }
    762        }
    763        // #endregion 
    764    };
    765    //**************************************************************************************
    766    in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.fromSchema =
    767    function(schema)
    768    {
    769        // #region Check the schema is valid 
    770        var asn1 = in_window.org.pkijs.compareSchema(schema,
    771            schema,
    772            in_window.org.pkijs.schema.x509.RSAPrivateKey({
    773                names: {
    774                    version: "version",
    775                    modulus: "modulus",
    776                    publicExponent: "publicExponent",
    777                    privateExponent: "privateExponent",
    778                    prime1: "prime1",
    779                    prime2: "prime2",
    780                    exponent1: "exponent1",
    781                    exponent2: "exponent2",
    782                    coefficient: "coefficient",
    783                    otherPrimeInfos: "otherPrimeInfos"
    784                }
    785            })
    786            );
    787 
    788        if(asn1.verified === false)
    789            throw new Error("Object's schema was not verified against input data for RSAPrivateKey");
    790        // #endregion 
    791 
    792        // #region Get internal properties from parsed schema 
    793        this.version = asn1.result["version"].value_block.value_dec;
    794        this.modulus = asn1.result["modulus"];
    795        this.publicExponent = asn1.result["publicExponent"];
    796        this.privateExponent = asn1.result["privateExponent"];
    797        this.prime1 = asn1.result["prime1"];
    798        this.prime2 = asn1.result["prime2"];
    799        this.exponent1 = asn1.result["exponent1"];
    800        this.exponent2 = asn1.result["exponent2"];
    801        this.coefficient = asn1.result["coefficient"];
    802 
    803        if("otherPrimeInfos" in asn1.result)
    804        {
    805            var otherPrimeInfos_array = asn1.result["otherPrimeInfos"];
    806 
    807            for(var i = 0; i < otherPrimeInfos_array.length; i++)
    808                this.otherPrimeInfos.push(new in_window.org.pkijs.simpl.x509.OtherPrimeInfo({ schema: otherPrimeInfos_array[i] }));
    809        }
    810        // #endregion 
    811    };
    812    //**************************************************************************************
    813    in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.toSchema =
    814    function()
    815    {
    816        // #region Create array for output sequence 
    817        var output_array = new Array();
    818 
    819        output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.version }));
    820        output_array.push(this.modulus);
    821        output_array.push(this.publicExponent);
    822        output_array.push(this.privateExponent);
    823        output_array.push(this.prime1);
    824        output_array.push(this.prime2);
    825        output_array.push(this.exponent1);
    826        output_array.push(this.exponent2);
    827        output_array.push(this.coefficient);
    828 
    829        if("otherPrimeInfos" in this)
    830        {
    831            var otherPrimeInfos_array = new Array();
    832 
    833            for(var i = 0; i < this.otherPrimeInfos.length; i++)
    834                otherPrimeInfos_array.push(this.otherPrimeInfos[i].toSchema());
    835 
    836            output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({ value: otherPrimeInfos_array }));
    837        }
    838        // #endregion 
    839 
    840        // #region Construct and return new ASN.1 schema for this object 
    841        return (new in_window.org.pkijs.asn1.SEQUENCE({
    842            value: output_array
    843        }));
    844        // #endregion 
    845    };
    846    //**************************************************************************************
    847    in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.toJSON =
    848    function()
    849    {
    850        var _object = {
    851            version: this.version,
    852            modulus: this.modulus.toJSON(),
    853            publicExponent: this.publicExponent.toJSON(),
    854            privateExponent: this.privateExponent.toJSON(),
    855            prime1: this.prime1.toJSON(),
    856            prime2: this.prime2.toJSON(),
    857            exponent1: this.exponent1.toJSON(),
    858            exponent2: this.exponent2.toJSON(),
    859            coefficient: this.coefficient.toJSON()
    860        };
    861 
    862        if("otherPrimeInfos" in this)
    863        {
    864            _object.otherPrimeInfos = new Array();
    865 
    866            for(var i = 0; i < this.otherPrimeInfos.length; i++)
    867                _object.otherPrimeInfos.push(this.otherPrimeInfos[i].toJSON());
    868        }
    869 
    870        return _object;
    871    };
    872    //**************************************************************************************
    873    // #endregion 
    874    //**************************************************************************************
    875    // #region Simplified structure for "RSASSA_PSS_params" type (RFC3447)
    876    //**************************************************************************************
    877    in_window.org.pkijs.simpl.x509.RSASSA_PSS_params =
    878    function()
    879    {
    880        // #region Internal properties of the object 
    881        // OPTIONAL this.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
    882        // OPTIONAL this.maskGenAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
    883        // OPTIONAL this.saltLength = 20; // new in_window.org.pkijs.asn1.INTEGER();
    884        // OPTIONAL this.trailerField = 1; // new in_window.org.pkijs.asn1.INTEGER();
    885        // #endregion 
    886 
    887        // #region If input argument array contains "schema" for this object 
    888        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
    889            in_window.org.pkijs.simpl.x509.RSASSA_PSS_params.prototype.fromSchema.call(this, arguments[0].schema);
    890        // #endregion 
    891        // #region If input argument array contains "native" values for internal properties 
    892        else
    893        {
    894            if(arguments[0] instanceof Object)
    895            {
    896                if("hashAlgorithm" in arguments[0])
    897                    this.hashAlgorithm = arguments[0].hashAlgorithm;
    898 
    899                if("maskGenAlgorithm" in arguments[0])
    900                    this.maskGenAlgorithm = arguments[0].maskGenAlgorithm;
    901 
    902                if("saltLength" in arguments[0])
    903                    this.saltLength = arguments[0].saltLength;
    904 
    905                if("trailerField" in arguments[0])
    906                    this.trailerField = arguments[0].trailerField;
    907            }
    908        }
    909        // #endregion 
    910    };
    911    //**************************************************************************************
    912    in_window.org.pkijs.simpl.x509.RSASSA_PSS_params.prototype.fromSchema =
    913    function(schema)
    914    {
    915        // #region Check the schema is valid 
    916        var asn1 = in_window.org.pkijs.compareSchema(schema,
    917            schema,
    918            in_window.org.pkijs.schema.x509.RSASSA_PSS_params({
    919                names: {
    920                    hashAlgorithm: {
    921                        names: {
    922                            block_name: "hashAlgorithm"
    923                        }
    924                    },
    925                    maskGenAlgorithm: {
    926                        names: {
    927                            block_name: "maskGenAlgorithm"
    928                        }
    929                    },
    930                    saltLength: "saltLength",
    931                    trailerField: "trailerField"
    932                }
    933            })
    934            );
    935 
    936        if(asn1.verified === false)
    937            throw new Error("Object's schema was not verified against input data for RSASSA_PSS_params");
    938        // #endregion 
    939 
    940        // #region Get internal properties from parsed schema 
    941        if("hashAlgorithm" in asn1.result)
    942            this.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["hashAlgorithm"] });
    943 
    944        if("maskGenAlgorithm" in asn1.result)
    945            this.maskGenAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["maskGenAlgorithm"] });
    946 
    947        if("saltLength" in asn1.result)
    948            this.saltLength = asn1.result["saltLength"].value_block.value_dec;
    949 
    950        if("trailerField" in asn1.result)
    951            this.trailerField = asn1.result["trailerField"].value_block.value_dec;
    952        // #endregion 
    953    };
    954    //**************************************************************************************
    955    in_window.org.pkijs.simpl.x509.RSASSA_PSS_params.prototype.toSchema =
    956    function()
    957    {
    958        // #region Create array for output sequence 
    959        var output_array = new Array();
    960 
    961        if("hashAlgorithm" in this)
    962            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    963                id_block: {
    964                    tag_class: 3, // CONTEXT-SPECIFIC
    965                    tag_number: 0 // [0]
    966                },
    967                value: [this.hashAlgorithm.toSchema()]
    968            }));
    969 
    970        if("maskGenAlgorithm" in this)
    971            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    972                id_block: {
    973                    tag_class: 3, // CONTEXT-SPECIFIC
    974                    tag_number: 1 // [1]
    975                },
    976                value: [this.maskGenAlgorithm.toSchema()]
    977            }));
    978 
    979        if("saltLength" in this)
    980            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    981                id_block: {
    982                    tag_class: 3, // CONTEXT-SPECIFIC
    983                    tag_number: 2 // [2]
    984                },
    985                value: [new in_window.org.pkijs.asn1.INTEGER({ value: this.saltLength })]
    986            }));
    987 
    988        if("trailerField" in this)
    989            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
    990                id_block: {
    991                    tag_class: 3, // CONTEXT-SPECIFIC
    992                    tag_number: 3 // [3]
    993                },
    994                value: [new in_window.org.pkijs.asn1.INTEGER({ value: this.trailerField })]
    995            }));
    996        // #endregion 
    997 
    998        // #region Construct and return new ASN.1 schema for this object 
    999        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1000            value: output_array
   1001        }));
   1002        // #endregion 
   1003    };
   1004    //**************************************************************************************
   1005    in_window.org.pkijs.simpl.x509.RSASSA_PSS_params.prototype.toJSON =
   1006    function()
   1007    {
   1008        var _object = {};
   1009 
   1010        if("hashAlgorithm" in this)
   1011            _object.hashAlgorithm = this.hashAlgorithm.toJSON();
   1012 
   1013        if("maskGenAlgorithm" in this)
   1014            _object.maskGenAlgorithm = this.maskGenAlgorithm.toJSON();
   1015 
   1016        if("saltLength" in this)
   1017            _object.saltLength = this.saltLength.toJSON();
   1018 
   1019        if("trailerField" in this)
   1020            _object.trailerField = this.trailerField.toJSON();
   1021 
   1022        return _object;
   1023    };
   1024    //**************************************************************************************
   1025    // #endregion 
   1026    //**************************************************************************************
   1027    // #region Simplified structure for "SubjectPublicKeyInfo" type 
   1028    //**************************************************************************************
   1029    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO =
   1030    function()
   1031    {
   1032        // #region Internal properties of the object 
   1033        this.algorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   1034        this.subjectPublicKey = new in_window.org.pkijs.asn1.BITSTRING();
   1035        // #endregion 
   1036 
   1037        // #region If input argument array contains "schema" for this object 
   1038        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1039            in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema.call(this, arguments[0].schema);
   1040        // #endregion 
   1041        // #region If input argument array contains "native" values for internal properties 
   1042        else
   1043        {
   1044            if(arguments[0] instanceof Object)
   1045            {
   1046                this.algorithm = (arguments[0].algorithm || (new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER()));
   1047                this.subjectPublicKey = (arguments[0].subjectPublicKey || (new in_window.org.pkijs.asn1.BITSTRING()));
   1048            }
   1049        }
   1050        // #endregion 
   1051    };
   1052    //**************************************************************************************
   1053    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema =
   1054    function(schema)
   1055    {
   1056        // #region Check the schema is valid 
   1057        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1058            schema,
   1059            in_window.org.pkijs.schema.PUBLIC_KEY_INFO({
   1060                names: {
   1061                    algorithm: {
   1062                        names: {
   1063                            block_name: "algorithm"
   1064                        }
   1065                    },
   1066                    subjectPublicKey: "subjectPublicKey"
   1067                }
   1068            })
   1069            );
   1070 
   1071        if(asn1.verified === false)
   1072            throw new Error("Object's schema was not verified against input data for PUBLIC_KEY_INFO");
   1073        // #endregion 
   1074 
   1075        // #region Get internal properties from parsed schema 
   1076        this.algorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result.algorithm });
   1077        this.subjectPublicKey = asn1.result.subjectPublicKey;
   1078        // #endregion 
   1079    };
   1080    //**************************************************************************************
   1081    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.toSchema =
   1082    function()
   1083    {
   1084        // #region Construct and return new ASN.1 schema for this object 
   1085        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1086            value: [
   1087                this.algorithm.toSchema(),
   1088                this.subjectPublicKey
   1089            ]
   1090        }));
   1091        // #endregion 
   1092    };
   1093    //**************************************************************************************
   1094    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.importKey =
   1095    function(publicKey)
   1096    {
   1097        /// <param name="publicKey" type="Key">Public key to work with</param>
   1098 
   1099        // #region Initial variables 
   1100        var sequence = Promise.resolve();
   1101        var _this = this;
   1102        // #endregion   
   1103 
   1104        // #region Initial check 
   1105        if(typeof publicKey === "undefined")
   1106            return new Promise(function(resolve, reject) { reject("Need to provide publicKey input parameter"); });
   1107        // #endregion 
   1108 
   1109        // #region Get a "crypto" extension 
   1110        var crypto = in_window.org.pkijs.getCrypto();
   1111        if(typeof crypto == "undefined")
   1112            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   1113        // #endregion 
   1114 
   1115        // #region Export public key 
   1116        sequence = sequence.then(
   1117            function()
   1118            {
   1119                return crypto.exportKey("spki", publicKey);
   1120            }
   1121            );
   1122        // #endregion 
   1123 
   1124        // #region Initialize internal variables by parsing exported value
   1125        sequence = sequence.then(
   1126            function(exportedKey)
   1127            {
   1128                var asn1 = in_window.org.pkijs.fromBER(exportedKey);
   1129                try
   1130                {
   1131                    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema.call(_this, asn1.result);
   1132                }
   1133                catch(exception)
   1134                {
   1135                    return new Promise(function(resolve, reject) { reject("Error during initializing object from schema"); });
   1136                }
   1137            },
   1138            function(error)
   1139            {
   1140                return new Promise(function(resolve, reject) { reject("Error during exporting public key: " + error); });
   1141            }
   1142            );
   1143        // #endregion 
   1144 
   1145        return sequence;
   1146    };
   1147    //**************************************************************************************
   1148    in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.toJSON =
   1149    function()
   1150    {
   1151        return {
   1152            algorithm: this.algorithm.toJSON(),
   1153            subjectPublicKey: this.subjectPublicKey.toJSON()
   1154        };
   1155    };
   1156    //**************************************************************************************
   1157    // #endregion 
   1158    //**************************************************************************************
   1159    // #region Simplified structure for "AttributeTypeAndValue" type (part of RelativeDistinguishedName)
   1160    //**************************************************************************************
   1161    in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE =
   1162    function()
   1163    {
   1164        // #region Internal properties of the object 
   1165        this.type = "";
   1166        this.value = {}; // ANY -- DEFINED BY AttributeType
   1167        // #endregion 
   1168 
   1169        // #region If input argument array contains "schema" for this object 
   1170        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1171            in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.fromSchema.call(this, arguments[0].schema);
   1172        // #endregion 
   1173        // #region If input argument array contains "native" values for internal properties 
   1174        else
   1175        {
   1176            if(arguments[0] instanceof Object)
   1177            {
   1178                this.type = (arguments[0].type || "");
   1179                this.value = (arguments[0].value || {});
   1180            }
   1181        }
   1182        // #endregion 
   1183    };
   1184    //**************************************************************************************
   1185    in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.fromSchema =
   1186    function(schema)
   1187    {
   1188        // #region Check the schema is valid 
   1189        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1190            schema,
   1191            in_window.org.pkijs.schema.ATTR_TYPE_AND_VALUE({
   1192                names: {
   1193                    type: "type",
   1194                    value: "typeValue"
   1195                }
   1196            })
   1197            );
   1198 
   1199        if(asn1.verified === false)
   1200            throw new Error("Object's schema was not verified against input data for ATTR_TYPE_AND_VALUE");
   1201        // #endregion 
   1202 
   1203        // #region Get internal properties from parsed schema 
   1204        this.type = asn1.result.type.value_block.toString();
   1205        this.value = asn1.result.typeValue;
   1206        // #endregion 
   1207    };
   1208    //**************************************************************************************
   1209    in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.toSchema =
   1210    function()
   1211    {
   1212        // #region Construct and return new ASN.1 schema for this object 
   1213        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1214            value: [
   1215                new in_window.org.pkijs.asn1.OID({ value: this.type }),
   1216                this.value
   1217            ]
   1218        }));
   1219        // #endregion 
   1220    };
   1221    //**************************************************************************************
   1222    in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.isEqual =
   1223    function()
   1224    {
   1225        if(arguments[0] instanceof in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE)
   1226        {
   1227            if(this.type !== arguments[0].type)
   1228                return false;
   1229 
   1230            if(((this.value instanceof in_window.org.pkijs.asn1.UTF8STRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.UTF8STRING)) ||
   1231               ((this.value instanceof in_window.org.pkijs.asn1.BMPSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.BMPSTRING)) ||
   1232               ((this.value instanceof in_window.org.pkijs.asn1.UNIVERSALSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.UNIVERSALSTRING)) ||
   1233               ((this.value instanceof in_window.org.pkijs.asn1.NUMERICSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.NUMERICSTRING)) ||
   1234               ((this.value instanceof in_window.org.pkijs.asn1.PRINTABLESTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.PRINTABLESTRING)) ||
   1235               ((this.value instanceof in_window.org.pkijs.asn1.TELETEXSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.TELETEXSTRING)) ||
   1236               ((this.value instanceof in_window.org.pkijs.asn1.VIDEOTEXSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.VIDEOTEXSTRING)) ||
   1237               ((this.value instanceof in_window.org.pkijs.asn1.IA5STRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.IA5STRING)) ||
   1238               ((this.value instanceof in_window.org.pkijs.asn1.GRAPHICSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.GRAPHICSTRING)) ||
   1239               ((this.value instanceof in_window.org.pkijs.asn1.VISIBLESTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.VISIBLESTRING)) ||
   1240               ((this.value instanceof in_window.org.pkijs.asn1.GENERALSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.GENERALSTRING)) ||
   1241               ((this.value instanceof in_window.org.pkijs.asn1.CHARACTERSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.CHARACTERSTRING)))
   1242            {
   1243                var value1 = in_window.org.pkijs.stringPrep(this.value.value_block.value);
   1244                var value2 = in_window.org.pkijs.stringPrep(arguments[0].value.value_block.value);
   1245 
   1246                if(value1.localeCompare(value2) !== 0)
   1247                    return false;
   1248            }
   1249            else // Comparing as two ArrayBuffers
   1250            {
   1251                if(in_window.org.pkijs.isEqual_buffer(this.value.value_before_decode, arguments[0].value.value_before_decode) === false)
   1252                    return false;
   1253            }
   1254 
   1255            return true;
   1256        }
   1257        else
   1258            return false;
   1259    };
   1260    //**************************************************************************************
   1261    in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.toJSON =
   1262    function()
   1263    {
   1264        var _object = {
   1265            type: this.type
   1266        };
   1267 
   1268        if(Object.keys(this.value).length !== 0)
   1269            _object.value = this.value.toJSON();
   1270        else
   1271            _object.value = this.value;
   1272 
   1273        return _object;
   1274    };
   1275    //**************************************************************************************
   1276    // #endregion 
   1277    //**************************************************************************************
   1278    // #region Simplified structure for "RelativeDistinguishedName" type
   1279    //**************************************************************************************
   1280    in_window.org.pkijs.simpl.RDN =
   1281    function()
   1282    {
   1283        // #region Internal properties of the object 
   1284        /// <field name="types_and_values" type="Array" elementType="in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE">Array of "type and value" objects</field>
   1285        this.types_and_values = new Array();
   1286        /// <field name="value_before_decode" type="ArrayBuffer">Value of the RDN before decoding from schema</field>
   1287        this.value_before_decode = new ArrayBuffer(0);
   1288        // #endregion 
   1289 
   1290        // #region If input argument array contains "schema" for this object 
   1291        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1292            in_window.org.pkijs.simpl.RDN.prototype.fromSchema.call(this, arguments[0].schema);
   1293        // #endregion 
   1294        // #region If input argument array contains "native" values for internal properties 
   1295        else
   1296        {
   1297            if(arguments[0] instanceof Object)
   1298            {
   1299                this.types_and_values = (arguments[0].types_and_values || (new Array()));
   1300                this.value_before_decode = arguments[0].value_before_decode || new ArrayBuffer(0);
   1301            }
   1302        }
   1303        // #endregion 
   1304    };
   1305    //**************************************************************************************
   1306    in_window.org.pkijs.simpl.RDN.prototype.fromSchema =
   1307    function(schema)
   1308    {
   1309        // #region Check the schema is valid 
   1310        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1311            schema,
   1312            in_window.org.pkijs.schema.RDN({
   1313                names: {
   1314                    block_name: "RDN",
   1315                    repeated_set: "types_and_values"
   1316                }
   1317            })
   1318            );
   1319 
   1320        if(asn1.verified === false)
   1321            throw new Error("Object's schema was not verified against input data for RDN");
   1322        // #endregion 
   1323 
   1324        // #region Get internal properties from parsed schema 
   1325        if("types_and_values" in asn1.result) // Could be a case when there is no "types and values"
   1326        {
   1327            var types_and_values_array = asn1.result.types_and_values;
   1328            for(var i = 0; i < types_and_values_array.length; i++)
   1329                this.types_and_values.push(new in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ schema: types_and_values_array[i] }));
   1330        }
   1331 
   1332        this.value_before_decode = asn1.result.RDN.value_before_decode;
   1333        // #endregion 
   1334    };
   1335    //**************************************************************************************
   1336    in_window.org.pkijs.simpl.RDN.prototype.toSchema =
   1337    function()
   1338    {
   1339        // #region Decode stored TBS value 
   1340        if(this.value_before_decode.byteLength === 0) // No stored encoded array, create "from scratch"
   1341        {
   1342            // #region Create array for output set 
   1343            var output_array = new Array();
   1344 
   1345            for(var i = 0; i < this.types_and_values.length; i++)
   1346                output_array.push(this.types_and_values[i].toSchema());
   1347            // #endregion 
   1348 
   1349            return (new in_window.org.pkijs.asn1.SEQUENCE({
   1350                value: [new in_window.org.pkijs.asn1.SET({ value: output_array })]
   1351            }));
   1352        }
   1353 
   1354        var asn1 = in_window.org.pkijs.fromBER(this.value_before_decode);
   1355        // #endregion 
   1356 
   1357        // #region Construct and return new ASN.1 schema for this object 
   1358        return asn1.result;
   1359        // #endregion 
   1360    };
   1361    //**************************************************************************************
   1362    in_window.org.pkijs.simpl.RDN.prototype.isEqual =
   1363    function()
   1364    {
   1365        if(arguments[0] instanceof in_window.org.pkijs.simpl.RDN)
   1366        {
   1367            if(this.types_and_values.length != arguments[0].types_and_values.length)
   1368                return false;
   1369 
   1370            for(var i = 0; i < this.types_and_values.length; i++)
   1371            {
   1372                if(this.types_and_values[i].isEqual(arguments[0].types_and_values[i]) === false)
   1373                    return false;
   1374            }
   1375 
   1376            return true;
   1377        }
   1378        else
   1379        {
   1380            if(arguments[0] instanceof ArrayBuffer)
   1381                return in_window.org.pkijs.isEqual_buffer(this.value_before_decode, arguments[0]);
   1382            else
   1383                return false;
   1384        }
   1385 
   1386        return false;
   1387    };
   1388    //**************************************************************************************
   1389    in_window.org.pkijs.simpl.RDN.prototype.toJSON =
   1390    function()
   1391    {
   1392        var _object = {
   1393            types_and_values: new Array()
   1394        };
   1395 
   1396        for(var i = 0; i < this.types_and_values.length; i++)
   1397            _object.types_and_values.push(this.types_and_values[i].toJSON());
   1398 
   1399        return _object;
   1400    };
   1401    //**************************************************************************************
   1402    // #endregion 
   1403    //**************************************************************************************
   1404    // #region Simplified structure for "AuthorityKeyIdentifier" type of extension
   1405    //**************************************************************************************
   1406    in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier =
   1407    function()
   1408    {
   1409        // #region Internal properties of the object 
   1410        // OPTIONAL this.keyIdentifier - OCTETSTRING
   1411        // OPTIONAL this.authorityCertIssuer - Array of GeneralName
   1412        // OPTIONAL this.authorityCertSerialNumber - INTEGER
   1413        // #endregion 
   1414 
   1415        // #region If input argument array contains "schema" for this object 
   1416        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1417            in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.fromSchema.call(this, arguments[0].schema);
   1418        // #endregion 
   1419        // #region If input argument array contains "native" values for internal properties 
   1420        else
   1421        {
   1422            if(arguments[0] instanceof Object)
   1423            {
   1424                if("keyIdentifier" in arguments[0])
   1425                    this.keyIdentifier = arguments[0].keyIdentifier;
   1426 
   1427                if("authorityCertIssuer" in arguments[0])
   1428                    this.authorityCertIssuer = arguments[0].authorityCertIssuer;
   1429 
   1430                if("authorityCertSerialNumber" in arguments[0])
   1431                    this.authorityCertSerialNumber = arguments[0].authorityCertSerialNumber;
   1432            }
   1433        }
   1434        // #endregion 
   1435    };
   1436    //**************************************************************************************
   1437    in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.fromSchema =
   1438    function(schema)
   1439    {
   1440        // #region Check the schema is valid 
   1441        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1442            schema,
   1443            in_window.org.pkijs.schema.x509.AuthorityKeyIdentifier({
   1444                names: {
   1445                    keyIdentifier: "keyIdentifier",
   1446                    authorityCertIssuer: "authorityCertIssuer",
   1447                    authorityCertSerialNumber: "authorityCertSerialNumber"
   1448                }
   1449            })
   1450            );
   1451 
   1452        if(asn1.verified === false)
   1453            throw new Error("Object's schema was not verified against input data for AuthorityKeyIdentifier");
   1454        // #endregion 
   1455 
   1456        // #region Get internal properties from parsed schema 
   1457        if("keyIdentifier" in asn1.result)
   1458        {
   1459            asn1.result["keyIdentifier"].id_block.tag_class = 1; // UNIVERSAL
   1460            asn1.result["keyIdentifier"].id_block.tag_number = 4; // OCTETSTRING
   1461 
   1462            this.keyIdentifier = asn1.result["keyIdentifier"];
   1463        }
   1464 
   1465        if("authorityCertIssuer" in asn1.result)
   1466        {
   1467            this.authorityCertIssuer = new Array();
   1468            var issuer_array = asn1.result["authorityCertIssuer"];
   1469 
   1470            for(var i = 0; i < issuer_array.length; i++)
   1471                this.authorityCertIssuer.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: issuer_array[i] }));
   1472        }
   1473 
   1474        if("authorityCertSerialNumber" in asn1.result)
   1475        {
   1476            asn1.result["authorityCertSerialNumber"].id_block.tag_class = 1; // UNIVERSAL
   1477            asn1.result["authorityCertSerialNumber"].id_block.tag_number = 2; // INTEGER
   1478 
   1479            this.authorityCertSerialNumber = asn1.result["authorityCertSerialNumber"];
   1480        }
   1481        // #endregion 
   1482    };
   1483    //**************************************************************************************
   1484    in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.toSchema =
   1485    function()
   1486    {
   1487        // #region Create array for output sequence 
   1488        var output_array = new Array();
   1489 
   1490        if("keyIdentifier" in this)
   1491        {
   1492            var value = this.keyIdentifier;
   1493 
   1494            value.id_block.tag_class = 3; // CONTEXT-SPECIFIC
   1495            value.id_block.tag_number = 0; // [0]
   1496 
   1497            output_array.push(value);
   1498        }
   1499 
   1500        if("authorityCertIssuer" in this)
   1501        {
   1502            var issuer_array = new Array();
   1503 
   1504            for(var i = 0; i < this.authorityCertIssuer.length; i++)
   1505                issuer_array.push(this.authorityCertIssuer[i].toSchema());
   1506 
   1507            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   1508                optional: true,
   1509                id_block: {
   1510                    tag_class: 3, // CONTEXT-SPECIFIC
   1511                    tag_number: 1 // [1]
   1512                },
   1513                value: [new in_window.org.pkijs.asn1.SEQUENCE({
   1514                    value: issuer_array
   1515                })]
   1516            }));
   1517        }
   1518 
   1519        if("authorityCertSerialNumber" in this)
   1520        {
   1521            var value = this.authorityCertSerialNumber;
   1522 
   1523            value.id_block.tag_class = 3; // CONTEXT-SPECIFIC
   1524            value.id_block.tag_number = 2; // [2]
   1525 
   1526            output_array.push(value);
   1527        }
   1528        // #endregion 
   1529 
   1530        // #region Construct and return new ASN.1 schema for this object 
   1531        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1532            value: output_array
   1533        }));
   1534        // #endregion 
   1535    };
   1536    //**************************************************************************************
   1537    in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.toJSON =
   1538    function()
   1539    {
   1540        var _object = {};
   1541 
   1542        if("keyIdentifier" in this)
   1543            _object.keyIdentifier = this.keyIdentifier.toJSON();
   1544 
   1545        if("authorityCertIssuer" in this)
   1546        {
   1547            _object.authorityCertIssuer = new Array();
   1548 
   1549            for(var i = 0; i < this.authorityCertIssuer.length; i++)
   1550                _object.authorityCertIssuer.push(this.authorityCertIssuer[i].toJSON());
   1551        }
   1552 
   1553        if("authorityCertSerialNumber" in this)
   1554            _object.authorityCertSerialNumber = this.authorityCertSerialNumber.toJSON();
   1555 
   1556        return _object;
   1557    };
   1558    //**************************************************************************************
   1559    // #endregion 
   1560    //**************************************************************************************
   1561    // #region Simplified structure for "PrivateKeyUsagePeriod" type of extension
   1562    //**************************************************************************************
   1563    in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod =
   1564    function()
   1565    {
   1566        // #region Internal properties of the object 
   1567        // OPTIONAL this.notBefore - new Date()
   1568        // OPTIONAL this.notAfter - new Date()
   1569        // #endregion 
   1570 
   1571        // #region If input argument array contains "schema" for this object 
   1572        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1573            in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod.prototype.fromSchema.call(this, arguments[0].schema);
   1574        // #endregion 
   1575        // #region If input argument array contains "native" values for internal properties 
   1576        else
   1577        {
   1578            if(arguments[0] instanceof Object)
   1579            {
   1580                if("notBefore" in arguments[0])
   1581                    this.notBefore = arguments[0].notBefore;
   1582 
   1583                if("notAfter" in arguments[0])
   1584                    this.notAfter = arguments[0].notAfter;
   1585            }
   1586        }
   1587        // #endregion 
   1588    };
   1589    //**************************************************************************************
   1590    in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod.prototype.fromSchema =
   1591    function(schema)
   1592    {
   1593        // #region Check the schema is valid 
   1594        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1595            schema,
   1596            in_window.org.pkijs.schema.x509.PrivateKeyUsagePeriod({
   1597                names: {
   1598                    notBefore: "notBefore",
   1599                    notAfter: "notAfter"
   1600                }
   1601            })
   1602            );
   1603 
   1604        if(asn1.verified === false)
   1605            throw new Error("Object's schema was not verified against input data for PrivateKeyUsagePeriod");
   1606        // #endregion 
   1607 
   1608        // #region Get internal properties from parsed schema 
   1609        if("notBefore" in asn1.result)
   1610        {
   1611            var localNotBefore = new in_window.org.pkijs.asn1.GENERALIZEDTIME();
   1612            localNotBefore.fromBuffer(asn1.result["notBefore"].value_block.value_hex);
   1613            this.notBefore = localNotBefore.toDate();
   1614        }
   1615 
   1616        if("notAfter" in asn1.result)
   1617        {
   1618            var localNotAfter = new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_hex: asn1.result["notAfter"].value_block.value_hex });
   1619            localNotAfter.fromBuffer(asn1.result["notAfter"].value_block.value_hex);
   1620            this.notAfter = localNotAfter.toDate();
   1621        }
   1622        // #endregion 
   1623    };
   1624    //**************************************************************************************
   1625    in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod.prototype.toSchema =
   1626    function()
   1627    {
   1628        // #region Create array for output sequence 
   1629        var output_array = new Array();
   1630 
   1631        if("notBefore" in this)
   1632            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   1633                id_block: {
   1634                    tag_class: 3, // CONTEXT-SPECIFIC
   1635                    tag_number: 0 // [0]
   1636                },
   1637                value_hex: (new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.notBefore })).value_block.value_hex
   1638            }));
   1639 
   1640        if("notAfter" in this)
   1641            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   1642                id_block: {
   1643                    tag_class: 3, // CONTEXT-SPECIFIC
   1644                    tag_number: 1 // [1]
   1645                },
   1646                value_hex: (new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.notAfter })).value_block.value_hex
   1647            }));
   1648        // #endregion 
   1649 
   1650        // #region Construct and return new ASN.1 schema for this object 
   1651        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1652            value: output_array
   1653        }));
   1654        // #endregion 
   1655    };
   1656    //**************************************************************************************
   1657    in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod.prototype.toJSON =
   1658    function()
   1659    {
   1660        var _object = {};
   1661 
   1662        if("notBefore" in this)
   1663            _object.notBefore = this.notBefore;
   1664 
   1665        if("notAfter" in this)
   1666            _object.notAfter = this.notAfter;
   1667 
   1668        return _object;
   1669    };
   1670    //**************************************************************************************
   1671    // #endregion 
   1672    //**************************************************************************************
   1673    // #region Simplified structure for "IssuerAltName" and "SubjectAltName" types of extension
   1674    //**************************************************************************************
   1675    in_window.org.pkijs.simpl.x509.AltName =
   1676    function()
   1677    {
   1678        // #region Internal properties of the object 
   1679        this.altNames = new Array(); //Array of GeneralName
   1680        // #endregion 
   1681 
   1682        // #region If input argument array contains "schema" for this object 
   1683        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1684            in_window.org.pkijs.simpl.x509.AltName.prototype.fromSchema.call(this, arguments[0].schema);
   1685        // #endregion 
   1686        // #region If input argument array contains "native" values for internal properties 
   1687        else
   1688        {
   1689            if(arguments[0] instanceof Object)
   1690            {
   1691                this.altNames = arguments[0].altNames || new Array();
   1692            }
   1693        }
   1694        // #endregion 
   1695    };
   1696    //**************************************************************************************
   1697    in_window.org.pkijs.simpl.x509.AltName.prototype.fromSchema =
   1698    function(schema)
   1699    {
   1700        // #region Check the schema is valid 
   1701        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1702            schema,
   1703            in_window.org.pkijs.schema.x509.AltName({
   1704                names: {
   1705                    altNames: "altNames"
   1706                }
   1707            })
   1708            );
   1709 
   1710        if(asn1.verified === false)
   1711            throw new Error("Object's schema was not verified against input data for AltName");
   1712        // #endregion 
   1713 
   1714        // #region Get internal properties from parsed schema 
   1715        if("altNames" in asn1.result)
   1716        {
   1717            var altNames_array = asn1.result["altNames"];
   1718 
   1719            for(var i = 0; i < altNames_array.length; i++)
   1720                this.altNames.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: altNames_array[i] }));
   1721        }
   1722        // #endregion 
   1723    };
   1724    //**************************************************************************************
   1725    in_window.org.pkijs.simpl.x509.AltName.prototype.toSchema =
   1726    function()
   1727    {
   1728        // #region Create array for output sequence 
   1729        var output_array = new Array();
   1730 
   1731        for(var i = 0; i < this.altNames.length; i++)
   1732            output_array.push(this.altNames[i].toSchema());
   1733        // #endregion 
   1734 
   1735        // #region Construct and return new ASN.1 schema for this object 
   1736        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1737            value: output_array
   1738        }));
   1739        // #endregion 
   1740    };
   1741    //**************************************************************************************
   1742    in_window.org.pkijs.simpl.x509.AltName.prototype.toJSON =
   1743    function()
   1744    {
   1745        var _object = {
   1746            altNames: new Array()
   1747        };
   1748 
   1749        for(var i = 0; i < this.altNames.length; i++)
   1750            _object.altNames.push(this.altNames[i].toJSON());
   1751 
   1752        return _object;
   1753    };
   1754    //**************************************************************************************
   1755    // #endregion 
   1756    //**************************************************************************************
   1757    // #region Simplified structure for "SubjectDirectoryAttributes" type of extension
   1758    //**************************************************************************************
   1759    in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes =
   1760    function()
   1761    {
   1762        // #region Internal properties of the object 
   1763        this.attributes = new Array(); // Array of "simpl.ATTRIBUTE"
   1764        // #endregion 
   1765 
   1766        // #region If input argument array contains "schema" for this object 
   1767        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1768            in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes.prototype.fromSchema.call(this, arguments[0].schema);
   1769        // #endregion 
   1770        // #region If input argument array contains "native" values for internal properties 
   1771        else
   1772        {
   1773            if(arguments[0] instanceof Object)
   1774            {
   1775                this.attributes = arguments[0].attributes || new Array(); // Array of "simpl.ATTRIBUTE"
   1776            }
   1777        }
   1778        // #endregion 
   1779    };
   1780    //**************************************************************************************
   1781    in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes.prototype.fromSchema =
   1782    function(schema)
   1783    {
   1784        // #region Check the schema is valid 
   1785        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1786            schema,
   1787            in_window.org.pkijs.schema.x509.SubjectDirectoryAttributes({
   1788                names: {
   1789                    attributes: "attributes"
   1790                }
   1791            })
   1792            );
   1793 
   1794        if(asn1.verified === false)
   1795            throw new Error("Object's schema was not verified against input data for SubjectDirectoryAttributes");
   1796        // #endregion 
   1797 
   1798        // #region Get internal properties from parsed schema
   1799        var attrs = asn1.result["attributes"];
   1800 
   1801        for(var i = 0; i < attrs.length; i++)
   1802            this.attributes.push(new in_window.org.pkijs.simpl.ATTRIBUTE({ schema: attrs[i] }));
   1803        // #endregion 
   1804    };
   1805    //**************************************************************************************
   1806    in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes.prototype.toSchema =
   1807    function()
   1808    {
   1809        // #region Create array for output sequence 
   1810        var output_array = new Array();
   1811 
   1812        for(var i = 0; i < this.attributes.length; i++)
   1813            output_array.push(this.attributes[i].toSchema());
   1814        // #endregion 
   1815 
   1816        // #region Construct and return new ASN.1 schema for this object 
   1817        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1818            value: output_array
   1819        }));
   1820        // #endregion 
   1821    };
   1822    //**************************************************************************************
   1823    in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes.prototype.toJSON =
   1824    function()
   1825    {
   1826        var _object = {
   1827            attributes: new Array()
   1828        };
   1829 
   1830        for(var i = 0; i < this.attributes.length; i++)
   1831            _object.attributes.push(this.attributes[i].toJSON());
   1832 
   1833        return _object;
   1834    };
   1835    //**************************************************************************************
   1836    // #endregion 
   1837    //**************************************************************************************
   1838    // #region Simplified structure for "PolicyMapping" type
   1839    //**************************************************************************************
   1840    in_window.org.pkijs.simpl.x509.PolicyMapping =
   1841    function()
   1842    {
   1843        // #region Internal properties of the object 
   1844        this.issuerDomainPolicy = "";
   1845        this.subjectDomainPolicy = "";
   1846        // #endregion 
   1847 
   1848        // #region If input argument array contains "schema" for this object 
   1849        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1850            in_window.org.pkijs.simpl.x509.PolicyMapping.prototype.fromSchema.call(this, arguments[0].schema);
   1851        // #endregion 
   1852        // #region If input argument array contains "native" values for internal properties 
   1853        else
   1854        {
   1855            if(arguments[0] instanceof Object)
   1856            {
   1857                this.issuerDomainPolicy = arguments[0].issuerDomainPolicy || "";
   1858                this.subjectDomainPolicy = arguments[0].subjectDomainPolicy || "";
   1859            }
   1860        }
   1861        // #endregion 
   1862    };
   1863    //**************************************************************************************
   1864    in_window.org.pkijs.simpl.x509.PolicyMapping.prototype.fromSchema =
   1865    function(schema)
   1866    {
   1867        // #region Check the schema is valid 
   1868        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1869            schema,
   1870            in_window.org.pkijs.schema.x509.PolicyMapping({
   1871                names: {
   1872                    issuerDomainPolicy: "issuerDomainPolicy",
   1873                    subjectDomainPolicy: "subjectDomainPolicy"
   1874                }
   1875            })
   1876            );
   1877 
   1878        if(asn1.verified === false)
   1879            throw new Error("Object's schema was not verified against input data for PolicyMapping");
   1880        // #endregion 
   1881 
   1882        // #region Get internal properties from parsed schema
   1883        this.issuerDomainPolicy = asn1.result["issuerDomainPolicy"].value_block.toString();
   1884        this.subjectDomainPolicy = asn1.result["subjectDomainPolicy"].value_block.toString();
   1885        // #endregion 
   1886    };
   1887    //**************************************************************************************
   1888    in_window.org.pkijs.simpl.x509.PolicyMapping.prototype.toSchema =
   1889    function()
   1890    {
   1891        // #region Construct and return new ASN.1 schema for this object 
   1892        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1893            value: [
   1894                new in_window.org.pkijs.asn1.OID({ value: this.issuerDomainPolicy }),
   1895                new in_window.org.pkijs.asn1.OID({ value: this.subjectDomainPolicy })
   1896            ]
   1897        }));
   1898        // #endregion 
   1899    };
   1900    //**************************************************************************************
   1901    in_window.org.pkijs.simpl.x509.PolicyMapping.prototype.toJSON =
   1902    function()
   1903    {
   1904        return {
   1905            issuerDomainPolicy: this.issuerDomainPolicy,
   1906            subjectDomainPolicy: this.subjectDomainPolicy
   1907        };
   1908    };
   1909    //**************************************************************************************
   1910    // #endregion 
   1911    //**************************************************************************************
   1912    // #region Simplified structure for "PolicyMappings" type of extension
   1913    //**************************************************************************************
   1914    in_window.org.pkijs.simpl.x509.PolicyMappings =
   1915    function()
   1916    {
   1917        // #region Internal properties of the object 
   1918        this.mappings = new Array(); // Array of "simpl.x509.PolicyMapping"
   1919        // #endregion 
   1920 
   1921        // #region If input argument array contains "schema" for this object 
   1922        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   1923            in_window.org.pkijs.simpl.x509.PolicyMappings.prototype.fromSchema.call(this, arguments[0].schema);
   1924        // #endregion 
   1925        // #region If input argument array contains "native" values for internal properties 
   1926        else
   1927        {
   1928            if(arguments[0] instanceof Object)
   1929            {
   1930                this.mappings = arguments[0].mappings || new Array();
   1931            }
   1932        }
   1933        // #endregion 
   1934    };
   1935    //**************************************************************************************
   1936    in_window.org.pkijs.simpl.x509.PolicyMappings.prototype.fromSchema =
   1937    function(schema)
   1938    {
   1939        // #region Check the schema is valid 
   1940        var asn1 = in_window.org.pkijs.compareSchema(schema,
   1941            schema,
   1942            in_window.org.pkijs.schema.x509.PolicyMappings({
   1943                names: {
   1944                    mappings: "mappings"
   1945                }
   1946            })
   1947            );
   1948 
   1949        if(asn1.verified === false)
   1950            throw new Error("Object's schema was not verified against input data for PolicyMappings");
   1951        // #endregion 
   1952 
   1953        // #region Get internal properties from parsed schema 
   1954        var maps = asn1.result["mappings"];
   1955 
   1956        for(var i = 0; i < maps.length; i++)
   1957            this.mappings.push(new in_window.org.pkijs.simpl.x509.PolicyMapping({ schema: maps[i] }));
   1958        // #endregion 
   1959    };
   1960    //**************************************************************************************
   1961    in_window.org.pkijs.simpl.x509.PolicyMappings.prototype.toSchema =
   1962    function()
   1963    {
   1964        // #region Create array for output sequence 
   1965        var output_array = new Array();
   1966 
   1967        for(var i = 0; i < this.mappings.length; i++)
   1968            output_array.push(this.mappings.toSchema());
   1969        // #endregion 
   1970 
   1971        // #region Construct and return new ASN.1 schema for this object 
   1972        return (new in_window.org.pkijs.asn1.SEQUENCE({
   1973            value: output_array
   1974        }));
   1975        // #endregion 
   1976    };
   1977    //**************************************************************************************
   1978    in_window.org.pkijs.simpl.x509.PolicyMappings.prototype.toJSON =
   1979    function()
   1980    {
   1981        var _object = {
   1982            mappings: new Array()
   1983        };
   1984 
   1985        for(var i = 0; i < this.mappings.length; i++)
   1986            _object.mappings.push(this.mappings[i].toJSON());
   1987 
   1988        return _object;
   1989    };
   1990    //**************************************************************************************
   1991    // #endregion 
   1992    //**************************************************************************************
   1993    // #region Simplified structure for "GeneralSubtree" type
   1994    //**************************************************************************************
   1995    in_window.org.pkijs.simpl.x509.GeneralSubtree =
   1996    function()
   1997    {
   1998        // #region Internal properties of the object 
   1999        this.base = new in_window.org.pkijs.simpl.GENERAL_NAME();
   2000        // OPTIONAL this.minimum // in_window.org.pkijs.asn1.INTEGER
   2001        // OPTIONAL this.maximum // in_window.org.pkijs.asn1.INTEGER
   2002        // #endregion 
   2003 
   2004        // #region If input argument array contains "schema" for this object 
   2005        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2006            in_window.org.pkijs.simpl.x509.GeneralSubtree.prototype.fromSchema.call(this, arguments[0].schema);
   2007        // #endregion 
   2008        // #region If input argument array contains "native" values for internal properties 
   2009        else
   2010        {
   2011            if(arguments[0] instanceof Object)
   2012            {
   2013                this.base = arguments[0].base || new in_window.org.pkijs.simpl.GENERAL_NAME();
   2014 
   2015                if("minimum" in arguments[0])
   2016                    this.minimum = arguments[0].minimum;
   2017 
   2018                if("maximum" in arguments[0])
   2019                    this.maximum = arguments[0].maximum;
   2020            }
   2021        }
   2022        // #endregion 
   2023    };
   2024    //**************************************************************************************
   2025    in_window.org.pkijs.simpl.x509.GeneralSubtree.prototype.fromSchema =
   2026    function(schema)
   2027    {
   2028        // #region Check the schema is valid 
   2029        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2030            schema,
   2031            in_window.org.pkijs.schema.x509.GeneralSubtree({
   2032                names: {
   2033                    base: {
   2034                        names: {
   2035                            block_name: "base"
   2036                        }
   2037                    },
   2038                    minimum: "minimum",
   2039                    maximum: "maximum"
   2040                }
   2041            })
   2042            );
   2043 
   2044        if(asn1.verified === false)
   2045            throw new Error("Object's schema was not verified against input data for ");
   2046        // #endregion 
   2047 
   2048        // #region Get internal properties from parsed schema 
   2049        this.base = new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: asn1.result["base"] });
   2050 
   2051        if("minimum" in asn1.result)
   2052        {
   2053            if(asn1.result["minimum"].value_block.is_hex_only)
   2054                this.minimum = asn1.result["minimum"];
   2055            else
   2056                this.minimum = asn1.result["minimum"].value_block.value_dec;
   2057        }
   2058 
   2059        if("maximum" in asn1.result)
   2060        {
   2061            if(asn1.result["maximum"].value_block.is_hex_only)
   2062                this.maximum = asn1.result["maximum"];
   2063            else
   2064                this.maximum = asn1.result["maximum"].value_block.value_dec;
   2065        }
   2066        // #endregion 
   2067    };
   2068    //**************************************************************************************
   2069    in_window.org.pkijs.simpl.x509.GeneralSubtree.prototype.toSchema =
   2070    function()
   2071    {
   2072        // #region Create array for output sequence 
   2073        var output_array = new Array();
   2074 
   2075        output_array.push(this.base.toSchema());
   2076 
   2077        if("minimum" in this)
   2078        {
   2079            var value_minimum = 0;
   2080 
   2081            if(this.minimum instanceof in_window.org.pkijs.asn1.INTEGER)
   2082                value_minimum = this.minimum;
   2083            else
   2084                value_minimum = new in_window.org.pkijs.asn1.INTEGER({ value: this.minimum });
   2085 
   2086            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2087                optional: true,
   2088                id_block: {
   2089                    tag_class: 3, // CONTEXT-SPECIFIC
   2090                    tag_number: 0 // [0]
   2091                },
   2092                value: [value_minimum]
   2093            }));
   2094        }
   2095 
   2096        if("maximum" in this)
   2097        {
   2098            var value_maximum = 0;
   2099 
   2100            if(this.maximum instanceof in_window.org.pkijs.asn1.INTEGER)
   2101                value_maximum = this.maximum;
   2102            else
   2103                value_maximum = new in_window.org.pkijs.asn1.INTEGER({ value: this.maximum });
   2104 
   2105            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2106                optional: true,
   2107                id_block: {
   2108                    tag_class: 3, // CONTEXT-SPECIFIC
   2109                    tag_number: 1 // [1]
   2110                },
   2111                value: [value_maximum]
   2112            }));
   2113        }
   2114        // #endregion 
   2115 
   2116        // #region Construct and return new ASN.1 schema for this object 
   2117        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2118            value: output_array
   2119        }));
   2120        // #endregion 
   2121    };
   2122    //**************************************************************************************
   2123    in_window.org.pkijs.simpl.x509.GeneralSubtree.prototype.toJSON =
   2124    function()
   2125    {
   2126        var _object = {
   2127            base: this.base.toJSON()
   2128        };
   2129 
   2130        if("minimum" in this)
   2131        {
   2132            if((typeof this.minimum) === "number")
   2133                _object.minimum = this.minimum;
   2134            else
   2135                _object.minimum = this.minimum.toJSON();
   2136        }
   2137 
   2138        if("maximum" in this)
   2139        {
   2140            if((typeof this.maximum) === "number")
   2141                _object.maximum = this.maximum;
   2142            else
   2143                _object.maximum = this.maximum.toJSON();
   2144        }
   2145 
   2146        return _object;
   2147    };
   2148    //**************************************************************************************
   2149    // #endregion 
   2150    //**************************************************************************************
   2151    // #region Simplified structure for "NameConstraints" type of extension
   2152    //**************************************************************************************
   2153    in_window.org.pkijs.simpl.x509.NameConstraints =
   2154    function()
   2155    {
   2156        // #region Internal properties of the object 
   2157        // OPTIONAL this.permittedSubtrees - Array of "simpl.x509.GeneralSubtree"
   2158        // OPTIONAL this.excludedSubtrees - Array of "simpl.x509.GeneralSubtree"
   2159        // #endregion 
   2160 
   2161        // #region If input argument array contains "schema" for this object 
   2162        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2163            in_window.org.pkijs.simpl.x509.NameConstraints.prototype.fromSchema.call(this, arguments[0].schema);
   2164        // #endregion 
   2165        // #region If input argument array contains "native" values for internal properties 
   2166        else
   2167        {
   2168            if(arguments[0] instanceof Object)
   2169            {
   2170                if("permittedSubtrees" in arguments[0])
   2171                    this.permittedSubtrees = arguments[0].permittedSubtrees;
   2172 
   2173                if("excludedSubtrees" in arguments[0])
   2174                    this.excludedSubtrees = arguments[0].excludedSubtrees;
   2175            }
   2176        }
   2177        // #endregion 
   2178    };
   2179    //**************************************************************************************
   2180    in_window.org.pkijs.simpl.x509.NameConstraints.prototype.fromSchema =
   2181    function(schema)
   2182    {
   2183        // #region Check the schema is valid 
   2184        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2185            schema,
   2186            in_window.org.pkijs.schema.x509.NameConstraints({
   2187                names: {
   2188                    permittedSubtrees: "permittedSubtrees",
   2189                    excludedSubtrees: "excludedSubtrees"
   2190                }
   2191            })
   2192            );
   2193 
   2194        if(asn1.verified === false)
   2195            throw new Error("Object's schema was not verified against input data for NameConstraints");
   2196        // #endregion 
   2197 
   2198        // #region Get internal properties from parsed schema 
   2199        if("permittedSubtrees" in asn1.result)
   2200        {
   2201            this.permittedSubtrees = new Array();
   2202            var permited_array = asn1.result["permittedSubtrees"];
   2203 
   2204            for(var i = 0; i < permited_array.length; i++)
   2205                this.permittedSubtrees.push(new in_window.org.pkijs.simpl.x509.GeneralSubtree({ schema: permited_array[i] }));
   2206        }
   2207 
   2208        if("excludedSubtrees" in asn1.result)
   2209        {
   2210            this.excludedSubtrees = new Array();
   2211            var excluded_array = asn1.result["excludedSubtrees"];
   2212 
   2213            for(var i = 0; i < excluded_array.length; i++)
   2214                this.excludedSubtrees.push(new in_window.org.pkijs.simpl.x509.GeneralSubtree({ schema: excluded_array[i] }));
   2215        }
   2216        // #endregion 
   2217    };
   2218    //**************************************************************************************
   2219    in_window.org.pkijs.simpl.x509.NameConstraints.prototype.toSchema =
   2220    function()
   2221    {
   2222        // #region Create array for output sequence 
   2223        var output_array = new Array();
   2224 
   2225        if("permittedSubtrees" in this)
   2226        {
   2227            var permited_array = new Array();
   2228 
   2229            for(var i = 0; i < this.permittedSubtrees.length; i++)
   2230                permited_array.push(this.permittedSubtrees[i].toSchema());
   2231 
   2232            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2233                optional: true,
   2234                id_block: {
   2235                    tag_class: 3, // CONTEXT-SPECIFIC
   2236                    tag_number: 0 // [0]
   2237                },
   2238                value: [new in_window.org.pkijs.asn1.SEQUENCE({
   2239                    value: permited_array
   2240                })]
   2241            }));
   2242        }
   2243 
   2244        if("excludedSubtrees" in this)
   2245        {
   2246            var excluded_array = new Array();
   2247 
   2248            for(var i = 0; i < this.excludedSubtrees.length; i++)
   2249                excluded_array.push(this.excludedSubtrees[i].toSchema());
   2250 
   2251            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2252                optional: true,
   2253                id_block: {
   2254                    tag_class: 3, // CONTEXT-SPECIFIC
   2255                    tag_number: 1 // [1]
   2256                },
   2257                value: [new in_window.org.pkijs.asn1.SEQUENCE({
   2258                    value: excluded_array
   2259                })]
   2260            }));
   2261        }
   2262        // #endregion 
   2263 
   2264        // #region Construct and return new ASN.1 schema for this object 
   2265        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2266            value: output_array
   2267        }));
   2268        // #endregion 
   2269    };
   2270    //**************************************************************************************
   2271    in_window.org.pkijs.simpl.x509.NameConstraints.prototype.toJSON =
   2272    function()
   2273    {
   2274        var _object = {};
   2275 
   2276        if("permittedSubtrees" in this)
   2277        {
   2278            _object.permittedSubtrees = new Array();
   2279 
   2280            for(var i = 0; i < this.permittedSubtrees.length; i++)
   2281                _object.permittedSubtrees.push(this.permittedSubtrees[i].toJSON());
   2282        }
   2283 
   2284        if("excludedSubtrees" in this)
   2285        {
   2286            _object.excludedSubtrees = new Array();
   2287 
   2288            for(var i = 0; i < this.excludedSubtrees.length; i++)
   2289                _object.excludedSubtrees.push(this.excludedSubtrees[i].toJSON());
   2290        }
   2291 
   2292        return _object;
   2293    };
   2294    //**************************************************************************************
   2295    // #endregion 
   2296    //**************************************************************************************
   2297    // #region Simplified structure for "BasicConstraints" type of extension
   2298    //**************************************************************************************
   2299    in_window.org.pkijs.simpl.x509.BasicConstraints =
   2300    function()
   2301    {
   2302        // #region Internal properties of the object 
   2303        // OPTIONAL this.cA - boolean value
   2304        // OPTIONAL this.pathLenConstraint - integer value
   2305        // #endregion 
   2306 
   2307        // #region If input argument array contains "schema" for this object 
   2308        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2309            in_window.org.pkijs.simpl.x509.BasicConstraints.prototype.fromSchema.call(this, arguments[0].schema);
   2310        // #endregion 
   2311        // #region If input argument array contains "native" values for internal properties 
   2312        else
   2313        {
   2314            if(arguments[0] instanceof Object)
   2315            {
   2316                if("cA" in arguments[0])
   2317                    this.cA = arguments[0].cA;
   2318 
   2319                if("pathLenConstraint" in arguments[0])
   2320                    this.pathLenConstraint = arguments[0].pathLenConstraint;
   2321            }
   2322        }
   2323        // #endregion 
   2324    };
   2325    //**************************************************************************************
   2326    in_window.org.pkijs.simpl.x509.BasicConstraints.prototype.fromSchema =
   2327    function(schema)
   2328    {
   2329        // #region Check the schema is valid 
   2330        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2331            schema,
   2332            in_window.org.pkijs.schema.x509.BasicConstraints({
   2333                names: {
   2334                    cA: "cA",
   2335                    pathLenConstraint: "pathLenConstraint"
   2336                }
   2337            })
   2338            );
   2339 
   2340        if(asn1.verified === false)
   2341            throw new Error("Object's schema was not verified against input data for BasicConstraints");
   2342        // #endregion 
   2343 
   2344        // #region Get internal properties from parsed schema 
   2345        if("cA" in asn1.result)
   2346            this.cA = asn1.result["cA"].value_block.value;
   2347 
   2348        if("pathLenConstraint" in asn1.result)
   2349            this.pathLenConstraint = asn1.result["pathLenConstraint"].value_block.value_dec;
   2350        // #endregion 
   2351    };
   2352    //**************************************************************************************
   2353    in_window.org.pkijs.simpl.x509.BasicConstraints.prototype.toSchema =
   2354    function()
   2355    {
   2356        // #region Create array for output sequence 
   2357        var output_array = new Array();
   2358 
   2359        if("cA" in this)
   2360            output_array.push(new in_window.org.pkijs.asn1.BOOLEAN({ value: this.cA }));
   2361 
   2362        if("pathLenConstraint" in this)
   2363            output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.pathLenConstraint }));
   2364        // #endregion 
   2365 
   2366        // #region Construct and return new ASN.1 schema for this object 
   2367        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2368            value: output_array
   2369        }));
   2370        // #endregion 
   2371    };
   2372    //**************************************************************************************
   2373    in_window.org.pkijs.simpl.x509.BasicConstraints.prototype.toJSON =
   2374    function()
   2375    {
   2376        var _object = {};
   2377 
   2378        if("cA" in this)
   2379            _object.cA = this.cA;
   2380 
   2381        if("pathLenConstraint" in this)
   2382            _object.pathLenConstraint = this.pathLenConstraint;
   2383 
   2384        return _object;
   2385    };
   2386    //**************************************************************************************
   2387    // #endregion 
   2388    //**************************************************************************************
   2389    // #region Simplified structure for "PolicyQualifierInfo" type
   2390    //**************************************************************************************
   2391    in_window.org.pkijs.simpl.x509.PolicyQualifierInfo =
   2392    function()
   2393    {
   2394        // #region Internal properties of the object 
   2395        this.policyQualifierId = "";
   2396        this.qualifier = new in_window.org.pkijs.asn1.ANY();
   2397        // #endregion 
   2398 
   2399        // #region If input argument array contains "schema" for this object 
   2400        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2401            in_window.org.pkijs.simpl.x509.PolicyQualifierInfo.prototype.fromSchema.call(this, arguments[0].schema);
   2402        // #endregion 
   2403        // #region If input argument array contains "native" values for internal properties 
   2404        else
   2405        {
   2406            if(arguments[0] instanceof Object)
   2407            {
   2408                this.policyQualifierId = arguments[0].policyQualifierId || "";
   2409                this.qualifier = arguments[0].qualifier || new in_window.org.pkijs.asn1.ANY();
   2410            }
   2411        }
   2412        // #endregion 
   2413    };
   2414    //**************************************************************************************
   2415    in_window.org.pkijs.simpl.x509.PolicyQualifierInfo.prototype.fromSchema =
   2416    function(schema)
   2417    {
   2418        // #region Check the schema is valid 
   2419        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2420            schema,
   2421            in_window.org.pkijs.schema.x509.PolicyQualifierInfo({
   2422                names: {
   2423                    policyQualifierId: "policyQualifierId",
   2424                    qualifier: "qualifier"
   2425                }
   2426            })
   2427            );
   2428 
   2429        if(asn1.verified === false)
   2430            throw new Error("Object's schema was not verified against input data for PolicyQualifierInfo");
   2431        // #endregion 
   2432 
   2433        // #region Get internal properties from parsed schema 
   2434        this.policyQualifierId = asn1.result["policyQualifierId"].value_block.toString();
   2435        this.qualifier = asn1.result["qualifier"];
   2436        // #endregion 
   2437    };
   2438    //**************************************************************************************
   2439    in_window.org.pkijs.simpl.x509.PolicyQualifierInfo.prototype.toSchema =
   2440    function()
   2441    {
   2442        // #region Construct and return new ASN.1 schema for this object 
   2443        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2444            value: [
   2445                new in_window.org.pkijs.asn1.OID({ value: this.policyQualifierId }),
   2446                this.qualifier
   2447            ]
   2448        }));
   2449        // #endregion 
   2450    };
   2451    //**************************************************************************************
   2452    in_window.org.pkijs.simpl.x509.PolicyQualifierInfo.prototype.toJSON =
   2453    function()
   2454    {
   2455        return {
   2456            policyQualifierId: this.policyQualifierId,
   2457            qualifier: this.qualifier.toJSON()
   2458        };
   2459    };
   2460    //**************************************************************************************
   2461    // #endregion 
   2462    //**************************************************************************************
   2463    // #region Simplified structure for "PolicyInformation" type
   2464    //**************************************************************************************
   2465    in_window.org.pkijs.simpl.x509.PolicyInformation =
   2466    function()
   2467    {
   2468        // #region Internal properties of the object 
   2469        this.policyIdentifier = "";
   2470        // OPTIONAL this.policyQualifiers = new Array(); // Array of "simpl.x509.PolicyQualifierInfo"
   2471        // #endregion 
   2472 
   2473        // #region If input argument array contains "schema" for this object 
   2474        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2475            in_window.org.pkijs.simpl.x509.PolicyInformation.prototype.fromSchema.call(this, arguments[0].schema);
   2476        // #endregion 
   2477        // #region If input argument array contains "native" values for internal properties 
   2478        else
   2479        {
   2480            if(arguments[0] instanceof Object)
   2481            {
   2482                this.policyIdentifier = arguments[0].policyIdentifier || "";
   2483 
   2484                if("policyQualifiers" in arguments[0])
   2485                    this.policyQualifiers = arguments[0].policyQualifiers;
   2486            }
   2487        }
   2488        // #endregion 
   2489    };
   2490    //**************************************************************************************
   2491    in_window.org.pkijs.simpl.x509.PolicyInformation.prototype.fromSchema =
   2492    function(schema)
   2493    {
   2494        // #region Check the schema is valid 
   2495        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2496            schema,
   2497            in_window.org.pkijs.schema.x509.PolicyInformation({
   2498                names: {
   2499                    policyIdentifier: "policyIdentifier",
   2500                    policyQualifiers: "policyQualifiers"
   2501                }
   2502            })
   2503            );
   2504 
   2505        if(asn1.verified === false)
   2506            throw new Error("Object's schema was not verified against input data for PolicyInformation");
   2507        // #endregion 
   2508 
   2509        // #region Get internal properties from parsed schema 
   2510        this.policyIdentifier = asn1.result["policyIdentifier"].value_block.toString();
   2511 
   2512        if("policyQualifiers" in asn1.result)
   2513        {
   2514            this.policyQualifiers = new Array();
   2515            var qualifiers = asn1.result["policyQualifiers"];
   2516 
   2517            for(var i = 0; i < qualifiers.length; i++)
   2518                this.policyQualifiers.push(new in_window.org.pkijs.simpl.x509.PolicyQualifierInfo({ schema: qualifiers[i] }));
   2519        }
   2520        // #endregion 
   2521    };
   2522    //**************************************************************************************
   2523    in_window.org.pkijs.simpl.x509.PolicyInformation.prototype.toSchema =
   2524    function()
   2525    {
   2526        // #region Create array for output sequence 
   2527        var output_array = new Array();
   2528 
   2529        output_array.push(new in_window.org.pkijs.asn1.OID({ value: this.policyIdentifier }));
   2530 
   2531        if("policyQualifiers" in this)
   2532        {
   2533            var qualifiers = new Array();
   2534 
   2535            for(var i = 0; i < this.policyQualifiers.length; i++)
   2536                qualifiers.push(this.policyQualifiers[i].toSchema());
   2537 
   2538            output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
   2539                value: qualifiers
   2540            }));
   2541        }
   2542        // #endregion 
   2543 
   2544        // #region Construct and return new ASN.1 schema for this object 
   2545        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2546            value: output_array
   2547        }));
   2548        // #endregion 
   2549    };
   2550    //**************************************************************************************
   2551    in_window.org.pkijs.simpl.x509.PolicyInformation.prototype.toJSON =
   2552    function()
   2553    {
   2554        var _object = {
   2555            policyIdentifier: this.policyIdentifier
   2556        };
   2557 
   2558        if("policyQualifiers" in this)
   2559        {
   2560            _object.policyQualifiers = new Array();
   2561 
   2562            for(var i = 0; i < this.policyQualifiers.length; i++)
   2563                _object.policyQualifiers.push(this.policyQualifiers[i].toJSON());
   2564        }
   2565 
   2566        return _object;
   2567    };
   2568    //**************************************************************************************
   2569    // #endregion 
   2570    //**************************************************************************************
   2571    // #region Simplified structure for "CertificatePolicies" type of extension
   2572    //**************************************************************************************
   2573    in_window.org.pkijs.simpl.x509.CertificatePolicies =
   2574    function()
   2575    {
   2576        // #region Internal properties of the object 
   2577        this.certificatePolicies = new Array(); // Array of "simpl.x509.PolicyInformation"
   2578        // #endregion 
   2579 
   2580        // #region If input argument array contains "schema" for this object 
   2581        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2582            in_window.org.pkijs.simpl.x509.CertificatePolicies.prototype.fromSchema.call(this, arguments[0].schema);
   2583        // #endregion 
   2584        // #region If input argument array contains "native" values for internal properties 
   2585        else
   2586        {
   2587            if(arguments[0] instanceof Object)
   2588            {
   2589                this.certificatePolicies = arguments[0].certificatePolicies || new Array(); // Array of "simpl.x509.PolicyInformation"
   2590            }
   2591        }
   2592        // #endregion 
   2593    };
   2594    //**************************************************************************************
   2595    in_window.org.pkijs.simpl.x509.CertificatePolicies.prototype.fromSchema =
   2596    function(schema)
   2597    {
   2598        // #region Check the schema is valid 
   2599        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2600            schema,
   2601            in_window.org.pkijs.schema.x509.CertificatePolicies({
   2602                names: {
   2603                    certificatePolicies: "certificatePolicies"
   2604                }
   2605            })
   2606            );
   2607 
   2608        if(asn1.verified === false)
   2609            throw new Error("Object's schema was not verified against input data for CertificatePolicies");
   2610        // #endregion 
   2611 
   2612        // #region Get internal properties from parsed schema
   2613        var policies = asn1.result["certificatePolicies"];
   2614 
   2615        for(var i = 0; i < policies.length; i++)
   2616            this.certificatePolicies.push(new in_window.org.pkijs.simpl.x509.PolicyInformation({ schema: policies[i] }));
   2617        // #endregion 
   2618    };
   2619    //**************************************************************************************
   2620    in_window.org.pkijs.simpl.x509.CertificatePolicies.prototype.toSchema =
   2621    function()
   2622    {
   2623        // #region Create array for output sequence 
   2624        var output_array = new Array();
   2625 
   2626        for(var i = 0; i < this.certificatePolicies.length; i++)
   2627            output_array.push(this.certificatePolicies[i].toSchema());
   2628        // #endregion 
   2629 
   2630        // #region Construct and return new ASN.1 schema for this object 
   2631        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2632            value: output_array
   2633        }));
   2634        // #endregion 
   2635    };
   2636    //**************************************************************************************
   2637    in_window.org.pkijs.simpl.x509.CertificatePolicies.prototype.toJSON =
   2638    function()
   2639    {
   2640        var _object = {
   2641            certificatePolicies: new Array()
   2642        };
   2643 
   2644        for(var i = 0; i < this.certificatePolicies.length; i++)
   2645            _object.certificatePolicies.push(this.certificatePolicies[i].toJSON());
   2646 
   2647        return _object;
   2648    };
   2649    //**************************************************************************************
   2650    // #endregion 
   2651    //**************************************************************************************
   2652    // #region Simplified structure for "PolicyConstraints" type of extension
   2653    //**************************************************************************************
   2654    in_window.org.pkijs.simpl.x509.PolicyConstraints =
   2655    function()
   2656    {
   2657        // #region Internal properties of the object 
   2658        // OPTIONAL this.requireExplicitPolicy = 0;
   2659        // OPTIONAL this.inhibitPolicyMapping = 0;
   2660        // #endregion 
   2661 
   2662        // #region If input argument array contains "schema" for this object 
   2663        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2664            in_window.org.pkijs.simpl.x509.PolicyConstraints.prototype.fromSchema.call(this, arguments[0].schema);
   2665        // #endregion 
   2666        // #region If input argument array contains "native" values for internal properties 
   2667        else
   2668        {
   2669            if(arguments[0] instanceof Object)
   2670            {
   2671                this.requireExplicitPolicy = arguments[0].requireExplicitPolicy || 0;
   2672                this.inhibitPolicyMapping = arguments[0].inhibitPolicyMapping || 0;
   2673            }
   2674        }
   2675        // #endregion 
   2676    };
   2677    //**************************************************************************************
   2678    in_window.org.pkijs.simpl.x509.PolicyConstraints.prototype.fromSchema =
   2679    function(schema)
   2680    {
   2681        // #region Check the schema is valid 
   2682        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2683            schema,
   2684            in_window.org.pkijs.schema.x509.PolicyConstraints({
   2685                names: {
   2686                    requireExplicitPolicy: "requireExplicitPolicy",
   2687                    inhibitPolicyMapping: "inhibitPolicyMapping"
   2688                }
   2689            })
   2690            );
   2691 
   2692        if(asn1.verified === false)
   2693            throw new Error("Object's schema was not verified against input data for PolicyConstraints");
   2694        // #endregion 
   2695 
   2696        // #region Get internal properties from parsed schema
   2697        if("requireExplicitPolicy" in asn1.result)
   2698        {
   2699            var field1 = asn1.result["requireExplicitPolicy"];
   2700 
   2701            field1.id_block.tag_class = 1; // UNIVERSAL
   2702            field1.id_block.tag_number = 2; // INTEGER
   2703 
   2704            var ber1 = field1.toBER(false);
   2705            var int1 = in_window.org.pkijs.fromBER(ber1);
   2706 
   2707            this.requireExplicitPolicy = int1.result.value_block.value_dec;
   2708        }
   2709 
   2710        if("inhibitPolicyMapping" in asn1.result)
   2711        {
   2712            var field2 = asn1.result["inhibitPolicyMapping"];
   2713 
   2714            field2.id_block.tag_class = 1; // UNIVERSAL
   2715            field2.id_block.tag_number = 2; // INTEGER
   2716 
   2717            var ber2 = field2.toBER(false);
   2718            var int2 = in_window.org.pkijs.fromBER(ber2);
   2719 
   2720            this.inhibitPolicyMapping = int2.result.value_block.value_dec;
   2721        }
   2722        // #endregion 
   2723    };
   2724    //**************************************************************************************
   2725    in_window.org.pkijs.simpl.x509.PolicyConstraints.prototype.toSchema =
   2726    function()
   2727    {
   2728        // #region Create correct values for output sequence 
   2729        var output_array = new Array();
   2730 
   2731        if("requireExplicitPolicy" in this)
   2732        {
   2733            var int1 = new in_window.org.pkijs.asn1.INTEGER({ value: this.requireExplicitPolicy });
   2734 
   2735            int1.id_block.tag_class = 3; // CONTEXT-SPECIFIC
   2736            int1.id_block.tag_number = 0; // [0]
   2737 
   2738            output_array.push(int1);
   2739        }
   2740 
   2741        if("inhibitPolicyMapping" in this)
   2742        {
   2743            var int2 = new in_window.org.pkijs.asn1.INTEGER({ value: this.inhibitPolicyMapping });
   2744 
   2745            int1.id_block.tag_class = 3; // CONTEXT-SPECIFIC
   2746            int1.id_block.tag_number = 1; // [1]
   2747 
   2748            output_array.push(int2);
   2749        }
   2750        // #endregion 
   2751 
   2752        // #region Construct and return new ASN.1 schema for this object 
   2753        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2754            value: output_array
   2755        }));
   2756        // #endregion 
   2757    };
   2758    //**************************************************************************************
   2759    in_window.org.pkijs.simpl.x509.PolicyConstraints.prototype.toJSON =
   2760    function()
   2761    {
   2762        var _object = {};
   2763 
   2764        if("requireExplicitPolicy" in this)
   2765            _object.requireExplicitPolicy = this.requireExplicitPolicy;
   2766 
   2767        if("inhibitPolicyMapping" in this)
   2768            _object.inhibitPolicyMapping = this.inhibitPolicyMapping;
   2769 
   2770        return _object;
   2771    };
   2772    //**************************************************************************************
   2773    // #endregion 
   2774    //**************************************************************************************
   2775    // #region Simplified structure for "ExtKeyUsage" type of extension
   2776    //**************************************************************************************
   2777    in_window.org.pkijs.simpl.x509.ExtKeyUsage =
   2778    function()
   2779    {
   2780        // #region Internal properties of the object 
   2781        this.keyPurposes = new Array(); // Array of strings (OIDs value for key purposes)
   2782        // #endregion 
   2783 
   2784        // #region If input argument array contains "schema" for this object 
   2785        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2786            in_window.org.pkijs.simpl.x509.ExtKeyUsage.prototype.fromSchema.call(this, arguments[0].schema);
   2787        // #endregion 
   2788        // #region If input argument array contains "native" values for internal properties 
   2789        else
   2790        {
   2791            if(arguments[0] instanceof Object)
   2792            {
   2793                this.keyPurposes = arguments[0].keyPurposes || new Array(); // Array of strings (OIDs value for key purposes)
   2794            }
   2795        }
   2796        // #endregion 
   2797    };
   2798    //**************************************************************************************
   2799    in_window.org.pkijs.simpl.x509.ExtKeyUsage.prototype.fromSchema =
   2800    function(schema)
   2801    {
   2802        // #region Check the schema is valid 
   2803        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2804            schema,
   2805            in_window.org.pkijs.schema.x509.ExtKeyUsage({
   2806                names: {
   2807                    keyPurposes: "keyPurposes"
   2808                }
   2809            })
   2810            );
   2811 
   2812        if(asn1.verified === false)
   2813            throw new Error("Object's schema was not verified against input data for ExtKeyUsage");
   2814        // #endregion 
   2815 
   2816        // #region Get internal properties from parsed schema 
   2817        var purposes = asn1.result["keyPurposes"];
   2818 
   2819        for(var i = 0; i < purposes.length; i++)
   2820            this.keyPurposes.push(purposes[i].value_block.toString());
   2821        // #endregion 
   2822    };
   2823    //**************************************************************************************
   2824    in_window.org.pkijs.simpl.x509.ExtKeyUsage.prototype.toSchema =
   2825    function()
   2826    {
   2827        // #region Create array for output sequence 
   2828        var output_array = new Array();
   2829 
   2830        for(var i = 0; i < this.keyPurposes.length; i++)
   2831            output_array.push(new in_window.org.pkijs.asn1.OID({ value: this.keyPurposes[i] }));
   2832        // #endregion 
   2833 
   2834        // #region Construct and return new ASN.1 schema for this object 
   2835        return (new in_window.org.pkijs.asn1.SEQUENCE({
   2836            value: output_array
   2837        }));
   2838        // #endregion 
   2839    };
   2840    //**************************************************************************************
   2841    in_window.org.pkijs.simpl.x509.ExtKeyUsage.prototype.toJSON =
   2842    function()
   2843    {
   2844        var _object = {
   2845            keyPurposes: new Array()
   2846        };
   2847 
   2848        for(var i = 0; i < this.keyPurposes.length; i++)
   2849            _object.keyPurposes.push(this.keyPurposes[i]);
   2850 
   2851        return _object;
   2852    };
   2853    //**************************************************************************************
   2854    // #endregion 
   2855    //**************************************************************************************
   2856    // #region Simplified structure for "DistributionPoint" type
   2857    //**************************************************************************************
   2858    in_window.org.pkijs.simpl.x509.DistributionPoint =
   2859    function()
   2860    {
   2861        // #region Internal properties of the object 
   2862        // OPTIONAL this.distributionPoint // Array of "simpl.GENERAL_NAME" or a value of "simpl.RDN" type
   2863        // OPTIONAL this.reasons // BITSTRING value
   2864        // OPTIONAL this.cRLIssuer // Array of "simpl.GENERAL_NAME"
   2865        // #endregion 
   2866 
   2867        // #region If input argument array contains "schema" for this object 
   2868        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   2869            in_window.org.pkijs.simpl.x509.DistributionPoint.prototype.fromSchema.call(this, arguments[0].schema);
   2870        // #endregion 
   2871        // #region If input argument array contains "native" values for internal properties 
   2872        else
   2873        {
   2874            if(arguments[0] instanceof Object)
   2875            {
   2876                if("distributionPoint" in arguments[0])
   2877                    this.distributionPoint = arguments[0].distributionPoint;
   2878 
   2879                if("reasons" in arguments[0])
   2880                    this.reasons = arguments[0].reasons;
   2881 
   2882                if("cRLIssuer" in arguments[0])
   2883                    this.cRLIssuer = arguments[0].cRLIssuer;
   2884            }
   2885        }
   2886        // #endregion 
   2887    };
   2888    //**************************************************************************************
   2889    in_window.org.pkijs.simpl.x509.DistributionPoint.prototype.fromSchema =
   2890    function(schema)
   2891    {
   2892        // #region Check the schema is valid 
   2893        var asn1 = in_window.org.pkijs.compareSchema(schema,
   2894            schema,
   2895            in_window.org.pkijs.schema.x509.DistributionPoint({
   2896                names: {
   2897                    distributionPoint: "distributionPoint",
   2898                    distributionPoint_names: "distributionPoint_names",
   2899                    reasons: "reasons",
   2900                    cRLIssuer: "cRLIssuer",
   2901                    cRLIssuer_names: "cRLIssuer_names"
   2902                }
   2903            })
   2904            );
   2905 
   2906        if(asn1.verified === false)
   2907            throw new Error("Object's schema was not verified against input data for DistributionPoint");
   2908        // #endregion 
   2909 
   2910        // #region Get internal properties from parsed schema 
   2911        if("distributionPoint" in asn1.result)
   2912        {
   2913            if(asn1.result["distributionPoint"].id_block.tag_number == 0) // GENERAL_NAMES variant
   2914            {
   2915                this.distributionPoint = new Array();
   2916                var names = asn1.result["distributionPoint_names"];
   2917 
   2918                for(var i = 0; i < names.length; i++)
   2919                    this.distributionPoint.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: names[i] }));
   2920            }
   2921 
   2922            if(asn1.result["distributionPoint"].id_block.tag_number == 1) // RDN variant
   2923            {
   2924                asn1.result["distributionPoint"].id_block.tag_class = 1; // UNIVERSAL
   2925                asn1.result["distributionPoint"].id_block.tag_number = 16; // SEQUENCE
   2926 
   2927                this.distributionPoint = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["distributionPoint"] });
   2928            }
   2929        }
   2930 
   2931        if("reasons" in asn1.result)
   2932            this.reasons = new in_window.org.pkijs.asn1.BITSTRING({ value_hex: asn1.result["reasons"].value_block.value_hex });
   2933 
   2934        if("cRLIssuer" in asn1.result)
   2935        {
   2936            this.cRLIssuer = new Array();
   2937            var crl_names = asn1.result["cRLIssuer_names"];
   2938 
   2939            for(var i = 0; i < crl_names; i++)
   2940                this.cRLIssuer.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: crl_names[i] }));
   2941        }
   2942        // #endregion 
   2943    };
   2944    //**************************************************************************************
   2945    in_window.org.pkijs.simpl.x509.DistributionPoint.prototype.toSchema =
   2946    function()
   2947    {
   2948        // #region Create array for output sequence 
   2949        var output_array = new Array();
   2950 
   2951        if("distributionPoint" in this)
   2952        {
   2953            var internalValue;
   2954 
   2955            if(this.distributionPoint instanceof Array)
   2956            {
   2957                var namesArray = new Array();
   2958 
   2959                for(var i = 0; i < this.distributionPoint.length; i++)
   2960                    namesArray.push(this.distributionPoint[i].toSchema());
   2961 
   2962                internalValue = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2963                    id_block: {
   2964                        tag_class: 3, // CONTEXT-SPECIFIC
   2965                        tag_number: 0 // [0]
   2966                    },
   2967                    value: namesArray
   2968                });
   2969            }
   2970            else
   2971            {
   2972                internalValue = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2973                    id_block: {
   2974                        tag_class: 3, // CONTEXT-SPECIFIC
   2975                        tag_number: 1 // [1]
   2976                    },
   2977                    value: [this.distributionPoint.toSchema()]
   2978                });
   2979            }
   2980 
   2981            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   2982                id_block: {
   2983                    tag_class: 3, // CONTEXT-SPECIFIC
   2984                    tag_number: 0 // [0]
   2985                },
   2986                value: [internalValue]
   2987            }));
   2988        }
   2989 
   2990        if("reasons" in this)
   2991        {
   2992            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   2993                id_block: {
   2994                    tag_class: 3, // CONTEXT-SPECIFIC
   2995                    tag_number: 1 // [1]
   2996                },
   2997                value_hex: this.reasons.value_block.value_hex
   2998            }));
   2999        }
   3000 
   3001        if("cRLIssuer" in this)
   3002        {
   3003            var value = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   3004                id_block: {
   3005                    tag_class: 3, // CONTEXT-SPECIFIC
   3006                    tag_number: 2 // [2]
   3007                }
   3008            });
   3009 
   3010            for(var i = 0; i < this.cRLIssuer.length; i++)
   3011                value.value_block.value.push(this.cRLIssuer[i].toSchema());
   3012 
   3013            output_array.push(value);
   3014        }
   3015        // #endregion 
   3016 
   3017        // #region Construct and return new ASN.1 schema for this object 
   3018        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3019            value: output_array
   3020        }));
   3021        // #endregion 
   3022    };
   3023    //**************************************************************************************
   3024    in_window.org.pkijs.simpl.x509.DistributionPoint.prototype.toJSON =
   3025    function()
   3026    {
   3027        var _object = {};
   3028 
   3029        if("distributionPoint" in this)
   3030        {
   3031            if(this.distributionPoint instanceof Array)
   3032            {
   3033                _object.distributionPoint = new Array();
   3034 
   3035                for(var i = 0; i < this.distributionPoint.length; i++)
   3036                    _object.distributionPoint.push(this.distributionPoint[i].toJSON());
   3037            }
   3038            else
   3039                _object.distributionPoint = this.distributionPoint.toJSON();
   3040        }
   3041 
   3042        if("reasons" in this)
   3043            _object.reasons = this.reasons.toJSON();
   3044 
   3045        if("cRLIssuer" in this)
   3046        {
   3047            _object.cRLIssuer = new Array();
   3048 
   3049            for(var i = 0; i < this.cRLIssuer.length; i++)
   3050                _object.cRLIssuer.push(this.cRLIssuer[i].toJSON());
   3051        }
   3052 
   3053        return _object;
   3054    };
   3055    //**************************************************************************************
   3056    // #endregion 
   3057    //**************************************************************************************
   3058    // #region Simplified structure for "CRLDistributionPoints" type of extension
   3059    //**************************************************************************************
   3060    in_window.org.pkijs.simpl.x509.CRLDistributionPoints =
   3061    function()
   3062    {
   3063        // #region Internal properties of the object 
   3064        this.distributionPoints = new Array(); // Array of "simpl.x509.DistributionPoint"
   3065        // #endregion 
   3066 
   3067        // #region If input argument array contains "schema" for this object 
   3068        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3069            in_window.org.pkijs.simpl.x509.CRLDistributionPoints.prototype.fromSchema.call(this, arguments[0].schema);
   3070        // #endregion 
   3071        // #region If input argument array contains "native" values for internal properties 
   3072        else
   3073        {
   3074            if(arguments[0] instanceof Object)
   3075            {
   3076                this.distributionPoints = arguments[0].distributionPoints || new Array(); // Array of "simpl.x509.DistributionPoint"
   3077            }
   3078        }
   3079        // #endregion 
   3080    };
   3081    //**************************************************************************************
   3082    in_window.org.pkijs.simpl.x509.CRLDistributionPoints.prototype.fromSchema =
   3083    function(schema)
   3084    {
   3085        // #region Check the schema is valid 
   3086        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3087            schema,
   3088            in_window.org.pkijs.schema.x509.CRLDistributionPoints({
   3089                names: {
   3090                    distributionPoints: "distributionPoints"
   3091                }
   3092            })
   3093            );
   3094 
   3095        if(asn1.verified === false)
   3096            throw new Error("Object's schema was not verified against input data for CRLDistributionPoints");
   3097        // #endregion 
   3098 
   3099        // #region Get internal properties from parsed schema 
   3100        var points = asn1.result["distributionPoints"];
   3101 
   3102        for(var i = 0; i < points.length; i++)
   3103            this.distributionPoints.push(new in_window.org.pkijs.simpl.x509.DistributionPoint({ schema: points[i] }));
   3104        // #endregion 
   3105    };
   3106    //**************************************************************************************
   3107    in_window.org.pkijs.simpl.x509.CRLDistributionPoints.prototype.toSchema =
   3108    function()
   3109    {
   3110        // #region Create array for output sequence 
   3111        var output_array = new Array();
   3112 
   3113        for(var i = 0; i < this.distributionPoints.length; i++)
   3114            output_array.push(this.distributionPoints[i].toSchema());
   3115        // #endregion 
   3116 
   3117        // #region Construct and return new ASN.1 schema for this object 
   3118        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3119            value: output_array
   3120        }));
   3121        // #endregion 
   3122    };
   3123    //**************************************************************************************
   3124    in_window.org.pkijs.simpl.x509.CRLDistributionPoints.prototype.toJSON =
   3125    function()
   3126    {
   3127        var _object = {
   3128            distributionPoints: new Array()
   3129        };
   3130 
   3131        for(var i = 0; i < this.distributionPoints.length; i++)
   3132            _object.distributionPoints.push(this.distributionPoints[i].toJSON());
   3133 
   3134        return _object;
   3135    };
   3136    //**************************************************************************************
   3137    // #endregion 
   3138    //**************************************************************************************
   3139    // #region Simplified structure for "AccessDescription" type
   3140    //**************************************************************************************
   3141    in_window.org.pkijs.simpl.x509.AccessDescription =
   3142    function()
   3143    {
   3144        // #region Internal properties of the object 
   3145        this.accessMethod = "";
   3146        this.accessLocation = new in_window.org.pkijs.simpl.GENERAL_NAME();
   3147        // #endregion 
   3148 
   3149        // #region If input argument array contains "schema" for this object 
   3150        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3151            in_window.org.pkijs.simpl.x509.AccessDescription.prototype.fromSchema.call(this, arguments[0].schema);
   3152        // #endregion 
   3153        // #region If input argument array contains "native" values for internal properties 
   3154        else
   3155        {
   3156            if(arguments[0] instanceof Object)
   3157            {
   3158                this.accessMethod = arguments[0].accessMethod || "";
   3159                this.accessLocation = arguments[0].accessLocation || new in_window.org.pkijs.simpl.GENERAL_NAME();
   3160            }
   3161        }
   3162        // #endregion 
   3163    };
   3164    //**************************************************************************************
   3165    in_window.org.pkijs.simpl.x509.AccessDescription.prototype.fromSchema =
   3166    function(schema)
   3167    {
   3168        // #region Check the schema is valid 
   3169        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3170            schema,
   3171            in_window.org.pkijs.schema.x509.AccessDescription({
   3172                names: {
   3173                    accessMethod: "accessMethod",
   3174                    accessLocation: {
   3175                        names: {
   3176                            block_name: "accessLocation"
   3177                        }
   3178                    }
   3179                }
   3180            })
   3181            );
   3182 
   3183        if(asn1.verified === false)
   3184            throw new Error("Object's schema was not verified against input data for AccessDescription");
   3185        // #endregion 
   3186 
   3187        // #region Get internal properties from parsed schema 
   3188        this.accessMethod = asn1.result["accessMethod"].value_block.toString();
   3189        this.accessLocation = new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: asn1.result["accessLocation"] });
   3190        // #endregion 
   3191    };
   3192    //**************************************************************************************
   3193    in_window.org.pkijs.simpl.x509.AccessDescription.prototype.toSchema =
   3194    function()
   3195    {
   3196        // #region Construct and return new ASN.1 schema for this object 
   3197        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3198            value: [
   3199                new in_window.org.pkijs.asn1.OID({ value: this.accessMethod }),
   3200                this.accessLocation.toSchema()
   3201            ]
   3202        }));
   3203        // #endregion 
   3204    };
   3205    //**************************************************************************************
   3206    in_window.org.pkijs.simpl.x509.AccessDescription.prototype.toJSON =
   3207    function()
   3208    {
   3209        return {
   3210            accessMethod: this.accessMethod,
   3211            accessLocation: this.accessLocation.toJSON()
   3212        };
   3213    };
   3214    //**************************************************************************************
   3215    // #endregion 
   3216    //**************************************************************************************
   3217    // #region Simplified structure for "AuthorityInfoAccess" and "SubjectInfoAccess" types of extension
   3218    //**************************************************************************************
   3219    in_window.org.pkijs.simpl.x509.InfoAccess =
   3220    function()
   3221    {
   3222        // #region Internal properties of the object 
   3223        this.accessDescriptions = new Array(); // Array of "simpl.x509.AccessDescription"
   3224        // #endregion 
   3225 
   3226        // #region If input argument array contains "schema" for this object 
   3227        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3228            in_window.org.pkijs.simpl.x509.InfoAccess.prototype.fromSchema.call(this, arguments[0].schema);
   3229        // #endregion 
   3230        // #region If input argument array contains "native" values for internal properties 
   3231        else
   3232        {
   3233            if(arguments[0] instanceof Object)
   3234            {
   3235                this.accessDescriptions = arguments[0].accessDescriptions || new Array(); // Array of "simpl.x509.DistributionPoint"
   3236            }
   3237        }
   3238        // #endregion 
   3239    };
   3240    //**************************************************************************************
   3241    in_window.org.pkijs.simpl.x509.InfoAccess.prototype.fromSchema =
   3242    function(schema)
   3243    {
   3244        // #region Check the schema is valid 
   3245        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3246            schema,
   3247            in_window.org.pkijs.schema.x509.InfoAccess({
   3248                names: {
   3249                    accessDescriptions: "accessDescriptions"
   3250                }
   3251            })
   3252            );
   3253 
   3254        if(asn1.verified === false)
   3255            throw new Error("Object's schema was not verified against input data for InfoAccess");
   3256        // #endregion 
   3257 
   3258        // #region Get internal properties from parsed schema 
   3259        var descriptions = asn1.result["accessDescriptions"];
   3260 
   3261        for(var i = 0; i < descriptions.length; i++)
   3262            this.accessDescriptions.push(new in_window.org.pkijs.simpl.x509.AccessDescription({ schema: descriptions[i] }));
   3263        // #endregion 
   3264    };
   3265    //**************************************************************************************
   3266    in_window.org.pkijs.simpl.x509.InfoAccess.prototype.toSchema =
   3267    function()
   3268    {
   3269        // #region Create array for output sequence 
   3270        var output_array = new Array();
   3271 
   3272        for(var i = 0; i < this.accessDescriptions.length; i++)
   3273            output_array.push(this.accessDescriptions[i].toSchema());
   3274        // #endregion 
   3275 
   3276        // #region Construct and return new ASN.1 schema for this object 
   3277        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3278            value: output_array
   3279        }));
   3280        // #endregion 
   3281    };
   3282    //**************************************************************************************
   3283    in_window.org.pkijs.simpl.x509.InfoAccess.prototype.toJSON =
   3284    function()
   3285    {
   3286        var _object = {
   3287            accessDescriptions: new Array()
   3288        };
   3289 
   3290        for(var i = 0; i < this.accessDescriptions.length; i++)
   3291            _object.accessDescriptions.push(this.accessDescriptions[i].toJSON());
   3292 
   3293        return _object;
   3294    };
   3295    //**************************************************************************************
   3296    // #endregion 
   3297    //**************************************************************************************
   3298    // #region Simplified structure for "IssuingDistributionPoint" type of extension
   3299    //**************************************************************************************
   3300    in_window.org.pkijs.simpl.x509.IssuingDistributionPoint =
   3301    function()
   3302    {
   3303        // #region Internal properties of the object 
   3304        // OPTIONAL this.distributionPoint // Array of "simpl.GENERAL_NAME" or a value of "simpl.RDN" type
   3305        // OPTIONAL this.onlyContainsUserCerts // BOOLEAN flag
   3306        // OPTIONAL this.onlyContainsCACerts // BOOLEAN flag
   3307        // OPTIONAL this.onlySomeReasons // BITSTRING
   3308        // OPTIONAL this.indirectCRL // BOOLEAN flag
   3309        // OPTIONAL this.onlyContainsAttributeCerts // BOOLEAN flag
   3310        // #endregion 
   3311 
   3312        // #region If input argument array contains "schema" for this object 
   3313        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3314            in_window.org.pkijs.simpl.x509.IssuingDistributionPoint.prototype.fromSchema.call(this, arguments[0].schema);
   3315        // #endregion 
   3316        // #region If input argument array contains "native" values for internal properties 
   3317        else
   3318        {
   3319            if(arguments[0] instanceof Object)
   3320            {
   3321                if("distributionPoint" in arguments[0])
   3322                    this.distributionPoint = arguments[0].distributionPoint;
   3323 
   3324                if("onlyContainsUserCerts" in arguments[0])
   3325                    this.onlyContainsUserCerts = arguments[0].onlyContainsUserCerts;
   3326 
   3327                if("onlyContainsCACerts" in arguments[0])
   3328                    this.onlyContainsCACerts = arguments[0].onlyContainsCACerts;
   3329 
   3330                if("onlySomeReasons" in arguments[0])
   3331                    this.onlySomeReasons = arguments[0].onlySomeReasons;
   3332 
   3333                if("indirectCRL" in arguments[0])
   3334                    this.indirectCRL = arguments[0].indirectCRL;
   3335 
   3336                if("onlyContainsAttributeCerts" in arguments[0])
   3337                    this.onlyContainsAttributeCerts = arguments[0].onlyContainsAttributeCerts;
   3338            }
   3339        }
   3340        // #endregion 
   3341    };
   3342    //**************************************************************************************
   3343    in_window.org.pkijs.simpl.x509.IssuingDistributionPoint.prototype.fromSchema =
   3344    function(schema)
   3345    {
   3346        // #region Check the schema is valid 
   3347        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3348            schema,
   3349            in_window.org.pkijs.schema.x509.IssuingDistributionPoint({
   3350                names: {
   3351                    distributionPoint: "distributionPoint",
   3352                    distributionPoint_names: "distributionPoint_names",
   3353                    onlyContainsUserCerts: "onlyContainsUserCerts",
   3354                    onlyContainsCACerts: "onlyContainsCACerts",
   3355                    onlySomeReasons: "onlySomeReasons",
   3356                    indirectCRL: "indirectCRL",
   3357                    onlyContainsAttributeCerts: "onlyContainsAttributeCerts"
   3358                }
   3359            })
   3360            );
   3361 
   3362        if(asn1.verified === false)
   3363            throw new Error("Object's schema was not verified against input data for IssuingDistributionPoint");
   3364        // #endregion 
   3365 
   3366        // #region Get internal properties from parsed schema 
   3367        if("distributionPoint" in asn1.result)
   3368        {
   3369            if(asn1.result["distributionPoint"].id_block.tag_number == 0) // GENERAL_NAMES variant
   3370            {
   3371                this.distributionPoint = new Array();
   3372                var names = asn1.result["distributionPoint_names"];
   3373 
   3374                for(var i = 0; i < names.length; i++)
   3375                    this.distributionPoint.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: names[i] }));
   3376            }
   3377 
   3378            if(asn1.result["distributionPoint"].id_block.tag_number == 1) // RDN variant
   3379            {
   3380                asn1.result["distributionPoint"].id_block.tag_class = 1; // UNIVERSAL
   3381                asn1.result["distributionPoint"].id_block.tag_number = 16; // SEQUENCE
   3382 
   3383                this.distributionPoint = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["distributionPoint"] });
   3384            }
   3385        }
   3386 
   3387        if("onlyContainsUserCerts" in asn1.result)
   3388        {
   3389            var view = new Uint8Array(asn1.result["onlyContainsUserCerts"].value_block.value_hex);
   3390            this.onlyContainsUserCerts = (view[0] !== 0x00);
   3391        }
   3392 
   3393        if("onlyContainsCACerts" in asn1.result)
   3394        {
   3395            var view = new Uint8Array(asn1.result["onlyContainsCACerts"].value_block.value_hex);
   3396            this.onlyContainsCACerts = (view[0] !== 0x00);
   3397        }
   3398 
   3399        if("onlySomeReasons" in asn1.result)
   3400        {
   3401            var view = new Uint8Array(asn1.result["onlySomeReasons"].value_block.value_hex);
   3402            this.onlySomeReasons = view[0];
   3403        }
   3404 
   3405        if("indirectCRL" in asn1.result)
   3406        {
   3407            var view = new Uint8Array(asn1.result["indirectCRL"].value_block.value_hex);
   3408            this.indirectCRL = (view[0] !== 0x00);
   3409        }
   3410 
   3411        if("onlyContainsAttributeCerts" in asn1.result)
   3412        {
   3413            var view = new Uint8Array(asn1.result["onlyContainsAttributeCerts"].value_block.value_hex);
   3414            this.onlyContainsAttributeCerts = (view[0] !== 0x00);
   3415        }
   3416        // #endregion 
   3417    };
   3418    //**************************************************************************************
   3419    in_window.org.pkijs.simpl.x509.IssuingDistributionPoint.prototype.toSchema =
   3420    function()
   3421    {
   3422        // #region Create array for output sequence 
   3423        var output_array = new Array();
   3424 
   3425        if("distributionPoint" in this)
   3426        {
   3427            var value;
   3428 
   3429            if(this.distributionPoint instanceof Array)
   3430            {
   3431                value = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   3432                    id_block: {
   3433                        tag_class: 3, // CONTEXT-SPECIFIC
   3434                        tag_number: 0 // [0]
   3435                    }
   3436                });
   3437 
   3438                for(var i = 0; i < this.distributionPoint.length; i++)
   3439                    value.value_block.value.push(this.distributionPoint[i].toSchema());
   3440            }
   3441            else
   3442            {
   3443                value = this.distributionPoint.toSchema();
   3444 
   3445                value.id_block.tag_class = 3; // CONTEXT - SPECIFIC
   3446                value.id_block.tag_number = 1; // [1]
   3447            }
   3448 
   3449            output_array.push(value);
   3450        }
   3451 
   3452        if("onlyContainsUserCerts" in this)
   3453        {
   3454            var buffer = new ArrayBuffer(1);
   3455            var view = new Uint8Array(buffer);
   3456 
   3457            view[0] = (this.onlyContainsUserCerts === false) ? 0x00 : 0xFF;
   3458 
   3459            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3460                id_block: {
   3461                    tag_class: 3, // CONTEXT-SPECIFIC
   3462                    tag_number: 1 // [1]
   3463                },
   3464                value_hex: buffer
   3465            }));
   3466        }
   3467 
   3468        if("onlyContainsCACerts" in this)
   3469        {
   3470            var buffer = new ArrayBuffer(1);
   3471            var view = new Uint8Array(buffer);
   3472 
   3473            view[0] = (this.onlyContainsCACerts === false) ? 0x00 : 0xFF;
   3474 
   3475            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3476                id_block: {
   3477                    tag_class: 3, // CONTEXT-SPECIFIC
   3478                    tag_number: 2 // [2]
   3479                },
   3480                value_hex: buffer
   3481            }));
   3482        }
   3483 
   3484        if("onlySomeReasons" in this)
   3485        {
   3486            var buffer = new ArrayBuffer(1);
   3487            var view = new Uint8Array(buffer);
   3488 
   3489            view[0] = this.onlySomeReasons;
   3490 
   3491            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3492                id_block: {
   3493                    tag_class: 3, // CONTEXT-SPECIFIC
   3494                    tag_number: 3 // [3]
   3495                },
   3496                value_hex: buffer
   3497            }));
   3498        }
   3499 
   3500        if("indirectCRL" in this)
   3501        {
   3502            var buffer = new ArrayBuffer(1);
   3503            var view = new Uint8Array(buffer);
   3504 
   3505            view[0] = (this.indirectCRL === false) ? 0x00 : 0xFF;
   3506 
   3507            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3508                id_block: {
   3509                    tag_class: 3, // CONTEXT-SPECIFIC
   3510                    tag_number: 4 // [4]
   3511                },
   3512                value_hex: buffer
   3513            }));
   3514        }
   3515 
   3516        if("onlyContainsAttributeCerts" in this)
   3517        {
   3518            var buffer = new ArrayBuffer(1);
   3519            var view = new Uint8Array(buffer);
   3520 
   3521            view[0] = (this.onlyContainsAttributeCerts === false) ? 0x00 : 0xFF;
   3522 
   3523            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3524                id_block: {
   3525                    tag_class: 3, // CONTEXT-SPECIFIC
   3526                    tag_number: 5 // [5]
   3527                },
   3528                value_hex: buffer
   3529            }));
   3530        }
   3531        // #endregion 
   3532 
   3533        // #region Construct and return new ASN.1 schema for this object 
   3534        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3535            value: output_array
   3536        }));
   3537        // #endregion 
   3538    };
   3539    //**************************************************************************************
   3540    in_window.org.pkijs.simpl.x509.IssuingDistributionPoint.prototype.toJSON =
   3541    function()
   3542    {
   3543        var _object = {};
   3544 
   3545        if("distributionPoint" in this)
   3546        {
   3547            if(this.distributionPoint instanceof Array)
   3548            {
   3549                _object.distributionPoint = new Array();
   3550 
   3551                for(var i = 0; i < this.distributionPoint.length; i++)
   3552                    _object.distributionPoint.push(this.distributionPoint[i].toJSON());
   3553            }
   3554            else
   3555                _object.distributionPoint = this.distributionPoint.toJSON();
   3556        }
   3557 
   3558        if("onlyContainsUserCerts" in this)
   3559            _object.onlyContainsUserCerts = this.onlyContainsUserCerts;
   3560 
   3561        if("onlyContainsCACerts" in this)
   3562            _object.onlyContainsCACerts = this.onlyContainsCACerts;
   3563 
   3564        if("onlySomeReasons" in this)
   3565            _object.onlySomeReasons = this.onlySomeReasons.toJSON();
   3566 
   3567        if("indirectCRL" in this)
   3568            _object.indirectCRL = this.indirectCRL;
   3569 
   3570        if("onlyContainsAttributeCerts" in this)
   3571            _object.onlyContainsAttributeCerts = this.onlyContainsAttributeCerts;
   3572 
   3573        return _object;
   3574    };
   3575    //**************************************************************************************
   3576    // #endregion 
   3577    //**************************************************************************************
   3578    // #region Simplified structure for "Extension" type
   3579    //**************************************************************************************
   3580    in_window.org.pkijs.simpl.EXTENSION =
   3581    function()
   3582    {
   3583        // #region Internal properties of the object 
   3584        this.extnID = "";
   3585        this.critical = false;
   3586        this.extnValue = new in_window.org.pkijs.asn1.OCTETSTRING();
   3587 
   3588        // OPTIONAL this.parsedValue - Parsed "extnValue" in case of well-known "extnID"
   3589        // #endregion 
   3590 
   3591        // #region If input argument array contains "schema" for this object 
   3592        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3593            in_window.org.pkijs.simpl.EXTENSION.prototype.fromSchema.call(this, arguments[0].schema);
   3594        // #endregion 
   3595        // #region If input argument array contains "native" values for internal properties 
   3596        else
   3597        {
   3598            if(arguments[0] instanceof Object)
   3599            {
   3600                this.extnID = (arguments[0].extnID || "");
   3601                this.critical = (arguments[0].critical || false);
   3602                if("extnValue" in arguments[0])
   3603                    this.extnValue = new in_window.org.pkijs.asn1.OCTETSTRING({ value_hex: arguments[0].extnValue });
   3604                else
   3605                    this.extnValue = new in_window.org.pkijs.asn1.OCTETSTRING();
   3606 
   3607                if("parsedValue" in arguments[0])
   3608                    this.parsedValue = arguments[0].parsedValue;
   3609            }
   3610        }
   3611        // #endregion 
   3612    };
   3613    //**************************************************************************************
   3614    in_window.org.pkijs.simpl.EXTENSION.prototype.fromSchema =
   3615    function(schema)
   3616    {
   3617        // #region Check the schema is valid 
   3618        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3619            schema,
   3620            in_window.org.pkijs.schema.EXTENSION({
   3621                names: {
   3622                    extnID: "extnID",
   3623                    critical: "critical",
   3624                    extnValue: "extnValue"
   3625                }
   3626            })
   3627            );
   3628 
   3629        if(asn1.verified === false)
   3630            throw new Error("Object's schema was not verified against input data for EXTENSION");
   3631        // #endregion 
   3632 
   3633        // #region Get internal properties from parsed schema 
   3634        this.extnID = asn1.result.extnID.value_block.toString();
   3635        if("critical" in asn1.result)
   3636            this.critical = asn1.result.critical.value_block.value;
   3637        this.extnValue = asn1.result.extnValue;
   3638 
   3639        // #region Get "parsedValue" for well-known extensions 
   3640        var asn1 = in_window.org.pkijs.fromBER(this.extnValue.value_block.value_hex);
   3641        if(asn1.offset === (-1))
   3642            return;
   3643 
   3644        switch(this.extnID)
   3645        {
   3646            case "2.5.29.9": // SubjectDirectoryAttributes
   3647                this.parsedValue = new in_window.org.pkijs.simpl.x509.SubjectDirectoryAttributes({ schema: asn1.result });
   3648                break;
   3649            case "2.5.29.14": // SubjectKeyIdentifier
   3650                this.parsedValue = asn1.result; // Should be just a simple OCTETSTRING
   3651                break;
   3652            case "2.5.29.15": // KeyUsage
   3653                this.parsedValue = asn1.result; // Should be just a simple BITSTRING
   3654                break;
   3655            case "2.5.29.16": // PrivateKeyUsagePeriod
   3656                this.parsedValue = new in_window.org.pkijs.simpl.x509.PrivateKeyUsagePeriod({ schema: asn1.result });
   3657                break;
   3658            case "2.5.29.17": // SubjectAltName
   3659            case "2.5.29.18": // IssuerAltName
   3660                this.parsedValue = new in_window.org.pkijs.simpl.x509.AltName({ schema: asn1.result });
   3661                break;
   3662            case "2.5.29.19": // BasicConstraints
   3663                this.parsedValue = new in_window.org.pkijs.simpl.x509.BasicConstraints({ schema: asn1.result });
   3664                break;
   3665            case "2.5.29.20": // CRLNumber
   3666            case "2.5.29.27": // BaseCRLNumber (delta CRL indicator)
   3667                this.parsedValue = asn1.result; // Should be just a simple INTEGER
   3668                break;
   3669            case "2.5.29.21": // CRLReason
   3670                this.parsedValue = asn1.result; // Should be just a simple ENUMERATED
   3671                break;
   3672            case "2.5.29.24": // InvalidityDate
   3673                this.parsedValue = asn1.result; // Should be just a simple GeneralizedTime
   3674                break;
   3675            case "2.5.29.28": // IssuingDistributionPoint
   3676                this.parsedValue = new in_window.org.pkijs.simpl.x509.IssuingDistributionPoint({ schema: asn1.result });
   3677                break;
   3678            case "2.5.29.29": // CertificateIssuer
   3679                this.parsedValue = new in_window.org.pkijs.simpl.GENERAL_NAMES({ schema: asn1.result }); // Should be just a simple 
   3680                break;
   3681            case "2.5.29.30": // NameConstraints
   3682                this.parsedValue = new in_window.org.pkijs.simpl.x509.NameConstraints({ schema: asn1.result });
   3683                break;
   3684            case "2.5.29.31": // CRLDistributionPoints
   3685            case "2.5.29.46": // FreshestCRL
   3686                this.parsedValue = new in_window.org.pkijs.simpl.x509.CRLDistributionPoints({ schema: asn1.result });
   3687                break;
   3688            case "2.5.29.32": // CertificatePolicies
   3689                this.parsedValue = new in_window.org.pkijs.simpl.x509.CertificatePolicies({ schema: asn1.result });
   3690                break;
   3691            case "2.5.29.33": // PolicyMappings
   3692                this.parsedValue = new in_window.org.pkijs.simpl.x509.PolicyMappings({ schema: asn1.result });
   3693                break;
   3694            case "2.5.29.35": // AuthorityKeyIdentifier
   3695                this.parsedValue = new in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier({ schema: asn1.result });
   3696                break;
   3697            case "2.5.29.36": // PolicyConstraints
   3698                this.parsedValue = new in_window.org.pkijs.simpl.x509.PolicyConstraints({ schema: asn1.result });
   3699                break;
   3700            case "2.5.29.37": // ExtKeyUsage
   3701                this.parsedValue = new in_window.org.pkijs.simpl.x509.ExtKeyUsage({ schema: asn1.result });
   3702                break;
   3703            case "2.5.29.54": // InhibitAnyPolicy
   3704                this.parsedValue = asn1.result; // Should be just a simple INTEGER
   3705                break;
   3706            case "1.3.6.1.5.5.7.1.1": // AuthorityInfoAccess
   3707            case "1.3.6.1.5.5.7.1.11": // SubjectInfoAccess
   3708                this.parsedValue = new in_window.org.pkijs.simpl.x509.InfoAccess({ schema: asn1.result });
   3709                break;
   3710            default:
   3711        }
   3712        // #endregion 
   3713        // #endregion 
   3714    };
   3715    //**************************************************************************************
   3716    in_window.org.pkijs.simpl.EXTENSION.prototype.toSchema =
   3717    function()
   3718    {
   3719        // #region Create array for output sequence 
   3720        var output_array = new Array();
   3721 
   3722        output_array.push(new in_window.org.pkijs.asn1.OID({ value: this.extnID }));
   3723 
   3724        if(this.critical)
   3725            output_array.push(new in_window.org.pkijs.asn1.BOOLEAN({ value: this.critical }));
   3726 
   3727        output_array.push(this.extnValue);
   3728        // #endregion 
   3729 
   3730        // #region Construct and return new ASN.1 schema for this object 
   3731        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3732            value: output_array
   3733        }));
   3734        // #endregion 
   3735    };
   3736    //**************************************************************************************
   3737    in_window.org.pkijs.simpl.EXTENSION.prototype.toJSON =
   3738    function()
   3739    {
   3740        var _object = {
   3741            extnID: this.extnID,
   3742            critical: this.critical,
   3743            extnValue: this.extnValue.toJSON()
   3744        };
   3745 
   3746        if("parsedValue" in this)
   3747            _object.parsedValue = this.parsedValue.toJSON();
   3748 
   3749        return _object;
   3750    };
   3751    //**************************************************************************************
   3752    // #endregion 
   3753    //**************************************************************************************
   3754    // #region Simplified structure for "Extensions" type (sequence of many Extension)
   3755    //**************************************************************************************
   3756    in_window.org.pkijs.simpl.EXTENSIONS =
   3757    function()
   3758    {
   3759        // #region Internal properties of the object 
   3760        this.extensions_array = new Array();
   3761        // #endregion 
   3762 
   3763        // #region If input argument array contains "schema" for this object 
   3764        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3765            in_window.org.pkijs.simpl.EXTENSIONS.prototype.fromSchema.call(this, arguments[0].schema);
   3766        // #endregion 
   3767        // #region If input argument array contains "native" values for internal properties 
   3768        else
   3769        {
   3770            if(arguments[0] instanceof Object)
   3771                this.extensions_array = (arguments[0].extensions_array || (new Array()));
   3772        }
   3773        // #endregion 
   3774    };
   3775    //**************************************************************************************
   3776    in_window.org.pkijs.simpl.EXTENSIONS.prototype.fromSchema =
   3777    function(schema)
   3778    {
   3779        // #region Check the schema is valid 
   3780        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3781            schema,
   3782            in_window.org.pkijs.schema.EXTENSIONS({
   3783                names: {
   3784                    extensions: "extensions"
   3785                }
   3786            })
   3787            );
   3788 
   3789        if(asn1.verified === false)
   3790            throw new Error("Object's schema was not verified against input data for EXTENSIONS");
   3791        // #endregion 
   3792 
   3793        // #region Get internal properties from parsed schema 
   3794        for(var i = 0; i < asn1.result.extensions.length; i++)
   3795            this.extensions_array.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: asn1.result.extensions[i] }));
   3796        // #endregion 
   3797    };
   3798    //**************************************************************************************
   3799    in_window.org.pkijs.simpl.EXTENSIONS.prototype.toSchema =
   3800    function()
   3801    {
   3802        // #region Construct and return new ASN.1 schema for this object 
   3803        var extension_schemas = new Array();
   3804 
   3805        for(var i = 0; i < this.extensions_array.length; i++)
   3806            extension_schemas.push(this.extensions_array[i].toSchema());
   3807 
   3808        return (new in_window.org.pkijs.asn1.SEQUENCE({
   3809            value: extension_schemas
   3810        }));
   3811        // #endregion 
   3812    };
   3813    //**************************************************************************************
   3814    in_window.org.pkijs.simpl.EXTENSIONS.prototype.toJSON =
   3815    function()
   3816    {
   3817        var _object = {
   3818            extensions_array: new Array()
   3819        };
   3820 
   3821        for(var i = 0; i < this.extensions_array.length; i++)
   3822            _object.extensions_array.push(this.extensions_array[i].toJSON());
   3823 
   3824        return _object;
   3825    };
   3826    //**************************************************************************************
   3827    // #endregion 
   3828    //**************************************************************************************
   3829    // #region Simplified structure for X.509 v3 certificate (RFC5280)
   3830    //**************************************************************************************
   3831    in_window.org.pkijs.simpl.CERT =
   3832    function()
   3833    {
   3834        // #region Internal properties of the object 
   3835        // #region Properties from certificate TBS part 
   3836        this.tbs = new ArrayBuffer(0); // Encoded value of certificate TBS (need to have it for certificate validation)
   3837 
   3838        // OPTIONAL this.version = 0;
   3839        this.serialNumber = new in_window.org.pkijs.asn1.INTEGER(); // Might be a very long integer value
   3840        this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate TBS part
   3841        this.issuer = new in_window.org.pkijs.simpl.RDN();
   3842        this.notBefore = new in_window.org.pkijs.simpl.TIME();
   3843        this.notAfter = new in_window.org.pkijs.simpl.TIME();
   3844        this.subject = new in_window.org.pkijs.simpl.RDN();
   3845        this.subjectPublicKeyInfo = new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO();
   3846        // OPTIONAL this.issuerUniqueID = new ArrayBuffer(0); // IMPLICIT bistring value
   3847        // OPTIONAL this.subjectUniqueID = new ArrayBuffer(0); // IMPLICIT bistring value
   3848        // OPTIONAL this.extensions = new Array(); // Array of "simpl.EXTENSION"
   3849        // #endregion 
   3850 
   3851        // #region Properties from certificate major part 
   3852        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate major part
   3853        this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING();
   3854        // #endregion 
   3855        // #endregion 
   3856 
   3857        // #region If input argument array contains "schema" for this object 
   3858        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   3859            in_window.org.pkijs.simpl.CERT.prototype.fromSchema.call(this, arguments[0].schema);
   3860        // #endregion 
   3861        // #region If input argument array contains "native" values for internal properties 
   3862        else
   3863        {
   3864            if(arguments[0] instanceof Object)
   3865            {
   3866                // #region Properties from certificate TBS part 
   3867                this.tbs = arguments[0].tbs || new ArrayBuffer(0);
   3868 
   3869                if("version" in arguments[0])
   3870                    this.version = arguments[0].version;
   3871                this.serialNumber = arguments[0].serialNumber || new in_window.org.pkijs.asn1.INTEGER(); // Might be a very long integer value
   3872                this.signature = arguments[0].signature || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate TBS part
   3873                this.issuer = arguments[0].issuer || new in_window.org.pkijs.simpl.RDN();
   3874                this.notBefore = arguments[0].not_before || new in_window.org.pkijs.simpl.TIME();
   3875                this.notAfter = arguments[0].not_after || new in_window.org.pkijs.simpl.TIME();
   3876                this.subject = arguments[0].subject || new in_window.org.pkijs.simpl.RDN();
   3877                this.subjectPublicKeyInfo = arguments[0].subjectPublicKeyInfo || new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO();
   3878                if("issuerUniqueID" in arguments[0])
   3879                    this.issuerUniqueID = arguments[0].issuerUniqueID;
   3880                if("subjectUniqueID" in arguments[0])
   3881                    this.subjectUniqueID = arguments[0].subjectUniqueID;
   3882                if("extensions" in arguments[0])
   3883                    this.extensions = arguments[0].extensions;
   3884                // #endregion 
   3885 
   3886                // #region Properties from certificate major part 
   3887                this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate major part
   3888                this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING();
   3889                // #endregion 
   3890            }
   3891        }
   3892        // #endregion 
   3893    };
   3894    //**************************************************************************************
   3895    in_window.org.pkijs.simpl.CERT.prototype.fromSchema =
   3896    function(schema)
   3897    {
   3898        // #region Check the schema is valid 
   3899        var asn1 = in_window.org.pkijs.compareSchema(schema,
   3900            schema,
   3901            in_window.org.pkijs.schema.CERT({
   3902                names: {
   3903                    tbsCertificate: {
   3904                        names: {
   3905                            extensions: {
   3906                                names: {
   3907                                    extensions: "tbsCertificate.extensions"
   3908                                }
   3909                            }
   3910                        }
   3911                    }
   3912                }
   3913            })
   3914            );
   3915 
   3916        if(asn1.verified === false)
   3917            throw new Error("Object's schema was not verified against input data for CERT");
   3918        // #endregion 
   3919 
   3920        // #region Get internal properties from parsed schema 
   3921        this.tbs = asn1.result["tbsCertificate"].value_before_decode;
   3922 
   3923        if("tbsCertificate.version" in asn1.result)
   3924            this.version = asn1.result["tbsCertificate.version"].value_block.value_dec;
   3925        this.serialNumber = asn1.result["tbsCertificate.serialNumber"];
   3926        this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["tbsCertificate.signature"] });
   3927        this.issuer = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["tbsCertificate.issuer"] });
   3928        this.notBefore = new in_window.org.pkijs.simpl.TIME({ schema: asn1.result["tbsCertificate.notBefore"] });
   3929        this.notAfter = new in_window.org.pkijs.simpl.TIME({ schema: asn1.result["tbsCertificate.notAfter"] });
   3930        this.subject = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["tbsCertificate.subject"] });
   3931        this.subjectPublicKeyInfo = new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO({ schema: asn1.result["tbsCertificate.subjectPublicKeyInfo"] });
   3932        if("tbsCertificate.issuerUniqueID" in asn1.result)
   3933            this.issuerUniqueID = asn1.result["tbsCertificate.issuerUniqueID"].value_block.value_hex;
   3934        if("tbsCertificate.subjectUniqueID" in asn1.result)
   3935            this.issuerUniqueID = asn1.result["tbsCertificate.subjectUniqueID"].value_block.value_hex;
   3936        if("tbsCertificate.extensions" in asn1.result)
   3937        {
   3938            this.extensions = new Array();
   3939 
   3940            var extensions = asn1.result["tbsCertificate.extensions"];
   3941 
   3942            for(var i = 0; i < extensions.length; i++)
   3943                this.extensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: extensions[i] }));
   3944        }
   3945 
   3946        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["signatureAlgorithm"] });
   3947        this.signatureValue = asn1.result["signatureValue"];
   3948        // #endregion 
   3949    };
   3950    //**************************************************************************************
   3951    in_window.org.pkijs.simpl.CERT.prototype.encodeTBS =
   3952    function()
   3953    {
   3954        /// <summary>Create ASN.1 schema for existing values of TBS part for the certificate</summary>
   3955 
   3956        // #region Create array for output sequence 
   3957        var output_array = new Array();
   3958 
   3959        if("version" in this)
   3960            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   3961                optional: true,
   3962                id_block: {
   3963                    tag_class: 3, // CONTEXT-SPECIFIC
   3964                    tag_number: 0 // [0]
   3965                },
   3966                value: [
   3967                    new in_window.org.pkijs.asn1.INTEGER({ value: this.version }) // EXPLICIT integer value
   3968                ]
   3969            }));
   3970 
   3971        output_array.push(this.serialNumber);
   3972        output_array.push(this.signature.toSchema());
   3973        output_array.push(this.issuer.toSchema());
   3974 
   3975        output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
   3976            value: [
   3977                this.notBefore.toSchema(),
   3978                this.notAfter.toSchema()
   3979            ]
   3980        }));
   3981 
   3982        output_array.push(this.subject.toSchema());
   3983        output_array.push(this.subjectPublicKeyInfo.toSchema());
   3984 
   3985        if("issuerUniqueID" in this)
   3986            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3987                optional: true,
   3988                id_block: {
   3989                    tag_class: 3, // CONTEXT-SPECIFIC
   3990                    tag_number: 1 // [1]
   3991                },
   3992                value_hex: this.issuerUniqueID
   3993            }));
   3994        if("subjectUniqueID" in this)
   3995            output_array.push(new in_window.org.pkijs.asn1.ASN1_PRIMITIVE({
   3996                optional: true,
   3997                id_block: {
   3998                    tag_class: 3, // CONTEXT-SPECIFIC
   3999                    tag_number: 2 // [2]
   4000                },
   4001                value_hex: this.subjectUniqueID
   4002            }));
   4003 
   4004        if("subjectUniqueID" in this)
   4005            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   4006                optional: true,
   4007                id_block: {
   4008                    tag_class: 3, // CONTEXT-SPECIFIC
   4009                    tag_number: 3 // [3]
   4010                },
   4011                value: [this.extensions.toSchema()]
   4012            }));
   4013 
   4014        if("extensions" in this)
   4015        {
   4016            var extensions = new Array();
   4017 
   4018            for(var i = 0; i < this.extensions.length; i++)
   4019                extensions.push(this.extensions[i].toSchema());
   4020 
   4021            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   4022                optional: true,
   4023                id_block: {
   4024                    tag_class: 3, // CONTEXT-SPECIFIC
   4025                    tag_number: 3 // [3]
   4026                },
   4027                value: [new in_window.org.pkijs.asn1.SEQUENCE({
   4028                    value: extensions
   4029                })]
   4030            }));
   4031        }
   4032        // #endregion 
   4033 
   4034        // #region Create and return output sequence 
   4035        return (new in_window.org.pkijs.asn1.SEQUENCE({
   4036            value: output_array
   4037        }));
   4038        // #endregion 
   4039    };
   4040    //**************************************************************************************
   4041    in_window.org.pkijs.simpl.CERT.prototype.toSchema =
   4042    function(encodeFlag)
   4043    {
   4044        /// <param name="encodeFlag" type="Boolean">If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts.</param>
   4045 
   4046        if(typeof encodeFlag === "undefined")
   4047            encodeFlag = false;
   4048 
   4049        var tbs_schema = {};
   4050 
   4051        // #region Decode stored TBS value 
   4052        if(encodeFlag === false)
   4053        {
   4054            if(this.tbs.length === 0) // No stored certificate TBS part
   4055                return in_window.org.pkijs.schema.CERT().value[0];
   4056 
   4057            var tbs_asn1 = in_window.org.pkijs.fromBER(this.tbs);
   4058 
   4059            tbs_schema = tbs_asn1.result;
   4060        }
   4061        // #endregion 
   4062        // #region Create TBS schema via assembling from TBS parts 
   4063        else
   4064            tbs_schema = in_window.org.pkijs.simpl.CERT.prototype.encodeTBS.call(this);
   4065        // #endregion 
   4066 
   4067        // #region Construct and return new ASN.1 schema for this object 
   4068        return (new in_window.org.pkijs.asn1.SEQUENCE({
   4069            value: [
   4070                tbs_schema,
   4071                this.signatureAlgorithm.toSchema(),
   4072                this.signatureValue
   4073            ]
   4074        }));
   4075        // #endregion 
   4076    };
   4077    //**************************************************************************************
   4078    in_window.org.pkijs.simpl.CERT.prototype.verify =
   4079    function()
   4080    {
   4081        /// <summary>!!! Works well in Chrome dev versions only (April 2014th) !!!</summary>
   4082        /// <returns type="Promise">Returns a new Promise object (in case of error), or a result of "crypto.subtle.veryfy" function</returns>
   4083 
   4084        // #region Global variables 
   4085        var sequence = Promise.resolve();
   4086 
   4087        var subjectPublicKeyInfo = {};
   4088 
   4089        var signature = this.signatureValue;
   4090        var tbs = this.tbs;
   4091 
   4092        var _this = this;
   4093        // #endregion 
   4094 
   4095        // #region Set correct "subjectPublicKeyInfo" value 
   4096        if(arguments[0] instanceof Object)
   4097        {
   4098            if("issuerCertificate" in arguments[0]) // Must be of type "simpl.CERT"
   4099                subjectPublicKeyInfo = arguments[0].issuerCertificate.subjectPublicKeyInfo;
   4100        }
   4101        else
   4102        {
   4103            if(this.issuer.isEqual(this.subject)) // Self-signed certificate
   4104                subjectPublicKeyInfo = this.subjectPublicKeyInfo;
   4105        }
   4106 
   4107        if((subjectPublicKeyInfo instanceof in_window.org.pkijs.simpl.PUBLIC_KEY_INFO) === false)
   4108            return new Promise(function(resolve, reject) { reject("Please provide issuer certificate as a parameter"); });
   4109        // #endregion 
   4110 
   4111        // #region Get a "crypto" extension 
   4112        var crypto = in_window.org.pkijs.getCrypto();
   4113        if(typeof crypto == "undefined")
   4114            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   4115        // #endregion 
   4116 
   4117        // #region Find signer's hashing algorithm 
   4118        var sha_algorithm = in_window.org.pkijs.getHashAlgorithm(this.signatureAlgorithm);
   4119        if(sha_algorithm === "")
   4120            return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   4121        // #endregion 
   4122 
   4123        // #region Importing public key 
   4124        sequence = sequence.then(
   4125            function()
   4126            {
   4127                // #region Get information about public key algorithm and default parameters for import
   4128                var algorithmObject = in_window.org.pkijs.getAlgorithmByOID(_this.signatureAlgorithm.algorithm_id);
   4129                if(("name" in algorithmObject) === false)
   4130                    return new Promise(function(resolve, reject) { reject("Unsupported public key algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   4131 
   4132                var algorithm_name = algorithmObject.name;
   4133 
   4134                var algorithm = in_window.org.pkijs.getAlgorithmParameters(algorithm_name, "importkey");
   4135                if("hash" in algorithm.algorithm)
   4136                    algorithm.algorithm.hash.name = sha_algorithm;
   4137                // #endregion 
   4138 
   4139                var publicKeyInfo_schema = subjectPublicKeyInfo.toSchema();
   4140                var publicKeyInfo_buffer = publicKeyInfo_schema.toBER(false);
   4141                var publicKeyInfo_view = new Uint8Array(publicKeyInfo_buffer);
   4142 
   4143                return crypto.importKey("spki", publicKeyInfo_view, algorithm.algorithm, true, algorithm.usages);
   4144            }
   4145            );
   4146        // #endregion 
   4147 
   4148        // #region Verify signature for the certificate 
   4149        sequence = sequence.then(
   4150            function(publicKey)
   4151            {
   4152                // #region Get default algorithm parameters for verification 
   4153                var algorithm = in_window.org.pkijs.getAlgorithmParameters(publicKey.algorithm.name, "verify");
   4154                if("hash" in algorithm.algorithm)
   4155                    algorithm.algorithm.hash.name = sha_algorithm;
   4156                // #endregion 
   4157 
   4158                // #region Special case for ECDSA signatures 
   4159                var signature_value = signature.value_block.value_hex;
   4160 
   4161                if(publicKey.algorithm.name === "ECDSA")
   4162                {
   4163                    var asn1 = in_window.org.pkijs.fromBER(signature_value);
   4164                    signature_value = in_window.org.pkijs.createECDSASignatureFromCMS(asn1.result);
   4165                }
   4166                // #endregion 
   4167 
   4168                // #region Special case for RSA-PSS 
   4169                if(publicKey.algorithm.name === "RSA-PSS")
   4170                {
   4171                    var pssParameters;
   4172 
   4173                    try
   4174                    {
   4175                        pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params({ schema: _this.signatureAlgorithm.algorithm_params });
   4176                    }
   4177                    catch(ex)
   4178                    {
   4179                        return new Promise(function(resolve, reject) { reject(ex); });
   4180                    }
   4181 
   4182                    if("saltLength" in pssParameters)
   4183                        algorithm.algorithm.saltLength = pssParameters.saltLength;
   4184                    else
   4185                        algorithm.algorithm.saltLength = 20;
   4186 
   4187                    var hash_algo = "SHA-1";
   4188 
   4189                    if("hashAlgorithm" in pssParameters)
   4190                    {
   4191                        var hashAlgorithm = in_window.org.pkijs.getAlgorithmByOID(pssParameters.hashAlgorithm.algorithm_id);
   4192                        if(("name" in hashAlgorithm) === false)
   4193                            return new Promise(function(resolve, reject) { reject("Unrecognized hash algorithm: " + pssParameters.hashAlgorithm.algorithm_id); });
   4194 
   4195                        hash_algo = hashAlgorithm.name;
   4196                    }
   4197 
   4198                    algorithm.algorithm.hash.name = hash_algo;
   4199                }
   4200                // #endregion 
   4201 
   4202                return crypto.verify(algorithm.algorithm,
   4203                    publicKey,
   4204                    new Uint8Array(signature_value),
   4205                    new Uint8Array(tbs));
   4206            }
   4207            );
   4208        // #endregion 
   4209 
   4210        return sequence;
   4211    };
   4212    //**************************************************************************************
   4213    in_window.org.pkijs.simpl.CERT.prototype.sign =
   4214    function(privateKey, hashAlgorithm)
   4215    {
   4216        /// <param name="privateKey" type="CryptoKey">Private key for "subjectPublicKeyInfo" structure</param>
   4217        /// <param name="hashAlgorithm" type="String" optional="true">Hashing algorithm. Default SHA-1</param>
   4218 
   4219        // #region Initial variables 
   4220        var _this = this;
   4221        // #endregion 
   4222 
   4223        // #region Get a private key from function parameter 
   4224        if(typeof privateKey === "undefined")
   4225            return new Promise(function(resolve, reject) { reject("Need to provide a private key for signing"); });
   4226        // #endregion 
   4227 
   4228        // #region Get hashing algorithm 
   4229        if(typeof hashAlgorithm === "undefined")
   4230            hashAlgorithm = "SHA-1";
   4231        else
   4232        {
   4233            // #region Simple check for supported algorithm 
   4234            var oid = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   4235            if(oid === "")
   4236                return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   4237            // #endregion 
   4238        }
   4239        // #endregion 
   4240 
   4241        // #region Get a "default parameters" for current algorithm 
   4242        var defParams = in_window.org.pkijs.getAlgorithmParameters(privateKey.algorithm.name, "sign");
   4243        defParams.algorithm.hash.name = hashAlgorithm;
   4244        // #endregion 
   4245 
   4246        // #region Fill internal structures base on "privateKey" and "hashAlgorithm" 
   4247        switch(privateKey.algorithm.name.toUpperCase())
   4248        {
   4249            case "RSASSA-PKCS1-V1_5":
   4250            case "ECDSA":
   4251                _this.signature.algorithm_id = in_window.org.pkijs.getOIDByAlgorithm(defParams.algorithm);
   4252                _this.signatureAlgorithm.algorithm_id = _this.signature.algorithm_id;
   4253                break;
   4254            case "RSA-PSS":
   4255                {
   4256                    // #region Set "saltLength" as a length (in octets) of hash function result 
   4257                    switch(hashAlgorithm.toUpperCase())
   4258                    {
   4259                        case "SHA-256":
   4260                            defParams.algorithm.saltLength = 32;
   4261                            break;
   4262                        case "SHA-384":
   4263                            defParams.algorithm.saltLength = 48;
   4264                            break;
   4265                        case "SHA-512":
   4266                            defParams.algorithm.saltLength = 64;
   4267                            break;
   4268                        default:
   4269                    }
   4270                    // #endregion 
   4271 
   4272                    // #region Fill "RSASSA_PSS_params" object 
   4273                    var paramsObject = {};
   4274 
   4275                    if(hashAlgorithm.toUpperCase() !== "SHA-1")
   4276                    {
   4277                        var hashAlgorithmOID = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   4278                        if(hashAlgorithmOID === "")
   4279                            return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   4280 
   4281                        paramsObject.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   4282                            algorithm_id: hashAlgorithmOID,
   4283                            algorithm_params: new in_window.org.pkijs.asn1.NULL()
   4284                        });
   4285 
   4286                        paramsObject.maskGenAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   4287                            algorithm_id: "1.2.840.113549.1.1.8", // MGF1
   4288                            algorithm_params: paramsObject.hashAlgorithm.toSchema()
   4289                        })
   4290                    }
   4291 
   4292                    if(defParams.algorithm.saltLength !== 20)
   4293                        paramsObject.saltLength = defParams.algorithm.saltLength;
   4294 
   4295                    var pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params(paramsObject);
   4296                    // #endregion   
   4297 
   4298                    // #region Automatically set signature algorithm 
   4299                    _this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   4300                        algorithm_id: "1.2.840.113549.1.1.10",
   4301                        algorithm_params: pssParameters.toSchema()
   4302                    });
   4303                    _this.signatureAlgorithm = _this.signature; // Must be the same
   4304                    // #endregion 
   4305                }
   4306                break;
   4307            default:
   4308                return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + privateKey.algorithm.name); });
   4309        }
   4310        // #endregion 
   4311 
   4312        // #region Create TBS data for signing 
   4313        _this.tbs = in_window.org.pkijs.simpl.CERT.prototype.encodeTBS.call(this).toBER(false);
   4314        // #endregion 
   4315 
   4316        // #region Get a "crypto" extension 
   4317        var crypto = in_window.org.pkijs.getCrypto();
   4318        if(typeof crypto == "undefined")
   4319            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   4320        // #endregion 
   4321 
   4322        // #region Signing TBS data on provided private key 
   4323        return crypto.sign(defParams.algorithm,
   4324            privateKey,
   4325            new Uint8Array(_this.tbs)).then(
   4326            function(result)
   4327            {
   4328                // #region Special case for ECDSA algorithm 
   4329                if(defParams.algorithm.name === "ECDSA")
   4330                    result = in_window.org.pkijs.createCMSECDSASignature(result);
   4331                // #endregion 
   4332 
   4333                _this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING({ value_hex: result });
   4334            },
   4335            function(error)
   4336            {
   4337                return new Promise(function(resolve, reject) { reject("Signing error: " + error); });
   4338            }
   4339            );
   4340        // #endregion 
   4341    };
   4342    //**************************************************************************************
   4343    in_window.org.pkijs.simpl.CERT.prototype.getPublicKey =
   4344    function()
   4345    {
   4346        /// <summary>Importing public key for current certificate</summary>
   4347 
   4348        // #region Initial variables 
   4349        var algorithm;
   4350        // #endregion 
   4351 
   4352        // #region Get a "crypto" extension 
   4353        var crypto = in_window.org.pkijs.getCrypto();
   4354        if(typeof crypto == "undefined")
   4355            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   4356        // #endregion 
   4357 
   4358        // #region Find correct algorithm for imported public key 
   4359        if(arguments[0] instanceof Object)
   4360        {
   4361            if("algorithm" in arguments[0])
   4362                algorithm = arguments[0].algorithm;
   4363            else
   4364                return new Promise(function(resolve, reject) { reject("Absent mandatory parameter \"algorithm\""); });
   4365        }
   4366        else
   4367        {
   4368            // #region Find signer's hashing algorithm 
   4369            var sha_algorithm = in_window.org.pkijs.getHashAlgorithm(this.signatureAlgorithm);
   4370            if(sha_algorithm === "")
   4371                return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   4372            // #endregion   
   4373 
   4374            // #region Get information about public key algorithm and default parameters for import
   4375            var algorithmObject = in_window.org.pkijs.getAlgorithmByOID(this.signatureAlgorithm.algorithm_id);
   4376            if(("name" in algorithmObject) === false)
   4377                return new Promise(function(resolve, reject) { reject("Unsupported public key algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   4378 
   4379            var algorithm_name = algorithmObject.name;
   4380 
   4381            algorithm = in_window.org.pkijs.getAlgorithmParameters(algorithm_name, "importkey");
   4382            if("hash" in algorithm.algorithm)
   4383                algorithm.algorithm.hash.name = sha_algorithm;
   4384            // #endregion 
   4385        }
   4386        // #endregion 
   4387 
   4388        // #region Get neccessary values from internal fields for current certificate 
   4389        var publicKeyInfo_schema = this.subjectPublicKeyInfo.toSchema();
   4390        var publicKeyInfo_buffer = publicKeyInfo_schema.toBER(false);
   4391        var publicKeyInfo_view = new Uint8Array(publicKeyInfo_buffer);
   4392        // #endregion 
   4393 
   4394        return crypto.importKey("spki", publicKeyInfo_view, algorithm.algorithm, true, algorithm.usages);
   4395    };
   4396    //**************************************************************************************
   4397    in_window.org.pkijs.simpl.CERT.prototype.getKeyHash =
   4398    function()
   4399    {
   4400        /// <summary>Get SHA-1 hash value for subject public key</summary>
   4401 
   4402        // #region Get a "crypto" extension 
   4403        var crypto = in_window.org.pkijs.getCrypto();
   4404        if(typeof crypto == "undefined")
   4405            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   4406        // #endregion 
   4407 
   4408        return crypto.digest({ name: "sha-1" }, new Uint8Array(this.subjectPublicKeyInfo.subjectPublicKey.value_block.value_hex));
   4409    };
   4410    //**************************************************************************************
   4411    in_window.org.pkijs.simpl.CERT.prototype.toJSON =
   4412    function()
   4413    {
   4414        var _object = {
   4415            tbs: in_window.org.pkijs.bufferToHexCodes(this.tbs, 0, this.tbs.byteLength),
   4416            serialNumber: this.serialNumber.toJSON(),
   4417            signature: this.signature.toJSON(),
   4418            issuer: this.issuer.toJSON(),
   4419            notBefore: this.notBefore.toJSON(),
   4420            notAfter: this.notAfter.toJSON(),
   4421            subject: this.subject.toJSON(),
   4422            subjectPublicKeyInfo: this.subjectPublicKeyInfo.toJSON(),
   4423            signatureAlgorithm: this.signatureAlgorithm.toJSON(),
   4424            signatureValue: this.signatureValue.toJSON()
   4425        };
   4426 
   4427        if("version" in this)
   4428            _object.version = this.version;
   4429 
   4430        if("issuerUniqueID" in this)
   4431            _object.issuerUniqueID = in_window.org.pkijs.bufferToHexCodes(this.issuerUniqueID, 0, this.issuerUniqueID.byteLength);
   4432 
   4433        if("subjectUniqueID" in this)
   4434            _object.subjectUniqueID = in_window.org.pkijs.bufferToHexCodes(this.subjectUniqueID, 0, this.subjectUniqueID.byteLength);
   4435 
   4436        if("extensions" in this)
   4437        {
   4438            _object.extensions = new Array();
   4439 
   4440            for(var i = 0; i < this.extensions.length; i++)
   4441                _object.extensions.push(this.extensions[i].toJSON());
   4442        }
   4443 
   4444        return _object;
   4445    };
   4446    //**************************************************************************************
   4447    // #endregion 
   4448    //**************************************************************************************
   4449    // #region Simplified structure for "revoked certificate" type (to use in CRL)
   4450    //**************************************************************************************
   4451    in_window.org.pkijs.simpl.REV_CERT =
   4452    function()
   4453    {
   4454        // #region Internal properties of the object 
   4455        this.userCertificate = new in_window.org.pkijs.asn1.INTEGER();
   4456        this.revocationDate = new in_window.org.pkijs.simpl.TIME();
   4457        // OPTIONAL this.crlEntryExtensions = new Array(); // Array of "in_window.org.pkijs.simpl.EXTENSION");
   4458        // #endregion 
   4459 
   4460        // #region If input argument array contains "schema" for this object 
   4461        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   4462            in_window.org.pkijs.simpl.REV_CERT.prototype.fromSchema.call(this, arguments[0].schema);
   4463        // #endregion 
   4464        // #region If input argument array contains "native" values for internal properties 
   4465        else
   4466        {
   4467            if(arguments[0] instanceof Object)
   4468            {
   4469                this.userCertificate = arguments[0].userCertificate || new in_window.org.pkijs.asn1.INTEGER();
   4470                this.revocationDate = arguments[0].revocationDate || new in_window.org.pkijs.simpl.TIME();
   4471                if("crlEntryExtensions" in arguments[0])
   4472                    this.crlEntryExtensions = arguments[0].crlEntryExtensions;
   4473            }
   4474        }
   4475        // #endregion 
   4476    };
   4477    //**************************************************************************************
   4478    in_window.org.pkijs.simpl.REV_CERT.prototype.fromSchema =
   4479    function(schema)
   4480    {
   4481        // #region Check the schema is valid 
   4482        var asn1 = in_window.org.pkijs.compareSchema(schema,
   4483            schema,
   4484            new in_window.org.pkijs.asn1.SEQUENCE({
   4485                value: [
   4486                    new in_window.org.pkijs.asn1.INTEGER({ name: "userCertificate" }),
   4487                    in_window.org.pkijs.schema.TIME({
   4488                        names: {
   4489                            utcTimeName: "revocationDate",
   4490                            generalTimeName: "revocationDate"
   4491                    }
   4492                    }),
   4493                    in_window.org.pkijs.schema.EXTENSIONS({
   4494                        names: {
   4495                            block_name: "crlEntryExtensions"
   4496                        }
   4497                    }, true)
   4498                ]
   4499            })
   4500            );
   4501 
   4502        if(asn1.verified === false)
   4503            throw new Error("Object's schema was not verified against input data for REV_CERT");
   4504        // #endregion 
   4505 
   4506        // #region Get internal properties from parsed schema 
   4507        this.userCertificate = asn1.result["userCertificate"];
   4508        this.revocationDate = new in_window.org.pkijs.simpl.TIME({ schema: asn1.result["revocationDate"] });
   4509 
   4510        if("crlEntryExtensions" in asn1.result)
   4511        {
   4512            this.crlEntryExtensions = new Array();
   4513            var exts = asn1.result["crlEntryExtensions"].value_block.value;
   4514 
   4515            for(var i = 0; i < exts.length; i++)
   4516                this.crlEntryExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
   4517        }
   4518        // #endregion 
   4519    };
   4520    //**************************************************************************************
   4521    in_window.org.pkijs.simpl.REV_CERT.prototype.toSchema =
   4522    function()
   4523    {
   4524        // #region Create array for output sequence 
   4525        var sequence_array = new Array();
   4526        sequence_array.push(this.userCertificate);
   4527        sequence_array.push(this.revocationDate.toSchema());
   4528 
   4529        if("crlEntryExtensions" in this)
   4530        {
   4531            var exts = new Array();
   4532 
   4533            for(var i = 0; i < this.crlEntryExtensions.length; i++)
   4534                exts.push(this.crlEntryExtensions[i].toSchema());
   4535 
   4536            sequence_array.push(new in_window.org.pkijs.asn1.SEQUENCE({ value: exts }));
   4537        }
   4538        // #endregion 
   4539 
   4540        // #region Construct and return new ASN.1 schema for this object 
   4541        return (new in_window.org.pkijs.asn1.SEQUENCE({
   4542            value: sequence_array
   4543        }));
   4544        // #endregion 
   4545    };
   4546    //**************************************************************************************
   4547    in_window.org.pkijs.simpl.REV_CERT.prototype.toJSON =
   4548    function()
   4549    {
   4550        var _object = {
   4551            userCertificate: this.userCertificate.toJSON(),
   4552            revocationDate: this.revocationDate.toJSON
   4553        };
   4554 
   4555        if("crlEntryExtensions" in this)
   4556        {
   4557            _object.crlEntryExtensions = new Array();
   4558 
   4559            for(var i = 0; i < this.crlEntryExtensions.length; i++)
   4560                _object.crlEntryExtensions.push(this.crlEntryExtensions[i].toJSON());
   4561        }
   4562 
   4563        return _object;
   4564    };
   4565    //**************************************************************************************
   4566    // #endregion 
   4567    //**************************************************************************************
   4568    // #region Simplified structure for X.509 CRL (Certificate Revocation List)(RFC5280)  
   4569    //**************************************************************************************
   4570    in_window.org.pkijs.simpl.CRL =
   4571    function()
   4572    {
   4573        // #region Internal properties of the object 
   4574        // #region Properties from CRL TBS part 
   4575        this.tbs = new ArrayBuffer(0);
   4576 
   4577        // OPTIONAL this.version = 1;
   4578        this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   4579        this.issuer = new in_window.org.pkijs.simpl.RDN();
   4580        this.thisUpdate = new in_window.org.pkijs.simpl.TIME();
   4581        // OPTIONAL this.nextUpdate = new in_window.org.pkijs.simpl.TIME();
   4582        // OPTIONAL this.revokedCertificates = new Array(); // Array of REV_CERT objects
   4583        // OPTIONAL this.crlExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
   4584        // #endregion 
   4585 
   4586        // #region Properties from CRL major part 
   4587        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   4588        this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING();
   4589        // #endregion 
   4590        // #endregion 
   4591 
   4592        // #region If input argument array contains "schema" for this object 
   4593        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   4594            in_window.org.pkijs.simpl.CRL.prototype.fromSchema.call(this, arguments[0].schema);
   4595        // #endregion 
   4596        // #region If input argument array contains "native" values for internal properties 
   4597        else
   4598        {
   4599            if(arguments[0] instanceof Object)
   4600            {
   4601                // #region Properties from CRL TBS part 
   4602                this.tbs = arguments[0].tbs || new ArrayBuffer(0);
   4603 
   4604                if("version" in arguments[0])
   4605                    this.version = arguments[0].version;
   4606                this.signature = arguments[0].signature || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   4607                this.issuer = arguments[0].issuer || new in_window.org.pkijs.simpl.RDN();
   4608                this.thisUpdate = arguments[0].thisUpdate || new in_window.org.pkijs.simpl.TIME();
   4609                if("nextUpdate" in arguments[0])
   4610                    this.nextUpdate = arguments[0].nextUpdate;
   4611                if("revokedCertificates" in arguments[0])
   4612                    this.revokedCertificates = arguments[0].revokedCertificates;
   4613                if("crlExtensions" in arguments[0])
   4614                    this.crlExtensions = arguments[0].crlExtensions;
   4615                // #endregion 
   4616 
   4617                // #region Properties from CRL major part 
   4618                this.signatureAlgorithm = arguments[0].signatureAlgorithm || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   4619                this.signatureValue = arguments[0].signatureValue || new in_window.org.pkijs.asn1.BITSTRING();
   4620                // #endregion 
   4621            }
   4622        }
   4623        // #endregion 
   4624    };
   4625    //**************************************************************************************
   4626    in_window.org.pkijs.simpl.CRL.prototype.fromSchema =
   4627    function(schema)
   4628    {
   4629        // #region Check the schema is valid 
   4630        var asn1 = in_window.org.pkijs.compareSchema(schema,
   4631            schema,
   4632            in_window.org.pkijs.schema.CRL()
   4633            );
   4634 
   4635        if(asn1.verified === false)
   4636            throw new Error("Object's schema was not verified against input data for CRL");
   4637        // #endregion 
   4638 
   4639        // #region Get internal properties from parsed schema 
   4640        this.tbs = asn1.result["tbsCertList"].value_before_decode;
   4641 
   4642        if("tbsCertList.version" in asn1.result)
   4643            this.version = asn1.result["tbsCertList.version"].value_block.value_dec;
   4644        this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["tbsCertList.signature"] });
   4645        this.issuer = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["tbsCertList.issuer"] });
   4646        this.thisUpdate = new in_window.org.pkijs.simpl.TIME({ schema: asn1.result["tbsCertList.thisUpdate"] });
   4647        if("tbsCertList.nextUpdate" in asn1.result)
   4648            this.nextUpdate = new in_window.org.pkijs.simpl.TIME({ schema: asn1.result["tbsCertList.nextUpdate"] });
   4649        if("tbsCertList.revokedCertificates" in asn1.result)
   4650        {
   4651            this.revokedCertificates = new Array();
   4652 
   4653            var rev_certs = asn1.result["tbsCertList.revokedCertificates"];
   4654            for(var i = 0; i < rev_certs.length; i++)
   4655                this.revokedCertificates.push(new in_window.org.pkijs.simpl.REV_CERT({ schema: rev_certs[i] }));
   4656        }
   4657        if("tbsCertList.extensions" in asn1.result)
   4658        {
   4659            this.crlExtensions = new Array();
   4660            var exts = asn1.result["tbsCertList.extensions"].value_block.value;
   4661 
   4662            for(var i = 0; i < exts.length; i++)
   4663                this.crlExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
   4664        }
   4665 
   4666        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["signatureAlgorithm"] });
   4667        this.signatureValue = asn1.result["signatureValue"];
   4668        // #endregion 
   4669    };
   4670    //**************************************************************************************
   4671    in_window.org.pkijs.simpl.CRL.prototype.encodeTBS =
   4672    function()
   4673    {
   4674        // #region Create array for output sequence 
   4675        var output_array = new Array();
   4676 
   4677        if("version" in this)
   4678            output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.version }));
   4679 
   4680        output_array.push(this.signature.toSchema());
   4681        output_array.push(this.issuer.toSchema());
   4682        output_array.push(this.thisUpdate.toSchema());
   4683 
   4684        if("nextUpdate" in this)
   4685            output_array.push(this.nextUpdate.toSchema());
   4686 
   4687        if("revokedCertificates" in this)
   4688        {
   4689            var rev_certificates = new Array();
   4690 
   4691            for(var i = 0; i < this.revokedCertificates.length; i++)
   4692                rev_certificates.push(this.revokedCertificates[i].toSchema());
   4693 
   4694            output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
   4695                value: rev_certificates
   4696            }));
   4697        }
   4698 
   4699        if("crlExtensions" in this)
   4700        {
   4701            var extensions = new Array();
   4702 
   4703            for(var j = 0; j < this.crlExtensions.length; j++)
   4704                extensions.push(this.crlExtensions[j].toSchema());
   4705 
   4706            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   4707                optional: true,
   4708                id_block: {
   4709                    tag_class: 3, // CONTEXT-SPECIFIC
   4710                    tag_number: 0 // [0]
   4711                },
   4712                value: [
   4713                    new in_window.org.pkijs.asn1.SEQUENCE({
   4714                        value: extensions
   4715                    })
   4716                ]
   4717            }));
   4718        }
   4719        // #endregion 
   4720 
   4721        return (new in_window.org.pkijs.asn1.SEQUENCE({
   4722            value: output_array
   4723        }));
   4724    };
   4725    //**************************************************************************************
   4726    in_window.org.pkijs.simpl.CRL.prototype.toSchema =
   4727    function(encodeFlag)
   4728    {
   4729        /// <param name="encodeFlag" type="Boolean">If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts.</param>
   4730 
   4731        // #region Check "encodeFlag" 
   4732        if(typeof encodeFlag === "undefined")
   4733            encodeFlag = false;
   4734        // #endregion 
   4735 
   4736        // #region Decode stored TBS value 
   4737        var tbs_schema;
   4738 
   4739        if(encodeFlag === false)
   4740        {
   4741            if(this.tbs.length === 0) // No stored TBS part
   4742                return in_window.org.pkijs.schema.CRL();
   4743 
   4744            tbs_schema = in_window.org.pkijs.fromBER(this.tbs).result;
   4745        }
   4746        // #endregion 
   4747        // #region Create TBS schema via assembling from TBS parts 
   4748        else
   4749            tbs_schema = in_window.org.pkijs.simpl.CRL.prototype.encodeTBS.call(this);
   4750        // #endregion 
   4751 
   4752        // #region Construct and return new ASN.1 schema for this object 
   4753        return (new in_window.org.pkijs.asn1.SEQUENCE({
   4754            value: [
   4755                tbs_schema,
   4756                this.signatureAlgorithm.toSchema(),
   4757                this.signatureValue
   4758            ]
   4759        }));
   4760        // #endregion 
   4761    };
   4762    //**************************************************************************************
   4763    in_window.org.pkijs.simpl.CRL.prototype.verify =
   4764    function()
   4765    {
   4766        // #region Global variables 
   4767        var sequence = Promise.resolve();
   4768 
   4769        var signature = this.signatureValue;
   4770        var tbs = this.tbs;
   4771 
   4772        var subjectPublicKeyInfo = -1;
   4773 
   4774        var _this = this;
   4775        // #endregion 
   4776 
   4777        // #region Get information about CRL issuer certificate 
   4778        if(arguments[0] instanceof Object)
   4779        {
   4780            if("issuerCertificate" in arguments[0]) // "issuerCertificate" must be of type "simpl.CERT"
   4781            {
   4782                subjectPublicKeyInfo = arguments[0].issuerCertificate.subjectPublicKeyInfo;
   4783 
   4784                // The CRL issuer name and "issuerCertificate" subject name are not equal
   4785                if(this.issuer.isEqual(arguments[0].issuerCertificate.subject) == false)
   4786                    return new Promise(function(resolve, reject) { resolve(false); });
   4787            }
   4788 
   4789            // #region In case if there is only public key during verification 
   4790            if("publicKeyInfo" in arguments[0])
   4791                subjectPublicKeyInfo = arguments[0].publicKeyInfo; // Must be of type "org.pkijs.simpl.PUBLIC_KEY_INFO"
   4792            // #endregion 
   4793        }
   4794 
   4795        if((subjectPublicKeyInfo instanceof in_window.org.pkijs.simpl.PUBLIC_KEY_INFO) === false)
   4796            return new Promise(function(resolve, reject) { reject("Issuer's certificate must be provided as an input parameter"); });
   4797        // #endregion 
   4798 
   4799        // #region Check the CRL for unknown critical extensions 
   4800        if("crlExtensions" in this)
   4801        {
   4802            for(var i = 0; i < this.crlExtensions.length; i++)
   4803            {
   4804                if(this.crlExtensions[i].critical)
   4805                {
   4806                    // We can not be sure that unknown extension has no value for CRL signature
   4807                    if(("parsedValue" in this.crlExtensions[i]) == false)
   4808                        return new Promise(function(resolve, reject) { resolve(false); });
   4809                }
   4810            }
   4811        }
   4812        // #endregion 
   4813 
   4814        // #region Get a "crypto" extension 
   4815        var crypto = in_window.org.pkijs.getCrypto();
   4816        if(typeof crypto == "undefined")
   4817            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   4818        // #endregion 
   4819 
   4820        // #region Find signer's hashing algorithm 
   4821        var sha_algorithm = in_window.org.pkijs.getHashAlgorithm(this.signatureAlgorithm);
   4822        if(sha_algorithm === "")
   4823            return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   4824        // #endregion 
   4825 
   4826        // #region Import public key 
   4827        sequence = sequence.then(
   4828            function()
   4829            {
   4830                // #region Get information about public key algorithm and default parameters for import
   4831                var algorithmObject = in_window.org.pkijs.getAlgorithmByOID(_this.signature.algorithm_id);
   4832                if(("name" in algorithmObject) === "")
   4833                    return new Promise(function(resolve, reject) { reject("Unsupported public key algorithm: " + _this.signature.algorithm_id); });
   4834 
   4835                var algorithm_name = algorithmObject.name;
   4836 
   4837                var algorithm = in_window.org.pkijs.getAlgorithmParameters(algorithm_name, "importkey");
   4838                if("hash" in algorithm.algorithm)
   4839                    algorithm.algorithm.hash.name = sha_algorithm;
   4840                // #endregion 
   4841 
   4842                var publicKeyInfo_schema = subjectPublicKeyInfo.toSchema();
   4843                var publicKeyInfo_buffer = publicKeyInfo_schema.toBER(false);
   4844                var publicKeyInfo_view = new Uint8Array(publicKeyInfo_buffer);
   4845 
   4846                return crypto.importKey("spki",
   4847                    publicKeyInfo_view,
   4848                    algorithm.algorithm,
   4849                    true,
   4850                    algorithm.usages);
   4851            }
   4852            );
   4853        // #endregion 
   4854 
   4855        // #region Verify signature for the certificate 
   4856        sequence = sequence.then(
   4857            function(publicKey)
   4858            {
   4859                // #region Get default algorithm parameters for verification 
   4860                var algorithm = in_window.org.pkijs.getAlgorithmParameters(publicKey.algorithm.name, "verify");
   4861                if("hash" in algorithm.algorithm)
   4862                    algorithm.algorithm.hash.name = sha_algorithm;
   4863                // #endregion 
   4864 
   4865                // #region Special case for ECDSA signatures 
   4866                var signature_value = signature.value_block.value_hex;
   4867 
   4868                if(publicKey.algorithm.name === "ECDSA")
   4869                {
   4870                    var asn1 = in_window.org.pkijs.fromBER(signature_value);
   4871                    signature_value = in_window.org.pkijs.createECDSASignatureFromCMS(asn1.result);
   4872                }
   4873                // #endregion 
   4874 
   4875                // #region Special case for RSA-PSS 
   4876                if(publicKey.algorithm.name === "RSA-PSS")
   4877                {
   4878                    var pssParameters;
   4879 
   4880                    try
   4881                    {
   4882                        pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params({ schema: _this.signatureAlgorithm.algorithm_params });
   4883                    }
   4884                    catch(ex)
   4885                    {
   4886                        return new Promise(function(resolve, reject) { reject(ex); });
   4887                    }
   4888 
   4889                    if("saltLength" in pssParameters)
   4890                        algorithm.algorithm.saltLength = pssParameters.saltLength;
   4891                    else
   4892                        algorithm.algorithm.saltLength = 20;
   4893 
   4894                    var hash_algo = "SHA-1";
   4895 
   4896                    if("hashAlgorithm" in pssParameters)
   4897                    {
   4898                        var hashAlgorithm = in_window.org.pkijs.getAlgorithmByOID(pssParameters.hashAlgorithm.algorithm_id);
   4899                        if(("name" in hashAlgorithm) === false)
   4900                            return new Promise(function(resolve, reject) { reject("Unrecognized hash algorithm: " + pssParameters.hashAlgorithm.algorithm_id); });
   4901 
   4902                        hash_algo = hashAlgorithm.name;
   4903                    }
   4904 
   4905                    algorithm.algorithm.hash.name = hash_algo;
   4906                }
   4907                // #endregion 
   4908 
   4909                return crypto.verify(algorithm.algorithm,
   4910                    publicKey,
   4911                    new Uint8Array(signature_value),
   4912                    new Uint8Array(tbs));
   4913            }
   4914            );
   4915        // #endregion 
   4916 
   4917        return sequence;
   4918    };
   4919    //**************************************************************************************
   4920    in_window.org.pkijs.simpl.CRL.prototype.sign =
   4921    function(privateKey, hashAlgorithm)
   4922    {
   4923        /// <param name="privateKey" type="Key">Private key for "subjectPublicKeyInfo" structure</param>
   4924        /// <param name="hashAlgorithm" type="String" optional="true">Hashing algorithm. Default SHA-1</param>
   4925 
   4926        // #region Initial variables 
   4927        var _this = this;
   4928        // #endregion 
   4929 
   4930        // #region Get a private key from function parameter 
   4931        if(typeof privateKey === "undefined")
   4932            return new Promise(function(resolve, reject) { reject("Need to provide a private key for signing"); });
   4933        // #endregion 
   4934 
   4935        // #region Get hashing algorithm 
   4936        if(typeof hashAlgorithm === "undefined")
   4937            hashAlgorithm = "SHA-1";
   4938        else
   4939        {
   4940            // #region Simple check for supported algorithm 
   4941            var oid = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   4942            if(oid === "")
   4943                return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   4944            // #endregion 
   4945        }
   4946        // #endregion 
   4947 
   4948        // #region Get a "default parameters" for current algorithm 
   4949        var defParams = in_window.org.pkijs.getAlgorithmParameters(privateKey.algorithm.name, "sign");
   4950        defParams.algorithm.hash.name = hashAlgorithm;
   4951        // #endregion 
   4952 
   4953        // #region Fill internal structures base on "privateKey" and "hashAlgorithm" 
   4954        switch(privateKey.algorithm.name.toUpperCase())
   4955        {
   4956            case "RSASSA-PKCS1-V1_5":
   4957            case "ECDSA":
   4958                _this.signature.algorithm_id = in_window.org.pkijs.getOIDByAlgorithm(defParams.algorithm);
   4959                _this.signatureAlgorithm.algorithm_id = _this.signature.algorithm_id;
   4960                break;
   4961            case "RSA-PSS":
   4962                {
   4963                    // #region Set "saltLength" as a length (in octets) of hash function result 
   4964                    switch(hashAlgorithm.toUpperCase())
   4965                    {
   4966                        case "SHA-256":
   4967                            defParams.algorithm.saltLength = 32;
   4968                            break;
   4969                        case "SHA-384":
   4970                            defParams.algorithm.saltLength = 48;
   4971                            break;
   4972                        case "SHA-512":
   4973                            defParams.algorithm.saltLength = 64;
   4974                            break;
   4975                        default:
   4976                    }
   4977                    // #endregion 
   4978 
   4979                    // #region Fill "RSASSA_PSS_params" object 
   4980                    var paramsObject = {};
   4981 
   4982                    if(hashAlgorithm.toUpperCase() !== "SHA-1")
   4983                    {
   4984                        var hashAlgorithmOID = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   4985                        if(hashAlgorithmOID === "")
   4986                            return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   4987 
   4988                        paramsObject.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   4989                            algorithm_id: hashAlgorithmOID,
   4990                            algorithm_params: new in_window.org.pkijs.asn1.NULL()
   4991                        });
   4992 
   4993                        paramsObject.maskGenAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   4994                            algorithm_id: "1.2.840.113549.1.1.8", // MGF1
   4995                            algorithm_params: paramsObject.hashAlgorithm.toSchema()
   4996                        })
   4997                    }
   4998 
   4999                    if(defParams.algorithm.saltLength !== 20)
   5000                        paramsObject.saltLength = defParams.algorithm.saltLength;
   5001 
   5002                    var pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params(paramsObject);
   5003                    // #endregion   
   5004 
   5005                    // #region Automatically set signature algorithm 
   5006                    _this.signature = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   5007                        algorithm_id: "1.2.840.113549.1.1.10",
   5008                        algorithm_params: pssParameters.toSchema()
   5009                    });
   5010                    _this.signatureAlgorithm = _this.signature; // Must be the same
   5011                    // #endregion 
   5012                }
   5013                break;
   5014            default:
   5015                return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + privateKey.algorithm.name); });
   5016        }
   5017        // #endregion 
   5018 
   5019        // #region Create TBS data for signing 
   5020        _this.tbs = in_window.org.pkijs.simpl.CRL.prototype.encodeTBS.call(this).toBER(false);
   5021        // #endregion 
   5022 
   5023        // #region Get a "crypto" extension 
   5024        var crypto = in_window.org.pkijs.getCrypto();
   5025        if(typeof crypto == "undefined")
   5026            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   5027        // #endregion 
   5028 
   5029        // #region Signing TBS data on provided private key 
   5030        return crypto.sign(
   5031            defParams.algorithm,
   5032            privateKey,
   5033            new Uint8Array(_this.tbs)).
   5034            then(
   5035            function(result)
   5036            {
   5037                // #region Special case for ECDSA algorithm 
   5038                if(defParams.algorithm.name === "ECDSA")
   5039                    result = in_window.org.pkijs.createCMSECDSASignature(result);
   5040                // #endregion 
   5041 
   5042                _this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING({ value_hex: result });
   5043            },
   5044            function(error)
   5045            {
   5046                return new Promise(function(resolve, reject) { reject("Signing error: " + error); });
   5047            }
   5048            );
   5049        // #endregion 
   5050    };
   5051    //**************************************************************************************
   5052    in_window.org.pkijs.simpl.CRL.prototype.isCertificateRevoked =
   5053    function()
   5054    {
   5055        // #region Get input certificate 
   5056        var certificate = {};
   5057 
   5058        if(arguments[0] instanceof Object)
   5059        {
   5060            if("certificate" in arguments[0])
   5061                certificate = arguments[0].certificate;
   5062        }
   5063 
   5064        if((certificate instanceof in_window.org.pkijs.simpl.CERT) === false)
   5065            return false;
   5066        // #endregion 
   5067 
   5068        // #region Check that issuer of the input certificate is the same with issuer of this CRL 
   5069        if(this.issuer.isEqual(certificate.issuer) === false)
   5070            return false;
   5071        // #endregion 
   5072 
   5073        // #region Check that there are revoked certificates in this CRL 
   5074        if(("revokedCertificates" in this) === false)
   5075            return false;
   5076        // #endregion 
   5077 
   5078        // #region Search for input certificate in revoked certificates array 
   5079        for(var i = 0; i < this.revokedCertificates.length; i++)
   5080        {
   5081            if(this.revokedCertificates[i].userCertificate.isEqual(certificate.serialNumber))
   5082                return true;
   5083        }
   5084        // #endregion 
   5085 
   5086        return false;
   5087    };
   5088    //**************************************************************************************
   5089    in_window.org.pkijs.simpl.CRL.prototype.toJSON =
   5090    function()
   5091    {
   5092        var _object = {
   5093            tbs: in_window.org.pkijs.bufferToHexCodes(this.tbs, 0, this.tbs.byteLength),
   5094            signature: this.signature.toJSON(),
   5095            issuer: this.issuer.toJSON(),
   5096            thisUpdate: this.thisUpdate.toJSON(),
   5097            signatureAlgorithm: this.signatureAlgorithm.toJSON(),
   5098            signatureValue: this.signatureValue.toJSON()
   5099        };
   5100 
   5101        if("version" in this)
   5102            _object.version = this.version;
   5103 
   5104        if("nextUpdate" in this)
   5105            _object.nextUpdate = this.nextUpdate.toJSON();
   5106 
   5107        if("revokedCertificates" in this)
   5108        {
   5109            _object.revokedCertificates = new Array();
   5110 
   5111            for(var i = 0; i < this.revokedCertificates.length; i++)
   5112                _object.revokedCertificates.push(this.revokedCertificates[i].toJSON());
   5113        }
   5114 
   5115        if("crlExtensions" in this)
   5116        {
   5117            _object.crlExtensions = new Array();
   5118 
   5119            for(var i = 0; i < this.crlExtensions.length; i++)
   5120                _object.crlExtensions.push(this.crlExtensions[i].toJSON());
   5121        }
   5122 
   5123        return _object;
   5124    };
   5125    //**************************************************************************************
   5126    // #endregion 
   5127    //**************************************************************************************
   5128    // #region Simplified structure for "Attribute" type
   5129    //**************************************************************************************
   5130    in_window.org.pkijs.simpl.ATTRIBUTE =
   5131    function()
   5132    {
   5133        // #region Internal properties of the object 
   5134        this.type = "";
   5135        this.values = new Array();
   5136        // #endregion 
   5137 
   5138        // #region If input argument array contains "schema" for this object 
   5139        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   5140            in_window.org.pkijs.simpl.ATTRIBUTE.prototype.fromSchema.call(this, arguments[0].schema);
   5141        // #endregion 
   5142        // #region If input argument array contains "native" values for internal properties 
   5143        else
   5144        {
   5145            if(arguments[0] instanceof Object)
   5146            {
   5147                this.type = arguments[0].type || "";
   5148                this.values = arguments[0].values || new Array();
   5149            }
   5150        }
   5151        // #endregion 
   5152    };
   5153    //**************************************************************************************
   5154    in_window.org.pkijs.simpl.ATTRIBUTE.prototype.fromSchema =
   5155    function(schema)
   5156    {
   5157        // #region Check the schema is valid 
   5158        var asn1 = in_window.org.pkijs.compareSchema(schema,
   5159            schema,
   5160            in_window.org.pkijs.schema.ATTRIBUTE({
   5161                names: {
   5162                    type: "type",
   5163                    values: "values"
   5164                }
   5165            })
   5166            );
   5167 
   5168        if(asn1.verified === false)
   5169            throw new Error("Object's schema was not verified against input data for ATTRIBUTE");
   5170        // #endregion 
   5171 
   5172        // #region Get internal properties from parsed schema 
   5173        this.type = asn1.result["type"].value_block.toString();
   5174        this.values = asn1.result["values"];
   5175        // #endregion 
   5176    };
   5177    //**************************************************************************************
   5178    in_window.org.pkijs.simpl.ATTRIBUTE.prototype.toSchema =
   5179    function()
   5180    {
   5181        // #region Construct and return new ASN.1 schema for this object 
   5182        return (new in_window.org.pkijs.asn1.SEQUENCE({
   5183            value: [
   5184                new in_window.org.pkijs.asn1.OID({ value: this.type }),
   5185                new in_window.org.pkijs.asn1.SET({
   5186                    value: this.values
   5187                })
   5188            ]
   5189        }));
   5190        // #endregion 
   5191    };
   5192    //**************************************************************************************
   5193    in_window.org.pkijs.simpl.ATTRIBUTE.prototype.toJSON =
   5194    function()
   5195    {
   5196        var _object = {
   5197            type: this.type,
   5198            values: new Array()
   5199        };
   5200 
   5201        for(var i = 0; i < this.values.length; i++)
   5202            _object.values.push(this.values[i].toJSON());
   5203 
   5204        return _object;
   5205    };
   5206    //**************************************************************************************
   5207    // #endregion 
   5208    //**************************************************************************************
   5209    // #region Simplified structure for PKCS#10 certificate request
   5210    //**************************************************************************************
   5211    in_window.org.pkijs.simpl.PKCS10 =
   5212    function()
   5213    {
   5214        // #region Internal properties of the object 
   5215        this.tbs = new ArrayBuffer(0);
   5216 
   5217        this.version = 0;
   5218        this.subject = new in_window.org.pkijs.simpl.RDN();
   5219        this.subjectPublicKeyInfo = new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO();
   5220        // OPTIONAL this.attributes = new Array(); // Array of simpl.ATTRIBUTE objects
   5221 
   5222        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate major part
   5223        this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING();
   5224        // #endregion 
   5225 
   5226        // #region If input argument array contains "schema" for this object 
   5227        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   5228            in_window.org.pkijs.simpl.PKCS10.prototype.fromSchema.call(this, arguments[0].schema);
   5229        // #endregion 
   5230        // #region If input argument array contains "native" values for internal properties 
   5231        else
   5232        {
   5233            if(arguments[0] instanceof Object)
   5234            {
   5235                this.tbs = arguments[0].tbs || new ArrayBuffer(0);
   5236 
   5237                this.version = arguments[0].version || 0;
   5238                this.subject = arguments[0].subject || new in_window.org.pkijs.simpl.RDN();
   5239                this.subjectPublicKeyInfo = arguments[0].subjectPublicKeyInfo || new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO();
   5240 
   5241                if("attributes" in arguments[0])
   5242                    this.attributes = arguments[0].attributes;
   5243 
   5244                this.signatureAlgorithm = arguments[0].signatureAlgorithm || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER(); // Signature algorithm from certificate major part
   5245                this.signatureValue = arguments[0].signatureValue || new in_window.org.pkijs.asn1.BITSTRING();
   5246            }
   5247        }
   5248        // #endregion 
   5249    };
   5250    //**************************************************************************************
   5251    in_window.org.pkijs.simpl.PKCS10.prototype.fromSchema =
   5252    function(schema)
   5253    {
   5254        // #region Check the schema is valid 
   5255        var asn1 = in_window.org.pkijs.compareSchema(schema,
   5256            schema,
   5257            in_window.org.pkijs.schema.PKCS10()
   5258            );
   5259 
   5260        if(asn1.verified === false)
   5261            throw new Error("Object's schema was not verified against input data for PKCS10");
   5262        // #endregion 
   5263 
   5264        // #region Get internal properties from parsed schema 
   5265        this.tbs = asn1.result["CertificationRequestInfo"].value_before_decode;
   5266 
   5267        this.version = asn1.result["CertificationRequestInfo.version"].value_block.value_dec;
   5268        this.subject = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["CertificationRequestInfo.subject"] });
   5269        this.subjectPublicKeyInfo = new in_window.org.pkijs.simpl.PUBLIC_KEY_INFO({ schema: asn1.result["CertificationRequestInfo.subjectPublicKeyInfo"] });
   5270        if("CertificationRequestInfo.attributes" in asn1.result)
   5271        {
   5272            this.attributes = new Array();
   5273 
   5274            var attrs = asn1.result["CertificationRequestInfo.attributes"];
   5275            for(var i = 0; i < attrs.length; i++)
   5276                this.attributes.push(new in_window.org.pkijs.simpl.ATTRIBUTE({ schema: attrs[i] }));
   5277        }
   5278 
   5279        this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["signatureAlgorithm"] });
   5280        this.signatureValue = asn1.result["signatureValue"];
   5281        // #endregion 
   5282    };
   5283    //**************************************************************************************
   5284    in_window.org.pkijs.simpl.PKCS10.prototype.encodeTBS =
   5285    function()
   5286    {
   5287        // #region Create array for output sequence 
   5288        var output_array = new Array();
   5289 
   5290        output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.version }));
   5291        output_array.push(this.subject.toSchema());
   5292        output_array.push(this.subjectPublicKeyInfo.toSchema());
   5293 
   5294        if("attributes" in this)
   5295        {
   5296            var attributes = new Array();
   5297 
   5298            for(var i = 0; i < this.attributes.length; i++)
   5299                attributes.push(this.attributes[i].toSchema());
   5300 
   5301            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   5302                id_block: {
   5303                    tag_class: 3, // CONTEXT-SPECIFIC
   5304                    tag_number: 0 // [0]
   5305                },
   5306                value: attributes
   5307            }));
   5308        }
   5309        // #endregion 
   5310 
   5311        return (new in_window.org.pkijs.asn1.SEQUENCE({ value: output_array }));
   5312    };
   5313    //**************************************************************************************
   5314    in_window.org.pkijs.simpl.PKCS10.prototype.toSchema =
   5315    function(encodeFlag)
   5316    {
   5317        /// <param name="encodeFlag" type="Boolean">If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts.</param>
   5318 
   5319        // #region Check "encodeFlag" 
   5320        if(typeof encodeFlag === "undefined")
   5321            encodeFlag = false;
   5322        // #endregion 
   5323 
   5324        // #region Decode stored TBS value 
   5325        var tbs_schema;
   5326 
   5327        if(encodeFlag === false)
   5328        {
   5329            if(this.tbs.length === 0) // No stored TBS part
   5330                return in_window.org.pkijs.schema.PKCS10();
   5331 
   5332            tbs_schema = in_window.org.pkijs.fromBER(this.tbs).result;
   5333        }
   5334        // #endregion 
   5335        // #region Create TBS schema via assembling from TBS parts 
   5336        else
   5337            tbs_schema = in_window.org.pkijs.simpl.PKCS10.prototype.encodeTBS.call(this);
   5338        // #endregion 
   5339 
   5340        // #region Construct and return new ASN.1 schema for this object 
   5341        return (new in_window.org.pkijs.asn1.SEQUENCE({
   5342            value: [
   5343                tbs_schema,
   5344                this.signatureAlgorithm.toSchema(),
   5345                this.signatureValue
   5346            ]
   5347        }));
   5348        // #endregion 
   5349    };
   5350    //**************************************************************************************
   5351    in_window.org.pkijs.simpl.PKCS10.prototype.verify =
   5352    function()
   5353    {
   5354        /// <summary>!!! Works well in Chrome dev versions only (April 2014th) !!!</summary>
   5355        /// <returns type="Promise">Returns a new Promise object (in case of error), or a result of "crypto.subtle.veryfy" function</returns>
   5356 
   5357        // #region Global variables 
   5358        var _this = this;
   5359        var sha_algorithm = "";
   5360 
   5361        var sequence = Promise.resolve();
   5362 
   5363        var subjectPublicKeyInfo = this.subjectPublicKeyInfo;
   5364        var signature = this.signatureValue;
   5365        var tbs = this.tbs;
   5366        // #endregion 
   5367 
   5368        // #region Get a "crypto" extension 
   5369        var crypto = in_window.org.pkijs.getCrypto();
   5370        if(typeof crypto == "undefined")
   5371            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   5372        // #endregion 
   5373 
   5374        // #region Find a correct hashing algorithm 
   5375        sha_algorithm = in_window.org.pkijs.getHashAlgorithm(this.signatureAlgorithm);
   5376        if(sha_algorithm === "")
   5377            return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   5378        // #endregion 
   5379 
   5380        // #region Importing public key 
   5381        sequence = sequence.then(
   5382            function()
   5383            {
   5384                // #region Get information about public key algorithm and default parameters for import
   5385                var algorithmObject = in_window.org.pkijs.getAlgorithmByOID(_this.signatureAlgorithm.algorithm_id);
   5386                if(("name" in algorithmObject) === false)
   5387                    return new Promise(function(resolve, reject) { reject("Unsupported public key algorithm: " + _this.signatureAlgorithm.algorithm_id); });
   5388 
   5389                var algorithm_name = algorithmObject.name;
   5390 
   5391                var algorithm = in_window.org.pkijs.getAlgorithmParameters(algorithm_name, "importkey");
   5392                if("hash" in algorithm.algorithm)
   5393                    algorithm.algorithm.hash.name = sha_algorithm;
   5394                // #endregion 
   5395 
   5396                var publicKeyInfo_schema = subjectPublicKeyInfo.toSchema();
   5397                var publicKeyInfo_buffer = publicKeyInfo_schema.toBER(false);
   5398                var publicKeyInfo_view = new Uint8Array(publicKeyInfo_buffer);
   5399 
   5400                return crypto.importKey("spki", publicKeyInfo_view, algorithm.algorithm, true, algorithm.usages);
   5401            }
   5402            );
   5403        // #endregion 
   5404 
   5405        // #region Verify signature  
   5406        sequence = sequence.then(
   5407            function(publicKey)
   5408            {
   5409                // #region Get default algorithm parameters for verification 
   5410                var algorithm = in_window.org.pkijs.getAlgorithmParameters(publicKey.algorithm.name, "verify");
   5411                if("hash" in algorithm.algorithm)
   5412                    algorithm.algorithm.hash.name = sha_algorithm;
   5413                // #endregion 
   5414 
   5415                // #region Special case for ECDSA signatures 
   5416                var signature_value = signature.value_block.value_hex;
   5417 
   5418                if(publicKey.algorithm.name === "ECDSA")
   5419                {
   5420                    var asn1 = in_window.org.pkijs.fromBER(signature_value);
   5421                    signature_value = in_window.org.pkijs.createECDSASignatureFromCMS(asn1.result);
   5422                }
   5423                // #endregion 
   5424 
   5425                // #region Special case for RSA-PSS 
   5426                if(publicKey.algorithm.name === "RSA-PSS")
   5427                {
   5428                    var pssParameters;
   5429 
   5430                    try
   5431                    {
   5432                        pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params({ schema: _this.signatureAlgorithm.algorithm_params });
   5433                    }
   5434                    catch(ex)
   5435                    {
   5436                        return new Promise(function(resolve, reject) { reject(ex); });
   5437                    }
   5438 
   5439                    if("saltLength" in pssParameters)
   5440                        algorithm.algorithm.saltLength = pssParameters.saltLength;
   5441                    else
   5442                        algorithm.algorithm.saltLength = 20;
   5443 
   5444                    var hash_algo = "SHA-1";
   5445 
   5446                    if("hashAlgorithm" in pssParameters)
   5447                    {
   5448                        var hashAlgorithm = in_window.org.pkijs.getAlgorithmByOID(pssParameters.hashAlgorithm.algorithm_id);
   5449                        if(("name" in hashAlgorithm) === false)
   5450                            return new Promise(function(resolve, reject) { reject("Unrecognized hash algorithm: " + pssParameters.hashAlgorithm.algorithm_id); });
   5451 
   5452                        hash_algo = hashAlgorithm.name;
   5453                    }
   5454 
   5455                    algorithm.algorithm.hash.name = hash_algo;
   5456                }
   5457                // #endregion 
   5458 
   5459                return crypto.verify(algorithm.algorithm,
   5460                    publicKey,
   5461                    new Uint8Array(signature_value),
   5462                    new Uint8Array(tbs));
   5463            }
   5464            );
   5465        // #endregion   
   5466 
   5467        return sequence;
   5468    };
   5469    //**************************************************************************************
   5470    in_window.org.pkijs.simpl.PKCS10.prototype.sign =
   5471    function(privateKey, hashAlgorithm)
   5472    {
   5473        /// <param name="privateKey" type="Key">Private key for "subjectPublicKeyInfo" structure</param>
   5474        /// <param name="hashAlgorithm" type="String" optional="true">Hashing algorithm. Default SHA-1</param>
   5475 
   5476        // #region Initial variables 
   5477        var _this = this;
   5478        // #endregion 
   5479 
   5480        // #region Get a private key from function parameter 
   5481        if(typeof privateKey === "undefined")
   5482            return new Promise(function(resolve, reject) { reject("Need to provide a private key for signing"); });
   5483        // #endregion 
   5484 
   5485        // #region Get hashing algorithm 
   5486        if(typeof hashAlgorithm === "undefined")
   5487            hashAlgorithm = "SHA-1";
   5488        else
   5489        {
   5490            // #region Simple check for supported algorithm 
   5491            var oid = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   5492            if(oid === "")
   5493                return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   5494            // #endregion 
   5495        }
   5496        // #endregion 
   5497 
   5498        // #region Get a "default parameters" for current algorithm 
   5499        var defParams = in_window.org.pkijs.getAlgorithmParameters(privateKey.algorithm.name, "sign");
   5500        defParams.algorithm.hash.name = hashAlgorithm;
   5501        // #endregion 
   5502 
   5503        // #region Fill internal structures base on "privateKey" and "hashAlgorithm" 
   5504        switch(privateKey.algorithm.name.toUpperCase())
   5505        {
   5506            case "RSASSA-PKCS1-V1_5":
   5507            case "ECDSA":
   5508                _this.signatureAlgorithm.algorithm_id = in_window.org.pkijs.getOIDByAlgorithm(defParams.algorithm);
   5509                break;
   5510            case "RSA-PSS":
   5511                {
   5512                    // #region Set "saltLength" as a length (in octets) of hash function result 
   5513                    switch(hashAlgorithm.toUpperCase())
   5514                    {
   5515                        case "SHA-256":
   5516                            defParams.algorithm.saltLength = 32;
   5517                            break;
   5518                        case "SHA-384":
   5519                            defParams.algorithm.saltLength = 48;
   5520                            break;
   5521                        case "SHA-512":
   5522                            defParams.algorithm.saltLength = 64;
   5523                            break;
   5524                        default:
   5525                    }
   5526                    // #endregion 
   5527 
   5528                    // #region Fill "RSASSA_PSS_params" object 
   5529                    var paramsObject = {};
   5530 
   5531                    if(hashAlgorithm.toUpperCase() !== "SHA-1")
   5532                    {
   5533                        var hashAlgorithmOID = in_window.org.pkijs.getOIDByAlgorithm({ name: hashAlgorithm });
   5534                        if(hashAlgorithmOID === "")
   5535                            return new Promise(function(resolve, reject) { reject("Unsupported hash algorithm: " + hashAlgorithm); });
   5536 
   5537                        paramsObject.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   5538                            algorithm_id: hashAlgorithmOID,
   5539                            algorithm_params: new in_window.org.pkijs.asn1.NULL()
   5540                        });
   5541 
   5542                        paramsObject.maskGenAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   5543                            algorithm_id: "1.2.840.113549.1.1.8", // MGF1
   5544                            algorithm_params: paramsObject.hashAlgorithm.toSchema()
   5545                        })
   5546                    }
   5547 
   5548                    if(defParams.algorithm.saltLength !== 20)
   5549                        paramsObject.saltLength = defParams.algorithm.saltLength;
   5550 
   5551                    var pssParameters = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params(paramsObject);
   5552                    // #endregion   
   5553 
   5554                    // #region Automatically set signature algorithm 
   5555                    _this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
   5556                        algorithm_id: "1.2.840.113549.1.1.10",
   5557                        algorithm_params: pssParameters.toSchema()
   5558                    });
   5559                    // #endregion 
   5560                }
   5561                break;
   5562            default:
   5563                return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + privateKey.algorithm.name); });
   5564        }
   5565        // #endregion 
   5566 
   5567        // #region Create TBS data for signing 
   5568        _this.tbs = in_window.org.pkijs.simpl.PKCS10.prototype.encodeTBS.call(this).toBER(false);
   5569        // #endregion 
   5570 
   5571        // #region Get a "crypto" extension 
   5572        var crypto = in_window.org.pkijs.getCrypto();
   5573        if(typeof crypto == "undefined")
   5574            return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
   5575        // #endregion 
   5576 
   5577        // #region Signing TBS data on provided private key 
   5578        return crypto.sign(defParams.algorithm,
   5579            privateKey,
   5580            new Uint8Array(_this.tbs)).then(
   5581            function(result)
   5582            {
   5583                // #region Special case for ECDSA algorithm 
   5584                if(defParams.algorithm.name === "ECDSA")
   5585                    result = in_window.org.pkijs.createCMSECDSASignature(result);
   5586                // #endregion 
   5587 
   5588                _this.signatureValue = new in_window.org.pkijs.asn1.BITSTRING({ value_hex: result });
   5589            },
   5590            function(error)
   5591            {
   5592                return new Promise(function(resolve, reject) { reject("Signing error: " + error); });
   5593            }
   5594            );
   5595        // #endregion 
   5596    };
   5597    //**************************************************************************************
   5598    in_window.org.pkijs.simpl.PKCS10.prototype.toJSON =
   5599    function()
   5600    {
   5601        var _object = {
   5602            tbs: in_window.org.pkijs.bufferToHexCodes(this.tbs, 0, this.tbs.byteLength),
   5603            version: this.version,
   5604            subject: this.subject.toJSON(),
   5605            subjectPublicKeyInfo: this.subjectPublicKeyInfo.toJSON(),
   5606            signatureAlgorithm: this.signatureAlgorithm.toJSON(),
   5607            signatureValue: this.signatureValue.toJSON()
   5608        };
   5609 
   5610        if("attributes" in this)
   5611        {
   5612            _object.attributes = new Array();
   5613 
   5614            for(var i = 0; i < this.attributes.length; i++)
   5615                _object.attributes.push(this.attributes[i].toJSON());
   5616        }
   5617 
   5618        return _object;
   5619    };
   5620    //**************************************************************************************
   5621    // #endregion 
   5622    //**************************************************************************************
   5623    // #region Simplified structure for PKCS#8 private key bag
   5624    //**************************************************************************************
   5625    in_window.org.pkijs.simpl.PKCS8 =
   5626    function()
   5627    {
   5628        // #region Internal properties of the object 
   5629        this.version = 0;
   5630        this.privateKeyAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   5631        this.privateKey = new in_window.org.pkijs.asn1.OCTETSTRING();
   5632        // OPTIONAL this.attributes // Array of "in_window.org.pkijs.simpl.ATTRIBUTE"
   5633        // #endregion 
   5634 
   5635        // #region If input argument array contains "schema" for this object 
   5636        if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
   5637            in_window.org.pkijs.simpl.PKCS8.prototype.fromSchema.call(this, arguments[0].schema);
   5638        // #endregion 
   5639        // #region If input argument array contains "native" values for internal properties 
   5640        else
   5641        {
   5642            if(arguments[0] instanceof Object)
   5643            {
   5644                this.version = arguments[0].version || 0;
   5645                this.privateKeyAlgorithm = arguments[0].privateKeyAlgorithm || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
   5646                this.privateKey = arguments[0].privateKey || new in_window.org.pkijs.asn1.OCTETSTRING();
   5647 
   5648                if("attributes" in arguments[0])
   5649                    this.attributes = arguments[0].attributes;
   5650            }
   5651        }
   5652        // #endregion 
   5653    };
   5654    //**************************************************************************************
   5655    in_window.org.pkijs.simpl.PKCS8.prototype.fromSchema =
   5656    function(schema)
   5657    {
   5658        // #region Check the schema is valid 
   5659        var asn1 = in_window.org.pkijs.compareSchema(schema,
   5660            schema,
   5661            in_window.org.pkijs.schema.PKCS8({
   5662                names: {
   5663                    version: "version",
   5664                    privateKeyAlgorithm: {
   5665                        names: {
   5666                            block_name: "privateKeyAlgorithm"
   5667                        }
   5668                    },
   5669                    privateKey: "privateKey",
   5670                    attributes: "attributes"
   5671                }
   5672            })
   5673            );
   5674 
   5675        if(asn1.verified === false)
   5676            throw new Error("Object's schema was not verified against input data for PKCS8");
   5677        // #endregion 
   5678 
   5679        // #region Get internal properties from parsed schema 
   5680        this.version = asn1.result["version"].value_block.value_dec;
   5681        this.privateKeyAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["privateKeyAlgorithm"] });
   5682        this.privateKey = asn1.result["privateKey"];
   5683 
   5684        if("attributes" in asn1.result)
   5685        {
   5686            this.attributes = new Array();
   5687            var attrs = asn1.result["attributes"];
   5688 
   5689            for(var i = 0; i < attrs.length; i++)
   5690                this.attributes.push(new in_window.org.pkijs.simpl.ATTRIBUTE({ schema: attrs[i] }));
   5691        }
   5692        // #endregion 
   5693    };
   5694    //**************************************************************************************
   5695    in_window.org.pkijs.simpl.PKCS8.prototype.toSchema =
   5696    function()
   5697    {
   5698        // #region Create array for output sequence 
   5699        var output_array = new Array();
   5700 
   5701        output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.version }));
   5702        output_array.push(this.privateKeyAlgorithm.toSchema());
   5703        output_array.push(this.privateKey);
   5704 
   5705        if("attributes" in this)
   5706        {
   5707            var attrs = new Array();
   5708 
   5709            for(var i = 0; i < this.attributes.length; i++)
   5710                attrs.push(this.attributes[i].toSchema());
   5711 
   5712            output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
   5713                optional: true,
   5714                id_block: {
   5715                    tag_class: 3, // CONTEXT-SPECIFIC
   5716                    tag_number: 0 // [0]
   5717                },
   5718                value: attrs
   5719            }));
   5720        }
   5721        // #endregion 
   5722 
   5723        // #region Construct and return new ASN.1 schema for this object 
   5724        return (new in_window.org.pkijs.asn1.SEQUENCE({
   5725            value: output_array
   5726        }));
   5727        // #endregion 
   5728    };
   5729    //**************************************************************************************
   5730    in_window.org.pkijs.simpl.PKCS8.prototype.toJSON =
   5731    function()
   5732    {
   5733        var _object = {
   5734            version: this.version,
   5735            privateKeyAlgorithm: this.privateKeyAlgorithm.toJSON(),
   5736            privateKey: this.privateKey.toJSON()
   5737        };
   5738 
   5739        if("attributes" in this)
   5740        {
   5741            _object.attributes = new Array();
   5742 
   5743            for(var i = 0; i < this.attributes.length; i++)
   5744                _object.attributes.push(this.attributes[i].toJSON());
   5745        }
   5746 
   5747        return _object;
   5748    };
   5749    //**************************************************************************************
   5750    // #endregion 
   5751    //**************************************************************************************
   5752    // #region Simplified structure for working with X.509 certificate chains 
   5753    //**************************************************************************************
   5754    in_window.org.pkijs.simpl.CERT_CHAIN =
   5755    function()
   5756    {
   5757        // #region Internal properties of the object 
   5758        /// <field name="trusted_certs" type="Array" elementType="in_window.org.pkijs.simpl.CERT">Array of pre-defined trusted (by user) certificates</field>
   5759        this.trusted_certs = new Array();
   5760        /// <field name="certs" type="Array" elementType="in_window.org.pkijs.simpl.CERT">Array with certificate chain. Could be only one end-user certificate in there!</field>
   5761        this.certs = new Array();
   5762        /// <field name="crls" type="Array" elementType="in_window.org.pkijs.simpl.CRL">Array of all CRLs for all certificates from certificate chain</field>
   5763        this.crls = new Array();
   5764        // #endregion 
   5765 
   5766        // #region Initialize internal properties by input values
   5767        if(arguments[0] instanceof Object)
   5768        {
   5769            this.trusted_certs = arguments[0].trusted_certs || new Array();
   5770            this.certs = arguments[0].certs || new Array();
   5771            this.crls = arguments[0].crls || new Array();
   5772        }
   5773        // #endregion 
   5774    };
   5775    //**************************************************************************************
   5776    in_window.org.pkijs.simpl.CERT_CHAIN.prototype.sort =
   5777    function()
   5778    {
   5779        // #region Initial variables 
   5780        /// <var type="Array" elementType="in_window.org.pkijs.simpl.CERT">Array of sorted certificates</var>
   5781        var sorted_certs = new Array();
   5782 
   5783        /// <var type="Array" elementType="in_window.org.pkijs.simpl.CERT">Initial array of certificates</var>
   5784        var certs = this.certs.slice(0); // Explicity copy "this.certs"
   5785 
   5786        /// <var type="Date">Date for checking certificate validity period</var>
   5787        var check_date = new Date();
   5788 
   5789        var _this = this;
   5790        // #endregion 
   5791 
   5792        // #region Initial checks 
   5793        if(certs.length === 0)
   5794            return new Promise(function(resolve, reject)
   5795            {
   5796                reject({
   5797                    result: false,
   5798                    result_code: 2,
   5799                    result_message: "Certificate's array can not be empty"
   5800                });
   5801            });
   5802        // #endregion 
   5803 
   5804        // #region Find end-user certificate 
   5805        var end_user_index = -1;
   5806 
   5807        for(var i = 0; i < certs.length; i++)
   5808        {
   5809            var isCA = false;
   5810 
   5811            if("extensions" in certs[i])
   5812            {
   5813                var mustBeCA = false;
   5814                var keyUsagePresent = false;
   5815                var cRLSign = false;
   5816 
   5817                for(var j = 0; j < certs[i].extensions.length; j++)
   5818                {
   5819                    if((certs[i].extensions[j].critical === true) &&
   5820                       (("parsedValue" in certs[i].extensions[j]) === false))
   5821                    {
   5822                        return new Promise(function(resolve, reject)
   5823                        {
   5824                            reject({
   5825                                result: false,
   5826                                result_code: 6,
   5827                                result_message: "Unable to parse critical certificate extension: " + certs[i].extensions[j].extnID
   5828                            });
   5829                        });
   5830                    }
   5831 
   5832                    if(certs[i].extensions[j].extnID === "2.5.29.15") // KeyUsage
   5833                    {
   5834                        keyUsagePresent = true;
   5835 
   5836                        var view = new Uint8Array(certs[i].extensions[j].parsedValue.value_block.value_hex);
   5837 
   5838                        if((view[0] & 0x04) === 0x04) // Set flag "keyCertSign"
   5839                            mustBeCA = true;
   5840 
   5841                        if((view[0] & 0x02) === 0x02) // Set flag "cRLSign"
   5842                            cRLSign = true;
   5843                    }
   5844 
   5845                    if(certs[i].extensions[j].extnID === "2.5.29.19") // BasicConstraints
   5846                    {
   5847                        if("cA" in certs[i].extensions[j].parsedValue)
   5848                        {
   5849                            if(certs[i].extensions[j].parsedValue.cA === true)
   5850                                isCA = true;
   5851                        }
   5852                    }
   5853                }
   5854 
   5855                if((mustBeCA === true) && (isCA === false))
   5856                    return new Promise(function(resolve, reject)
   5857                    {
   5858                        reject({
   5859                            result: false,
   5860                            result_code: 3,
   5861                            result_message: "Unable to build certificate chain - using \"keyCertSign\" flag set without BasicConstaints"
   5862                        });
   5863                    });
   5864 
   5865                if((keyUsagePresent === true) && (isCA === true) && (mustBeCA === false))
   5866                    return new Promise(function(resolve, reject)
   5867                    {
   5868                        reject({
   5869                            result: false,
   5870                            result_code: 4,
   5871                            result_message: "Unable to build certificate chain - \"keyCertSign\" flag was not set"
   5872                        });
   5873                    });
   5874 
   5875                if((isCA === true) && (keyUsagePresent === true) && (cRLSign === false))
   5876                    return new Promise(function(resolve, reject)
   5877                    {
   5878                        reject({
   5879                            result: false,
   5880                            result_code: 5,
   5881                            result_message: "Unable to build certificate chain - intermediate certificate must have \"cRLSign\" key usage flag"
   5882                        });
   5883                    });
   5884            }
   5885 
   5886            if(isCA === false)
   5887            {
   5888                if(sorted_certs.length !== 0)
   5889                    return new Promise(function(resolve, reject)
   5890                    {
   5891                        reject({
   5892                            result: false,
   5893                            result_code: 7,
   5894                            result_message: "Unable to build certificate chain - more than one possible end-user certificate"
   5895                        });
   5896                    });
   5897 
   5898                sorted_certs.push(certs[i]);
   5899                end_user_index = i;
   5900            }
   5901        }
   5902 
   5903        certs.splice(end_user_index, 1);
   5904        // #endregion 
   5905 
   5906        // #region Check that end-user certificate was found 
   5907        if(sorted_certs.length === 0)
   5908            return new Promise(function(resolve, reject)
   5909            {
   5910                reject({
   5911                    result: false,
   5912                    result_code: 1,
   5913                    result_message: "Can't find end-user certificate"
   5914                });
   5915            });
   5916        // #endregion 
   5917 
   5918        // #region Return if there is only one certificate in certificate's array 
   5919        if(certs.length === 0)
   5920        {
   5921            if(sorted_certs[0].issuer.isEqual(sorted_certs[0].subject) === true)
   5922                return new Promise(function(resolve, reject) { resolve(sorted_certs); });
   5923            else
   5924            {
   5925                if(this.trusted_certs.length === 0)
   5926                {
   5927                    return new Promise(function(resolve, reject)
   5928                    {
   5929                        reject({
   5930                            result: false,
   5931                            result_code: 70,
   5932                            result_message: "Can't find root certificate"
   5933                        });
   5934                    });
   5935                }
   5936                else
   5937                {
   5938                    certs = _this.trusted_certs.splice(0);
   5939                }
   5940            }
   5941 
   5942        }
   5943        // #endregion 
   5944 
   5945        /// <var type="in_window.org.pkijs.simpl.CERT">Current certificate (to find issuer for)</var>
   5946        var current_certificate = sorted_certs[0];
   5947 
   5948        // #region Auxiliary functions working with Promises
   5949        function basic(subject_certificate, issuer_certificate)
   5950        {
   5951            /// <summary>Basic certificate checks</summary>
   5952            /// <param name="subject_certificate" type="in_window.org.pkijs.simpl.CERT">Certificate for testing (subject)</param>
   5953            /// <param name="issuer_certificate" type="in_window.org.pkijs.simpl.CERT">Certificate for issuer of subject certificate</param>
   5954 
   5955            // #region Initial variables 
   5956            var sequence = Promise.resolve();
   5957            // #endregion 
   5958 
   5959            // #region Check validity period for subject certificate 
   5960            sequence = sequence.then(
   5961                function()
   5962                {
   5963                    if((subject_certificate.notBefore.value > check_date) ||
   5964                       (subject_certificate.notAfter.value < check_date))
   5965                    {
   5966                        return new Promise(function(resolve, reject)
   5967                        {
   5968                            reject({
   5969                                result: false,
   5970                                result_code: 8,
   5971                                result_message: "Certificate validity period is out of checking date"
   5972                            });
   5973                        });
   5974                    }
   5975                }
   5976                );
   5977            // #endregion 
   5978 
   5979            // #region Give ability to not provide CRLs (all certificates assume to be valid) 
   5980            if(_this.crls.length === 0)
   5981                return sequence.then(
   5982                    function()
   5983                    {
   5984                        return new Promise(function(resolve, reject) { resolve(); });
   5985                    }
   5986                    );
   5987            // #endregion 
   5988 
   5989            // #region Find correct CRL for "issuer_certificate" 
   5990            function find_crl(index)
   5991            {
   5992                return _this.crls[index].verify({ issuerCertificate: issuer_certificate }).then(
   5993                    function(result)
   5994                    {
   5995                        if(result === true)
   5996                            return new Promise(function(resolve, reject) { resolve(_this.crls[index]); });
   5997                        else
   5998                        {
   5999                            index++;
   6000 
   6001                            if(index < _this.crls.length)
   6002                                return find_crl(index);
   6003                            else
   6004                                return new Promise(function(resolve, reject)
   6005                                {
   6006                                    reject({
   6007                                        result: false,
   6008                                        result_code: 9,
   6009                                        result_message: "Unable to find CRL for issuer's certificate"
   6010                                    });
   6011                                });
   6012                        }
   6013                    },
   6014                    function(error)
   6015                    {
   6016                        return new Promise(function(resolve, reject)
   6017                        {
   6018                            reject({
   6019                                result: false,
   6020                                result_code: 10,
   6021                                result_message: "Unable to find CRL for issuer's certificate"
   6022                            });
   6023                        });
   6024                    }
   6025                    );
   6026            }
   6027 
   6028            sequence = sequence.then(
   6029                function()
   6030                {
   6031                    return find_crl(0);
   6032                }
   6033                );
   6034            // #endregion 
   6035 
   6036            // #region Check that subject certificate is not in the CRL 
   6037            sequence = sequence.then(
   6038                function(crl)
   6039                {
   6040                    /// <param name="crl" type="in_window.org.pkijs.simpl.CRL">CRL for issuer's certificate</param>                
   6041 
   6042                    if(crl.isCertificateRevoked({ certificate: subject_certificate }) === true)
   6043                        return new Promise(function(resolve, reject)
   6044                        {
   6045                            reject({
   6046                                result: false,
   6047                                result_code: 11,
   6048                                result_message: "Subject certificate was revoked"
   6049                            });
   6050                        });
   6051                    else
   6052                        return new Promise(function(resolve, reject) { resolve(); });
   6053                },
   6054                function(error)
   6055                {
   6056                    /// <summary>Not for all certificates we have a CRL. So, this "stub" is for handling such situation - assiming we have a valid, non-revoked certificate</summary>
   6057                    return new Promise(function(resolve, reject) { resolve(); });
   6058                }
   6059                );
   6060            // #endregion 
   6061 
   6062            return sequence;
   6063        }
   6064 
   6065        function outer()
   6066        {
   6067            return inner(current_certificate, 0).then(
   6068                function(index)
   6069                {
   6070                    sorted_certs.push(certs[index]);
   6071                    current_certificate = certs[index];
   6072 
   6073                    certs.splice(index, 1);
   6074 
   6075                    if(current_certificate.issuer.isEqual(current_certificate.subject) === true)
   6076                    {
   6077                        // #region Check that the "self-signed" certificate there is in "trusted_certs" array 
   6078                        var found = (_this.trusted_certs.length === 0); // If user did not set "trusted_certs" then we have an option to trust any self-signed certificate as root
   6079 
   6080                        for(var i = 0; i < _this.trusted_certs.length; i++)
   6081                        {
   6082                            if((current_certificate.issuer.isEqual(_this.trusted_certs[i].issuer) === true) &&
   6083                               (current_certificate.subject.isEqual(_this.trusted_certs[i].subject) === true) &&
   6084                               (current_certificate.serialNumber.isEqual(_this.trusted_certs[i].serialNumber) === true))
   6085                            {
   6086                                found = true;
   6087                                break;
   6088                            }
   6089                        }
   6090 
   6091                        if(found === false)
   6092                            return new Promise(function(resolve, reject)
   6093                            {
   6094                                reject({
   6095                                    result: false,
   6096                                    result_code: 22,
   6097                                    result_message: "Self-signed root certificate not in \"trusted certificates\" array"
   6098                                });
   6099                            });
   6100                        // #endregion 
   6101 
   6102                        return (current_certificate.verify()).then( // Verifing last, self-signed certificate
   6103                            function(result)
   6104                            {
   6105                                if(result === true)
   6106                                    return basic(current_certificate, current_certificate).then(
   6107                                        function()
   6108                                        {
   6109                                            return new Promise(function(resolve, reject) { resolve(sorted_certs); });
   6110                                        },
   6111                                        function(error)
   6112                                        {
   6113                                            return new Promise(function(resolve, reject)
   6114                                            {
   6115                                                reject({
   6116                                                    result: false,
   6117                                                    result_code: 12,
   6118                                                    result_message: error
   6119                                                });
   6120                                            });
   6121                                        }
   6122                                        );
   6123                                else
   6124                                    return new Promise(function(resolve, reject)
   6125                                    {
   6126                                        reject({
   6127                                            result: false,
   6128                                            result_code: 13,
   6129                                            result_message: "Unable to build certificate chain - signature of root certificate is invalid"
   6130                                        });
   6131                                    });
   6132                            },
   6133                            function(error)
   6134                            {
   6135                                return new Promise(function(resolve, reject)
   6136                                {
   6137                                    reject({
   6138                                        result: false,
   6139                                        result_code: 14,
   6140                                        result_message: error
   6141                                    });
   6142                                });
   6143                            }
   6144                            );
   6145                    }
   6146                    else // In case if self-signed cert for the chain in the "trusted_certs" array
   6147                    {
   6148                        if(certs.length > 0)
   6149                            return outer();
   6150                        else
   6151                        {
   6152                            if(_this.trusted_certs.length !== 0)
   6153                            {
   6154                                certs = _this.trusted_certs.splice(0);
   6155                                return outer();
   6156                            }
   6157                            else
   6158                                return new Promise(function(resolve, reject)
   6159                                {
   6160                                    reject({
   6161                                        result: false,
   6162                                        result_code: 23,
   6163                                        result_message: "Root certificate not found"
   6164                                    });
   6165                                });
   6166                        }
   6167                    }
   6168                },
   6169                function(error)
   6170                {
   6171                    return new Promise(function(resolve, reject)
   6172                    {
   6173                        reject(error);
   6174                    });
   6175                }
   6176                );
   6177        }
   6178 
   6179        function inner(current_certificate, index)
   6180        {
   6181            if(certs[index].subject.isEqual(current_certificate.issuer) === true)
   6182            {
   6183                return current_certificate.verify({ issuerCertificate: certs[index] }).then(
   6184                    function(result)
   6185                    {
   6186                        if(result === true)
   6187                        {
   6188                            return basic(current_certificate, certs[index]).then(
   6189                                function()
   6190                                {
   6191                                    return new Promise(function(resolve, reject) { resolve(index); });
   6192                                },
   6193                                function(error)
   6194                                {
   6195                                    return new Promise(function(resolve, reject)
   6196                                    {
   6197                                        reject({
   6198                                            result: false,
   6199                                            result_code: 16,
   6200                                            result_message: error
   6201                                        });
   6202                                    });
   6203                                }
   6204                                );
   6205                        }
   6206                        else
   6207                        {
   6208                            if(index < (certs.length - 1))
   6209                                return inner(current_certificate, index + 1);
   6210                            else
   6211                                return new Promise(function(resolve, reject)
   6212                                {
   6213                                    reject({
   6214                                        result: false,
   6215                                        result_code: 17,
   6216                                        result_message: "Unable to build certificate chain - incomplete certificate chain or signature of some certificate is invalid"
   6217                                    });
   6218                                });
   6219                        }
   6220                    },
   6221                    function(error)
   6222                    {
   6223                        return new Promise(function(resolve, reject)
   6224                        {
   6225                            reject({
   6226                                result: false,
   6227                                result_code: 18,
   6228                                result_message: "Unable to build certificate chain - error during certificate signature verification"
   6229                            });
   6230                        });
   6231                    }
   6232                    );
   6233            }
   6234            else
   6235            {
   6236                if(index < (certs.length - 1))
   6237                    return inner(current_certificate, index + 1);
   6238                else
   6239                    return new Promise(function(resolve, reject)
   6240                    {
   6241                        reject({
   6242                            result: false,
   6243                            result_code: 19,
   6244                            result_message: "Unable to build certificate chain - incomplete certificate chain"
   6245                        });
   6246                    });
   6247            }
   6248        }
   6249        // #endregion   
   6250 
   6251        // #region Find certificates for all issuers 
   6252        return outer();
   6253        // #endregion 
   6254    };
   6255    //**************************************************************************************
   6256    in_window.org.pkijs.simpl.CERT_CHAIN.prototype.verify =
   6257    function()
   6258    {
   6259        // #region Initial checks 
   6260        if(this.certs.length === 0)
   6261            return new Promise(function(resolve, reject) { reject("Empty certificate array"); });
   6262        // #endregion 
   6263 
   6264        // #region Initial variables 
   6265        var sequence = Promise.resolve();
   6266 
   6267        var _this = this;
   6268        // #endregion 
   6269 
   6270        // #region Get input variables 
   6271        var initial_policy_set = new Array();
   6272        initial_policy_set.push("2.5.29.32.0"); // "anyPolicy"
   6273 
   6274        var initial_explicit_policy = false;
   6275        var initial_policy_mapping_inhibit = false;
   6276        var initial_inhibit_policy = false;
   6277 
   6278        var initial_permitted_subtrees_set = new Array(); // Array of "simpl.x509.GeneralSubtree"
   6279        var initial_excluded_subtrees_set = new Array();  // Array of "simpl.x509.GeneralSubtree"
   6280        var initial_required_name_forms = new Array();    // Array of "simpl.x509.GeneralSubtree"
   6281 
   6282        var verification_time = new Date();
   6283 
   6284        if(arguments[0] instanceof Object)
   6285        {
   6286            if("initial_policy_set" in arguments[0])
   6287                initial_policy_set = arguments[0].initial_policy_set;
   6288 
   6289            if("initial_explicit_policy" in arguments[0])
   6290                initial_explicit_policy = arguments[0].initial_explicit_policy;
   6291 
   6292            if("initial_policy_mapping_inhibit" in arguments[0])
   6293                initial_policy_mapping_inhibit = arguments[0].initial_policy_mapping_inhibit;
   6294 
   6295            if("initial_inhibit_policy" in arguments[0])
   6296                initial_inhibit_policy = arguments[0].initial_inhibit_policy;
   6297 
   6298            if("initial_permitted_subtrees_set" in arguments[0])
   6299                initial_permitted_subtrees_set = arguments[0].initial_permitted_subtrees_set;
   6300 
   6301            if("initial_excluded_subtrees_set" in arguments[0])
   6302                initial_excluded_subtrees_set = arguments[0].initial_excluded_subtrees_set;
   6303 
   6304            if("initial_required_name_forms" in arguments[0])
   6305                initial_required_name_forms = arguments[0].initial_required_name_forms;
   6306        }
   6307 
   6308        var explicit_policy_indicator = initial_explicit_policy;
   6309        var policy_mapping_inhibit_indicator = initial_policy_mapping_inhibit;
   6310        var inhibit_any_policy_indicator = initial_inhibit_policy;
   6311 
   6312        var pending_constraints = new Array(3);
   6313        pending_constraints[0] = false; // For "explicit_policy_pending"
   6314        pending_constraints[1] = false; // For "policy_mapping_inhibit_pending"
   6315        pending_constraints[2] = false; // For "inhibit_any_policy_pending"
   6316 
   6317        var explicit_policy_pending = 0;
   6318        var policy_mapping_inhibit_pending = 0;
   6319        var inhibit_any_policy_pending = 0;
   6320 
   6321        var permitted_subtrees = initial_permitted_subtrees_set;
   6322        var excluded_subtrees = initial_excluded_subtrees_set;
   6323        var required_name_forms = initial_required_name_forms;
   6324 
   6325        var path_depth = 1;
   6326        // #endregion 
   6327 
   6328        // #region Sorting certificates in the chain array 
   6329        sequence = (in_window.org.pkijs.simpl.CERT_CHAIN.prototype.sort.call(this)).then(
   6330            function(sorted_certs)
   6331            {
   6332                _this.certs = sorted_certs;
   6333            }
   6334            );
   6335        // #endregion 
   6336 
   6337        // #region Work with policies
   6338        sequence = sequence.then(
   6339            function()
   6340            {
   6341                // #region Support variables 
   6342                var all_policies = new Array(); // Array of all policies (string values)
   6343                all_policies.push("2.5.29.32.0"); // Put "anyPolicy" at first place
   6344 
   6345                var policies_and_certs = new Array(); // In fact "array of array" where rows are for each specific policy, column for each certificate and value is "true/false"
   6346 
   6347                var any_policy_array = new Array(_this.certs.length - 1); // Minus "trusted anchor"
   6348                for(var ii = 0; ii < (_this.certs.length - 1) ; ii++)
   6349                    any_policy_array[ii] = true;
   6350 
   6351                policies_and_certs.push(any_policy_array);
   6352 
   6353                var policy_mappings = new Array(_this.certs.length - 1); // Array of "PolicyMappings" for each certificate
   6354                var cert_policies = new Array(_this.certs.length - 1); // Array of "CertificatePolicies" for each certificate
   6355                // #endregion 
   6356 
   6357                for(var i = (_this.certs.length - 2) ; i >= 0 ; i--, path_depth++)
   6358                {
   6359                    if("extensions" in _this.certs[i])
   6360                    {
   6361                        for(var j = 0; j < _this.certs[i].extensions.length; j++)
   6362                        {
   6363                            // #region CertificatePolicies 
   6364                            if(_this.certs[i].extensions[j].extnID === "2.5.29.32")
   6365                            {
   6366                                cert_policies[i] = _this.certs[i].extensions[j].parsedValue;
   6367 
   6368                                for(var k = 0; k < _this.certs[i].extensions[j].parsedValue.certificatePolicies.length; k++)
   6369                                {
   6370                                    var policy_index = (-1);
   6371 
   6372                                    // #region Try to find extension in "all_policies" array 
   6373                                    for(var s = 0; s < all_policies.length; s++)
   6374                                    {
   6375                                        if(_this.certs[i].extensions[j].parsedValue.certificatePolicies[k].policyIdentifier === all_policies[s])
   6376                                        {
   6377                                            policy_index = s;
   6378                                            break;
   6379                                        }
   6380                                    }
   6381                                    // #endregion 
   6382 
   6383                                    if(policy_index === (-1))
   6384                                    {
   6385                                        all_policies.push(_this.certs[i].extensions[j].parsedValue.certificatePolicies[k].policyIdentifier);
   6386 
   6387                                        var cert_array = new Array(_this.certs.length - 1);
   6388                                        cert_array[i] = true;
   6389 
   6390                                        policies_and_certs.push(cert_array);
   6391                                    }
   6392                                    else(policies_and_certs[policy_index])[i] = true;
   6393                                }
   6394                            }
   6395                            // #endregion 
   6396 
   6397                            // #region PolicyMappings 
   6398                            if(_this.certs[i].extensions[j].extnID === "2.5.29.33")
   6399                                policy_mappings[i] = _this.certs[i].extensions[j].parsedValue;
   6400                            // #endregion 
   6401 
   6402                            // #region PolicyConstraints 
   6403                            if(_this.certs[i].extensions[j].extnID === "2.5.29.36")
   6404                            {
   6405                                if(explicit_policy_indicator == false)
   6406                                {
   6407                                    // #region requireExplicitPolicy 
   6408                                    if(_this.certs[i].extensions[j].parsedValue.requireExplicitPolicy === 0)
   6409                                        explicit_policy_indicator = true;
   6410                                    else
   6411                                    {
   6412                                        if(pending_constraints[0] === false)
   6413                                        {
   6414                                            pending_constraints[0] = true;
   6415                                            explicit_policy_pending = _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy;
   6416                                        }
   6417                                        else
   6418                                        {
   6419                                            explicit_policy_pending = (explicit_policy_pending > _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy) ? _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy : explicit_policy_pending;
   6420                                        }
   6421                                    }
   6422                                    // #endregion 
   6423 
   6424                                    // #region inhibitPolicyMapping 
   6425                                    if(_this.certs[i].extensions[j].parsedValue.inhibitPolicyMapping === 0)
   6426                                        policy_mapping_inhibit_indicator = true;
   6427                                    else
   6428                                    {
   6429                                        if(pending_constraints[1] === false)
   6430                                        {
   6431                                            pending_constraints[1] = true;
   6432                                            policy_mapping_inhibit_pending = _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy;
   6433                                        }
   6434                                        else
   6435                                        {
   6436                                            policy_mapping_inhibit_pending = (policy_mapping_inhibit_pending > _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy) ? _this.certs[i].extensions[j].parsedValue.requireExplicitPolicy : policy_mapping_inhibit_pending;
   6437                                        }
   6438                                    }
   6439                                    // #endregion   
   6440                                }
   6441                            }
   6442                            // #endregion 
   6443 
   6444                            // #region InhibitAnyPolicy
   6445                            if(_this.certs[i].extensions[j].extnID === "2.5.29.54")
   6446                            {
   6447                                if(inhibit_any_policy_indicator === false)
   6448                                {
   6449                                    if(_this.certs[i].extensions[j].parsedValue.value_block.value_dec === 0)
   6450                                        inhibit_any_policy_indicator = true;
   6451                                    else
   6452                                    {
   6453                                        if(pending_constraints[2] === false)
   6454                                        {
   6455                                            pending_constraints[2] = true;
   6456                                            inhibit_any_policy_pending = _this.certs[i].extensions[j].parsedValue.value_block.value_dec;
   6457                                        }
   6458                                        else
   6459                                        {
   6460                                            inhibit_any_policy_pending = (inhibit_any_policy_pending > _this.certs[i].extensions[j].parsedValue.value_block.value_dec) ? _this.certs[i].extensions[j].parsedValue.value_block.value_dec : inhibit_any_policy_pending;
   6461                                        }
   6462                                    }
   6463                                }
   6464                            }
   6465                            // #endregion 
   6466                        }
   6467 
   6468                        // #region Check "inhibit_any_policy_indicator" 
   6469                        if(inhibit_any_policy_indicator === true)
   6470                            delete (policies_and_certs[0])[i]; // Unset value to "undefined" for "anyPolicies" value for current certificate
   6471                        // #endregion 
   6472 
   6473                        // #region Combine information from certificate policies and policy mappings 
   6474                        if((typeof cert_policies[i] !== "undefined") &&
   6475                           (typeof policy_mappings[i] !== "undefined") &&
   6476                           (policy_mapping_inhibit_indicator === false))
   6477                        {
   6478                            for(var m = 0; m < cert_policies[i].certificatePolicies.length; m++)
   6479                            {
   6480                                var domainPolicy = "";
   6481 
   6482                                // #region Find if current policy is in "mappings" array 
   6483                                for(var n = 0; n < policy_mappings[i].mappings.length; n++)
   6484                                {
   6485                                    if(policy_mappings[i].mappings[n].subjectDomainPolicy === cert_policies[i].certificatePolicies[m].policyIdentifier)
   6486                                    {
   6487                                        domainPolicy = policy_mappings[i].mappings[n].issuerDomainPolicy;
   6488                                        break;
   6489                                    }
   6490 
   6491                                    // #region Could be the case for some reasons 
   6492                                    if(policy_mappings[i].mappings[n].issuerDomainPolicy === cert_policies[i].certificatePolicies[m].policyIdentifier)
   6493                                    {
   6494                                        domainPolicy = policy_mappings[i].mappings[n].subjectDomainPolicy;
   6495                                        break;
   6496                                    }
   6497                                    // #endregion 
   6498                                }
   6499 
   6500                                if(domainPolicy === "")
   6501                                    continue;
   6502                                // #endregion
   6503 
   6504                                // #region Find the index of "domainPolicy"  
   6505                                var domainPolicy_index = (-1);
   6506 
   6507                                for(var p = 0; p < all_policies.length; p++)
   6508                                {
   6509                                    if(all_policies[p] === domainPolicy)
   6510                                    {
   6511                                        domainPolicy_index = p;
   6512                                        break;
   6513                                    }
   6514                                }
   6515                                // #endregion 
   6516 
   6517                                // #region Change array value for "domainPolicy" 
   6518                                if(domainPolicy_index !== (-1))
   6519                                    (policies_and_certs[domainPolicy_index])[i] = true; // Put "set" in "domainPolicy" cell for specific certificate
   6520                                // #endregion 
   6521                            }
   6522                        }
   6523                        // #endregion 
   6524 
   6525                        // #region Process with "pending constraints" 
   6526                        if(explicit_policy_indicator === false)
   6527                        {
   6528                            if(pending_constraints[0] === true)
   6529                            {
   6530                                explicit_policy_pending--;
   6531                                if(explicit_policy_pending === 0)
   6532                                {
   6533                                    explicit_policy_indicator = true;
   6534                                    pending_constraints[0] = false;
   6535                                }
   6536                            }
   6537                        }
   6538 
   6539                        if(policy_mapping_inhibit_indicator === false)
   6540                        {
   6541                            if(pending_constraints[1] === true)
   6542                            {
   6543                                policy_mapping_inhibit_pending--;
   6544                                if(policy_mapping_inhibit_pending === 0)
   6545                                {
   6546                                    policy_mapping_inhibit_indicator = true;
   6547                                    pending_constraints[1] = false;
   6548                                }
   6549                            }
   6550                        }
   6551 
   6552                        if(inhibit_any_policy_indicator === false)
   6553                        {
   6554                            if(pending_constraints[2] === true)
   6555                            {
   6556                                inhibit_any_policy_pending--;
   6557                                if(inhibit_any_policy_pending === 0)
   6558                                {
   6559                                    inhibit_any_policy_indicator = true;
   6560                                    pending_constraints[2] = false;
   6561                                }
   6562                            }
   6563                        }
   6564                        // #endregion 
   6565                    }
   6566                }
   6567 
   6568                // #region Create "set of authorities-constrained policies"
   6569                var auth_constr_policies = new Array();
   6570 
   6571                for(var i = 0; i < policies_and_certs.length; i++)
   6572                {
   6573                    var found = true;
   6574 
   6575                    for(var j = 0; j < (_this.certs.length - 1) ; j++)
   6576                    {
   6577                        if(typeof (policies_and_certs[i])[j] === "undefined")
   6578                        {
   6579                            found = false;
   6580                            break;
   6581                        }
   6582                    }
   6583 
   6584                    if(found === true)
   6585                        auth_constr_policies.push(all_policies[i]);
   6586                }
   6587                // #endregion 
   6588 
   6589                // #region Create "set of user-constrained policies"
   6590                var user_constr_policies = new Array();
   6591 
   6592                for(var i = 0; i < auth_constr_policies.length; i++)
   6593                {
   6594                    for(var j = 0; j < initial_policy_set.length; j++)
   6595                    {
   6596                        if(initial_policy_set[j] === auth_constr_policies[i])
   6597                        {
   6598                            user_constr_policies.push(initial_policy_set[j]);
   6599                            break;
   6600                        }
   6601                    }
   6602                }
   6603                // #endregion 
   6604 
   6605                // #region Combine output object 
   6606                return {
   6607                    result: (user_constr_policies.length > 0),
   6608                    result_code: 0,
   6609                    result_message: (user_constr_policies.length > 0) ? "" : "Zero \"user_constr_policies\" array, no intersections with \"auth_constr_policies\"",
   6610                    auth_constr_policies: auth_constr_policies,
   6611                    user_constr_policies: user_constr_policies,
   6612                    explicit_policy_indicator: explicit_policy_indicator,
   6613                    policy_mappings: policy_mappings
   6614                };
   6615                // #endregion 
   6616            }
   6617            );
   6618        // #endregion 
   6619 
   6620        // #region Work with name constraints
   6621        sequence = sequence.then(
   6622            function(policy_result)
   6623            {
   6624                // #region Auxiliary functions for name constraints checking
   6625                function compare_dNSName(name, constraint)
   6626                {
   6627                    /// <summary>Compare two dNSName values</summary>
   6628                    /// <param name="name" type="String">DNS from name</param>
   6629                    /// <param name="constraint" type="String">Constraint for DNS from name</param>
   6630                    /// <returns type="Boolean">Boolean result - valid or invalid the "name" against the "constraint"</returns>
   6631 
   6632                    // #region Make a "string preparation" for both name and constrain 
   6633                    var name_prepared = in_window.org.pkijs.stringPrep(name);
   6634                    var constraint_prepared = in_window.org.pkijs.stringPrep(constraint);
   6635                    // #endregion 
   6636 
   6637                    // #region Make a "splitted" versions of "constraint" and "name" 
   6638                    var name_splitted = name_prepared.split(".");
   6639                    var constraint_splitted = constraint_prepared.split(".");
   6640                    // #endregion 
   6641 
   6642                    // #region Length calculation and additional check 
   6643                    var name_len = name_splitted.length;
   6644                    var constr_len = constraint_splitted.length;
   6645 
   6646                    if((name_len === 0) || (constr_len === 0) || (name_len < constr_len))
   6647                        return false;
   6648                    // #endregion 
   6649 
   6650                    // #region Check that no part of "name" has zero length 
   6651                    for(var i = 0; i < name_len; i++)
   6652                    {
   6653                        if(name_splitted[i].length === 0)
   6654                            return false;
   6655                    }
   6656                    // #endregion 
   6657 
   6658                    // #region Check that no part of "constraint" has zero length
   6659                    for(var i = 0; i < constr_len; i++)
   6660                    {
   6661                        if(constraint_splitted[i].length === 0)
   6662                        {
   6663                            if(i === 0)
   6664                            {
   6665                                if(constr_len === 1)
   6666                                    return false;
   6667                                else
   6668                                    continue;
   6669                            }
   6670 
   6671                            return false;
   6672                        }
   6673                    }
   6674                    // #endregion 
   6675 
   6676                    // #region Check that "name" has a tail as "constraint" 
   6677 
   6678                    for(var i = 0; i < constr_len; i++)
   6679                    {
   6680                        if(constraint_splitted[constr_len - 1 - i].length === 0)
   6681                            continue;
   6682 
   6683                        if(name_splitted[name_len - 1 - i].localeCompare(constraint_splitted[constr_len - 1 - i]) !== 0)
   6684                            return false;
   6685                    }
   6686                    // #endregion 
   6687 
   6688                    return true;
   6689                }
   6690 
   6691                function compare_rfc822Name(name, constraint)
   6692                {
   6693                    /// <summary>Compare two rfc822Name values</summary>
   6694                    /// <param name="name" type="String">E-mail address from name</param>
   6695                    /// <param name="constraint" type="String">Constraint for e-mail address from name</param>
   6696                    /// <returns type="Boolean">Boolean result - valid or invalid the "name" against the "constraint"</returns>
   6697 
   6698                    // #region Make a "string preparation" for both name and constrain 
   6699                    var name_prepared = in_window.org.pkijs.stringPrep(name);
   6700                    var constraint_prepared = in_window.org.pkijs.stringPrep(constraint);
   6701                    // #endregion 
   6702 
   6703                    // #region Make a "splitted" versions of "constraint" and "name" 
   6704                    var name_splitted = name_prepared.split("@");
   6705                    var constraint_splitted = constraint_prepared.split("@");
   6706                    // #endregion 
   6707 
   6708                    // #region Splitted array length checking 
   6709                    if((name_splitted.length === 0) || (constraint_splitted.length === 0) || (name_splitted.length < constraint_splitted.length))
   6710                        return false;
   6711                    // #endregion 
   6712 
   6713                    if(constraint_splitted.length === 1)
   6714                    {
   6715                        var result = compare_dNSName(name_splitted[1], constraint_splitted[0]);
   6716 
   6717                        if(result)
   6718                        {
   6719                            // #region Make a "splitted" versions of domain name from "constraint" and "name" 
   6720                            var ns = name_splitted[1].split(".");
   6721                            var cs = constraint_splitted[0].split(".");
   6722                            // #endregion 
   6723 
   6724                            if(cs[0].length === 0)
   6725                                return true;
   6726 
   6727                            return ns.length === cs.length;
   6728                        }
   6729                        else
   6730                            return false;
   6731                    }
   6732                    else
   6733                        return (name_prepared.localeCompare(constraint_prepared) === 0);
   6734 
   6735                    return false;
   6736                }
   6737 
   6738                function compare_uniformResourceIdentifier(name, constraint)
   6739                {
   6740                    /// <summary>Compare two uniformResourceIdentifier values</summary>
   6741                    /// <param name="name" type="String">uniformResourceIdentifier from name</param>
   6742                    /// <param name="constraint" type="String">Constraint for uniformResourceIdentifier from name</param>
   6743                    /// <returns type="Boolean">Boolean result - valid or invalid the "name" against the "constraint"</returns>
   6744 
   6745                    // #region Make a "string preparation" for both name and constrain 
   6746                    var name_prepared = in_window.org.pkijs.stringPrep(name);
   6747                    var constraint_prepared = in_window.org.pkijs.stringPrep(constraint);
   6748                    // #endregion 
   6749 
   6750                    // #region Find out a major URI part to compare with
   6751                    var ns = name_prepared.split("/");
   6752                    var cs = constraint_prepared.split("/");
   6753 
   6754                    if(cs.length > 1) // Malformed constraint
   6755                        return false;
   6756 
   6757                    if(ns.length > 1) // Full URI string
   6758                    {
   6759                        for(var i = 0; i < ns.length; i++)
   6760                        {
   6761                            if((ns[i].length > 0) && (ns[i].charAt(ns[i].length - 1) !== ':'))
   6762                            {
   6763                                var ns_port = ns[i].split(":");
   6764                                name_prepared = ns_port[0];
   6765                                break;
   6766                            }
   6767                        }
   6768                    }
   6769                    // #endregion 
   6770 
   6771                    var result = compare_dNSName(name_prepared, constraint_prepared);
   6772 
   6773                    if(result)
   6774                    {
   6775                        // #region Make a "splitted" versions of "constraint" and "name" 
   6776                        var name_splitted = name_prepared.split(".");
   6777                        var constraint_splitted = constraint_prepared.split(".");
   6778                        // #endregion 
   6779 
   6780                        if(constraint_splitted[0].length === 0)
   6781                            return true;
   6782 
   6783                        return name_splitted.length === constraint_splitted.length;
   6784                    }
   6785                    else
   6786                        return false;
   6787 
   6788                    return false;
   6789                }
   6790 
   6791                function compare_iPAddress(name, constraint)
   6792                {
   6793                    /// <summary>Compare two iPAddress values</summary>
   6794                    /// <param name="name" type="in_window.org.pkijs.asn1.OCTETSTRING">iPAddress from name</param>
   6795                    /// <param name="constraint" type="in_window.org.pkijs.asn1.OCTETSTRING">Constraint for iPAddress from name</param>
   6796                    /// <returns type="Boolean">Boolean result - valid or invalid the "name" against the "constraint"</returns>
   6797 
   6798                    // #region Common variables 
   6799                    var name_view = new Uint8Array(name.value_block.value_hex);
   6800                    var constraint_view = new Uint8Array(constraint.value_block.value_hex);
   6801                    // #endregion 
   6802 
   6803                    // #region Work with IPv4 addresses 
   6804                    if((name_view.length === 4) && (constraint_view.length === 8))
   6805                    {
   6806                        for(var i = 0; i < 4; i++)
   6807                        {
   6808                            if((name_view[i] ^ constraint_view[i]) & constraint_view[i + 4])
   6809                                return false;
   6810                        }
   6811 
   6812                        return true;
   6813                    }
   6814                    // #endregion 
   6815 
   6816                    // #region Work with IPv6 addresses 
   6817                    if((name_view.length === 16) && (constraint_view.length === 32))
   6818                    {
   6819                        for(var i = 0; i < 16; i++)
   6820                        {
   6821                            if((name_view[i] ^ constraint_view[i]) & constraint_view[i + 16])
   6822                                return false;
   6823                        }
   6824 
   6825                        return true;
   6826                    }
   6827                    // #endregion 
   6828 
   6829                    return false;
   6830                }
   6831 
   6832                function compare_directoryName(name, constraint)
   6833                {
   6834                    /// <summary>Compare two directoryName values</summary>
   6835                    /// <param name="name" type="in_window.org.pkijs.simpl.RDN">directoryName from name</param>
   6836                    /// <param name="constraint" type="in_window.org.pkijs.simpl.RDN">Constraint for directoryName from name</param>
   6837                    /// <param name="any" type="Boolean">Boolean flag - should be comparision interrupted after first match or we need to match all "constraints" parts</param>
   6838                    /// <returns type="Boolean">Boolean result - valid or invalid the "name" against the "constraint"</returns>
   6839 
   6840                    // #region Initial check 
   6841                    if((name.types_and_values.length === 0) || (constraint.types_and_values.length === 0))
   6842                        return true;
   6843 
   6844                    if(name.types_and_values.length < constraint.types_and_values.length)
   6845                        return false;
   6846                    // #endregion 
   6847 
   6848                    // #region Initial variables 
   6849                    var result = true;
   6850                    var name_start = 0;
   6851                    // #endregion 
   6852 
   6853                    for(var i = 0; i < constraint.types_and_values.length; i++)
   6854                    {
   6855                        var local_result = false;
   6856 
   6857                        for(var j = name_start; j < name.types_and_values.length; j++)
   6858                        {
   6859                            local_result = name.types_and_values[j].isEqual(constraint.types_and_values[i]);
   6860 
   6861                            if(name.types_and_values[j].type === constraint.types_and_values[i].type)
   6862                                result = result && local_result;
   6863 
   6864                            if(local_result === true)
   6865                            {
   6866                                if((name_start === 0) || (name_start === j))
   6867                                {
   6868                                    name_start = j + 1;
   6869                                    break;
   6870                                }
   6871                                else // Structure of "name" must be the same with "constraint"
   6872                                    return false;
   6873                            }
   6874                        }
   6875 
   6876                        if(local_result === false)
   6877                            return false;
   6878                    }
   6879 
   6880                    return (name_start === 0) ? false : result;
   6881                }
   6882                // #endregion 
   6883 
   6884                // #region Check a result from "policy checking" part  
   6885                if(policy_result.result === false)
   6886                    return policy_result;
   6887                // #endregion 
   6888 
   6889                // #region Check all certificates, excluding "trust anchor" 
   6890                path_depth = 1;
   6891 
   6892                for(var i = (_this.certs.length - 2) ; i >= 0 ; i--, path_depth++)
   6893                {
   6894                    // #region Support variables 
   6895                    var subject_alt_names = new Array();
   6896 
   6897                    var cert_permitted_subtrees = new Array();
   6898                    var cert_excluded_subtrees = new Array();
   6899                    // #endregion 
   6900 
   6901                    if("extensions" in _this.certs[i])
   6902                    {
   6903                        for(var j = 0; j < _this.certs[i].extensions.length; j++)
   6904                        {
   6905                            // #region NameConstraints 
   6906                            if(_this.certs[i].extensions[j].extnID === "2.5.29.30")
   6907                            {
   6908                                if("permittedSubtrees" in _this.certs[i].extensions[j].parsedValue)
   6909                                    cert_permitted_subtrees = cert_permitted_subtrees.concat(_this.certs[i].extensions[j].parsedValue.permittedSubtrees);
   6910 
   6911                                if("excludedSubtrees" in _this.certs[i].extensions[j].parsedValue)
   6912                                    cert_excluded_subtrees = cert_excluded_subtrees.concat(_this.certs[i].extensions[j].parsedValue.excludedSubtrees);
   6913                            }
   6914                            // #endregion   
   6915 
   6916                            // #region SubjectAltName 
   6917                            if(_this.certs[i].extensions[j].extnID === "2.5.29.17")
   6918                                subject_alt_names = subject_alt_names.concat(_this.certs[i].extensions[j].parsedValue.altNames);
   6919                            // #endregion 
   6920                        }
   6921                    }
   6922 
   6923                    // #region Checking for "required name forms" 
   6924                    var form_found = (required_name_forms.length <= 0);
   6925 
   6926                    for(var j = 0; j < required_name_forms.length; j++)
   6927                    {
   6928                        switch(required_name_forms[j].base.NameType)
   6929                        {
   6930                            case 4: // directoryName
   6931                                {
   6932                                    if(required_name_forms[j].base.Name.types_and_values.length !== _this.certs[i].subject.types_and_values.length)
   6933                                        continue;
   6934 
   6935                                    form_found = true;
   6936 
   6937                                    for(var k = 0; k < _this.certs[i].subject.types_and_values.length; k++)
   6938                                    {
   6939                                        if(_this.certs[i].subject.types_and_values[k].type !== required_name_forms[j].base.Name.types_and_values[k].type)
   6940                                        {
   6941                                            form_found = false;
   6942                                            break;
   6943                                        }
   6944                                    }
   6945 
   6946                                    if(form_found === true)
   6947                                        break;
   6948                                }
   6949                                break;
   6950                            default: // ??? Probably here we should reject the certificate ???
   6951                        }
   6952                    }
   6953 
   6954                    if(form_found === false)
   6955                    {
   6956                        policy_result.result = false;
   6957                        policy_result.result_code = 21;
   6958                        policy_result.result_message = "No neccessary name form found";
   6959 
   6960                        return new Promise(function(resolve, reject)
   6961                        {
   6962                            reject(policy_result);
   6963                        });
   6964                    }
   6965                    // #endregion 
   6966 
   6967                    // #region Checking for "permited sub-trees" 
   6968                    // #region Make groups for all types of constraints 
   6969                    var constr_groups = new Array(); // Array of array for groupped constraints
   6970                    constr_groups[0] = new Array(); // rfc822Name
   6971                    constr_groups[1] = new Array(); // dNSName
   6972                    constr_groups[2] = new Array(); // directoryName
   6973                    constr_groups[3] = new Array(); // uniformResourceIdentifier
   6974                    constr_groups[4] = new Array(); // iPAddress
   6975 
   6976                    for(var j = 0; j < permitted_subtrees.length; j++)
   6977                    {
   6978                        switch(permitted_subtrees[j].base.NameType)
   6979                        {
   6980                            // #region rfc822Name 
   6981                            case 1:
   6982                                constr_groups[0].push(permitted_subtrees[j]);
   6983                                break;
   6984                                // #endregion 
   6985                                // #region dNSName 
   6986                            case 2:
   6987                                constr_groups[1].push(permitted_subtrees[j]);
   6988                                break;
   6989                                // #endregion 
   6990                                // #region directoryName 
   6991                            case 4:
   6992                                constr_groups[2].push(permitted_subtrees[j]);
   6993                                break;
   6994                                // #endregion 
   6995                                // #region uniformResourceIdentifier 
   6996                            case 6:
   6997                                constr_groups[3].push(permitted_subtrees[j]);
   6998                                break;
   6999                                // #endregion 
   7000                                // #region iPAddress 
   7001                            case 7:
   7002                                constr_groups[4].push(permitted_subtrees[j]);
   7003                                break;
   7004                                // #endregion 
   7005                                // #region default 
   7006 
   7007                            default:
   7008                            // #endregion
   7009                        }
   7010                    }
   7011                    // #endregion   
   7012 
   7013                    // #region Check name constraints groupped by type, one-by-one 
   7014                    for(var p = 0; p < 5; p++)
   7015                    {
   7016                        var group_permitted = false;
   7017                        var valueExists = false;
   7018                        var group = constr_groups[p];
   7019 
   7020                        for(var j = 0; j < group.length; j++)
   7021                        {
   7022                            switch(p)
   7023                            {
   7024                                // #region rfc822Name 
   7025                                case 0:
   7026                                    if(subject_alt_names.length > 0)
   7027                                    {
   7028                                        for(var k = 0; k < subject_alt_names.length; k++)
   7029                                        {
   7030                                            if(subject_alt_names[k].NameType === 1) // rfc822Name
   7031                                            {
   7032                                                valueExists = true;
   7033                                                group_permitted = group_permitted || compare_rfc822Name(subject_alt_names[k].Name, group[j].base.Name);
   7034                                            }
   7035                                        }
   7036                                    }
   7037                                    else // Try to find out "emailAddress" inside "subject"
   7038                                    {
   7039                                        for(var k = 0; k < _this.certs[i].subject.types_and_values.length; k++)
   7040                                        {
   7041                                            if((_this.certs[i].subject.types_and_values[k].type === "1.2.840.113549.1.9.1") ||    // PKCS#9 e-mail address
   7042                                               (_this.certs[i].subject.types_and_values[k].type === "0.9.2342.19200300.100.1.3")) // RFC1274 "rfc822Mailbox" e-mail address
   7043                                            {
   7044                                                valueExists = true;
   7045                                                group_permitted = group_permitted || compare_rfc822Name(_this.certs[i].subject.types_and_values[k].value.value_block.value, group[j].base.Name);
   7046                                            }
   7047                                        }
   7048                                    }
   7049                                    break;
   7050                                    // #endregion 
   7051                                    // #region dNSName 
   7052                                case 1:
   7053                                    if(subject_alt_names.length > 0)
   7054                                    {
   7055                                        for(var k = 0; k < subject_alt_names.length; k++)
   7056                                        {
   7057                                            if(subject_alt_names[k].NameType === 2) // dNSName
   7058                                            {
   7059                                                valueExists = true;
   7060                                                group_permitted = group_permitted || compare_dNSName(subject_alt_names[k].Name, group[j].base.Name);
   7061                                            }
   7062                                        }
   7063                                    }
   7064                                    break;
   7065                                    // #endregion 
   7066                                    // #region directoryName 
   7067                                case 2:
   7068                                    valueExists = true;
   7069                                    group_permitted = compare_directoryName(_this.certs[i].subject, group[j].base.Name);
   7070                                    break;
   7071                                    // #endregion 
   7072                                    // #region uniformResourceIdentifier 
   7073                                case 3:
   7074                                    if(subject_alt_names.length > 0)
   7075                                    {
   7076                                        for(var k = 0; k < subject_alt_names.length; k++)
   7077                                        {
   7078                                            if(subject_alt_names[k].NameType === 6) // uniformResourceIdentifier
   7079                                            {
   7080                                                valueExists = true;
   7081                                                group_permitted = group_permitted || compare_uniformResourceIdentifier(subject_alt_names[k].Name, group[j].base.Name);
   7082                                            }
   7083                                        }
   7084                                    }
   7085                                    break;
   7086                                    // #endregion 
   7087                                    // #region iPAddress 
   7088                                case 4:
   7089                                    if(subject_alt_names.length > 0)
   7090                                    {
   7091                                        for(var k = 0; k < subject_alt_names.length; k++)
   7092                                        {
   7093                                            if(subject_alt_names[k].NameType === 7) // iPAddress
   7094                                            {
   7095                                                valueExists = true;
   7096                                                group_permitted = group_permitted || compare_iPAddress(subject_alt_names[k].Name, group[j].base.Name);
   7097                                            }
   7098                                        }
   7099                                    }
   7100                                    break;
   7101                                    // #endregion 
   7102                                    // #region default 
   7103 
   7104                                default:
   7105                                // #endregion
   7106                            }
   7107 
   7108                            if(group_permitted)
   7109                                break;
   7110                        }
   7111 
   7112                        if((group_permitted === false) && (group.length > 0) && valueExists)
   7113                        {
   7114                            policy_result.result = false;
   7115                            policy_result.result_code = 41;
   7116                            policy_result.result_message = "Failed to meet \"permitted sub-trees\" name constraint";
   7117 
   7118                            return new Promise(function(resolve, reject)
   7119                            {
   7120                                reject(policy_result);
   7121                            });
   7122                        }
   7123                    }
   7124                    // #endregion 
   7125                    // #endregion 
   7126 
   7127                    // #region Checking for "excluded sub-trees" 
   7128                    var excluded = false;
   7129 
   7130                    for(var j = 0; j < excluded_subtrees.length; j++)
   7131                    {
   7132                        switch(excluded_subtrees[j].base.NameType)
   7133                        {
   7134                            // #region rfc822Name 
   7135                            case 1:
   7136                                if(subject_alt_names.length >= 0)
   7137                                {
   7138                                    for(var k = 0; k < subject_alt_names.length; k++)
   7139                                    {
   7140                                        if(subject_alt_names[k].NameType === 1) // rfc822Name
   7141                                            excluded = excluded || compare_rfc822Name(subject_alt_names[k].Name, excluded_subtrees[j].base.Name);
   7142                                    }
   7143                                }
   7144                                else // Try to find out "emailAddress" inside "subject"
   7145                                {
   7146                                    for(var k = 0; k < _this.subject.types_and_values.length; k++)
   7147                                    {
   7148                                        if((_this.subject.types_and_values[k].type === "1.2.840.113549.1.9.1") ||    // PKCS#9 e-mail address
   7149                                           (_this.subject.types_and_values[k].type === "0.9.2342.19200300.100.1.3")) // RFC1274 "rfc822Mailbox" e-mail address
   7150                                        {
   7151                                            excluded = excluded || compare_rfc822Name(_this.subject.types_and_values[k].value.value_block.value, excluded_subtrees[j].base.Name);
   7152                                        }
   7153                                    }
   7154                                }
   7155                                break;
   7156                                // #endregion 
   7157                                // #region dNSName 
   7158                            case 2:
   7159                                if(subject_alt_names.length > 0)
   7160                                {
   7161                                    for(var k = 0; k < subject_alt_names.length; k++)
   7162                                    {
   7163                                        if(subject_alt_names[k].NameType === 2) // dNSName
   7164                                            excluded = excluded || compare_dNSName(subject_alt_names[k].Name, excluded_subtrees[j].base.Name);
   7165                                    }
   7166                                }
   7167                                break;
   7168                                // #endregion 
   7169                                // #region directoryName 
   7170                            case 4:
   7171                                excluded = excluded || compare_directoryName(_this.certs[i].subject, excluded_subtrees[j].base.Name);
   7172                                break;
   7173                                // #endregion 
   7174                                // #region uniformResourceIdentifier 
   7175                            case 6:
   7176                                if(subject_alt_names.length > 0)
   7177                                {
   7178                                    for(var k = 0; k < subject_alt_names.length; k++)
   7179                                    {
   7180                                        if(subject_alt_names[k].NameType === 6) // uniformResourceIdentifier
   7181                                            excluded = excluded || compare_uniformResourceIdentifier(subject_alt_names[k].Name, excluded_subtrees[j].base.Name);
   7182                                    }
   7183                                }
   7184                                break;
   7185                                // #endregion 
   7186                                // #region iPAddress 
   7187                            case 7:
   7188                                if(subject_alt_names.length > 0)
   7189                                {
   7190                                    for(var k = 0; k < subject_alt_names.length; k++)
   7191                                    {
   7192                                        if(subject_alt_names[k].NameType === 7) // iPAddress
   7193                                            excluded = excluded || compare_iPAddress(subject_alt_names[k].Name, excluded_subtrees[j].base.Name);
   7194                                    }
   7195                                }
   7196                                break;
   7197                                // #endregion 
   7198                                // #region default 
   7199 
   7200                            default: // No action, but probably here we need to create a warning for "malformed constraint"
   7201                            // #endregion
   7202                        }
   7203 
   7204                        if(excluded)
   7205                            break;
   7206                    }
   7207 
   7208                    if(excluded === true)
   7209                    {
   7210                        policy_result.result = false;
   7211                        policy_result.result_code = 42;
   7212                        policy_result.result_message = "Failed to meet \"excluded sub-trees\" name constraint";
   7213 
   7214                        return new Promise(function(resolve, reject)
   7215                        {
   7216                            reject(policy_result);
   7217                        });
   7218                    }
   7219                    // #endregion 
   7220 
   7221                    // #region Append "cert_..._subtrees" to "..._subtrees" 
   7222                    permitted_subtrees = permitted_subtrees.concat(cert_permitted_subtrees);
   7223                    excluded_subtrees = excluded_subtrees.concat(cert_excluded_subtrees);
   7224                    // #endregion   
   7225                }
   7226                // #endregion 
   7227 
   7228                return policy_result;
   7229            }
   7230            );
   7231        // #endregion   
   7232 
   7233        return sequence;
   7234    };
   7235    //**************************************************************************************
   7236    // #endregion 
   7237    //**************************************************************************************
   7238 }
   7239 )(typeof exports !== "undefined" ? exports : window);