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

779 lines
38 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: packet/openpgp.packet.signature.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.signature.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 Signature Packet (Tag 2)
*
* RFC4480 5.2:
* A Signature packet describes a binding between some public key and
* some data. The most common signatures are a signature of a file or a
* block of text, and a signature that is a certification of a User ID.
*/
function openpgp_packet_signature() {
this.tagType = 2;
this.signatureType = null;
this.creationTime = null;
this.keyId = null;
this.signatureData = null;
this.signatureExpirationTime = null;
this.signatureNeverExpires = null;
this.signedHashValue = null;
this.MPIs = null;
this.publicKeyAlgorithm = null;
this.hashAlgorithm = null;
this.exportable = null;
this.trustLevel = null;
this.trustAmount = null;
this.regular_expression = null;
this.revocable = null;
this.keyExpirationTime = null;
this.keyNeverExpires = null;
this.preferredSymmetricAlgorithms = null;
this.revocationKeyClass = null;
this.revocationKeyAlgorithm = null;
this.revocationKeyFingerprint = null;
this.issuerKeyId = null;
this.notationFlags = null;
this.notationName = null;
this.notationValue = null;
this.preferredHashAlgorithms = null;
this.preferredCompressionAlgorithms = null;
this.keyServerPreferences = null;
this.preferredKeyServer = null;
this.isPrimaryUserID = null;
this.policyURI = null;
this.keyFlags = null;
this.signersUserId = null;
this.reasonForRevocationFlag = null;
this.reasonForRevocationString = null;
this.signatureTargetPublicKeyAlgorithm = null;
this.signatureTargetHashAlgorithm = null;
this.signatureTargetHash = null;
this.embeddedSignature = null;
this.verified = false;
/**
* parsing function for a signature packet (tag 2).
* @param {String} input payload of a tag 2 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
*/
function read_packet(input, position, len) {
this.data = input.substring (position, position+len);
if (len &lt; 0) {
util.print_debug("openpgp.packet.signature.js\n"+"openpgp_packet_signature read_packet length &lt; 0 @:"+position);
return null;
}
var mypos = position;
this.packetLength = len;
// alert('starting parsing signature: '+position+' '+this.packetLength);
this.version = input[mypos++].charCodeAt();
// switch on version (3 and 4)
switch (this.version) {
case 3:
// One-octet length of following hashed material. MUST be 5.
if (input[mypos++].charCodeAt() != 5)
util.print_debug("openpgp.packet.signature.js\n"+'invalid One-octet length of following hashed material. MUST be 5. @:'+(mypos-1));
var sigpos = mypos;
// One-octet signature type.
this.signatureType = input[mypos++].charCodeAt();
// Four-octet creation time.
this.creationTime = new Date(((input[mypos++].charCodeAt()) &lt;&lt; 24 |
(input[mypos++].charCodeAt() &lt;&lt; 16) | (input[mypos++].charCodeAt() &lt;&lt; 8) |
input[mypos++].charCodeAt())* 1000);
// storing data appended to data which gets verified
this.signatureData = input.substring(position, mypos);
// Eight-octet Key ID of signer.
this.keyId = input.substring(mypos, mypos +8);
mypos += 8;
// One-octet public-key algorithm.
this.publicKeyAlgorithm = input[mypos++].charCodeAt();
// One-octet hash algorithm.
this.hashAlgorithm = input[mypos++].charCodeAt();
// Two-octet field holding left 16 bits of signed hash value.
this.signedHashValue = (input[mypos++].charCodeAt() &lt;&lt; 8) | input[mypos++].charCodeAt();
var mpicount = 0;
// Algorithm-Specific Fields for RSA signatures:
// - multiprecision integer (MPI) of RSA signature value m**d mod n.
if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm &lt; 4)
mpicount = 1;
// Algorithm-Specific Fields for DSA signatures:
// - MPI of DSA value r.
// - MPI of DSA value s.
else if (this.publicKeyAlgorithm == 17)
mpicount = 2;
this.MPIs = new Array();
for (var i = 0; i &lt; mpicount; i++) {
this.MPIs[i] = new openpgp_type_mpi();
if (this.MPIs[i].read(input, mypos, (mypos-position)) != null &&
!this.packetLength &lt; (mypos-position)) {
mypos += this.MPIs[i].packetLength;
} else {
util.print_error('signature contains invalid MPI @:'+mypos);
}
}
break;
case 4:
this.signatureType = input[mypos++].charCodeAt();
this.publicKeyAlgorithm = input[mypos++].charCodeAt();
this.hashAlgorithm = input[mypos++].charCodeAt();
// Two-octet scalar octet count for following hashed subpacket
// data.
var hashed_subpacket_count = (input[mypos++].charCodeAt() &lt;&lt; 8) + input[mypos++].charCodeAt();
// Hashed subpacket data set (zero or more subpackets)
var subpacket_length = 0;
while (hashed_subpacket_count != subpacket_length) {
if (hashed_subpacket_count &lt; subpacket_length) {
util.print_debug("openpgp.packet.signature.js\n"+"hashed missed something: "+mypos+" c:"+hashed_subpacket_count+" l:"+subpacket_length);
}
subpacket_length += this._raw_read_signature_sub_packet(input,
mypos + subpacket_length, hashed_subpacket_count
- subpacket_length);
}
mypos += hashed_subpacket_count;
this.signatureData = input.substring(position, mypos);
// alert("signatureData: "+util.hexstrdump(this.signatureData));
// Two-octet scalar octet count for the following unhashed subpacket
var subpacket_count = (input[mypos++].charCodeAt() &lt;&lt; 8) + input[mypos++].charCodeAt();
// Unhashed subpacket data set (zero or more subpackets).
subpacket_length = 0;
while (subpacket_count != subpacket_length) {
if (subpacket_count &lt; subpacket_length) {
util.print_debug("openpgp.packet.signature.js\n"+"missed something: "+subpacket_length+" c:"+subpacket_count+" "+" l:"+subpacket_length);
}
subpacket_length += this._raw_read_signature_sub_packet(input,
mypos + subpacket_length, subpacket_count
- subpacket_length);
}
mypos += subpacket_count;
// Two-octet field holding the left 16 bits of the signed hash
// value.
this.signedHashValue = (input[mypos++].charCodeAt() &lt;&lt; 8) | input[mypos++].charCodeAt();
// One or more multiprecision integers comprising the signature.
// This portion is algorithm specific, as described above.
var mpicount = 0;
if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm &lt; 4)
mpicount = 1;
else if (this.publicKeyAlgorithm == 17)
mpicount = 2;
this.MPIs = new Array();
for (var i = 0; i &lt; mpicount; i++) {
this.MPIs[i] = new openpgp_type_mpi();
if (this.MPIs[i].read(input, mypos, (mypos-position)) != null &&
!this.packetLength &lt; (mypos-position)) {
mypos += this.MPIs[i].packetLength;
} else {
util.print_error('signature contains invalid MPI @:'+mypos);
}
}
break;
default:
util.print_error("openpgp.packet.signature.js\n"+'unknown signature packet version'+this.version);
break;
}
// util.print_message("openpgp.packet.signature.js\n"+"end signature: l: "+this.packetLength+"m: "+mypos+" m-p: "+(mypos-position));
return this;
}
/**
* creates a string representation of a message signature packet (tag 2).
* This can be only used on text data
* @param {Integer} signature_type should be 1 (one)
* @param {String} data data to be signed
* @param {openpgp_msg_privatekey} privatekey private key used to sign the message. (secMPIs MUST be unlocked)
* @return {String} string representation of a signature packet
*/
function write_message_signature(signature_type, data, privatekey) {
var publickey = privatekey.privateKeyPacket.publicKey;
var hash_algo = privatekey.getPreferredSignatureHashAlgorithm();
var result = String.fromCharCode(4);
result += String.fromCharCode(signature_type);
result += String.fromCharCode(publickey.publicKeyAlgorithm);
result += String.fromCharCode(hash_algo);
var d = Math.round(new Date().getTime() / 1000);
var datesubpacket = write_sub_signature_packet(2,""+
String.fromCharCode((d >> 24) & 0xFF) +
String.fromCharCode((d >> 16) & 0xFF) +
String.fromCharCode((d >> 8) & 0xFF) +
String.fromCharCode(d & 0xFF));
var issuersubpacket = write_sub_signature_packet(16, privatekey.getKeyId());
result += String.fromCharCode(((datesubpacket.length + issuersubpacket.length) >> 8) & 0xFF);
result += String.fromCharCode ((datesubpacket.length + issuersubpacket.length) & 0xFF);
result += datesubpacket;
result += issuersubpacket;
var trailer = '';
trailer += String.fromCharCode(4);
trailer += String.fromCharCode(0xFF);
trailer += String.fromCharCode((result.length) >> 24);
trailer += String.fromCharCode(((result.length) >> 16) & 0xFF);
trailer += String.fromCharCode(((result.length) >> 8) & 0xFF);
trailer += String.fromCharCode((result.length) & 0xFF);
var result2 = String.fromCharCode(0);
result2 += String.fromCharCode(0);
var hash = openpgp_crypto_hashData(hash_algo, data+result+trailer);
util.print_debug("DSA Signature is calculated with:|"+data+result+trailer+"|\n"+util.hexstrdump(data+result+trailer)+"\n hash:"+util.hexstrdump(hash));
result2 += hash.charAt(0);
result2 += hash.charAt(1);
result2 += openpgp_crypto_signData(hash_algo,privatekey.privateKeyPacket.publicKey.publicKeyAlgorithm,
publickey.MPIs,
privatekey.privateKeyPacket.secMPIs,
data+result+trailer);
return {openpgp: (openpgp_packet.write_packet_header(2, (result+result2).length)+result + result2),
hash: util.get_hashAlgorithmString(hash_algo)};
}
/**
* creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1)
* @param {Integer} type subpacket signature type. Signature types as described in RFC4880 Section 5.2.3.2
* @param {String} data data to be included
* @return {String} a string-representation of a sub signature packet (See RFC 4880 5.2.3.1)
*/
function write_sub_signature_packet(type, data) {
var result = "";
result += openpgp_packet.encode_length(data.length+1);
result += String.fromCharCode(type);
result += data;
return result;
}
// V4 signature sub packets
this._raw_read_signature_sub_packet = function(input, position, len) {
if (len &lt; 0)
util.print_debug("openpgp.packet.signature.js\n"+"_raw_read_signature_sub_packet length &lt; 0 @:"+position);
var mypos = position;
var subplen = 0;
// alert('starting signature subpackage read at position:'+position+' length:'+len);
if (input[mypos].charCodeAt() &lt; 192) {
subplen = input[mypos++].charCodeAt();
} else if (input[mypos].charCodeAt() >= 192 && input[mypos].charCodeAt() &lt; 224) {
subplen = ((input[mypos++].charCodeAt() - 192) &lt;&lt; 8) + (input[mypos++].charCodeAt()) + 192;
} else if (input[mypos].charCodeAt() > 223 && input[mypos].charCodeAt() &lt; 255) {
subplen = 1 &lt;&lt; (input[mypos++].charCodeAt() & 0x1F);
} else if (input[mypos].charCodeAt() &lt; 255) {
mypos++;
subplen = (input[mypos++].charCodeAt() &lt;&lt; 24) | (input[mypos++].charCodeAt() &lt;&lt; 16)
| (input[mypos++].charCodeAt() &lt;&lt; 8) | input[mypos++].charCodeAt();
}
var type = input[mypos++].charCodeAt() & 0x7F;
// alert('signature subpacket type '+type+" with length: "+subplen);
// subpacket type
switch (type) {
case 2: // Signature Creation Time
this.creationTime = new Date(((input[mypos++].charCodeAt() &lt;&lt; 24) | (input[mypos++].charCodeAt() &lt;&lt; 16)
| (input[mypos++].charCodeAt() &lt;&lt; 8) | input[mypos++].charCodeAt())*1000);
break;
case 3: // Signature Expiration Time
this.signatureExpirationTime = (input[mypos++].charCodeAt() &lt;&lt; 24)
| (input[mypos++].charCodeAt() &lt;&lt; 16) | (input[mypos++].charCodeAt() &lt;&lt; 8)
| input[mypos++].charCodeAt();
this.signatureNeverExpires = (this.signature_expiration_time == 0);
break;
case 4: // Exportable Certification
this.exportable = input[mypos++].charCodeAt() == 1;
break;
case 5: // Trust Signature
this.trustLevel = input[mypos++].charCodeAt();
this.trustAmount = input[mypos++].charCodeAt();
break;
case 6: // Regular Expression
this.regular_expression = new String();
for (var i = 0; i &lt; subplen - 1; i++)
this.regular_expression += (input[mypos++]);
break;
case 7: // Revocable
this.revocable = input[mypos++].charCodeAt() == 1;
break;
case 9: // Key Expiration Time
this.keyExpirationTime = (input[mypos++].charCodeAt() &lt;&lt; 24)
| (input[mypos++].charCodeAt() &lt;&lt; 16) | (input[mypos++].charCodeAt() &lt;&lt; 8)
| input[mypos++].charCodeAt();
this.keyNeverExpires = (this.keyExpirationTime == 0);
break;
case 11: // Preferred Symmetric Algorithms
this.preferredSymmetricAlgorithms = new Array();
for (var i = 0; i &lt; subplen-1; i++) {
this.preferredSymmetricAlgorithms = input[mypos++].charCodeAt();
}
break;
case 12: // Revocation Key
// (1 octet of class, 1 octet of public-key algorithm ID, 20
// octets of
// fingerprint)
this.revocationKeyClass = input[mypos++].charCodeAt();
this.revocationKeyAlgorithm = input[mypos++].charCodeAt();
this.revocationKeyFingerprint = new Array();
for ( var i = 0; i &lt; 20; i++) {
this.revocationKeyFingerprint = input[mypos++].charCodeAt();
}
break;
case 16: // Issuer
this.issuerKeyId = input.substring(mypos,mypos+8);
mypos += 8;
break;
case 20: // Notation Data
this.notationFlags = (input[mypos++].charCodeAt() &lt;&lt; 24) |
(input[mypos++].charCodeAt() &lt;&lt; 16) |
(input[mypos++].charCodeAt() &lt;&lt; 8) |
(input[mypos++].charCodeAt());
var nameLength = (input[mypos++].charCodeAt() &lt;&lt; 8) | (input[mypos++].charCodeAt());
var valueLength = (input[mypos++].charCodeAt() &lt;&lt; 8) | (input[mypos++].charCodeAt());
this.notationName = "";
for (var i = 0; i &lt; nameLength; i++) {
this.notationName += input[mypos++];
}
this.notationValue = "";
for (var i = 0; i &lt; valueLength; i++) {
this.notationValue += input[mypos++];
}
break;
case 21: // Preferred Hash Algorithms
this.preferredHashAlgorithms = new Array();
for (var i = 0; i &lt; subplen-1; i++) {
this.preferredHashAlgorithms = input[mypos++].charCodeAt();
}
break;
case 22: // Preferred Compression Algorithms
this.preferredCompressionAlgorithms = new Array();
for ( var i = 0; i &lt; subplen-1; i++) {
this.preferredCompressionAlgorithms = input[mypos++].charCodeAt();
}
break;
case 23: // Key Server Preferences
this.keyServerPreferences = new Array();
for ( var i = 0; i &lt; subplen-1; i++) {
this.keyServerPreferences = input[mypos++].charCodeAt();
}
break;
case 24: // Preferred Key Server
this.preferredKeyServer = new String();
for ( var i = 0; i &lt; subplen-1; i++) {
this.preferredKeyServer += input[mypos++];
}
break;
case 25: // Primary User ID
this.isPrimaryUserID = input[mypos++] != 0;
break;
case 26: // Policy URI
this.policyURI = new String();
for ( var i = 0; i &lt; subplen-1; i++) {
this.policyURI += input[mypos++];
}
break;
case 27: // Key Flags
this.keyFlags = new Array();
for ( var i = 0; i &lt; subplen-1; i++) {
this.keyFlags = input[mypos++].charCodeAt();
}
break;
case 28: // Signer's User ID
this.signersUserId = new String();
for ( var i = 0; i &lt; subplen-1; i++) {
this.signersUserId += input[mypos++];
}
break;
case 29: // Reason for Revocation
this.reasonForRevocationFlag = input[mypos++].charCodeAt();
this.reasonForRevocationString = new String();
for ( var i = 0; i &lt; subplen -2; i++) {
this.reasonForRevocationString += input[mypos++];
}
break;
case 30: // Features
// TODO: to be implemented
return subplen+1;
case 31: // Signature Target
// (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash)
this.signatureTargetPublicKeyAlgorithm = input[mypos++].charCodeAt();
this.signatureTargetHashAlgorithm = input[mypos++].charCodeAt();
var signatureTargetHashAlgorithmLength = 0;
switch(this.signatureTargetHashAlgorithm) {
case 1: // - MD5 [HAC] "MD5"
case 2: // - SHA-1 [FIPS180] "SHA1"
signatureTargetHashAlgorithmLength = 20;
break;
case 3: // - RIPE-MD/160 [HAC] "RIPEMD160"
case 8: // - SHA256 [FIPS180] "SHA256"
case 9: // - SHA384 [FIPS180] "SHA384"
case 10: // - SHA512 [FIPS180] "SHA512"
case 11: // - SHA224 [FIPS180] "SHA224"
break;
// 100 to 110 - Private/Experimental algorithm
default:
util.print_error("openpgp.packet.signature.js\n"+"unknown signature target hash algorithm:"+this.signatureTargetHashAlgorithm);
return null;
}
this.signatureTargetHash = new Array();
for (var i = 0; i &lt; signatureTargetHashAlgorithmLength; i++) {
this.signatureTargetHash[i] = input[mypos++];
}
case 32: // Embedded Signature
this.embeddedSignature = new openpgp_packet_signature();
this.embeddedSignature.read_packet(input, mypos, len -(mypos-position));
return ((mypos+ this.embeddedSignature.packetLength) - position);
break;
case 100: // Private or experimental
case 101: // Private or experimental
case 102: // Private or experimental
case 103: // Private or experimental
case 104: // Private or experimental
case 105: // Private or experimental
case 106: // Private or experimental
case 107: // Private or experimental
case 108: // Private or experimental
case 109: // Private or experimental
case 110: // Private or experimental
util.print_error("openpgp.packet.signature.js\n"+'private or experimental signature subpacket type '+type+" @:"+mypos+" subplen:"+subplen+" len:"+len);
return subplen+1;
break;
case 0: // Reserved
case 1: // Reserved
case 8: // Reserved
case 10: // Placeholder for backward compatibility
case 13: // Reserved
case 14: // Reserved
case 15: // Reserved
case 17: // Reserved
case 18: // Reserved
case 19: // Reserved
default:
util.print_error("openpgp.packet.signature.js\n"+'unknown signature subpacket type '+type+" @:"+mypos+" subplen:"+subplen+" len:"+len);
return subplen+1;
break;
}
return mypos -position;
};
/**
* verifys the signature packet. Note: not signature types are implemented
* @param {String} data data which on the signature applies
* @param {openpgp_msg_privatekey} key the public key to verify the signature
* @return {boolean} True if message is verified, else false.
*/
function verify(data, key) {
// calculating the trailer
var trailer = '';
trailer += String.fromCharCode(this.version);
trailer += String.fromCharCode(0xFF);
trailer += String.fromCharCode(this.signatureData.length >> 24);
trailer += String.fromCharCode((this.signatureData.length >> 16) &0xFF);
trailer += String.fromCharCode((this.signatureData.length >> 8) &0xFF);
trailer += String.fromCharCode(this.signatureData.length & 0xFF);
switch(this.signatureType) {
case 0: // 0x00: Signature of a binary document.
if (this.version == 4) {
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.obj.publicKeyPacket.MPIs, data+this.signatureData+trailer);
}
break;
case 1: // 0x01: Signature of a canonical text document.
if (this.version == 4) {
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.obj.publicKeyPacket.MPIs, data+this.signatureData+trailer);
return this.verified;
}
break;
case 2: // 0x02: Standalone signature.
// This signature is a signature of only its own subpacket contents.
// It is calculated identically to a signature over a zero-length
// binary document. Note that it doesn't make sense to have a V3
// standalone signature.
if (this.version == 3) {
this.verified = false;
break;
}
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.obj.publicKeyPacket.MPIs, this.signatureData+trailer);
break;
case 16:
// 0x10: Generic certification of a User ID and Public-Key packet.
// The issuer of this certification does not make any particular
// assertion as to how well the certifier has checked that the owner
// of the key is in fact the person described by the User ID.
case 17:
// 0x11: Persona certification of a User ID and Public-Key packet.
// The issuer of this certification has not done any verification of
// the claim that the owner of this key is the User ID specified.
case 18:
// 0x12: Casual certification of a User ID and Public-Key packet.
// The issuer of this certification has done some casual
// verification of the claim of identity.
case 19:
// 0x13: Positive certification of a User ID and Public-Key packet.
// The issuer of this certification has done substantial
// verification of the claim of identity.
//
// Most OpenPGP implementations make their "key signatures" as 0x10
// certifications. Some implementations can issue 0x11-0x13
// certifications, but few differentiate between the types.
case 48:
// 0x30: Certification revocation signature
// This signature revokes an earlier User ID certification signature
// (signature class 0x10 through 0x13) or direct-key signature
// (0x1F). It should be issued by the same key that issued the
// revoked signature or an authorized revocation key. The signature
// is computed over the same data as the certificate that it
// revokes, and should have a later creation date than that
// certificate.
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.MPIs, data+this.signatureData+trailer);
break;
case 24:
// 0x18: Subkey Binding Signature
// This signature is a statement by the top-level signing key that
// indicates that it owns the subkey. This signature is calculated
// directly on the primary key and subkey, and not on any User ID or
// other packets. A signature that binds a signing subkey MUST have
// an Embedded Signature subpacket in this binding signature that
// contains a 0x19 signature made by the signing subkey on the
// primary key and subkey.
if (this.version == 3) {
this.verified = false;
break;
}
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.MPIs, data+this.signatureData+trailer);
break;
case 25:
// 0x19: Primary Key Binding Signature
// This signature is a statement by a signing subkey, indicating
// that it is owned by the primary key and subkey. This signature
// is calculated the same way as a 0x18 signature: directly on the
// primary key and subkey, and not on any User ID or other packets.
// When a signature is made over a key, the hash data starts with the
// octet 0x99, followed by a two-octet length of the key, and then body
// of the key packet. (Note that this is an old-style packet header for
// a key packet with two-octet length.) A subkey binding signature
// (type 0x18) or primary key binding signature (type 0x19) then hashes
// the subkey using the same format as the main key (also using 0x99 as
// the first octet).
case 31:
// 0x1F: Signature directly on a key
// This signature is calculated directly on a key. It binds the
// information in the Signature subpackets to the key, and is
// appropriate to be used for subpackets that provide information
// about the key, such as the Revocation Key subpacket. It is also
// appropriate for statements that non-self certifiers want to make
// about the key itself, rather than the binding between a key and a
// name.
case 32:
// 0x20: Key revocation signature
// The signature is calculated directly on the key being revoked. A
// revoked key is not to be used. Only revocation signatures by the
// key being revoked, or by an authorized revocation key, should be
// considered valid revocation signatures.
case 40:
// 0x28: Subkey revocation signature
// The signature is calculated directly on the subkey being revoked.
// A revoked subkey is not to be used. Only revocation signatures
// by the top-level signature key that is bound to this subkey, or
// by an authorized revocation key, should be considered valid
// revocation signatures.
this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm,
this.MPIs, key.MPIs, data+this.signatureData+trailer);
break;
// Key revocation signatures (types 0x20 and 0x28)
// hash only the key being revoked.
case 64:
// 0x40: Timestamp signature.
// This signature is only meaningful for the timestamp contained in
// it.
case 80:
// 0x50: Third-Party Confirmation signature.
// This signature is a signature over some other OpenPGP Signature
// packet(s). It is analogous to a notary seal on the signed data.
// A third-party signature SHOULD include Signature Target
// subpacket(s) to give easy identification. Note that we really do
// mean SHOULD. There are plausible uses for this (such as a blind
// party that only sees the signature, not the key or source
// document) that cannot include a target subpacket.
default:
util.print_error("openpgp.packet.signature.js\n"+"signature verification for type"+ this.signatureType+" not implemented");
break;
}
return this.verified;
}
/**
* generates debug output (pretty print)
* @return {String} String which gives some information about the signature packet
*/
function toString () {
if (this.version == 3) {
var result = '5.2. Signature Packet (Tag 2)\n'+
"Packet Length: :"+this.packetLength+'\n'+
"Packet version: :"+this.version+'\n'+
"One-octet signature type :"+this.signatureType+'\n'+
"Four-octet creation time. :"+this.creationTime+'\n'+
"Eight-octet Key ID of signer. :"+util.hexidump(this.keyId)+'\n'+
"One-octet public-key algorithm. :"+this.publicKeyAlgorithm+'\n'+
"One-octet hash algorithm. :"+this.hashAlgorithm+'\n'+
"Two-octet field holding left\n" +
" 16 bits of signed hash value. :"+this.signedHashValue+'\n';
} else {
var result = '5.2. Signature Packet (Tag 2)\n'+
"Packet Length: :"+this.packetLength+'\n'+
"Packet version: :"+this.version+'\n'+
"One-octet signature type :"+this.signatureType+'\n'+
"One-octet public-key algorithm. :"+this.publicKeyAlgorithm+'\n'+
"One-octet hash algorithm. :"+this.hashAlgorithm+'\n'+
"Two-octet field holding left\n" +
" 16 bits of signed hash value. :"+this.signedHashValue+'\n'+
"Signature Creation Time :"+this.creationTime+'\n'+
"Signature Expiration Time :"+this.signatureExpirationTime+'\n'+
"Signature Never Expires :"+this.signatureNeverExpires+'\n'+
"Exportable Certification :"+this.exportable+'\n'+
"Trust Signature level: :"+this.trustLevel+' amount'+this.trustAmount+'\n'+
"Regular Expression :"+this.regular_expression+'\n'+
"Revocable :"+this.revocable+'\n'+
"Key Expiration Time :"+this.keyExpirationTime+" "+this.keyNeverExpires+'\n'+
"Preferred Symmetric Algorithms :"+this.preferredSymmetricAlgorithms+'\n'+
"Revocation Key"+'\n'+
" ( 1 octet of class, :"+this.revocationKeyClass +'\n'+
" 1 octet of public-key ID, :" +this.revocationKeyAlgorithm+'\n'+
" 20 octets of fingerprint) :"+this.revocationKeyFingerprint+'\n'+
"Issuer :"+util.hexstrdump(this.issuerKeyId)+'\n'+
"Preferred Hash Algorithms :"+this.preferredHashAlgorithms+'\n'+
"Preferred Compression Alg. :"+this.preferredCompressionAlgorithms+'\n'+
"Key Server Preferences :"+this.keyServerPreferences+'\n'+
"Preferred Key Server :"+this.preferredKeyServer+'\n'+
"Primary User ID :"+this.isPrimaryUserID+'\n'+
"Policy URI :"+this.policyURI+'\n'+
"Key Flags :"+this.keyFlags+'\n'+
"Signer's User ID :"+this.signersUserId+'\n'+
"Notation :"+this.notationName+" = "+this.notationValue+"\n"+
"Reason for Revocation\n"+
" Flag :"+this.reasonForRevocationFlag+'\n'+
" Reason :"+this.reasonForRevocationString+'\nMPI:\n';
}
for (var i = 0; i &lt; this.MPIs.length; i++) {
result += this.MPIs[i].toString();
}
return result;
}
/**
* gets the issuer key id of this signature
* @return {String} issuer key id as string (8bytes)
*/
function getIssuer() {
if (this.version == 4)
return this.issuerKeyId;
if (this.verions == 4)
return this.keyId;
return null;
}
/**
* Tries to get the corresponding public key out of the public keyring for the issuer created this signature
* @return {Object} {obj: [openpgp_msg_publickey], text: [String]} if found the public key will be returned. null otherwise
*/
function getIssuerKey() {
var result = null;
if (this.version == 4) {
result = openpgp.keyring.getPublicKeysForKeyId(this.issuerKeyId);
} else if (this.version == 3) {
result = openpgp.keyring.getPublicKeysForKeyId(this.keyId);
} else return null;
if (result.length == 0)
return null;
return result[0];
}
this.getIssuerKey = getIssuerKey;
this.getIssuer = getIssuer;
this.write_message_signature = write_message_signature;
this.verify = verify;
this.read_packet = read_packet;
this.toString = toString;
}
</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>