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

File AbstractBcPBES2CipherFactory.java

 

Coverage histogram

../../../../../../../img/srcFileCovDistChart7.png
64% of files have more coverage

Code metrics

12
30
7
1
157
93
17
0.57
4.29
7
2.43

Classes

Class Line # Actions
AbstractBcPBES2CipherFactory 46 30 0% 17 15
0.693877669.4%
 

Contributing tests

This file is covered by 13 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.password.internal.pbe.factory;
21   
22    import java.io.IOException;
23   
24    import org.bouncycastle.asn1.ASN1Encodable;
25    import org.bouncycastle.asn1.ASN1OctetString;
26    import org.bouncycastle.asn1.pkcs.EncryptionScheme;
27    import org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
28    import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
29    import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
30    import org.xwiki.crypto.params.cipher.symmetric.KeyParameter;
31    import org.xwiki.crypto.params.cipher.symmetric.KeyWithIVParameters;
32    import org.xwiki.crypto.params.cipher.symmetric.SymmetricCipherParameters;
33    import org.xwiki.crypto.password.KeyDerivationFunction;
34    import org.xwiki.crypto.password.KeyDerivationFunctionFactory;
35    import org.xwiki.crypto.password.PasswordBasedCipher;
36    import org.xwiki.crypto.password.internal.kdf.PBES2Parameters;
37    import org.xwiki.crypto.password.internal.kdf.factory.AbstractBcKDFFactory;
38    import org.xwiki.crypto.password.params.KeyDerivationFunctionParameters;
39   
40    /**
41    * Abstract base class for PBES2 Password Based Cipher factory using Bouncy Castle as the underlying implementation.
42    *
43    * @version $Id: e18ca3139d4a272449368fcf5b0de2914aac1190 $
44    * @since 5.4M1
45    */
 
46    public abstract class AbstractBcPBES2CipherFactory extends AbstractBcPBCipherFactory
47    {
48    private static final RuntimeException UNSUPPORTED =
49    new UnsupportedOperationException("Sorry, no concrete implementation to create an instance.");
50   
 
51  25 toggle private KeyDerivationFunctionFactory safeGetKDFFactory()
52    {
53  25 try {
54  25 return getKDFFactory();
55    } catch (UnsupportedOperationException e) {
56  0 throw UNSUPPORTED;
57    }
58    }
59   
 
60  13 toggle @Override
61    public PasswordBasedCipher getInstance(boolean forEncryption, byte[] password, ASN1Encodable parameters)
62    {
63  13 AlgorithmIdentifier alg = AlgorithmIdentifier.getInstance(parameters);
64   
65  13 if (!alg.getAlgorithm().equals(PKCSObjectIdentifiers.id_PBES2)) {
66  0 throw new IllegalArgumentException("Illegal algorithm identifier for PBES2: " + alg.getAlgorithm().getId());
67    }
68   
69  13 PBES2Parameters params = PBES2Parameters.getInstance(alg.getParameters());
70  13 return getInstance(forEncryption, password, params.getKeyDerivationFunc(), params.getEncryptionScheme());
71    }
72   
 
73  12 toggle @Override
74    public PasswordBasedCipher getInstance(boolean forEncryption, SymmetricCipherParameters password,
75    KeyDerivationFunctionParameters parameters)
76    {
77  12 KeyDerivationFunction kdf = safeGetKDFFactory().getInstance(parameters);
78   
79  12 if (kdf.getKeySize() < 0 || !isSupportedKeySize(kdf.getKeySize())) {
80  5 kdf.overrideKeySize(getKeySize());
81    }
82   
83  12 return getInstance(forEncryption, password, kdf);
84    }
85   
 
86  12 toggle @Override
87    public PasswordBasedCipher getInstance(boolean forEncryption, SymmetricCipherParameters password,
88    KeyDerivationFunction kdf)
89    {
90  12 SymmetricCipherParameters params;
91   
92  12 if (password instanceof KeyWithIVParameters) {
93  12 params = new KeyWithIVParameters(kdf.derive(((KeyWithIVParameters) password).getKey()),
94    ((KeyWithIVParameters) password).getIV());
95  0 } else if (password instanceof KeyParameter) {
96  0 params = kdf.derive(((KeyParameter) password).getKey(), getIVSize());
97    } else {
98  0 throw new IllegalArgumentException("Invalid cipher parameters for this password based cipher: "
99    + password.getClass().getName());
100    }
101   
102  12 return getPasswordBasedCipher(forEncryption, kdf, params);
103    }
104   
105    /**
106    * @param forEncryption if true the cipher is initialised for encryption, if false for decryption.
107    * @param password the password that will be used to derive the key.
108    * @param kdfParams key derivation function parameters.
109    * @param scheme encryption scheme.
110    * @return a initialized key derivation function with a specific password bytes conversion mode.
111    */
 
112  5 toggle protected PasswordBasedCipher getInstance(boolean forEncryption, byte[] password, KeyDerivationFunc kdfParams,
113    EncryptionScheme scheme)
114    {
115  5 KeyDerivationFunction kdf = getKeyDerivationFunction(kdfParams);
116   
117    // Fix key size if needed.
118  5 if (kdf.getKeySize() < 0 || !isSupportedKeySize(kdf.getKeySize())) {
119  3 kdf.overrideKeySize(getKeySize());
120    }
121   
122  5 return getPasswordBasedCipher(forEncryption, kdf, new KeyWithIVParameters(kdf.derive(password).getKey(),
123    ((ASN1OctetString) scheme.getParameters()).getOctets()));
124    }
125   
126    /**
127    * Create a new instance of a password based cipher.
128    *
129    * @param forEncryption if true the cipher is initialised for encryption, if false for decryption.
130    * @param kdf the key derivation function
131    * @param params the cipher parameters
132    * @return a initialized password based cipher.
133    */
 
134  0 toggle protected PasswordBasedCipher getPasswordBasedCipher(boolean forEncryption, final KeyDerivationFunction kdf,
135    SymmetricCipherParameters params)
136    {
137  0 throw UNSUPPORTED;
138    }
139   
 
140  13 toggle protected KeyDerivationFunction getKeyDerivationFunction(KeyDerivationFunc func)
141    {
142  13 KeyDerivationFunctionFactory kdfFactory = safeGetKDFFactory();
143   
144    // Optimization
145  13 if (kdfFactory instanceof AbstractBcKDFFactory) {
146  13 return ((AbstractBcKDFFactory) kdfFactory).getInstance(func);
147    }
148   
149    // Generic fallback
150  0 try {
151  0 return kdfFactory.getInstance(func.toASN1Primitive().getEncoded());
152    } catch (IOException e) {
153    // Very unlikely to happen
154  0 throw new RuntimeException("Unexpected exception during parameter encoding");
155    }
156    }
157    }