1 package org.bouncycastle.operator.jcajce;
2 
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.security.AlgorithmParameters;
6 import java.security.GeneralSecurityException;
7 import java.security.KeyFactory;
8 import java.security.KeyPairGenerator;
9 import java.security.MessageDigest;
10 import java.security.NoSuchAlgorithmException;
11 import java.security.NoSuchProviderException;
12 import java.security.PublicKey;
13 import java.security.Signature;
14 import java.security.cert.CertificateException;
15 import java.security.cert.CertificateFactory;
16 import java.security.cert.X509Certificate;
17 import java.security.spec.InvalidKeySpecException;
18 import java.security.spec.PSSParameterSpec;
19 import java.security.spec.X509EncodedKeySpec;
20 import java.util.HashMap;
21 import java.util.Map;
22 
23 import javax.crypto.Cipher;
24 import javax.crypto.KeyAgreement;
25 
26 import org.bouncycastle.asn1.ASN1Encodable;
27 import org.bouncycastle.asn1.ASN1Integer;
28 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
29 import org.bouncycastle.asn1.ASN1Sequence;
30 import org.bouncycastle.asn1.DERNull;
31 import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
32 import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
33 import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
34 import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
35 import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
36 import org.bouncycastle.asn1.isara.IsaraObjectIdentifiers;
37 import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
38 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
39 import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
40 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
41 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
42 import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
43 import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
44 import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
45 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
46 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
47 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
48 import org.bouncycastle.cert.X509CertificateHolder;
49 import org.bouncycastle.cms.CMSException;
50 import org.bouncycastle.jcajce.util.AlgorithmParametersUtils;
51 import org.bouncycastle.jcajce.util.JcaJceHelper;
52 import org.bouncycastle.jcajce.util.MessageDigestUtils;
53 import org.bouncycastle.operator.OperatorCreationException;
54 import org.bouncycastle.util.Integers;
55 
56 class OperatorHelper
57 {
58     private static final Map oids = new HashMap();
59     private static final Map asymmetricWrapperAlgNames = new HashMap();
60     private static final Map symmetricWrapperAlgNames = new HashMap();
61     private static final Map symmetricKeyAlgNames = new HashMap();
62     private static final Map symmetricWrapperKeySizes = new HashMap();
63 
64     static
65     {
66         //
67         // reverse mappings
68         //
oids.put(EdECObjectIdentifiers.id_Ed25519, R)69         oids.put(EdECObjectIdentifiers.id_Ed25519, "Ed25519");
oids.put(EdECObjectIdentifiers.id_Ed448, R)70         oids.put(EdECObjectIdentifiers.id_Ed448, "Ed448");
oids.put(new ASN1ObjectIdentifier(R), R)71         oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, R)72         oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, R)73         oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, R)74         oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, R)75         oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, R)76         oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE128, "SHAKE128WITHRSAPSS");
oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, R)77         oids.put(CMSObjectIdentifiers.id_RSASSA_PSS_SHAKE256, "SHAKE256WITHRSAPSS");
oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, R)78         oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, R)79         oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, R)80         oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256WITHECGOST3410-2012-256");
oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, R)81         oids.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512WITHECGOST3410-2012-512");
oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, R)82         oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, R)83         oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, R)84         oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, R)85         oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, R)86         oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, R)87         oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, R)88         oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, R)89         oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, R)90         oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, R)91         oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, R)92         oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
oids.put(IsaraObjectIdentifiers.id_alg_xmss, R)93         oids.put(IsaraObjectIdentifiers.id_alg_xmss, "XMSS");
oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, R)94         oids.put(IsaraObjectIdentifiers.id_alg_xmssmt, "XMSSMT");
95 
oids.put(new ASN1ObjectIdentifier(R), R)96         oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
oids.put(new ASN1ObjectIdentifier(R), R)97         oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
oids.put(new ASN1ObjectIdentifier(R), R)98         oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, R)99         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, R)100         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, R)101         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, R)102         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, R)103         oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, R)104         oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake128, "SHAKE128WITHECDSA");
oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, R)105         oids.put(CMSObjectIdentifiers.id_ecdsa_with_shake256, "SHAKE256WITHECDSA");
oids.put(OIWObjectIdentifiers.sha1WithRSA, R)106         oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
oids.put(OIWObjectIdentifiers.dsaWithSHA1, R)107         oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
oids.put(NISTObjectIdentifiers.dsa_with_sha224, R)108         oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
oids.put(NISTObjectIdentifiers.dsa_with_sha256, R)109         oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
110 
oids.put(OIWObjectIdentifiers.idSHA1, R)111         oids.put(OIWObjectIdentifiers.idSHA1, "SHA1");
oids.put(NISTObjectIdentifiers.id_sha224, R)112         oids.put(NISTObjectIdentifiers.id_sha224, "SHA224");
oids.put(NISTObjectIdentifiers.id_sha256, R)113         oids.put(NISTObjectIdentifiers.id_sha256, "SHA256");
oids.put(NISTObjectIdentifiers.id_sha384, R)114         oids.put(NISTObjectIdentifiers.id_sha384, "SHA384");
oids.put(NISTObjectIdentifiers.id_sha512, R)115         oids.put(NISTObjectIdentifiers.id_sha512, "SHA512");
oids.put(TeleTrusTObjectIdentifiers.ripemd128, R)116         oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
oids.put(TeleTrusTObjectIdentifiers.ripemd160, R)117         oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
oids.put(TeleTrusTObjectIdentifiers.ripemd256, R)118         oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
119 
asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, R)120         asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
121 
asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, R)122         asymmetricWrapperAlgNames.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410");
123 
symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, R)124         symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap");
symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, R)125         symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap");
symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, R)126         symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap");
symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, R)127         symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap");
symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, R)128         symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap");
symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, R)129         symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap");
symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, R)130         symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap");
symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, R)131         symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap");
symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, R)132         symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap");
symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, R)133         symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
134 
symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, Integers.valueOf(192))135         symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, Integers.valueOf(192));
symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes128_wrap, Integers.valueOf(128))136         symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes128_wrap, Integers.valueOf(128));
symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes192_wrap, Integers.valueOf(192))137         symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes192_wrap, Integers.valueOf(192));
symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes256_wrap, Integers.valueOf(256))138         symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes256_wrap, Integers.valueOf(256));
symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia128_wrap, Integers.valueOf(128))139         symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia128_wrap, Integers.valueOf(128));
symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia192_wrap, Integers.valueOf(192))140         symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia192_wrap, Integers.valueOf(192));
symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia256_wrap, Integers.valueOf(256))141         symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia256_wrap, Integers.valueOf(256));
symmetricWrapperKeySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, Integers.valueOf(128))142         symmetricWrapperKeySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, Integers.valueOf(128));
symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192))143         symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
144 
symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, R)145         symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES");
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, R)146         symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES");
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, R)147         symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES");
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, R)148         symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES");
symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, R)149         symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, R)150         symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2");
151     }
152 
153     private JcaJceHelper helper;
154 
OperatorHelper(JcaJceHelper helper)155     OperatorHelper(JcaJceHelper helper)
156     {
157         this.helper = helper;
158     }
159 
getWrappingAlgorithmName(ASN1ObjectIdentifier algOid)160     String getWrappingAlgorithmName(ASN1ObjectIdentifier algOid)
161     {
162         return (String)symmetricWrapperAlgNames.get(algOid);
163     }
164 
getKeySizeInBits(ASN1ObjectIdentifier algOid)165     int getKeySizeInBits(ASN1ObjectIdentifier algOid)
166     {
167         return ((Integer)symmetricWrapperKeySizes.get(algOid)).intValue();
168     }
169 
createKeyPairGenerator(ASN1ObjectIdentifier algorithm)170     KeyPairGenerator createKeyPairGenerator(ASN1ObjectIdentifier algorithm)
171         throws CMSException
172     {
173         try
174         {
175             String agreementName = null; //(String)BASE_CIPHER_NAMES.get(algorithm);
176 
177             if (agreementName != null)
178             {
179                 try
180                 {
181                     // this is reversed as the Sun policy files now allow unlimited strength RSA
182                     return helper.createKeyPairGenerator(agreementName);
183                 }
184                 catch (NoSuchAlgorithmException e)
185                 {
186                     // Ignore
187                 }
188             }
189             return helper.createKeyPairGenerator(algorithm.getId());
190         }
191         catch (GeneralSecurityException e)
192         {
193             throw new CMSException("cannot create key agreement: " + e.getMessage(), e);
194         }
195     }
196 
createCipher(ASN1ObjectIdentifier algorithm)197     Cipher createCipher(ASN1ObjectIdentifier algorithm)
198         throws OperatorCreationException
199     {
200         try
201         {
202             return helper.createCipher(algorithm.getId());
203         }
204         catch (GeneralSecurityException e)
205         {
206             throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
207         }
208     }
209 
createKeyAgreement(ASN1ObjectIdentifier algorithm)210     KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm)
211         throws OperatorCreationException
212     {
213         try
214         {
215             String agreementName = null; //(String)BASE_CIPHER_NAMES.get(algorithm);
216 
217             if (agreementName != null)
218             {
219                 try
220                 {
221                     // this is reversed as the Sun policy files now allow unlimited strength RSA
222                     return helper.createKeyAgreement(agreementName);
223                 }
224                 catch (NoSuchAlgorithmException e)
225                 {
226                     // Ignore
227                 }
228             }
229             return helper.createKeyAgreement(algorithm.getId());
230         }
231         catch (GeneralSecurityException e)
232         {
233             throw new OperatorCreationException("cannot create key agreement: " + e.getMessage(), e);
234         }
235     }
236 
createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames)237     Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames)
238         throws OperatorCreationException
239     {
240         try
241         {
242             String cipherName = null;
243 
244             if (!extraAlgNames.isEmpty())
245             {
246                 cipherName = (String)extraAlgNames.get(algorithm);
247             }
248 
249             if (cipherName == null)
250             {
251                 cipherName = (String)asymmetricWrapperAlgNames.get(algorithm);
252             }
253 
254             if (cipherName != null)
255             {
256                 try
257                 {
258                     // this is reversed as the Sun policy files now allow unlimited strength RSA
259                     return helper.createCipher(cipherName);
260                 }
261                 catch (NoSuchAlgorithmException e)
262                 {
263                     // try alternate for RSA
264                     if (cipherName.equals("RSA/ECB/PKCS1Padding"))
265                     {
266                         try
267                         {
268                             return helper.createCipher("RSA/NONE/PKCS1Padding");
269                         }
270                         catch (NoSuchAlgorithmException ex)
271                         {
272                             // Ignore
273                         }
274                     }
275                     // Ignore
276                 }
277             }
278 
279             return helper.createCipher(algorithm.getId());
280         }
281         catch (GeneralSecurityException e)
282         {
283             throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
284         }
285     }
286 
createSymmetricWrapper(ASN1ObjectIdentifier algorithm)287     Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm)
288         throws OperatorCreationException
289     {
290         try
291         {
292             String cipherName = (String)symmetricWrapperAlgNames.get(algorithm);
293 
294             if (cipherName != null)
295             {
296                 try
297                 {
298                     // this is reversed as the Sun policy files now allow unlimited strength RSA
299                     return helper.createCipher(cipherName);
300                 }
301                 catch (NoSuchAlgorithmException e)
302                 {
303                     // Ignore
304                 }
305             }
306             return helper.createCipher(algorithm.getId());
307         }
308         catch (GeneralSecurityException e)
309         {
310             throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
311         }
312     }
313 
createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)314     AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
315         throws OperatorCreationException
316     {
317         AlgorithmParameters parameters;
318 
319         if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
320         {
321             return null;
322         }
323 
324         try
325         {
326             parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
327         }
328         catch (NoSuchAlgorithmException e)
329         {
330             return null;   // There's a good chance there aren't any!
331         }
332         catch (NoSuchProviderException e)
333         {
334             throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
335         }
336 
337         try
338         {
339             parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
340         }
341         catch (IOException e)
342         {
343             throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
344         }
345 
346         return parameters;
347     }
348 
createDigest(AlgorithmIdentifier digAlgId)349     MessageDigest createDigest(AlgorithmIdentifier digAlgId)
350         throws GeneralSecurityException
351     {
352         MessageDigest dig;
353 
354         try
355         {
356             if (digAlgId.getAlgorithm().equals(NISTObjectIdentifiers.id_shake256_len))
357             {
358                 dig = helper.createMessageDigest("SHAKE256-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
359             }
360             else if (digAlgId.getAlgorithm().equals(NISTObjectIdentifiers.id_shake128_len))
361             {
362                 dig = helper.createMessageDigest("SHAKE128-" + ASN1Integer.getInstance(digAlgId.getParameters()).getValue());
363             }
364             else
365             {
366                 dig = helper.createMessageDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
367             }
368         }
369         catch (NoSuchAlgorithmException e)
370         {
371             //
372             // try an alternate
373             //
374             if (oids.get(digAlgId.getAlgorithm()) != null)
375             {
376                 String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm());
377 
378                 dig = helper.createMessageDigest(digestAlgorithm);
379             }
380             else
381             {
382                 throw e;
383             }
384         }
385 
386         return dig;
387     }
388 
createSignature(AlgorithmIdentifier sigAlgId)389     Signature createSignature(AlgorithmIdentifier sigAlgId)
390         throws GeneralSecurityException
391     {
392         String sigName = getSignatureName(sigAlgId);
393         Signature sig;
394 
395         try
396         {
397             sig = helper.createSignature(sigName);
398         }
399         catch (NoSuchAlgorithmException e)
400         {
401             //
402             // try an alternate
403             //
404             if (sigName.endsWith("WITHRSAANDMGF1"))
405             {
406                 String signatureAlgorithm =
407                     sigName.substring(0, sigName.indexOf('W')) + "WITHRSASSA-PSS";
408 
409                 sig = helper.createSignature(signatureAlgorithm);
410             }
411             else if (oids.get(sigAlgId.getAlgorithm()) != null)
412             {
413                 String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
414 
415                 sig = helper.createSignature(signatureAlgorithm);
416             }
417             else
418             {
419                 throw e;
420             }
421         }
422 
423         if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
424         {
425             ASN1Sequence seq = ASN1Sequence.getInstance(sigAlgId.getParameters());
426 
427             if (notDefaultPSSParams(seq))
428             {
429                 try
430                 {
431                     AlgorithmParameters algParams = helper.createAlgorithmParameters("PSS");
432 
433                     algParams.init(seq.getEncoded());
434 
435                     sig.setParameter(algParams.getParameterSpec(PSSParameterSpec.class));
436                 }
437                 catch (IOException e)
438                 {
439                     throw new GeneralSecurityException("unable to process PSS parameters: " + e.getMessage());
440                 }
441             }
442         }
443 
444         return sig;
445     }
446 
createRawSignature(AlgorithmIdentifier algorithm)447     public Signature createRawSignature(AlgorithmIdentifier algorithm)
448     {
449         Signature sig;
450 
451         try
452         {
453             String algName = getSignatureName(algorithm);
454 
455             algName = "NONE" + algName.substring(algName.indexOf("WITH"));
456 
457             sig = helper.createSignature(algName);
458 
459             // RFC 4056
460             // When the id-RSASSA-PSS algorithm identifier is used for a signature,
461             // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
462             if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
463             {
464                 AlgorithmParameters params = helper.createAlgorithmParameters(algName);
465 
466                 AlgorithmParametersUtils.loadParameters(params, algorithm.getParameters());
467 
468                 PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
469                 sig.setParameter(spec);
470             }
471         }
472         catch (Exception e)
473         {
474             return null;
475         }
476 
477         return sig;
478     }
479 
getSignatureName( AlgorithmIdentifier sigAlgId)480     private static String getSignatureName(
481         AlgorithmIdentifier sigAlgId)
482     {
483         ASN1Encodable params = sigAlgId.getParameters();
484 
485         if (params != null && !DERNull.INSTANCE.equals(params))
486         {
487             if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
488             {
489                 RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
490                 return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
491             }
492         }
493 
494         if (oids.containsKey(sigAlgId.getAlgorithm()))
495         {
496             return (String)oids.get(sigAlgId.getAlgorithm());
497         }
498 
499         return sigAlgId.getAlgorithm().getId();
500     }
501 
502     // we need to remove the - to create a correct signature name
getDigestName(ASN1ObjectIdentifier oid)503     private static String getDigestName(ASN1ObjectIdentifier oid)
504     {
505         String name = MessageDigestUtils.getDigestName(oid);
506 
507         int dIndex = name.indexOf('-');
508         if (dIndex > 0 && !name.startsWith("SHA3"))
509         {
510             return name.substring(0, dIndex) + name.substring(dIndex + 1);
511         }
512 
513         return name;
514     }
515 
convertCertificate(X509CertificateHolder certHolder)516     public X509Certificate convertCertificate(X509CertificateHolder certHolder)
517         throws CertificateException
518     {
519         try
520         {
521             CertificateFactory certFact = helper.createCertificateFactory("X.509");
522 
523             return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded()));
524         }
525         catch (IOException e)
526         {
527             throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e);
528         }
529         catch (NoSuchProviderException e)
530         {
531             throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e);
532         }
533     }
534 
convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)535     public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
536         throws OperatorCreationException
537     {
538         try
539         {
540             KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
541 
542             return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
543         }
544         catch (IOException e)
545         {
546             throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
547         }
548         catch (NoSuchAlgorithmException e)
549         {
550             throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
551         }
552         catch (NoSuchProviderException e)
553         {
554             throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
555         }
556         catch (InvalidKeySpecException e)
557         {
558             throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
559         }
560     }
561 
562     // TODO: put somewhere public so cause easily accessed
563     private static class OpCertificateException
564         extends CertificateException
565     {
566         private Throwable cause;
567 
OpCertificateException(String msg, Throwable cause)568         public OpCertificateException(String msg, Throwable cause)
569         {
570             super(msg);
571 
572             this.cause = cause;
573         }
574 
getCause()575         public Throwable getCause()
576         {
577             return cause;
578         }
579     }
580 
getKeyAlgorithmName(ASN1ObjectIdentifier oid)581     String getKeyAlgorithmName(ASN1ObjectIdentifier oid)
582     {
583 
584         String name = (String)symmetricKeyAlgNames.get(oid);
585 
586         if (name != null)
587         {
588             return name;
589         }
590 
591         return oid.getId();
592     }
593 
594     // for our purposes default includes varient digest with salt the same size as digest
notDefaultPSSParams(ASN1Sequence seq)595     private boolean notDefaultPSSParams(ASN1Sequence seq)
596         throws GeneralSecurityException
597     {
598         if (seq == null || seq.size() == 0)
599         {
600             return false;
601         }
602 
603         RSASSAPSSparams pssParams = RSASSAPSSparams.getInstance(seq);
604 
605         if (!pssParams.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
606         {
607             return true;
608         }
609 
610         // same digest for sig and MGF1
611         if (!pssParams.getHashAlgorithm().equals(AlgorithmIdentifier.getInstance(pssParams.getMaskGenAlgorithm().getParameters())))
612         {
613             return true;
614         }
615 
616         MessageDigest digest = createDigest(pssParams.getHashAlgorithm());
617 
618         return pssParams.getSaltLength().intValue() != digest.getDigestLength();
619     }
620 }
621