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