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.store; 019 020 import javax.crypto.BadPaddingException; 021 import javax.crypto.Cipher; 022 import javax.crypto.IllegalBlockSizeException; 023 import javax.crypto.spec.IvParameterSpec; 024 import javax.crypto.spec.SecretKeySpec; 025 026 import org.cumulus4j.store.crypto.AbstractCryptoManager; 027 import org.cumulus4j.store.crypto.AbstractCryptoSession; 028 import org.cumulus4j.store.crypto.Ciphertext; 029 import org.cumulus4j.store.crypto.CryptoContext; 030 import org.cumulus4j.store.crypto.CryptoSession; 031 import org.cumulus4j.store.crypto.Plaintext; 032 033 /** 034 * Dummy crypto-manager for debugging and testing. 035 * 036 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 037 */ 038 public class DummyCryptoManager extends AbstractCryptoManager 039 { 040 @Override 041 protected CryptoSession createCryptoSession() { 042 return new DummySession(); 043 } 044 045 private static final class DummySession 046 extends AbstractCryptoSession 047 { 048 // key length: 128 bits 049 private static final byte[] dummyKey = { 'D', 'e', 'r', ' ', 'F', 'e', 'r', 'd', ' ', 'h', 'a', 't', ' ', 'v', 'i', 'e' }; 050 // initialization vector length: 128 bits 051 private static final IvParameterSpec iv = new IvParameterSpec(new byte[] {'b', 'l', 'a', 't', 'r', 'u', 'l', 'l', 'a', 'l', 'a', 't', 'r', 'a', 'r', 'a'}); 052 053 private static final String ALGORITHM = "AES"; 054 private static final String ALGORITHM_WITH_PARAMS = ALGORITHM + "/CBC/PKCS5Padding"; 055 056 private Cipher encrypter; 057 private Cipher decrypter; 058 { 059 try { 060 SecretKeySpec key = new SecretKeySpec(dummyKey, ALGORITHM); 061 encrypter = Cipher.getInstance(ALGORITHM_WITH_PARAMS); 062 encrypter.init(Cipher.ENCRYPT_MODE, key, iv); 063 decrypter = Cipher.getInstance(ALGORITHM_WITH_PARAMS); 064 decrypter.init(Cipher.DECRYPT_MODE, key, iv); 065 } catch (Exception ex) { 066 throw new RuntimeException(ex); 067 } 068 } 069 070 @Override 071 public Ciphertext encrypt(CryptoContext cryptoContext, Plaintext plaintext) 072 { 073 // First get the required resources (that are cleared in close()). 074 Cipher c = encrypter; 075 076 // Then assert that we are not yet closed. This makes sure that we definitely can continue 077 // even if close() is called right now simultaneously. 078 assertNotClosed(); 079 080 Ciphertext result = new Ciphertext(); 081 result.setKeyID(12345); 082 083 synchronized (c) { 084 try { 085 result.setData( 086 c.doFinal(plaintext.getData()) 087 ); 088 } catch (IllegalBlockSizeException e) { 089 throw new RuntimeException(e); 090 } catch (BadPaddingException e) { 091 throw new RuntimeException(e); 092 } 093 } 094 095 return result; 096 } 097 098 @Override 099 public Plaintext decrypt(CryptoContext cryptoContext, Ciphertext ciphertext) 100 { 101 if (ciphertext.getKeyID() != 12345) 102 throw new IllegalArgumentException("No key with this keyID: " + ciphertext.getKeyID()); 103 104 // First get the required resources (that are cleared in close()). 105 Cipher c = decrypter; 106 107 // Then assert that we are not yet closed. This makes sure that we definitely can continue 108 // even if close() is called right now simultaneously. 109 assertNotClosed(); 110 111 Plaintext result = new Plaintext(); 112 113 synchronized (c) { 114 try { 115 result.setData( 116 c.doFinal(ciphertext.getData()) 117 ); 118 } catch (IllegalBlockSizeException e) { 119 throw new RuntimeException(e); 120 } catch (BadPaddingException e) { 121 throw new RuntimeException(e); 122 } 123 } 124 125 return result; 126 } 127 128 @Override 129 public void close() { 130 super.close(); 131 encrypter = null; 132 decrypter = null; 133 } 134 } 135 136 }