fork-openpgpjs/doc/openpgp.packet.userid.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

414 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: packet/openpgp.packet.userid.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.userid.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 Implementation of the User ID Packet (Tag 13)
* A User ID packet consists of UTF-8 text that is intended to represent
* the name and email address of the key holder. By convention, it
* includes an RFC 2822 [RFC2822] mail name-addr, but there are no
* restrictions on its content. The packet length in the header
* specifies the length of the User ID.
*/
function openpgp_packet_userid() {
this.text = ''
this.tagType = 13;
this.certificationSignatures = new Array();
this.certificationRevocationSignatures = new Array();
this.revocationSignatures = new Array();
this.parentNode = null;
/**
* Set the packet text field to a native javascript string
* Conversion to a proper utf8 encoding takes place when the
* packet is written.
* @param {String} str Any native javascript string
*/
this.set_text = function(str) {
this.text = str;
}
/**
* Set the packet text to value represented by the provided string
* of bytes.
* @param {String} bytes A string of bytes
*/
this.set_text_bytes = function(bytes) {
this.text = util.decode_utf8(bytes);
}
/**
* Get the byte sequence representing the text of this packet.
* @returns {String} A sequence of bytes
*/
this.get_text_bytes = function() {
return util.encode_utf8(this.text);
}
/**
* Parsing function for a user id packet (tag 13).
* @param {String} input payload of a tag 13 packet
* @param {Integer} position position to start reading from the input string
* @param {Integer} len length of the packet or the remaining length of input at position
* @return {openpgp_packet_encrypteddata} object representation
*/
this.read_packet = function(input, position, len) {
this.packetLength = len;
var bytes = '';
for ( var i = 0; i &lt; len; i++) {
bytes += input[position + i];
}
this.set_text_bytes(bytes);
return this;
}
/**
* Creates a string representation of the user id packet
* @param {String} user_id the user id as string ("John Doe &lt;john.doe@mail.us")
* @return {String} string representation
*/
this.write_packet = function(user_id) {
this.set_text(user_id);
var bytes = this.get_text_bytes();
var result = openpgp_packet.write_packet_header(13, bytes.length);
result += bytes;
return result;
}
/**
* Continue parsing packets belonging to the userid packet such as signatures
* @param {Object} parent_node the parent object
* @param {String} input input string to read the packet(s) from
* @param {Integer} position start position for the parser
* @param {Integer} len length of the packet(s) or remaining length of input
* @return {Integer} length of nodes read
*/
this.read_nodes = function(parent_node, input, position, len) {
if (parent_node.tagType == 6) { // public key
this.parentNode = parent_node;
var pos = position;
var l = len;
while (input.length != pos) {
var result = openpgp_packet.read_packet(input, pos, l - (pos - position));
if (result == null) {
util.print_error('[user_id] parsing ends here @:' + pos + " l:" + l);
break;
} else {
pos += result.packetLength + result.headerLength;
l = input.length - pos;
switch (result.tagType) {
case 2: // Signature Packet
if (result.signatureType > 15
&& result.signatureType &lt; 20) { // certification
// //
// signature
this.certificationSignatures[this.certificationSignatures.length] = result;
break;
} else if (result.signatureType == 48) {// certification revocation signature
this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result;
break;
} else if (result.signatureType == 24) { // omg. standalone signature
this.certificationSignatures[this.certificationSignatures.length] = result;
break;
} else {
util.print_debug("unknown sig t: "+result.signatureType+"@"+(pos - (result.packetLength + result.headerLength)));
}
default:
this.data = input;
this.position = position - parent_node.packetLength;
this.len = pos - position -(result.headerLength + result.packetLength);
return this.len;
}
}
}
this.data = input;
this.position = position - parent_node.packetLength;
this.len = pos - position -(result.headerLength + result.packetLength);
return this.len;
} else if (parent_node.tagType == 5) { // secret Key
this.parentNode = parent_node;
var exit = false;
var pos = position;
while (input.length != pos) {
var result = openpgp_packet.read_packet(input, pos, l - (pos - position));
if (result == null) {
util.print_error('parsing ends here @:' + pos + " l:" + l);
break;
} else {
pos += result.packetLength + result.headerLength;
l = input.length - pos;
switch (result.tagType) {
case 2: // Signature Packet certification signature
if (result.signatureType > 15
&& result.signatureType &lt; 20)
this.certificationSignatures[this.certificationSignatures.length] = result;
// certification revocation signature
else if (result.signatureType == 48)
this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result;
default:
this.data = input;
this.position = position - parent_node.packetLength;
this.len = pos - position -(result.headerLength + result.packetLength);
return this.len;
}
}
}
} else {
util.print_error("unknown parent node for a userId packet "+parent_node.tagType);
}
}
/**
* generates debug output (pretty print)
* @return {String} String which gives some information about the user id packet
*/
this.toString = function() {
var result = ' 5.11. User ID Packet (Tag 13)\n' + ' text ('
+ this.text.length + '): "' + this.text.replace("&lt;", "&lt;")
+ '"\n';
result +="certification signatures:\n";
for (var i = 0; i &lt; this.certificationSignatures.length; i++) {
result += " "+this.certificationSignatures[i].toString();
}
result +="certification revocation signatures:\n";
for (var i = 0; i &lt; this.certificationRevocationSignatures.length; i++) {
result += " "+this.certificationRevocationSignatures[i].toString();
}
return result;
}
/**
* lookup function to find certification revocation signatures
* @param {String} keyId string containing the key id of the issuer of this signature
* @return a CertificationRevocationSignature if found; otherwise null
*/
this.hasCertificationRevocationSignature = function(keyId) {
for (var i = 0; i &lt; this.certificationRevocationSignatures.length; i++) {
if ((this.certificationRevocationSignatures[i].version == 3 &&
this.certificationRevocationSignatures[i].keyId == keyId) ||
(this.certificationRevocationSignatures[i].version == 4 &&
this.certificationRevocationSignatures[i].issuerKeyId == keyId))
return this.certificationRevocationSignatures[i];
}
return null;
}
/**
* Verifies all certification signatures. This method does not consider possible revocation signatures.
* @param {Object} publicKeyPacket the top level key material
* @return {Integer[]} An array of integers corresponding to the array of certification signatures. The meaning of each integer is the following:
* 0 = bad signature
* 1 = signature expired
* 2 = issuer key not available
* 3 = revoked
* 4 = signature valid
* 5 = signature by key owner expired
* 6 = signature by key owner revoked
*/
this.verifyCertificationSignatures = function(publicKeyPacket) {
var bytes = this.get_text_bytes();
result = new Array();
for (var i = 0 ; i &lt; this.certificationSignatures.length; i++) {
// A certification signature (type 0x10 through 0x13) hashes the User
// ID being bound to the key into the hash context after the above
// data. A V3 certification hashes the contents of the User ID or
// attribute packet packet, without any header. A V4 certification
// hashes the constant 0xB4 for User ID certifications or the constant
// 0xD1 for User Attribute certifications, followed by a four-octet
// number giving the length of the User ID or User Attribute data, and
// then the User ID or User Attribute data.
if (this.certificationSignatures[i].version == 4) {
if (this.certificationSignatures[i].signatureExpirationTime != null &&
this.certificationSignatures[i].signatureExpirationTime != null &&
this.certificationSignatures[i].signatureExpirationTime != 0 &&
!this.certificationSignatures[i].signatureNeverExpires &&
new Date(this.certificationSignatures[i].creationTime.getTime() +(this.certificationSignatures[i].signatureExpirationTime*1000)) &lt; new Date()) {
if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId())
result[i] = 5;
else
result[i] = 1;
continue;
}
if (this.certificationSignatures[i].issuerKeyId == null) {
result[i] = 0;
continue;
}
var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].issuerKeyId);
if (issuerPublicKey == null || issuerPublicKey.length == 0) {
result[i] = 2;
continue;
}
// TODO: try to verify all returned issuer public keys (key ids are not unique!)
var issuerPublicKey = issuerPublicKey[0];
var signingKey = issuerPublicKey.obj.getSigningKey();
if (signingKey == null) {
result[i] = 0;
continue;
}
var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].issuerKeyId);
if (revocation != null && revocation.creationTime >
this.certificationSignatures[i].creationTime) {
var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+
publicKeyPacket.data+String.fromCharCode(0xB4)+
String.fromCharCode((bytes.length >> 24) & 0xFF)+
String.fromCharCode((bytes.length >> 16) & 0xFF)+
String.fromCharCode((bytes.length >> 8) & 0xFF)+
String.fromCharCode((bytes.length) & 0xFF)+
bytes;
if (revocation.verify(signaturedata, signingKey)) {
if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId())
result[i] = 6;
else
result[i] = 3;
continue;
}
}
var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+
publicKeyPacket.data+String.fromCharCode(0xB4)+
String.fromCharCode((bytes.length >> 24) & 0xFF)+
String.fromCharCode((bytes.length >> 16) & 0xFF)+
String.fromCharCode((bytes.length >> 8) & 0xFF)+
String.fromCharCode((bytes.length) & 0xFF)+
bytes;
if (this.certificationSignatures[i].verify(signaturedata, signingKey)) {
result[i] = 4;
} else
result[i] = 0;
} else if (this.certificationSignatures[i].version == 3) {
if (this.certificationSignatures[i].keyId == null) {
result[i] = 0;
continue;
}
var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].keyId);
if (issuerPublicKey == null || issuerPublicKey.length == 0) {
result[i] = 2;
continue;
}
issuerPublicKey = issuerPublicKey[0];
var signingKey = publicKey.obj.getSigningKey();
if (signingKey == null) {
result[i] = 0;
continue;
}
var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].keyId);
if (revocation != null && revocation.creationTime >
this.certificationSignatures[i].creationTime) {
var signaturedata = String.fromCharCode(0x99)+ this.publicKeyPacket.header.substring(1)+
this.publicKeyPacket.data+bytes;
if (revocation.verify(signaturedata, signingKey)) {
if (revocation.keyId == publicKeyPacket.getKeyId())
result[i] = 6;
else
result[i] = 3;
continue;
}
}
var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+
publicKeyPacket.data + bytes;
if (this.certificationSignatures[i].verify(signaturedata, signingKey)) {
result[i] = 4;
} else
result[i] = 0;
} else {
result[i] = 0;
}
}
return result;
}
/**
* verifies the signatures of the user id
* @return 0 if the userid is valid; 1 = userid expired; 2 = userid revoked
*/
this.verify = function(publicKeyPacket) {
var result = this.verifyCertificationSignatures(publicKeyPacket);
if (result.indexOf(6) != -1)
return 2;
if (result.indexOf(5) != -1)
return 1;
return 0;
}
// TODO: implementation missing
this.addCertification = function(publicKeyPacket, privateKeyPacket) {
}
// TODO: implementation missing
this.revokeCertification = function(publicKeyPacket, privateKeyPacket) {
}
}
</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:40 GMT+0200 (CEST)
</footer>
<script> prettyPrint(); </script>
</body>
</html>