Key revocation
This commit is contained in:
parent
1bb86231af
commit
a3484c3116
17
src/enums.js
17
src/enums.js
|
@ -428,6 +428,23 @@ export default {
|
|||
signature: 6
|
||||
},
|
||||
|
||||
/** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
|
||||
* @enum {Integer}
|
||||
* @readonly
|
||||
*/
|
||||
reasonForRevocation: {
|
||||
/** No reason specified (key revocations or cert revocations) */
|
||||
no_reason: 0,
|
||||
/** Key is superseded (key revocations) */
|
||||
key_superseded: 1,
|
||||
/** Key material has been compromised (key revocations) */
|
||||
key_compromised: 2,
|
||||
/** Key is retired and no longer used (key revocations) */
|
||||
key_retired: 3,
|
||||
/** User ID information is no longer valid (cert revocations) */
|
||||
userid_invalid: 32
|
||||
},
|
||||
|
||||
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
|
||||
* @enum {Integer}
|
||||
* @readonly
|
||||
|
|
43
src/key.js
43
src/key.js
|
@ -624,9 +624,45 @@ async function mergeSignatures(source, dest, attr, checkFn) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
Key.prototype.revoke = function() {
|
||||
|
||||
/**
|
||||
* Revokes the key
|
||||
* @param {module:key~Key} privateKey decrypted private key for revocation
|
||||
* @param {Object} reasonForRevocation optional, object indicating the reason for revocation
|
||||
* @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
|
||||
* @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
|
||||
* @param {Date} date optional, override the creationtime of the revocation signature
|
||||
* @return {module:key~Key} new key with revocation signature
|
||||
*/
|
||||
Key.prototype.revoke = async function(privateKey, {
|
||||
flag: reasonForRevocationFlag=enums.reasonForRevocation.no_reason,
|
||||
string: reasonForRevocationString=''
|
||||
} = {}, date=new Date()) {
|
||||
if (privateKey.isPublic()) {
|
||||
throw new Error('Need private key for revoking');
|
||||
}
|
||||
if (privateKey.primaryKey.getFingerprint() !== this.primaryKey.getFingerprint()) {
|
||||
throw new Error('Private key does not match public key');
|
||||
}
|
||||
await privateKey.verifyPrimaryUser();
|
||||
const signingKeyPacket = privateKey.getSigningKeyPacket();
|
||||
if (!signingKeyPacket) {
|
||||
throw new Error(`Could not find valid signing key packet in key ${
|
||||
privateKey.primaryKey.getKeyId().toHex()}`);
|
||||
}
|
||||
if (!signingKeyPacket.isDecrypted) {
|
||||
throw new Error('Private key is not decrypted.');
|
||||
}
|
||||
const dataToSign = { key: this.primaryKey };
|
||||
const signaturePacket = new packet.Signature(date);
|
||||
signaturePacket.signatureType = enums.write(enums.signature, enums.signature.key_revocation);
|
||||
signaturePacket.reasonForRevocationFlag = enums.write(enums.reasonForRevocation, reasonForRevocationFlag);
|
||||
signaturePacket.reasonForRevocationString = reasonForRevocationString;
|
||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
|
||||
await signaturePacket.sign(signingKeyPacket, dataToSign);
|
||||
const key = new Key(this.toPacketlist());
|
||||
key.revocationSignature = signaturePacket;
|
||||
return key;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -768,7 +804,6 @@ User.prototype.sign = async function(primaryKey, privateKeys) {
|
|||
signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data];
|
||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey);
|
||||
signaturePacket.signingKeyId = signingKeyPacket.getKeyId();
|
||||
signaturePacket.sign(signingKeyPacket, dataToSign);
|
||||
return signaturePacket;
|
||||
}));
|
||||
|
|
|
@ -50,6 +50,71 @@ describe('Key', function() {
|
|||
});
|
||||
|
||||
function tests() {
|
||||
const priv_key_arm2 =
|
||||
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
'',
|
||||
'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',
|
||||
'=lw5e',
|
||||
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||
|
||||
const pub_key_arm2 =
|
||||
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
'',
|
||||
'mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+',
|
||||
'fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5',
|
||||
'GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0',
|
||||
'JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS',
|
||||
'YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6',
|
||||
'AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki',
|
||||
'Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf',
|
||||
'9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa',
|
||||
'JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag',
|
||||
'Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr',
|
||||
'woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb',
|
||||
'LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA',
|
||||
'SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP',
|
||||
'GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2',
|
||||
'bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X',
|
||||
'W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD',
|
||||
'AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY',
|
||||
'hz3tYjKhoFTKEIq3y3Pp',
|
||||
'=h/aX',
|
||||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||
|
||||
const twoKeys =
|
||||
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
|
@ -1172,6 +1237,11 @@ const mergeKey2 = '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
|
|||
done();
|
||||
});
|
||||
|
||||
it('Verify status of revoked primary key', function(done) {
|
||||
const pubKey = openpgp.key.readArmored(pub_revoked).keys[0];
|
||||
expect(pubKey.verifyPrimaryKey()).to.eventually.equal(openpgp.enums.keyStatus.revoked).notify(done);
|
||||
});
|
||||
|
||||
it('Verify status of revoked subkey', function(done) {
|
||||
const pubKeys = openpgp.key.readArmored(pub_sig_test);
|
||||
expect(pubKeys).to.exist;
|
||||
|
@ -1359,6 +1429,25 @@ const mergeKey2 = '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
|
|||
});
|
||||
});
|
||||
|
||||
it('revoke() - primary key', function(done) {
|
||||
const pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
|
||||
const privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
||||
privKey.decrypt('hello world');
|
||||
|
||||
pubKey.revoke(privKey, {
|
||||
flag: openpgp.enums.reasonForRevocation.key_retired,
|
||||
string: 'Testing key revocation'
|
||||
}).then(revKey => {
|
||||
expect(revKey.revocationSignature).to.exist;
|
||||
expect(revKey.revocationSignature.signatureType).to.equal(openpgp.enums.signature.key_revocation);
|
||||
expect(revKey.revocationSignature.reasonForRevocationFlag).to.equal(openpgp.enums.reasonForRevocation.key_retired);
|
||||
expect(revKey.revocationSignature.reasonForRevocationString).to.equal('Testing key revocation');
|
||||
|
||||
expect(pubKey.verifyPrimaryKey()).to.eventually.equal(openpgp.enums.keyStatus.valid);
|
||||
expect(revKey.verifyPrimaryKey()).to.eventually.equal(openpgp.enums.keyStatus.revoked).notify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it("getPreferredAlgo('symmetric') - one key - AES256", async function() {
|
||||
const key1 = openpgp.key.readArmored(twoKeys).keys[0];
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('symmetric', [key1]);
|
||||
|
|
Loading…
Reference in New Issue
Block a user