subKey.bindingSignature -> subKey.bindingSignatures[] - process all | #527

This commit is contained in:
Tom James Holub 2017-07-21 21:38:33 -07:00
parent 28abf77a18
commit 2bda12731b

View File

@ -130,7 +130,7 @@ Key.prototype.packetlist2structure = function(packetlist) {
util.print_debug('Dropping subkey binding signature without preceding subkey packet');
continue;
}
subKey.bindingSignature = packetlist[i];
subKey.bindingSignatures.push(packetlist[i]);
break;
case enums.signature.key_revocation:
this.revocationSignature = packetlist[i];
@ -903,7 +903,7 @@ function SubKey(subKeyPacket) {
return new SubKey(subKeyPacket);
}
this.subKey = subKeyPacket;
this.bindingSignature = null;
this.bindingSignatures = [];
this.revocationSignature = null;
}
@ -915,7 +915,9 @@ SubKey.prototype.toPacketlist = function() {
var packetlist = new packet.List();
packetlist.push(this.subKey);
packetlist.push(this.revocationSignature);
packetlist.push(this.bindingSignature);
for(var i = 0; i < this.bindingSignatures.length; i++) {
packetlist.push(this.bindingSignatures[i]);
}
return packetlist;
};
@ -925,8 +927,15 @@ SubKey.prototype.toPacketlist = function() {
* @return {Boolean}
*/
SubKey.prototype.isValidEncryptionKey = function(primaryKey) {
return this.verify(primaryKey) === enums.keyStatus.valid &&
isValidEncryptionKeyPacket(this.subKey, this.bindingSignature);
if(this.verify(primaryKey) !== enums.keyStatus.valid) {
return false;
}
for(var i = 0; i < this.bindingSignatures.length; i++) {
if(isValidEncryptionKeyPacket(this.subKey, this.bindingSignatures[i])) {
return true;
}
}
return false;
};
/**
@ -935,8 +944,15 @@ SubKey.prototype.isValidEncryptionKey = function(primaryKey) {
* @return {Boolean}
*/
SubKey.prototype.isValidSigningKey = function(primaryKey) {
return this.verify(primaryKey) === enums.keyStatus.valid &&
isValidSigningKeyPacket(this.subKey, this.bindingSignature);
if(this.verify(primaryKey) !== enums.keyStatus.valid) {
return false;
}
for(var i = 0; i < this.bindingSignatures.length; i++) {
if(isValidSigningKeyPacket(this.subKey, this.bindingSignatures[i])) {
return true;
}
}
return false;
};
/**
@ -956,24 +972,39 @@ SubKey.prototype.verify = function(primaryKey) {
Date.now() > (this.subKey.created.getTime() + this.subKey.expirationTimeV3*24*3600*1000)) {
return enums.keyStatus.expired;
}
// check subkey binding signature
if (!this.bindingSignature) {
return enums.keyStatus.invalid;
// check subkey binding signatures (at least one valid binding sig needed)
for(var i = 0; i < this.bindingSignatures.length; i++) {
var isLast = (i === this.bindingSignatures.length - 1);
var sig = this.bindingSignatures[i];
// check binding signature is not expired
if(sig.isExpired()) {
if(isLast) {
return enums.keyStatus.expired; // last expired binding signature
} else {
continue;
}
}
// check binding signature can verify
if (!(sig.verified || sig.verify(primaryKey, {key: primaryKey, bind: this.subKey}))) {
if(isLast) {
return enums.keyStatus.invalid; // last invalid binding signature
} else {
continue;
}
}
// check V4 expiration time
if (this.subKey.version === 4) {
if(sig.keyNeverExpires === false && Date.now() > (this.subKey.created.getTime() + sig.keyExpirationTime*1000)) {
if(isLast) {
return enums.keyStatus.expired; // last V4 expired binding signature
} else {
continue;
}
}
}
return enums.keyStatus.valid; // found a binding signature that passed all checks
}
if (this.bindingSignature.isExpired()) {
return enums.keyStatus.expired;
}
if (!(this.bindingSignature.verified ||
this.bindingSignature.verify(primaryKey, {key: primaryKey, bind: this.subKey}))) {
return enums.keyStatus.invalid;
}
// check V4 expiration time
if (this.subKey.version === 4 &&
this.bindingSignature.keyNeverExpires === false &&
Date.now() > (this.subKey.created.getTime() + this.bindingSignature.keyExpirationTime*1000)) {
return enums.keyStatus.expired;
}
return enums.keyStatus.valid;
return enums.keyStatus.invalid; // no binding signatures to check
};
/**
@ -981,7 +1012,17 @@ SubKey.prototype.verify = function(primaryKey) {
* @return {Date|null}
*/
SubKey.prototype.getExpirationTime = function() {
return getExpirationTime(this.subKey, this.bindingSignature);
var highest;
for(var i = 0; i < this.bindingSignatures.length; i++) {
var current = getExpirationTime(this.subKey, this.bindingSignatures[i]);
if(current === null) {
return null;
}
if(!highest || current > highest) {
highest = current;
}
}
return highest;
};
/**
@ -1001,11 +1042,14 @@ SubKey.prototype.update = function(subKey, primaryKey) {
subKey.subKey.tag === enums.packet.secretSubkey) {
this.subKey = subKey.subKey;
}
// binding signature
if (!this.bindingSignature && subKey.bindingSignature &&
(subKey.bindingSignature.verified ||
subKey.bindingSignature.verify(primaryKey, {key: primaryKey, bind: this.subKey}))) {
this.bindingSignature = subKey.bindingSignature;
// update missing binding signatures
if(this.bindingSignatures.length < subKey.bindingSignatures.length) {
for(var i = this.bindingSignatures.length; i < subKey.bindingSignatures.length; i++) {
var newSig = subKey.bindingSignatures[i];
if (newSig.verified || newSig.verify(primaryKey, {key: primaryKey, bind: this.subKey})) {
this.bindingSignatures.push(newSig);
}
}
}
// revocation signature
if (!this.revocationSignature && subKey.revocationSignature && !subKey.revocationSignature.isExpired() &&