package io.fathom.cloud.identity.services;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
import com.fathomdb.crypto.bouncycastle.BouncyCastleLoader;
import com.fathomdb.io.IoUtils;
public class KeyPairs {
public static final String DEFAULT_ALGORITHM = "RSA";
public static final int DEFAULT_KEYSIZE = 2048;
public static KeyPair deserialize(String keyData) throws IOException {
PEMReader r = new PEMReader(new StringReader(keyData), null, BouncyCastleLoader.getName());
try {
return (KeyPair) r.readObject();
} finally {
IoUtils.safeClose(r);
}
}
// public static String serialize(KeyPair keyPair) throws IOException {
// StringWriter writer = new StringWriter();
// PEMWriter pemWriter = new PEMWriter(writer,
// BouncyCastleLoader.getName());
// try {
// pemWriter.writeObject(keyPair);
// pemWriter.flush();
// return writer.toString();
// } finally {
// IoUtils.safeClose(pemWriter);
// }
// }
public static String serializePem(Object data) throws IOException {
StringWriter writer = new StringWriter();
try (PEMWriter pemWriter = new PEMWriter(writer)) {
pemWriter.writeObject(data);
pemWriter.flush();
return writer.toString();
}
}
static KeyPair generateKeyPair(String algorithm, Integer keySize) {
KeyPairGenerator generator;
try {
generator = KeyPairGenerator.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Error building keypair generator: " + algorithm, e);
}
if (keySize != null) {
generator.initialize(keySize);
}
return generator.generateKeyPair();
}
public static KeyPair generateKeyPair() {
return generateKeyPair(DEFAULT_ALGORITHM, DEFAULT_KEYSIZE);
}
private static KeyFactory getKeyFactory() {
KeyFactory keyFactory;
try {
keyFactory = KeyFactory.getInstance(DEFAULT_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Error loading RSA provider", e);
}
return keyFactory;
}
public static PublicKey deserializePublicKey(byte[] keyData) {
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(keyData);
KeyFactory keyFactory = getKeyFactory();
PublicKey publicKey;
try {
publicKey = keyFactory.generatePublic(pubKeySpec);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException("Error deserializing public key", e);
}
return publicKey;
}
public static PrivateKey deserializePrivateKey(byte[] keyData) {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyData);
KeyFactory keyFactory = getKeyFactory();
PrivateKey privateKey;
try {
privateKey = keyFactory.generatePrivate(keySpec);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException("Error deserializing private key", e);
}
return privateKey;
}
// public static byte[] encrypt(Key key, byte[] plaintext) {
// return encrypt(getCipher(), key, plaintext);
// }
//
// static Cipher getCipher() {
// return getCipher(DEFAULT_ALGORITHM);
// }
//
// public static Cipher getCipher(String algorithm) {
// try {
// return Cipher.getInstance(algorithm);
// } catch (NoSuchAlgorithmException e) {
// throw new IllegalArgumentException("Error loading crypto provider", e);
// } catch (NoSuchPaddingException e) {
// throw new IllegalArgumentException("Error loading crypto provider", e);
// }
// }
//
// private static void initEncrypt(Cipher cipher, Key key) {
// try {
// cipher.init(Cipher.ENCRYPT_MODE, key);
// } catch (InvalidKeyException e) {
// throw new IllegalArgumentException("Invalid key", e);
// }
// }
//
// static byte[] encrypt(Cipher cipher, Key key, byte[] plaintext) {
// initEncrypt(cipher, key);
// byte[] encryptedBytes;
// try {
// encryptedBytes = cipher.doFinal(plaintext);
// } catch (IllegalBlockSizeException e) {
// throw new IllegalArgumentException("Error in encryption", e);
// } catch (BadPaddingException e) {
// throw new IllegalArgumentException("Error in encryption", e);
// }
// return encryptedBytes;
// }
//
// public static byte[] decrypt(PrivateKey key, byte[] cipherText) {
// return decrypt(getCipher(), key, cipherText);
//
// }
//
// public static byte[] decrypt(Cipher cipher, Key key, byte[] cipherText) {
// initDecrypt(cipher, key);
// byte[] plainText;
// try {
// plainText = cipher.doFinal(cipherText);
// } catch (IllegalBlockSizeException e) {
// throw new IllegalArgumentException("Error in decryption", e);
// } catch (BadPaddingException e) {
// throw new IllegalArgumentException("Error in decryption", e);
// }
// return plainText;
// }
//
// private static void initDecrypt(Cipher cipher, Key key) {
// try {
// cipher.init(Cipher.DECRYPT_MODE, key);
// } catch (InvalidKeyException e) {
// throw new IllegalArgumentException("Invalid key", e);
// }
// }
}