001    package org.cumulus4j.store.localkeystoremessagebroker;
002    
003    import java.io.IOException;
004    import java.security.GeneralSecurityException;
005    import java.util.concurrent.TimeoutException;
006    
007    import org.bouncycastle.crypto.CryptoException;
008    import org.cumulus4j.keymanager.back.shared.GetActiveEncryptionKeyRequest;
009    import org.cumulus4j.keymanager.back.shared.GetActiveEncryptionKeyResponse;
010    import org.cumulus4j.keymanager.back.shared.GetKeyRequest;
011    import org.cumulus4j.keymanager.back.shared.GetKeyResponse;
012    import org.cumulus4j.keymanager.back.shared.KeyEncryptionUtil;
013    import org.cumulus4j.keymanager.back.shared.Request;
014    import org.cumulus4j.keymanager.back.shared.Response;
015    import org.cumulus4j.keystore.DateDependentKeyStrategy;
016    import org.cumulus4j.keystore.KeyStore;
017    import org.cumulus4j.store.crypto.keymanager.messagebroker.AbstractMessageBroker;
018    import org.cumulus4j.store.crypto.keymanager.rest.ErrorResponseException;
019    
020    public class LocalKeyStoreMessageBroker extends AbstractMessageBroker
021    {
022            private KeyStore keyStore;
023            private String userName;
024            private char[] password;
025    
026            private DateDependentKeyStrategy.ActiveKey currentActiveKey;
027    
028            public synchronized KeyStore getKeyStore() {
029                    return keyStore;
030            }
031            public synchronized void setKeyStore(KeyStore keyStore) {
032                    this.keyStore = keyStore;
033                    currentActiveKey = null;
034            }
035            public synchronized String getUserName() {
036                    return userName;
037            }
038            public synchronized void setUserName(String authUserName) {
039                    this.userName = authUserName;
040                    currentActiveKey = null;
041            }
042            public synchronized char[] getPassword() {
043                    return password;
044            }
045            public synchronized void setPassword(char[] authPassword) {
046                    this.password = authPassword;
047                    currentActiveKey = null;
048            }
049    
050            protected GetActiveEncryptionKeyResponse handle(GetActiveEncryptionKeyRequest request) throws GeneralSecurityException, IOException, CryptoException {
051                    KeyStore keyStore = getKeyStore();
052    
053                    if (currentActiveKey == null || currentActiveKey.getActiveToExcl().compareTo(request.getTimestamp()) <= 0) {
054                            DateDependentKeyStrategy keyStrategy = new DateDependentKeyStrategy(keyStore);
055                            DateDependentKeyStrategy.ActiveKey newActiveKey = keyStrategy.getActiveKey(
056                                            getUserName(), getPassword(), request.getTimestamp()
057                            );
058                            if (newActiveKey == null)
059                                    throw new IllegalStateException("keyStrategy.getActiveKey(...) returned null!");
060    
061                            currentActiveKey = newActiveKey;
062                    }
063    
064                    byte[] key = keyStore.getKey(getUserName(), getPassword(), currentActiveKey.getKeyID());
065                    byte[] keyEncodedEncrypted = KeyEncryptionUtil.encryptKey(key, request.getKeyEncryptionTransformation(), request.getKeyEncryptionPublicKey());
066                    return new GetActiveEncryptionKeyResponse(
067                                    request,
068                                    currentActiveKey.getKeyID(), keyEncodedEncrypted, currentActiveKey.getActiveToExcl()
069                    );
070            }
071    
072            protected GetKeyResponse handle(GetKeyRequest request) throws GeneralSecurityException, IOException, CryptoException {
073                    byte[] key = getKeyStore().getKey(getUserName(), getPassword(), request.getKeyID());
074                    byte[] keyEncodedEncrypted = KeyEncryptionUtil.encryptKey(key, request.getKeyEncryptionTransformation(), request.getKeyEncryptionPublicKey());
075                    return new GetKeyResponse(request, request.getKeyID(), keyEncodedEncrypted);
076            }
077    
078            @Override
079            protected synchronized Response _query(Class<? extends Response> responseClass, Request request)
080            throws TimeoutException, ErrorResponseException
081            {
082                if (getKeyStore() == null) {
083                    throw new IllegalStateException("getKeyStore() == null :: setKeyStore(...) must be called before!");
084                }
085                if (getUserName() == null) {
086                throw new IllegalStateException("getUserName() == null :: setUserName(...) must be called before!");
087            }
088                if (getPassword() == null) {
089                throw new IllegalStateException("getPassword() == null :: setPassword(...) must be called before!");
090            }
091    
092                    try {
093                            if (request instanceof GetActiveEncryptionKeyRequest) {
094                                    return handle((GetActiveEncryptionKeyRequest) request);
095                            }
096                            if (request instanceof GetKeyRequest) {
097                                    return handle((GetKeyRequest) request);
098                            }
099                    } catch (RuntimeException x) {
100                            throw x;
101                    } catch (Exception x) {
102                            throw new RuntimeException(x);
103                    }
104                    throw new UnsupportedOperationException("NYI");
105            }
106    
107            @Override
108            protected Request _pollRequest(String cryptoSessionIDPrefix)
109            {
110                    throw new UnsupportedOperationException("LocalKeyStoreMessageBroker does not implement this!");
111            }
112    
113            @Override
114            protected void _pushResponse(Response response)
115            {
116                    throw new UnsupportedOperationException("LocalKeyStoreMessageBroker does not implement this!");
117            }
118    
119    }