1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.crypto.password.internal.pbe.factory

File BcPBES2Rc2CipherFactory.java

 

Coverage histogram

../../../../../../../img/srcFileCovDistChart5.png
76% of files have more coverage

Code metrics

20
64
9
1
202
156
26
0.41
7.11
9
2.89

Classes

Class Line # Actions
BcPBES2Rc2CipherFactory 51 64 0% 26 46
0.5053763450.5%
 

Contributing tests

This file is covered by 1 test. .

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.password.internal.pbe.factory;
21   
22    import java.math.BigInteger;
23   
24    import javax.inject.Inject;
25    import javax.inject.Named;
26    import javax.inject.Singleton;
27   
28    import org.bouncycastle.asn1.pkcs.EncryptionScheme;
29    import org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
30    import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
31    import org.bouncycastle.asn1.pkcs.RC2CBCParameter;
32    import org.xwiki.component.annotation.Component;
33    import org.xwiki.crypto.cipher.CipherFactory;
34    import org.xwiki.crypto.params.cipher.symmetric.KeyParameter;
35    import org.xwiki.crypto.params.cipher.symmetric.KeyWithIVParameters;
36    import org.xwiki.crypto.params.cipher.symmetric.RC2KeyParameters;
37    import org.xwiki.crypto.params.cipher.symmetric.SymmetricCipherParameters;
38    import org.xwiki.crypto.password.KeyDerivationFunction;
39    import org.xwiki.crypto.password.PasswordBasedCipher;
40    import org.xwiki.crypto.password.internal.pbe.AbstractBcPBES2Cipher;
41    import org.xwiki.crypto.password.params.KeyDerivationFunctionParameters;
42   
43    /**
44    * Implement PBES2 encryption scheme with RC2 encryption.
45    *
46    * @version $Id: d701dcadfac13c952a91bca8c9cdf7c58ab0f6b8 $
47    * @since 5.4M1
48    */
49    @Component(hints = { "PBES2-RC2-CBC-Pad", "1.2.840.113549.3.2" })
50    @Singleton
 
51    public class BcPBES2Rc2CipherFactory extends AbstractBcPBES2CipherFactory
52    {
53    @Inject
54    @Named("RC2/CBC/PKCS5Padding")
55    private CipherFactory cipherFactory;
56   
 
57  3 toggle @Override
58    protected CipherFactory getCipherFactory()
59    {
60  3 return this.cipherFactory;
61    }
62   
 
63  1 toggle @Override
64    public PasswordBasedCipher getInstance(boolean forEncryption, SymmetricCipherParameters password,
65    KeyDerivationFunctionParameters parameters)
66    {
67  1 KeyDerivationFunction kdf = getKDFFactory().getInstance(parameters);
68   
69  1 if (kdf.getKeySize() < 0 || !isSupportedKeySize(kdf.getKeySize())) {
70  0 KeyParameter keyPass;
71  0 if (password instanceof KeyWithIVParameters) {
72  0 keyPass = ((KeyWithIVParameters) password).getKeyParameter();
73    } else {
74  0 keyPass = (KeyParameter) password;
75    }
76  0 if (keyPass instanceof RC2KeyParameters) {
77  0 kdf.overrideKeySize((((RC2KeyParameters) keyPass).getEffectiveBits() + 7) / 8);
78    } else {
79  0 kdf.overrideKeySize(getKeySize());
80    }
81    }
82   
83  1 return getInstance(forEncryption, password, kdf);
84    }
85   
 
86  1 toggle @Override
87    public PasswordBasedCipher getInstance(boolean forEncryption, SymmetricCipherParameters password,
88    KeyDerivationFunction kdf)
89    {
90  1 KeyWithIVParameters params;
91   
92  1 if (password instanceof KeyWithIVParameters) {
93  1 KeyParameter passkey = ((KeyWithIVParameters) password).getKeyParameter();
94  1 if (passkey instanceof RC2KeyParameters) {
95  0 params = new KeyWithIVParameters(
96    new RC2KeyParameters(kdf.derive(passkey.getKey()).getKey(),
97    ((RC2KeyParameters) passkey).getEffectiveBits()),
98    ((KeyWithIVParameters) password).getIV());
99    } else {
100  1 params = new KeyWithIVParameters(kdf.derive(((KeyWithIVParameters) password).getKey()),
101    ((KeyWithIVParameters) password).getIV());
102    }
103  0 } else if (password instanceof RC2KeyParameters) {
104  0 params = kdf.derive(((KeyParameter) password).getKey(), getIVSize());
105  0 params = new KeyWithIVParameters(new RC2KeyParameters(params.getKey(),
106    ((RC2KeyParameters) password).getEffectiveBits()), params.getIV());
107  0 } else if (password instanceof KeyParameter) {
108  0 params = kdf.derive(((KeyParameter) password).getKey(), getIVSize());
109    } else {
110  0 throw new IllegalArgumentException("Invalid cipher parameters for RC2 password based cipher: "
111    + password.getClass().getName());
112    }
113   
114    // ensure RC2Version is computable
115  1 getRC2Version(params);
116   
117  1 return getPasswordBasedCipher(forEncryption, kdf, params);
118    }
119   
 
120  2 toggle @Override
121    protected PasswordBasedCipher getPasswordBasedCipher(boolean forEncryption, KeyDerivationFunction kdf,
122    SymmetricCipherParameters params)
123    {
124  2 return new AbstractBcPBES2Cipher(getCipherFactory().getInstance(forEncryption, params), kdf, params)
125    {
 
126  1 toggle @Override
127    protected EncryptionScheme getScheme(SymmetricCipherParameters parameters)
128    {
129  1 return new EncryptionScheme(PKCSObjectIdentifiers.RC2_CBC,
130    new RC2CBCParameter(getRC2Version((KeyWithIVParameters) parameters),
131    ((KeyWithIVParameters) parameters).getIV()));
132    }
133    };
134    }
135   
 
136  1 toggle @Override
137    protected PasswordBasedCipher getInstance(boolean forEncryption, byte[] password, KeyDerivationFunc kdfParams,
138    EncryptionScheme scheme)
139    {
140  1 KeyDerivationFunction kdf = getKeyDerivationFunction(kdfParams);
141  1 RC2CBCParameter rc2Params = RC2CBCParameter.getInstance(scheme.getParameters());
142   
143  1 return getPasswordBasedCipher(forEncryption, kdf, getRC2CipherParameters(password, rc2Params, kdf));
144    }
145   
 
146  2 toggle private int getRC2Version(KeyWithIVParameters parameters)
147    {
148  2 KeyParameter keyParams = parameters.getKeyParameter();
149  2 int keySize;
150  2 if (keyParams instanceof RC2KeyParameters) {
151  0 keySize = ((RC2KeyParameters) keyParams).getEffectiveBits();
152    } else {
153  2 keySize = keyParams.getKey().length * 8;
154    }
155   
156  2 switch (keySize) {
157  0 case 40:
158  0 return 160;
159  0 case 64:
160  0 return 120;
161  2 case 128:
162  2 return 58;
163  0 default:
164  0 if (keySize < 256) {
165  0 throw new IllegalArgumentException("Invalid cipher key size for PBES2 RC2 password based cipher: "
166    + keySize + " bits. Valid key size are 40, 64, 128 and 256 and more.");
167    }
168  0 return keySize;
169    }
170    }
171   
 
172  1 toggle private SymmetricCipherParameters getRC2CipherParameters(byte[] password, RC2CBCParameter rc2Params,
173    KeyDerivationFunction df)
174    {
175  1 KeyParameter keyParam;
176  1 BigInteger version = rc2Params.getRC2ParameterVersion();
177  1 if (version != null) {
178  1 int bits = getRC2EffectiveBits(version.intValue());
179  1 df.overrideKeySize((bits + 7) / 8);
180  1 keyParam = new RC2KeyParameters(df.derive(password).getKey(), bits);
181    } else {
182  0 df.overrideKeySize(4);
183  0 keyParam = new KeyParameter(df.derive(password).getKey());
184    }
185   
186  1 return new KeyWithIVParameters(keyParam, rc2Params.getIV());
187    }
188   
 
189  1 toggle private int getRC2EffectiveBits(int version)
190    {
191  1 switch (version) {
192  0 case 160:
193  0 return 40;
194  0 case 120:
195  0 return 64;
196  1 case 58:
197  1 return 128;
198  0 default:
199  0 return version;
200    }
201    }
202    }