InMemoryKeyStore.java
- /*
- * @copyright defined in LICENSE.txt
- */
- package hera.keystore;
- import static org.slf4j.LoggerFactory.getLogger;
- import hera.annotation.ApiAudience;
- import hera.annotation.ApiStability;
- import hera.api.model.Authentication;
- import hera.api.model.EncryptedPrivateKey;
- import hera.api.model.Identity;
- import hera.exception.InvalidAuthenticationException;
- import hera.exception.KeyStoreException;
- import hera.key.AergoKey;
- import hera.key.Signer;
- import hera.util.Sha256Utils;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import org.slf4j.Logger;
- @ApiAudience.Public
- @ApiStability.Unstable
- public class InMemoryKeyStore implements KeyStore {
- protected final transient Logger logger = getLogger(getClass());
- protected final Set<Identity> storedIdentities = new HashSet<>();
- protected final Map<String, EncryptedPrivateKey> hashedAuth2Encrypted = new HashMap<>();
- @Override
- public void save(final Authentication authentication, final AergoKey key) {
- try {
- logger.debug("Save with authentication: {}, key: {}", authentication, key);
- final String digested = digest(authentication);
- synchronized (this) {
- if (this.storedIdentities.contains(authentication.getIdentity())) {
- throw new InvalidAuthenticationException("Identity already exists");
- }
- if (this.hashedAuth2Encrypted.containsKey(digested)) {
- throw new InvalidAuthenticationException("Invalid authentication");
- }
- final EncryptedPrivateKey encryptedKey = key.export(authentication.getPassword());
- this.storedIdentities.add(authentication.getIdentity());
- this.hashedAuth2Encrypted.put(digested, encryptedKey);
- }
- } catch (InvalidAuthenticationException e) {
- throw e;
- } catch (final Exception e) {
- throw new KeyStoreException(e);
- }
- }
- @Override
- public Signer load(final Authentication authentication) {
- try {
- logger.debug("Unlock with authentication: {}", authentication);
- final String digested = digest(authentication);
- synchronized (this) {
- if (false == this.hashedAuth2Encrypted.containsKey(digested)) {
- throw new InvalidAuthenticationException("Invalid authentication");
- }
- final EncryptedPrivateKey encrypted = hashedAuth2Encrypted.get(digested);
- final AergoKey decrypted = AergoKey.of(encrypted, authentication.getPassword());
- return decrypted;
- }
- } catch (InvalidAuthenticationException e) {
- throw e;
- } catch (Exception e) {
- throw new KeyStoreException(e);
- }
- }
- @Override
- public void remove(final Authentication authentication) {
- try {
- logger.debug("Remove aergo key with authentication: {}", authentication);
- final String digested = digest(authentication);
- synchronized (this) {
- if (false == this.hashedAuth2Encrypted.containsKey(digested)) {
- throw new InvalidAuthenticationException("Invalid authentication");
- }
- this.storedIdentities.remove(authentication.getIdentity());
- this.hashedAuth2Encrypted.remove(digested);
- }
- } catch (InvalidAuthenticationException e) {
- throw e;
- } catch (final Exception e) {
- throw new KeyStoreException(e);
- }
- }
- @Override
- public EncryptedPrivateKey export(final Authentication authentication, final String password) {
- try {
- logger.debug("Export key with authentication: {}", authentication);
- final String digested = digest(authentication);
- synchronized (this) {
- if (false == hashedAuth2Encrypted.containsKey(digested)) {
- throw new InvalidAuthenticationException("Invalid authentication");
- }
- final EncryptedPrivateKey encrypted = hashedAuth2Encrypted.get(digested);
- final AergoKey decrypted = AergoKey.of(encrypted, authentication.getPassword());
- return decrypted.export(password);
- }
- } catch (InvalidAuthenticationException e) {
- throw e;
- } catch (final Exception e) {
- throw new KeyStoreException(e);
- }
- }
- @Override
- public List<Identity> listIdentities() {
- try {
- return new ArrayList<>(this.storedIdentities);
- } catch (final Exception e) {
- throw new KeyStoreException(e);
- }
- }
- @Override
- public void store(final String path, final char[] password) {
- // do nothing
- }
- protected String digest(final Authentication authentication) {
- final byte[] rawIdentity = authentication.getIdentity().getValue().getBytes();
- final byte[] rawPassword = authentication.getPassword().getBytes();
- final byte[] plaintext = new byte[rawIdentity.length + rawPassword.length];
- System.arraycopy(rawIdentity, 0, plaintext, 0, rawIdentity.length);
- System.arraycopy(rawPassword, 0, plaintext, rawIdentity.length, rawPassword.length);
- return new String(Sha256Utils.digest(plaintext));
- }
- }