fork-openpgpjs/doc/openpgp.packet.js.html
Michal Kolodziej 23295342fc Added utf8 awareness to the literal and userid packet classes. Made s2k
work correctly with utf8 strings. Fixeda visibility issue with the
testing suite and added relevant unit tests.
2013-04-16 10:47:17 +02:00

457 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: packet/openpgp.packet.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: packet/openpgp.packet.js</h1>
<section>
<article>
<pre class="prettyprint source"><code>// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @class
* @classdesc Parent openpgp packet class. Operations focus on determining
* packet types and packet header.
*/
function _openpgp_packet() {
/**
* Encodes a given integer of length to the openpgp length specifier to a
* string
*
* @param {Integer} length The length to encode
* @return {String} String with openpgp length representation
*/
function encode_length(length) {
result = "";
if (length &lt; 192) {
result += String.fromCharCode(length);
} else if (length > 191 && length &lt; 8384) {
/*
* let a = (total data packet length) - 192 let bc = two octet
* representation of a let d = b + 192
*/
result += String.fromCharCode(((length - 192) >> 8) + 192);
result += String.fromCharCode((length - 192) & 0xFF);
} else {
result += String.fromCharCode(255);
result += String.fromCharCode((length >> 24) & 0xFF);
result += String.fromCharCode((length >> 16) & 0xFF);
result += String.fromCharCode((length >> 8) & 0xFF);
result += String.fromCharCode(length & 0xFF);
}
return result;
}
this.encode_length = encode_length;
/**
* Writes a packet header version 4 with the given tag_type and length to a
* string
*
* @param {Integer} tag_type Tag type
* @param {Integer} length Length of the payload
* @return {String} String of the header
*/
function write_packet_header(tag_type, length) {
/* we're only generating v4 packet headers here */
var result = "";
result += String.fromCharCode(0xC0 | tag_type);
result += encode_length(length);
return result;
}
/**
* Writes a packet header Version 3 with the given tag_type and length to a
* string
*
* @param {Integer} tag_type Tag type
* @param {Integer} length Length of the payload
* @return {String} String of the header
*/
function write_old_packet_header(tag_type, length) {
var result = "";
if (length &lt; 256) {
result += String.fromCharCode(0x80 | (tag_type &lt;&lt; 2));
result += String.fromCharCode(length);
} else if (length &lt; 65536) {
result += String.fromCharCode(0x80 | (tag_type &lt;&lt; 2) | 1);
result += String.fromCharCode(length >> 8);
result += String.fromCharCode(length & 0xFF);
} else {
result += String.fromCharCode(0x80 | (tag_type &lt;&lt; 2) | 2);
result += String.fromCharCode((length >> 24) & 0xFF);
result += String.fromCharCode((length >> 16) & 0xFF);
result += String.fromCharCode((length >> 8) & 0xFF);
result += String.fromCharCode(length & 0xFF);
}
return result;
}
this.write_old_packet_header = write_old_packet_header;
this.write_packet_header = write_packet_header;
/**
* Generic static Packet Parser function
*
* @param {String} input Input stream as string
* @param {integer} position Position to start parsing
* @param {integer} len Length of the input from position on
* @return {Object} Returns a parsed openpgp_packet
*/
function read_packet(input, position, len) {
// some sanity checks
if (input == null || input.length &lt;= position
|| input.substring(position).length &lt; 2
|| (input[position].charCodeAt() & 0x80) == 0) {
util
.print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format.");
return null;
}
var mypos = position;
var tag = -1;
var format = -1;
format = 0; // 0 = old format; 1 = new format
if ((input[mypos].charCodeAt() & 0x40) != 0) {
format = 1;
}
var packet_length_type;
if (format) {
// new format header
tag = input[mypos].charCodeAt() & 0x3F; // bit 5-0
} else {
// old format header
tag = (input[mypos].charCodeAt() & 0x3F) >> 2; // bit 5-2
packet_length_type = input[mypos].charCodeAt() & 0x03; // bit 1-0
}
// header octet parsing done
mypos++;
// parsed length from length field
var bodydata = null;
// used for partial body lengths
var real_packet_length = -1;
if (!format) {
// 4.2.1. Old Format Packet Lengths
switch (packet_length_type) {
case 0: // The packet has a one-octet length. The header is 2 octets
// long.
packet_length = input[mypos++].charCodeAt();
break;
case 1: // The packet has a two-octet length. The header is 3 octets
// long.
packet_length = (input[mypos++].charCodeAt() &lt;&lt; 8)
| input[mypos++].charCodeAt();
break;
case 2: // The packet has a four-octet length. The header is 5
// octets long.
packet_length = (input[mypos++].charCodeAt() &lt;&lt; 24)
| (input[mypos++].charCodeAt() &lt;&lt; 16)
| (input[mypos++].charCodeAt() &lt;&lt; 8)
| input[mypos++].charCodeAt();
break;
default:
// 3 - The packet is of indeterminate length. The header is 1
// octet long, and the implementation must determine how long
// the packet is. If the packet is in a file, this means that
// the packet extends until the end of the file. In general,
// an implementation SHOULD NOT use indeterminate-length
// packets except where the end of the data will be clear
// from the context, and even then it is better to use a
// definite length, or a new format header. The new format
// headers described below have a mechanism for precisely
// encoding data of indeterminate length.
packet_length = len;
break;
}
} else // 4.2.2. New Format Packet Lengths
{
// 4.2.2.1. One-Octet Lengths
if (input[mypos].charCodeAt() &lt; 192) {
packet_length = input[mypos++].charCodeAt();
util.print_debug("1 byte length:" + packet_length);
// 4.2.2.2. Two-Octet Lengths
} else if (input[mypos].charCodeAt() >= 192
&& input[mypos].charCodeAt() &lt; 224) {
packet_length = ((input[mypos++].charCodeAt() - 192) &lt;&lt; 8)
+ (input[mypos++].charCodeAt()) + 192;
util.print_debug("2 byte length:" + packet_length);
// 4.2.2.4. Partial Body Lengths
} else if (input[mypos].charCodeAt() > 223
&& input[mypos].charCodeAt() &lt; 255) {
packet_length = 1 &lt;&lt; (input[mypos++].charCodeAt() & 0x1F);
util.print_debug("4 byte length:" + packet_length);
// EEEK, we're reading the full data here...
var mypos2 = mypos + packet_length;
bodydata = input.substring(mypos, mypos + packet_length);
while (true) {
if (input[mypos2].charCodeAt() &lt; 192) {
var tmplen = input[mypos2++].charCodeAt();
packet_length += tmplen;
bodydata += input.substring(mypos2, mypos2 + tmplen);
mypos2 += tmplen;
break;
} else if (input[mypos2].charCodeAt() >= 192
&& input[mypos2].charCodeAt() &lt; 224) {
var tmplen = ((input[mypos2++].charCodeAt() - 192) &lt;&lt; 8)
+ (input[mypos2++].charCodeAt()) + 192;
packet_length += tmplen;
bodydata += input.substring(mypos2, mypos2 + tmplen);
mypos2 += tmplen;
break;
} else if (input[mypos2].charCodeAt() > 223
&& input[mypos2].charCodeAt() &lt; 255) {
var tmplen = 1 &lt;&lt; (input[mypos2++].charCodeAt() & 0x1F);
packet_length += tmplen;
bodydata += input.substring(mypos2, mypos2 + tmplen);
mypos2 += tmplen;
} else {
mypos2++;
var tmplen = (input[mypos2++].charCodeAt() &lt;&lt; 24)
| (input[mypos2++].charCodeAt() &lt;&lt; 16)
| (input[mypos2++].charCodeAt() &lt;&lt; 8)
| input[mypos2++].charCodeAt();
bodydata += input.substring(mypos2, mypos2 + tmplen);
packet_length += tmplen;
mypos2 += tmplen;
break;
}
}
real_packet_length = mypos2;
// 4.2.2.3. Five-Octet Lengths
} else {
mypos++;
packet_length = (input[mypos++].charCodeAt() &lt;&lt; 24)
| (input[mypos++].charCodeAt() &lt;&lt; 16)
| (input[mypos++].charCodeAt() &lt;&lt; 8)
| input[mypos++].charCodeAt();
}
}
// if there was'nt a partial body length: use the specified
// packet_length
if (real_packet_length == -1) {
real_packet_length = packet_length;
}
if (bodydata == null) {
bodydata = input.substring(mypos, mypos + real_packet_length);
}
// alert('tag type: '+this.tag+' length: '+packet_length);
var version = 1; // (old format; 2= new format)
// if (input[mypos++].charCodeAt() > 15)
// version = 2;
switch (tag) {
case 0: // Reserved - a packet tag MUST NOT have this value
break;
case 1: // Public-Key Encrypted Session Key Packet
var result = new openpgp_packet_encryptedsessionkey();
if (result.read_pub_key_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 2: // Signature Packet
var result = new openpgp_packet_signature();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 3: // Symmetric-Key Encrypted Session Key Packet
var result = new openpgp_packet_encryptedsessionkey();
if (result.read_symmetric_key_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 4: // One-Pass Signature Packet
var result = new openpgp_packet_onepasssignature();
if (result.read_packet(bodydata, 0, packet_length)) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 5: // Secret-Key Packet
var result = new openpgp_packet_keymaterial();
result.header = input.substring(position, mypos);
if (result.read_tag5(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 6: // Public-Key Packet
var result = new openpgp_packet_keymaterial();
result.header = input.substring(position, mypos);
if (result.read_tag6(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 7: // Secret-Subkey Packet
var result = new openpgp_packet_keymaterial();
if (result.read_tag7(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 8: // Compressed Data Packet
var result = new openpgp_packet_compressed();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 9: // Symmetrically Encrypted Data Packet
var result = new openpgp_packet_encrypteddata();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 10: // Marker Packet = PGP (0x50, 0x47, 0x50)
var result = new openpgp_packet_marker();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 11: // Literal Data Packet
var result = new openpgp_packet_literaldata();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.header = input.substring(position, mypos);
result.packetLength = real_packet_length;
return result;
}
break;
case 12: // Trust Packet
// TODO: to be implemented
break;
case 13: // User ID Packet
var result = new openpgp_packet_userid();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 14: // Public-Subkey Packet
var result = new openpgp_packet_keymaterial();
result.header = input.substring(position, mypos);
if (result.read_tag14(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 17: // User Attribute Packet
var result = new openpgp_packet_userattribute();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 18: // Sym. Encrypted and Integrity Protected Data Packet
var result = new openpgp_packet_encryptedintegrityprotecteddata();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
case 19: // Modification Detection Code Packet
var result = new openpgp_packet_modificationdetectioncode();
if (result.read_packet(bodydata, 0, packet_length) != null) {
result.headerLength = mypos - position;
result.packetLength = real_packet_length;
return result;
}
break;
default:
util.print_error("openpgp.packet.js\n"
+ "[ERROR] openpgp_packet: failed to parse packet @:"
+ mypos + "\nchar:'"
+ util.hexstrdump(input.substring(mypos)) + "'\ninput:"
+ util.hexstrdump(input));
return null;
break;
}
}
this.read_packet = read_packet;
}
var openpgp_packet = new _openpgp_packet();
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="_openpgp_packet.html">_openpgp_packet</a></li><li><a href="JXG.Util.html">Util</a></li><li><a href="openpgp.html">openpgp</a></li><li><a href="openpgp_config.html">openpgp_config</a></li><li><a href="openpgp_keyring.html">openpgp_keyring</a></li><li><a href="openpgp_msg_message.html">openpgp_msg_message</a></li><li><a href="openpgp_msg_privatekey.html">openpgp_msg_privatekey</a></li><li><a href="openpgp_msg_publickey.html">openpgp_msg_publickey</a></li><li><a href="openpgp_packet_compressed.html">openpgp_packet_compressed</a></li><li><a href="openpgp_packet_encrypteddata.html">openpgp_packet_encrypteddata</a></li><li><a href="openpgp_packet_encryptedintegrityprotecteddata.html">openpgp_packet_encryptedintegrityprotecteddata</a></li><li><a href="openpgp_packet_encryptedsessionkey.html">openpgp_packet_encryptedsessionkey</a></li><li><a href="openpgp_packet_keymaterial.html">openpgp_packet_keymaterial</a></li><li><a href="openpgp_packet_literaldata.html">openpgp_packet_literaldata</a></li><li><a href="openpgp_packet_marker.html">openpgp_packet_marker</a></li><li><a href="openpgp_packet_modificationdetectioncode.html">openpgp_packet_modificationdetectioncode</a></li><li><a href="openpgp_packet_onepasssignature.html">openpgp_packet_onepasssignature</a></li><li><a href="openpgp_packet_signature.html">openpgp_packet_signature</a></li><li><a href="openpgp_packet_userattribute.html">openpgp_packet_userattribute</a></li><li><a href="openpgp_packet_userid.html">openpgp_packet_userid</a></li><li><a href="openpgp_type_keyid.html">openpgp_type_keyid</a></li><li><a href="openpgp_type_mpi.html">openpgp_type_mpi</a></li><li><a href="openpgp_type_s2k.html">openpgp_type_s2k</a></li></ul><h3>Global</h3><ul><li><a href="global.html#bin2str">bin2str</a></li><li><a href="global.html#calc_checksum">calc_checksum</a></li><li><a href="global.html#crc_table">crc_table</a></li><li><a href="global.html#decode_utf8">decode_utf8</a></li><li><a href="global.html#encode_utf8">encode_utf8</a></li><li><a href="global.html#get_hashAlgorithmString">get_hashAlgorithmString</a></li><li><a href="global.html#getCheckSum">getCheckSum</a></li><li><a href="global.html#getPGPMessageType">getPGPMessageType</a></li><li><a href="global.html#hash_headers">hash_headers</a></li><li><a href="global.html#hex2bin">hex2bin</a></li><li><a href="global.html#hexidump">hexidump</a></li><li><a href="global.html#hexstrdump">hexstrdump</a></li><li><a href="global.html#MD5">MD5</a></li><li><a href="global.html#openpgp_cfb_decrypt">openpgp_cfb_decrypt</a></li><li><a href="global.html#openpgp_cfb_encrypt">openpgp_cfb_encrypt</a></li><li><a href="global.html#openpgp_cfb_mdc">openpgp_cfb_mdc</a></li><li><a href="global.html#openpgp_crypto_asymetricDecrypt">openpgp_crypto_asymetricDecrypt</a></li><li><a href="global.html#openpgp_crypto_asymetricEncrypt">openpgp_crypto_asymetricEncrypt</a></li><li><a href="global.html#openpgp_crypto_generateKeyPair">openpgp_crypto_generateKeyPair</a></li><li><a href="global.html#openpgp_crypto_generateSessionKey">openpgp_crypto_generateSessionKey</a></li><li><a href="global.html#openpgp_crypto_getHashByteLength">openpgp_crypto_getHashByteLength</a></li><li><a href="global.html#openpgp_crypto_getPrefixRandom">openpgp_crypto_getPrefixRandom</a></li><li><a href="global.html#openpgp_crypto_getPseudoRandom">openpgp_crypto_getPseudoRandom</a></li><li><a href="global.html#openpgp_crypto_getRandomBigInteger">openpgp_crypto_getRandomBigInteger</a></li><li><a href="global.html#openpgp_crypto_getRandomBytes">openpgp_crypto_getRandomBytes</a></li><li><a href="global.html#openpgp_crypto_getSecureRandom">openpgp_crypto_getSecureRandom</a></li><li><a href="global.html#openpgp_crypto_hashData">openpgp_crypto_hashData</a></li><li><a href="global.html#openpgp_crypto_MDCSystemBytes">openpgp_crypto_MDCSystemBytes</a></li><li><a href="global.html#openpgp_crypto_signData">openpgp_crypto_signData</a></li><li><a href="global.html#openpgp_crypto_symmetricDecrypt">openpgp_crypto_symmetricDecrypt</a></li><li><a href="global.html#openpgp_crypto_symmetricEncrypt">openpgp_crypto_symmetricEncrypt</a></li><li><a href="global.html#openpgp_crypto_verifySignature">openpgp_crypto_verifySignature</a></li><li><a href="global.html#openpgp_encoding_armor">openpgp_encoding_armor</a></li><li><a href="global.html#openpgp_encoding_armor_addheader">openpgp_encoding_armor_addheader</a></li><li><a href="global.html#openpgp_encoding_base64_decode">openpgp_encoding_base64_decode</a></li><li><a href="global.html#openpgp_encoding_base64_encode">openpgp_encoding_base64_encode</a></li><li><a href="global.html#openpgp_encoding_deArmor">openpgp_encoding_deArmor</a></li><li><a href="global.html#openpgp_encoding_eme_pkcs1_decode">openpgp_encoding_eme_pkcs1_decode</a></li><li><a href="global.html#openpgp_encoding_eme_pkcs1_encode">openpgp_encoding_eme_pkcs1_encode</a></li><li><a href="global.html#openpgp_encoding_emsa_pkcs1_decode">openpgp_encoding_emsa_pkcs1_decode</a></li><li><a href="global.html#openpgp_encoding_emsa_pkcs1_encode">openpgp_encoding_emsa_pkcs1_encode</a></li><li><a href="global.html#openpgp_encoding_html_encode">openpgp_encoding_html_encode</a></li><li><a href="global.html#print_debug">print_debug</a></li><li><a href="global.html#print_debug_hexstr_dump">print_debug_hexstr_dump</a></li><li><a href="global.html#print_error">print_error</a></li><li><a href="global.html#print_info">print_info</a></li><li><a href="global.html#shiftRight">shiftRight</a></li><li><a href="global.html#str2bin">str2bin</a></li><li><a href="global.html#str2Uint8Array">str2Uint8Array</a></li><li><a href="global.html#Uint8Array2str">Uint8Array2str</a></li><li><a href="global.html#util">util</a></li><li><a href="global.html#verifyCheckSum">verifyCheckSum</a></li></ul>
</nav>
<br clear="both">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.0-dev</a> on Tue Apr 16 2013 10:42:39 GMT+0200 (CEST)
</footer>
<script> prettyPrint(); </script>
</body>
</html>