001 /* 002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org 003 * Copyright (C) 2011 NightLabs Consulting GmbH 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 package org.cumulus4j.keymanager.channel; 019 020 import java.io.IOException; 021 import java.security.GeneralSecurityException; 022 import java.util.Collections; 023 import java.util.Date; 024 import java.util.Map; 025 import java.util.WeakHashMap; 026 027 import org.bouncycastle.crypto.CryptoException; 028 import org.cumulus4j.keymanager.Session; 029 import org.cumulus4j.keymanager.SessionManager; 030 import org.cumulus4j.keymanager.back.shared.GetActiveEncryptionKeyRequest; 031 import org.cumulus4j.keymanager.back.shared.GetActiveEncryptionKeyResponse; 032 import org.cumulus4j.keymanager.back.shared.GetKeyResponse; 033 import org.cumulus4j.keymanager.back.shared.KeyEncryptionUtil; 034 import org.cumulus4j.keymanager.back.shared.Response; 035 import org.cumulus4j.keystore.AuthenticationException; 036 import org.cumulus4j.keystore.DateDependentKeyStrategy; 037 import org.cumulus4j.keystore.KeyNotFoundException; 038 import org.cumulus4j.keystore.KeyStore; 039 040 /** 041 * <p> 042 * Handler for {@link GetActiveEncryptionKeyRequest}. 043 * </p> 044 * <p> 045 * If the {@link Session} is found for the given 046 * {@link org.cumulus4j.keymanager.back.shared.Request#getCryptoSessionID() cryptoSessionID} and 047 * it is not {@link Session#isReleased() locked}, this handler determines the currently active 048 * encryption key and sends it in a {@link GetKeyResponse} to the server. 049 * </p> 050 * 051 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 052 */ 053 public class GetActiveEncryptionKeyRequestHandler extends AbstractRequestHandler<GetActiveEncryptionKeyRequest> 054 { 055 private static Map<KeyStore, DateDependentKeyStrategy.ActiveKey> keyStore2activeKey = Collections.synchronizedMap( 056 new WeakHashMap<KeyStore, DateDependentKeyStrategy.ActiveKey>() 057 ); 058 059 @Override 060 public Response handle(GetActiveEncryptionKeyRequest request) 061 throws AuthenticationException, KeyNotFoundException, IOException, GeneralSecurityException, CryptoException 062 { 063 SessionManager sessionManager = getKeyManagerChannelManager().getSessionManager(); 064 Session session = sessionManager.getSessionForCryptoSessionID(request.getCryptoSessionID()); 065 066 // TODO typed exceptions/typed responses?! 067 if (session == null) 068 throw new IllegalStateException("There is no session for cryptoSessionID=" + request.getCryptoSessionID() + "!"); 069 070 if (session.isReleased()) 071 throw new IllegalStateException("The session for cryptoSessionID=" + request.getCryptoSessionID() + " is currently locked!"); 072 073 if (session.getExpiry().before(new Date())) 074 throw new IllegalStateException("The session for cryptoSessionID=" + request.getCryptoSessionID() + " is already expired!"); 075 076 if (request.getTimestamp() == null) 077 throw new IllegalArgumentException("request.getTimestamp() == null"); 078 079 KeyStore keyStore = sessionManager.getKeyStore(); 080 DateDependentKeyStrategy.ActiveKey currentActiveKey = keyStore2activeKey.get(keyStore); 081 082 if (currentActiveKey == null || currentActiveKey.getActiveToExcl().compareTo(request.getTimestamp()) <= 0) { 083 DateDependentKeyStrategy keyStrategy = new DateDependentKeyStrategy(keyStore); 084 DateDependentKeyStrategy.ActiveKey newActiveKey = keyStrategy.getActiveKey( 085 session.getUserName(), session.getPassword(), request.getTimestamp() 086 ); 087 if (newActiveKey == null) 088 throw new IllegalStateException("keyStrategy.getActiveKey(...) returned null!"); 089 090 keyStore2activeKey.put(keyStore, newActiveKey); 091 currentActiveKey = newActiveKey; 092 } 093 094 byte[] key = keyStore.getKey(session.getUserName(), session.getPassword(), currentActiveKey.getKeyID()); 095 byte[] keyEncodedEncrypted = KeyEncryptionUtil.encryptKey(key, request.getKeyEncryptionTransformation(), request.getKeyEncryptionPublicKey()); 096 return new GetActiveEncryptionKeyResponse( 097 request, 098 currentActiveKey.getKeyID(), keyEncodedEncrypted, currentActiveKey.getActiveToExcl() 099 ); 100 } 101 102 }