Skip to content

Commit

Permalink
Add config option to allow insecure decryption with RSA signing keys …
Browse files Browse the repository at this point in the history
…(#1148)
  • Loading branch information
larabr authored Aug 28, 2020
1 parent cc1bdcb commit 2eab8a1
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ export default {
* @property {Boolean} revocations_expire If true, expired revocation signatures are ignored
*/
revocations_expire: false,
/**
* Allow decryption using RSA keys without `encrypt` flag.
* This setting is potentially insecure, but it is needed to get around an old openpgpjs bug
* where key flags were ignored when selecting a key for encryption.
* @memberof module:config
* @property {Boolean} allow_insecure_decryption_with_signing_keys
*/
allow_insecure_decryption_with_signing_keys: false,

/**
* @memberof module:config
Expand Down
6 changes: 6 additions & 0 deletions src/key/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ export function isValidDecryptionKeyPacket(signature) {
if (!signature.verified) { // Sanity check
throw new Error('Signature not verified');
}

if (config.allow_insecure_decryption_with_signing_keys) {
// This is only relevant for RSA keys, all other signing ciphers cannot decrypt
return true;
}

return !signature.keyFlags ||
(signature.keyFlags[0] & enums.keyFlags.encrypt_communication) !== 0 ||
(signature.keyFlags[0] & enums.keyFlags.encrypt_storage) !== 0;
Expand Down
69 changes: 69 additions & 0 deletions test/general/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,55 @@ vqBGKJzmO5q3cECw
=X9kJ
-----END PGP PRIVATE KEY BLOCK-----`;


const rsaSignOnly = `-----BEGIN PGP PRIVATE KEY BLOCK-----
xcLYBF9Gl+MBCACc09O3gjyO0B1ledGxGFSUpPmhhJzkxKoY1WDX8VlASCHz
bAA/BytgYBXHTe7N+N3yJ6uiN3DIQ2j5uGWk/h5jyIOsRuzQxJ40n8AdK/71
SGDCG1X5l1h9vmVTJxkQ3pcOxqRg55EEuJWKN1v7B1hIPxhaM5hgH/7s+PNn
lQddckQJqYkpm9Hy6EI7f9oHrOtWJWZoCHkWZVld7+9ZVPi34ex5ofYOuvNL
AIKZCc7lAiUiDJYQ+hIJRoYwLYhjIshpYoHgNeG4snlupNO32BiwDbHFDjeu
eoBLQ0rxZV7B664ceCmIl+VRht9G20hfGoTjAiop5tyrN1ZeL4EaI+aTABEB
AAEAB/oCKTQnftvHwrkBVlyzSN6tfXylF2551Q3n4CZGg3efI/9PCa9wF58+
WApqmgsUqcNbVnDfl2T58ow05FLMxnFFNnHJq8ltfnXl+gG6c7iy94p79SQE
AGCOL7xNassXrDAQZhqWkCdiLK3b6r9F8Y3URb/AYbWH2BkFkS0oWQDav+Tw
lABt5vG2L5QtnShdqi8CCitcHGEKHocPHp0yAQlp3oAMq09YubgrzESDJ7Pe
l93cT35NlyimAZ6IYk/gumX0/6spqcw7205KfG6P84WlMp3WmE0IUWtiOp+7
rjMjDki0WeVKtuLbHBhOwKvxcILWz+0vQf3uu6aXOKQ3JlsVBADHoXa6QjrT
RmKD9ch65Pkd+EZiKhe+pqqIArVj4QsVBEnaggR59SD8uXhtpyBnvOp3xpof
Vut3SKWl/jmH7vKansFbHOo8xLUyVctu7lCL2/v85FcRJxfPK00MBic+z/vf
mWOAY1VBoi5I9qi6o8vVHA5BJ/xw2uV9VpxfiLG0vwQAyRxHmoZl/OxaZUsm
J9eDYV9xyYumkTCYvHPk9X+ehS+XeYh24z1q9a/1jEnSR3A5XE67UCLaspiA
+Px7nSU1+ftJ9bC2bnRR0Upop+3UkPeCBVp4tYAhsNnPXhSWC0gCgeGU7EmW
DechFg29LId35LXKgmXls9u5yDy2w978Hy0D/jbKZaxNMMwlx/XCFCoBEcXS
DBzg7GHNXdillJqy215j46lfVqOCB3IiffNKjHua2l6fQc0BoiWIZnElMnIa
faEBBSpOVqKhktDFacHa5xChjqXZVyw68qc0I36xkCfcwvYCpNKKkXv90r8A
tRI6gpBLeMJvkL3VkmKd6AZymxFxRGjNEkJvYiA8aW5mb0Bib2IuY29tPsLA
jQQQAQgAIAUCX0aX4wYLCQcIAwIEFQgKAgQWAgEAAhkBAhsDAh4BACEJEAr9
x5ZY6oZmFiEEm+B7p+lshgEOwGGZCv3HlljqhmaUWgf/efmGSpOKIGQ3Kh32
HUqn/4ARvUmqMtZz4xUA9P3GAPY8XwJf00jSQlAo4//3aA1eEOJFHCr2qzCk
/4gIoZEScTTZp4itfL/Fer3UX+bV/VeTNgZGi+MRylSDQxLRQNpRgu+FmRAi
E6fr8D8GMvEcGb0jTRgWGj1EVtfOHfDg+EyPrtw+Z8u/bErUJ+Fnxz+KOGSN
SBQVAOflUYFoQhUNgZiq1s8WFD55sfes3UdBwsmHquDtYGo9dvWLJXxTEF8q
QCyKHYdk25ShIlNpRUqOH3CHqY/38z7QeV7INwtZaQvoES08RlD6ZMtczYLj
BZou86lozq7ISvRg1RSIWZ0ZRA==
=A9Ts
-----END PGP PRIVATE KEY BLOCK-----
`;

const encryptedRsaSignOnly = `-----BEGIN PGP MESSAGE-----
wcBMAwr9x5ZY6oZmAQf+Lxghg4keIFpEq8a65gFkIfW+chHTDPlfI8xnx6U9
HdsICX3Oye5V0ToCVKkEWDxfN1yCfXiYalSNo7ScRZKR7C+j02/pC+FfR6AJ
2cvdFoGIrLaXdjXXc/oXbsCCZA4C1DhQqpdORo2qGF0Q6Sm8659B0CfOgYSL
fBfKQ5VJngUT5JG8Uek3YuXBufPNhzdmXLHyB2Y2CwKkldi2vo4YNAukDhrR
2TojxdNoouhnMm+gloCE1n8huY1vw5F78/uiHen0tmHQ0dxtfk8cc1burgl/
zUdJ3Sg6Eu+OC2ae5II63iB5fG+lCwZtfuepWnePDv8RDKNHCVP/LoBNpGOZ
U9I6AUkZWdcsueib9ghKDDy+HbUbf2kCJWUnuyeOCKqQifDb8bsLmdQY4Wb6
EBeLgD8oZHVsH3NLjPakPw==
=STqy
-----END PGP MESSAGE-----`

function versionSpecificTests() {
it('Preferences of generated key', function() {
const testPref = function(key) {
Expand Down Expand Up @@ -2667,6 +2716,26 @@ describe('Key', function() {
await expect(pubKey.getEncryptionKey()).to.be.rejectedWith('Could not find valid encryption key packet in key c076e634d32b498d');
});

it('should not decrypt using a sign-only RSA key, unless explicitly configured', async function () {
const allowSigningKeyDecryption = openpgp.config.allow_insecure_decryption_with_signing_keys;
const { keys: [key] } = await openpgp.key.readArmored(rsaSignOnly);
try {
openpgp.config.allow_insecure_decryption_with_signing_keys = false;
await expect(openpgp.decrypt({
message: await openpgp.message.readArmored(encryptedRsaSignOnly),
privateKeys: key
})).to.be.rejectedWith(/Session key decryption failed/);

openpgp.config.allow_insecure_decryption_with_signing_keys = true;
await expect(openpgp.decrypt({
message: await openpgp.message.readArmored(encryptedRsaSignOnly),
privateKeys: key
})).to.be.fulfilled;
} finally {
openpgp.config.allow_insecure_decryption_with_signing_keys = allowSigningKeyDecryption;
}
});

it('Method getExpirationTime V4 Key', async function() {
const pubKey = (await openpgp.key.readArmored(twoKeys)).keys[1];
expect(pubKey).to.exist;
Expand Down

0 comments on commit 2eab8a1

Please sign in to comment.