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 23 public abstract class AlgorithmParametersSpi 24 extends java.security.AlgorithmParametersSpi 25 { isASN1FormatString(String format)26 protected boolean isASN1FormatString(String format) 27 { 28 return format == null || format.equals("ASN.1"); 29 } 30 engineGetParameterSpec( Class paramSpec)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 localEngineGetParameterSpec(Class paramSpec)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 */ engineGetEncoded()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 engineGetEncoded( String format)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 localEngineGetParameterSpec( Class paramSpec)89 protected AlgorithmParameterSpec localEngineGetParameterSpec( 90 Class paramSpec) 91 throws InvalidParameterSpecException 92 { 93 if (paramSpec == OAEPParameterSpec.class || paramSpec == AlgorithmParameterSpec.class) 94 { 95 return currentSpec; 96 } 97 98 throw new InvalidParameterSpecException("unknown parameter spec passed to OAEP parameters object."); 99 } 100 engineInit( AlgorithmParameterSpec paramSpec)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 engineInit( byte[] params)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 engineInit( byte[] params, String format)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 engineToString()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 */ engineGetEncoded()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 engineGetEncoded( String format)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 localEngineGetParameterSpec( Class paramSpec)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 engineInit( AlgorithmParameterSpec paramSpec)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 engineInit( byte[] params)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 engineInit( byte[] params, String format)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 engineToString()260 protected String engineToString() 261 { 262 return "PSS Parameters"; 263 } 264 } 265 } 266