From 6058b1923cf8dc55226263a5d88d30d57a5c2472 Mon Sep 17 00:00:00 2001 From: pphaal Date: Fri, 16 Feb 2018 12:43:45 -0800 Subject: [PATCH 1/3] Fixed MSCHAP regressions Restore gnu-crypto methods --- core/pom.xml | 2 - .../main/java/net/jradius/util/MSCHAP.java | 47 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 9e94014..b346f1d 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -72,13 +72,11 @@ - diff --git a/core/src/main/java/net/jradius/util/MSCHAP.java b/core/src/main/java/net/jradius/util/MSCHAP.java index a5f5380..d30c778 100644 --- a/core/src/main/java/net/jradius/util/MSCHAP.java +++ b/core/src/main/java/net/jradius/util/MSCHAP.java @@ -25,12 +25,22 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +/* fails, revert to gnu-crypto version import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; +*/ + +import gnu.crypto.cipher.CipherFactory; +import gnu.crypto.cipher.IBlockCipher; +import gnu.crypto.cipher.WeakKeyException; +import gnu.crypto.hash.HashFactory; +import gnu.crypto.hash.IMessageDigest; import net.jradius.log.RadiusLog; @@ -80,6 +90,7 @@ private static byte[] ChallengeHash(final byte[] PeerChallenge, final byte[] Aut return Challenge; } + /* fails without MD4 provider, revert to gnu-crypto version private static byte[] NtPasswordHash(byte[] Password) throws NoSuchAlgorithmException { byte PasswordHash[] = new byte[16]; @@ -89,6 +100,17 @@ private static byte[] NtPasswordHash(byte[] Password) throws NoSuchAlgorithmExce System.arraycopy(md.digest(), 0, PasswordHash, 0, 16); return PasswordHash; } + */ + + private static byte[] NtPasswordHash(byte[] Password) throws NoSuchAlgorithmException + { + byte PasswordHash[] = new byte[16]; + byte uniPassword[] = unicode(Password); + IMessageDigest md = HashFactory.getInstance("MD4"); + md.update(uniPassword, 0, uniPassword.length); + System.arraycopy(md.digest(), 0, PasswordHash, 0, 16); + return PasswordHash; + } /* not used currently private static byte[] HashNtPasswordHash(byte[] PasswordHash) @@ -101,6 +123,7 @@ private static byte[] HashNtPasswordHash(byte[] PasswordHash) } */ + /* fails, revert to gnu-crypto version private static void DesEncrypt(byte[] Clear, int clearOffset, byte[] Key, int keyOffset, byte[] Cypher, int cypherOffset) { byte szParityKey[] = new byte[8]; @@ -122,6 +145,30 @@ private static void DesEncrypt(byte[] Clear, int clearOffset, byte[] Key, int ke RadiusLog.warn(e.getMessage(), e); } } + */ + + private static void DesEncrypt(byte[] Clear, int clearOffset, byte[] Key, int keyOffset, byte[] Cypher, int cypherOffset) + { + byte szParityKey[] = new byte[8]; + parity_key(szParityKey, Key, keyOffset); + + IBlockCipher cipher = CipherFactory.getInstance("DES"); + Map attributes = new HashMap(); + + attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(8)); + attributes.put(IBlockCipher.KEY_MATERIAL, szParityKey); + + try + { + cipher.init(attributes); + cipher.encryptBlock(Clear, clearOffset, Cypher, cypherOffset); + } + catch (WeakKeyException e) { } + catch (Exception e) + { + RadiusLog.warn(e.getMessage(), e); + } + } private static byte[] ChallengeResponse(final byte[] Challenge, final byte[] PasswordHash) { From 5827998c0d1f1411475a72c1c0404931385a9a59 Mon Sep 17 00:00:00 2001 From: pphaal Date: Wed, 21 Feb 2018 13:18:03 -0800 Subject: [PATCH 2/3] Fixed TLS certificate parsing --- extended/pom.xml | 6 + .../java/net/jradius/util/KeyStoreUtil.java | 136 +++++++++--------- 2 files changed, 74 insertions(+), 68 deletions(-) diff --git a/extended/pom.xml b/extended/pom.xml index 2eed19c..831b60a 100644 --- a/extended/pom.xml +++ b/extended/pom.xml @@ -33,6 +33,12 @@ bcprov-jdk15on 1.56 + + + org.bouncycastle + bcpkix-jdk15on + 1.56 + diff --git a/extended/src/main/java/net/jradius/util/KeyStoreUtil.java b/extended/src/main/java/net/jradius/util/KeyStoreUtil.java index 85d0a7e..25bbc91 100644 --- a/extended/src/main/java/net/jradius/util/KeyStoreUtil.java +++ b/extended/src/main/java/net/jradius/util/KeyStoreUtil.java @@ -22,11 +22,17 @@ import java.io.InputStream; import java.io.InputStreamReader; +import java.io.ByteArrayInputStream; +import java.security.Key; +import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyStore; import java.security.PrivateKey; +import java.security.AlgorithmParameters; import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; import java.util.Enumeration; import javax.net.ssl.KeyManager; @@ -36,7 +42,19 @@ import javax.net.ssl.X509TrustManager; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.util.io.pem.PemReader; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.PEMDecryptorProvider; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMEncryptedKeyPair; +import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.operator.InputDecryptorProvider; public class KeyStoreUtil { @@ -56,22 +74,41 @@ public static KeyManager[] loadKeyManager(String type, InputStream in, String pa if (type.equalsIgnoreCase("pem")) { - PemReader pemReader = new PemReader(new InputStreamReader(in)); - - Object obj, keyObj=null, certObj=null, keyPair=null; - - while ((obj = pemReader.readPemObject()) != null) - { - if (obj instanceof X509Certificate) certObj = obj; - else if (obj instanceof PrivateKey) keyObj = obj; - else if (obj instanceof KeyPair) keyPair = obj; + Object obj; + PrivateKey key = null; + X509Certificate cert = null; + KeyPair keyPair = null; + + PEMParser pemParser = new PEMParser(new InputStreamReader(in)); + try { + while ((obj = pemParser.readObject()) != null) + { + if(obj instanceof X509CertificateHolder) { + cert = new JcaX509CertificateConverter() + .setProvider("BC") + .getCertificate((X509CertificateHolder)obj); + } else if(obj instanceof PrivateKeyInfo) { + key = BouncyCastleProvider.getPrivateKey((PrivateKeyInfo)obj); + } else if(obj instanceof PKCS8EncryptedPrivateKeyInfo) { + InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray()); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); + key = converter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo)obj).decryptPrivateKeyInfo(pkcs8Prov)); + } else if(obj instanceof PEMKeyPair) { + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); + keyPair = converter.getKeyPair((PEMKeyPair)obj); + } else if(obj instanceof PEMEncryptedKeyPair) { + PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray()); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); + keyPair = converter.getKeyPair(((PEMEncryptedKeyPair)obj).decryptKeyPair(decProv)); + } + } + } finally { + pemParser.close(); } - if ((keyObj != null || keyPair != null) && certObj != null) + if ((key != null || keyPair != null) && cert != null) { - final PrivateKey key = keyPair != null ? ((KeyPair)keyPair).getPrivate() : (PrivateKey) keyObj; - final X509Certificate cert = (X509Certificate) certObj; - + // final PrivateKey key = keyPair != null ? ((KeyPair)keyPair).getPrivate() : (PrivateKey) keyObj; KeyStore ksKeys = KeyStore.getInstance("JKS"); ksKeys.load(null, pwd == null ? "".toCharArray() : pwd); @@ -81,35 +118,6 @@ public static KeyManager[] loadKeyManager(String type, InputStream in, String pa kmf.init(ksKeys, pwd == null ? "".toCharArray() : pwd); return kmf.getKeyManagers(); - -/* - return new KeyManager[] { new X509KeyManager() - { - public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - return "a"; - } - - public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { - return "a"; - } - - public X509Certificate[] getCertificateChain(String alias) { - return new X509Certificate[] { cert }; - } - - public String[] getClientAliases(String keyType, Principal[] issuers) { - return new String[] {"a"}; - } - - public PrivateKey getPrivateKey(String alias) { - return key; - } - - public String[] getServerAliases(String keyType, Principal[] issuers) { - return new String[] {"a"}; - } - }}; - */ } else { @@ -118,32 +126,33 @@ public String[] getServerAliases(String keyType, Principal[] issuers) { } KeyStore ksKeys = KeyStore.getInstance(type); - ksKeys.load(in, pwd); + ksKeys.load(in, pwd); - Enumeration aliases = ksKeys.aliases(); + Enumeration aliases = ksKeys.aliases(); while (aliases.hasMoreElements()) { String alias = (String) aliases.nextElement(); System.err.println("KeyStore Alias: "+alias); } - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ksKeys, pwd); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ksKeys, pwd); - return kmf.getKeyManagers(); + return kmf.getKeyManagers(); } public static X509Certificate loadCertificateFromPEM(InputStream in, final char[] pwd) throws Exception { loadBC(); - PemReader pemReader = new PemReader(new InputStreamReader(in)); + PEMParser pemParser = new PEMParser(new InputStreamReader(in)); Object obj; - while ((obj = pemReader.readPemObject()) != null) + while ((obj = pemParser.readObject()) != null) { - if (obj instanceof X509Certificate) - { - return (X509Certificate) obj; + if(obj instanceof X509CertificateHolder) { + return new JcaX509CertificateConverter() + .setProvider("BC") + .getCertificate((X509CertificateHolder)obj); } } @@ -169,30 +178,21 @@ public static TrustManager[] loadTrustManager(String type, InputStream in, Strin tmf.init(ksKeys); return tmf.getTrustManagers(); - -/* - return new TrustManager[] { new X509TrustManager() - { - public void checkClientTrusted(X509Certificate[] chain, String authType) { } - public void checkServerTrusted(X509Certificate[] chain, String authType) { } - public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] { cert }; } - }}; -*/ } KeyStore caKeys = KeyStore.getInstance(type); - caKeys.load(in, pwd); + caKeys.load(in, pwd); - Enumeration aliases = caKeys.aliases(); + Enumeration aliases = caKeys.aliases(); while (aliases.hasMoreElements()) { String alias = (String) aliases.nextElement(); System.err.println("KeyStore Alias: "+alias); } - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(caKeys); + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(caKeys); - return tmf.getTrustManagers(); + return tmf.getTrustManagers(); } public static TrustManager[] trustAllManager() @@ -206,4 +206,4 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}; } -} \ No newline at end of file +} From b35734e50edbc3b843cd7c6f4d6645ace0622f9f Mon Sep 17 00:00:00 2001 From: pphaal Date: Wed, 21 Feb 2018 14:51:14 -0800 Subject: [PATCH 3/3] Missing close of PEMParser --- .../java/net/jradius/util/KeyStoreUtil.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/extended/src/main/java/net/jradius/util/KeyStoreUtil.java b/extended/src/main/java/net/jradius/util/KeyStoreUtil.java index 25bbc91..86851e2 100644 --- a/extended/src/main/java/net/jradius/util/KeyStoreUtil.java +++ b/extended/src/main/java/net/jradius/util/KeyStoreUtil.java @@ -146,14 +146,18 @@ public static X509Certificate loadCertificateFromPEM(InputStream in, final char[ PEMParser pemParser = new PEMParser(new InputStreamReader(in)); - Object obj; - while ((obj = pemParser.readObject()) != null) - { - if(obj instanceof X509CertificateHolder) { - return new JcaX509CertificateConverter() - .setProvider("BC") - .getCertificate((X509CertificateHolder)obj); + try { + Object obj; + while ((obj = pemParser.readObject()) != null) + { + if(obj instanceof X509CertificateHolder) { + return new JcaX509CertificateConverter() + .setProvider("BC") + .getCertificate((X509CertificateHolder)obj); + } } + } finally { + pemParser.close(); } return null;