-
Notifications
You must be signed in to change notification settings - Fork 2
Module architecture refactoring #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
pin module Took 37 minutes
…ms should be placed in input map implement PinModule starting Manager with "ktor" argument start it with ktor server implementation add logback to parent pom.xml Took 3 hours 23 minutes
Took 29 minutes
ExampleModule before refactoring public class ExampleModule extends Module {
@Override
public String getDescription() {
return "An example waiting and xoring module to show how things work.";
}
public static final byte[] KEY = "EXAMPLEKEY".getBytes();
private long lastTime = 1000;
@Override
public void register() {
lastTime = System.currentTimeMillis();
setStatusString("Wait 5 seconds for decryption to start");
}
@Override
public String getHtmlUi() {
return null;
}
@Override
public boolean check() {
return System.currentTimeMillis() - lastTime > 5000;
}
@Override
public byte[] encryptInput(byte[] data) {
byte[] r = data.clone();
for (int i = 0; i < r.length; ++i)
r[i] = (byte) (r[i] ^ KEY[i % KEY.length]);
return r;
}
@Override
public void process() {
decrypt(new Decrypter() {
@Override
public synchronized byte[] decrypt(byte[] payload) throws DecryptionException {
if (payload == null) throw new Module.DecryptionException(Module.DecryptionException.NO_DATA);
byte[] r = payload.clone();
for (int i = 0; i < r.length; ++i)
r[i] = (byte) (r[i] ^ KEY[i % KEY.length]);
return r;
}
});
}
} after refactoring public class ExampleModule extends Module {
private static final byte[] KEY = "EXAMPLEKEY".getBytes();
private long lastTime = 1000;
@Override
public void register() {
lastTime = System.currentTimeMillis();
setStatusString("Wait 5 seconds for decryption to start");
}
@Override
public String getDescription() {
return "An example waiting and xoring module to show how things work.";
}
@Override
public String getHtmlUi() {
return null;
}
@Override
public boolean check() {
return System.currentTimeMillis() - lastTime > 5000;
}
@Override
public byte[] encrypt(byte[] data) {
byte[] r = data.clone();
for (int i = 0; i < r.length; ++i)
r[i] = (byte) (r[i] ^ KEY[i % KEY.length]);
return r;
}
@Override
public byte[] decrypt(byte[] payload) throws DecryptionException {
if (payload == null) throw new Module.DecryptionException(Module.DecryptionException.NO_DATA);
byte[] r = payload.clone();
for (int i = 0; i < r.length; ++i)
r[i] = (byte) (r[i] ^ KEY[i % KEY.length]);
return r;
}
} |
As about We might ask about above two our advisor.
|
I don't know how you connect anonymous classes with security. Could you please provide some proofs ?
Thats why I left the
I don't get it, GC won't clear data until you keep reference to it. And I don't see any reason to lose reference to this data before clearing it manually.
Ok, so could you please describe what they are, and where may be required ? And why can't be stored as class memebers ? |
1, 3. We might ask about above two our advisor.
|
Strange, I didn't know that. Anyway, I don't see this problem in our case. What I thought was something like that: val encryptedKeyParts : Map<String, byte[]> = getKeyPartsFromDb() // module.id -> encryptedKeyPart
val modules = listOf(PinModule(), ButtonModule(), ServerModule())
var decryptedKeys = modules.map{ module -> module.decrypt(encryptedKeyParts[module.id]) }
var privateKey = shamir.restoreSecretFromKeyParts(decryptedKeys)
bitcoin.restoreWallet(privateKey)
decryptedKeys = null
privateKey = null
System.gc() But as I said, I don't push on this change, it was just proposal. I care about the others changes. Do you think that we can merge it ? |
I think that we should stay away from things like trying to improve security by adding annonymous classes and other tricks. Let's keep code clean and understandable, it's more important. |
During PIN Module implementation #32 I was confused with the pattern chosen by @pfoof .
Could you please explain what is the reason for using hook method for encryption
public byte[] encryptInput(byte[] data) and functional interface for decryption
It looks like your idea is not finished because
is unused.
Both patterns are good, but they shouldn't be mixed in symetric operations.
Additionally
is very error-prone, since the decrypt(Decrypter) MUST be called in order to generate decryptedValue. The architecture must force user to implement methods that are required to correctly working system.
And here I faced with another consideration, do we need to keep decryptedValue in memory ? Can't we just calculate this value on-demand ? For example when all modules are check() == true then manager would call encrypt(keyPart) on every module, combine the parts and restore seed. No memory clearing would be necessary.
I'm not forcing this change, I just want to make our code consistent
Let's debate !
Took 29 minutes