Skip to content

Commit

Permalink
Used new CryptoModule from kotlin SDK. (#280)
Browse files Browse the repository at this point in the history
fix: Improve security of crypto implementation. 

Improved security of crypto implementation by adding enhanced AES-CBC cryptor

feat: Add crypto module

Add crypto module that allows configure SDK to encrypt and decrypt messages. 

---------

Co-authored-by: PubNub Release Bot <[email protected]>
  • Loading branch information
marcin-cebo and pubnub-release-bot authored Oct 16, 2023
1 parent 5e5e061 commit 6feef15
Show file tree
Hide file tree
Showing 43 changed files with 2,486 additions and 315 deletions.
19 changes: 13 additions & 6 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: java
version: 6.3.6
version: 6.4.0
schema: 1
scm: github.com/pubnub/java
files:
- build/libs/pubnub-gson-6.3.6-all.jar
- build/libs/pubnub-gson-6.4.0-all.jar
sdks:
-
type: library
Expand All @@ -23,8 +23,8 @@ sdks:
-
distribution-type: library
distribution-repository: GitHub
package-name: pubnub-gson-6.3.6
location: https://github.com/pubnub/java/releases/download/v6.3.6/pubnub-gson-6.3.6-all.jar
package-name: pubnub-gson-6.4.0
location: https://github.com/pubnub/java/releases/download/v6.4.0/pubnub-gson-6.4.0-all.jar
supported-platforms:
supported-operating-systems:
Android:
Expand Down Expand Up @@ -135,8 +135,8 @@ sdks:
-
distribution-type: library
distribution-repository: maven
package-name: pubnub-gson-6.3.6
location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-gson/6.3.6/pubnub-gson-6.3.6.jar
package-name: pubnub-gson-6.4.0
location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-gson/6.4.0/pubnub-gson-6.4.0.jar
supported-platforms:
supported-operating-systems:
Android:
Expand Down Expand Up @@ -234,6 +234,13 @@ sdks:
is-required: Required

changelog:
- date: 2023-10-16
version: v6.4.0
changes:
- type: feature
text: "Add crypto module that allows configure SDK to encrypt and decrypt messages."
- type: bug
text: "Improved security of crypto implementation by adding enhanced AES-CBC cryptor."
- date: 2023-06-19
version: v6.3.6
changes:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## v6.4.0
October 16 2023

#### Added
- Add crypto module that allows configure SDK to encrypt and decrypt messages.

#### Fixed
- Improved security of crypto implementation by adding enhanced AES-CBC cryptor.

## v6.3.6
June 19 2023

Expand Down
48 changes: 25 additions & 23 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
Copyright (c) 2013 PubNub Inc.
http://www.pubnub.com/
http://www.pubnub.com/terms
PubNub Software Development Kit License Agreement
Copyright © 2023 PubNub Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Subject to the terms and conditions of the license, you are hereby granted
a non-exclusive, worldwide, royalty-free license to (a) copy and modify
the software in source code or binary form for use with the software services
and interfaces provided by PubNub, and (b) redistribute unmodified copies
of the software to third parties. The software may not be incorporated in
or used to provide any product or service competitive with the products
and services of PubNub.

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this license shall be included
in or with all copies or substantial portions of the software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This license does not grant you permission to use the trade names, trademarks,
service marks, or product names of PubNub, except as required for reasonable
and customary use in describing the origin of the software and reproducing
the content of this license.

PubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks
Copyright (c) 2013 PubNub Inc.
http://www.pubnub.com/
http://www.pubnub.com/terms
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL PUBNUB OR THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

https://www.pubnub.com/
https://www.pubnub.com/terms
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ You will need the publish and subscribe keys to authenticate your app. Get your
<dependency>
<groupId>com.pubnub</groupId>
<artifactId>pubnub-gson</artifactId>
<version>6.3.6</version>
<version>6.4.0</version>
</dependency>
```

* for Gradle, add the following dependency in your `gradle.build`:
```groovy
implementation 'com.pubnub:pubnub-gson:6.3.6'
implementation 'com.pubnub:pubnub-gson:6.4.0'
```

2. Configure your keys:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
}
group = 'com.pubnub'

version = '6.3.6'
version = '6.4.0'

description = """"""

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ SONATYPE_HOST=DEFAULT
SONATYPE_AUTOMATIC_RELEASE=true
GROUP=com.pubnub
POM_ARTIFACT_ID=pubnub-gson
VERSION_NAME=6.3.6
VERSION_NAME=6.4.0
POM_PACKAGING=jar

POM_NAME=PubNub Java SDK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.pubnub.api.PubNub;
import com.pubnub.api.PubNubException;
import com.pubnub.api.crypto.CryptoModule;
import com.pubnub.api.integration.util.BaseIntegrationTest;
import com.pubnub.api.integration.util.RandomGenerator;
import com.pubnub.api.models.consumer.PNPublishResult;
Expand Down Expand Up @@ -312,12 +313,10 @@ public void testFetchSingleChannel_OverflowLimit() throws PubNubException {
@Test
public void testHistorySingleChannel_IncludeAll_Crypto() throws PubNubException {
final String expectedCipherKey = random();
pubNub.getConfiguration().setCipherKey(expectedCipherKey);
pubNub.getConfiguration().setCryptoModule(CryptoModule.createLegacyCryptoModule(expectedCipherKey, true));

final PubNub observer = getPubNub();
observer.getConfiguration().setCipherKey(expectedCipherKey);

assertEquals(pubNub.getConfiguration().getCipherKey(), observer.getConfiguration().getCipherKey());
observer.getConfiguration().setCryptoModule(CryptoModule.createLegacyCryptoModule(expectedCipherKey, true));

final String expectedChannelName = random();
final int expectedMessageCount = 10;
Expand All @@ -343,12 +342,11 @@ public void testHistorySingleChannel_IncludeAll_Crypto() throws PubNubException
@Test
public void testFetchSingleChannel_IncludeAll_Crypto() throws PubNubException {
final String expectedCipherKey = random();
pubNub.getConfiguration().setCipherKey(expectedCipherKey);
pubNub.getConfiguration().setCryptoModule(CryptoModule.createLegacyCryptoModule(expectedCipherKey, false));

final PubNub observer = getPubNub();
observer.getConfiguration().setCipherKey(expectedCipherKey);
observer.getConfiguration().setCryptoModule(CryptoModule.createLegacyCryptoModule(expectedCipherKey, false));

assertEquals(pubNub.getConfiguration().getCipherKey(), observer.getConfiguration().getCipherKey());

final String expectedChannelName = random();
final int expectedMessageCount = 10;
Expand Down Expand Up @@ -379,7 +377,7 @@ public void testFetchSingleChannel_WithActions_IncludeAll_Crypto() throws PubNub
final PubNub observer = getPubNub();
observer.getConfiguration().setCipherKey(expectedCipherKey);

assertEquals(pubNub.getConfiguration().getCipherKey(), observer.getConfiguration().getCipherKey());
assertEquals(pubNub.getConfiguration().getCipherKey(), observer.getConfiguration().getCipherKey()); //todo

final String expectedChannelName = random();
final int expectedMessageCount = 10;
Expand Down
39 changes: 34 additions & 5 deletions src/main/java/com/pubnub/api/PNConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.pubnub.api;


import com.pubnub.api.crypto.CryptoModule;
import com.pubnub.api.enums.PNHeartbeatNotificationOptions;
import com.pubnub.api.enums.PNLogVerbosity;
import com.pubnub.api.enums.PNReconnectionPolicy;
Expand Down Expand Up @@ -94,9 +95,40 @@ public class PNConfiguration {
*/
private String publishKey;
private String secretKey;
private String cipherKey;
private String authKey;


/**
* @deprecated Use {@link #cryptoModule} instead.
*/
@Deprecated
private String cipherKey;

/**
* @deprecated Use {@link #cryptoModule} instead.
*/
@Deprecated
private boolean useRandomInitializationVector;

/**
* CryptoModule is responsible for handling encryption and decryption.
* If set, all communications to and from PubNub will be encrypted.
*/
private CryptoModule cryptoModule;

public CryptoModule getCryptoModule() {
if (cryptoModule != null) {
return cryptoModule;
} else {
if (cipherKey != null && !cipherKey.isEmpty()) {
log.warning("cipherKey is deprecated. Use CryptoModule instead");
return CryptoModule.createLegacyCryptoModule(cipherKey, useRandomInitializationVector);
} else {
return null;
}
}
}

/**
* @deprecated Use {@link #getUserId()} instead.
*/
Expand All @@ -110,7 +142,7 @@ public void setUuid(@NotNull String uuid) {
this.uuid = uuid;
}

public UserId getUserId() {
public UserId getUserId() {
return new UserId(this.uuid);
}

Expand Down Expand Up @@ -210,9 +242,6 @@ public void setUserId(@NotNull UserId userId) {
private boolean dedupOnSubscribe;
@Setter
private Integer maximumMessagesCacheSize;
@Setter
private boolean useRandomInitializationVector;

@Setter
private int fileMessagePublishRetryLimit;

Expand Down
49 changes: 35 additions & 14 deletions src/main/java/com/pubnub/api/PubNub.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.pubnub.api.builder.SubscribeBuilder;
import com.pubnub.api.builder.UnsubscribeBuilder;
import com.pubnub.api.callbacks.SubscribeCallback;
import com.pubnub.api.crypto.CryptoModule;
import com.pubnub.api.crypto.CryptoModuleKt;
import com.pubnub.api.endpoints.DeleteMessages;
import com.pubnub.api.endpoints.FetchMessages;
import com.pubnub.api.endpoints.History;
Expand Down Expand Up @@ -68,8 +70,6 @@
import com.pubnub.api.managers.token_manager.TokenManager;
import com.pubnub.api.managers.token_manager.TokenParser;
import com.pubnub.api.models.consumer.access_manager.v3.PNToken;
import com.pubnub.api.vendor.Crypto;
import com.pubnub.api.vendor.FileEncryptionUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -105,12 +105,16 @@ public class PubNub {
private static final int TIMESTAMP_DIVIDER = 1000;
private static final int MAX_SEQUENCE = 65535;

private static final String SDK_VERSION = "6.3.6";
private static final String SDK_VERSION = "6.4.0";
private final ListenerManager listenerManager;
private final StateManager stateManager;

private final TokenManager tokenManager;

public CryptoModule getCryptoModule() {
return configuration.getCryptoModule();
}

public PubNub(@NotNull PNConfiguration initialConfig) {
this.configuration = initialConfig;
this.mapper = new MapperManager();
Expand Down Expand Up @@ -456,8 +460,7 @@ public String decrypt(String inputString) throws PubNubException {
if (inputString == null) {
throw PubNubException.builder().pubnubError(PubNubErrorBuilder.PNERROBJ_INVALID_ARGUMENTS).build();
}

return decrypt(inputString, this.getConfiguration().getCipherKey());
return decrypt(inputString, null);
}

/**
Expand All @@ -473,16 +476,33 @@ public String decrypt(String inputString, String cipherKey) throws PubNubExcepti
if (inputString == null) {
throw PubNubException.builder().pubnubError(PubNubErrorBuilder.PNERROBJ_INVALID_ARGUMENTS).build();
}
boolean dynamicIV = this.getConfiguration().isUseRandomInitializationVector();
return new Crypto(cipherKey, dynamicIV).decrypt(inputString);
CryptoModule cryptoModule = getCryptoModuleOrThrow(cipherKey);

return CryptoModuleKt.decryptString(cryptoModule, inputString);
}

private CryptoModule getCryptoModuleOrThrow(String cipherKey) throws PubNubException {
CryptoModule effectiveCryptoModule;
if (cipherKey != null) {
effectiveCryptoModule = CryptoModule.createLegacyCryptoModule(cipherKey, this.getConfiguration().isUseRandomInitializationVector());
} else {
CryptoModule cryptoModule = getCryptoModule();
if (cryptoModule != null) {
effectiveCryptoModule = cryptoModule;
} else {
throw PubNubException.builder().errormsg("Crypto module is not initialized").build();
}
}
return effectiveCryptoModule;
}

public InputStream decryptInputStream(InputStream inputStream) throws PubNubException {
return decryptInputStream(inputStream, this.getConfiguration().getCipherKey());
return decryptInputStream(inputStream, null);
}

public InputStream decryptInputStream(InputStream inputStream, String cipherKey) throws PubNubException {
return FileEncryptionUtil.decrypt(cipherKey, inputStream);
CryptoModule cryptoModule = getCryptoModuleOrThrow(cipherKey);
return cryptoModule.decryptStream(inputStream);
}

/**
Expand All @@ -497,7 +517,7 @@ public String encrypt(String inputString) throws PubNubException {
throw PubNubException.builder().pubnubError(PubNubErrorBuilder.PNERROBJ_INVALID_ARGUMENTS).build();
}

return encrypt(inputString, this.getConfiguration().getCipherKey());
return encrypt(inputString, null);
}

/**
Expand All @@ -514,16 +534,17 @@ public String encrypt(String inputString, String cipherKey) throws PubNubExcepti
throw PubNubException.builder().pubnubError(PubNubErrorBuilder.PNERROBJ_INVALID_ARGUMENTS).build();
}

boolean dynamicIV = this.getConfiguration().isUseRandomInitializationVector();
return new Crypto(cipherKey, dynamicIV).encrypt(inputString);
CryptoModule cryptoModule = getCryptoModuleOrThrow(cipherKey);
return CryptoModuleKt.encryptString(cryptoModule, inputString);
}

public InputStream encryptInputStream(InputStream inputStream) throws PubNubException {
return encryptInputStream(inputStream, this.getConfiguration().getCipherKey());
return encryptInputStream(inputStream, null);
}

public InputStream encryptInputStream(InputStream inputStream, String cipherKey) throws PubNubException {
return FileEncryptionUtil.encrypt(cipherKey, inputStream);
CryptoModule cryptoModule = getCryptoModuleOrThrow(cipherKey);
return cryptoModule.encryptStream(inputStream);
}

public int getTimestamp() {
Expand Down
Loading

0 comments on commit 6feef15

Please sign in to comment.