From 689ed4135ea36bed8d420eb11ca389499fa4a440 Mon Sep 17 00:00:00 2001
From: caodongxia <315816521@qq.com>
Date: Sat, 12 Dec 2020 14:25:15 +0800
Subject: [PATCH] CVE-2014-0363.patch
Reference: https://src.fedoraproject.org/rpms/smack/blob/48915f05037f5c246878f9b6a6fab78bfcd6c86f/f/smack-3.2.2-CVE-2014-0363.patch


diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionConfiguration.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionConfiguration.java
index 9eb7bb9..5c52561 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionConfiguration.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ConnectionConfiguration.java
@@ -27,7 +27,6 @@ import org.jivesoftware.smack.util.dns.HostAddress;
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLContext;
 import javax.security.auth.callback.CallbackHandler;
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -54,17 +53,9 @@ public class ConnectionConfiguration implements Cloneable {
     private int port;
     protected List<HostAddress> hostAddresses;
 
-    private String truststorePath;
-    private String truststoreType;
-    private String truststorePassword;
     private String keystorePath;
     private String keystoreType;
     private String pkcs11Library;
-    private boolean verifyChainEnabled = false;
-    private boolean verifyRootCAEnabled = false;
-    private boolean selfSignedCertificateEnabled = false;
-    private boolean expiredCertificatesCheckEnabled = false;
-    private boolean notMatchingDomainCheckEnabled = false;
     private SSLContext customSSLContext;
 
     private boolean compressionEnabled = false;
@@ -190,18 +181,6 @@ public class ConnectionConfiguration implements Cloneable {
         this.serviceName = serviceName;
         this.proxy = proxy;
 
-        // Build the default path to the cacert truststore file. By default we are
-        // going to use the file located in $JREHOME/lib/security/cacerts.
-        String javaHome = System.getProperty("java.home");
-        StringBuilder buffer = new StringBuilder();
-        buffer.append(javaHome).append(File.separator).append("lib");
-        buffer.append(File.separator).append("security");
-        buffer.append(File.separator).append("cacerts");
-        truststorePath = buffer.toString();
-        // Set the default store type
-        truststoreType = "jks";
-        // Set the default password of the cacert file that is "changeit"
-        truststorePassword = "changeit";
         keystorePath = System.getProperty("javax.net.ssl.keyStore");
         keystoreType = "jks";
         pkcs11Library = "pkcs11.config";
@@ -274,66 +253,6 @@ public class ConnectionConfiguration implements Cloneable {
         this.securityMode = securityMode;
     }
 
-    /**
-     * Retuns the path to the trust store file. The trust store file contains the root
-     * certificates of several well known CAs. By default, will attempt to use the
-     * the file located in $JREHOME/lib/security/cacerts.
-     *
-     * @return the path to the truststore file.
-     */
-    public String getTruststorePath() {
-        return truststorePath;
-    }
-
-    /**
-     * Sets the path to the trust store file. The truststore file contains the root
-     * certificates of several well?known CAs. By default Smack is going to use
-     * the file located in $JREHOME/lib/security/cacerts.
-     *
-     * @param truststorePath the path to the truststore file.
-     */
-    public void setTruststorePath(String truststorePath) {
-        this.truststorePath = truststorePath;
-    }
-
-    /**
-     * Returns the trust store type, or <tt>null</tt> if it's not set.
-     *
-     * @return the trust store type.
-     */
-    public String getTruststoreType() {
-        return truststoreType;
-    }
-
-    /**
-     * Sets the trust store type.
-     *
-     * @param truststoreType the trust store type.
-     */
-    public void setTruststoreType(String truststoreType) {
-        this.truststoreType = truststoreType;
-    }
-
-    /**
-     * Returns the password to use to access the trust store file. It is assumed that all
-     * certificates share the same password in the trust store.
-     *
-     * @return the password to use to access the truststore file.
-     */
-    public String getTruststorePassword() {
-        return truststorePassword;
-    }
-
-    /**
-     * Sets the password to use to access the trust store file. It is assumed that all
-     * certificates share the same password in the trust store.
-     *
-     * @param truststorePassword the password to use to access the truststore file.
-     */
-    public void setTruststorePassword(String truststorePassword) {
-        this.truststorePassword = truststorePassword;
-    }
-
     /**
      * Retuns the path to the keystore file. The key store file contains the 
      * certificates that may be used to authenticate the client to the server,
@@ -395,110 +314,6 @@ public class ConnectionConfiguration implements Cloneable {
         this.pkcs11Library = pkcs11Library;
     }
 
-    /**
-     * Returns true if the whole chain of certificates presented by the server are going to
-     * be checked. By default the certificate chain is not verified.
-     *
-     * @return true if the whole chaing of certificates presented by the server are going to
-     *         be checked.
-     */
-    public boolean isVerifyChainEnabled() {
-        return verifyChainEnabled;
-    }
-
-    /**
-     * Sets if the whole chain of certificates presented by the server are going to
-     * be checked. By default the certificate chain is not verified.
-     *
-     * @param verifyChainEnabled if the whole chaing of certificates presented by the server
-     *        are going to be checked.
-     */
-    public void setVerifyChainEnabled(boolean verifyChainEnabled) {
-        this.verifyChainEnabled = verifyChainEnabled;
-    }
-
-    /**
-     * Returns true if root CA checking is going to be done. By default checking is disabled.
-     *
-     * @return true if root CA checking is going to be done.
-     */
-    public boolean isVerifyRootCAEnabled() {
-        return verifyRootCAEnabled;
-    }
-
-    /**
-     * Sets if root CA checking is going to be done. By default checking is disabled.
-     *
-     * @param verifyRootCAEnabled if root CA checking is going to be done.
-     */
-    public void setVerifyRootCAEnabled(boolean verifyRootCAEnabled) {
-        this.verifyRootCAEnabled = verifyRootCAEnabled;
-    }
-
-    /**
-     * Returns true if self-signed certificates are going to be accepted. By default
-     * this option is disabled.
-     *
-     * @return true if self-signed certificates are going to be accepted.
-     */
-    public boolean isSelfSignedCertificateEnabled() {
-        return selfSignedCertificateEnabled;
-    }
-
-    /**
-     * Sets if self-signed certificates are going to be accepted. By default
-     * this option is disabled.
-     *
-     * @param selfSignedCertificateEnabled if self-signed certificates are going to be accepted.
-     */
-    public void setSelfSignedCertificateEnabled(boolean selfSignedCertificateEnabled) {
-        this.selfSignedCertificateEnabled = selfSignedCertificateEnabled;
-    }
-
-    /**
-     * Returns true if certificates presented by the server are going to be checked for their
-     * validity. By default certificates are not verified.
-     *
-     * @return true if certificates presented by the server are going to be checked for their
-     *         validity.
-     */
-    public boolean isExpiredCertificatesCheckEnabled() {
-        return expiredCertificatesCheckEnabled;
-    }
-
-    /**
-     * Sets if certificates presented by the server are going to be checked for their
-     * validity. By default certificates are not verified.
-     *
-     * @param expiredCertificatesCheckEnabled if certificates presented by the server are going
-     *        to be checked for their validity.
-     */
-    public void setExpiredCertificatesCheckEnabled(boolean expiredCertificatesCheckEnabled) {
-        this.expiredCertificatesCheckEnabled = expiredCertificatesCheckEnabled;
-    }
-
-    /**
-     * Returns true if certificates presented by the server are going to be checked for their
-     * domain. By default certificates are not verified.
-     *
-     * @return true if certificates presented by the server are going to be checked for their
-     *         domain.
-     */
-    public boolean isNotMatchingDomainCheckEnabled() {
-        return notMatchingDomainCheckEnabled;
-    }
-
-    /**
-     * Sets if certificates presented by the server are going to be checked for their
-     * domain. By default certificates are not verified.
-     *
-     * @param notMatchingDomainCheckEnabled if certificates presented by the server are going
-     *        to be checked for their domain.
-     */
-    public void setNotMatchingDomainCheckEnabled(boolean notMatchingDomainCheckEnabled) {
-        this.notMatchingDomainCheckEnabled = notMatchingDomainCheckEnabled;
-    }
-
     /**
      * Gets the custom SSLContext for SSL sockets. This is null by default.
      *
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ServerTrustManager.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ServerTrustManager.java
deleted file mode 100644
index afc4e23..0000000
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/ServerTrustManager.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
- * $RCSfile$
- * $Revision$
- * $Date$
- *
- * Copyright 2003-2005 Jive Software.
- *
- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jivesoftware.smack;
-
-import javax.net.ssl.X509TrustManager;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.security.*;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Trust manager that checks all certificates presented by the server. This class
- * is used during TLS negotiation. It is possible to disable/enable some or all checkings
- * by configuring the {@link ConnectionConfiguration}. The truststore file that contains
- * knows and trusted CA root certificates can also be configure in {@link ConnectionConfiguration}.
- *
- * @author Gaston Dombiak
- */
-class ServerTrustManager implements X509TrustManager {
-
-    private static Pattern cnPattern = Pattern.compile("(?i)(cn=)([^,]*)");
-
-    private ConnectionConfiguration configuration;
-
-    /**
-     * Holds the domain of the remote server we are trying to connect
-     */
-    private String server;
-    private KeyStore trustStore;
-
-    private static Map<KeyStoreOptions, KeyStore> stores = new HashMap<KeyStoreOptions, KeyStore>();
-
-    public ServerTrustManager(String server, ConnectionConfiguration configuration) {
-        this.configuration = configuration;
-        this.server = server;
-
-        InputStream in = null;
-        synchronized (stores) {
-            KeyStoreOptions options = new KeyStoreOptions(configuration.getTruststoreType(),
-                    configuration.getTruststorePath(), configuration.getTruststorePassword());
-            if (stores.containsKey(options)) {
-                trustStore = stores.get(options);
-            } else {
-                try {
-                    trustStore = KeyStore.getInstance(options.getType());
-                    in = new FileInputStream(options.getPath());
-                    trustStore.load(in, options.getPassword().toCharArray());
-                } catch (Exception e) {
-                    trustStore = null;
-                    e.printStackTrace();
-                } finally {
-                    if (in != null) {
-                        try {
-                            in.close();
-                        } catch (IOException ioe) {
-                            // Ignore.
-                        }
-                    }
-                }
-                stores.put(options, trustStore);
-            }
-            if (trustStore == null)
-                // Disable root CA checking
-                configuration.setVerifyRootCAEnabled(false);
-        }
-    }
-
-    public X509Certificate[] getAcceptedIssuers() {
-        return new X509Certificate[0];
-    }
-
-    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
-            throws CertificateException {
-    }
-
-    public void checkServerTrusted(X509Certificate[] x509Certificates, String arg1)
-            throws CertificateException {
-
-        int nSize = x509Certificates.length;
-
-        List<String> peerIdentities = getPeerIdentity(x509Certificates[0]);
-
-        if (configuration.isVerifyChainEnabled()) {
-            // Working down the chain, for every certificate in the chain,
-            // verify that the subject of the certificate is the issuer of the
-            // next certificate in the chain.
-            Principal principalLast = null;
-            for (int i = nSize -1; i >= 0 ; i--) {
-                X509Certificate x509certificate = x509Certificates[i];
-                Principal principalIssuer = x509certificate.getIssuerDN();
-                Principal principalSubject = x509certificate.getSubjectDN();
-                if (principalLast != null) {
-                    if (principalIssuer.equals(principalLast)) {
-                        try {
-                            PublicKey publickey =
-                                    x509Certificates[i + 1].getPublicKey();
-                            x509Certificates[i].verify(publickey);
-                        }
-                        catch (GeneralSecurityException generalsecurityexception) {
-                            throw new CertificateException(
-                                    "signature verification failed of " + peerIdentities);
-                        }
-                    }
-                    else {
-                        throw new CertificateException(
-                                "subject/issuer verification failed of " + peerIdentities);
-                    }
-                }
-                principalLast = principalSubject;
-            }
-        }
-
-        if (configuration.isVerifyRootCAEnabled()) {
-            // Verify that the the last certificate in the chain was issued
-            // by a third-party that the client trusts.
-            boolean trusted = false;
-            try {
-                trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
-                if (!trusted && nSize == 1 && configuration.isSelfSignedCertificateEnabled())
-                {
-                    System.out.println("Accepting self-signed certificate of remote server: " +
-                            peerIdentities);
-                    trusted = true;
-                }
-            }
-            catch (KeyStoreException e) {
-                e.printStackTrace();
-            }
-            if (!trusted) {
-                throw new CertificateException("root certificate not trusted of " + peerIdentities);
-            }
-        }
-
-        if (configuration.isNotMatchingDomainCheckEnabled()) {
-            // Verify that the first certificate in the chain corresponds to
-            // the server we desire to authenticate.
-            // Check if the certificate uses a wildcard indicating that subdomains are valid
-            if (peerIdentities.size() == 1 && peerIdentities.get(0).startsWith("*.")) {
-                // Remove the wildcard
-                String peerIdentity = peerIdentities.get(0).replace("*.", "");
-                // Check if the requested subdomain matches the certified domain
-                if (!server.endsWith(peerIdentity)) {
-                    throw new CertificateException("target verification failed of " + peerIdentities);
-                }
-            }
-            else if (!peerIdentities.contains(server)) {
-                throw new CertificateException("target verification failed of " + peerIdentities);
-            }
-        }
-
-        if (configuration.isExpiredCertificatesCheckEnabled()) {
-            // For every certificate in the chain, verify that the certificate
-            // is valid at the current time.
-            Date date = new Date();
-            for (int i = 0; i < nSize; i++) {
-                try {
-                    x509Certificates[i].checkValidity(date);
-                }
-                catch (GeneralSecurityException generalsecurityexception) {
-                    throw new CertificateException("invalid date of " + server);
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Returns the identity of the remote server as defined in the specified certificate. The
-     * identity is defined in the subjectDN of the certificate and it can also be defined in
-     * the subjectAltName extension of type "xmpp". When the extension is being used then the
-     * identity defined in the extension in going to be returned. Otherwise, the value stored in
-     * the subjectDN is returned.
-     *
-     * @param x509Certificate the certificate the holds the identity of the remote server.
-     * @return the identity of the remote server as defined in the specified certificate.
-     */
-    public static List<String> getPeerIdentity(X509Certificate x509Certificate) {
-        // Look the identity in the subjectAltName extension if available
-        List<String> names = getSubjectAlternativeNames(x509Certificate);
-        if (names.isEmpty()) {
-            String name = x509Certificate.getSubjectDN().getName();
-            Matcher matcher = cnPattern.matcher(name);
-            if (matcher.find()) {
-                name = matcher.group(2);
-            }
-            // Create an array with the unique identity
-            names = new ArrayList<String>();
-            names.add(name);
-        }
-        return names;
-    }
-
-    /**
-     * Returns the JID representation of an XMPP entity contained as a SubjectAltName extension
-     * in the certificate. If none was found then return <tt>null</tt>.
-     *
-     * @param certificate the certificate presented by the remote entity.
-     * @return the JID representation of an XMPP entity contained as a SubjectAltName extension
-     *         in the certificate. If none was found then return <tt>null</tt>.
-     */
-    private static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
-        List<String> identities = new ArrayList<String>();
-        try {
-            Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
-            // Check that the certificate includes the SubjectAltName extension
-            if (altNames == null) {
-                return Collections.emptyList();
-            }
-            // Use the type OtherName to search for the certified server name
-            /*for (List item : altNames) {
-                Integer type = (Integer) item.get(0);
-                if (type == 0) {
-                    // Type OtherName found so return the associated value
-                    try {
-                        // Value is encoded using ASN.1 so decode it to get the server's identity
-                        ASN1InputStream decoder = new ASN1InputStream((byte[]) item.toArray()[1]);
-                        DEREncodable encoded = decoder.readObject();
-                        encoded = ((DERSequence) encoded).getObjectAt(1);
-                        encoded = ((DERTaggedObject) encoded).getObject();
-                        encoded = ((DERTaggedObject) encoded).getObject();
-                        String identity = ((DERUTF8String) encoded).getString();
-                        // Add the decoded server name to the list of identities
-                        identities.add(identity);
-                    }
-                    catch (UnsupportedEncodingException e) {
-                        // Ignore
-                    }
-                    catch (IOException e) {
-                        // Ignore
-                    }
-                    catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-                // Other types are not good for XMPP so ignore them
-                System.out.println("SubjectAltName of invalid type found: " + certificate);
-            }*/
-        }
-        catch (CertificateParsingException e) {
-            e.printStackTrace();
-        }
-        return identities;
-    }
-
-    private static class KeyStoreOptions {
-        private final String type;
-        private final String path;
-        private final String password;
-
-        public KeyStoreOptions(String type, String path, String password) {
-            super();
-            this.type = type;
-            this.path = path;
-            this.password = password;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getPath() {
-            return path;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((password == null) ? 0 : password.hashCode());
-            result = prime * result + ((path == null) ? 0 : path.hashCode());
-            result = prime * result + ((type == null) ? 0 : type.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            KeyStoreOptions other = (KeyStoreOptions) obj;
-            if (password == null) {
-                if (other.password != null)
-                    return false;
-            } else if (!password.equals(other.password))
-                return false;
-            if (path == null) {
-                if (other.path != null)
-                    return false;
-            } else if (!path.equals(other.path))
-                return false;
-            if (type == null) {
-                if (other.type != null)
-                    return false;
-            } else if (!type.equals(other.type))
-                return false;
-            return true;
-        }
-    }
-}
diff --git a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
index 49d6c72..3ddd324 100644
--- a/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
+++ b/protocols/bundles/org.jivesoftware.smack/src/org/jivesoftware/smack/XMPPConnection.java
@@ -860,8 +860,7 @@ public class XMPPConnection extends Connection {
         // Verify certificate presented by the server
         if (context == null) {
             context = SSLContext.getInstance("TLS");
-            context.init(kms, new javax.net.ssl.TrustManager[] { new ServerTrustManager(getServiceName(), config) },
-                    new java.security.SecureRandom());
+            context.init(kms, null, new java.security.SecureRandom());
         }
         Socket plain = socket;
         // Secure the plain connection
-- 
2.27.0

