Signature verification on primary key is working!
This commit is contained in:
parent
ba68203b56
commit
ab31b39d2f
|
@ -7449,7 +7449,7 @@ function openpgp_config() {
|
||||||
keyserver: "keyserver.linux.it" // "pgp.mit.edu:11371"
|
keyserver: "keyserver.linux.it" // "pgp.mit.edu:11371"
|
||||||
};
|
};
|
||||||
|
|
||||||
this.versionstring ="OpenPGP.js v.1.20130508";
|
this.versionstring ="OpenPGP.js v.1.20130509";
|
||||||
this.commentstring ="http://openpgpjs.org";
|
this.commentstring ="http://openpgpjs.org";
|
||||||
/**
|
/**
|
||||||
* Reads the config out of the HTML5 local storage
|
* Reads the config out of the HTML5 local storage
|
||||||
|
@ -10924,190 +10924,11 @@ function openpgp_packet_secret_key() {
|
||||||
this.public_key.algorithm);
|
this.public_key.algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates Debug output
|
|
||||||
* @return String which gives some information about the keymaterial
|
|
||||||
*/
|
|
||||||
function toString() {
|
|
||||||
var result = "";
|
|
||||||
switch (this.tagType) {
|
|
||||||
case 6:
|
|
||||||
result += '5.5.1.1. Public-Key Packet (Tag 6)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.version+'\n'+
|
|
||||||
' creation time: '+this.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
result += '5.5.1.2. Public-Subkey Packet (Tag 14)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.version+'\n'+
|
|
||||||
' creation time: '+this.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result +='5.5.1.3. Secret-Key Packet (Tag 5)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.publicKey.version+'\n'+
|
|
||||||
' creation time: '+this.publicKey.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.publicKey.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKey.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result += '5.5.1.4. Secret-Subkey Packet (Tag 7)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version[1]: '+(this.version == 4)+'\n'+
|
|
||||||
' creationtime[4]: '+this.creationTime+'\n'+
|
|
||||||
' expiration[2]: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result += 'unknown key material packet\n';
|
|
||||||
}
|
|
||||||
if (this.MPIs != null) {
|
|
||||||
result += "Public Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.MPIs.length; i++) {
|
|
||||||
result += this.MPIs[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.publicKey != null && this.publicKey.MPIs != null) {
|
|
||||||
result += "Public Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.publicKey.MPIs.length; i++) {
|
|
||||||
result += this.publicKey.MPIs[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.mpi != null) {
|
|
||||||
result += "Secret Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.mpi.length; i++) {
|
|
||||||
result += this.mpi[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subKeySignature != null)
|
|
||||||
result += "subKey Signature:\n"+this.subKeySignature.toString();
|
|
||||||
|
|
||||||
if (this.subKeyRevocationSignature != null )
|
|
||||||
result += "subKey Revocation Signature:\n"+this.subKeyRevocationSignature.toString();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Continue parsing packets belonging to the key material such as signatures
|
|
||||||
* @param {Object} parent_node The parent object
|
|
||||||
* @param {String} bytes Input string to read the packet(s) from
|
|
||||||
* @param {Integer} position Start position for the parser
|
|
||||||
* @param {Integer} len Length of the packet(s) or remaining length of bytes
|
|
||||||
* @return {Integer} Length of nodes read
|
|
||||||
*/
|
|
||||||
function read_nodes(parent_node, bytes, position, len) {
|
|
||||||
this.parentNode = parent_node;
|
|
||||||
if (this.tagType == 14) { // public sub-key packet
|
|
||||||
var pos = position;
|
|
||||||
var result = null;
|
|
||||||
while (bytes.length != pos) {
|
|
||||||
var l = bytes.length - pos;
|
|
||||||
result = openpgp_packet.read_packet(bytes, pos, l);
|
|
||||||
if (result == null) {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_pub]parsing ends here @:' + pos + " l:" + l);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
switch (result.tagType) {
|
|
||||||
case 2: // Signature Packet certification signature
|
|
||||||
if (result.signatureType == 24) { // subkey binding signature
|
|
||||||
this.subKeySignature = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
} else if (result.signatureType == 40) { // subkey revocation signature
|
|
||||||
this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
} else if (this.tagType == 7) { // private sub-key packet
|
|
||||||
var pos = position;
|
|
||||||
while (bytes.length != pos) {
|
|
||||||
var result = openpgp_packet.read_packet(bytes, pos, len - (pos - position));
|
|
||||||
if (result == null) {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_priv] parsing ends here @:' + pos);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
switch (result.tagType) {
|
|
||||||
case 2: // Signature Packet certification signature
|
|
||||||
if (result.signatureType == 24) // subkey embedded signature
|
|
||||||
this.subKeySignature = result;
|
|
||||||
else if (result.signatureType == 40) // subkey revocation signature
|
|
||||||
this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
} else {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+"unknown parent node for a key material packet "+parent_node.tagType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the validity for usage of this (sub)key
|
|
||||||
* @return {Integer} 0 = bad key, 1 = expired, 2 = revoked, 3 = valid
|
|
||||||
*/
|
|
||||||
function verifyKey() {
|
|
||||||
if (this.tagType == 14) {
|
|
||||||
if (this.subKeySignature == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (this.subKeySignature.version == 4 &&
|
|
||||||
this.subKeySignature.keyNeverExpires != null &&
|
|
||||||
!this.subKeySignature.keyNeverExpires &&
|
|
||||||
new Date((this.subKeySignature.keyExpirationTime*1000)+ this.creationTime.getTime()) < new Date()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
var hashdata = String.fromCharCode(0x99)+this.parentNode.header.substring(1)+this.parentNode.data+
|
|
||||||
String.fromCharCode(0x99)+this.header.substring(1)+this.packetdata;
|
|
||||||
if (!this.subKeySignature.verify(hashdata,this.parentNode)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < this.subKeyRevocationSignature.length; i++) {
|
|
||||||
if (this.getKeyId() == this.subKeyRevocationSignature[i].keyId){
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the key id of they key
|
* Calculates the key id of they key
|
||||||
* @return {String} A 8 byte key id
|
* @return {String} A 8 byte key id
|
||||||
*/
|
*/
|
||||||
function getKeyId() {
|
this.getKeyId = function() {
|
||||||
if (this.version == 4) {
|
if (this.version == 4) {
|
||||||
var f = this.getFingerprint();
|
var f = this.getFingerprint();
|
||||||
return f.substring(12,20);
|
return f.substring(12,20);
|
||||||
|
@ -11122,7 +10943,7 @@ function openpgp_packet_secret_key() {
|
||||||
* Calculates the fingerprint of the key
|
* Calculates the fingerprint of the key
|
||||||
* @return {String} A string containing the fingerprint
|
* @return {String} A string containing the fingerprint
|
||||||
*/
|
*/
|
||||||
function getFingerprint() {
|
this.getFingerprint = function() {
|
||||||
if (this.version == 4) {
|
if (this.version == 4) {
|
||||||
tohash = String.fromCharCode(0x99)+ String.fromCharCode(((this.packetdata.length) >> 8) & 0xFF)
|
tohash = String.fromCharCode(0x99)+ String.fromCharCode(((this.packetdata.length) >> 8) & 0xFF)
|
||||||
+ String.fromCharCode((this.packetdata.length) & 0xFF)+this.packetdata;
|
+ String.fromCharCode((this.packetdata.length) & 0xFF)+this.packetdata;
|
||||||
|
@ -11132,8 +10953,6 @@ function openpgp_packet_secret_key() {
|
||||||
return MD5(this.MPIs[0].MPI);
|
return MD5(this.MPIs[0].MPI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11523,6 +11342,79 @@ function openpgp_packet_signature() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.toSign = function(type, data) {
|
||||||
|
var t = openpgp_packet_signature.type;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case t.binary:
|
||||||
|
return data.literal.get_data_bytes();
|
||||||
|
|
||||||
|
case t.text:
|
||||||
|
return toSign(t.binary, data)
|
||||||
|
.replace(/\r\n/g, '\n')
|
||||||
|
.replace(/\n/g, '\r\n');
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
return this.toSign(t.key, data) +
|
||||||
|
String.fromCharCode(tag) +
|
||||||
|
openpgp_packet_number_write(bytes.length, 4) +
|
||||||
|
bytes;
|
||||||
|
}
|
||||||
|
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.');
|
||||||
|
|
||||||
|
var bytes = data.key.write();
|
||||||
|
|
||||||
|
return String.fromCharCode(0x99) +
|
||||||
|
openpgp_packet_number_write(bytes.length, 2) +
|
||||||
|
bytes;
|
||||||
|
}
|
||||||
|
case t.key_revocation:
|
||||||
|
case t.subkey_revocation:
|
||||||
|
return this.toSign(t.key, data);
|
||||||
|
case t.timestamp:
|
||||||
|
return '';
|
||||||
|
case t.thrid_party:
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown signature type.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* verifys the signature packet. Note: not signature types are implemented
|
* verifys the signature packet. Note: not signature types are implemented
|
||||||
* @param {String} data data which on the signature applies
|
* @param {String} data data which on the signature applies
|
||||||
|
@ -11531,65 +11423,7 @@ function openpgp_packet_signature() {
|
||||||
*/
|
*/
|
||||||
this.verify = function(key, data) {
|
this.verify = function(key, data) {
|
||||||
|
|
||||||
var bytes =
|
var bytes = this.toSign(this.signatureType, data);
|
||||||
|
|
||||||
(function(type, data) {
|
|
||||||
switch(type) {
|
|
||||||
case 0: // 0x00: Signature of a binary document.
|
|
||||||
return data.literal.data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // 0x01: Signature of a canonical text document.
|
|
||||||
return data.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
|
|
||||||
|
|
||||||
case 2: // 0x02: Standalone signature.
|
|
||||||
return ''
|
|
||||||
case 16:
|
|
||||||
// 0x10: Generic certification of a User ID and Public-Key packet.
|
|
||||||
case 17:
|
|
||||||
// 0x11: Persona certification of a User ID and Public-Key packet.
|
|
||||||
case 18:
|
|
||||||
// 0x12: Casual certification of a User ID and Public-Key packet.
|
|
||||||
case 19:
|
|
||||||
// 0x13: Positive certification of a User ID and Public-Key packet.
|
|
||||||
case 48:
|
|
||||||
// 0x30: Certification revocation signature
|
|
||||||
|
|
||||||
if(data.userid != undefined) {
|
|
||||||
return String.fromCharCode(0xB4) +
|
|
||||||
openpgp_packet_number_write(data.userid.userid.length, 4) +
|
|
||||||
data;
|
|
||||||
}
|
|
||||||
else if(data.userattribute != undefined) {
|
|
||||||
return String.fromCharCode(0xB4) +
|
|
||||||
openpgp_packet_number_write(data.userattribute.userid.length, 4) +
|
|
||||||
data;
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
case 24:
|
|
||||||
// 0x18: Subkey Binding Signature
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
// 0x19: Primary Key Binding Signature
|
|
||||||
case 31:
|
|
||||||
// 0x1F: Signature directly on a key
|
|
||||||
case 32:
|
|
||||||
// 0x20: Key revocation signature
|
|
||||||
case 40:
|
|
||||||
// 0x28: Subkey revocation signature
|
|
||||||
return;
|
|
||||||
case 64:
|
|
||||||
// 0x40: Timestamp signature.
|
|
||||||
break;
|
|
||||||
case 80:
|
|
||||||
// 0x50: Third-Party Confirmation signature.
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
util.print_error("openpgp.packet.signature.js\n"+
|
|
||||||
"signature verification for type"+
|
|
||||||
this.signatureType+" not implemented");
|
|
||||||
return false;
|
|
||||||
}})(this.signatureType, data);
|
|
||||||
|
|
||||||
// calculating the trailer
|
// calculating the trailer
|
||||||
var trailer = '';
|
var trailer = '';
|
||||||
|
@ -11606,7 +11440,7 @@ function openpgp_packet_signature() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* One pass signature packet type
|
/** One pass signature packet type
|
||||||
* @enum {Integer} */
|
* @enum {Integer} */
|
||||||
openpgp_packet_signature.type = {
|
openpgp_packet_signature.type = {
|
||||||
/** 0x00: Signature of a binary document. */
|
/** 0x00: Signature of a binary document. */
|
||||||
|
|
14
resources/openpgp.min.js
vendored
14
resources/openpgp.min.js
vendored
|
@ -285,7 +285,7 @@ JXG.Util.asciiCharCodeAt=function(a,b){var c=a.charCodeAt(b);if(255<c)switch(c){
|
||||||
151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c};
|
151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c};
|
||||||
JXG.Util.utf8Decode=function(a){var b=[],c=0,d=0,e=0,f;if(!JXG.exists(a))return"";for(;c<a.length;)d=a.charCodeAt(c),128>d?(b.push(String.fromCharCode(d)),c++):191<d&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((d&15)<<12|(e&63)<<6|f&63)),c+=3);return b.join("")};
|
JXG.Util.utf8Decode=function(a){var b=[],c=0,d=0,e=0,f;if(!JXG.exists(a))return"";for(;c<a.length;)d=a.charCodeAt(c),128>d?(b.push(String.fromCharCode(d)),c++):191<d&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((d&15)<<12|(e&63)<<6|f&63)),c+=3);return b.join("")};
|
||||||
JXG.Util.genUUID=function(){for(var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d,e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")};
|
JXG.Util.genUUID=function(){for(var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d,e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")};
|
||||||
function openpgp_config(){this.config=null;this.default_config={prefer_hash_algorithm:8,encryption_cipher:9,compression:1,show_version:!0,show_comment:!0,integrity_protect:!0,composition_behavior:0,keyserver:"keyserver.linux.it"};this.versionstring="OpenPGP.js v.1.20130508";this.commentstring="http://openpgpjs.org";this.debug=!1;this.read=function(){var a=JSON.parse(window.localStorage.getItem("config"));null==a?(this.config=this.default_config,this.write()):this.config=a};this.write=function(){window.localStorage.setItem("config",
|
function openpgp_config(){this.config=null;this.default_config={prefer_hash_algorithm:8,encryption_cipher:9,compression:1,show_version:!0,show_comment:!0,integrity_protect:!0,composition_behavior:0,keyserver:"keyserver.linux.it"};this.versionstring="OpenPGP.js v.1.20130509";this.commentstring="http://openpgpjs.org";this.debug=!1;this.read=function(){var a=JSON.parse(window.localStorage.getItem("config"));null==a?(this.config=this.default_config,this.write()):this.config=a};this.write=function(){window.localStorage.setItem("config",
|
||||||
JSON.stringify(this.config))}}var b64s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function s2r(a){var b,c,d,e="",f=0,h=0,g=a.length;for(d=0;d<g;d++)c=a.charCodeAt(d),0==h?(e+=b64s.charAt(c>>2&63),b=(c&3)<<4):1==h?(e+=b64s.charAt(b|c>>4&15),b=(c&15)<<2):2==h&&(e+=b64s.charAt(b|c>>6&3),f+=1,0==f%60&&(e+="\n"),e+=b64s.charAt(c&63)),f+=1,0==f%60&&(e+="\n"),h+=1,3==h&&(h=0);0<h&&(e+=b64s.charAt(b),f+=1,0==f%60&&(e+="\n"),e+="=",f+=1);1==h&&(0==f%60&&(e+="\n"),e+="=");return e}
|
JSON.stringify(this.config))}}var b64s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function s2r(a){var b,c,d,e="",f=0,h=0,g=a.length;for(d=0;d<g;d++)c=a.charCodeAt(d),0==h?(e+=b64s.charAt(c>>2&63),b=(c&3)<<4):1==h?(e+=b64s.charAt(b|c>>4&15),b=(c&15)<<2):2==h&&(e+=b64s.charAt(b|c>>6&3),f+=1,0==f%60&&(e+="\n"),e+=b64s.charAt(c&63)),f+=1,0==f%60&&(e+="\n"),h+=1,3==h&&(h=0);0<h&&(e+=b64s.charAt(b),f+=1,0==f%60&&(e+="\n"),e+="=",f+=1);1==h&&(0==f%60&&(e+="\n"),e+="=");return e}
|
||||||
function r2s(a){var b,c,d="",e=0,f=0,h=a.length;for(c=0;c<h;c++)b=b64s.indexOf(a.charAt(c)),0<=b&&(e&&(d+=String.fromCharCode(f|b>>6-e&255)),e=e+2&7,f=b<<e&255);return d}
|
function r2s(a){var b,c,d="",e=0,f=0,h=a.length;for(c=0;c<h;c++)b=b64s.indexOf(a.charAt(c)),0<=b&&(e&&(d+=String.fromCharCode(f|b>>6-e&255)),e=e+2&7,f=b<<e&255);return d}
|
||||||
function openpgp_encoding_deArmor(a){var a=a.replace(/\r/g,""),b=openpgp_encoding_get_type(a);if(2!=b){a=a.split("-----");b={openpgp:openpgp_encoding_base64_decode(a[2].split("\n\n")[1].split("\n=")[0].replace(/\n- /g,"\n")),type:b};if(verifyCheckSum(b.openpgp,a[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]))return b;util.print_error("Ascii armor integrity check on message failed: '"+a[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]+"' should be '"+getCheckSum(b));return!1}a=a.split("-----");
|
function openpgp_encoding_deArmor(a){var a=a.replace(/\r/g,""),b=openpgp_encoding_get_type(a);if(2!=b){a=a.split("-----");b={openpgp:openpgp_encoding_base64_decode(a[2].split("\n\n")[1].split("\n=")[0].replace(/\n- /g,"\n")),type:b};if(verifyCheckSum(b.openpgp,a[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]))return b;util.print_error("Ascii armor integrity check on message failed: '"+a[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]+"' should be '"+getCheckSum(b));return!1}a=a.split("-----");
|
||||||
|
@ -384,8 +384,9 @@ e);var f=openpgp_crypto_getRandomBytes(8);util.print_debug_hexstr_dump("write_pr
|
||||||
16)),b+e,this.iv);body+=this.iv+ciphertextMPIs;break;case 7:case 8:case 9:this.iv.length=16,this.iv=openpgp_crypto_getRandomBytes(this.iv.length),ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.iv.length,a,b+e,this.iv),body+=this.iv+ciphertextMPIs}}else body+=String.fromCharCode(0),body+=key.d.toMPI()+key.p.toMPI()+key.q.toMPI()+key.u.toMPI(),b=util.calc_checksum(key.d.toMPI()+key.p.toMPI()+key.q.toMPI()+key.u.toMPI()),body+=String.fromCharCode(b/256)+String.fromCharCode(b%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+
|
16)),b+e,this.iv);body+=this.iv+ciphertextMPIs;break;case 7:case 8:case 9:this.iv.length=16,this.iv=openpgp_crypto_getRandomBytes(this.iv.length),ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.iv.length,a,b+e,this.iv),body+=this.iv+ciphertextMPIs}}else body+=String.fromCharCode(0),body+=key.d.toMPI()+key.p.toMPI()+key.q.toMPI()+key.u.toMPI(),b=util.calc_checksum(key.d.toMPI()+key.p.toMPI()+key.q.toMPI()+key.u.toMPI()),body+=String.fromCharCode(b/256)+String.fromCharCode(b%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+
|
||||||
b);break;default:body="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+keyType)}b=openpgp_packet.write_packet_header(tag,body.length);return{string:b+body,header:b,body:body}};this.decrypt=function(a){if(null!=this.encrypted){var a=this.s2k.produce_key(a,openpgp_crypto_getKeyLength(this.symmetric_algorithm)),d="";switch(this.symmetric_algorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"),
|
b);break;default:body="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+keyType)}b=openpgp_packet.write_packet_header(tag,body.length);return{string:b+body,header:b,body:body}};this.decrypt=function(a){if(null!=this.encrypted){var a=this.s2k.produce_key(a,openpgp_crypto_getKeyLength(this.symmetric_algorithm)),d="";switch(this.symmetric_algorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"),
|
||||||
!1;case 2:d=normal_cfb_decrypt(function(a,b){return des(b,a,1,null,0)},this.iv.length,a,this.encrypted,this.iv);break;case 3:d=normal_cfb_decrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.iv.length,util.str2bin(a.substring(0,16)),this.encrypted,this.iv);break;case 4:d=normal_cfb_decrypt(function(a,b){return(new Blowfish(b)).encrypt(a)},this.iv.length,a,this.encrypted,this.iv);break;case 7:case 8:case 9:d=normal_cfb_decrypt(function(a,b){return AESencrypt(util.str2bin(a),
|
!1;case 2:d=normal_cfb_decrypt(function(a,b){return des(b,a,1,null,0)},this.iv.length,a,this.encrypted,this.iv);break;case 3:d=normal_cfb_decrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.iv.length,util.str2bin(a.substring(0,16)),this.encrypted,this.iv);break;case 4:d=normal_cfb_decrypt(function(a,b){return(new Blowfish(b)).encrypt(a)},this.iv.length,a,this.encrypted,this.iv);break;case 7:case 8:case 9:d=normal_cfb_decrypt(function(a,b){return AESencrypt(util.str2bin(a),
|
||||||
b)},this.iv.length,keyExpansion(a),this.encrypted,this.iv);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetric_algorithm),!1}if(null==d)return util.print_error("openpgp.packet.keymaterial.js\ncleartext was null"),!1;this.mpi=b(this.hash_algorithm,d,this.public_key.algorithm)}}}
|
b)},this.iv.length,keyExpansion(a),this.encrypted,this.iv);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetric_algorithm),!1}if(null==d)return util.print_error("openpgp.packet.keymaterial.js\ncleartext was null"),!1;this.mpi=b(this.hash_algorithm,d,this.public_key.algorithm)}};this.getKeyId=function(){if(4==
|
||||||
function openpgp_packet_secret_subkey(){openpgp_packet_secret_key.call(this);this.tag=7}
|
this.version)return this.getFingerprint().substring(12,20);if(3==this.version&&0<this.publicKeyAlgorithm&&4>this.publicKeyAlgorithm){var a=this.MPIs[0].substring(this.MPIs[0].mpiByteLength-8);util.print_debug("openpgp.msg.publickey read_nodes:\nV3 key ID: "+a);return a}};this.getFingerprint=function(){if(4==this.version)return tohash=String.fromCharCode(153)+String.fromCharCode(this.packetdata.length>>8&255)+String.fromCharCode(this.packetdata.length&255)+this.packetdata,util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+
|
||||||
|
util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm),str_sha1(tohash,tohash.length);if(3==this.version&&0<this.publicKeyAlgorithm&&4>this.publicKeyAlgorithm)return MD5(this.MPIs[0].MPI)}}function openpgp_packet_secret_subkey(){openpgp_packet_secret_key.call(this);this.tag=7}
|
||||||
function openpgp_packet_signature(){this.tag=2;this.issuerKeyId=this.revocationKeyFingerprint=this.revocationKeyAlgorithm=this.revocationKeyClass=this.preferredSymmetricAlgorithms=this.keyNeverExpires=this.keyExpirationTime=this.revocable=this.regularExpression=this.trustAmount=this.trustLevel=this.exportable=this.hashAlgorithm=this.publicKeyAlgorithm=this.mpi=this.signedHashValue=this.signatureNeverExpires=this.signatureExpirationTime=this.signatureData=this.created=this.signatureType=null;this.notation=
|
function openpgp_packet_signature(){this.tag=2;this.issuerKeyId=this.revocationKeyFingerprint=this.revocationKeyAlgorithm=this.revocationKeyClass=this.preferredSymmetricAlgorithms=this.keyNeverExpires=this.keyExpirationTime=this.revocable=this.regularExpression=this.trustAmount=this.trustLevel=this.exportable=this.hashAlgorithm=this.publicKeyAlgorithm=this.mpi=this.signedHashValue=this.signatureNeverExpires=this.signatureExpirationTime=this.signatureData=this.created=this.signatureType=null;this.notation=
|
||||||
{};this.embeddedSignature=this.signatureTargetHash=this.signatureTargetHashAlgorithm=this.signatureTargetPublicKeyAlgorithm=this.reasonForRevocationString=this.reasonForRevocationFlag=this.signersUserId=this.keyFlags=this.policyURI=this.isPrimaryUserID=this.preferredKeyServer=this.keyServerPreferences=this.preferredCompressionAlgorithms=this.preferredHashAlgorithms=null;this.verified=!1;this.read=function(a){var b=0;this.version=a[b++].charCodeAt();switch(this.version){case 3:5!=a[b++].charCodeAt()&&
|
{};this.embeddedSignature=this.signatureTargetHash=this.signatureTargetHashAlgorithm=this.signatureTargetPublicKeyAlgorithm=this.reasonForRevocationString=this.reasonForRevocationFlag=this.signersUserId=this.keyFlags=this.policyURI=this.isPrimaryUserID=this.preferredKeyServer=this.keyServerPreferences=this.preferredCompressionAlgorithms=this.preferredHashAlgorithms=null;this.verified=!1;this.read=function(a){var b=0;this.version=a[b++].charCodeAt();switch(this.version){case 3:5!=a[b++].charCodeAt()&&
|
||||||
util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(b-1));this.signatureType=a[b++].charCodeAt();this.created=openpgp_packet_time_read(a.substr(b,4));b+=4;this.signatureData=a.substring(position,b);this.issuerKeyId=a.substring(b,b+8);b+=8;this.publicKeyAlgorithm=a[b++].charCodeAt();this.hashAlgorithm=a[b++].charCodeAt();break;case 4:this.signatureType=a[b++].charCodeAt();this.publicKeyAlgorithm=a[b++].charCodeAt();this.hashAlgorithm=
|
util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(b-1));this.signatureType=a[b++].charCodeAt();this.created=openpgp_packet_time_read(a.substr(b,4));b+=4;this.signatureData=a.substring(position,b);this.issuerKeyId=a.substring(b,b+8);b+=8;this.publicKeyAlgorithm=a[b++].charCodeAt();this.hashAlgorithm=a[b++].charCodeAt();break;case 4:this.signatureType=a[b++].charCodeAt();this.publicKeyAlgorithm=a[b++].charCodeAt();this.hashAlgorithm=
|
||||||
|
@ -394,9 +395,10 @@ a[b++].charCodeAt();var c=function(a,b){for(var c=openpgp_packet_number_read(a.s
|
||||||
a;break;case 4:this.exportable=1==a[c++].charCodeAt();break;case 5:this.trustLevel=a[c++].charCodeAt();this.trustAmount=a[c++].charCodeAt();break;case 6:this.regularExpression=a.substr(c);break;case 7:this.revocable=1==a[c++].charCodeAt();break;case 9:this.keyExpirationTime=a=openpgp_packet_time_read(a.substr(c));this.keyNeverExpires=0==a.getTime();break;case 11:for(this.preferredSymmetricAlgorithms=[];c!=a.length;)this.preferredSymmetricAlgorithms.push(a[c++].charCodeAt());break;case 12:this.revocationKeyClass=
|
a;break;case 4:this.exportable=1==a[c++].charCodeAt();break;case 5:this.trustLevel=a[c++].charCodeAt();this.trustAmount=a[c++].charCodeAt();break;case 6:this.regularExpression=a.substr(c);break;case 7:this.revocable=1==a[c++].charCodeAt();break;case 9:this.keyExpirationTime=a=openpgp_packet_time_read(a.substr(c));this.keyNeverExpires=0==a.getTime();break;case 11:for(this.preferredSymmetricAlgorithms=[];c!=a.length;)this.preferredSymmetricAlgorithms.push(a[c++].charCodeAt());break;case 12:this.revocationKeyClass=
|
||||||
a[c++].charCodeAt();this.revocationKeyAlgorithm=a[c++].charCodeAt();this.revocationKeyFingerprint=a.substr(c,20);break;case 16:this.issuerKeyId=a.substr(c,8);break;case 20:if(128==a[c].charCodeAt()){var c=c+4,e=openpgp_packet_number_read(a.substr(c,2)),c=c+2,f=openpgp_packet_number_read(a.substr(c,2)),c=c+2,d=a.substr(c,e),a=a.substr(c+e,f);this.notation[d]=a}break;case 21:b.call(this,"preferredHashAlgorithms",a.substr(c));break;case 22:b.call(this,"preferredCompressionAlgorithms ",a.substr(c));break;
|
a[c++].charCodeAt();this.revocationKeyAlgorithm=a[c++].charCodeAt();this.revocationKeyFingerprint=a.substr(c,20);break;case 16:this.issuerKeyId=a.substr(c,8);break;case 20:if(128==a[c].charCodeAt()){var c=c+4,e=openpgp_packet_number_read(a.substr(c,2)),c=c+2,f=openpgp_packet_number_read(a.substr(c,2)),c=c+2,d=a.substr(c,e),a=a.substr(c+e,f);this.notation[d]=a}break;case 21:b.call(this,"preferredHashAlgorithms",a.substr(c));break;case 22:b.call(this,"preferredCompressionAlgorithms ",a.substr(c));break;
|
||||||
case 23:b.call(this,"keyServerPreferencess",a.substr(c));break;case 24:this.preferredKeyServer=a.substr(c);break;case 25:this.isPrimaryUserID=0!=a[c++];break;case 26:this.policyURI=a.substr(c);break;case 27:b.call(this,"keyFlags",a.substr(c));break;case 28:this.signersUserId+=a.substr(c);break;case 29:this.reasonForRevocationFlag=a[c++].charCodeAt();this.reasonForRevocationString=a.substr(c);break;case 30:b.call(this,"features",a.substr(c));break;case 31:this.signatureTargetPublicKeyAlgorithm=a[c++].charCodeAt();
|
case 23:b.call(this,"keyServerPreferencess",a.substr(c));break;case 24:this.preferredKeyServer=a.substr(c);break;case 25:this.isPrimaryUserID=0!=a[c++];break;case 26:this.policyURI=a.substr(c);break;case 27:b.call(this,"keyFlags",a.substr(c));break;case 28:this.signersUserId+=a.substr(c);break;case 29:this.reasonForRevocationFlag=a[c++].charCodeAt();this.reasonForRevocationString=a.substr(c);break;case 30:b.call(this,"features",a.substr(c));break;case 31:this.signatureTargetPublicKeyAlgorithm=a[c++].charCodeAt();
|
||||||
this.signatureTargetHashAlgorithm=a[c++].charCodeAt();e=openpgp_crypto_getHashByteLength(this.signatureTargetHashAlgorithm);this.signatureTargetHash=a.substr(c,e);break;case 32:this.embeddedSignature=new openpgp_packet_signature;this.embeddedSignature.read(a.substr(c));break;default:util.print_error("openpgp.packet.signature.js\nunknown signature subpacket type "+d+" @:"+c+" subplen:"+subplen+" len:"+e)}};this.verify=function(a,b){var c=function(a,b){switch(a){case 0:return b.literal.data;case 1:return b.replace(/\r\n/g,
|
this.signatureTargetHashAlgorithm=a[c++].charCodeAt();e=openpgp_crypto_getHashByteLength(this.signatureTargetHashAlgorithm);this.signatureTargetHash=a.substr(c,e);break;case 32:this.embeddedSignature=new openpgp_packet_signature;this.embeddedSignature.read(a.substr(c));break;default:util.print_error("openpgp.packet.signature.js\nunknown signature subpacket type "+d+" @:"+c+" subplen:"+subplen+" len:"+e)}};this.toSign=function(a,b){var c=openpgp_packet_signature.type;switch(a){case c.binary:return b.literal.get_data_bytes();
|
||||||
"\n").replace(/\n/g,"\r\n");case 2:return"";case 16:case 17:case 18:case 19:case 48:if(void 0!=b.userid)return String.fromCharCode(180)+openpgp_packet_number_write(b.userid.userid.length,4)+b;if(void 0!=b.userattribute)return String.fromCharCode(180)+openpgp_packet_number_write(b.userattribute.userid.length,4)+b;break;case 24:break;case 25:case 31:case 32:case 40:break;case 64:break;case 80:break;default:return util.print_error("openpgp.packet.signature.js\nsignature verification for type"+this.signatureType+
|
case c.text:return toSign(c.binary,b).replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");case c.standalone:return"";case c.cert_generic:case c.cert_persona:case c.cert_casual:case c.cert_positive:case c.cert_revocation:var d,e;if(void 0!=b.userid)e=180,d=b.userid;else if(void 0!=b.userattribute)e=209,d=b.userattribute;else throw Error("Either a userid or userattribute packet needs to be supplied for certification.");d=d.write();return this.toSign(c.key,b)+String.fromCharCode(e)+openpgp_packet_number_write(d.length,
|
||||||
" not implemented"),!1}}(this.signatureType,b),d;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=openpgp_packet_number_write(this.signatureData.length,4);return this.verified=openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.mpi,a.mpi,c+this.signatureData+d)}}
|
4)+d;case c.subkey_binding:case c.key_binding:return this.toSign(c.key,b)+this.toSign(c.key,{key:b.bind});case c.key:if(void 0==b.key)throw Error("Key packet is required for this sigtature.");d=b.key.write();return String.fromCharCode(153)+openpgp_packet_number_write(d.length,2)+d;case c.key_revocation:case c.subkey_revocation:return this.toSign(c.key,b);case c.timestamp:return"";case c.thrid_party:throw Error("Not implemented");default:throw Error("Unknown signature type.");}};this.verify=function(a,
|
||||||
|
b){var c=this.toSign(this.signatureType,b),d;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=openpgp_packet_number_write(this.signatureData.length,4);return this.verified=openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.mpi,a.mpi,c+this.signatureData+d)}}
|
||||||
openpgp_packet_signature.type={binary:0,text:1,standalone:2,cert_generic:16,cert_persona:17,cert_casual:18,cert_positive:19,cert_revocation:48,subkey_binding:24,key_binding:25,key:31,key_revocation:32,subkey_revocation:40,timestamp:64,third_party:80};
|
openpgp_packet_signature.type={binary:0,text:1,standalone:2,cert_generic:16,cert_persona:17,cert_casual:18,cert_positive:19,cert_revocation:48,subkey_binding:24,key_binding:25,key:31,key_revocation:32,subkey_revocation:40,timestamp:64,third_party:80};
|
||||||
function openpgp_packet_sym_encrypted_integrity_protected(){this.tag=18;this.version=1;this.encrypted=null;this.modification=!1;this.packets=new openpgp_packetlist;this.read=function(a){this.version=a[0].charCodeAt();if(1!=this.version)return util.print_error("openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: "+this.version+"hex:"+util.hexstrdump(a)),null;this.encrypted=a.substr(1)};this.write=function(){return String.fromCharCode(this.version)+
|
function openpgp_packet_sym_encrypted_integrity_protected(){this.tag=18;this.version=1;this.encrypted=null;this.modification=!1;this.packets=new openpgp_packetlist;this.read=function(a){this.version=a[0].charCodeAt();if(1!=this.version)return util.print_error("openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: "+this.version+"hex:"+util.hexstrdump(a)),null;this.encrypted=a.substr(1)};this.write=function(){return String.fromCharCode(this.version)+
|
||||||
this.encrypted};this.encrypt=function(a,b){var c=this.packets.write(),d=openpgp_crypto_getPrefixRandom(a),e=d+d.charAt(d.length-2)+d.charAt(d.length-1),c=c+String.fromCharCode(211),c=c+String.fromCharCode(20);util.print_debug_hexstr_dump("data to be hashed:",e+c);c+=str_sha1(e+c);util.print_debug_hexstr_dump("hash:",c.substring(c.length-20,c.length));this.encrypted=openpgp_crypto_symmetricEncrypt(d,a,b,c,!1).substring(0,e.length+c.length)};this.decrypt=function(a,b){var c=openpgp_crypto_symmetricDecrypt(a,
|
this.encrypted};this.encrypt=function(a,b){var c=this.packets.write(),d=openpgp_crypto_getPrefixRandom(a),e=d+d.charAt(d.length-2)+d.charAt(d.length-1),c=c+String.fromCharCode(211),c=c+String.fromCharCode(20);util.print_debug_hexstr_dump("data to be hashed:",e+c);c+=str_sha1(e+c);util.print_debug_hexstr_dump("hash:",c.substring(c.length-20,c.length));this.encrypted=openpgp_crypto_symmetricEncrypt(d,a,b,c,!1).substring(0,e.length+c.length)};this.decrypt=function(a,b){var c=openpgp_crypto_symmetricDecrypt(a,
|
||||||
|
|
|
@ -340,190 +340,11 @@ function openpgp_packet_secret_key() {
|
||||||
this.public_key.algorithm);
|
this.public_key.algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates Debug output
|
|
||||||
* @return String which gives some information about the keymaterial
|
|
||||||
*/
|
|
||||||
function toString() {
|
|
||||||
var result = "";
|
|
||||||
switch (this.tagType) {
|
|
||||||
case 6:
|
|
||||||
result += '5.5.1.1. Public-Key Packet (Tag 6)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.version+'\n'+
|
|
||||||
' creation time: '+this.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
result += '5.5.1.2. Public-Subkey Packet (Tag 14)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.version+'\n'+
|
|
||||||
' creation time: '+this.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result +='5.5.1.3. Secret-Key Packet (Tag 5)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version: '+this.publicKey.version+'\n'+
|
|
||||||
' creation time: '+this.publicKey.creationTime+'\n'+
|
|
||||||
' expiration time: '+this.publicKey.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKey.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result += '5.5.1.4. Secret-Subkey Packet (Tag 7)\n'+
|
|
||||||
' length: '+this.packetLength+'\n'+
|
|
||||||
' version[1]: '+(this.version == 4)+'\n'+
|
|
||||||
' creationtime[4]: '+this.creationTime+'\n'+
|
|
||||||
' expiration[2]: '+this.expiration+'\n'+
|
|
||||||
' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result += 'unknown key material packet\n';
|
|
||||||
}
|
|
||||||
if (this.MPIs != null) {
|
|
||||||
result += "Public Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.MPIs.length; i++) {
|
|
||||||
result += this.MPIs[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.publicKey != null && this.publicKey.MPIs != null) {
|
|
||||||
result += "Public Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.publicKey.MPIs.length; i++) {
|
|
||||||
result += this.publicKey.MPIs[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.mpi != null) {
|
|
||||||
result += "Secret Key MPIs:\n";
|
|
||||||
for (var i = 0; i < this.mpi.length; i++) {
|
|
||||||
result += this.mpi[i].toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subKeySignature != null)
|
|
||||||
result += "subKey Signature:\n"+this.subKeySignature.toString();
|
|
||||||
|
|
||||||
if (this.subKeyRevocationSignature != null )
|
|
||||||
result += "subKey Revocation Signature:\n"+this.subKeyRevocationSignature.toString();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Continue parsing packets belonging to the key material such as signatures
|
|
||||||
* @param {Object} parent_node The parent object
|
|
||||||
* @param {String} bytes Input string to read the packet(s) from
|
|
||||||
* @param {Integer} position Start position for the parser
|
|
||||||
* @param {Integer} len Length of the packet(s) or remaining length of bytes
|
|
||||||
* @return {Integer} Length of nodes read
|
|
||||||
*/
|
|
||||||
function read_nodes(parent_node, bytes, position, len) {
|
|
||||||
this.parentNode = parent_node;
|
|
||||||
if (this.tagType == 14) { // public sub-key packet
|
|
||||||
var pos = position;
|
|
||||||
var result = null;
|
|
||||||
while (bytes.length != pos) {
|
|
||||||
var l = bytes.length - pos;
|
|
||||||
result = openpgp_packet.read_packet(bytes, pos, l);
|
|
||||||
if (result == null) {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_pub]parsing ends here @:' + pos + " l:" + l);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
switch (result.tagType) {
|
|
||||||
case 2: // Signature Packet certification signature
|
|
||||||
if (result.signatureType == 24) { // subkey binding signature
|
|
||||||
this.subKeySignature = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
} else if (result.signatureType == 40) { // subkey revocation signature
|
|
||||||
this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
} else if (this.tagType == 7) { // private sub-key packet
|
|
||||||
var pos = position;
|
|
||||||
while (bytes.length != pos) {
|
|
||||||
var result = openpgp_packet.read_packet(bytes, pos, len - (pos - position));
|
|
||||||
if (result == null) {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_priv] parsing ends here @:' + pos);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
switch (result.tagType) {
|
|
||||||
case 2: // Signature Packet certification signature
|
|
||||||
if (result.signatureType == 24) // subkey embedded signature
|
|
||||||
this.subKeySignature = result;
|
|
||||||
else if (result.signatureType == 40) // subkey revocation signature
|
|
||||||
this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result;
|
|
||||||
pos += result.packetLength + result.headerLength;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.data = bytes;
|
|
||||||
this.position = position - this.parentNode.packetLength;
|
|
||||||
this.len = pos - position;
|
|
||||||
return this.len;
|
|
||||||
} else {
|
|
||||||
util.print_error("openpgp.packet.keymaterial.js\n"+"unknown parent node for a key material packet "+parent_node.tagType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the validity for usage of this (sub)key
|
|
||||||
* @return {Integer} 0 = bad key, 1 = expired, 2 = revoked, 3 = valid
|
|
||||||
*/
|
|
||||||
function verifyKey() {
|
|
||||||
if (this.tagType == 14) {
|
|
||||||
if (this.subKeySignature == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (this.subKeySignature.version == 4 &&
|
|
||||||
this.subKeySignature.keyNeverExpires != null &&
|
|
||||||
!this.subKeySignature.keyNeverExpires &&
|
|
||||||
new Date((this.subKeySignature.keyExpirationTime*1000)+ this.creationTime.getTime()) < new Date()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
var hashdata = String.fromCharCode(0x99)+this.parentNode.header.substring(1)+this.parentNode.data+
|
|
||||||
String.fromCharCode(0x99)+this.header.substring(1)+this.packetdata;
|
|
||||||
if (!this.subKeySignature.verify(hashdata,this.parentNode)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < this.subKeyRevocationSignature.length; i++) {
|
|
||||||
if (this.getKeyId() == this.subKeyRevocationSignature[i].keyId){
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the key id of they key
|
* Calculates the key id of they key
|
||||||
* @return {String} A 8 byte key id
|
* @return {String} A 8 byte key id
|
||||||
*/
|
*/
|
||||||
function getKeyId() {
|
this.getKeyId = function() {
|
||||||
if (this.version == 4) {
|
if (this.version == 4) {
|
||||||
var f = this.getFingerprint();
|
var f = this.getFingerprint();
|
||||||
return f.substring(12,20);
|
return f.substring(12,20);
|
||||||
|
@ -538,7 +359,7 @@ function openpgp_packet_secret_key() {
|
||||||
* Calculates the fingerprint of the key
|
* Calculates the fingerprint of the key
|
||||||
* @return {String} A string containing the fingerprint
|
* @return {String} A string containing the fingerprint
|
||||||
*/
|
*/
|
||||||
function getFingerprint() {
|
this.getFingerprint = function() {
|
||||||
if (this.version == 4) {
|
if (this.version == 4) {
|
||||||
tohash = String.fromCharCode(0x99)+ String.fromCharCode(((this.packetdata.length) >> 8) & 0xFF)
|
tohash = String.fromCharCode(0x99)+ String.fromCharCode(((this.packetdata.length) >> 8) & 0xFF)
|
||||||
+ String.fromCharCode((this.packetdata.length) & 0xFF)+this.packetdata;
|
+ String.fromCharCode((this.packetdata.length) & 0xFF)+this.packetdata;
|
||||||
|
@ -548,8 +369,6 @@ function openpgp_packet_secret_key() {
|
||||||
return MD5(this.MPIs[0].MPI);
|
return MD5(this.MPIs[0].MPI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -378,6 +378,79 @@ function openpgp_packet_signature() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.toSign = function(type, data) {
|
||||||
|
var t = openpgp_packet_signature.type;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case t.binary:
|
||||||
|
return data.literal.get_data_bytes();
|
||||||
|
|
||||||
|
case t.text:
|
||||||
|
return toSign(t.binary, data)
|
||||||
|
.replace(/\r\n/g, '\n')
|
||||||
|
.replace(/\n/g, '\r\n');
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
return this.toSign(t.key, data) +
|
||||||
|
String.fromCharCode(tag) +
|
||||||
|
openpgp_packet_number_write(bytes.length, 4) +
|
||||||
|
bytes;
|
||||||
|
}
|
||||||
|
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.');
|
||||||
|
|
||||||
|
var bytes = data.key.write();
|
||||||
|
|
||||||
|
return String.fromCharCode(0x99) +
|
||||||
|
openpgp_packet_number_write(bytes.length, 2) +
|
||||||
|
bytes;
|
||||||
|
}
|
||||||
|
case t.key_revocation:
|
||||||
|
case t.subkey_revocation:
|
||||||
|
return this.toSign(t.key, data);
|
||||||
|
case t.timestamp:
|
||||||
|
return '';
|
||||||
|
case t.thrid_party:
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown signature type.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* verifys the signature packet. Note: not signature types are implemented
|
* verifys the signature packet. Note: not signature types are implemented
|
||||||
* @param {String} data data which on the signature applies
|
* @param {String} data data which on the signature applies
|
||||||
|
@ -386,65 +459,7 @@ function openpgp_packet_signature() {
|
||||||
*/
|
*/
|
||||||
this.verify = function(key, data) {
|
this.verify = function(key, data) {
|
||||||
|
|
||||||
var bytes =
|
var bytes = this.toSign(this.signatureType, data);
|
||||||
|
|
||||||
(function(type, data) {
|
|
||||||
switch(type) {
|
|
||||||
case 0: // 0x00: Signature of a binary document.
|
|
||||||
return data.literal.data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // 0x01: Signature of a canonical text document.
|
|
||||||
return data.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
|
|
||||||
|
|
||||||
case 2: // 0x02: Standalone signature.
|
|
||||||
return ''
|
|
||||||
case 16:
|
|
||||||
// 0x10: Generic certification of a User ID and Public-Key packet.
|
|
||||||
case 17:
|
|
||||||
// 0x11: Persona certification of a User ID and Public-Key packet.
|
|
||||||
case 18:
|
|
||||||
// 0x12: Casual certification of a User ID and Public-Key packet.
|
|
||||||
case 19:
|
|
||||||
// 0x13: Positive certification of a User ID and Public-Key packet.
|
|
||||||
case 48:
|
|
||||||
// 0x30: Certification revocation signature
|
|
||||||
|
|
||||||
if(data.userid != undefined) {
|
|
||||||
return String.fromCharCode(0xB4) +
|
|
||||||
openpgp_packet_number_write(data.userid.userid.length, 4) +
|
|
||||||
data;
|
|
||||||
}
|
|
||||||
else if(data.userattribute != undefined) {
|
|
||||||
return String.fromCharCode(0xB4) +
|
|
||||||
openpgp_packet_number_write(data.userattribute.userid.length, 4) +
|
|
||||||
data;
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
case 24:
|
|
||||||
// 0x18: Subkey Binding Signature
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
// 0x19: Primary Key Binding Signature
|
|
||||||
case 31:
|
|
||||||
// 0x1F: Signature directly on a key
|
|
||||||
case 32:
|
|
||||||
// 0x20: Key revocation signature
|
|
||||||
case 40:
|
|
||||||
// 0x28: Subkey revocation signature
|
|
||||||
return;
|
|
||||||
case 64:
|
|
||||||
// 0x40: Timestamp signature.
|
|
||||||
break;
|
|
||||||
case 80:
|
|
||||||
// 0x50: Third-Party Confirmation signature.
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
util.print_error("openpgp.packet.signature.js\n"+
|
|
||||||
"signature verification for type"+
|
|
||||||
this.signatureType+" not implemented");
|
|
||||||
return false;
|
|
||||||
}})(this.signatureType, data);
|
|
||||||
|
|
||||||
// calculating the trailer
|
// calculating the trailer
|
||||||
var trailer = '';
|
var trailer = '';
|
||||||
|
|
|
@ -335,7 +335,8 @@ unittests.register("Packet testing", function() {
|
||||||
|
|
||||||
var verified = key[2].verify(key[0].public_key,
|
var verified = key[2].verify(key[0].public_key,
|
||||||
{
|
{
|
||||||
userid: key[1]
|
userid: key[1],
|
||||||
|
key: key[0].public_key
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user