2323import javax .crypto .Cipher ;
2424import javax .crypto .KeyAgreement ;
2525
26- import org .bouncycastle .asn1 .ASN1Encodable ;
26+ import org .bouncycastle .asn1 .ASN1Encoding ;
2727import org .bouncycastle .asn1 .ASN1Integer ;
2828import org .bouncycastle .asn1 .ASN1ObjectIdentifier ;
2929import org .bouncycastle .asn1 .ASN1Sequence ;
3030import org .bouncycastle .asn1 .DERNull ;
31- import org .bouncycastle .asn1 .DERSequence ;
3231import org .bouncycastle .asn1 .cryptopro .CryptoProObjectIdentifiers ;
3332import org .bouncycastle .asn1 .kisa .KISAObjectIdentifiers ;
3433import org .bouncycastle .asn1 .nist .NISTObjectIdentifiers ;
4746import org .bouncycastle .jcajce .util .MessageDigestUtils ;
4847import org .bouncycastle .operator .DefaultSignatureNameFinder ;
4948import org .bouncycastle .operator .OperatorCreationException ;
49+ import org .bouncycastle .util .Arrays ;
5050import org .bouncycastle .util .Integers ;
5151
5252class OperatorHelper
@@ -56,13 +56,11 @@ class OperatorHelper
5656 private static final Map symmetricWrapperAlgNames = new HashMap ();
5757 private static final Map symmetricKeyAlgNames = new HashMap ();
5858 private static final Map symmetricWrapperKeySizes = new HashMap ();
59+ // ASN1ObjectIdentifier -> OAEPParamsValue
60+ private static final Map oaepParamsMap = new HashMap ();
5961
6062 private static DefaultSignatureNameFinder sigFinder = new DefaultSignatureNameFinder ();
6163
62- private static final RSAESOAEPparams oaepParams_sha256 = calculateDefForDigest (NISTObjectIdentifiers .id_sha256 );
63- private static final RSAESOAEPparams oaepParams_sha384 = calculateDefForDigest (NISTObjectIdentifiers .id_sha384 );
64- private static final RSAESOAEPparams oaepParams_sha512 = calculateDefForDigest (NISTObjectIdentifiers .id_sha512 );
65-
6664 static
6765 {
6866 oids .put (OIWObjectIdentifiers .idSHA1 , "SHA1" );
@@ -107,17 +105,12 @@ class OperatorHelper
107105 symmetricKeyAlgNames .put (NISTObjectIdentifiers .id_aes256_CBC , "AES" );
108106 symmetricKeyAlgNames .put (PKCSObjectIdentifiers .des_EDE3_CBC , "DESede" );
109107 symmetricKeyAlgNames .put (PKCSObjectIdentifiers .RC2_CBC , "RC2" );
110- }
111108
112- private static RSAESOAEPparams calculateDefForDigest (ASN1ObjectIdentifier digest )
113- {
114- AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier (
115- digest ,
116- DERNull .INSTANCE );
117- AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier (
118- PKCSObjectIdentifiers .id_mgf1 ,
119- new AlgorithmIdentifier (digest , DERNull .INSTANCE ));
120- return new RSAESOAEPparams (hashAlgorithm , maskGenAlgorithm , RSAESOAEPparams .DEFAULT_P_SOURCE_ALGORITHM );
109+ OAEPParamsValue .add (oaepParamsMap , "RSA/ECB/OAEPWithSHA-1AndMGF1Padding" , OIWObjectIdentifiers .idSHA1 );
110+ OAEPParamsValue .add (oaepParamsMap , "RSA/ECB/OAEPWithSHA-224AndMGF1Padding" , NISTObjectIdentifiers .id_sha224 );
111+ OAEPParamsValue .add (oaepParamsMap , "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" , NISTObjectIdentifiers .id_sha256 );
112+ OAEPParamsValue .add (oaepParamsMap , "RSA/ECB/OAEPWithSHA-384AndMGF1Padding" , NISTObjectIdentifiers .id_sha384 );
113+ OAEPParamsValue .add (oaepParamsMap , "RSA/ECB/OAEPWithSHA-512AndMGF1Padding" , NISTObjectIdentifiers .id_sha512 );
121114 }
122115
123116 private JcaJceHelper helper ;
@@ -207,52 +200,51 @@ KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm)
207200 Cipher createAsymmetricWrapper (AlgorithmIdentifier algorithmID , Map extraAlgNames )
208201 throws OperatorCreationException
209202 {
210- ASN1ObjectIdentifier algorithm = algorithmID .getAlgorithm ();
203+ if (algorithmID == null )
204+ {
205+ throw new NullPointerException ("'algorithmID' cannot be null" );
206+ }
207+
208+ ASN1ObjectIdentifier algOID = algorithmID .getAlgorithm ();
211209 try
212210 {
213211 String cipherName = null ;
214212
215- if (!extraAlgNames .isEmpty ())
213+ if (extraAlgNames != null && !extraAlgNames .isEmpty ())
216214 {
217- cipherName = (String )extraAlgNames .get (algorithm );
215+ cipherName = (String )extraAlgNames .get (algOID );
218216 }
219217
220218 if (cipherName == null )
221219 {
222- cipherName = (String )asymmetricWrapperAlgNames .get (algorithm );
220+ cipherName = (String )asymmetricWrapperAlgNames .get (algOID );
221+ }
222+
223+ if (cipherName != null )
224+ {
223225 if (cipherName .indexOf ("OAEPPadding" ) > 0 )
224226 {
225- ASN1Encodable params = algorithmID .getParameters ().toASN1Primitive ();
226- if ((params instanceof ASN1Sequence ))
227+ try
227228 {
228- ASN1Sequence paramSeq = ASN1Sequence .getInstance (params );
229- if (paramSeq . size () == 0 )
229+ RSAESOAEPparams oaepParams = RSAESOAEPparams .getInstance (algorithmID . getParameters () );
230+ if (oaepParams != null )
230231 {
231- cipherName = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding" ;
232- }
233- else if (paramSeq .size () >= 2 )
234- {
235- // we only check the first 2 as pSource may be different
236- paramSeq = new DERSequence (new ASN1Encodable []{ paramSeq .getObjectAt (0 ), paramSeq .getObjectAt (1 ) });
237- if (oaepParams_sha256 .equals (paramSeq ))
238- {
239- cipherName = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" ;
240- }
241- else if (oaepParams_sha512 .equals (paramSeq ))
242- {
243- cipherName = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding" ;
244- }
245- else if (oaepParams_sha384 .equals (paramSeq ))
232+ ASN1ObjectIdentifier digestOID = oaepParams .getHashAlgorithm ().getAlgorithm ();
233+ OAEPParamsValue oaepParamsValue = (OAEPParamsValue )oaepParamsMap .get (digestOID );
234+
235+ // Note that the original pSourceAlgorithm is ignored for this comparison
236+ if (oaepParamsValue != null && oaepParamsValue .matches (oaepParams .withDefaultPSource ()))
246237 {
247- cipherName = "RSA/ECB/OAEPWithSHA-384AndMGF1Padding" ;
238+ cipherName = oaepParamsValue . getCipherName () ;
248239 }
249240 }
250241 }
242+ catch (Exception e )
243+ {
244+ // Ignore
245+ }
251246 }
252- }
253247
254- if (cipherName != null )
255- {
256248 try
257249 {
258250 // this is reversed as the Sun policy files now allow unlimited strength RSA
@@ -288,7 +280,7 @@ else if (cipherName.indexOf("ECB/OAEPWith") > 0)
288280 }
289281 }
290282
291- return helper .createCipher (algorithm .getId ());
283+ return helper .createCipher (algOID .getId ());
292284 }
293285 catch (GeneralSecurityException e )
294286 {
@@ -626,4 +618,52 @@ private boolean notDefaultPSSParams(ASN1Sequence seq)
626618
627619 return pssParams .getSaltLength ().intValue () != digest .getDigestLength ();
628620 }
621+
622+ private static class OAEPParamsValue
623+ {
624+ static void add (Map oaepParamsMap , String cipherName , ASN1ObjectIdentifier digestOID )
625+ {
626+ try
627+ {
628+ RSAESOAEPparams oaepParams = createOAEPParams (digestOID );
629+ byte [] derEncoding = getDEREncoding (oaepParams );
630+ oaepParamsMap .put (digestOID , new OAEPParamsValue (cipherName , derEncoding ));
631+ }
632+ catch (Exception e )
633+ {
634+ throw new RuntimeException (e );
635+ }
636+ }
637+
638+ private String cipherName ;
639+ private byte [] derEncoding ;
640+
641+ private OAEPParamsValue (String cipherName , byte [] derEncoding )
642+ {
643+ this .cipherName = cipherName ;
644+ this .derEncoding = derEncoding ;
645+ }
646+
647+ String getCipherName ()
648+ {
649+ return cipherName ;
650+ }
651+
652+ boolean matches (RSAESOAEPparams oaepParams ) throws IOException
653+ {
654+ return Arrays .areEqual (derEncoding , getDEREncoding (oaepParams ));
655+ }
656+
657+ private static RSAESOAEPparams createOAEPParams (ASN1ObjectIdentifier digestOID )
658+ {
659+ AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier (digestOID , DERNull .INSTANCE );
660+ AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier (PKCSObjectIdentifiers .id_mgf1 , hashAlgorithm );
661+ return new RSAESOAEPparams (hashAlgorithm , maskGenAlgorithm , RSAESOAEPparams .DEFAULT_P_SOURCE_ALGORITHM );
662+ }
663+
664+ private static byte [] getDEREncoding (RSAESOAEPparams oaepParams ) throws IOException
665+ {
666+ return oaepParams .getEncoded (ASN1Encoding .DER );
667+ }
668+ }
629669}
0 commit comments