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