1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.crypto.cipher.internal.symmetric

File BcSymmetricCipher.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

12
43
14
1
201
128
24
0.56
3.07
14
1.71

Classes

Class Line # Actions
BcSymmetricCipher 46 43 0% 24 18
0.7391304473.9%
 

Contributing tests

This file is covered by 78 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.crypto.cipher.internal.symmetric;
21   
22    import java.io.FilterInputStream;
23    import java.io.FilterOutputStream;
24    import java.io.InputStream;
25    import java.io.OutputStream;
26    import java.security.GeneralSecurityException;
27   
28    import javax.crypto.BadPaddingException;
29    import javax.crypto.IllegalBlockSizeException;
30   
31    import org.bouncycastle.crypto.BlockCipher;
32    import org.bouncycastle.crypto.BufferedBlockCipher;
33    import org.bouncycastle.crypto.CipherParameters;
34    import org.bouncycastle.crypto.DataLengthException;
35    import org.bouncycastle.crypto.InvalidCipherTextException;
36    import org.bouncycastle.crypto.io.CipherInputStream;
37    import org.bouncycastle.crypto.io.CipherOutputStream;
38    import org.xwiki.crypto.cipher.SymmetricCipher;
39   
40    /**
41    * Base class for Bouncy Castle symmetric ciphers.
42    *
43    * @version $Id: ae69bf8cc3f738efa6a7ed7e67f37ae19abb0774 $
44    * @since 5.4M1
45    */
 
46    public class BcSymmetricCipher implements SymmetricCipher
47    {
48    /** The underlying cipher. */
49    protected final BufferedBlockCipher cipher;
50   
51    /** True if the cipher is initialized for encryption. */
52    protected final boolean forEncryption;
53   
54    /**
55    * Generic Bouncy Castle based block cipher.
56    *
57    * @param cipher the block cipher to encapsulate, it will get buffered.
58    * @param forEncryption true if the block cipher is setup for encryption.
59    * @param parameters parameters to initialize the cipher.
60    */
 
61  0 toggle BcSymmetricCipher(BlockCipher cipher, boolean forEncryption, CipherParameters parameters)
62    {
63  0 this.cipher = new BufferedBlockCipher(cipher);
64  0 this.forEncryption = forEncryption;
65  0 cipher.init(forEncryption, parameters);
66    }
67   
68    /**
69    * Generic Bouncy Castle based block cipher.
70    *
71    * @param cipher the buffered block cipher to encapsulate.
72    * @param forEncryption true if the block cipher is setup for encryption.
73    * @param parameters parameters to initialize the cipher.
74    */
 
75  43 toggle BcSymmetricCipher(BufferedBlockCipher cipher, boolean forEncryption, CipherParameters parameters)
76    {
77  43 this.cipher = cipher;
78  43 this.forEncryption = forEncryption;
79  43 cipher.init(forEncryption, parameters);
80    }
81   
 
82  0 toggle @Override
83    public String getAlgorithmName()
84    {
85  0 return this.cipher.getUnderlyingCipher().getAlgorithmName();
86    }
87   
 
88  0 toggle @Override
89    public int getInputBlockSize()
90    {
91  0 return this.cipher.getBlockSize();
92    }
93   
 
94  57 toggle @Override
95    public int getOutputBlockSize()
96    {
97  57 return this.cipher.getBlockSize();
98    }
99   
 
100  14 toggle @Override
101    public boolean isForEncryption()
102    {
103  14 return this.forEncryption;
104    }
105   
 
106  28 toggle @Override
107    public FilterInputStream getInputStream(InputStream is)
108    {
109  28 this.cipher.reset();
110  28 return new CipherInputStream(is, this.cipher);
111    }
112   
 
113  28 toggle @Override
114    public FilterOutputStream getOutputStream(OutputStream os)
115    {
116  28 this.cipher.reset();
117  28 return new CipherOutputStream(os, this.cipher);
118    }
119   
 
120  0 toggle @Override
121    public byte[] update(byte[] input)
122    {
123  0 if (input != null) {
124  0 return update(input, 0, input.length);
125    } else {
126  0 return update(null, 0, 0);
127    }
128    }
129   
 
130  112 toggle @Override
131    public byte[] update(byte[] input, int inputOffset, int inputLen)
132    {
133  112 int len = this.cipher.getUpdateOutputSize(inputLen);
134   
135  112 if (input == null || len == 0) {
136  28 this.cipher.processBytes(input, inputOffset, inputLen, null, 0);
137  28 return null;
138    }
139   
140  84 byte[] out = new byte[len];
141  84 return shrinkBuffer(out, this.cipher.processBytes(input, inputOffset, inputLen, out, 0));
142    }
143   
 
144  28 toggle @Override
145    public byte[] doFinal() throws GeneralSecurityException
146    {
147  28 return doFinal(null, 0, 0);
148    }
149   
 
150  70 toggle @Override
151    public byte[] doFinal(byte[] input) throws GeneralSecurityException
152    {
153  70 if (input != null) {
154  70 return doFinal(input, 0, input.length);
155    } else {
156  0 return doFinal(null, 0, 0);
157    }
158    }
159   
 
160  98 toggle @Override
161    public byte[] doFinal(byte[] input, int inputOffset, int inputLen) throws GeneralSecurityException
162    {
163  98 byte[] out = new byte[this.cipher.getOutputSize(inputLen)];
164  98 int len = 0;
165   
166  98 if (input != null && inputLen > 0) {
167  70 len = this.cipher.processBytes(input, inputOffset, inputLen, out, 0);
168    }
169   
170  98 try {
171  98 len += this.cipher.doFinal(out, len);
172    } catch (DataLengthException e) {
173  0 throw new IllegalBlockSizeException(e.getMessage());
174    } catch (InvalidCipherTextException e) {
175  0 throw new BadPaddingException(e.getMessage());
176    }
177  98 return shrinkBuffer(out, len);
178    }
179   
180    /**
181    * Return a buffer of {@code size} bytes containing the {@code size} first byte of {@code buffer}.
182    *
183    * @param buffer the buffer.
184    * @param size the size.
185    * @return null if size is 0, the buffer if it has the right size, or a new truncated copy of buffer.
186    */
 
187  182 toggle private byte[] shrinkBuffer(byte[] buffer, int size)
188    {
189  182 if (size == 0) {
190  7 return null;
191    }
192   
193  175 if (size == buffer.length) {
194  139 return buffer;
195    }
196   
197  36 byte[] output = new byte[size];
198  36 System.arraycopy(buffer, 0, output, 0, size);
199  36 return output;
200    }
201    }