1
package org.bouncycastle.crypto.tls;
3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.io.OutputStream;
7
import org.bouncycastle.asn1.x509.KeyUsage;
8
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
9
import org.bouncycastle.asn1.x509.X509CertificateStructure;
10
import org.bouncycastle.crypto.InvalidCipherTextException;
11
import org.bouncycastle.crypto.encodings.PKCS1Encoding;
12
import org.bouncycastle.crypto.engines.RSABlindedEngine;
13
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
14
import org.bouncycastle.crypto.params.ParametersWithRandom;
15
import org.bouncycastle.crypto.params.RSAKeyParameters;
16
import org.bouncycastle.crypto.util.PublicKeyFactory;
19
* TLS 1.0 RSA key exchange.
21
class TlsRSAKeyExchange implements TlsKeyExchange
23
protected TlsClientContext context;
25
protected AsymmetricKeyParameter serverPublicKey = null;
27
protected RSAKeyParameters rsaServerPublicKey = null;
29
protected byte[] premasterSecret;
31
TlsRSAKeyExchange(TlsClientContext context)
33
this.context = context;
36
public void skipServerCertificate() throws IOException
38
throw new TlsFatalAlert(AlertDescription.unexpected_message);
41
public void processServerCertificate(Certificate serverCertificate) throws IOException
43
X509CertificateStructure x509Cert = serverCertificate.certs[0];
44
SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
48
this.serverPublicKey = PublicKeyFactory.createKey(keyInfo);
50
catch (RuntimeException e)
52
throw new TlsFatalAlert(AlertDescription.unsupported_certificate);
55
// Sanity check the PublicKeyFactory
56
if (this.serverPublicKey.isPrivate())
58
throw new TlsFatalAlert(AlertDescription.internal_error);
61
this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters)this.serverPublicKey);
63
TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment);
67
* Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
68
* signing algorithm for the certificate must be the same as the algorithm for the
73
public void skipServerKeyExchange() throws IOException
78
public void processServerKeyExchange(InputStream is)
82
throw new TlsFatalAlert(AlertDescription.unexpected_message);
85
public void validateCertificateRequest(CertificateRequest certificateRequest)
88
short[] types = certificateRequest.getCertificateTypes();
89
for (int i = 0; i < types.length; ++i)
93
case ClientCertificateType.rsa_sign:
94
case ClientCertificateType.dss_sign:
95
case ClientCertificateType.ecdsa_sign:
98
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
103
public void skipClientCredentials() throws IOException
108
public void processClientCredentials(TlsCredentials clientCredentials) throws IOException
110
if (!(clientCredentials instanceof TlsSignerCredentials))
112
throw new TlsFatalAlert(AlertDescription.internal_error);
116
public void generateClientKeyExchange(OutputStream os) throws IOException
119
* Choose a PremasterSecret and send it encrypted to the server
121
premasterSecret = new byte[48];
122
context.getSecureRandom().nextBytes(premasterSecret);
123
TlsUtils.writeVersion(premasterSecret, 0);
125
PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine());
126
encoding.init(true, new ParametersWithRandom(this.rsaServerPublicKey, context.getSecureRandom()));
130
byte[] keData = encoding.processBlock(premasterSecret, 0, premasterSecret.length);
131
TlsUtils.writeUint24(keData.length + 2, os);
132
TlsUtils.writeOpaque16(keData, os);
134
catch (InvalidCipherTextException e)
137
* This should never happen, only during decryption.
139
throw new TlsFatalAlert(AlertDescription.internal_error);
143
public byte[] generatePremasterSecret() throws IOException
145
byte[] tmp = this.premasterSecret;
146
this.premasterSecret = null;
150
// Would be needed to process RSA_EXPORT server key exchange
151
// protected void processRSAServerKeyExchange(InputStream is, Signer signer) throws IOException
153
// InputStream sigIn = is;
154
// if (signer != null)
156
// sigIn = new SignerInputStream(is, signer);
159
// byte[] modulusBytes = TlsUtils.readOpaque16(sigIn);
160
// byte[] exponentBytes = TlsUtils.readOpaque16(sigIn);
162
// if (signer != null)
164
// byte[] sigByte = TlsUtils.readOpaque16(is);
166
// if (!signer.verifySignature(sigByte))
168
// handler.failWithError(AlertLevel.fatal, AlertDescription.bad_certificate);
172
// BigInteger modulus = new BigInteger(1, modulusBytes);
173
// BigInteger exponent = new BigInteger(1, exponentBytes);
175
// this.rsaServerPublicKey = validateRSAPublicKey(new RSAKeyParameters(false, modulus,
179
protected RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOException
181
// TODO What is the minimum bit length required?
182
// key.getModulus().bitLength();
184
if (!key.getExponent().isProbablePrime(2))
186
throw new TlsFatalAlert(AlertDescription.illegal_parameter);