1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59: public class EncryptedEntry extends MaskableEnvelopeEntry implements Registry
60: {
61: public static final int TYPE = 0;
62:
63: public EncryptedEntry(String cipher, String mode, Properties properties)
64: {
65: super(TYPE, properties);
66: if (cipher == null || mode == null)
67: throw new IllegalArgumentException("neither cipher nor mode can be null");
68: properties.put("cipher", cipher);
69: properties.put("mode", mode);
70: setMasked(false);
71: }
72:
73: private EncryptedEntry()
74: {
75: super(TYPE, new Properties());
76: setMasked(true);
77: }
78:
79: public static EncryptedEntry decode(DataInputStream in) throws IOException
80: {
81: EncryptedEntry entry = new EncryptedEntry();
82: entry.defaultDecode(in);
83: if (! entry.properties.containsKey("cipher"))
84: throw new MalformedKeyringException("no cipher");
85: if (! entry.properties.containsKey("cipher"))
86: throw new MalformedKeyringException("no cipher");
87: return entry;
88: }
89:
90: public void decrypt(byte[] key, byte[] iv) throws IllegalArgumentException,
91: WrongPaddingException
92: {
93: if (! isMasked() || payload == null)
94: return;
95: IMode mode = getMode(key, iv, IMode.DECRYPTION);
96: IPad padding = null;
97: padding = PadFactory.getInstance("PKCS7");
98: padding.init(mode.currentBlockSize());
99: byte[] buf = new byte[payload.length];
100: int count = 0;
101: for (int i = 0; i < payload.length; i++)
102: {
103: mode.update(payload, count, buf, count);
104: count += mode.currentBlockSize();
105: }
106: int padlen = padding.unpad(buf, 0, buf.length);
107: int len = buf.length - padlen;
108: DataInputStream in = new DataInputStream(new ByteArrayInputStream(buf, 0, len));
109: try
110: {
111: decodeEnvelope(in);
112: }
113: catch (IOException ioe)
114: {
115: throw new IllegalArgumentException("decryption failed");
116: }
117: setMasked(false);
118: payload = null;
119: }
120:
121: public void encrypt(byte[] key, byte[] iv) throws IOException
122: {
123: IMode mode = getMode(key, iv, IMode.ENCRYPTION);
124: IPad pad = PadFactory.getInstance("PKCS7");
125: pad.init(mode.currentBlockSize());
126: ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
127: DataOutputStream out2 = new DataOutputStream(bout);
128: for (Iterator it = entries.iterator(); it.hasNext();)
129: {
130: Entry entry = (Entry) it.next();
131: entry.encode(out2);
132: }
133: byte[] plaintext = bout.toByteArray();
134: byte[] padding = pad.pad(plaintext, 0, plaintext.length);
135: payload = new byte[plaintext.length + padding.length];
136: byte[] lastBlock = new byte[mode.currentBlockSize()];
137: int l = mode.currentBlockSize() - padding.length;
138: System.arraycopy(plaintext, plaintext.length - l, lastBlock, 0, l);
139: System.arraycopy(padding, 0, lastBlock, l, padding.length);
140: int count = 0;
141: while (count + mode.currentBlockSize() < plaintext.length)
142: {
143: mode.update(plaintext, count, payload, count);
144: count += mode.currentBlockSize();
145: }
146: mode.update(lastBlock, 0, payload, count);
147: }
148:
149: public void encodePayload() throws IOException
150: {
151: if (payload == null)
152: throw new IOException("not encrypted");
153: }
154:
155: private IMode getMode(byte[] key, byte[] iv, int state)
156: {
157: IBlockCipher cipher = CipherFactory.getInstance(properties.get("cipher"));
158: if (cipher == null)
159: throw new IllegalArgumentException("no such cipher: " + properties.get("cipher"));
160: int blockSize = cipher.defaultBlockSize();
161: if (properties.containsKey("block-size"))
162: {
163: try
164: {
165: blockSize = Integer.parseInt(properties.get("block-size"));
166: }
167: catch (NumberFormatException nfe)
168: {
169: throw new IllegalArgumentException("bad block size: "
170: + nfe.getMessage());
171: }
172: }
173: IMode mode = ModeFactory.getInstance(properties.get("mode"), cipher, blockSize);
174: if (mode == null)
175: throw new IllegalArgumentException("no such mode: " + properties.get("mode"));
176:
177: HashMap modeAttr = new HashMap();
178: modeAttr.put(IMode.KEY_MATERIAL, key);
179: modeAttr.put(IMode.STATE, Integer.valueOf(state));
180: modeAttr.put(IMode.IV, iv);
181: try
182: {
183: mode.init(modeAttr);
184: }
185: catch (InvalidKeyException ike)
186: {
187: throw new IllegalArgumentException(ike.toString());
188: }
189: return mode;
190: }
191: }