Skip to content

Commit

Permalink
fix: save generated cipher params in ChannelOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ttypic committed Sep 28, 2023
1 parent da5406f commit 188541d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 14 deletions.
4 changes: 2 additions & 2 deletions lib/src/main/java/io/ably/lib/types/BaseMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public void decode(ChannelOptions opts, DecodingContext context) throws Message
case "cipher":
if(opts != null && opts.encrypted) {
try {
DecryptingChannelCipher cipher = Crypto.createChannelDecipher(opts);
DecryptingChannelCipher cipher = Crypto.createChannelDecipher(opts.getCipherParamsOrDefault());
data = cipher.decrypt((byte[]) data);
} catch(AblyException e) {
throw MessageDecodeException.fromDescription(e.errorInfo.message);
Expand Down Expand Up @@ -196,7 +196,7 @@ public void encode(ChannelOptions opts) throws AblyException {
}
}
if (opts != null && opts.encrypted) {
EncryptingChannelCipher cipher = Crypto.createChannelEncipher(opts);
EncryptingChannelCipher cipher = Crypto.createChannelEncipher(opts.getCipherParamsOrDefault());
data = cipher.encrypt((byte[]) data);
encoding = ((encoding == null) ? "" : encoding + "/") + "cipher+" + cipher.getAlgorithm();
}
Expand Down
12 changes: 12 additions & 0 deletions lib/src/main/java/io/ably/lib/types/ChannelOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import io.ably.lib.util.Base64Coder;
import io.ably.lib.util.Crypto;
import io.ably.lib.util.Crypto.CipherParams;

/**
* Passes additional properties to a {@link io.ably.lib.rest.Channel} or {@link io.ably.lib.realtime.Channel} object,
Expand Down Expand Up @@ -105,4 +106,15 @@ public static ChannelOptions withCipherKey(byte[] key) throws AblyException {
public static ChannelOptions withCipherKey(String base64Key) throws AblyException {
return withCipherKey(Base64Coder.decode(base64Key));
}

/**
* Internal; returns cipher params or generate default
*/
public synchronized CipherParams getCipherParamsOrDefault() throws AblyException {
CipherParams params = Crypto.checkCipherParams(this.cipherParams);
if (this.cipherParams == null) {
this.cipherParams = params;
}
return params;
}
}
13 changes: 8 additions & 5 deletions lib/src/main/java/io/ably/lib/util/Crypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,21 @@ public interface DecryptingChannelCipher {
/**
* Internal; get an encrypting cipher instance based on the given channel options.
*/
public static EncryptingChannelCipher createChannelEncipher(final Object cipherParams) throws AblyException {
return new EncryptingCBCCipher(checkCipherParams(cipherParams));
public static EncryptingChannelCipher createChannelEncipher(final CipherParams cipherParams) throws AblyException {
return new EncryptingCBCCipher(cipherParams);
}

/**
* Internal; get a decrypting cipher instance based on the given channel options.
*/
public static DecryptingChannelCipher createChannelDecipher(final Object cipherParams) throws AblyException {
return new DecryptingCBCCipher(checkCipherParams(cipherParams));
public static DecryptingChannelCipher createChannelDecipher(final CipherParams cipherParams) throws AblyException {
return new DecryptingCBCCipher(cipherParams);
}

private static CipherParams checkCipherParams(final Object cipherParams) throws AblyException {
/**
* Internal; if `cipherParams` is null returns default params otherwise check if params valid and returns them
*/
public static CipherParams checkCipherParams(final Object cipherParams) throws AblyException {
if (null == cipherParams) {
return Crypto.getDefaultParams();
} else if (cipherParams instanceof CipherParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ public void single_send_256() {
final CipherParams params = Crypto.getDefaultParams(key);

/* create a channel */
ChannelOptions channelOpts = new ChannelOptions() {{ encrypted = true; this.cipherParams = params; }};
ChannelOptions channelOpts = new ChannelOptions();
channelOpts.encrypted = true;
channelOpts.cipherParams = params;
final Channel channel = ably.channels.get(channelName, channelOpts);

/* attach */
Expand Down Expand Up @@ -276,9 +278,16 @@ public void single_send_binary_text() {
final CipherParams params = Crypto.getDefaultParams();

/* create a channel */
final ChannelOptions senderChannelOpts = new ChannelOptions() {{ encrypted = true; cipherParams = params; }};
final ChannelOptions senderChannelOpts = new ChannelOptions();
senderChannelOpts.encrypted = true;
senderChannelOpts.cipherParams = params;

final Channel senderChannel = sender.channels.get(channelName, senderChannelOpts);
final ChannelOptions receiverChannelOpts = new ChannelOptions() {{ encrypted = true; cipherParams = params; }};

final ChannelOptions receiverChannelOpts = new ChannelOptions();
receiverChannelOpts.encrypted = true;
receiverChannelOpts.cipherParams = params;

final Channel receiverChannel = receiver.channels.get(channelName, receiverChannelOpts);

/* attach */
Expand Down Expand Up @@ -570,9 +579,14 @@ public void set_cipher_params() {
final CipherParams params1 = Crypto.getDefaultParams();

/* create a channel */
ChannelOptions senderChannelOpts = new ChannelOptions() {{ encrypted = true; cipherParams = params1; }};
ChannelOptions senderChannelOpts = new ChannelOptions();
senderChannelOpts.encrypted = true;
senderChannelOpts.cipherParams = params1;
final Channel senderChannel = sender.channels.get("set_cipher_params", senderChannelOpts);
ChannelOptions receiverChannelOpts = new ChannelOptions() {{ encrypted = true; cipherParams = params1; }};

ChannelOptions receiverChannelOpts = new ChannelOptions();
receiverChannelOpts.encrypted = true;
receiverChannelOpts.cipherParams = params1;
final Channel receiverChannel = receiver.channels.get("set_cipher_params", receiverChannelOpts);

/* attach */
Expand Down
9 changes: 7 additions & 2 deletions lib/src/test/java/io/ably/lib/util/CryptoMessageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ public void testDecrypt() throws NoSuchAlgorithmException, CloneNotSupportedExce
final String algorithm = testData.algorithm;

final CipherParams params = Crypto.getParams(algorithm, fixtureSet.key, fixtureSet.iv);
final ChannelOptions options = new ChannelOptions() {{encrypted = true; cipherParams = params;}};
final ChannelOptions options = new ChannelOptions();
options.encrypted = true;
options.cipherParams = params;

for(final CryptoTestItem item : testData.items) {
final Message plain = item.encoded;
Expand Down Expand Up @@ -116,7 +118,10 @@ public void testEncrypt() throws NoSuchAlgorithmException, CloneNotSupportedExce
final CipherParams params = Crypto.getParams(algorithm, fixtureSet.key, fixtureSet.iv);

for(final CryptoTestItem item : testData.items) {
final ChannelOptions options = new ChannelOptions() {{encrypted = true; cipherParams = params;}};
final ChannelOptions options = new ChannelOptions();
options.encrypted = true;
options.cipherParams = params;

final Message plain = item.encoded;
final Message encrypted = item.encrypted;
assertThat(encrypted.encoding, endsWith(fixtureSet.cipherName + "/base64"));
Expand Down

0 comments on commit 188541d

Please sign in to comment.