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.crypto;
019    
020    import org.bouncycastle.crypto.CipherParameters;
021    import org.bouncycastle.crypto.CryptoException;
022    import org.bouncycastle.crypto.DataLengthException;
023    
024    /**
025     * Abstract base class for {@link Cipher} implementations. Implementors should not implement
026     * the <code>Cipher</code> interface directly, but sub-class this class instead.
027     *
028     * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
029     */
030    public abstract class AbstractCipher implements Cipher
031    {
032            private String transformation;
033    
034            protected AbstractCipher(String transformation)
035            {
036                    if (transformation == null)
037                            throw new IllegalArgumentException("transformation == null");
038    
039                    this.transformation = transformation;
040            }
041    
042            @Override
043            public final String getTransformation() {
044                    return transformation;
045            }
046    
047            public byte[] doFinal(byte[] in)
048            throws DataLengthException, IllegalStateException, CryptoException
049            {
050                    byte[] out = new byte[getOutputSize(in.length)];
051                    int outOff = update(in, 0, in.length, out, 0);
052                    outOff += doFinal(out, outOff);
053    
054                    if (outOff == out.length)
055                            return out;
056    
057                    byte[] truncOut = new byte[outOff];
058                    System.arraycopy(out, 0, truncOut, 0, truncOut.length);
059                    return truncOut;
060            }
061    
062            private CipherOperationMode mode;
063    
064            private CipherParameters parameters;
065    
066            @Override
067            public final void init(CipherOperationMode mode, CipherParameters parameters)
068            throws IllegalArgumentException
069            {
070                    if (mode == null)
071                            throw new IllegalArgumentException("mode == null");
072    
073                    if (parameters == null)
074                            throw new IllegalArgumentException("parameters == null");
075    
076                    this.mode = mode;
077                    this.parameters = parameters;
078    
079                    _init(mode, parameters);
080            }
081    
082            @Override
083            public CipherOperationMode getMode() {
084                    return mode;
085            }
086    
087            @Override
088            public CipherParameters getParameters() {
089                    return parameters;
090            }
091    
092            protected abstract void _init(CipherOperationMode mode, CipherParameters parameters)
093            throws IllegalArgumentException;
094    }