Skip to content
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

[#11] - Bind Keys to Version and Purpose. #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.aholbrook.paseto.crypto.v1.bc;

import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.exception.CryptoProviderException;
import net.aholbrook.paseto.crypto.v1.V1CryptoProvider;
import org.bouncycastle.asn1.DERNull;
Expand Down Expand Up @@ -163,7 +163,7 @@ public boolean rsaVerify(byte[] m, byte[] sig, byte[] publicKey) {
}

@Override
public KeyPair rsaGenerate() {
public Pair<byte[], byte[]> rsaGenerate() {
RSAKeyPairGenerator keyGen = new RSAKeyPairGenerator();
keyGen.init(new RSAKeyGenerationParameters(E, rng, RSA_KEY_SIZE,
PrimeCertaintyCalculator.getDefaultCertainty(RSA_KEY_SIZE)));
Expand All @@ -180,6 +180,6 @@ public KeyPair rsaGenerate() {
priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(),
priv.getQInv()));

return new KeyPair(privateKey, publicKey);
return new Pair<>(privateKey, publicKey);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.aholbrook.paseto.crypto.v1.bc;

import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.exception.CryptoProviderException;
import net.aholbrook.paseto.crypto.v1.V1CryptoLoader;
import org.bouncycastle.crypto.BufferedBlockCipher;
Expand All @@ -24,7 +24,7 @@ public class BouncyCastleV1CryptoProviderTests {
private byte[] iv = new byte[8];

// TODO hardcode a result for keypair.
private KeyPair keyPair = new BouncyCastleV1CryptoProvider().rsaGenerate();
private Pair<byte[], byte[]> keyPair = new BouncyCastleV1CryptoProvider().rsaGenerate();

public void withAse256CtrCipherMocks(Consumer<BouncyCastleV1CryptoProvider> test) {
BouncyCastleV1CryptoProvider provider = Mockito.spy(BouncyCastleV1CryptoProvider.class);
Expand Down Expand Up @@ -62,8 +62,8 @@ public void withPssSha384Mocks(Consumer<BouncyCastleV1CryptoProvider> test) {
BouncyCastleV1CryptoProvider provider = Mockito.spy(BouncyCastleV1CryptoProvider.class);
PSSSigner pssSigner = Mockito.mock(PSSSigner.class);

Mockito.when(provider.pssSha384(true, keyPair.getSecretKey())).thenReturn(pssSigner);
Mockito.when(provider.pssSha384(false, keyPair.getPublicKey())).thenReturn(pssSigner);
Mockito.when(provider.pssSha384(true, keyPair.a)).thenReturn(pssSigner);
Mockito.when(provider.pssSha384(false, keyPair.b)).thenReturn(pssSigner);

try {
Mockito.when(pssSigner.generateSignature())
Expand All @@ -79,7 +79,7 @@ public void withPssSha384Mocks(Consumer<BouncyCastleV1CryptoProvider> test) {
@DisplayName("rsaSign correctly handles a CryptoException if thrown.")
public void rsaSign_CryptoProviderException() {
withPssSha384Mocks((provider) -> {
Assertions.assertThrows(CryptoProviderException.class, () -> provider.rsaSign(m, keyPair.getSecretKey()));
Assertions.assertThrows(CryptoProviderException.class, () -> provider.rsaSign(m, keyPair.a));
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.aholbrook.paseto.crypto.v1;

import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.NonceGenerator;
import net.aholbrook.paseto.crypto.exception.ByteArrayLengthException;

Expand Down Expand Up @@ -45,7 +45,7 @@ public byte[] generateNonce() {

abstract public boolean rsaVerify(byte[] m, byte[] sig, byte[] publicKey);

abstract public KeyPair rsaGenerate();
abstract public Pair<byte[], byte[]> rsaGenerate();

// Validation
protected final void validateHkdfExtractAndExpand(byte[] salt, byte[] inputKeyingMaterial, byte[] info) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.aholbrook.paseto.crypto.v2.bc;

import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.v2.V2CryptoProvider;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
Expand Down Expand Up @@ -77,7 +77,7 @@ public byte[] ed25519SkToPk(byte[] sk) {
}

@Override
public KeyPair ed25519Generate() {
public Pair<byte[], byte[]> ed25519Generate() {
int skLen = ed25519SignSecretKeyBytes() - ed25519SignPublicKeyBytes();
byte[] sk = new byte[ed25519SignSecretKeyBytes()];
byte[] pk = new byte[ed25519SignPublicKeyBytes()];
Expand All @@ -89,6 +89,6 @@ public KeyPair ed25519Generate() {
System.arraycopy(pkParams.getEncoded(), 0, sk, skLen, pk.length);
System.arraycopy(sk, skLen, pk, 0, pk.length);

return new KeyPair(sk, pk);
return new Pair<>(sk, pk);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.aholbrook.paseto.crypto.v2.libsodium;

import com.goterl.lazysodium.SodiumJava;
import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.v2.V2CryptoProvider;

public class LibSodiumV2CryptoProvider extends V2CryptoProvider {
Expand Down Expand Up @@ -68,10 +68,10 @@ public byte[] ed25519SkToPk(byte[] sk) {
}

@Override
public KeyPair ed25519Generate() {
public Pair<byte[], byte[]> ed25519Generate() {
byte[] sk = new byte[ed25519SignSecretKeyBytes()];
byte[] pk = new byte[ed25519SignPublicKeyBytes()];
sodium.crypto_sign_keypair(pk, sk);
return new KeyPair(sk, pk);
return new Pair<>(sk, pk);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.aholbrook.paseto.crypto.v2;

import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.crypto.NonceGenerator;
import net.aholbrook.paseto.crypto.Pair;
import net.aholbrook.paseto.crypto.exception.ByteArrayLengthException;
import net.aholbrook.paseto.crypto.exception.ByteArrayRangeException;

Expand Down Expand Up @@ -36,7 +36,7 @@ public abstract class V2CryptoProvider implements NonceGenerator {

abstract public byte[] ed25519SkToPk(byte[] sk);

abstract public KeyPair ed25519Generate();
abstract public Pair<byte[], byte[]> ed25519Generate();

// Nonce
public NonceGenerator getNonceGenerator() {
Expand Down
37 changes: 0 additions & 37 deletions crypto/src/main/java/net/aholbrook/paseto/crypto/KeyPair.java

This file was deleted.

27 changes: 27 additions & 0 deletions crypto/src/main/java/net/aholbrook/paseto/crypto/Pair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.aholbrook.paseto.crypto;

import java.util.Objects;

public class Pair<A, B> {
public final A a;
public final B b;

public Pair(A a, B b) {
this.a = a;
this.b = b;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return a.equals(pair.a) &&
b.equals(pair.b);
}

@Override
public int hashCode() {
return Objects.hash(a, b);
}
}
37 changes: 20 additions & 17 deletions paseto-core/src/main/java/net/aholbrook/paseto/Paseto.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import net.aholbrook.paseto.base64.jvm8.Base64Loader;
import net.aholbrook.paseto.base64.jvm8.Base64Provider;
import net.aholbrook.paseto.crypto.KeyPair;
import net.aholbrook.paseto.keys.KeyPair;
import net.aholbrook.paseto.crypto.NonceGenerator;
import net.aholbrook.paseto.encoding.EncodingLoader;
import net.aholbrook.paseto.encoding.EncodingProvider;
import net.aholbrook.paseto.exception.InvalidFooterException;
import net.aholbrook.paseto.exception.InvalidHeaderException;
import net.aholbrook.paseto.keys.AsymmetricPublicKey;
import net.aholbrook.paseto.keys.AsymmetricSecretKey;
import net.aholbrook.paseto.keys.SymmetricKey;
import net.aholbrook.paseto.util.StringUtils;

import java.nio.charset.Charset;
Expand All @@ -28,70 +31,70 @@ public Paseto(Base64Provider base64Provider, EncodingProvider encodingProvider,
this.nonceGenerator = nonceGenerator;
}

public abstract String encrypt(Object payload, byte[] key, String footer);
public abstract String encrypt(Object payload, SymmetricKey key, String footer);

public abstract <_Payload> _Payload decrypt(String token, byte[] key, String footer, Class<_Payload> payloadClass);
public abstract <_Payload> _Payload decrypt(String token, SymmetricKey key, String footer, Class<_Payload> payloadClass);

public abstract String sign(Object payload, byte[] key, String footer);
public abstract String sign(Object payload, AsymmetricSecretKey sk, String footer);

public abstract <_Payload> _Payload verify(String token, byte[] pk, String footer, Class<_Payload> payloadClass);
public abstract <_Payload> _Payload verify(String token, AsymmetricPublicKey pk, String footer, Class<_Payload> payloadClass);

public abstract KeyPair generateKeyPair();

public String encrypt(Object payload, byte[] key) {
public String encrypt(Object payload, SymmetricKey key) {
return encrypt(payload, key, null);
}

public String encrypt(Object payload, byte[] key, Object footer) {
public String encrypt(Object payload, SymmetricKey key, Object footer) {
return encrypt(payload, key, (String) ((footer instanceof String) ? footer : encodingProvider.encode(footer)));
}

public <_Payload> _Payload decrypt(String token, byte[] key, Class<_Payload> payloadClass) {
public <_Payload> _Payload decrypt(String token, SymmetricKey key, Class<_Payload> payloadClass) {
return decrypt(token, key, null, payloadClass);
}

public <_Payload> _Payload decrypt(String token, byte[] key, Object footer, Class<_Payload> payloadClass) {
public <_Payload> _Payload decrypt(String token, SymmetricKey key, Object footer, Class<_Payload> payloadClass) {
return decrypt(token, key, (String) ((footer instanceof String) ? footer : encodingProvider.encode(footer)), payloadClass);
}

public String sign(Object payload, byte[] sk) {
public String sign(Object payload, AsymmetricSecretKey sk) {
return sign(payload, sk, null);
}

public String sign(Object payload, byte[] sk, Object footer) {
public String sign(Object payload, AsymmetricSecretKey sk, Object footer) {
return sign(payload, sk, (String) ((footer instanceof String) ? footer : encodingProvider.encode(footer)));
}

public <_Payload> _Payload verify(String token, byte[] pk, Class<_Payload> payloadClass) {
public <_Payload> _Payload verify(String token, AsymmetricPublicKey pk, Class<_Payload> payloadClass) {
return verify(token, pk, null, payloadClass);
}

public <_Payload> _Payload verify(String token, byte[] pk, Object footer, Class<_Payload> payloadClass) {
public <_Payload> _Payload verify(String token, AsymmetricPublicKey pk, Object footer, Class<_Payload> payloadClass) {
return verify(token, pk, (String) ((footer instanceof String) ? footer : encodingProvider.encode(footer)), payloadClass);
}

public <_Payload> TokenWithFooter<_Payload, String> decryptWithFooter(String token, byte[] key,
public <_Payload> TokenWithFooter<_Payload, String> decryptWithFooter(String token, SymmetricKey key,
Class<_Payload> payloadClass) {
_Payload payload = decrypt(token, key, payloadClass);
String footer = extractFooter(token);
return new TokenWithFooter<>(payload, footer);
}

public <_Payload, _Footer> TokenWithFooter<_Payload, _Footer> decryptWithFooter(String token, byte[] key,
public <_Payload, _Footer> TokenWithFooter<_Payload, _Footer> decryptWithFooter(String token, SymmetricKey key,
Class<_Payload> payloadClass, Class<_Footer> footerClass) {
_Payload payload = decrypt(token, key, payloadClass);
_Footer footer = extractFooter(token, footerClass);
return new TokenWithFooter<>(payload, footer);
}

public <_Payload> TokenWithFooter<_Payload, String> verifyWithFooter(String token, byte[] pk,
public <_Payload> TokenWithFooter<_Payload, String> verifyWithFooter(String token, AsymmetricPublicKey pk,
Class<_Payload> payloadClass) {
_Payload payload = verify(token, pk, payloadClass);
String footer = extractFooter(token);
return new TokenWithFooter<>(payload, footer);
}

public <_Payload, _Footer> TokenWithFooter<_Payload, _Footer> verifyWithFooter(String token, byte[] pk,
public <_Payload, _Footer> TokenWithFooter<_Payload, _Footer> verifyWithFooter(String token, AsymmetricPublicKey pk,
Class<_Payload> payloadClass, Class<_Footer> footerClass) {
_Payload payload = verify(token, pk, payloadClass);
_Footer footer = extractFooter(token, footerClass);
Expand Down
Loading