fork-openpgpjs/doc/openpgp.packet.signature.js.html
2013-04-12 15:11:34 +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#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 Fri Apr 12 2013 14:20:33 GMT+0200 (CEST)
</footer>
<script> prettyPrint(); </script>
</body>
</html>