Skip to content

Commit

Permalink
Merge pull request #637 from mmso/feat/compression
Browse files Browse the repository at this point in the history
Feat/compression
  • Loading branch information
Bart Butler committed Feb 13, 2018
2 parents 90337de + 8873ed0 commit a09066e
Show file tree
Hide file tree
Showing 6 changed files with 864 additions and 715 deletions.
29 changes: 29 additions & 0 deletions README.md
Expand Up @@ -154,6 +154,35 @@ openpgp.decrypt(options).then(function(plaintext) {
});
```

#### Encrypt with compression

By default, `encrypt` will not use any compression. It's possible to override that behavior in two ways:

Either set the `compression` parameter in the options object when calling `encrypt`.

```js
var options, encrypted;

options = {
data: new Uint8Array([0x01, 0x02, 0x03]), // input as Uint8Array (or String)
passwords: ['secret stuff'], // multiple passwords possible
compression: openpgp.enums.compression.zip // compress the data with zip
};

openpgp.encrypt(options).then(function(ciphertext) {
// use ciphertext
});
```

Or, override the config to enable compression:

```js
openpgp.config.compression = openpgp.enums.compression.zip
```

Where `compression` can take the value of `openpgp.enums.compression.zlib` or `openpgp.enums.compression.zip`.


#### Generate new key pair

RSA keys:
Expand Down
2 changes: 1 addition & 1 deletion src/config/config.js
Expand Up @@ -31,7 +31,7 @@ export default {
/** @property {Integer} encryption_cipher Default encryption cipher {@link module:enums.symmetric} */
encryption_cipher: enums.symmetric.aes256,
/** @property {Integer} compression Default compression algorithm {@link module:enums.compression} */
compression: enums.compression.zip,
compression: enums.compression.uncompressed,

/**
* Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption.
Expand Down
20 changes: 20 additions & 0 deletions src/message.js
Expand Up @@ -451,6 +451,26 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) {
return new Message(packetlist);
};

/**
* Compresses the message (the literal and -if signed- signature data packets of the message)
* @param {module:enums.compression} compression compression algorithm to be used
* @return {module:message~Message} new message with compressed content
*/
Message.prototype.compress = function(compression) {
if (compression === enums.compression.uncompressed) {
return this;
}

const compressed = new packet.Compressed();
compressed.packets = this.packets;
compressed.algorithm = enums.read(enums.compression, compression);

const packetList = new packet.List();
packetList.push(compressed);

return new Message(packetList);
};

/**
* Create a detached signature for the message (the literal data packet of the message)
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
Expand Down
32 changes: 17 additions & 15 deletions src/openpgp.js
Expand Up @@ -186,23 +186,24 @@ export function decryptKey({ privateKey, passphrase }) {
/**
* Encrypts message text/data with public keys, passwords or both at once. At least either public keys or passwords
* must be specified. If private keys are specified, those will be used to sign the message.
* @param {String|Uint8Array} data text/data to be encrypted as JavaScript binary string or Uint8Array
* @param {Key|Array<Key>} publicKeys (optional) array of keys or single key, used to encrypt the message
* @param {Key|Array<Key>} privateKeys (optional) private keys for signing. If omitted message will not be signed
* @param {String|Array<String>} passwords (optional) array of passwords or a single password to encrypt the message
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} filename (optional) a filename for the literal data packet
* @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @return {Promise<Object>} encrypted (and optionally signed message) in the form:
* {data: ASCII armored message if 'armor' is true,
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
* @param {String|Uint8Array} data text/data to be encrypted as JavaScript binary string or Uint8Array
* @param {Key|Array<Key>} publicKeys (optional) array of keys or single key, used to encrypt the message
* @param {Key|Array<Key>} privateKeys (optional) private keys for signing. If omitted message will not be signed
* @param {String|Array<String>} passwords (optional) array of passwords or a single password to encrypt the message
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} filename (optional) a filename for the literal data packet
* @param {module:enums.compression} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config
* @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @return {Promise<Object>} encrypted (and optionally signed message) in the form:
* {data: ASCII armored message if 'armor' is true,
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
* @static
*/
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false}) {
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, compression=config.compression, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false}) {
checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords);

if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
Expand All @@ -223,6 +224,7 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey,
message = await message.sign(privateKeys, signature);
}
}
message = message.compress(compression);
return message.encrypt(publicKeys, passwords, sessionKey, wildcard);

}).then(encrypted => {
Expand Down
2 changes: 1 addition & 1 deletion src/packet/compressed.js
Expand Up @@ -88,7 +88,7 @@ Compressed.prototype.write = function () {
this.compress();
}

return util.concatUint8Array(new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed);
return util.concatUint8Array([new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed]);
};


Expand Down

0 comments on commit a09066e

Please sign in to comment.