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

File BcPKCS5S2KeyDerivationFunctionFactory.java

 

Coverage histogram

../../../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

40
56
6
1
197
145
27
0.48
9.33
6
4.5

Classes

Class Line # Actions
BcPKCS5S2KeyDerivationFunctionFactory 56 56 0% 27 17
0.833333383.3%
 

Contributing tests

This file is covered by 25 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.kdf.factory;
21   
22    import javax.inject.Inject;
23    import javax.inject.Singleton;
24   
25    import org.bouncycastle.asn1.ASN1Encodable;
26    import org.bouncycastle.asn1.ASN1ObjectIdentifier;
27    import org.bouncycastle.asn1.DERNull;
28    import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
29    import org.bouncycastle.asn1.pkcs.KeyDerivationFunc;
30    import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
31    import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
32    import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
33    import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
34    import org.xwiki.component.annotation.Component;
35    import org.xwiki.component.manager.ComponentLookupException;
36    import org.xwiki.component.manager.ComponentManager;
37    import org.xwiki.crypto.DigestFactory;
38    import org.xwiki.crypto.internal.digest.factory.AbstractBcDigestFactory;
39    import org.xwiki.crypto.internal.digest.factory.BcDigestFactory;
40    import org.xwiki.crypto.password.KeyDerivationFunction;
41    import org.xwiki.crypto.password.internal.kdf.AbstractBcPBKDF2;
42    import org.xwiki.crypto.password.internal.kdf.PBKDF2Params;
43    import org.xwiki.crypto.password.params.KeyDerivationFunctionParameters;
44    import org.xwiki.crypto.password.params.PBKDF2Parameters;
45   
46    /**
47    * Implementation of the key derivation function for PBKDF2 with Hmac SHA-1 digest using Bouncy Castle.
48    *
49    * Functions provided by this factory are conform with the PKCS 5 V2.0 Scheme 2 published as IETF's RFC 2898.
50    *
51    * @version $Id: d9b5a2d930233a1d31b1cb5540796b280b109a11 $
52    * @since 5.4M1
53    */
54    @Component(hints = { "PKCS5S2", "1.2.840.113549.1.5.12" })
55    @Singleton
 
56    public class BcPKCS5S2KeyDerivationFunctionFactory extends AbstractBcKDFFactory
57    {
58    private static final AlgorithmIdentifier HMAC_SHA1 =
59    new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);
60   
61    private static final AlgorithmIdentifier HMAC_SHA224 =
62    new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE);
63   
64    private static final AlgorithmIdentifier HMAC_SHA256 =
65    new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE);
66   
67    private static final AlgorithmIdentifier HMAC_SHA384 =
68    new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE);
69   
70    private static final AlgorithmIdentifier HMAC_SHA512 =
71    new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE);
72   
73    @Inject
74    private ComponentManager manager;
75   
 
76  45 toggle @Override
77    public KeyDerivationFunction getInstance(KeyDerivationFunctionParameters params)
78    {
79  45 if (!(params instanceof PBKDF2Parameters)) {
80  0 throw new IllegalArgumentException("Invalid parameter used for PKCS5S2 function: "
81    + params.getClass().getName());
82    }
83   
84  45 PBKDF2Parameters kdfParams = (PBKDF2Parameters) params;
85  45 PKCS5S2ParametersGenerator generator;
86  45 BcDigestFactory factory = null;
87  45 if (kdfParams.getPseudoRandomFuntionHint() != null) {
88  8 factory = this.getDigestFactory(kdfParams.getPseudoRandomFuntionHint());
89  8 generator = new PKCS5S2ParametersGenerator(factory.getDigestInstance());
90    } else {
91  37 generator = new PKCS5S2ParametersGenerator();
92    }
93   
94  45 return new AbstractBcPBKDF2(generator, (PBKDF2Parameters) params,
95  45 (factory != null) ? toHmacAlgId(factory.getAlgorithmIdentifier()) : HMAC_SHA1)
96    {
 
97  24 toggle @Override
98    public KeyDerivationFunc getKeyDerivationFunction()
99    {
100  24 PBKDF2Parameters parameters = (PBKDF2Parameters) getParameters();
101  24 AlgorithmIdentifier algId = getPRFAlgorithmIdentifier();
102  24 return new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2,
103  24 (isKeySizeOverwritten())
104    ? new PBKDF2Params(parameters.getSalt(), parameters.getIterationCount(), algId)
105    : new PBKDF2Params(parameters.getSalt(), parameters.getIterationCount(),
106    parameters.getKeySize(), algId));
107    }
108    };
109    }
110   
 
111  14 toggle @Override
112    public KeyDerivationFunction getInstance(ASN1Encodable parameters)
113    {
114  14 KeyDerivationFunc kdf = KeyDerivationFunc.getInstance(parameters);
115   
116  14 if (!kdf.getAlgorithm().equals(PKCSObjectIdentifiers.id_PBKDF2)) {
117  0 throw new IllegalArgumentException("Illegal algorithm identifier for PBKDF2: "
118    + kdf.getAlgorithm().getId());
119    }
120   
121  14 PBKDF2Params params = PBKDF2Params.getInstance(kdf.getParameters());
122   
123  14 return getInstance(
124  14 new PBKDF2Parameters((params.getKeyLength() != null) ? params.getKeyLength().intValue() : -1,
125    params.getIterationCount().intValue(),
126    params.getSalt(),
127    toDigestHint(params.getPseudoRandomFunctionIdentifier()))
128    );
129    }
130   
 
131  8 toggle private BcDigestFactory getDigestFactory(String hint)
132    {
133  8 try {
134  8 DigestFactory factory = this.manager.getInstance(DigestFactory.class, hint);
135   
136  8 if (!(factory instanceof BcDigestFactory)) {
137  0 throw new IllegalArgumentException(
138    "Requested digest algorithm is not implemented by a factory compatible with this factory."
139    + " Factory found: " + factory.getClass().getName());
140    }
141   
142  8 return (AbstractBcDigestFactory) factory;
143    } catch (ComponentLookupException e) {
144  0 throw new UnsupportedOperationException("Digest algorithm not found: " + hint, e);
145    }
146    }
147   
 
148  8 toggle private AlgorithmIdentifier toHmacAlgId(AlgorithmIdentifier algorithmIdentifier)
149    {
150  8 ASN1ObjectIdentifier algId = algorithmIdentifier.getAlgorithm();
151  8 AlgorithmIdentifier hmac = null;
152   
153  8 if (algId.equals(X509ObjectIdentifiers.id_SHA1)) {
154  0 hmac = HMAC_SHA1;
155  8 } else if (algId.equals(NISTObjectIdentifiers.id_sha224)) {
156  2 hmac = HMAC_SHA224;
157  6 } else if (algId.equals(NISTObjectIdentifiers.id_sha256)) {
158  2 hmac = HMAC_SHA256;
159  4 } else if (algId.equals(NISTObjectIdentifiers.id_sha384)) {
160  2 hmac = HMAC_SHA384;
161  2 } else if (algId.equals(NISTObjectIdentifiers.id_sha512)) {
162  2 hmac = HMAC_SHA512;
163    }
164  8 if (hmac == null) {
165  0 throw new IllegalArgumentException("HMac algorithm not found for digest: " + algId.getId());
166    }
167   
168  8 return hmac;
169    }
170   
 
171  14 toggle private String toDigestHint(AlgorithmIdentifier algorithmIdentifier)
172    {
173  14 if (algorithmIdentifier == null) {
174  10 return null;
175    }
176   
177  4 ASN1ObjectIdentifier algId = algorithmIdentifier.getAlgorithm();
178  4 String hint = null;
179   
180  4 if (algId.equals(HMAC_SHA1.getAlgorithm())) {
181  0 hint = X509ObjectIdentifiers.id_SHA1.getId();
182  4 } else if (algId.equals(HMAC_SHA224.getAlgorithm())) {
183  1 hint = NISTObjectIdentifiers.id_sha224.getId();
184  3 } else if (algId.equals(HMAC_SHA256.getAlgorithm())) {
185  1 hint = NISTObjectIdentifiers.id_sha256.getId();
186  2 } else if (algId.equals(HMAC_SHA384.getAlgorithm())) {
187  1 hint = NISTObjectIdentifiers.id_sha384.getId();
188  1 } else if (algId.equals(HMAC_SHA512.getAlgorithm())) {
189  1 hint = NISTObjectIdentifiers.id_sha512.getId();
190    }
191  4 if (hint == null) {
192  0 throw new IllegalArgumentException("Digest hint not found for HMac algorithm: " + algId.getId());
193    }
194   
195  4 return hint;
196    }
197    }