-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
44 changed files
with
1,807 additions
and
196 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
65 changes: 65 additions & 0 deletions
65
src/main/java/org/cryptomator/cryptolib/common/ECKeyPair.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,65 @@ | ||
package org.cryptomator.cryptolib.common; | ||
|
||
import com.google.common.base.Preconditions; | ||
|
||
import javax.security.auth.Destroyable; | ||
import java.security.KeyPair; | ||
import java.security.MessageDigest; | ||
import java.security.interfaces.ECPrivateKey; | ||
import java.security.interfaces.ECPublicKey; | ||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
public class ECKeyPair implements Destroyable { | ||
|
||
private final KeyPair keyPair; | ||
private boolean destroyed; | ||
|
||
ECKeyPair(KeyPair keyPair) { | ||
Preconditions.checkArgument(keyPair.getPrivate() instanceof ECPrivateKey); | ||
Preconditions.checkArgument(keyPair.getPublic() instanceof ECPublicKey); | ||
this.keyPair = keyPair; | ||
} | ||
|
||
public KeyPair keyPair() { | ||
return keyPair; | ||
} | ||
|
||
public ECPrivateKey getPrivate() { | ||
Preconditions.checkState(!destroyed); | ||
assert keyPair.getPrivate() instanceof ECPrivateKey; | ||
return (ECPrivateKey) keyPair.getPrivate(); | ||
} | ||
|
||
public ECPublicKey getPublic() { | ||
Preconditions.checkState(!destroyed); | ||
assert keyPair.getPublic() instanceof ECPublicKey; | ||
return (ECPublicKey) keyPair.getPublic(); | ||
} | ||
|
||
@Override | ||
public boolean isDestroyed() { | ||
return destroyed; | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
Destroyables.destroySilently(keyPair.getPrivate()); | ||
destroyed = true; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
ECKeyPair that = (ECKeyPair) o; | ||
return MessageDigest.isEqual(this.getPublic().getEncoded(), that.getPublic().getEncoded()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = Objects.hash(keyPair.getPublic().getAlgorithm()); | ||
result = 31 * result + Arrays.hashCode(keyPair.getPublic().getEncoded()); | ||
return result; | ||
} | ||
} |
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
65 changes: 65 additions & 0 deletions
65
src/main/java/org/cryptomator/cryptolib/common/MasterkeyHubAccess.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,65 @@ | ||
package org.cryptomator.cryptolib.common; | ||
|
||
import com.google.common.io.BaseEncoding; | ||
import org.cryptomator.cryptolib.api.Masterkey; | ||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; | ||
import org.cryptomator.cryptolib.ecies.EncryptedMessage; | ||
import org.cryptomator.cryptolib.ecies.ECIntegratedEncryptionScheme; | ||
|
||
import javax.crypto.AEADBadTagException; | ||
import java.security.KeyFactory; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.PublicKey; | ||
import java.security.interfaces.ECPrivateKey; | ||
import java.security.interfaces.ECPublicKey; | ||
import java.security.spec.InvalidKeySpecException; | ||
import java.security.spec.X509EncodedKeySpec; | ||
import java.util.Arrays; | ||
|
||
public class MasterkeyHubAccess { | ||
|
||
private static final BaseEncoding BASE64_URL = BaseEncoding.base64Url().omitPadding(); | ||
|
||
private MasterkeyHubAccess() { | ||
} | ||
|
||
/** | ||
* Decrypts a masterkey retrieved from Cryptomator Hub | ||
* | ||
* @param devicePrivateKey Private key of the device this ciphertext is intended for | ||
* @param encodedCiphertext The encrypted masterkey | ||
* @param encodedEphPubKey The ephemeral public key to be used to derive a secret shared between message sender and this device | ||
* @return The decrypted masterkey | ||
* @throws MasterkeyLoadingFailedException If the parameters don't match and decryption fails | ||
*/ | ||
public static Masterkey decryptMasterkey(ECPrivateKey devicePrivateKey, String encodedCiphertext, String encodedEphPubKey) throws MasterkeyLoadingFailedException { | ||
byte[] cleartext = new byte[0]; | ||
try { | ||
EncryptedMessage message = decode(encodedCiphertext, encodedEphPubKey); | ||
cleartext = ECIntegratedEncryptionScheme.HUB.decrypt(devicePrivateKey, message); | ||
return new Masterkey(cleartext); | ||
} catch (IllegalArgumentException | AEADBadTagException e) { | ||
throw new MasterkeyLoadingFailedException("Key and ciphertext don't match", e); | ||
} finally { | ||
Arrays.fill(cleartext, (byte) 0x00); | ||
} | ||
} | ||
|
||
private static EncryptedMessage decode(String encodedCiphertext, String encodedEphPubKey) throws IllegalArgumentException { | ||
byte[] ciphertext = BASE64_URL.decode(encodedCiphertext); | ||
byte[] keyBytes = BASE64_URL.decode(encodedEphPubKey); | ||
try { | ||
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes)); | ||
if (key instanceof ECPublicKey) { | ||
return new EncryptedMessage((ECPublicKey) key, ciphertext); | ||
} else { | ||
throw new IllegalArgumentException("Key not an EC public key."); | ||
} | ||
} catch (InvalidKeySpecException e) { | ||
throw new IllegalArgumentException("Invalid license public key", e); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
} | ||
|
||
} |
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
Oops, something went wrong.