/* * Copyright (c) 2014, GMO GlobalSign * Copyright (c) 2015, Peculiar Ventures * All rights reserved. * * Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. *
*/
( function(in_window)
{ //************************************************************************************** // #region Declaration of global variables //************************************************************************************** // #region "org" namespace if(typeof in_window.org === "undefined")
in_window.org = {}; else
{ if(typeof in_window.org !== "object") thrownew Error("Name org already exists and it's not an object");
} // #endregion
// #region "org.pkijs" namespace if(typeof in_window.org.pkijs === "undefined")
in_window.org.pkijs = {}; else
{ if(typeof in_window.org.pkijs !== "object") thrownew Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
} // #endregion
// #region "org.pkijs.asn1" namespace if(typeof in_window.org.pkijs.asn1 === "undefined")
in_window.org.pkijs.asn1 = {}; else
{ if(typeof in_window.org.pkijs.asn1 !== "object") thrownew Error("Name org.pkijs.asn1 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.asn1));
} // #endregion
// #region "local" namespace var local = {}; // #endregion //************************************************************************************** // #endregion //************************************************************************************** // #region Aux-functions //************************************************************************************** function util_frombase(input_buffer, input_base)
{ /// <summary>Convert number from 2^base to 2^10</summary> /// <param name="input_buffer" type="Uint8Array">Array of bytes representing the number to convert</param> /// <param name="input_base" type="Number">The base of initial number</param>
var result = 0;
for(var i = (input_buffer.length - 1); i >= 0; i-- )
result += input_buffer[(input_buffer.length - 1) - i] * Math.pow(2, input_base * i);
return result;
} //************************************************************************************** function util_tobase(value, base, reserved)
{ /// <summary>Convert number from 2^10 to 2^base</summary> /// <param name="value" type="Number">The number to convert</param> /// <param name="base" type="Number">The base for 2^base</param> /// <param name="reserved" type="Number">Pre-defined number of bytes in output array (-1 = limited by function itself)</param>
reserved = reserved || (-1);
var result = 0; var biggest = Math.pow(2, base);
for(var i = 1; i < 8; i++)
{ if(value < biggest)
{ var ret_buf;
if( reserved < 0 )
{
ret_buf = new ArrayBuffer(i);
result = i;
} else
{ if(reserved < i) return (new ArrayBuffer(0));
ret_view[ result - j - 1 ] = Math.floor( value / basis );
value -= ( ret_view[ result - j - 1 ] ) * basis;
}
return ret_buf;
}
biggest *= Math.pow(2, base);
}
} //************************************************************************************** function util_encode_tc(value)
{ /// <summary>Encode integer value to "two complement" format</summary> /// <param name="value" type="Number">Value to encode</param>
var mod_value = (value < 0) ? (value * (-1)) : value; var big_int = 128;
for(var i = 1; i < 8; i++)
{ if( mod_value <= big_int )
{ if( value < 0 )
{ var small_int = big_int - mod_value;
var ret_buf = util_tobase( small_int, 8, i ); var ret_view = new Uint8Array(ret_buf);
ret_view[ 0 ] |= 0x80;
return ret_buf;
} else
{ var ret_buf = util_tobase( mod_value, 8, i ); var ret_view = new Uint8Array(ret_buf);
if( ret_view[ 0 ] & 0x80 )
{ var temp_buf = util_copybuf(ret_buf); var temp_view = new Uint8Array(temp_buf);
ret_buf = new ArrayBuffer( ret_buf.byteLength + 1 );
ret_view = new Uint8Array(ret_buf);
for(var k = 0; k < temp_buf.byteLength; k++)
ret_view[k + 1] = temp_view[k];
ret_view[0] = 0x00;
}
return ret_buf;
}
}
big_int *= Math.pow(2, 8);
}
return (new ArrayBuffer(0));
} //************************************************************************************** function util_decode_tc()
{ /// <summary>Decoding of "two complement" values</summary> /// <remarks>The function must be called in scope of instance of "hex_block" class ("value_hex" and "warnings" properties must be present)</remarks>
if(condition_1 || condition_2) this.warnings.push("Needlessly long format");
}
// #region Create big part of the integer var big_int_buffer = new ArrayBuffer(this.value_hex.byteLength); var big_int_view = new Uint8Array(big_int_buffer); for(var i = 0; i < this.value_hex.byteLength; i++)
big_int_view[i] = 0;
big_int_view[0] = (buf[0] & 0x80); // mask only the biggest bit
var big_int = util_frombase(big_int_view, 8); // #endregion
// #region Create small part of the integer var small_int_buffer = new ArrayBuffer(this.value_hex.byteLength); var small_int_view = new Uint8Array(small_int_buffer); for(var j = 0; j < this.value_hex.byteLength; j++)
small_int_view[j] = buf[j];
small_int_view[0] &= 0x7F; // mask biggest bit
var small_int = util_frombase(small_int_view, 8); // #endregion
return (small_int - big_int);
} //************************************************************************************** function util_copybuf(input_buffer)
{ /// <summary>Creating a copy of input ArrayBuffer</summary> /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
if(check_buffer_params(input_buffer, 0, input_buffer.byteLength) === false) return (new ArrayBuffer(0));
var input_view = new Uint8Array(input_buffer);
var ret_buf = new ArrayBuffer(input_buffer.byteLength); var ret_view = new Uint8Array(ret_buf);
for(var i = 0; i < input_buffer.byteLength; i++)
ret_view[i] = input_view[i];
return ret_buf;
} //************************************************************************************** function util_copybuf_offset(input_buffer, input_offset, input_length)
{ /// <summary>Creating a copy of input ArrayBuffer</summary> /// <param name="input_buffer" type="ArrayBuffer">ArrayBuffer for coping</param>
if(check_buffer_params(input_buffer, input_offset, input_length) === false) return (new ArrayBuffer(0));
var input_view = new Uint8Array(input_buffer, input_offset, input_length);
var ret_buf = new ArrayBuffer(input_length); var ret_view = new Uint8Array(ret_buf);
for(var i = 0; i < input_length; i++)
ret_view[i] = input_view[i];
return ret_buf;
} //************************************************************************************** function util_concatbuf(input_buf1, input_buf2)
{ /// <summary>Concatenate two ArrayBuffers</summary> /// <param name="input_buf1" type="ArrayBuffer">First ArrayBuffer (first part of concatenated array)</param> /// <param name="input_buf2" type="ArrayBuffer">Second ArrayBuffer (second part of concatenated array)</param>
var input_view1 = new Uint8Array(input_buf1); var input_view2 = new Uint8Array(input_buf2);
var ret_buf = new ArrayBuffer(input_buf1.byteLength + input_buf2.byteLength); var ret_view = new Uint8Array(ret_buf);
for(var i = 0; i < input_buf1.byteLength; i++)
ret_view[i] = input_view1[i];
var int_buffer = new Uint8Array(input_buffer, input_offset, input_lenght);
for(var i = 0; i < int_buffer.length; i++)
{ var str = int_buffer[i].toString(16).toUpperCase();
result = result + ((str.length === 1) ? " 0" : " ") + str;
}
return result;
} //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of base block class //**************************************************************************************
local.base_block = function()
{ /// <summary>General class of all ASN.1 blocks</summary>
if(arguments[0] instanceof Object)
{ this.block_length = in_window.org.pkijs.getValue(arguments[0], "block_length", 0); this.error = in_window.org.pkijs.getValue(arguments[0], "error", new String()); this.warnings = in_window.org.pkijs.getValue(arguments[0], "warnings", new Array()); if("value_before_decode" in arguments[0]) this.value_before_decode = util_copybuf(arguments[0].value_before_decode); else this.value_before_decode = new ArrayBuffer(0);
} else
{ this.block_length = 0; this.error = new String(); this.warnings = new Array(); /// <field>Copy of the value of incoming ArrayBuffer done before decoding</field> this.value_before_decode = new ArrayBuffer(0);
}
}; //**************************************************************************************
local.base_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"base_block";
}; //**************************************************************************************
local.base_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
return {
block_name: local.base_block.prototype.block_name.call(this),
block_length: this.block_length,
error: this.error,
warnings: this.warnings,
value_before_decode: in_window.org.pkijs.bufferToHexCodes(this.value_before_decode, 0, this.value_before_decode.byteLength)
};
}; //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of hex block class //**************************************************************************************
local.hex_block = function()
{ /// <summary>Descendant of "base_block" with internal ArrayBuffer. Need to have it in case it is not possible to store ASN.1 value in native formats</summary>
local.base_block.call(this, arguments[0]);
if(arguments[0] instanceof Object)
{ this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", false); if("value_hex" in arguments[0]) this.value_hex = util_copybuf(arguments[0].value_hex); else this.value_hex = new ArrayBuffer(0);
} else
{ this.is_hex_only = false; this.value_hex = new ArrayBuffer(0);
}
}; //**************************************************************************************
local.hex_block.prototype = new local.base_block();
local.hex_block.constructor = local.hex_block; //**************************************************************************************
local.hex_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"hex_block";
}; //**************************************************************************************
local.hex_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
// #region Copy input buffer to internal buffer this.value_hex = new ArrayBuffer(input_length); var view = new Uint8Array(this.value_hex);
for(var i = 0; i < int_buffer.length; i++)
view[i] = int_buffer[i]; // #endregion
this.block_length = input_length;
return (input_offset + input_length);
}; //**************************************************************************************
local.hex_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
if(arguments[0] instanceof Object)
{ if("id_block" in arguments[0])
{ // #region Properties from hex_block class this.is_hex_only = in_window.org.pkijs.getValue(arguments[0].id_block, "is_hex_only", false); this.value_hex = in_window.org.pkijs.getValue(arguments[0].id_block, "value_hex", new ArrayBuffer(0)); // #endregion
this.tag_class = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_class", (-1)); this.tag_number = in_window.org.pkijs.getValue(arguments[0].id_block, "tag_number", (-1)); this.is_constructed = in_window.org.pkijs.getValue(arguments[0].id_block, "is_constructed", false);
}
}
}; //**************************************************************************************
local.identification_block.prototype = new local.hex_block();
local.identification_block.constructor = local.identification_block; //**************************************************************************************
local.identification_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"identification_block";
}; //**************************************************************************************
local.identification_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
return ret_buf;
}
}
}; //**************************************************************************************
local.identification_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
if(count >= int_buffer.length)
{ this.error = "End of input reached before message was fully decoded"; return (-1);
}
// #region In case if tag number length is greater than 255 bytes (rare but possible case) if(count == tag_number_buffer_max_length)
{
tag_number_buffer_max_length += 255;
var temp_buffer = new ArrayBuffer(tag_number_buffer_max_length); var temp_buffer_view = new Uint8Array(temp_buffer);
for(var i = 0; i < int_tag_number_buffer.length; i++)
temp_buffer_view[i] = int_tag_number_buffer[i];
this.value_hex = new ArrayBuffer(tag_number_buffer_max_length);
int_tag_number_buffer = new Uint8Array(this.value_hex);
} // #endregion
}
this.block_length = (count + 1);
int_tag_number_buffer[count - 1] = int_buffer[count] & 0x7F; // Write last byte to buffer
// #region Cut buffer var temp_buffer = new ArrayBuffer(count); var temp_buffer_view = new Uint8Array(temp_buffer); for(var i = 0; i < count; i++)
temp_buffer_view[i] = int_tag_number_buffer[i];
this.value_hex = new ArrayBuffer(count);
int_tag_number_buffer = new Uint8Array(this.value_hex);
int_tag_number_buffer.set(temp_buffer_view); // #endregion
// #region Try to convert long tag number to short form if(this.block_length <= 9) this.tag_number = util_frombase(int_tag_number_buffer, 7); else
{ this.is_hex_only = true; this.warnings.push("Tag too long, represented as hex-coded");
} // #endregion
} // #endregion // #endregion
// #region Check if constructed encoding was using for primitive type if(((this.tag_class == 1)) &&
(this.is_constructed))
{ switch(this.tag_number)
{ case 1: // BOOLEAN case 2: // REAL case 5: // NULL case 6: // OBJECT IDENTIFIER case 9: // REAL case 14: // TIME case 23: case 24: case 31: case 32: case 33: case 34: this.error = "Constructed encoding used for primitive type"; return (-1); default:
;
}
} // #endregion
return ( input_offset + this.block_length ); // Return current offset in input buffer
}; //**************************************************************************************
local.identification_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.hex_block.prototype.toJSON.call(this);
if(arguments[0] instanceof Object)
{ if("len_block" in arguments[0])
{ this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0].len_block, "is_indefinite_form", false); this.long_form_used = in_window.org.pkijs.getValue(arguments[0].len_block, "long_form_used", false); this.length = in_window.org.pkijs.getValue(arguments[0].len_block, "length", 0);
}
}
}; //**************************************************************************************
local.length_block.prototype = new local.base_block();
local.length_block.constructor = local.length_block; //**************************************************************************************
local.length_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"length_block";
}; //**************************************************************************************
local.length_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
if(int_buffer[0] == 0xFF)
{ this.error = "Length block 0xFF is reserved by standard"; return (-1);
} // #endregion
// #region Check for length form type this.is_indefinite_form = int_buffer[0] == 0x80; // #endregion
// #region Stop working in case of indefinite length form if(this.is_indefinite_form == true)
{ this.block_length = 1; return (input_offset + this.block_length);
} // #endregion
// #region Check is long form of length encoding using this.long_form_used = !!(int_buffer[0] & 0x80); // #endregion
// #region Stop working in case of short form of length value if(this.long_form_used == false)
{ this.length = (int_buffer[0]); this.block_length = 1; return (input_offset + this.block_length);
} // #endregion
// #region Calculate length value in case of long form var count = int_buffer[0] & 0x7F;
if(count > 8) // Too big length value
{ this.error = "Too big integer"; return (-1);
}
if((count + 1) > int_buffer.length)
{ this.error = "End of input reached before message was fully decoded"; return (-1);
}
var length_buffer_view = new Uint8Array(count);
for(var i = 0; i < count; i++)
length_buffer_view[i] = int_buffer[i + 1];
if(length_buffer_view[count - 1] == 0x00) this.warnings.push("Needlessly long encoded length");
if(this.long_form_used && (this.length <= 127)) this.warnings.push("Unneccesary usage of long length form");
this.block_length = count + 1; // #endregion
return (input_offset + this.block_length); // Return current offset in input buffer
}; //**************************************************************************************
local.length_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
if(this.is_indefinite_form)
{ var ret_buf = new ArrayBuffer(1);
if(size_only === false)
{ var ret_view = new Uint8Array(ret_buf);
ret_view[0] = 0x80;
}
return ret_buf;
}
if(this.long_form_used === true)
{ var encoded_buf = util_tobase(this.length, 8);
if(encoded_buf.byteLength > 127)
{ this.error = "Too big length"; return (new ArrayBuffer(0));
}
var ret_buf = new ArrayBuffer(encoded_buf.byteLength + 1);
if(size_only === true) return ret_buf;
var encoded_view = new Uint8Array(encoded_buf); var ret_view = new Uint8Array(ret_buf);
ret_view[0] = encoded_buf.byteLength | 0x80;
for(var i = 0; i < encoded_buf.byteLength; i++)
ret_view[i + 1] = encoded_view[i];
return ret_buf;
} else
{ var ret_buf = new ArrayBuffer(1);
if(size_only === false)
{ var ret_view = new Uint8Array(ret_buf);
ret_view[0] = this.length;
}
return ret_buf;
}
return (new ArrayBuffer(0));
}; //**************************************************************************************
local.length_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.base_block.prototype.toJSON.call(this);
return _object;
}; //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of value block class //**************************************************************************************
local.value_block = function()
{ /// <summary>Generic class of ASN.1 "value block"</summary>
local.base_block.call(this, arguments[0]);
}; //**************************************************************************************
local.value_block.prototype = new local.base_block();
local.value_block.constructor = local.value_block; //**************************************************************************************
local.value_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"value_block";
}; //**************************************************************************************
local.value_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.base_block.prototype.toJSON.call(this);
if("primitive_schema" in arguments[0]) this.primitive_schema = arguments[0].primitive_schema;
}
this.id_block = new local.identification_block(arguments[0]); this.len_block = new local.length_block(arguments[0]); this.value_block = new local.value_block(arguments[0]);
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_block.prototype = new local.base_block();
in_window.org.pkijs.asn1.ASN1_block.constructor = in_window.org.pkijs.asn1.ASN1_block; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"ASN1_block";
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
return result_offset;
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
if("name" in this)
_object.name = this.name; if("optional" in this)
_object.optional = this.optional; if("primitive_schema" in this)
_object.primitive_schema = this.primitive_schema.toJSON();
return _object;
}; //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of basic block for all PRIMITIVE types //**************************************************************************************
local.ASN1_PRIMITIVE_value_block = function()
{ /// <summary>Base class of ASN.1 value block for primitive values (non-constructive encoding)</summary>
local.value_block.call(this, arguments[0]);
if(arguments[0] instanceof Object)
{ // #region Variables from "hex_block" class if("value_hex" in arguments[0]) this.value_hex = util_copybuf(arguments[0].value_hex); else this.value_hex = new ArrayBuffer(0);
this.is_hex_only = in_window.org.pkijs.getValue(arguments[0], "is_hex_only", true); // #endregion
} else
{ // #region Variables from "hex_block" class this.value_hex = new ArrayBuffer(0); this.is_hex_only = true; // #endregion
}
}; //**************************************************************************************
local.ASN1_PRIMITIVE_value_block.prototype = new local.value_block();
local.ASN1_PRIMITIVE_value_block.constructor = local.ASN1_PRIMITIVE_value_block; //**************************************************************************************
local.ASN1_PRIMITIVE_value_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
// #region Copy input buffer into internal buffer this.value_hex = new ArrayBuffer(int_buffer.length); var value_hex_view = new Uint8Array(this.value_hex);
for(var i = 0; i < int_buffer.length; i++)
value_hex_view[i] = int_buffer[i]; // #endregion
this.block_length = input_length;
return (input_offset + input_length);
}; //**************************************************************************************
local.ASN1_PRIMITIVE_value_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
return util_copybuf(this.value_hex);
}; //**************************************************************************************
local.ASN1_PRIMITIVE_value_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"ASN1_PRIMITIVE_value_block";
}; //**************************************************************************************
local.ASN1_PRIMITIVE_value_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.value_block.prototype.toJSON.call(this);
this.id_block.is_constructed = false; this.value_block = new local.ASN1_PRIMITIVE_value_block(arguments[0]);
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype = new in_window.org.pkijs.asn1.ASN1_block();
in_window.org.pkijs.asn1.ASN1_PRIMITIVE.constructor = in_window.org.pkijs.asn1.ASN1_PRIMITIVE; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"PRIMITIVE";
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_PRIMITIVE.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
return _object;
}; //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of basic block for all CONSTRUCTED types //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block = function()
{ /// <summary>Base class of ASN.1 value block for constructive values (constructive encoding)</summary>
local.value_block.call(this, arguments[0]);
if(arguments[0] instanceof Object)
{ this.value = in_window.org.pkijs.getValue(arguments[0], "value", new Array()); this.is_indefinite_form = in_window.org.pkijs.getValue(arguments[0], "is_indefinite_form", false);
} else
{ this.value = new Array(); this.is_indefinite_form = false;
}
}; //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block.prototype = new local.value_block();
local.ASN1_CONSTRUCTED_value_block.constructor = local.ASN1_CONSTRUCTED_value_block; //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
// #region Store initial offset and length var initial_offset = input_offset; var initial_length = input_length; // #endregion
return current_offset;
}; //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
for(var i = 0; i < this.value.length; i++)
{ var value_buf = this.value[i].toBER(size_only);
ret_buf = util_concatbuf(ret_buf, value_buf);
}
return ret_buf;
}; //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"ASN1_CONSTRUCTED_value_block";
}; //**************************************************************************************
local.ASN1_CONSTRUCTED_value_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.value_block.prototype.toJSON.call(this);
_object.block_name = local.ASN1_CONSTRUCTED_value_block.prototype.block_name.call(this);
_object.is_indefinite_form = this.is_indefinite_form;
_object.value = new Array(); for(var i = 0; i < this.value.length; i++)
_object.value.push(this.value[i].toJSON());
return _object;
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_CONSTRUCTED = function()
{ /// <summary>Base class of ASN.1 block for constructive values (constructive encoding)</summary>
this.id_block.is_constructed = true; this.value_block = new local.ASN1_CONSTRUCTED_value_block(arguments[0]);
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype = new in_window.org.pkijs.asn1.ASN1_block();
in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.constructor = in_window.org.pkijs.asn1.ASN1_CONSTRUCTED; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"CONSTRUCTED";
}; //**************************************************************************************
in_window.org.pkijs.asn1.ASN1_CONSTRUCTED.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
return _object;
}; //************************************************************************************** // #endregion //************************************************************************************** // #region Declaration of ASN.1 EOC type class //**************************************************************************************
local.EOC_value_block = function()
{
local.value_block.call(this, arguments[0]);
}; //**************************************************************************************
local.EOC_value_block.prototype = new local.value_block();
local.EOC_value_block.constructor = local.EOC_value_block; //**************************************************************************************
local.EOC_value_block.prototype.fromBER = function(input_buffer, input_offset, input_length)
{ /// <summary>Base function for converting block from BER encoded array of bytes</summary> /// <param name="input_buffer" type="ArrayBuffer">ASN.1 BER encoded array</param> /// <param name="input_offset" type="Number">Offset in ASN.1 BER encoded array where decoding should be started</param> /// <param name="input_length" type="Number">Maximum length of array of bytes which can be using in this function</param>
// #region There is no "value block" for EOC type and we need to return the same offset return input_offset; // #endregion
}; //**************************************************************************************
local.EOC_value_block.prototype.toBER = function(size_only)
{ /// <summary>Encoding of current ASN.1 block into ASN.1 encoded array (BER rules)</summary> /// <param name="size_only" type="Boolean">Flag that we need only a size of encoding, not a real array of bytes</param>
return (new ArrayBuffer(0));
}; //**************************************************************************************
local.EOC_value_block.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"EOC_value_block";
}; //**************************************************************************************
local.EOC_value_block.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = local.value_block.prototype.toJSON.call(this);
this.id_block.tag_class = 1; // UNIVERSAL this.id_block.tag_number = 0; // EOC
}; //**************************************************************************************
in_window.org.pkijs.asn1.EOC.prototype = new in_window.org.pkijs.asn1.ASN1_block();
in_window.org.pkijs.asn1.EOC.constructor = local.EOC_value_block; //**************************************************************************************
in_window.org.pkijs.asn1.EOC.prototype.block_name = function()
{ /// <summary>Aux function, need to get a block name. Need to have it here for inhiritence</summary>
return"END_OF_CONTENT";
}; //**************************************************************************************
in_window.org.pkijs.asn1.EOC.prototype.toJSON = function()
{ /// <summary>Convertion for the block to JSON object</summary>
var _object = in_window.org.pkijs.asn1.ASN1_block.prototype.toJSON.call(this);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.