aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java')
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java418
1 files changed, 209 insertions, 209 deletions
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java b/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
index 0027ec5..262b717 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/RFC5922Matcher.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,211 +15,211 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.protocol.sip.net;
-
-import java.security.cert.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-import javax.sip.address.*;
-
-import net.java.sip.communicator.impl.protocol.sip.*;
-import net.java.sip.communicator.service.certificate.*;
-import net.java.sip.communicator.util.*;
-
-/**
- * Matcher that extracts certificate identities according to <a
- * href="http://tools.ietf.org/html/rfc5922#section-7.1">RFC5922, Section
- * 7.1</a> and compares them with the rules from Section 7.2 and 7.3.
- * @see #PNAME_STRICT_RFC5922 for wildcard handling; the default is false
- *
- * @author Ingo Bauersachs
- */
-public class RFC5922Matcher
- implements CertificateMatcher
-{
- /**
- * When set to true, enables strict validation of the hostname according to
- * <a href="http://tools.ietf.org/html/rfc5922#section-7.2">RFC5922 Section
- * 7.2</a>
- */
- public final static String PNAME_STRICT_RFC5922 =
- "net.java.sip.communicator.sip.tls.STRICT_RFC5922";
-
- private ProtocolProviderServiceSipImpl provider;
-
- /**
- * Creates a new instance of this class.
- * @param provider The SIP Provider to which this matcher belongs.
- */
- public RFC5922Matcher(ProtocolProviderServiceSipImpl provider)
- {
- this.provider = provider;
- }
-
- /** Our class logger. */
- private static final Logger logger = Logger
- .getLogger(CertificateMatcher.class);
-
- /*
- * (non-Javadoc)
- *
- * @see
- * net.java.sip.communicator.service.certificate.CertificateMatcher#verify
- * (java.lang.Iterable, java.security.cert.X509Certificate)
- */
- public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
- throws CertificateException
- {
- boolean strict = SipActivator.getConfigurationService()
- .getBoolean(PNAME_STRICT_RFC5922, false);
-
- // if any of the identities is contained in the certificate we're good
- boolean oneMatched = false;
- Iterable<String> certIdentities = extractCertIdentities(cert);
- for (String identity : identitiesToTest)
- {
- // check if the intended hostname is contained in one of the
- // hostnames of the certificate according to
- // http://tools.ietf.org/html/rfc5922#section-7.2
- for(String dnsName : certIdentities)
- {
- try
- {
- if(NetworkUtils.compareDnsNames(dnsName, identity) == 0)
- {
- // one of the hostnames matched, we're good to go
- return;
- }
-
- if(!strict
- // is a wildcard name
- && dnsName.startsWith("*.")
- // contains at least two dots (*.example.com)
- && identity.indexOf(".") < identity.lastIndexOf(".")
- // compare *.example.com stripped to example.com with
- // - foo.example.com stripped to example.com
- // - foo.bar.example.com to bar.example.com
- && NetworkUtils.compareDnsNames(
- dnsName.substring(2),
- identity.substring(identity.indexOf(".")+1)) == 0)
- {
- // the wildcard matched, we're good to go
- return;
- }
- }
- catch (ParseException e)
- {} // we don't care - this hostname did not match
- }
- }
- if (!oneMatched)
- throw new CertificateException("None of <" + identitiesToTest
- + "> matched by the rules of RFC5922 to the cert with CN="
- + cert.getSubjectDN());
- }
-
- private Iterable<String> extractCertIdentities(X509Certificate cert)
- {
- List<String> certIdentities = new ArrayList<String>();
- Collection<List<?>> subjAltNames = null;
- try
- {
- subjAltNames = cert.getSubjectAlternativeNames();
- }
- catch (CertificateParsingException ex)
- {
- logger.error("Error parsing TLS certificate", ex);
- }
- // subjAltName types are defined in rfc2459
- final Integer dnsNameType = 2;
- final Integer uriNameType = 6;
- if (subjAltNames != null)
- {
- if (logger.isDebugEnabled())
- logger.debug("found subjAltNames: " + subjAltNames);
-
- // First look for a URI in the subjectAltName field
- for (List<?> altName : subjAltNames)
- {
- // 0th position is the alt name type
- // 1st position is the alt name data
- if (altName.get(0).equals(uriNameType))
- {
- SipURI altNameUri;
- try
- {
- altNameUri =
- provider.getAddressFactory().createSipURI(
- (String) altName.get(1));
- // only sip URIs are allowed
- if (!"sip".equals(altNameUri.getScheme()))
- continue;
- // user certificates are not allowed
- if (altNameUri.getUser() != null)
- continue;
- String altHostName = altNameUri.getHost();
- if (logger.isDebugEnabled())
- {
- logger.debug("found uri " + altName.get(1)
- + ", hostName " + altHostName);
- }
- certIdentities.add(altHostName);
- }
- catch (ParseException e)
- {
- logger.error("certificate contains invalid uri: "
- + altName.get(1));
- }
- }
-
- }
- // DNS An implementation MUST accept a domain name system
- // identifier as a SIP domain identity if and only if no other
- // identity is found that matches the "sip" URI type described
- // above.
- if (certIdentities.isEmpty())
- {
- for (List<?> altName : subjAltNames)
- {
- if (altName.get(0).equals(dnsNameType))
- {
- if (logger.isDebugEnabled())
- logger.debug("found dns " + altName.get(1));
- certIdentities.add(altName.get(1).toString());
- }
- }
- }
- }
- else
- {
- // If and only if the subjectAltName does not appear in the
- // certificate, the implementation MAY examine the CN field of the
- // certificate. If a valid DNS name is found there, the
- // implementation MAY accept this value as a SIP domain identity.
- String dname = cert.getSubjectDN().getName();
- String cname = "";
- try
- {
- Pattern EXTRACT_CN =
- Pattern.compile(".*CN\\s*=\\s*([\\w*\\.]+).*");
- Matcher matcher = EXTRACT_CN.matcher(dname);
- if (matcher.matches())
- {
- cname = matcher.group(1);
- if (logger.isDebugEnabled())
- {
- logger.debug("found CN: " + cname + " from DN: "
- + dname);
- }
- certIdentities.add(cname);
- }
- }
- catch (Exception ex)
- {
- logger.error("exception while extracting CN", ex);
- }
- }
- return certIdentities;
- }
-}
+package net.java.sip.communicator.impl.protocol.sip.net;
+
+import java.security.cert.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.sip.address.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.service.certificate.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Matcher that extracts certificate identities according to <a
+ * href="http://tools.ietf.org/html/rfc5922#section-7.1">RFC5922, Section
+ * 7.1</a> and compares them with the rules from Section 7.2 and 7.3.
+ * @see #PNAME_STRICT_RFC5922 for wildcard handling; the default is false
+ *
+ * @author Ingo Bauersachs
+ */
+public class RFC5922Matcher
+ implements CertificateMatcher
+{
+ /**
+ * When set to true, enables strict validation of the hostname according to
+ * <a href="http://tools.ietf.org/html/rfc5922#section-7.2">RFC5922 Section
+ * 7.2</a>
+ */
+ public final static String PNAME_STRICT_RFC5922 =
+ "net.java.sip.communicator.sip.tls.STRICT_RFC5922";
+
+ private ProtocolProviderServiceSipImpl provider;
+
+ /**
+ * Creates a new instance of this class.
+ * @param provider The SIP Provider to which this matcher belongs.
+ */
+ public RFC5922Matcher(ProtocolProviderServiceSipImpl provider)
+ {
+ this.provider = provider;
+ }
+
+ /** Our class logger. */
+ private static final Logger logger = Logger
+ .getLogger(CertificateMatcher.class);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.service.certificate.CertificateMatcher#verify
+ * (java.lang.Iterable, java.security.cert.X509Certificate)
+ */
+ public void verify(Iterable<String> identitiesToTest, X509Certificate cert)
+ throws CertificateException
+ {
+ boolean strict = SipActivator.getConfigurationService()
+ .getBoolean(PNAME_STRICT_RFC5922, false);
+
+ // if any of the identities is contained in the certificate we're good
+ boolean oneMatched = false;
+ Iterable<String> certIdentities = extractCertIdentities(cert);
+ for (String identity : identitiesToTest)
+ {
+ // check if the intended hostname is contained in one of the
+ // hostnames of the certificate according to
+ // http://tools.ietf.org/html/rfc5922#section-7.2
+ for(String dnsName : certIdentities)
+ {
+ try
+ {
+ if(NetworkUtils.compareDnsNames(dnsName, identity) == 0)
+ {
+ // one of the hostnames matched, we're good to go
+ return;
+ }
+
+ if(!strict
+ // is a wildcard name
+ && dnsName.startsWith("*.")
+ // contains at least two dots (*.example.com)
+ && identity.indexOf(".") < identity.lastIndexOf(".")
+ // compare *.example.com stripped to example.com with
+ // - foo.example.com stripped to example.com
+ // - foo.bar.example.com to bar.example.com
+ && NetworkUtils.compareDnsNames(
+ dnsName.substring(2),
+ identity.substring(identity.indexOf(".")+1)) == 0)
+ {
+ // the wildcard matched, we're good to go
+ return;
+ }
+ }
+ catch (ParseException e)
+ {} // we don't care - this hostname did not match
+ }
+ }
+ if (!oneMatched)
+ throw new CertificateException("None of <" + identitiesToTest
+ + "> matched by the rules of RFC5922 to the cert with CN="
+ + cert.getSubjectDN());
+ }
+
+ private Iterable<String> extractCertIdentities(X509Certificate cert)
+ {
+ List<String> certIdentities = new ArrayList<String>();
+ Collection<List<?>> subjAltNames = null;
+ try
+ {
+ subjAltNames = cert.getSubjectAlternativeNames();
+ }
+ catch (CertificateParsingException ex)
+ {
+ logger.error("Error parsing TLS certificate", ex);
+ }
+ // subjAltName types are defined in rfc2459
+ final Integer dnsNameType = 2;
+ final Integer uriNameType = 6;
+ if (subjAltNames != null)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("found subjAltNames: " + subjAltNames);
+
+ // First look for a URI in the subjectAltName field
+ for (List<?> altName : subjAltNames)
+ {
+ // 0th position is the alt name type
+ // 1st position is the alt name data
+ if (altName.get(0).equals(uriNameType))
+ {
+ SipURI altNameUri;
+ try
+ {
+ altNameUri =
+ provider.getAddressFactory().createSipURI(
+ (String) altName.get(1));
+ // only sip URIs are allowed
+ if (!"sip".equals(altNameUri.getScheme()))
+ continue;
+ // user certificates are not allowed
+ if (altNameUri.getUser() != null)
+ continue;
+ String altHostName = altNameUri.getHost();
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("found uri " + altName.get(1)
+ + ", hostName " + altHostName);
+ }
+ certIdentities.add(altHostName);
+ }
+ catch (ParseException e)
+ {
+ logger.error("certificate contains invalid uri: "
+ + altName.get(1));
+ }
+ }
+
+ }
+ // DNS An implementation MUST accept a domain name system
+ // identifier as a SIP domain identity if and only if no other
+ // identity is found that matches the "sip" URI type described
+ // above.
+ if (certIdentities.isEmpty())
+ {
+ for (List<?> altName : subjAltNames)
+ {
+ if (altName.get(0).equals(dnsNameType))
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("found dns " + altName.get(1));
+ certIdentities.add(altName.get(1).toString());
+ }
+ }
+ }
+ }
+ else
+ {
+ // If and only if the subjectAltName does not appear in the
+ // certificate, the implementation MAY examine the CN field of the
+ // certificate. If a valid DNS name is found there, the
+ // implementation MAY accept this value as a SIP domain identity.
+ String dname = cert.getSubjectDN().getName();
+ String cname = "";
+ try
+ {
+ Pattern EXTRACT_CN =
+ Pattern.compile(".*CN\\s*=\\s*([\\w*\\.]+).*");
+ Matcher matcher = EXTRACT_CN.matcher(dname);
+ if (matcher.matches())
+ {
+ cname = matcher.group(1);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("found CN: " + cname + " from DN: "
+ + dname);
+ }
+ certIdentities.add(cname);
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.error("exception while extracting CN", ex);
+ }
+ }
+ return certIdentities;
+ }
+}