691 lines
26 KiB
HTML
691 lines
26 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>JSDoc: Source: 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/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
|
|
|
|
/**
|
|
* Implementation of the Signature Packet (Tag 2)<br/>
|
|
* <br/>
|
|
* 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.
|
|
* @requires crypto
|
|
* @requires enums
|
|
* @requires packet/packet
|
|
* @requires type/keyid
|
|
* @requires type/mpi
|
|
* @requires util
|
|
* @module packet/signature
|
|
*/
|
|
|
|
var util = require('../util'),
|
|
packet = require('./packet.js'),
|
|
enums = require('../enums.js'),
|
|
crypto = require('../crypto'),
|
|
type_mpi = require('../type/mpi.js'),
|
|
type_keyid = require('../type/keyid.js');
|
|
|
|
/**
|
|
* @constructor
|
|
*/
|
|
module.exports = function signature() {
|
|
|
|
this.version = 4;
|
|
this.signatureType = null;
|
|
this.hashAlgorithm = null;
|
|
this.publicKeyAlgorithm = null;
|
|
|
|
this.signatureData = null;
|
|
this.signedHashValue = null;
|
|
this.mpi = null;
|
|
|
|
this.created = new Date();
|
|
this.signatureExpirationTime = null;
|
|
this.signatureNeverExpires = true;
|
|
this.exportable = null;
|
|
this.trustLevel = null;
|
|
this.trustAmount = null;
|
|
this.regularExpression = null;
|
|
this.revocable = null;
|
|
this.keyExpirationTime = null;
|
|
this.keyNeverExpires = null;
|
|
this.preferredSymmetricAlgorithms = null;
|
|
this.revocationKeyClass = null;
|
|
this.revocationKeyAlgorithm = null;
|
|
this.revocationKeyFingerprint = null;
|
|
this.issuerKeyId = new type_keyid();
|
|
this.notation = 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.features = 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} bytes payload of a tag 2 packet
|
|
* @param {Integer} position position to start reading from the bytes string
|
|
* @param {Integer} len length of the packet or the remaining length of bytes at position
|
|
* @return {module:packet/signature} object representation
|
|
*/
|
|
this.read = function (bytes) {
|
|
var i = 0;
|
|
|
|
this.version = bytes.charCodeAt(i++);
|
|
// switch on version (3 and 4)
|
|
switch (this.version) {
|
|
case 3:
|
|
// One-octet length of following hashed material. MUST be 5.
|
|
if (bytes.charCodeAt(i++) != 5)
|
|
util.print_debug("packet/signature.js\n" +
|
|
'invalid One-octet length of following hashed material.' +
|
|
'MUST be 5. @:' + (i - 1));
|
|
|
|
var sigpos = i;
|
|
// One-octet signature type.
|
|
this.signatureType = bytes.charCodeAt(i++);
|
|
|
|
// Four-octet creation time.
|
|
this.created = util.readDate(bytes.substr(i, 4));
|
|
i += 4;
|
|
|
|
// storing data appended to data which gets verified
|
|
this.signatureData = bytes.substring(sigpos, i);
|
|
|
|
// Eight-octet Key ID of signer.
|
|
this.issuerKeyId.read(bytes.substring(i, i + 8));
|
|
i += 8;
|
|
|
|
// One-octet public-key algorithm.
|
|
this.publicKeyAlgorithm = bytes.charCodeAt(i++);
|
|
|
|
// One-octet hash algorithm.
|
|
this.hashAlgorithm = bytes.charCodeAt(i++);
|
|
break;
|
|
case 4:
|
|
this.signatureType = bytes.charCodeAt(i++);
|
|
this.publicKeyAlgorithm = bytes.charCodeAt(i++);
|
|
this.hashAlgorithm = bytes.charCodeAt(i++);
|
|
|
|
function subpackets(bytes) {
|
|
// Two-octet scalar octet count for following subpacket data.
|
|
var subpacket_length = util.readNumber(
|
|
bytes.substr(0, 2));
|
|
|
|
var i = 2;
|
|
|
|
// subpacket data set (zero or more subpackets)
|
|
var subpacked_read = 0;
|
|
while (i < 2 + subpacket_length) {
|
|
|
|
var len = packet.readSimpleLength(bytes.substr(i));
|
|
i += len.offset;
|
|
|
|
this.read_sub_packet(bytes.substr(i, len.len));
|
|
|
|
i += len.len;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
// hashed subpackets
|
|
i += subpackets.call(this, bytes.substr(i), true);
|
|
|
|
// A V4 signature hashes the packet body
|
|
// starting from its first field, the version number, through the end
|
|
// of the hashed subpacket data. Thus, the fields hashed are the
|
|
// signature version, the signature type, the public-key algorithm, the
|
|
// hash algorithm, the hashed subpacket length, and the hashed
|
|
// subpacket body.
|
|
this.signatureData = bytes.substr(0, i);
|
|
|
|
// unhashed subpackets
|
|
i += subpackets.call(this, bytes.substr(i), false);
|
|
|
|
break;
|
|
default:
|
|
throw new Error('Version ' + version + ' of the signature is unsupported.');
|
|
break;
|
|
}
|
|
|
|
// Two-octet field holding left 16 bits of signed hash value.
|
|
this.signedHashValue = bytes.substr(i, 2);
|
|
i += 2;
|
|
|
|
this.signature = bytes.substr(i);
|
|
};
|
|
|
|
this.write = function () {
|
|
return this.signatureData +
|
|
util.writeNumber(0, 2) + // Number of unsigned subpackets.
|
|
this.signedHashValue +
|
|
this.signature;
|
|
};
|
|
|
|
/**
|
|
* Signs provided data. This needs to be done prior to serialization.
|
|
* @param {module:packet/secret_key} key private key used to sign the message.
|
|
* @param {Object} data Contains packets to be signed.
|
|
*/
|
|
this.sign = function (key, data) {
|
|
var signatureType = enums.write(enums.signature, this.signatureType),
|
|
publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm),
|
|
hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
|
|
|
var result = String.fromCharCode(4);
|
|
result += String.fromCharCode(signatureType);
|
|
result += String.fromCharCode(publicKeyAlgorithm);
|
|
result += String.fromCharCode(hashAlgorithm);
|
|
|
|
this.issuerKeyId = key.getKeyId();
|
|
|
|
// Add hashed subpackets
|
|
result += this.write_all_sub_packets();
|
|
|
|
this.signatureData = result;
|
|
|
|
var trailer = this.calculateTrailer();
|
|
|
|
var toHash = this.toSign(signatureType, data) +
|
|
this.signatureData + trailer;
|
|
|
|
var hash = crypto.hash.digest(hashAlgorithm, toHash);
|
|
|
|
this.signedHashValue = hash.substr(0, 2);
|
|
|
|
this.signature = crypto.signature.sign(hashAlgorithm,
|
|
publicKeyAlgorithm, key.mpi, toHash);
|
|
};
|
|
|
|
/**
|
|
* Creates string of bytes with all subpacket data
|
|
* @return {String} a string-representation of a all subpacket data
|
|
*/
|
|
this.write_all_sub_packets = function () {
|
|
var sub = enums.signatureSubpacket;
|
|
var result = '';
|
|
var bytes = '';
|
|
if (this.created !== null) {
|
|
result += write_sub_packet(sub.signature_creation_time, util.writeDate(this.created));
|
|
}
|
|
if (this.signatureExpirationTime !== null) {
|
|
result += write_sub_packet(sub.signature_expiration_time, util.writeNumber(this.signatureExpirationTime, 4));
|
|
}
|
|
if (this.exportable !== null) {
|
|
result += write_sub_packet(sub.exportable_certification, String.fromCharCode(this.exportable ? 1 : 0));
|
|
}
|
|
if (this.trustLevel !== null) {
|
|
bytes = String.fromCharCode(this.trustLevel) + String.fromCharCode(this.trustAmount);
|
|
result += write_sub_packet(sub.trust_signature, bytes);
|
|
}
|
|
if (this.regularExpression !== null) {
|
|
result += write_sub_packet(sub.regular_expression, this.regularExpression);
|
|
}
|
|
if (this.revocable !== null) {
|
|
result += write_sub_packet(sub.revocable, String.fromCharCode(this.revocable ? 1 : 0));
|
|
}
|
|
if (this.keyExpirationTime !== null) {
|
|
result += write_sub_packet(sub.key_expiration_time, util.writeNumber(this.keyExpirationTime, 4));
|
|
}
|
|
if (this.preferredSymmetricAlgorithms !== null) {
|
|
bytes = util.bin2str(this.preferredSymmetricAlgorithms);
|
|
result += write_sub_packet(sub.preferred_symmetric_algorithms, bytes);
|
|
}
|
|
if (this.revocationKeyClass !== null) {
|
|
bytes = String.fromCharCode(this.revocationKeyClass);
|
|
bytes += String.fromCharCode(this.revocationKeyAlgorithm);
|
|
bytes += this.revocationKeyFingerprint;
|
|
result += write_sub_packet(sub.revocation_key, bytes);
|
|
}
|
|
if (!this.issuerKeyId.isNull()) {
|
|
result += write_sub_packet(sub.issuer, this.issuerKeyId.write());
|
|
}
|
|
if (this.notation !== null) {
|
|
for (var name in this.notation) {
|
|
if (this.notation.hasOwnProperty(name)) {
|
|
var value = this.notation[name];
|
|
bytes = String.fromCharCode(0x80);
|
|
bytes += String.fromCharCode(0);
|
|
bytes += String.fromCharCode(0);
|
|
bytes += String.fromCharCode(0);
|
|
// 2 octets of name length
|
|
bytes += util.writeNumber(name.length, 2);
|
|
// 2 octets of value length
|
|
bytes += util.writeNumber(value.length, 2);
|
|
bytes += name + value;
|
|
result += write_sub_packet(sub.notation_data, bytes);
|
|
}
|
|
}
|
|
}
|
|
if (this.preferredHashAlgorithms !== null) {
|
|
bytes = util.bin2str(this.preferredHashAlgorithms);
|
|
result += write_sub_packet(sub.preferred_hash_algorithms, bytes);
|
|
}
|
|
if (this.preferredCompressionAlgorithms !== null) {
|
|
bytes = util.bin2str(this.preferredCompressionAlgorithms);
|
|
result += write_sub_packet(sub.preferred_hash_algorithms, bytes);
|
|
}
|
|
if (this.keyServerPreferences !== null) {
|
|
bytes = util.bin2str(this.keyServerPreferences);
|
|
result += write_sub_packet(sub.key_server_preferences, bytes);
|
|
}
|
|
if (this.preferredKeyServer !== null) {
|
|
result += write_sub_packet(sub.preferred_key_server, this.preferredKeyServer);
|
|
}
|
|
if (this.isPrimaryUserID !== null) {
|
|
result += write_sub_packet(sub.primary_user_id, String.fromCharCode(this.isPrimaryUserID ? 1 : 0));
|
|
}
|
|
if (this.policyURI !== null) {
|
|
result += write_sub_packet(sub.policy_uri, this.policyURI);
|
|
}
|
|
if (this.keyFlags !== null) {
|
|
bytes = util.bin2str(this.keyFlags);
|
|
result += write_sub_packet(sub.key_flags, bytes);
|
|
}
|
|
if (this.signersUserId !== null) {
|
|
result += write_sub_packet(sub.signers_user_id, this.signersUserId);
|
|
}
|
|
if (this.reasonForRevocationFlag !== null) {
|
|
bytes = String.fromCharCode(this.reasonForRevocationFlag);
|
|
bytes += this.reasonForRevocationString;
|
|
result += write_sub_packet(sub.reason_for_revocation, bytes);
|
|
}
|
|
if (this.features !== null) {
|
|
bytes = util.bin2str(this.features);
|
|
result += write_sub_packet(sub.features, bytes);
|
|
}
|
|
if (this.signatureTargetPublicKeyAlgorithm !== null) {
|
|
bytes = String.fromCharCode(this.signatureTargetPublicKeyAlgorithm);
|
|
bytes += String.fromCharCode(this.signatureTargetHashAlgorithm);
|
|
bytes += this.signatureTargetHash;
|
|
result += write_sub_packet(sub.signature_target, bytes);
|
|
}
|
|
if (this.embeddedSignature !== null) {
|
|
result += write_sub_packet(sub.embedded_signature, this.embeddedSignature.write());
|
|
}
|
|
result = util.writeNumber(result.length, 2) + result;
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* 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_packet(type, data) {
|
|
var result = "";
|
|
result += packet.writeSimpleLength(data.length + 1);
|
|
result += String.fromCharCode(type);
|
|
result += data;
|
|
return result;
|
|
}
|
|
|
|
// V4 signature sub packets
|
|
|
|
this.read_sub_packet = function (bytes) {
|
|
var mypos = 0;
|
|
|
|
function read_array(prop, bytes) {
|
|
this[prop] = [];
|
|
|
|
for (var i = 0; i < bytes.length; i++) {
|
|
this[prop].push(bytes.charCodeAt(i));
|
|
}
|
|
}
|
|
|
|
// The leftwost bit denotes a "critical" packet, but we ignore it.
|
|
var type = bytes.charCodeAt(mypos++) & 0x7F;
|
|
|
|
// subpacket type
|
|
switch (type) {
|
|
case 2:
|
|
// Signature Creation Time
|
|
this.created = util.readDate(bytes.substr(mypos));
|
|
break;
|
|
case 3:
|
|
// Signature Expiration Time in seconds
|
|
var seconds = util.readNumber(bytes.substr(mypos));
|
|
|
|
this.signatureNeverExpires = seconds == 0;
|
|
this.signatureExpirationTime = seconds;
|
|
|
|
break;
|
|
case 4:
|
|
// Exportable Certification
|
|
this.exportable = bytes.charCodeAt(mypos++) == 1;
|
|
break;
|
|
case 5:
|
|
// Trust Signature
|
|
this.trustLevel = bytes.charCodeAt(mypos++);
|
|
this.trustAmount = bytes.charCodeAt(mypos++);
|
|
break;
|
|
case 6:
|
|
// Regular Expression
|
|
this.regularExpression = bytes.substr(mypos);
|
|
break;
|
|
case 7:
|
|
// Revocable
|
|
this.revocable = bytes.charCodeAt(mypos++) == 1;
|
|
break;
|
|
case 9:
|
|
// Key Expiration Time in seconds
|
|
var seconds = util.readNumber(bytes.substr(mypos));
|
|
|
|
this.keyExpirationTime = seconds;
|
|
this.keyNeverExpires = seconds == 0;
|
|
|
|
break;
|
|
case 11:
|
|
// Preferred Symmetric Algorithms
|
|
this.preferredSymmetricAlgorithms = [];
|
|
|
|
while (mypos != bytes.length) {
|
|
this.preferredSymmetricAlgorithms.push(bytes.charCodeAt(mypos++));
|
|
}
|
|
|
|
break;
|
|
case 12:
|
|
// Revocation Key
|
|
// (1 octet of class, 1 octet of public-key algorithm ID, 20
|
|
// octets of
|
|
// fingerprint)
|
|
this.revocationKeyClass = bytes.charCodeAt(mypos++);
|
|
this.revocationKeyAlgorithm = bytes.charCodeAt(mypos++);
|
|
this.revocationKeyFingerprint = bytes.substr(mypos, 20);
|
|
break;
|
|
|
|
case 16:
|
|
// Issuer
|
|
this.issuerKeyId.read(bytes.substr(mypos));
|
|
break;
|
|
|
|
case 20:
|
|
// Notation Data
|
|
// We don't know how to handle anything but a text flagged data.
|
|
if (bytes.charCodeAt(mypos) == 0x80) {
|
|
|
|
// We extract key/value tuple from the byte stream.
|
|
mypos += 4;
|
|
var m = util.readNumber(bytes.substr(mypos, 2));
|
|
mypos += 2
|
|
var n = util.readNumber(bytes.substr(mypos, 2));
|
|
mypos += 2
|
|
|
|
var name = bytes.substr(mypos, m),
|
|
value = bytes.substr(mypos + m, n);
|
|
|
|
this.notation = this.notation || {};
|
|
this.notation[name] = value;
|
|
} else throw new Error("Unsupported notation flag.");
|
|
break;
|
|
case 21:
|
|
// Preferred Hash Algorithms
|
|
read_array.call(this, 'preferredHashAlgorithms', bytes.substr(mypos));
|
|
break;
|
|
case 22:
|
|
// Preferred Compression Algorithms
|
|
read_array.call(this, 'preferredCompressionAlgorithms ', bytes.substr(mypos));
|
|
break;
|
|
case 23:
|
|
// Key Server Preferences
|
|
read_array.call(this, 'keyServerPreferencess', bytes.substr(mypos));
|
|
break;
|
|
case 24:
|
|
// Preferred Key Server
|
|
this.preferredKeyServer = bytes.substr(mypos);
|
|
break;
|
|
case 25:
|
|
// Primary User ID
|
|
this.isPrimaryUserID = bytes[mypos++] != 0;
|
|
break;
|
|
case 26:
|
|
// Policy URI
|
|
this.policyURI = bytes.substr(mypos);
|
|
break;
|
|
case 27:
|
|
// Key Flags
|
|
read_array.call(this, 'keyFlags', bytes.substr(mypos));
|
|
break;
|
|
case 28:
|
|
// Signer's User ID
|
|
this.signersUserId += bytes.substr(mypos);
|
|
break;
|
|
case 29:
|
|
// Reason for Revocation
|
|
this.reasonForRevocationFlag = bytes.charCodeAt(mypos++);
|
|
this.reasonForRevocationString = bytes.substr(mypos);
|
|
break;
|
|
case 30:
|
|
// Features
|
|
read_array.call(this, 'features', bytes.substr(mypos));
|
|
break;
|
|
case 31:
|
|
// Signature Target
|
|
// (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash)
|
|
this.signatureTargetPublicKeyAlgorithm = bytes.charCodeAt(mypos++);
|
|
this.signatureTargetHashAlgorithm = bytes.charCodeAt(mypos++);
|
|
|
|
var len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm);
|
|
|
|
this.signatureTargetHash = bytes.substr(mypos, len);
|
|
break;
|
|
case 32:
|
|
// Embedded Signature
|
|
this.embeddedSignature = new signature();
|
|
this.embeddedSignature.read(bytes.substr(mypos));
|
|
break;
|
|
default:
|
|
throw new Error("Unknown signature subpacket type " + type + " @:" + mypos);
|
|
break;
|
|
}
|
|
};
|
|
|
|
// Produces data to produce signature on
|
|
this.toSign = function (type, data) {
|
|
var t = enums.signature;
|
|
|
|
switch (type) {
|
|
case t.binary:
|
|
case t.text:
|
|
return data.getBytes();
|
|
|
|
case t.standalone:
|
|
return '';
|
|
|
|
case t.cert_generic:
|
|
case t.cert_persona:
|
|
case t.cert_casual:
|
|
case t.cert_positive:
|
|
case t.cert_revocation:
|
|
var packet, tag;
|
|
|
|
if (data.userid !== undefined) {
|
|
tag = 0xB4;
|
|
packet = data.userid;
|
|
} else if (data.userattribute !== undefined) {
|
|
tag = 0xD1;
|
|
packet = data.userattribute;
|
|
} else throw new Error('Either a userid or userattribute packet needs to be ' +
|
|
'supplied for certification.');
|
|
|
|
var bytes = packet.write();
|
|
|
|
if (this.version == 4) {
|
|
return this.toSign(t.key, data) +
|
|
String.fromCharCode(tag) +
|
|
util.writeNumber(bytes.length, 4) +
|
|
bytes;
|
|
} else if (this.version == 3) {
|
|
return this.toSign(t.key, data) +
|
|
bytes;
|
|
}
|
|
break;
|
|
|
|
case t.subkey_binding:
|
|
case t.key_binding:
|
|
return this.toSign(t.key, data) + this.toSign(t.key, {
|
|
key: data.bind
|
|
});
|
|
|
|
case t.key:
|
|
if (data.key == undefined)
|
|
throw new Error('Key packet is required for this sigtature.');
|
|
|
|
return data.key.writeOld();
|
|
|
|
case t.key_revocation:
|
|
case t.subkey_revocation:
|
|
return this.toSign(t.key, data);
|
|
case t.timestamp:
|
|
return '';
|
|
case t.third_party:
|
|
throw new Error('Not implemented');
|
|
break;
|
|
default:
|
|
throw new Error('Unknown signature type.')
|
|
}
|
|
}
|
|
|
|
|
|
this.calculateTrailer = function () {
|
|
// calculating the trailer
|
|
var trailer = '';
|
|
// V3 signatures don't have a trailer
|
|
if (this.version == 3) return trailer;
|
|
trailer += String.fromCharCode(4); // Version
|
|
trailer += String.fromCharCode(0xFF);
|
|
trailer += util.writeNumber(this.signatureData.length, 4);
|
|
return trailer
|
|
}
|
|
|
|
|
|
/**
|
|
* verifys the signature packet. Note: not signature types are implemented
|
|
* @param {String|Object} data data which on the signature applies
|
|
* @param {module:packet/public_subkey|module:packet/public_key} key the public key to verify the signature
|
|
* @return {boolean} True if message is verified, else false.
|
|
*/
|
|
this.verify = function (key, data) {
|
|
var signatureType = enums.write(enums.signature, this.signatureType),
|
|
publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm),
|
|
hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
|
|
|
var bytes = this.toSign(signatureType, data),
|
|
trailer = this.calculateTrailer();
|
|
|
|
|
|
var mpicount = 0;
|
|
// Algorithm-Specific Fields for RSA signatures:
|
|
// - multiprecision number (MPI) of RSA signature value m**d mod n.
|
|
if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4)
|
|
mpicount = 1;
|
|
// Algorithm-Specific Fields for DSA signatures:
|
|
// - MPI of DSA value r.
|
|
// - MPI of DSA value s.
|
|
else if (publicKeyAlgorithm == 17)
|
|
mpicount = 2;
|
|
|
|
var mpi = [],
|
|
i = 0;
|
|
for (var j = 0; j < mpicount; j++) {
|
|
mpi[j] = new type_mpi();
|
|
i += mpi[j].read(this.signature.substr(i));
|
|
}
|
|
|
|
this.verified = crypto.signature.verify(publicKeyAlgorithm,
|
|
hashAlgorithm, mpi, key.mpi,
|
|
bytes + this.signatureData + trailer);
|
|
|
|
return this.verified;
|
|
}
|
|
|
|
/**
|
|
* Verifies signature expiration date
|
|
* @return {Boolean} true if expired
|
|
*/
|
|
this.isExpired = function () {
|
|
if (!this.signatureNeverExpires) {
|
|
return Date.now() > (this.created.getTime() + this.signatureExpirationTime*1000);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
</code></pre>
|
|
</article>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<nav>
|
|
<h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-armor.html">armor</a></li><li><a href="module-cleartext.html">cleartext</a></li><li><a href="module-config.html">config</a></li><li><a href="config.html">config/config</a></li><li><a href="localStorage.html">config/localStorage</a></li><li><a href="module-crypto.html">crypto</a></li><li><a href="cfb.html">crypto/cfb</a></li><li><a href="cipher.html">crypto/cipher</a></li><li><a href="aes.html">crypto/cipher/aes</a></li><li><a href="blowfish.html">crypto/cipher/blowfish</a></li><li><a href="cast5.html">crypto/cipher/cast5</a></li><li><a href="des.html">crypto/cipher/des</a></li><li><a href="twofish.html">crypto/cipher/twofish</a></li><li><a href="crypto.html">crypto/crypto</a></li><li><a href="hash.html">crypto/hash</a></li><li><a href="md5.html">crypto/hash/md5</a></li><li><a href="ripe-md.html">crypto/hash/ripe-md</a></li><li><a href="sha.html">crypto/hash/sha</a></li><li><a href="pkcs1.html">crypto/pkcs1</a></li><li><a href="public_key.html">crypto/public_key</a></li><li><a href="dsa.html">crypto/public_key/dsa</a></li><li><a href="elgamal.html">crypto/public_key/elgamal</a></li><li><a href="jsbn.html">crypto/public_key/jsbn</a></li><li><a href="rsa.html">crypto/public_key/rsa</a></li><li><a href="random.html">crypto/random</a></li><li><a href="signature.html">crypto/signature</a></li><li><a href="armor.html">encoding/armor</a></li><li><a href="base64.html">encoding/base64</a></li><li><a href="module-enums.html">enums</a></li><li><a href="module-key.html">key</a></li><li><a href="module-keyid.html">keyid</a></li><li><a href="keyring.html">keyring/keyring</a></li><li><a href="localstore.html">keyring/localstore</a></li><li><a href="module-message.html">message</a></li><li><a href="module-mpi.html">mpi</a></li><li><a href="module-openpgp.html">openpgp</a></li><li><a href="module-packet.html">packet</a></li><li><a href="compressed.html">packet/compressed</a></li><li><a href="literal.html">packet/literal</a></li><li><a href="marker.html">packet/marker</a></li><li><a href="one_pass_signature.html">packet/one_pass_signature</a></li><li><a href="packet.html">packet/packet</a></li><li><a href="packetlist.html">packet/packetlist</a></li><li><a href="public_key_.html">packet/public_key</a></li><li><a href="public_key_encrypted_session_key.html">packet/public_key_encrypted_session_key</a></li><li><a href="public_subkey.html">packet/public_subkey</a></li><li><a href="secret_key.html">packet/secret_key</a></li><li><a href="secret_subkey.html">packet/secret_subkey</a></li><li><a href="signature_.html">packet/signature</a></li><li><a href="sym_encrypted_integrity_protected.html">packet/sym_encrypted_integrity_protected</a></li><li><a href="sym_encrypted_session_key.html">packet/sym_encrypted_session_key</a></li><li><a href="symmetrically_encrypted.html">packet/symmetrically_encrypted</a></li><li><a href="trust.html">packet/trust</a></li><li><a href="user_attribute.html">packet/user_attribute</a></li><li><a href="userid.html">packet/userid</a></li><li><a href="module-s2k.html">s2k</a></li><li><a href="keyid.html">type/keyid</a></li><li><a href="mpi.html">type/mpi</a></li><li><a href="s2k.html">type/s2k</a></li><li><a href="module-util.html">util</a></li><li><a href="util.html">util/util</a></li></ul><h3>Classes</h3><ul><li><a href="JXG.Util.html">Util</a></li><li><a href="module-cleartext-CleartextMessage.html">CleartextMessage</a></li><li><a href="module-key-Key.html">Key</a></li><li><a href="module-key-SubKey.html">SubKey</a></li><li><a href="module-key-User.html">User</a></li><li><a href="module-message-Message.html">Message</a></li></ul>
|
|
</nav>
|
|
|
|
<br clear="both">
|
|
|
|
<footer>
|
|
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.0</a> on Thu Jan 02 2014 13:02:39 GMT-0800 (PST)
|
|
</footer>
|
|
|
|
<script> prettyPrint(); </script>
|
|
<script src="scripts/linenumber.js"> </script>
|
|
</body>
|
|
</html>
|