Skip to content

Commit 7a1ab56

Browse files
BarbatosBarbatos
authored andcommitted
refactor(crypto): extract keystore library from framework module
Move keystore package (Wallet, WalletUtils, Credentials, WalletFile) from framework to crypto module to enable reuse by Toolkit.jar without pulling in the entire framework dependency. - Replace Args.getInstance().isECKeyCryptoEngine() calls with injected boolean ecKey parameter in Wallet.decrypt(), WalletUtils.loadCredentials(), generateNewWalletFile(), generateFullNewWalletFile(), generateLightNewWalletFile() - Update callers (KeystoreFactory, WitnessInitializer) to pass ecKey - Add implementation project(":crypto") to plugins build - Merge two CredentialsTest files (fix keystroe typo dir) into crypto module - Move WalletFileTest to crypto module - CipherException already in common module, no move needed
1 parent 721b165 commit 7a1ab56

13 files changed

Lines changed: 99 additions & 101 deletions

File tree

framework/src/main/java/org/tron/keystore/Credentials.java renamed to crypto/src/main/java/org/tron/keystore/Credentials.java

File renamed without changes.

framework/src/main/java/org/tron/keystore/Wallet.java renamed to crypto/src/main/java/org/tron/keystore/Wallet.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.tron.common.crypto.SignUtils;
2424
import org.tron.common.utils.ByteArray;
2525
import org.tron.common.utils.StringUtil;
26-
import org.tron.core.config.args.Args;
2726
import org.tron.core.exception.CipherException;
2827

2928
/**
@@ -168,8 +167,8 @@ private static byte[] generateMac(byte[] derivedKey, byte[] cipherText) {
168167
return Hash.sha3(result);
169168
}
170169

171-
public static SignInterface decrypt(String password, WalletFile walletFile)
172-
throws CipherException {
170+
public static SignInterface decrypt(String password, WalletFile walletFile,
171+
boolean ecKey) throws CipherException {
173172

174173
validate(walletFile);
175174

@@ -212,7 +211,7 @@ public static SignInterface decrypt(String password, WalletFile walletFile)
212211
byte[] encryptKey = Arrays.copyOfRange(derivedKey, 0, 16);
213212
byte[] privateKey = performCipherOperation(Cipher.DECRYPT_MODE, iv, encryptKey, cipherText);
214213

215-
return SignUtils.fromPrivate(privateKey, Args.getInstance().isECKeyCryptoEngine());
214+
return SignUtils.fromPrivate(privateKey, ecKey);
216215
}
217216

218217
static void validate(WalletFile walletFile) throws CipherException {

framework/src/main/java/org/tron/keystore/WalletFile.java renamed to crypto/src/main/java/org/tron/keystore/WalletFile.java

File renamed without changes.

framework/src/main/java/org/tron/keystore/WalletUtils.java renamed to crypto/src/main/java/org/tron/keystore/WalletUtils.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.tron.common.crypto.SignInterface;
1818
import org.tron.common.crypto.SignUtils;
1919
import org.tron.common.utils.Utils;
20-
import org.tron.core.config.args.Args;
2120
import org.tron.core.exception.CipherException;
2221

2322
/**
@@ -32,27 +31,28 @@ public class WalletUtils {
3231
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
3332
}
3433

35-
public static String generateFullNewWalletFile(String password, File destinationDirectory)
34+
public static String generateFullNewWalletFile(String password, File destinationDirectory,
35+
boolean ecKey)
3636
throws NoSuchAlgorithmException, NoSuchProviderException,
3737
InvalidAlgorithmParameterException, CipherException, IOException {
3838

39-
return generateNewWalletFile(password, destinationDirectory, true);
39+
return generateNewWalletFile(password, destinationDirectory, true, ecKey);
4040
}
4141

42-
public static String generateLightNewWalletFile(String password, File destinationDirectory)
42+
public static String generateLightNewWalletFile(String password, File destinationDirectory,
43+
boolean ecKey)
4344
throws NoSuchAlgorithmException, NoSuchProviderException,
4445
InvalidAlgorithmParameterException, CipherException, IOException {
4546

46-
return generateNewWalletFile(password, destinationDirectory, false);
47+
return generateNewWalletFile(password, destinationDirectory, false, ecKey);
4748
}
4849

4950
public static String generateNewWalletFile(
50-
String password, File destinationDirectory, boolean useFullScrypt)
51+
String password, File destinationDirectory, boolean useFullScrypt, boolean ecKey)
5152
throws CipherException, IOException, InvalidAlgorithmParameterException,
5253
NoSuchAlgorithmException, NoSuchProviderException {
5354

54-
SignInterface ecKeyPair = SignUtils.getGeneratedRandomSign(Utils.getRandom(),
55-
Args.getInstance().isECKeyCryptoEngine());
55+
SignInterface ecKeyPair = SignUtils.getGeneratedRandomSign(Utils.getRandom(), ecKey);
5656
return generateWalletFile(password, ecKeyPair, destinationDirectory, useFullScrypt);
5757
}
5858

@@ -75,10 +75,10 @@ public static String generateWalletFile(
7575
return fileName;
7676
}
7777

78-
public static Credentials loadCredentials(String password, File source)
78+
public static Credentials loadCredentials(String password, File source, boolean ecKey)
7979
throws IOException, CipherException {
8080
WalletFile walletFile = objectMapper.readValue(source, WalletFile.class);
81-
return Credentials.create(Wallet.decrypt(password, walletFile));
81+
return Credentials.create(Wallet.decrypt(password, walletFile, ecKey));
8282
}
8383

8484
private static String getWalletFileName(WalletFile walletFile) {
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.tron.keystore;
2+
3+
import java.security.NoSuchAlgorithmException;
4+
import java.security.SecureRandom;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
import org.mockito.Mockito;
9+
import org.tron.common.crypto.SignInterface;
10+
import org.tron.common.crypto.SignUtils;
11+
import org.tron.common.crypto.sm2.SM2;
12+
import org.tron.common.utils.ByteUtil;
13+
14+
@Slf4j
15+
public class CredentialsTest {
16+
17+
@Test
18+
public void testCreate() throws NoSuchAlgorithmException {
19+
Credentials credentials = Credentials.create(SignUtils.getGeneratedRandomSign(
20+
SecureRandom.getInstance("NativePRNG"), true));
21+
Assert.assertTrue("Credentials address create failed!",
22+
credentials.getAddress() != null && !credentials.getAddress().isEmpty());
23+
Assert.assertNotNull("Credentials cryptoEngine create failed",
24+
credentials.getSignInterface());
25+
}
26+
27+
@Test
28+
public void testCreateFromSM2() {
29+
try {
30+
Credentials.create(SM2.fromNodeId(ByteUtil.hexToBytes("fffffffffff"
31+
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
32+
+ "fffffffffffffffffffffffffffffffffffffff")));
33+
} catch (Exception e) {
34+
Assert.assertTrue(e instanceof IllegalArgumentException);
35+
}
36+
}
37+
38+
@Test
39+
public void testEquals() throws NoSuchAlgorithmException {
40+
Credentials credentials1 = Credentials.create(SignUtils.getGeneratedRandomSign(
41+
SecureRandom.getInstance("NativePRNG"), true));
42+
Credentials credentials2 = Credentials.create(SignUtils.getGeneratedRandomSign(
43+
SecureRandom.getInstance("NativePRNG"), true));
44+
Assert.assertFalse("Credentials instance should be not equal!",
45+
credentials1.equals(credentials2));
46+
Assert.assertFalse("Credentials instance hashcode should be not equal!",
47+
credentials1.hashCode() == credentials2.hashCode());
48+
}
49+
50+
@Test
51+
public void testEqualityWithMocks() {
52+
Object aObject = new Object();
53+
SignInterface si = Mockito.mock(SignInterface.class);
54+
SignInterface si2 = Mockito.mock(SignInterface.class);
55+
SignInterface si3 = Mockito.mock(SignInterface.class);
56+
byte[] address = "TQhZ7W1RudxFdzJMw6FvMnujPxrS6sFfmj".getBytes();
57+
byte[] address2 = "TNCmcTdyrYKMtmE1KU2itzeCX76jGm5Not".getBytes();
58+
Mockito.when(si.getAddress()).thenReturn(address);
59+
Mockito.when(si2.getAddress()).thenReturn(address);
60+
Mockito.when(si3.getAddress()).thenReturn(address2);
61+
Credentials aCredential = Credentials.create(si);
62+
Assert.assertFalse(aObject.equals(aCredential));
63+
Assert.assertFalse(aCredential.equals(aObject));
64+
Assert.assertFalse(aCredential.equals(null));
65+
Credentials anotherCredential = Credentials.create(si);
66+
Assert.assertTrue(aCredential.equals(anotherCredential));
67+
Credentials aCredential2 = Credentials.create(si2);
68+
// si and si2 are different mock objects, so credentials are not equal
69+
Assert.assertFalse(aCredential.equals(aCredential2));
70+
Credentials aCredential3 = Credentials.create(si3);
71+
Assert.assertFalse(aCredential.equals(aCredential3));
72+
}
73+
}

framework/src/test/java/org/tron/keystore/WalletFileTest.java renamed to crypto/src/test/java/org/tron/keystore/WalletFileTest.java

File renamed without changes.

framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ public static LocalWitnesses initFromKeystore(
7979

8080
List<String> privateKeys = new ArrayList<>();
8181
try {
82-
Credentials credentials = WalletUtils.loadCredentials(pwd, new File(fileName));
82+
Credentials credentials = WalletUtils.loadCredentials(pwd, new File(fileName),
83+
Args.getInstance().isECKeyCryptoEngine());
8384
SignInterface sign = credentials.getSignInterface();
8485
String prikey = ByteArray.toHexString(sign.getPrivateKey());
8586
privateKeys.add(prikey);

framework/src/main/java/org/tron/program/KeystoreFactory.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,11 @@ private void genKeystore() throws CipherException, IOException {
6363
CommonParameter.getInstance().isECKeyCryptoEngine());
6464
File file = new File(FilePath);
6565
fileCheck(file);
66+
boolean ecKey = CommonParameter.getInstance().isECKeyCryptoEngine();
6667
String fileName = WalletUtils.generateWalletFile(password, eCkey, file, true);
6768
System.out.println("Gen a keystore its name " + fileName);
68-
Credentials credentials = WalletUtils.loadCredentials(password, new File(file, fileName));
69+
Credentials credentials = WalletUtils.loadCredentials(password, new File(file, fileName),
70+
ecKey);
6971
System.out.println("Your address is " + credentials.getAddress());
7072
}
7173

@@ -88,9 +90,11 @@ private void importPrivateKey() throws CipherException, IOException {
8890
CommonParameter.getInstance().isECKeyCryptoEngine());
8991
File file = new File(FilePath);
9092
fileCheck(file);
93+
boolean ecKey = CommonParameter.getInstance().isECKeyCryptoEngine();
9194
String fileName = WalletUtils.generateWalletFile(password, eCkey, file, true);
9295
System.out.println("Gen a keystore its name " + fileName);
93-
Credentials credentials = WalletUtils.loadCredentials(password, new File(file, fileName));
96+
Credentials credentials = WalletUtils.loadCredentials(password, new File(file, fileName),
97+
ecKey);
9498
System.out.println("Your address is " + credentials.getAddress());
9599
}
96100

framework/src/test/java/org/tron/core/config/args/WitnessInitializerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import static org.junit.Assert.assertNull;
77
import static org.junit.Assert.assertThrows;
88
import static org.mockito.ArgumentMatchers.any;
9+
import static org.mockito.ArgumentMatchers.anyBoolean;
910
import static org.mockito.ArgumentMatchers.anyString;
1011
import static org.mockito.Mockito.mock;
1112
import static org.mockito.Mockito.mockStatic;
@@ -106,7 +107,7 @@ public void testInitFromKeystore() {
106107
byte[] keyBytes = Hex.decode(privateKey);
107108
when(signInterface.getPrivateKey()).thenReturn(keyBytes);
108109
mockedWallet.when(() -> WalletUtils.loadCredentials(
109-
anyString(), any(File.class))).thenReturn(credentials);
110+
anyString(), any(File.class), anyBoolean())).thenReturn(credentials);
110111
mockedByteArray.when(() -> ByteArray.toHexString(any()))
111112
.thenReturn(privateKey);
112113
mockedByteArray.when(() -> ByteArray.fromHexString(anyString()))

framework/src/test/java/org/tron/keystore/CredentialsTest.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)