forked from Consensys/orion
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of the Lib Sodium enclave. (Consensys#29)
* Initial implementation of the Lib Sodium enclave.
- Loading branch information
Showing
16 changed files
with
404 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/main/java/net/consensys/athena/impl/enclave/sodium/LibSodiumEnclave.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import net.consensys.athena.api.config.Config; | ||
import net.consensys.athena.api.enclave.CombinedKey; | ||
import net.consensys.athena.api.enclave.Enclave; | ||
import net.consensys.athena.api.enclave.EnclaveException; | ||
import net.consensys.athena.api.enclave.EncryptedPayload; | ||
import net.consensys.athena.api.enclave.HashAlgorithm; | ||
import net.consensys.athena.api.enclave.KeyStore; | ||
import net.consensys.athena.impl.enclave.SimpleEncryptedPayload; | ||
import net.consensys.athena.impl.enclave.bouncycastle.Hasher; | ||
|
||
import java.security.PrivateKey; | ||
import java.security.PublicKey; | ||
import java.security.Security; | ||
|
||
import com.muquit.libsodiumjna.SodiumLibrary; | ||
import com.muquit.libsodiumjna.exceptions.SodiumLibraryException; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class LibSodiumEnclave implements Enclave { | ||
private static final Logger log = LogManager.getLogger(); | ||
|
||
static { | ||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); | ||
} | ||
|
||
private final Hasher hasher = new Hasher(); | ||
private KeyStore keyStore; | ||
|
||
public LibSodiumEnclave(Config config, KeyStore keyStore) { | ||
SodiumLibrary.setLibraryPath(config.libSodiumPath()); | ||
|
||
this.keyStore = keyStore; | ||
} | ||
|
||
@Override | ||
public byte[] digest(HashAlgorithm algorithm, byte[] input) { | ||
return hasher.digest(algorithm, input); | ||
} | ||
|
||
@Override | ||
public EncryptedPayload encrypt(byte[] plaintext, PublicKey senderKey, PublicKey[] recipients) { | ||
try { | ||
PrivateKey senderPrivateKey = keyStore.getPrivateKey(senderKey); | ||
if (senderPrivateKey == null) { | ||
throw new EnclaveException("No PrivateKey found in keystore"); | ||
} | ||
byte[] secretKey = | ||
SodiumLibrary.randomBytes(SodiumLibrary.cryptoSecretBoxKeyBytes().intValue()); | ||
byte[] secretNonce = secretNonce(); | ||
byte[] cipherText = SodiumLibrary.cryptoSecretBoxEasy(plaintext, secretNonce, secretKey); | ||
|
||
byte[] nonce = nonce(); | ||
CombinedKey[] combinedKeys = getCombinedKeys(recipients, senderPrivateKey, secretKey, nonce); | ||
return new SimpleEncryptedPayload(senderKey, secretNonce, nonce, combinedKeys, cipherText); | ||
} catch (SodiumLibraryException e) { | ||
throw new EnclaveException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public byte[] decrypt(EncryptedPayload ciphertextAndMetadata, PublicKey identity) { | ||
try { | ||
PrivateKey privateKey = keyStore.getPrivateKey(identity); | ||
if (privateKey == null) { | ||
throw new EnclaveException("No PrivateKey found in keystore"); | ||
} | ||
CombinedKey key = ciphertextAndMetadata.getCombinedKeys()[0]; | ||
byte[] secretKey = | ||
SodiumLibrary.cryptoBoxOpenEasy( | ||
key.getEncoded(), | ||
ciphertextAndMetadata.getCombinedKeyNonce(), | ||
ciphertextAndMetadata.getSender().getEncoded(), | ||
privateKey.getEncoded()); | ||
return SodiumLibrary.cryptoSecretBoxOpenEasy( | ||
ciphertextAndMetadata.getCipherText(), ciphertextAndMetadata.getNonce(), secretKey); | ||
} catch (SodiumLibraryException e) { | ||
throw new EnclaveException(e); | ||
} | ||
} | ||
|
||
private byte[] secretNonce() { | ||
int secretNonceBytesLength = SodiumLibrary.cryptoSecretBoxNonceBytes().intValue(); | ||
|
||
return SodiumLibrary.randomBytes(secretNonceBytesLength); | ||
} | ||
|
||
private byte[] nonce() { | ||
int nonceBytesLength = SodiumLibrary.cryptoBoxNonceBytes().intValue(); | ||
return SodiumLibrary.randomBytes(nonceBytesLength); | ||
} | ||
|
||
@NotNull | ||
private CombinedKey[] getCombinedKeys( | ||
PublicKey[] recipients, PrivateKey senderPrivateKey, byte[] secretKey, byte[] nonce) | ||
throws SodiumLibraryException { | ||
CombinedKey[] combinedKeys = new CombinedKey[recipients.length]; | ||
for (int i = 0; i < recipients.length; i++) { | ||
PublicKey recipient = recipients[i]; | ||
byte[] encryptedKey = | ||
SodiumLibrary.cryptoBoxEasy( | ||
secretKey, nonce, recipient.getEncoded(), senderPrivateKey.getEncoded()); | ||
SodiumCombinedKey combinedKey = new SodiumCombinedKey(encryptedKey); | ||
combinedKeys[i] = combinedKey; | ||
} | ||
return combinedKeys; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/net/consensys/athena/impl/enclave/sodium/LibSodiumSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import java.io.File; | ||
|
||
import com.sun.jna.Platform; | ||
|
||
public class LibSodiumSettings { | ||
|
||
public static String defaultLibSodiumPath() { | ||
if (Platform.isMac()) { | ||
return "/usr/local/lib/libsodium.dylib"; | ||
} else if (Platform.isWindows()) { | ||
return "C:/libsodium/libsodium.dll"; | ||
} else if (new File("/usr/lib/x86_64-linux-gnu/libsodium.so").exists()) { | ||
//Ubuntu trusty location. | ||
return "/usr/lib/x86_64-linux-gnu/libsodium.so"; | ||
} else { | ||
return "/usr/local/lib/libsodium.so"; | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/net/consensys/athena/impl/enclave/sodium/SodiumCombinedKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import net.consensys.athena.api.enclave.CombinedKey; | ||
|
||
public class SodiumCombinedKey implements CombinedKey { | ||
|
||
byte[] key; | ||
|
||
public SodiumCombinedKey(byte[] key) { | ||
this.key = key; | ||
} | ||
|
||
@Override | ||
public byte[] getEncoded() { | ||
return key; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/net/consensys/athena/impl/enclave/sodium/SodiumMemoryKeyStore.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import net.consensys.athena.api.enclave.EnclaveException; | ||
import net.consensys.athena.api.enclave.KeyStore; | ||
|
||
import java.security.PrivateKey; | ||
import java.security.PublicKey; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import com.muquit.libsodiumjna.SodiumKeyPair; | ||
import com.muquit.libsodiumjna.SodiumLibrary; | ||
import com.muquit.libsodiumjna.exceptions.SodiumLibraryException; | ||
|
||
public class SodiumMemoryKeyStore implements KeyStore { | ||
|
||
Map<PublicKey, PrivateKey> store = new HashMap<>(); | ||
|
||
@Override | ||
public PrivateKey getPrivateKey(PublicKey publicKey) { | ||
return store.get(publicKey); | ||
} | ||
|
||
@Override | ||
public PublicKey generateKeyPair() { | ||
try { | ||
SodiumKeyPair keyPair = SodiumLibrary.cryptoBoxKeyPair(); | ||
SodiumPrivateKey privateKey = new SodiumPrivateKey(keyPair.getPrivateKey()); | ||
SodiumPublicKey publicKey = new SodiumPublicKey(keyPair.getPublicKey()); | ||
store.put(publicKey, privateKey); | ||
return publicKey; | ||
} catch (SodiumLibraryException e) { | ||
throw new EnclaveException(e); | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/main/java/net/consensys/athena/impl/enclave/sodium/SodiumPrivateKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import java.security.PrivateKey; | ||
import java.util.Arrays; | ||
|
||
public class SodiumPrivateKey implements PrivateKey { | ||
|
||
private byte[] privateKey; | ||
|
||
public SodiumPrivateKey(byte[] privateKey) { | ||
|
||
this.privateKey = privateKey; | ||
} | ||
|
||
@Override | ||
public String getAlgorithm() { | ||
return "sodium"; | ||
} | ||
|
||
@Override | ||
public String getFormat() { | ||
return "raw"; | ||
} | ||
|
||
@Override | ||
public byte[] getEncoded() { | ||
return privateKey; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "SodiumPrivateKey{" + "privateKey=" + Arrays.toString(privateKey) + '}'; | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/net/consensys/athena/impl/enclave/sodium/SodiumPublicKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package net.consensys.athena.impl.enclave.sodium; | ||
|
||
import java.security.PublicKey; | ||
|
||
public class SodiumPublicKey implements PublicKey { | ||
|
||
private byte[] publicKey; | ||
|
||
public SodiumPublicKey(byte[] publicKey) { | ||
this.publicKey = publicKey; | ||
} | ||
|
||
@Override | ||
public String getAlgorithm() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getFormat() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public byte[] getEncoded() { | ||
return publicKey; | ||
} | ||
} |
Oops, something went wrong.