![JAR search and dependency download from the Maven repository](/logo.png)
nl.open.jwtdependency.org.bouncycastle.crypto.tls.TlsSRPKeyExchange Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-jwt-nodependencies Show documentation
Show all versions of java-jwt-nodependencies Show documentation
This is a drop in replacement for the auth0 java-jwt library (see https://github.com/auth0/java-jwt). This jar makes sure there are no external dependencies (e.g. fasterXml, Apacha Commons) needed. This is useful when deploying to an application server (e.g. tomcat with Alfreso or Pega).
The newest version!
package org.bouncycastle.crypto.tls;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Vector;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.Signer;
import org.bouncycastle.crypto.agreement.srp.SRP6Client;
import org.bouncycastle.crypto.agreement.srp.SRP6Server;
import org.bouncycastle.crypto.agreement.srp.SRP6Util;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.SRP6GroupParameters;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.io.TeeInputStream;
/**
* (D)TLS SRP key exchange (RFC 5054).
*/
public class TlsSRPKeyExchange extends AbstractTlsKeyExchange
{
protected static TlsSigner createSigner(int keyExchange)
{
switch (keyExchange)
{
case KeyExchangeAlgorithm.SRP:
return null;
case KeyExchangeAlgorithm.SRP_RSA:
return new TlsRSASigner();
case KeyExchangeAlgorithm.SRP_DSS:
return new TlsDSSSigner();
default:
throw new IllegalArgumentException("unsupported key exchange algorithm");
}
}
protected TlsSigner tlsSigner;
protected TlsSRPGroupVerifier groupVerifier;
protected byte[] identity;
protected byte[] password;
protected AsymmetricKeyParameter serverPublicKey = null;
protected SRP6GroupParameters srpGroup = null;
protected SRP6Client srpClient = null;
protected SRP6Server srpServer = null;
protected BigInteger srpPeerCredentials = null;
protected BigInteger srpVerifier = null;
protected byte[] srpSalt = null;
protected TlsSignerCredentials serverCredentials = null;
/**
* @deprecated Use constructor taking an explicit 'groupVerifier' argument
*/
public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity, byte[] password)
{
this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsSRPGroupVerifier(), identity, password);
}
public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, TlsSRPGroupVerifier groupVerifier,
byte[] identity, byte[] password)
{
super(keyExchange, supportedSignatureAlgorithms);
this.tlsSigner = createSigner(keyExchange);
this.groupVerifier = groupVerifier;
this.identity = identity;
this.password = password;
this.srpClient = new SRP6Client();
}
public TlsSRPKeyExchange(int keyExchange, Vector supportedSignatureAlgorithms, byte[] identity,
TlsSRPLoginParameters loginParameters)
{
super(keyExchange, supportedSignatureAlgorithms);
this.tlsSigner = createSigner(keyExchange);
this.identity = identity;
this.srpServer = new SRP6Server();
this.srpGroup = loginParameters.getGroup();
this.srpVerifier = loginParameters.getVerifier();
this.srpSalt = loginParameters.getSalt();
}
public void init(TlsContext context)
{
super.init(context);
if (this.tlsSigner != null)
{
this.tlsSigner.init(context);
}
}
public void skipServerCredentials() throws IOException
{
if (tlsSigner != null)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
}
public void processServerCertificate(Certificate serverCertificate) throws IOException
{
if (tlsSigner == null)
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
if (serverCertificate.isEmpty())
{
throw new TlsFatalAlert(AlertDescription.bad_certificate);
}
org.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0);
SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
try
{
this.serverPublicKey = PublicKeyFactory.createKey(keyInfo);
}
catch (RuntimeException e)
{
throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
}
if (!tlsSigner.isValidPublicKey(this.serverPublicKey))
{
throw new TlsFatalAlert(AlertDescription.certificate_unknown);
}
TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature);
super.processServerCertificate(serverCertificate);
}
public void processServerCredentials(TlsCredentials serverCredentials)
throws IOException
{
if ((keyExchange == KeyExchangeAlgorithm.SRP) || !(serverCredentials instanceof TlsSignerCredentials))
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
processServerCertificate(serverCredentials.getCertificate());
this.serverCredentials = (TlsSignerCredentials)serverCredentials;
}
public boolean requiresServerKeyExchange()
{
return true;
}
public byte[] generateServerKeyExchange() throws IOException
{
srpServer.init(srpGroup, srpVerifier, TlsUtils.createHash(HashAlgorithm.sha1), context.getSecureRandom());
BigInteger B = srpServer.generateServerCredentials();
ServerSRPParams srpParams = new ServerSRPParams(srpGroup.getN(), srpGroup.getG(), srpSalt, B);
DigestInputBuffer buf = new DigestInputBuffer();
srpParams.encode(buf);
if (serverCredentials != null)
{
/*
* RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
*/
SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtils.getSignatureAndHashAlgorithm(
context, serverCredentials);
Digest d = TlsUtils.createHash(signatureAndHashAlgorithm);
SecurityParameters securityParameters = context.getSecurityParameters();
d.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length);
d.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length);
buf.updateDigest(d);
byte[] hash = new byte[d.getDigestSize()];
d.doFinal(hash, 0);
byte[] signature = serverCredentials.generateCertificateSignature(hash);
DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature);
signed_params.encode(buf);
}
return buf.toByteArray();
}
public void processServerKeyExchange(InputStream input) throws IOException
{
SecurityParameters securityParameters = context.getSecurityParameters();
SignerInputBuffer buf = null;
InputStream teeIn = input;
if (tlsSigner != null)
{
buf = new SignerInputBuffer();
teeIn = new TeeInputStream(input, buf);
}
ServerSRPParams srpParams = ServerSRPParams.parse(teeIn);
if (buf != null)
{
DigitallySigned signed_params = parseSignature(input);
Signer signer = initVerifyer(tlsSigner, signed_params.getAlgorithm(), securityParameters);
buf.updateSigner(signer);
if (!signer.verifySignature(signed_params.getSignature()))
{
throw new TlsFatalAlert(AlertDescription.decrypt_error);
}
}
this.srpGroup = new SRP6GroupParameters(srpParams.getN(), srpParams.getG());
if (!groupVerifier.accept(srpGroup))
{
throw new TlsFatalAlert(AlertDescription.insufficient_security);
}
this.srpSalt = srpParams.getS();
/*
* RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if
* B % N = 0.
*/
try
{
this.srpPeerCredentials = SRP6Util.validatePublicValue(srpGroup.getN(), srpParams.getB());
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
this.srpClient.init(srpGroup, TlsUtils.createHash(HashAlgorithm.sha1), context.getSecureRandom());
}
public void validateCertificateRequest(CertificateRequest certificateRequest) throws IOException
{
throw new TlsFatalAlert(AlertDescription.unexpected_message);
}
public void processClientCredentials(TlsCredentials clientCredentials) throws IOException
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}
public void generateClientKeyExchange(OutputStream output) throws IOException
{
BigInteger A = srpClient.generateClientCredentials(srpSalt, identity, password);
TlsSRPUtils.writeSRPParameter(A, output);
context.getSecurityParameters().srpIdentity = Arrays.clone(identity);
}
public void processClientKeyExchange(InputStream input) throws IOException
{
/*
* RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if
* A % N = 0.
*/
try
{
this.srpPeerCredentials = SRP6Util.validatePublicValue(srpGroup.getN(), TlsSRPUtils.readSRPParameter(input));
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
context.getSecurityParameters().srpIdentity = Arrays.clone(identity);
}
public byte[] generatePremasterSecret() throws IOException
{
try
{
BigInteger S = srpServer != null
? srpServer.calculateSecret(srpPeerCredentials)
: srpClient.calculateSecret(srpPeerCredentials);
// TODO Check if this needs to be a fixed size
return BigIntegers.asUnsignedByteArray(S);
}
catch (CryptoException e)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter, e);
}
}
protected Signer initVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters)
{
Signer signer = tlsSigner.createVerifyer(algorithm, this.serverPublicKey);
signer.update(securityParameters.clientRandom, 0, securityParameters.clientRandom.length);
signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length);
return signer;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy