From 326e01360eebc96de8b2a4f8f48561ed754fe03c Mon Sep 17 00:00:00 2001 From: Sovietaced Date: Tue, 26 Sep 2017 09:51:25 -0700 Subject: [PATCH 1/4] Rename Certificate to CertificateChain since it is a chain of certificates --- .../java/net/jradius/client/auth/EAPTLSAuthenticator.java | 4 ++-- .../tls/{Certificate.java => CertificateChain.java} | 8 ++++---- .../src/main/java/net/jradius/tls/DefaultTlsClient.java | 6 +++--- extended/src/main/java/net/jradius/tls/TlsClient.java | 2 +- .../src/main/java/net/jradius/tls/TlsDHKeyExchange.java | 2 +- .../src/main/java/net/jradius/tls/TlsKeyExchange.java | 2 +- .../src/main/java/net/jradius/tls/TlsProtocolHandler.java | 4 ++-- .../src/main/java/net/jradius/tls/TlsRSAKeyExchange.java | 2 +- .../src/main/java/net/jradius/tls/TlsSRPKeyExchange.java | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) rename extended/src/main/java/net/jradius/tls/{Certificate.java => CertificateChain.java} (93%) diff --git a/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java b/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java index 42e0b9b..313c999 100644 --- a/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java +++ b/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java @@ -42,7 +42,7 @@ import net.jradius.log.RadiusLog; import net.jradius.packet.RadiusPacket; import net.jradius.tls.AlwaysValidVerifyer; -import net.jradius.tls.Certificate; +import net.jradius.tls.CertificateChain; import net.jradius.tls.DefaultTlsClient; import net.jradius.tls.TlsProtocolHandler; import net.jradius.util.KeyStoreUtil; @@ -186,7 +186,7 @@ else if (getCaFile() != null) certs[i] = (X509CertificateStructure)tmp.elementAt(i); } - tlsClient.enableClientAuthentication(new Certificate(certs), createKey(key.getEncoded())); + tlsClient.enableClientAuthentication(new CertificateChain(certs), createKey(key.getEncoded())); } } catch (Exception e) diff --git a/extended/src/main/java/net/jradius/tls/Certificate.java b/extended/src/main/java/net/jradius/tls/CertificateChain.java similarity index 93% rename from extended/src/main/java/net/jradius/tls/Certificate.java rename to extended/src/main/java/net/jradius/tls/CertificateChain.java index a051fa6..ac98217 100644 --- a/extended/src/main/java/net/jradius/tls/Certificate.java +++ b/extended/src/main/java/net/jradius/tls/CertificateChain.java @@ -13,7 +13,7 @@ /** * A representation for a certificate chain as used by a tls server. */ -public class Certificate +public class CertificateChain { /** * The certificates. @@ -27,7 +27,7 @@ public class Certificate * @return A Certificate object with the certs, the server has sended. * @throws IOException If something goes wrong during parsing. */ - public static Certificate parse(InputStream is) throws IOException + public static CertificateChain parse(InputStream is) throws IOException { X509CertificateStructure[] certs; int left = TlsUtils.readUint24(is); @@ -53,7 +53,7 @@ public static Certificate parse(InputStream is) throws IOException { certs[i] = (X509CertificateStructure)tmp.elementAt(i); } - return new Certificate(certs); + return new CertificateChain(certs); } /** @@ -88,7 +88,7 @@ protected void encode(OutputStream os) throws IOException * * @param certs The certs the chain should contain. */ - public Certificate(X509CertificateStructure[] certs) + public CertificateChain(X509CertificateStructure[] certs) { this.certs = certs; } diff --git a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java index 385dd10..81426e9 100644 --- a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java +++ b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java @@ -68,7 +68,7 @@ public class DefaultTlsClient implements TlsClient private TlsProtocolHandler handler; // (Optional) details for client-side authentication - private Certificate clientCert = new Certificate(new X509CertificateStructure[0]); + private CertificateChain clientCert = new CertificateChain(new X509CertificateStructure[0]); private AsymmetricKeyParameter clientPrivateKey = null; private TlsSigner clientSigner = null; @@ -79,7 +79,7 @@ public DefaultTlsClient(CertificateVerifyer verifyer) this.verifyer = verifyer; } - public void enableClientAuthentication(Certificate clientCertificate, + public void enableClientAuthentication(CertificateChain clientCertificate, AsymmetricKeyParameter clientPrivateKey) { if (clientCertificate == null) @@ -265,7 +265,7 @@ public byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException } } - public Certificate getCertificate() + public CertificateChain getCertificate() { return clientCert; } diff --git a/extended/src/main/java/net/jradius/tls/TlsClient.java b/extended/src/main/java/net/jradius/tls/TlsClient.java index 0a289b2..6b165bb 100644 --- a/extended/src/main/java/net/jradius/tls/TlsClient.java +++ b/extended/src/main/java/net/jradius/tls/TlsClient.java @@ -27,7 +27,7 @@ interface TlsClient byte[] generateCertificateSignature(byte[] md5andsha1) throws IOException; - Certificate getCertificate(); + CertificateChain getCertificate(); TlsCipher createCipher(SecurityParameters securityParameters) throws IOException; } diff --git a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java index 4050f15..de4bc16 100644 --- a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java @@ -69,7 +69,7 @@ public void skipServerCertificate() throws IOException handler.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unexpected_message); } - public void processServerCertificate(Certificate serverCertificate) throws IOException + public void processServerCertificate(CertificateChain serverCertificate) throws IOException { X509CertificateStructure x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); diff --git a/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java index aeb53b7..ed1ecec 100644 --- a/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java @@ -23,7 +23,7 @@ interface TlsKeyExchange void skipServerCertificate() throws IOException; - void processServerCertificate(Certificate serverCertificate) throws IOException; + void processServerCertificate(CertificateChain serverCertificate) throws IOException; void skipServerKeyExchange() throws IOException; diff --git a/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java b/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java index 72b21f3..66010b2 100644 --- a/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java +++ b/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java @@ -292,7 +292,7 @@ private void processHandshakeMessage(short type, byte[] buf) throws IOException { // Parse the Certificate message and send to cipher suite - Certificate serverCertificate = Certificate.parse(is); + CertificateChain serverCertificate = CertificateChain.parse(is); assertEmpty(is); @@ -716,7 +716,7 @@ private void processChangeCipherSpec() throws IOException } } - private void sendClientCertificate(Certificate clientCert) throws IOException + private void sendClientCertificate(CertificateChain clientCert) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TlsUtils.writeUint8(HP_CERTIFICATE, bos); diff --git a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java index 748ed2f..3cf992c 100644 --- a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java @@ -42,7 +42,7 @@ public void skipServerCertificate() throws IOException handler.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unexpected_message); } - public void processServerCertificate(Certificate serverCertificate) throws IOException + public void processServerCertificate(CertificateChain serverCertificate) throws IOException { X509CertificateStructure x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); diff --git a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java index 5fd0f64..bb47529 100644 --- a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java @@ -73,7 +73,7 @@ public void skipServerCertificate() throws IOException } } - public void processServerCertificate(Certificate serverCertificate) throws IOException + public void processServerCertificate(CertificateChain serverCertificate) throws IOException { if (tlsSigner == null) { From 4e6fd18ee34edf765024aa8a249486014ce47b29 Mon Sep 17 00:00:00 2001 From: Sovietaced Date: Tue, 26 Sep 2017 09:56:41 -0700 Subject: [PATCH 2/4] Add function to CertificateChain to return certificate chain in Java's X509 class --- .../net/jradius/tls/CertificateChain.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/extended/src/main/java/net/jradius/tls/CertificateChain.java b/extended/src/main/java/net/jradius/tls/CertificateChain.java index ac98217..df694a1 100644 --- a/extended/src/main/java/net/jradius/tls/CertificateChain.java +++ b/extended/src/main/java/net/jradius/tls/CertificateChain.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.Vector; import org.bouncycastle.asn1.ASN1InputStream; @@ -22,7 +25,7 @@ public class CertificateChain /** * Parse the ServerCertificate message. - * + * * @param is The stream where to parse from. * @return A Certificate object with the certs, the server has sended. * @throws IOException If something goes wrong during parsing. @@ -58,7 +61,7 @@ public static CertificateChain parse(InputStream is) throws IOException /** * Encodes version of the ClientCertificate message - * + * * @param os stream to write the message to * @throws IOException If something goes wrong */ @@ -85,7 +88,7 @@ protected void encode(OutputStream os) throws IOException /** * Private constructor from a cert array. - * + * * @param certs The certs the chain should contain. */ public CertificateChain(X509CertificateStructure[] certs) @@ -102,4 +105,17 @@ public X509CertificateStructure[] getCerts() System.arraycopy(certs, 0, result, 0, certs.length); return result; } + + public X509Certificate[] toX509() throws IOException, CertificateException { + X509Certificate[] x509 = new X509Certificate[certs.length]; + for (int i = 0; i < certs.length; i++) { + X509CertificateStructure cert = certs[i]; + InputStream in = new ByteArrayInputStream(cert.getEncoded()); + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + x509[i] = (X509Certificate)certFactory.generateCertificate(in); + in.close(); + } + + return x509; + } } From 3b21c1d9e049f588cfe474bbe15264af3585036c Mon Sep 17 00:00:00 2001 From: Sovietaced Date: Tue, 26 Sep 2017 13:22:42 -0700 Subject: [PATCH 3/4] Make key exchange algorithm more flexible to use and add support for verifying server certificates Similarly to JDK, I have moved the key exchange algorithm into an enum. This is helpful to verifying client certificates because I can leverage the algorithm name." --- .../net/jradius/tls/DefaultTlsClient.java | 26 +++--- .../net/jradius/tls/TlsDHKeyExchange.java | 34 ++++---- .../java/net/jradius/tls/TlsKeyExchange.java | 42 +++++++--- .../net/jradius/tls/TlsProtocolHandler.java | 81 ++++++++++++------- .../net/jradius/tls/TlsRSAKeyExchange.java | 11 ++- .../net/jradius/tls/TlsSRPKeyExchange.java | 29 ++++--- 6 files changed, 139 insertions(+), 84 deletions(-) diff --git a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java index 81426e9..3331146 100644 --- a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java +++ b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java @@ -15,6 +15,8 @@ import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; +import net.jradius.tls.TlsKeyExchange.Algorithm; + public class DefaultTlsClient implements TlsClient { // TODO Add runtime support for this check? @@ -63,7 +65,7 @@ public class DefaultTlsClient implements TlsClient private static final int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; private static final int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; - private CertificateVerifyer verifyer; + private final CertificateVerifyer verifyer; private TlsProtocolHandler handler; @@ -169,7 +171,7 @@ public Hashtable generateClientExtensions() public void notifySessionID(byte[] sessionID) { - // Currently ignored + // Currently ignored } public void notifySelectedCipherSuite(int selectedCipherSuite) @@ -195,37 +197,37 @@ public TlsKeyExchange createKeyExchange() throws IOException case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: case TLS_DH_DSS_WITH_AES_128_CBC_SHA: case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return createDHKeyExchange(TlsKeyExchange.KE_DH_DSS); + return createDHKeyExchange(TlsKeyExchange.Algorithm.KE_DH_DSS); case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_DH_RSA_WITH_AES_128_CBC_SHA: case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return createDHKeyExchange(TlsKeyExchange.KE_DH_RSA); + return createDHKeyExchange(TlsKeyExchange.Algorithm.KE_DH_RSA); case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return createDHKeyExchange(TlsKeyExchange.KE_DHE_DSS); + return createDHKeyExchange(TlsKeyExchange.Algorithm.KE_DHE_DSS); case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return createDHKeyExchange(TlsKeyExchange.KE_DHE_RSA); + return createDHKeyExchange(TlsKeyExchange.Algorithm.KE_DHE_RSA); case TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: case TLS_SRP_SHA_WITH_AES_128_CBC_SHA: case TLS_SRP_SHA_WITH_AES_256_CBC_SHA: - return createSRPExchange(TlsKeyExchange.KE_SRP); + return createSRPExchange(TlsKeyExchange.Algorithm.KE_SRP); case TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: case TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: - return createSRPExchange(TlsKeyExchange.KE_SRP_RSA); + return createSRPExchange(TlsKeyExchange.Algorithm.KE_SRP_RSA); case TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: case TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: case TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: - return createSRPExchange(TlsKeyExchange.KE_SRP_DSS); + return createSRPExchange(TlsKeyExchange.Algorithm.KE_SRP_DSS); default: /* @@ -242,7 +244,7 @@ public TlsKeyExchange createKeyExchange() throws IOException public void processServerCertificateRequest(byte[] certificateTypes, List certificateAuthorities) { - // TODO There shouldn't be a certificate request for SRP + // TODO There shouldn't be a certificate request for SRP // TODO Use provided info to choose a certificate in getCertificate() } @@ -317,7 +319,7 @@ public TlsCipher createCipher(SecurityParameters securityParameters) throws IOEx } } - private TlsKeyExchange createDHKeyExchange(short keyExchange) + private TlsKeyExchange createDHKeyExchange(Algorithm keyExchange) { return new TlsDHKeyExchange(handler, verifyer, keyExchange); } @@ -327,7 +329,7 @@ private TlsKeyExchange createRSAKeyExchange() return new TlsRSAKeyExchange(handler, verifyer); } - private TlsKeyExchange createSRPExchange(short keyExchange) + private TlsKeyExchange createSRPExchange(Algorithm keyExchange) { return new TlsSRPKeyExchange(handler, verifyer, keyExchange); } diff --git a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java index de4bc16..fe1c1aa 100644 --- a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java @@ -31,9 +31,9 @@ class TlsDHKeyExchange implements TlsKeyExchange private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger TWO = BigInteger.valueOf(2); - private TlsProtocolHandler handler; - private CertificateVerifyer verifyer; - private short keyExchange; + private final TlsProtocolHandler handler; + private final CertificateVerifyer verifyer; + private final Algorithm algorithm; private TlsSigner tlsSigner; private AsymmetricKeyParameter serverPublicKey = null; @@ -41,18 +41,18 @@ class TlsDHKeyExchange implements TlsKeyExchange private DHPublicKeyParameters dhAgreeServerPublicKey = null; private AsymmetricCipherKeyPair dhAgreeClientKeyPair = null; - TlsDHKeyExchange(TlsProtocolHandler handler, CertificateVerifyer verifyer, short keyExchange) + TlsDHKeyExchange(TlsProtocolHandler handler, CertificateVerifyer verifyer, Algorithm keyExchange) { switch (keyExchange) { - case TlsKeyExchange.KE_DH_RSA: - case TlsKeyExchange.KE_DH_DSS: + case KE_DH_RSA: + case KE_DH_DSS: this.tlsSigner = null; break; - case TlsKeyExchange.KE_DHE_RSA: + case KE_DHE_RSA: this.tlsSigner = new TlsRSASigner(); break; - case TlsKeyExchange.KE_DHE_DSS: + case KE_DHE_DSS: this.tlsSigner = new TlsDSSSigner(); break; default: @@ -61,7 +61,7 @@ class TlsDHKeyExchange implements TlsKeyExchange this.handler = handler; this.verifyer = verifyer; - this.keyExchange = keyExchange; + this.algorithm = keyExchange; } public void skipServerCertificate() throws IOException @@ -90,7 +90,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws handler.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_internal_error); } - // TODO + // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the @@ -99,9 +99,9 @@ public void processServerCertificate(CertificateChain serverCertificate) throws // TODO Should the 'instanceof' tests be replaces with stricter checks on keyInfo.getAlgorithmId()? - switch (this.keyExchange) + switch (this.algorithm) { - case TlsKeyExchange.KE_DH_DSS: + case KE_DH_DSS: if (!(this.serverPublicKey instanceof DHPublicKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -111,7 +111,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws // x509Cert.getSignatureAlgorithm(); this.dhAgreeServerPublicKey = validateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); break; - case TlsKeyExchange.KE_DH_RSA: + case KE_DH_RSA: if (!(this.serverPublicKey instanceof DHPublicKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -121,7 +121,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws // x509Cert.getSignatureAlgorithm(); this.dhAgreeServerPublicKey = validateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); break; - case TlsKeyExchange.KE_DHE_RSA: + case KE_DHE_RSA: if (!(this.serverPublicKey instanceof RSAKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -129,7 +129,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws } validateKeyUsage(x509Cert, KeyUsage.digitalSignature); break; - case TlsKeyExchange.KE_DHE_DSS: + case KE_DHE_DSS: if (!(this.serverPublicKey instanceof DSAPublicKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -287,4 +287,8 @@ private DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) thr return key; } + + public Algorithm getAlgorithm() { + return algorithm; + } } diff --git a/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java index ed1ecec..822b64d 100644 --- a/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsKeyExchange.java @@ -8,18 +8,34 @@ */ interface TlsKeyExchange { - static final short KE_RSA = 1; -// static final short KE_RSA_EXPORT = 2; - static final short KE_DHE_DSS = 3; -// static final short KE_DHE_DSS_EXPORT = 4; - static final short KE_DHE_RSA = 5; -// static final short KE_DHE_RSA_EXPORT = 6; - static final short KE_DH_DSS = 7; - static final short KE_DH_RSA = 8; -// static final short KE_DH_anon = 9; - static final short KE_SRP = 10; - static final short KE_SRP_DSS = 11; - static final short KE_SRP_RSA = 12; + enum Algorithm { + + KE_RSA("RSA", 1), + KE_DHE_DSS("DHE_DSS", 3), + KE_DHE_RSA("DHE_RSA", 5), + KE_DH_DSS("DH_DSS", 7), + KE_DH_RSA("DH_RSA", 8), + KE_SRP("SRP", 10), + KE_SRP_DSS("SRP_DSS", 11), + KE_SRP_RSA("SRP_RSA", 12); + + private final String name; + private final int id; + + Algorithm(String name, int id) { + this.name = name; + this.id = id; + } + + public String getName() { + return name; + } + + public int getId() { + return id; + } + + } void skipServerCertificate() throws IOException; @@ -33,4 +49,6 @@ void processServerKeyExchange(InputStream is, SecurityParameters securityParamet byte[] generateClientKeyExchange() throws IOException; byte[] generatePremasterSecret() throws IOException; + + Algorithm getAlgorithm(); } diff --git a/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java b/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java index 66010b2..1ecac43 100644 --- a/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java +++ b/extended/src/main/java/net/jradius/tls/TlsProtocolHandler.java @@ -6,14 +6,15 @@ import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; +import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; -import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.crypto.prng.ThreadedSeedGenerator; @@ -109,16 +110,16 @@ public class TlsProtocolHandler /* * Queues for data from some protocols. */ - private ByteQueue applicationDataQueue = new ByteQueue(); - private ByteQueue changeCipherSpecQueue = new ByteQueue(); - private ByteQueue alertQueue = new ByteQueue(); - private ByteQueue handshakeQueue = new ByteQueue(); + private final ByteQueue applicationDataQueue = new ByteQueue(); + private final ByteQueue changeCipherSpecQueue = new ByteQueue(); + private final ByteQueue alertQueue = new ByteQueue(); + private final ByteQueue handshakeQueue = new ByteQueue(); /* * The Record Stream we use */ - private RecordStream rs; - private SecureRandom random; + private final RecordStream rs; + private final SecureRandom random; private TlsInputStream tlsInputStream = null; private TlsOutputStream tlsOutputStream = null; @@ -135,10 +136,10 @@ public class TlsProtocolHandler private TlsKeyExchange keyExchange = null; private short connection_state = 0; - + private KeyManager[] keyManagers = null; private TrustManager[] trustManagers = null; - + private boolean isSendCertificate = false; private static SecureRandom createSecureRandom() @@ -169,7 +170,7 @@ public TlsProtocolHandler(InputStream is, OutputStream os, SecureRandom sr) this.random = sr; } - public TlsProtocolHandler() + public TlsProtocolHandler() { this.rs = new RecordStream(this); this.random = createSecureRandom(); @@ -179,7 +180,7 @@ SecureRandom getRandom() { return random; } - + public void setSendCertificate(boolean b) { this.isSendCertificate = b; @@ -215,7 +216,7 @@ protected void processData(short protocol, byte[] buf, int offset, int len) thro default: /* * Uh, we don't know this protocol. - * + * * RFC2246 defines on page 13, that we should ignore this. */ } @@ -298,6 +299,19 @@ private void processHandshakeMessage(short type, byte[] buf) throws IOException this.keyExchange.processServerCertificate(serverCertificate); + X509TrustManager trustManager = chooseTrustManager(trustManagers); + + if (trustManager != null) { + try { + trustManager.checkServerTrusted(serverCertificate.toX509(), + keyExchange.getAlgorithm().getName()); + } catch (CertificateException e) { + // If we encounter a certificate exception it + // is likely the server certificate chain is not trusted.. + this.failWithError(AL_fatal, AP_handshake_failure); + } + } + break; } default: @@ -621,7 +635,7 @@ private void processApplicationData() { /* * There is nothing we need to do here. - * + * * This function could be used for callbacks when application data arrives in the * future. */ @@ -680,7 +694,7 @@ private void processAlert() throws IOException /** * This method is called, when a change cipher spec message is received. - * + * * @throws IOException If the message has an invalid content or the handshake is not * in the correct state. */ @@ -761,9 +775,9 @@ private void sendCertificateVerify(byte[] data) throws IOException /** * Connects to the remote system. - * @param is - * @param out - * + * @param is + * @param out + * * @param verifyer Will be used when a certificate is received to verify that this * certificate is accepted by the client. * @throws IOException If handshake was not successful. @@ -785,7 +799,7 @@ public void connect(ByteArrayInputStream is, ByteArrayOutputStream out, Certific /** * Connects to the remote system using client authentication - * + * * @param verifyer Will be used when a certificate is received to verify that this * certificate is accepted by the client. * @param clientCertificate The client's certificate to be provided to the remote @@ -808,13 +822,13 @@ void connect(ByteArrayInputStream is, ByteArrayOutputStream out, TlsClient tlsCl rs.setInputStream(is); rs.setOutputStream(out); - + this.tlsClient = tlsClient; this.tlsClient.init(this); /* * Send Client hello - * + * * First, generate some random data. */ securityParameters = new SecurityParameters(); @@ -903,7 +917,7 @@ void connect(ByteArrayInputStream is, ByteArrayOutputStream out, TlsClient tlsCl while (connection_state != CS_DONE) { // TODO Should we send fatal alerts in the event of an exception - // (see readApplicationData) + // (see readApplicationData) rs.readData(); } @@ -1001,7 +1015,7 @@ public short updateConnectState(ByteArrayInputStream is, ByteArrayOutputStream o * Read data from the network. The method will return immediately, if there is still * some data left in the buffer, or block until some application data has been read * from the network. - * + * * @param buf The buffer where the data will be copied to. * @param offset The position where the data will be placed in the buffer. * @param len The maximum number of bytes to read. @@ -1062,7 +1076,7 @@ protected int readApplicationData(byte[] buf, int offset, int len) throws IOExce * Send some application data to the remote system. *

* The method will handle fragmentation internally. - * + * * @param buf The buffer with the data. * @param offset The position in the buffer where the data is placed. * @param len The length of the data. @@ -1082,7 +1096,7 @@ protected void writeData(byte[] buf, int offset, int len) throws IOException /* * Protect against known IV attack! - * + * * DO NOT REMOVE THIS LINE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. */ rs.writeMessage(RL_APPLICATION_DATA, emptybuf, 0, 0); @@ -1143,7 +1157,7 @@ public InputStream getInputStream() * Terminate this connection with an alert. *

* Can be used for normal closure too. - * + * * @param alertLevel The level of the alert, an be AL_fatal or AL_warning. * @param alertDescription The exact alert message. * @throws IOException If alert was fatal. @@ -1185,13 +1199,13 @@ private void sendAlert(short alertLevel, short alertDescription) throws IOExcept byte[] error = new byte[2]; error[0] = (byte)alertLevel; error[1] = (byte)alertDescription; - + rs.writeMessage(RL_ALERT, error, 0, 2); } /** * Closes this connection. - * + * * @throws IOException If something goes wrong during closing. */ public void close() throws IOException @@ -1204,7 +1218,7 @@ public void close() throws IOException /** * Make sure the InputStream is now empty. Fail otherwise. - * + * * @param is The InputStream to check. * @throws IOException If is is not empty. */ @@ -1241,6 +1255,17 @@ public void setTrustManagers(TrustManager[] trustManagers) { this.trustManagers = trustManagers; } + private X509TrustManager chooseTrustManager(TrustManager[] tm) { + // We only use the first instance of X509TrustManager passed to us. + for (int i = 0; tm != null && i < tm.length; i++) { + if (tm[i] instanceof X509TrustManager) { + return (X509TrustManager)tm[i]; + } + } + + return null; + } + // private byte[] CreateRenegotiationInfo(byte[] renegotiated_connection) throws IOException // { // ByteArrayOutputStream buf = new ByteArrayOutputStream(); diff --git a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java index 3cf992c..e5677fe 100644 --- a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.InputStream; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; @@ -22,8 +21,8 @@ */ class TlsRSAKeyExchange implements TlsKeyExchange { - private TlsProtocolHandler handler; - private CertificateVerifyer verifyer; + private final TlsProtocolHandler handler; + private final CertificateVerifyer verifyer; private AsymmetricKeyParameter serverPublicKey = null; @@ -63,7 +62,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws handler.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_internal_error); } - // TODO + // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the @@ -194,4 +193,8 @@ private RSAKeyParameters validateRSAPublicKey(RSAKeyParameters key) throws IOExc return key; } + + public Algorithm getAlgorithm() { + return Algorithm.KE_RSA; + } } diff --git a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java index bb47529..9063f77 100644 --- a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java @@ -4,7 +4,6 @@ import java.io.InputStream; import java.math.BigInteger; -import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.X509CertificateStructure; @@ -27,22 +26,22 @@ */ class TlsSRPKeyExchange implements TlsKeyExchange { - private TlsProtocolHandler handler; - private CertificateVerifyer verifyer; - private short keyExchange; + private final TlsProtocolHandler handler; + private final CertificateVerifyer verifyer; + private final Algorithm algorithm; private TlsSigner tlsSigner; private AsymmetricKeyParameter serverPublicKey = null; // TODO Need a way of providing these - private byte[] SRP_identity = null; - private byte[] SRP_password = null; + private final byte[] SRP_identity = null; + private final byte[] SRP_password = null; private byte[] s = null; private BigInteger B = null; - private SRP6Client srpClient = new SRP6Client(); + private final SRP6Client srpClient = new SRP6Client(); - TlsSRPKeyExchange(TlsProtocolHandler handler, CertificateVerifyer verifyer, short keyExchange) + TlsSRPKeyExchange(TlsProtocolHandler handler, CertificateVerifyer verifyer, Algorithm keyExchange) { switch (keyExchange) { @@ -61,7 +60,7 @@ class TlsSRPKeyExchange implements TlsKeyExchange this.handler = handler; this.verifyer = verifyer; - this.keyExchange = keyExchange; + this.algorithm = keyExchange; } public void skipServerCertificate() throws IOException @@ -100,15 +99,15 @@ public void processServerCertificate(CertificateChain serverCertificate) throws handler.failWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_internal_error); } - // TODO + // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the * certificate key." */ - switch (this.keyExchange) + switch (this.algorithm) { - case TlsKeyExchange.KE_SRP_RSA: + case KE_SRP_RSA: if (!(this.serverPublicKey instanceof RSAKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -116,7 +115,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws } validateKeyUsage(x509Cert, KeyUsage.digitalSignature); break; - case TlsKeyExchange.KE_SRP_DSS: + case KE_SRP_DSS: if (!(this.serverPublicKey instanceof DSAPublicKeyParameters)) { handler.failWithError(TlsProtocolHandler.AL_fatal, @@ -243,4 +242,8 @@ private Signer initSigner(TlsSigner tlsSigner, SecurityParameters securityParame signer.update(securityParameters.serverRandom, 0, securityParameters.serverRandom.length); return signer; } + + public Algorithm getAlgorithm() { + return algorithm; + } } From 8dea685cd3c3edf94065ed239be5524c58119ced Mon Sep 17 00:00:00 2001 From: Sovietaced Date: Tue, 26 Sep 2017 10:41:22 -0700 Subject: [PATCH 4/4] Update some deprecated usage in order to fix IllegalArgException while validating key usage During testing I was running into the following exception : Exception in thread "main" net.jradius.exception.RadiusException: java.lang.IllegalArgumentException: illegal object in getInstance: org.bouncycastle.asn1.x509.X509Extension. It appears that there is an updated KeyUsage.fromExtensions API that fixes this issue. In order to leverage this I had to update some of the bouncy castle classes to use newer versions. --- .../client/auth/EAPTLSAuthenticator.java | 139 +++++++++--------- .../net/jradius/tls/AlwaysValidVerifyer.java | 8 +- .../net/jradius/tls/CertificateChain.java | 20 +-- .../net/jradius/tls/CertificateVerifyer.java | 4 +- .../net/jradius/tls/DefaultTlsClient.java | 4 +- .../net/jradius/tls/TlsDHKeyExchange.java | 25 ++-- .../net/jradius/tls/TlsRSAKeyExchange.java | 25 ++-- .../net/jradius/tls/TlsSRPKeyExchange.java | 25 ++-- 8 files changed, 119 insertions(+), 131 deletions(-) diff --git a/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java b/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java index 313c999..6b0c159 100644 --- a/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java +++ b/extended/src/main/java/net/jradius/client/auth/EAPTLSAuthenticator.java @@ -37,17 +37,7 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509KeyManager; -import net.jradius.client.RadiusClient; -import net.jradius.exception.RadiusException; -import net.jradius.log.RadiusLog; -import net.jradius.packet.RadiusPacket; -import net.jradius.tls.AlwaysValidVerifyer; -import net.jradius.tls.CertificateChain; -import net.jradius.tls.DefaultTlsClient; -import net.jradius.tls.TlsProtocolHandler; -import net.jradius.util.KeyStoreUtil; import org.bouncycastle.asn1.ASN1Encodable; - import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -65,8 +55,8 @@ import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.DSAParameter; -import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x9.X962NamedCurves; import org.bouncycastle.asn1.x9.X962Parameters; import org.bouncycastle.asn1.x9.X9ECParameters; @@ -82,10 +72,20 @@ import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import net.jradius.client.RadiusClient; +import net.jradius.exception.RadiusException; +import net.jradius.log.RadiusLog; +import net.jradius.packet.RadiusPacket; +import net.jradius.tls.AlwaysValidVerifyer; +import net.jradius.tls.CertificateChain; +import net.jradius.tls.DefaultTlsClient; +import net.jradius.tls.TlsProtocolHandler; +import net.jradius.util.KeyStoreUtil; + /** * EAP-TLS Authentication (and TLS Tunnel support). - * + * * @author David Bird */ public class EAPTLSAuthenticator extends EAPAuthenticator @@ -95,22 +95,22 @@ public class EAPTLSAuthenticator extends EAPAuthenticator private String keyFileType; private String keyFile; private String keyPassword; - + private String caFileType; private String caFile; private String caPassword; - + private Boolean trustAll = Boolean.FALSE; private ByteArrayOutputStream bout; private ByteArrayInputStream bin; - private TlsProtocolHandler handler = new TlsProtocolHandler(); - private AlwaysValidVerifyer verifyer = new AlwaysValidVerifyer(); - + private final TlsProtocolHandler handler = new TlsProtocolHandler(); + private final AlwaysValidVerifyer verifyer = new AlwaysValidVerifyer(); + private DefaultTlsClient tlsClient = null; - - private ByteBuffer receivedEAP = ByteBuffer.allocate(10000000); + + private final ByteBuffer receivedEAP = ByteBuffer.allocate(10000000); private KeyManager keyManagers[] = null; private TrustManager trustManagers[] = null; @@ -124,10 +124,11 @@ public EAPTLSAuthenticator() caFileType = "pkcs12"; caPassword = ""; } - + /* (non-Javadoc) * @see net.sf.jradius.client.auth.RadiusAuthenticator#setupRequest(net.sf.jradius.client.RadiusClient, net.sf.jradius.packet.RadiusPacket) */ + @Override public void setupRequest(RadiusClient c, RadiusPacket p) throws RadiusException, NoSuchAlgorithmException { super.setupRequest(c, p); @@ -136,8 +137,8 @@ public void setupRequest(RadiusClient c, RadiusPacket p) throws RadiusException, /** * Initializs the SSL layer. - * @throws Exception - * @throws FileNotFoundException + * @throws Exception + * @throws FileNotFoundException */ public void init() throws RadiusException { @@ -147,8 +148,8 @@ public void init() throws RadiusException { keyManagers = KeyStoreUtil.loadKeyManager(getKeyFileType(), new FileInputStream(getKeyFile()), getKeyPassword()); } - - if (getTrustAll().booleanValue()) + + if (getTrustAll().booleanValue()) { trustManagers = KeyStoreUtil.trustAllManager(); } @@ -156,14 +157,14 @@ else if (getCaFile() != null) { trustManagers = KeyStoreUtil.loadTrustManager(getCaFileType(), new FileInputStream(getCaFile()), getCaPassword()); } - + tlsClient = new DefaultTlsClient(verifyer); try { if (keyManagers != null && keyManagers.length > 0) { - X509CertificateStructure[] certs = null; + Certificate[] certs = null; X509Certificate[] certChain = ((X509KeyManager)keyManagers[0]).getCertificateChain(""); PrivateKey key = ((X509KeyManager)keyManagers[0]).getPrivateKey(""); Vector tmp = new Vector(); @@ -173,17 +174,17 @@ else if (getCaFile() != null) ByteArrayInputStream bis = new ByteArrayInputStream(cert.getEncoded()); ASN1InputStream ais = new ASN1InputStream(bis); ASN1Primitive o = ais.readObject(); - tmp.addElement(X509CertificateStructure.getInstance(o)); + tmp.addElement(Certificate.getInstance(o)); if (bis.available() > 0) { throw new IllegalArgumentException( "Sorry, there is garbage data left after the certificate"); } } - certs = new X509CertificateStructure[tmp.size()]; + certs = new Certificate[tmp.size()]; for (int i = 0; i < tmp.size(); i++) { - certs[i] = (X509CertificateStructure)tmp.elementAt(i); + certs[i] = (Certificate)tmp.elementAt(i); } tlsClient.enableClientAuthentication(new CertificateChain(certs), createKey(key.getEncoded())); @@ -208,14 +209,14 @@ else if (getCaFile() != null) { KeyManager keyManagers[] = null; TrustManager trustManagers[] = null; - + if (getKeyFile() != null) { KeyStore ksKeys = KeyStore.getInstance(getKeyFileType()); ksKeys.load(new FileInputStream(getKeyFile()), getKeyPassword().toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ksKeys, getKeyPassword().toCharArray()); - + keyManagers = kmf.getKeyManagers(); } @@ -225,12 +226,12 @@ else if (getCaFile() != null) caKeys.load(new FileInputStream(getCaFile()), getCaPassword().toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(caKeys); - + trustManagers = tmf.getTrustManagers(); } - else + else { - if (getTrustAll().booleanValue()) + if (getTrustAll().booleanValue()) { trustManagers = new TrustManager[]{ new NoopX509TrustManager() }; } @@ -246,6 +247,7 @@ else if (getCaFile() != null) /** * @see net.jradius.client.auth.RadiusAuthenticator#getAuthName() */ + @Override public String getAuthName() { return NAME; @@ -259,17 +261,17 @@ public String getAuthName() protected static final int TLS_CLIENT_HELLO = 0; protected static final int TLS_SERVER_HELLO = 1; protected static final int TLS_APP_DATA = 2; - + protected byte[] eapFragmentedReply = null; protected int eapFragmentedOffset = 0; - + ByteArrayOutputStream appOutput = new ByteArrayOutputStream(); - + public void setServerMode() { state = TLS_SERVER_HELLO; } - + public void putAppBuffer(byte []b) { try @@ -294,21 +296,22 @@ public void putAppBuffer(byte []b, int off, int len) } } - protected byte[] getAppBuffer() + protected byte[] getAppBuffer() { byte b[] = appOutput.toByteArray(); appOutput = new ByteArrayOutputStream(); return b; } + @Override public byte[] doEAPType(byte id, byte[] data) throws RadiusException { ByteBuffer bb = ByteBuffer.wrap(data); - + byte dflags = bb.get(); byte flags = 0; int dlen = 0; - + try { if ((dflags & TLS_HAS_LENGTH) != 0) @@ -349,14 +352,14 @@ public byte[] doEAPType(byte id, byte[] data) throws RadiusException case 1: { receivedEAP.flip(); - ByteArrayInputStream is = new ByteArrayInputStream(receivedEAP.array(), - receivedEAP.position(), + ByteArrayInputStream is = new ByteArrayInputStream(receivedEAP.array(), + receivedEAP.position(), receivedEAP.remaining()); ByteArrayOutputStream os = new ByteArrayOutputStream(); short s = handler.updateConnectState(is, os); data = os.toByteArray(); receivedEAP.clear(); - if (s == TlsProtocolHandler.CS_DONE) + if (s == TlsProtocolHandler.CS_DONE) { state = 2; } @@ -370,8 +373,8 @@ public byte[] doEAPType(byte id, byte[] data) throws RadiusException case 2: { receivedEAP.flip(); - ByteArrayInputStream is = new ByteArrayInputStream(receivedEAP.array(), - receivedEAP.position(), + ByteArrayInputStream is = new ByteArrayInputStream(receivedEAP.array(), + receivedEAP.position(), receivedEAP.remaining()); ByteArrayOutputStream os = new ByteArrayOutputStream(); @@ -390,19 +393,19 @@ public byte[] doEAPType(byte id, byte[] data) throws RadiusException { RadiusLog.error(e.getMessage(), e); } - + data = os.toByteArray(); receivedEAP.clear(); } break; } - + if (data != null && data.length > 1024) { eapFragmentedReply = data; return nextFragment(); } - + return tlsResponse(flags, data); } catch (Exception e) @@ -410,13 +413,13 @@ public byte[] doEAPType(byte id, byte[] data) throws RadiusException throw new RadiusException(e); } } - + protected byte[] nextFragment() { int left = eapFragmentedReply.length - eapFragmentedOffset; byte flags = (byte)0; - - if (left > 1024) + + if (left > 1024) { left = 1024; flags |= TLS_MORE_FRAGMENTS; @@ -425,13 +428,13 @@ protected byte[] nextFragment() byte[] data = new byte[left]; System.arraycopy(eapFragmentedReply, eapFragmentedOffset, data, 0, data.length); eapFragmentedOffset += data.length; - + if (eapFragmentedReply.length == eapFragmentedOffset) { eapFragmentedReply = null; eapFragmentedOffset = 0; } - + return tlsResponse(flags, data); } @@ -439,10 +442,10 @@ protected byte[] tlsResponse(byte flags, byte[] data) { int length = 1; - if (data != null && data.length > 0) + if (data != null && data.length > 0) { length += data.length; - if (flags != 0) + if (flags != 0) { length += 4; flags |= TLS_HAS_LENGTH; @@ -451,15 +454,15 @@ protected byte[] tlsResponse(byte flags, byte[] data) byte[] response = new byte[length]; response[0] = flags; - - if (data != null && data.length > 0) + + if (data != null && data.length > 0) { - if (flags == 0) + if (flags == 0) { System.arraycopy(data, 0, response, 1, data.length); } - else - { + else + { length -= 1; response[1] = (byte) (eapFragmentedReply.length >> 24 & 0xFF); response[2] = (byte) (eapFragmentedReply.length >> 16 & 0xFF); @@ -471,7 +474,7 @@ protected byte[] tlsResponse(byte flags, byte[] data) return response; } - + protected boolean doTunnelAuthentication(byte id, byte[] in) throws Throwable { // Not needed for EAP-TLS, but dependent protocols (PEAP, EAP-TTLS) implement this @@ -537,7 +540,7 @@ public void setCaPassword(String caPassword) { this.caPassword = caPassword; } - + public Boolean getTrustAll() { return trustAll; @@ -548,10 +551,10 @@ public void setTrustAll(Boolean trustAll) this.trustAll = trustAll; } - + /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding. - * + * * @param privateKeyInfoData the PrivateKeyInfo encoding * @return a suitable private key parameter * @throws IOException on an error decoding the key @@ -567,7 +570,7 @@ public static AsymmetricKeyParameter createKey( /** * Create a private key parameter from a PKCS8 PrivateKeyInfo encoding read from a stream. - * + * * @param inStr the stream to read the PrivateKeyInfo encoding from * @return a suitable private key parameter * @throws IOException on an error decoding the key @@ -583,7 +586,7 @@ public static AsymmetricKeyParameter createKey( /** * Create a private key parameter from the passed in PKCS8 PrivateKeyInfo object. - * + * * @param keyInfo the PrivateKeyInfo object containing the key material * @return a suitable private key parameter * @throws IOException on an error decoding the key @@ -698,7 +701,7 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) { } } */ - protected boolean isCertificateRequired() + protected boolean isCertificateRequired() { return true; } diff --git a/extended/src/main/java/net/jradius/tls/AlwaysValidVerifyer.java b/extended/src/main/java/net/jradius/tls/AlwaysValidVerifyer.java index 807d353..3c38551 100644 --- a/extended/src/main/java/net/jradius/tls/AlwaysValidVerifyer.java +++ b/extended/src/main/java/net/jradius/tls/AlwaysValidVerifyer.java @@ -1,10 +1,10 @@ package net.jradius.tls; -import org.bouncycastle.asn1.x509.X509CertificateStructure; +import org.bouncycastle.asn1.x509.Certificate; /** * A certificate verifyer, that will always return true. - * + * *

  * DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING.
  * 
@@ -13,10 +13,10 @@ public class AlwaysValidVerifyer implements CertificateVerifyer { /** * Return true. - * + * * @see org.bouncycastle.crypto.tls.CertificateVerifyer#isValid(org.bouncycastle.asn1.x509.X509CertificateStructure[]) */ - public boolean isValid(X509CertificateStructure[] certs) + public boolean isValid(Certificate[] certs) { return true; } diff --git a/extended/src/main/java/net/jradius/tls/CertificateChain.java b/extended/src/main/java/net/jradius/tls/CertificateChain.java index df694a1..4622abe 100644 --- a/extended/src/main/java/net/jradius/tls/CertificateChain.java +++ b/extended/src/main/java/net/jradius/tls/CertificateChain.java @@ -11,7 +11,7 @@ import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.x509.X509CertificateStructure; +import org.bouncycastle.asn1.x509.Certificate; /** * A representation for a certificate chain as used by a tls server. @@ -21,7 +21,7 @@ public class CertificateChain /** * The certificates. */ - protected X509CertificateStructure[] certs; + protected Certificate[] certs; /** * Parse the ServerCertificate message. @@ -32,7 +32,7 @@ public class CertificateChain */ public static CertificateChain parse(InputStream is) throws IOException { - X509CertificateStructure[] certs; + Certificate[] certs; int left = TlsUtils.readUint24(is); Vector tmp = new Vector(); while (left > 0) @@ -44,17 +44,17 @@ public static CertificateChain parse(InputStream is) throws IOException ByteArrayInputStream bis = new ByteArrayInputStream(buf); ASN1InputStream ais = new ASN1InputStream(bis); ASN1Primitive o = ais.readObject(); - tmp.addElement(X509CertificateStructure.getInstance(o)); + tmp.addElement(Certificate.getInstance(o)); if (bis.available() > 0) { throw new IllegalArgumentException( "Sorry, there is garbage data left after the certificate"); } } - certs = new X509CertificateStructure[tmp.size()]; + certs = new Certificate[tmp.size()]; for (int i = 0; i < tmp.size(); i++) { - certs[i] = (X509CertificateStructure)tmp.elementAt(i); + certs[i] = (Certificate)tmp.elementAt(i); } return new CertificateChain(certs); } @@ -91,7 +91,7 @@ protected void encode(OutputStream os) throws IOException * * @param certs The certs the chain should contain. */ - public CertificateChain(X509CertificateStructure[] certs) + public CertificateChain(Certificate[] certs) { this.certs = certs; } @@ -99,9 +99,9 @@ public CertificateChain(X509CertificateStructure[] certs) /** * @return An array which contains the certs, this chain contains. */ - public X509CertificateStructure[] getCerts() + public Certificate[] getCerts() { - X509CertificateStructure[] result = new X509CertificateStructure[certs.length]; + Certificate[] result = new Certificate[certs.length]; System.arraycopy(certs, 0, result, 0, certs.length); return result; } @@ -109,7 +109,7 @@ public X509CertificateStructure[] getCerts() public X509Certificate[] toX509() throws IOException, CertificateException { X509Certificate[] x509 = new X509Certificate[certs.length]; for (int i = 0; i < certs.length; i++) { - X509CertificateStructure cert = certs[i]; + Certificate cert = certs[i]; InputStream in = new ByteArrayInputStream(cert.getEncoded()); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); x509[i] = (X509Certificate)certFactory.generateCertificate(in); diff --git a/extended/src/main/java/net/jradius/tls/CertificateVerifyer.java b/extended/src/main/java/net/jradius/tls/CertificateVerifyer.java index e03a93b..f283fff 100644 --- a/extended/src/main/java/net/jradius/tls/CertificateVerifyer.java +++ b/extended/src/main/java/net/jradius/tls/CertificateVerifyer.java @@ -1,6 +1,6 @@ package net.jradius.tls; -import org.bouncycastle.asn1.x509.X509CertificateStructure; +import org.bouncycastle.asn1.x509.Certificate; /** * This should be implemented by any class which can find out, if a given certificate @@ -12,5 +12,5 @@ public interface CertificateVerifyer * @param certs The certs, which are part of the chain. * @return True, if the chain is accepted, false otherwise. */ - public boolean isValid(X509CertificateStructure[] certs); + public boolean isValid(Certificate[] certs); } diff --git a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java index 3331146..2efc4a7 100644 --- a/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java +++ b/extended/src/main/java/net/jradius/tls/DefaultTlsClient.java @@ -4,7 +4,7 @@ import java.util.Hashtable; import java.util.List; -import org.bouncycastle.asn1.x509.X509CertificateStructure; +import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.digests.SHA1Digest; @@ -70,7 +70,7 @@ public class DefaultTlsClient implements TlsClient private TlsProtocolHandler handler; // (Optional) details for client-side authentication - private CertificateChain clientCert = new CertificateChain(new X509CertificateStructure[0]); + private CertificateChain clientCert = new CertificateChain(new Certificate[0]); private AsymmetricKeyParameter clientPrivateKey = null; private TlsSigner clientSigner = null; diff --git a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java index fe1c1aa..f5bf970 100644 --- a/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsDHKeyExchange.java @@ -4,11 +4,10 @@ import java.io.InputStream; import java.math.BigInteger; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509CertificateStructure; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.agreement.DHBasicAgreement; @@ -71,7 +70,7 @@ public void skipServerCertificate() throws IOException public void processServerCertificate(CertificateChain serverCertificate) throws IOException { - X509CertificateStructure x509Cert = serverCertificate.certs[0]; + Certificate x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try @@ -233,21 +232,17 @@ public byte[] generatePremasterSecret() throws IOException return BigIntegers.asUnsignedByteArray(agreement); } - private void validateKeyUsage(X509CertificateStructure c, int keyUsageBits) throws IOException + private void validateKeyUsage(Certificate c, int keyUsageBits) throws IOException { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(X509Extensions.KeyUsage); - if (ext != null) + KeyUsage ku = KeyUsage.fromExtensions(exts); + int bits = ku.getBytes()[0] & 0xff; + if ((bits & keyUsageBits) != keyUsageBits) { - KeyUsage ku = KeyUsage.getInstance(ext); - int bits = ku.getBytes()[0] & 0xff; - if ((bits & keyUsageBits) != keyUsageBits) - { - handler.failWithError(TlsProtocolHandler.AL_fatal, - TlsProtocolHandler.AP_certificate_unknown); - } + handler.failWithError(TlsProtocolHandler.AL_fatal, + TlsProtocolHandler.AP_certificate_unknown); } } } diff --git a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java index e5677fe..8bd3192 100644 --- a/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsRSAKeyExchange.java @@ -3,11 +3,10 @@ import java.io.IOException; import java.io.InputStream; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509CertificateStructure; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.PKCS1Encoding; import org.bouncycastle.crypto.engines.RSABlindedEngine; @@ -43,7 +42,7 @@ public void skipServerCertificate() throws IOException public void processServerCertificate(CertificateChain serverCertificate) throws IOException { - X509CertificateStructure x509Cert = serverCertificate.certs[0]; + Certificate x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try @@ -132,21 +131,17 @@ public byte[] generatePremasterSecret() throws IOException return tmp; } - private void validateKeyUsage(X509CertificateStructure c, int keyUsageBits) throws IOException + private void validateKeyUsage(Certificate c, int keyUsageBits) throws IOException { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(X509Extensions.KeyUsage); - if (ext != null) + KeyUsage ku = KeyUsage.fromExtensions(exts); + int bits = ku.getBytes()[0] & 0xff; + if ((bits & keyUsageBits) != keyUsageBits) { - KeyUsage ku = KeyUsage.getInstance(ext); - int bits = ku.getBytes()[0] & 0xff; - if ((bits & keyUsageBits) != keyUsageBits) - { - handler.failWithError(TlsProtocolHandler.AL_fatal, - TlsProtocolHandler.AP_certificate_unknown); - } + handler.failWithError(TlsProtocolHandler.AL_fatal, + TlsProtocolHandler.AP_certificate_unknown); } } } diff --git a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java index 9063f77..dc89095 100644 --- a/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java +++ b/extended/src/main/java/net/jradius/tls/TlsSRPKeyExchange.java @@ -4,11 +4,10 @@ import java.io.InputStream; import java.math.BigInteger; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509CertificateStructure; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.agreement.srp.SRP6Client; @@ -80,7 +79,7 @@ public void processServerCertificate(CertificateChain serverCertificate) throws TlsProtocolHandler.AP_unexpected_message); } - X509CertificateStructure x509Cert = serverCertificate.certs[0]; + Certificate x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo(); try @@ -216,21 +215,17 @@ public byte[] generatePremasterSecret() throws IOException } } - private void validateKeyUsage(X509CertificateStructure c, int keyUsageBits) throws IOException + private void validateKeyUsage(Certificate c, int keyUsageBits) throws IOException { - X509Extensions exts = c.getTBSCertificate().getExtensions(); + Extensions exts = c.getTBSCertificate().getExtensions(); if (exts != null) { - X509Extension ext = exts.getExtension(X509Extensions.KeyUsage); - if (ext != null) + KeyUsage ku = KeyUsage.getInstance(exts); + int bits = ku.getBytes()[0] & 0xff; + if ((bits & keyUsageBits) != keyUsageBits) { - KeyUsage ku = KeyUsage.getInstance(ext); - int bits = ku.getBytes()[0] & 0xff; - if ((bits & keyUsageBits) != keyUsageBits) - { - handler.failWithError(TlsProtocolHandler.AL_fatal, - TlsProtocolHandler.AP_certificate_unknown); - } + handler.failWithError(TlsProtocolHandler.AL_fatal, + TlsProtocolHandler.AP_certificate_unknown); } } }