AlgorithmParametersSpi.java revision e1142c149e244797ce73b0e7fad40816e447a817
1package org.bouncycastle.jcajce.provider.asymmetric.rsa;
2
3import java.io.IOException;
4import java.security.spec.AlgorithmParameterSpec;
5import java.security.spec.InvalidParameterSpecException;
6import java.security.spec.MGF1ParameterSpec;
7import java.security.spec.PSSParameterSpec;
8
9import javax.crypto.spec.OAEPParameterSpec;
10import javax.crypto.spec.PSource;
11
12import org.bouncycastle.asn1.ASN1Encoding;
13import org.bouncycastle.asn1.ASN1Integer;
14import org.bouncycastle.asn1.ASN1OctetString;
15import org.bouncycastle.asn1.DERNull;
16import org.bouncycastle.asn1.DEROctetString;
17import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
18import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
19import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
20import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
21import org.bouncycastle.jcajce.provider.util.DigestFactory;
22
23public abstract class AlgorithmParametersSpi
24    extends java.security.AlgorithmParametersSpi
25{
26    protected boolean isASN1FormatString(String format)
27    {
28        return format == null || format.equals("ASN.1");
29    }
30
31    protected AlgorithmParameterSpec engineGetParameterSpec(
32        Class paramSpec)
33        throws InvalidParameterSpecException
34    {
35        if (paramSpec == null)
36        {
37            throw new NullPointerException("argument to getParameterSpec must not be null");
38        }
39
40        return localEngineGetParameterSpec(paramSpec);
41    }
42
43    protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
44        throws InvalidParameterSpecException;
45
46    public static class OAEP
47        extends AlgorithmParametersSpi
48    {
49        OAEPParameterSpec currentSpec;
50
51        /**
52         * Return the PKCS#1 ASN.1 structure RSAES-OAEP-params.
53         */
54        protected byte[] engineGetEncoded()
55        {
56            AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
57                                                            DigestFactory.getOID(currentSpec.getDigestAlgorithm()),
58                                                            DERNull.INSTANCE);
59            MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)currentSpec.getMGFParameters();
60            AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
61                                                            PKCSObjectIdentifiers.id_mgf1,
62                                                            new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
63            PSource.PSpecified      pSource = (PSource.PSpecified)currentSpec.getPSource();
64            AlgorithmIdentifier pSourceAlgorithm = new AlgorithmIdentifier(
65                                                            PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(pSource.getValue()));
66            RSAESOAEPparams oaepP = new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, pSourceAlgorithm);
67
68            try
69            {
70                return oaepP.getEncoded(ASN1Encoding.DER);
71            }
72            catch (IOException e)
73            {
74                throw new RuntimeException("Error encoding OAEPParameters");
75            }
76        }
77
78        protected byte[] engineGetEncoded(
79            String format)
80        {
81            if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
82            {
83                return engineGetEncoded();
84            }
85
86            return null;
87        }
88
89        protected AlgorithmParameterSpec localEngineGetParameterSpec(
90            Class paramSpec)
91            throws InvalidParameterSpecException
92        {
93            if (paramSpec == OAEPParameterSpec.class && currentSpec != null)
94            {
95                return currentSpec;
96            }
97
98            throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object.");
99        }
100
101        protected void engineInit(
102            AlgorithmParameterSpec paramSpec)
103            throws InvalidParameterSpecException
104        {
105            if (!(paramSpec instanceof OAEPParameterSpec))
106            {
107                throw new InvalidParameterSpecException("OAEPParameterSpec required to initialise an OAEP algorithm parameters object");
108            }
109
110            this.currentSpec = (OAEPParameterSpec)paramSpec;
111        }
112
113        protected void engineInit(
114            byte[] params)
115            throws IOException
116        {
117            try
118            {
119                RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params);
120
121                currentSpec = new OAEPParameterSpec(
122                                       oaepP.getHashAlgorithm().getAlgorithm().getId(),
123                                       oaepP.getMaskGenAlgorithm().getAlgorithm().getId(),
124                                       new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()),
125                                       new PSource.PSpecified(ASN1OctetString.getInstance(oaepP.getPSourceAlgorithm().getParameters()).getOctets()));
126            }
127            catch (ClassCastException e)
128            {
129                throw new IOException("Not a valid OAEP Parameter encoding.");
130            }
131            catch (ArrayIndexOutOfBoundsException e)
132            {
133                throw new IOException("Not a valid OAEP Parameter encoding.");
134            }
135        }
136
137        protected void engineInit(
138            byte[] params,
139            String format)
140            throws IOException
141        {
142            if (format.equalsIgnoreCase("X.509")
143                    || format.equalsIgnoreCase("ASN.1"))
144            {
145                engineInit(params);
146            }
147            else
148            {
149                throw new IOException("Unknown parameter format " + format);
150            }
151        }
152
153        protected String engineToString()
154        {
155            return "OAEP Parameters";
156        }
157    }
158
159    public static class PSS
160        extends AlgorithmParametersSpi
161    {
162        PSSParameterSpec currentSpec;
163
164        /**
165         * Return the PKCS#1 ASN.1 structure RSASSA-PSS-params.
166         */
167        protected byte[] engineGetEncoded()
168            throws IOException
169        {
170            PSSParameterSpec pssSpec = currentSpec;
171            AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
172                                                DigestFactory.getOID(pssSpec.getDigestAlgorithm()),
173                                                DERNull.INSTANCE);
174            MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)pssSpec.getMGFParameters();
175            AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
176                                                PKCSObjectIdentifiers.id_mgf1,
177                                                new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE));
178            RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField()));
179
180            return pssP.getEncoded("DER");
181        }
182
183        protected byte[] engineGetEncoded(
184            String format)
185            throws IOException
186        {
187            if (format.equalsIgnoreCase("X.509")
188                    || format.equalsIgnoreCase("ASN.1"))
189            {
190                return engineGetEncoded();
191            }
192
193            return null;
194        }
195
196        protected AlgorithmParameterSpec localEngineGetParameterSpec(
197            Class paramSpec)
198            throws InvalidParameterSpecException
199        {
200            if (paramSpec == PSSParameterSpec.class && currentSpec != null)
201            {
202                return currentSpec;
203            }
204
205            throw new InvalidParameterSpecException("unknown parameter spec passed to PSS parameters object.");
206        }
207
208        protected void engineInit(
209            AlgorithmParameterSpec paramSpec)
210            throws InvalidParameterSpecException
211        {
212            if (!(paramSpec instanceof PSSParameterSpec))
213            {
214                throw new InvalidParameterSpecException("PSSParameterSpec required to initialise an PSS algorithm parameters object");
215            }
216
217            this.currentSpec = (PSSParameterSpec)paramSpec;
218        }
219
220        protected void engineInit(
221            byte[] params)
222            throws IOException
223        {
224            try
225            {
226                RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
227
228                currentSpec = new PSSParameterSpec(
229                                       pssP.getHashAlgorithm().getAlgorithm().getId(),
230                                       pssP.getMaskGenAlgorithm().getAlgorithm().getId(),
231                                       new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()),
232                                       pssP.getSaltLength().intValue(),
233                                       pssP.getTrailerField().intValue());
234            }
235            catch (ClassCastException e)
236            {
237                throw new IOException("Not a valid PSS Parameter encoding.");
238            }
239            catch (ArrayIndexOutOfBoundsException e)
240            {
241                throw new IOException("Not a valid PSS Parameter encoding.");
242            }
243        }
244
245        protected void engineInit(
246            byte[] params,
247            String format)
248            throws IOException
249        {
250            if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509"))
251            {
252                engineInit(params);
253            }
254            else
255            {
256                throw new IOException("Unknown parameter format " + format);
257            }
258        }
259
260        protected String engineToString()
261        {
262            return "PSS Parameters";
263        }
264    }
265}
266