This is an automated email from the ASF dual-hosted git repository.

rawlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 0d2560d  Add SSL Certificate Validation to Traffic Router (#3380)
0d2560d is described below

commit 0d2560d98795202088ea058c095b4ad32cd49840
Author: Andy Schmidt <[email protected]>
AuthorDate: Tue Mar 12 14:36:10 2019 -0700

    Add SSL Certificate Validation to Traffic Router (#3380)
    
    * updated tr docker config so it would work
    
    * added start and stop scripts for TR docker containers
    
    * fixed bug in Tomcat which wasn't unregistering old SslHostConfigs
    
    * Added validation checks of SSL certs while being loaded by 
CertificateRegistry
    
    * Changed error message for Certificate Expired
    
    * Corrected a parsing error in certificate validation checking
    Set the startup/shutdown scripts for the TR docker container to executable
    
    * Corrected some code formatting and one NullPointerException
    
    * Added info to CHANGELOG.md
---
 CHANGELOG.md                                       |   4 +
 infrastructure/docker/traffic_router/Dockerfile    |   2 +
 infrastructure/docker/traffic_router/run.sh        |   2 +-
 infrastructure/docker/traffic_router/shutdowntr.sh |  36 ++++++
 infrastructure/docker/traffic_router/starttr.sh    |  44 +++++++
 .../traffic_router/protocol/RouterNioEndpoint.java |  26 ++++
 .../secure/CertificateDataConverter.java           | 118 ++++++++++++++++--
 .../traffic_router/secure/CertificateRegistry.java |  12 +-
 .../java/secure/CertificateDataConverterTest.java  | 138 +++++++++++++++------
 .../1.3/cdns/name/thecdn/sslkeys-missing-1.json    |   2 +-
 .../api/1.3/cdns/name/thecdn/sslkeys.json          |   2 +-
 traffic_router/shared/pom.xml                      |  14 ---
 .../src/test/java/secure/BindPrivateKeyTest.java   |   3 +-
 .../shared/DeliveryServiceCertificatesTest.java    |   3 +-
 14 files changed, 338 insertions(+), 68 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e4bd37..91d2c4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,10 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - Snapshotting the CRConfig now deletes HTTPS certificates in Riak for 
delivery services which have been deleted in Traffic Ops.
 
 ### Changed
+- Traffic Router, added TLS certificate validation on certificates imported 
from Traffic Ops
+  - validates modulus of private and public keys
+  - validates current timestamp falls within the certificate date bracket
+  - validates certificate subjects against the DS URL
 - Traffic Ops Golang Endpoints
   - Updated /api/1.1/cachegroups: Cache Group Fallbacks are included
   - Updated /api/1.1/cachegroups: fixed so fallbackToClosest can be set 
through API
diff --git a/infrastructure/docker/traffic_router/Dockerfile 
b/infrastructure/docker/traffic_router/Dockerfile
index 3a6a0f1..c16dcc0 100644
--- a/infrastructure/docker/traffic_router/Dockerfile
+++ b/infrastructure/docker/traffic_router/Dockerfile
@@ -35,6 +35,8 @@ ARG TC_REPO=traffic-control.repo
 ADD $TMCAT /
 ADD $RPM /
 ADD $TC_REPO /etc/yum.repos.d/
+ADD starttr.sh /
+ADD shutdowntr.sh /
 
 ### Common for all sub-component builds
 RUN    yum -y install \
diff --git a/infrastructure/docker/traffic_router/run.sh 
b/infrastructure/docker/traffic_router/run.sh
index 1329cdf..3c03f6c 100755
--- a/infrastructure/docker/traffic_router/run.sh
+++ b/infrastructure/docker/traffic_router/run.sh
@@ -28,7 +28,7 @@
 # ORIGIN_URI # origin server (e.g. hotair), used to create a delivery service
 
 start() {
-       systemctl start traffic_router
+       ./starttr.sh
        touch /opt/traffic_router/var/log/traffic_router.log
        exec tail -f /opt/traffic_router/var/log/traffic_router.log
 }
diff --git a/infrastructure/docker/traffic_router/shutdowntr.sh 
b/infrastructure/docker/traffic_router/shutdowntr.sh
new file mode 100755
index 0000000..e6ffa5e
--- /dev/null
+++ b/infrastructure/docker/traffic_router/shutdowntr.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# Script for running the Dockerfile for Traffic Router.
+# The Dockerfile sets up a Docker image which can be used for any new 
container;
+# This script, which should be run when the container is run (it's the 
ENTRYPOINT), will configure the container.
+#
+# The following environment variables must be set (ordinarily by `docker run 
-e` arguments):
+# TRAFFIC_OPS_URI
+# TRAFFIC_OPS_USER
+# TRAFFIC_OPS_PASS
+# TRAFFIC_MONITORS # list of semicolon-delimited FQDN:port monitors. E.g. 
`monitor.foo.com:80;monitor2.bar.org:80`
+# ORIGIN_URI # origin server (e.g. hotair), used to create a delivery service
+
+export JAVA_HOME=/usr/java/jdk1.8.0_92/jre
+export CATALINA_PID=/opt/traffic_router/temp/tomcat.pid
+export CATALINA_HOME=/opt/tomcat
+export CATALINA_BASE=/opt/traffic_router
+export CATALINA_OUT=/opt/tomcat/logs/catalina.log
+source /opt/traffic_router/conf/startup.properties
+/opt/tomcat/bin/shutdown.sh
diff --git a/infrastructure/docker/traffic_router/starttr.sh 
b/infrastructure/docker/traffic_router/starttr.sh
new file mode 100755
index 0000000..adbb9ab
--- /dev/null
+++ b/infrastructure/docker/traffic_router/starttr.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# Script for running the Dockerfile for Traffic Router.
+# The Dockerfile sets up a Docker image which can be used for any new 
container;
+# This script simulates the systemd unit file that is used to start traffic 
router on 
+# servers in the real world, but in Docker containers systemd is disabled. 
+# Therefore it is important to keep this script up to date with any changes 
that are
+# made to traffic_router/build/build_rpm.sh and traffic_router/build/pom.xml
+
+export JAVA_HOME=/usr/java/jdk1.8.0_92/jre
+export CATALINA_PID=/opt/traffic_router/temp/tomcat.pid
+export CATALINA_HOME=/opt/tomcat
+export CATALINA_BASE=/opt/traffic_router
+export CATALINA_OUT=/opt/tomcat/logs/catalina.log
+export CATALINA_OPTS="\
+  -server -Xms512m -Xmx1g \
+  -Dlog4j.configuration=file://$CATALINA_BASE/conf/log4j.properties \
+  -Djava.library.path=/usr/lib64 \
+  
-Dorg.apache.catalina.connector.Response.ENFORCE_ENCODING_IN_GET_WRITER=false \
+  -XX:+UseG1GC \
+  -XX:+UnlockExperimentalVMOptions \
+  -XX:InitiatingHeapOccupancyPercent=30"
+export JAVA_OPTS="\
+  -Djava.awt.headless=true \
+  -Djava.security.egd=file:/dev/./urandom"
+
+ulimit -c unlimited
+/opt/tomcat/bin/startup.sh
diff --git 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
index 657e573..85f8c07 100644
--- 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
+++ 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/protocol/RouterNioEndpoint.java
@@ -19,6 +19,7 @@ import 
com.comcast.cdn.traffic_control.traffic_router.secure.CertificateRegistry
 import com.comcast.cdn.traffic_control.traffic_router.secure.HandshakeData;
 import com.comcast.cdn.traffic_control.traffic_router.secure.KeyManager;
 import org.apache.log4j.Logger;
+import org.apache.tomcat.util.modeler.Registry;
 import org.apache.tomcat.util.net.NioEndpoint;
 import org.apache.tomcat.util.net.SSLHostConfig;
 import org.apache.tomcat.util.net.SSLHostConfigCertificate;
@@ -92,4 +93,29 @@ public class RouterNioEndpoint extends NioEndpoint {
     protected SSLHostConfig getSSLHostConfig(final String sniHostName) {
         return super.getSSLHostConfig(sniHostName.toLowerCase());
     }
+
+    private void unregisterJmx(final SSLHostConfig sslHostConfig) {
+        final Registry registry = Registry.getRegistry(null, null);
+        registry.unregisterComponent(sslHostConfig.getObjectName());
+        for (final SSLHostConfigCertificate sslHostConfigCert : 
sslHostConfig.getCertificates()) {
+            registry.unregisterComponent(sslHostConfigCert.getObjectName());
+        }
+    }
+
+    @Override
+    public void addSslHostConfig(final SSLHostConfig sslHostConfig, final 
boolean replace) throws IllegalArgumentException {
+        final String key = sslHostConfig.getHostName();
+        if (key == null || key.length() == 0) {
+            throw new 
IllegalArgumentException(sm.getString("endpoint.noSslHostName"));
+        }
+
+        SSLHostConfig previous = null;
+        if (replace) {
+            previous = sslHostConfigs.get(key);
+        }
+        super.addSslHostConfig(sslHostConfig, replace);
+        if (previous != null) {
+            unregisterJmx(previous);
+        }
+    }
 }
diff --git 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateDataConverter.java
 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateDataConverter.java
index 9324145..b3990fb 100644
--- 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateDataConverter.java
+++ 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateDataConverter.java
@@ -17,11 +17,18 @@ package 
com.comcast.cdn.traffic_control.traffic_router.secure;
 
 import com.comcast.cdn.traffic_control.traffic_router.shared.CertificateData;
 import org.apache.log4j.Logger;
+import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey;
+import sun.security.rsa.RSAPrivateCrtKeyImpl;
+import sun.security.rsa.RSAPublicKeyImpl;
 
+import java.math.BigInteger;
 import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.stream.Collectors;
 
 public class CertificateDataConverter {
        private static final Logger log = 
Logger.getLogger(CertificateDataConverter.class);
@@ -29,18 +36,43 @@ public class CertificateDataConverter {
        private PrivateKeyDecoder privateKeyDecoder = new PrivateKeyDecoder();
        private CertificateDecoder certificateDecoder = new 
CertificateDecoder();
 
+       @SuppressWarnings({"PMD.CyclomaticComplexity"})
        public HandshakeData toHandshakeData(final CertificateData 
certificateData) {
                try {
                        final PrivateKey privateKey = 
privateKeyDecoder.decode(certificateData.getCertificate().getKey());
                        final List<String> encodedCertificates = 
certificateDecoder.doubleDecode(certificateData.getCertificate().getCrt());
 
-                       final List<X509Certificate> x509Chain = 
encodedCertificates.stream()
-                               .map(encodedCertificate -> 
certificateDecoder.toCertificate(encodedCertificate))
-                               .collect(Collectors.toList());
-
-                       return new 
HandshakeData(certificateData.getDeliveryservice(), 
certificateData.getHostname(),
-                               x509Chain.toArray(new 
X509Certificate[x509Chain.size()]), privateKey);
+                       final List<X509Certificate> x509Chain = new 
ArrayList<>();
+                       boolean hostMatch = false;
+                       boolean modMatch = false;
+                       for (final String encodedCertificate : 
encodedCertificates) {
+                               final X509Certificate certificate = 
certificateDecoder.toCertificate(encodedCertificate);
+                               certificate.checkValidity();
+                               if (!hostMatch && verifySubject(certificate, 
certificateData.alias())) {
+                                       hostMatch = true;
+                               }
+                               if (!modMatch && verifyModulus(privateKey, 
certificate)) {
+                                       modMatch = true;
+                               }
+                               x509Chain.add(certificate);
+                       }
+                       if (hostMatch && modMatch) {
+                               return new 
HandshakeData(certificateData.getDeliveryservice(), 
certificateData.getHostname(),
+                                               x509Chain.toArray(new 
X509Certificate[x509Chain.size()]), privateKey);
+                       }
+                       else if (!hostMatch) {
+                               log.warn("Service name doesn't match the 
subject of the certificate = "+certificateData.getHostname());
+                       }
+                       else if (!modMatch) {
+                               log.error("Modulus of the private key does not 
match the public key modulus for certificate host: 
"+certificateData.getHostname());
+                       }
 
+               } catch (CertificateNotYetValidException er) {
+                       log.error("Failed to convert certificate data for 
delivery service = " + certificateData.getHostname()
+                                                       + ", because the 
certificate is not valid yet. ");
+               } catch (CertificateExpiredException ex ) {
+                       log.error("Failed to convert certificate data for 
delivery service = " + certificateData.getHostname()
+                                       + ", because the certificate has 
expired. ");
                } catch (Exception e) {
                        log.error("Failed to convert certificate data (delivery 
service = " + certificateData.getDeliveryservice()
                                        + ", hostname = " + 
certificateData.getHostname() + ") from traffic ops to handshake data! "
@@ -49,6 +81,78 @@ public class CertificateDataConverter {
                return null;
        }
 
+       public boolean verifySubject(final X509Certificate certificate, final 
String hostAlias ) {
+               final String host = certificate.getSubjectDN().getName();
+               if (hostCompare(hostAlias,host)) {
+                       return true;
+               }
+
+               try {
+                       // This approach is probably the only one that is JDK 
independent
+                       if (certificate.getSubjectAlternativeNames() != null) {
+                               for (final List<?> altName : 
certificate.getSubjectAlternativeNames()) {
+                                       if (hostCompare(hostAlias, (String) 
altName.get(1))) {
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+               catch (Exception e) {
+                       log.error("Encountered an error while validating the 
certificate subject for service: "+hostAlias+", " +
+                                       "error: 
"+e.getClass().getSimpleName()+": " + e.getMessage(), e);
+                       return false;
+               }
+
+               return false;
+       }
+
+       private boolean hostCompare(final String hostAlias, final String 
subject) {
+               if (hostAlias.contains(subject) || subject.contains(hostAlias)) 
{
+                       return true;
+               }
+               final String[] chopped = subject.split("CN=", 2);
+               if (chopped != null && chopped.length > 1) {
+                       String chop = chopped[1];
+                       chop = chop.replaceFirst("\\*\\.", ".");
+                       chop = chop.split(",", 2)[0];
+                       if (chop.length()>0 && (hostAlias.contains(chop) || 
chop.contains(hostAlias))) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       public boolean verifyModulus(final PrivateKey privateKey, final 
X509Certificate certificate) {
+               BigInteger privModulus = null;
+               if (privateKey instanceof BCRSAPrivateCrtKey) {
+                       privModulus = ((BCRSAPrivateCrtKey) 
privateKey).getModulus();
+               } else if (privateKey instanceof RSAPrivateCrtKeyImpl) {
+                       privModulus = ((RSAPrivateCrtKeyImpl) 
privateKey).getModulus();
+               } else {
+                       return false;
+               }
+               BigInteger pubModulus = null;
+               final PublicKey publicKey = certificate.getPublicKey();
+               if ((publicKey instanceof RSAPublicKeyImpl)) {
+                       pubModulus = ((RSAPublicKeyImpl) 
publicKey).getModulus();
+               } else {
+                       final String[] keyparts = 
publicKey.toString().split(System.getProperty("line.separator"));
+                       for (final String part : keyparts) {
+                               final int start = part.indexOf("modulus: ") + 9;
+                               if (start < 9) {
+                                       continue;
+                               } else {
+                                       pubModulus = new 
BigInteger(part.substring(start));
+                                       break;
+                               }
+                       }
+               }
+               if (privModulus.equals(pubModulus)) {
+                       return true;
+               }
+               return false;
+       }
+
        public PrivateKeyDecoder getPrivateKeyDecoder() {
                return privateKeyDecoder;
        }
diff --git 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
index e3f773c..848c8b0 100644
--- 
a/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
+++ 
b/traffic_router/connector/src/main/java/com/comcast/cdn/traffic_control/traffic_router/secure/CertificateRegistry.java
@@ -73,10 +73,12 @@ public class CertificateRegistry {
 
                                if (!master.containsKey(alias)) {
                                        final HandshakeData handshakeData = 
certificateDataConverter.toHandshakeData(certificateData);
-                                       master.put(alias, handshakeData);
-                                       if 
(!certificateData.equals(previousData.get(alias))) {
-                                               changes.put(alias, 
handshakeData);
-                                               log.warn("Imported handshake 
data with alias " + alias);
+                                       if (handshakeData != null) {
+                                               master.put(alias, 
handshakeData);
+                                               if 
(!certificateData.equals(previousData.get(alias))) {
+                                                       changes.put(alias, 
handshakeData);
+                                                       log.warn("Imported 
handshake data with alias " + alias);
+                                               }
                                        }
                                }
                                else {
@@ -103,7 +105,7 @@ public class CertificateRegistry {
                previousData.clear();
                for (final CertificateData certificateData : 
certificateDataList) {
                        final String alias = certificateData.alias();
-                       if (!previousData.containsKey(alias)) {
+                       if (!previousData.containsKey(alias) && 
master.containsKey(alias)) {
                                previousData.put(alias, certificateData);
                        }
                }
diff --git 
a/traffic_router/connector/src/test/java/secure/CertificateDataConverterTest.java
 
b/traffic_router/connector/src/test/java/secure/CertificateDataConverterTest.java
index 6de4ae9..0554de6 100644
--- 
a/traffic_router/connector/src/test/java/secure/CertificateDataConverterTest.java
+++ 
b/traffic_router/connector/src/test/java/secure/CertificateDataConverterTest.java
@@ -16,73 +16,137 @@
 package secure;
 
 import 
com.comcast.cdn.traffic_control.traffic_router.secure.CertificateDataConverter;
-import 
com.comcast.cdn.traffic_control.traffic_router.secure.CertificateDecoder;
 import com.comcast.cdn.traffic_control.traffic_router.secure.HandshakeData;
-import com.comcast.cdn.traffic_control.traffic_router.secure.PrivateKeyDecoder;
 import com.comcast.cdn.traffic_control.traffic_router.shared.Certificate;
 import com.comcast.cdn.traffic_control.traffic_router.shared.CertificateData;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.Before;
 import org.junit.Test;
+import org.powermock.core.classloader.annotations.PrepareForTest;
 
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
+import java.time.Instant;
+import java.util.Date;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.fail;
 
 public class CertificateDataConverterTest {
 
        private CertificateDataConverter certificateDataConverter;
        private CertificateData certificateData;
-       private X509Certificate x509Certificate1;
-       private X509Certificate x509Certificate2;
-       private X509Certificate x509Certificate3;
-       private PrivateKey privateKey;
+       private Date certDate;
+       private final static String SUBJECT_MISS_CERT_DATA =
+               "    {\n" +
+                       "      \"deliveryservice\": \"https-subject-miss\",\n" +
+                       "      \"certificate\": {\n" +
+                       "        \"comment\" : \"The following is a self-signed 
key for *.subject-miss.thecdn.example.com\",\n" +
+                       "        \"key\": 
\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRQzhBWVVFYk1YcHZiVUMKaDBrNWRxYURnTHJGL3Y5VDdtOFNLUnVuRldYYUhFalVvcWlZc29tekhuZjNyUkVNRWpkVXB0M0lCVzk3M090cApqNmlkNUNLTHlFVDNUQ3h2ZHNERzhiYXB3UEdNT0dzQWhTMGxucmlrRll6ejArZXpxMWhzczcxRDBqN3o1TzlLCmxPVUJxSUgzOG16YU1JaFN3VXpsSGdFRzJjdlJiK1RwajhpU0k3Z3psek8rMVM1OEExS21UbjVDMC9ia0lvcFYKREJ5V3FySmpqSXZuWjBvK2I1MkRMcExzdlVnRU5BOVdHRzkycG8wS0RDZnFmNjN0RW5oRGYvZStFT0o5NUs5U
 [...]
+                       "        \"crt\": 
\"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURvakNDQW9vQ0NRQ1JFTVdLWEhZYkhUQU5CZ2txaGtpRzl3MEJBUXNGQURDQmtURUxNQWtHQTFVRUJoTUMKVlZNeEN6QUpCZ05WQkFnTUFrTlBNUXd3Q2dZRFZRUUhEQU5FUlU0eEN6QUpCZ05WQkFvTUFsUkRNUXN3Q1FZRApWUVFMREFKVVF6RXFNQ2dHQTFVRUF3d2hLaTV6ZFdKcVpXTjBMVzFwYzNNdWRHaGxZMlJ1TG1WNFlXMXdiR1V1ClkyOXRNU0V3SHdZSktvWklodmNOQVFrQkZoSjBZMEJ6Wld4bUxYTnBaMjVsWkM1amIyMHdJQmNOTVRrd016QTEKTVRjME1ETXhXaGdQTWpFeE9UQXlNRGt4TnpRd016RmFNSUdSTVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVR
 [...]
+                       "      },\n" +
+                       "      \"hostname\": 
\"*.https-subject-miss.thecdn.example.com\"\n" +
+               "    }";
+       private final static String VALID_CERT_DATA =
+               "    {\n" +
+                       "      \"deliveryservice\": \"https-valid-test\",\n" +
+                       "      \"certificate\": {\n" +
+                       "        \"comment\" : \"The following is just a self 
signed certificate and key to use for testing this is NOT private data from a 
CA\",\n" +
+                       "        \"key\": " +
+                                       
"\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQzVEMVhNbXJiQy9CT1gKUkZMVkczbTNSbmhWZ0ZJdUQ5dXhWSEJDYXR2TEFuc2ZyalhCM2tyZjVNTDVuS3dZRWl3OCtkQWo2N1Z2QkR4cwpDMTYvbFFBbFM4YnBxT1NRbzU5T0RDcVBNZmZaYzVVazdVdjUzN0R5MWFHMjRiT1R0eUxjQzIxc2MxSm1YWHVjCkVlQlZUZldFWUVLdS9McHEvZDZZUlNsa1lXUUt2TDBmUzRja0FtcUJkRVk2Q0s3ajZyYnphZGJIVHB2SXdQWGgKWVNTOWlJOFQxKzRTYTZDOTljcnRUR2ZZb21BL2hFWVFPTnVSVk42VUl5c1Bob2RCVndsVTJEV1pYNndyZm5DZApNOFBCajNHSXVV
 [...]
+                       "        \"crt\": " +
+                                       
"\"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURzakNDQXBvQ0NRRHpibHduYzNBLzVqQU5CZ2txaGtpRzl3MEJBUXNGQURDQm1URUxNQWtHQTFVRUJoTUMKVlZNeEN6QUpCZ05WQkFnTUFrTlBNUXd3Q2dZRFZRUUhEQU5FUlU0eER6QU5CZ05WQkFvTUJrRndZV05vWlRFTApNQWtHQTFVRUN3d0NWRU14TGpBc0JnTlZCQU1NSlNvdWFIUjBjSE10ZG1Gc2FXUXRkR1Z6ZEM1MGFHVmpaRzR1ClpYaGhiWEJzWlM1amIyMHhJVEFmQmdrcWhraUc5dzBCQ1FFV0VuUmpRSE5sYkdZdGMybG5ibVZrTG1OdmJUQWcKRncweE9UQXpNRFV4TnpRMk1UTmFHQTh5TVRFNU1ESXdPVEUzTkRZeE0xb3dnWmt4Q3pBSkJnTlZCQVlUQWxWVApNUXN3Q1FZRFZR
 [...]
+                       "      },\n" +
+                       "      \"hostname\": 
\"*.https-valid-test.thecdn.example.com\"\n" +
+               "    }";
+       private final static String EXPIRED_CERT_DATA =
+               "    {\n" +
+                       "      \"deliveryservice\": \"http-to-https-test\",\n" +
+                       "      \"certificate\": {\n" +
+                       "        \"comment\" : \"The following self signed 
certificate which expired on 3/5/2019 \",\n" +
+                       "        \"key\": " +
+                               
"\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2paZ0xpTHNRS0o0UXgKS0F5WnFqT0NOL2lXUmgzdXkyZCtyd0J1VWJ2NTBIVEk0QUdnOHE2eG9pbzNtZHFHZXRXdVJIemUvSmQ5ckxJSQpvWDFXOGNFeTVybW0wV0xXYnJDbzlJQUE5K0dHcTgyNXUreGplemdiSHg3TEt1N3lqdUJVVjI4SyszTXNOQUhGCjZsemZNdTJ5VEFUMExvU25waDRWeHZLRDlzM05rNzdtaW5vcVR0aGFlSldxWXVEQlZ4WTBNS3JGbWJuQkEybkcKV295ZHIrelBROHB2N3Fka0FmcXlnZ0loWjloM0JBNnVESHRtcDNueWlsc2ZSMHpGeFR4QnRhaVhTbnRZdXM4NAphVUNwaHVjWkIvY
 [...]
+                       "        \"crt\": " +
+                               
"\"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxakNDQXBJQ0NRQ0Q1OFZ3U2IrNWJqQU5CZ2txaGtpRzl3MEJBUXNGQURDQmxqRUxNQWtHQTFVRUJoTUMKVlZNeEN6QUpCZ05WQkFnTUFrTlBNUXd3Q2dZRFZRUUhEQU5FUlU0eER6QU5CZ05WQkFvTUJrRndZV05vWlRFTApNQWtHQTFVRUN3d0NWRU14TURBdUJnTlZCQU1NSnlvdWFIUjBjQzEwYnkxb2RIUndjeTEwWlhOMExuUm9aV05rCmJpNWxlR0Z0Y0d4bExtTnZiVEVjTUJvR0NTcUdTSWIzRFFFSkFSWU5kR05BWVhCaFkyaGxMbU52YlRBZUZ3MHgKT1RBek1EUXlNekl6TkRKYUZ3MHhPVEF6TURVeU16SXpOREphTUlHV01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrRwpBMVVFQ0F3Q1EwO
 [...]
+                       "      },\n" +
+                       "      \"hostname\": 
\"*.http-to-https-test.thecdn.example.com\"\n" +
+               "    }";
+       private final static String MOD_MISS_CERT_DATA =
+               "    {\n" +
+                       "      \"deliveryservice\": \"https-mod-miss\",\n" +
+                       "      \"certificate\": {\n" +
+                       "        \"comment\" : \"The following certificate and 
key are for the same subject but have " +
+                               "mismatched modulus between the private and 
public keys\",\n" +
+                       "        \"key\": " +
+                               
"\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRQ3lIMW91SmpXcE5SeVAKdE1nVDM3emhCc0tYM1VhTWlhdm5CUHNJUDhidmdaUnNicFNYeVVSdTJsaWdsYWZpWlAybTZxZE1LZ3BHcUo4ZgpwZHQzODFsMHduakI5YURleU92NzZrcnJBdzhlME9VOW9ZU0Q1VVlWMU11M0I4ZTV1UGFLYkdNcDZvc3o1WDJSCmlDYnRjcTAvUzJaeWhWNXIvRkJqNUtsN2I0UlBNTjdPVXJNVW5LcHlXZ2hZNzdXOXpzVm96cTg5cldOL0g5VUEKZjFMRmFSdU1mckNvYVVKZHRKZEIyY2FGblkwWmI1MDhzcmFGWXplaFUvK3FjZE9heWtVa0hMMTVweDVFbS9mOQpYVlpNcmVJeFlob
 [...]
+                       "        \"crt\": " +
+                               
"\"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURyRENDQXBRQ0NRQ0pZQWd0a1JtN3hUQU5CZ2txaGtpRzl3MEJBUXNGQURDQmxqRUxNQWtHQTFVRUJoTUMKVlZNeEN6QUpCZ05WQkFnTUFrTlBNUXd3Q2dZRFZRUUhEQU5FUlU0eER6QU5CZ05WQkFvTUJrRndZV05vWlRFTApNQWtHQTFVRUN3d0NWRU14S3pBcEJnTlZCQU1NSWlvdWFIUjBjQzF0YjJRdGJXbHpjeTUwYUdWalpHNHVaWGhoCmJYQnNaUzVqYjIweElUQWZCZ2txaGtpRzl3MEJDUUVXRW5SalFITmxiR1l0YzJsbmJtVmtMbU52YlRBZ0Z3MHgKT1RBek1EVXhPREE0TkRsYUdBOHlNVEU1TURJd09URTRNRGcwT1Zvd2daWXhDekFKQmdOVkJBWVRBbFZUTVFzdwpDUVlEVlFRSURBS
 [...]
+                       "      },\n" +
+                       "      \"hostname\": 
\"*.http-mod-miss.thecdn.example.com\"\n" +
+               "    }";
 
        @Before
+       @PrepareForTest({Instant.class})
        public void before() throws Exception {
-               PrivateKeyDecoder privateKeyDecoder = 
mock(PrivateKeyDecoder.class);
-               CertificateDecoder certificateDecoder = 
mock(CertificateDecoder.class);
-
                Certificate certificate = new Certificate();
                certificate.setCrt("encodedchaindata");
                certificate.setKey("encodedkeydata");
-
                certificateData = new CertificateData();
                certificateData.setCertificate(certificate);
                certificateData.setDeliveryservice("some-delivery-service");
                certificateData.setHostname("example.com");
+               certificateDataConverter = new CertificateDataConverter();
+       }
 
-               privateKey = mock(PrivateKey.class);
-               
when(privateKeyDecoder.decode("encodedkeydata")).thenReturn(privateKey);
-
-               
when(certificateDecoder.doubleDecode("encodedchaindata")).thenReturn(Arrays.asList(
-                       "encodedcert1", "encodedcert2", "encodedcert3"
-               ));
-
-               x509Certificate1 = mock(X509Certificate.class);
-               x509Certificate2 = mock(X509Certificate.class);
-               x509Certificate3 = mock(X509Certificate.class);
-
-               
when(certificateDecoder.toCertificate("encodedcert1")).thenReturn(x509Certificate1);
-               
when(certificateDecoder.toCertificate("encodedcert2")).thenReturn(x509Certificate2);
-               
when(certificateDecoder.toCertificate("encodedcert3")).thenReturn(x509Certificate3);
+       @Test
+       public void itConvertsValidCertToHandshakeData() throws Exception {
+               try {
+                       certificateData = ((CertificateData) new 
ObjectMapper().readValue(VALID_CERT_DATA,
+                                       new TypeReference<CertificateData>() { 
}));
+               } catch (Exception e) {
+                       fail("Failed parsing json data: " + e.getMessage());
+               }
+               HandshakeData handshakeData = 
certificateDataConverter.toHandshakeData(certificateData);
+               assertThat(handshakeData, notNullValue());
+               assertThat(handshakeData.getDeliveryService(), 
equalTo(certificateData.getDeliveryservice()));
+               assertThat(handshakeData.getHostname(), 
equalTo(certificateData.getHostname()));
+       }
 
-               certificateDataConverter = new CertificateDataConverter();
-               
certificateDataConverter.setCertificateDecoder(certificateDecoder);
-               
certificateDataConverter.setPrivateKeyDecoder(privateKeyDecoder);
+       @Test
+       public void itRejectsExpiredCert() throws Exception {
+               try {
+                       certificateData = ((CertificateData) new 
ObjectMapper().readValue(EXPIRED_CERT_DATA,
+                                       new TypeReference<CertificateData>() { 
}));
+               } catch (Exception e) {
+                       fail("Failed parsing json data: " + e.getMessage());
+               }
+               HandshakeData handshakeData = 
certificateDataConverter.toHandshakeData(certificateData);
+               assertThat(handshakeData, nullValue());
        }
 
        @Test
-       public void itConvertsToHandshakeData() throws Exception {
+       public void itRejectsModulusMismatch() throws Exception {
+               try {
+                       certificateData = ((CertificateData) new 
ObjectMapper().readValue(MOD_MISS_CERT_DATA,
+                                       new TypeReference<CertificateData>() { 
}));
+               } catch (Exception e) {
+                       fail("Failed parsing json data: " + e.getMessage());
+               }
                HandshakeData handshakeData = 
certificateDataConverter.toHandshakeData(certificateData);
+               assertThat(handshakeData, nullValue());
+       }
 
-               assertThat(handshakeData.getDeliveryService(), 
equalTo("some-delivery-service"));
-               assertThat(handshakeData.getHostname(), equalTo("example.com"));
-               assertThat(handshakeData.getPrivateKey(), equalTo(privateKey));
-               assertThat(handshakeData.getCertificateChain(), equalTo(new 
X509Certificate[]{x509Certificate1, x509Certificate2, x509Certificate3}));
+       @Test
+       public void itRejectsSubjectMismatch() throws Exception {
+               try {
+                       certificateData = ((CertificateData) new 
ObjectMapper().readValue(SUBJECT_MISS_CERT_DATA,
+                                       new TypeReference<CertificateData>() { 
}));
+               } catch (Exception e) {
+                       fail("Failed parsing json data: " + e.getMessage());
+               }
+               HandshakeData handshakeData = 
certificateDataConverter.toHandshakeData(certificateData);
+               assertThat(handshakeData, nullValue());
        }
 }
diff --git 
a/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys-missing-1.json
 
b/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys-missing-1.json
index 2d6c882..f0a8f23 100644
--- 
a/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys-missing-1.json
+++ 
b/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys-missing-1.json
@@ -22,7 +22,7 @@
       "deliveryservice": "http-to-https-test",
       "certificate": {
         "comment" : "The following is just a self signed certificate and key 
to use for testing this is NOT private data from a CA",
-        "key": 
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBc2Y0NnV5OGJ2\nQk5rMGhCaEVsbHdGT0dqREh6M1hJY1hteDRVNThNZG9Fa1JId0VTCjVONnd3NFV6bDAvRDcyMlJV\nODlMeHB4bldvclJmdVZNQldnOGVFcXBUb2NUS2NOZHhtZmdEUWZTcTZ1ODNTWkUKTmFCZFArK2g5\nYTJJRFZXWGFldVRhcVA3Q3lVVG52Sld5Mm1JalJWZkRGQWRWWHNhU1M4RGRYUWdibEJTelJ6NwpL\nMXFHVWt1RlZQc0R0ODZBYVF3TnN5R2ZDN3ltcUkzNU1FQ3hTdzNPd2lXSlAyZTg3U2E5UG9Pdjcr\nZUs2NVJnCmM3dzNkSXQxZUlyS3B6OWpQV1RPTkJOK0JhWFdvcHNXZ3UvdVd4Q1pnUk9qaXBWVUFK\nNHhrNFRG
 [...]
+        "key": 
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBMHBBWXlmamRz\nZ0NSL0ZXeEQvWE1vbDNwYjRWazlHSFdqTnR4bkdvWHA3OGxxM2p1CitLd012ZlU2ZDVScmdXbHp6\nMlJjZnFhMHdjbkYrNU1abkdkbzRGaGwycnhnT3ZBV2NSb3ZXS3BUaXNUUkcrQXcKbnFneUZTWjNT\nalhUcE9YUjV4dUJJOWI1c3ZIN3RhbzdBcWFLR2I0V3d1TnA3cTZzcUtRYlRxaUlXcE9JQWtFKwpS\nVnJXblBVdHRvaHlTV08yL2dIbDQ2NlU1S0czdC9TU3lqZVRPZ1ZFU0xoQUhlWlk2dExyTGd1YmdM\nanlLVWE5CkpDcWJLa1laZ2UrdWlhKzVVMzZ6alhYRUdBUEdwWWNrM2Zqb1pYN01zM3hkUzV6Zit6\nUDQzSnVV
 [...]
         "crt": 
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZuakNDQTRhZ0F3SUJBZ0lDRUFFd0RRWUpL\nb1pJaHZjTkFRRUxCUUF3WkRFTE1Ba0dBMVVFQmhNQ1ZWTXgKRVRBUEJnTlZCQWdNQ0VOdmJHOXlZ\nV1J2TVJBd0RnWURWUVFLREFkRGIyMWpZWE4wTVE0d0RBWURWUVFMREFWSgpVRU5FVGpFZ01CNEdB\nMVVFQXd3WFZHVnpkR2x1WnlCSmJuUmxjbTFsWkdsaGRHVWdRMEV3SGhjTk1UWXdPVEl6Ck1qSXpO\nREl4V2hjTk16VXhNVEl6TWpJek5ESXhXakNCaFRFTE1Ba0dBMVVFQmhNQ1ZWTXhFVEFQQmdOVkJB\nZ1QKQ0VOdmJHOXlZV1J2TVE4d0RRWURWUVFIRXdaRVpXNTJaWEl4RURBT0JnTlZCQW9UQjBOdmJX\nTmhjM1F4
 [...]
       },
       "hostname": "*.http-to-https-test.thecdn.example.com"
diff --git 
a/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys.json 
b/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys.json
index 804c83a..c5a9b3d 100644
--- 
a/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys.json
+++ 
b/traffic_router/core/src/test/resources/api/1.3/cdns/name/thecdn/sslkeys.json
@@ -31,7 +31,7 @@
       "deliveryservice": "http-to-https-test",
       "certificate": {
         "comment" : "The following is just a self signed certificate and key 
to use for testing this is NOT private data from a CA",
-        "key": 
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBc2Y0NnV5OGJ2\nQk5rMGhCaEVsbHdGT0dqREh6M1hJY1hteDRVNThNZG9Fa1JId0VTCjVONnd3NFV6bDAvRDcyMlJV\nODlMeHB4bldvclJmdVZNQldnOGVFcXBUb2NUS2NOZHhtZmdEUWZTcTZ1ODNTWkUKTmFCZFArK2g5\nYTJJRFZXWGFldVRhcVA3Q3lVVG52Sld5Mm1JalJWZkRGQWRWWHNhU1M4RGRYUWdibEJTelJ6NwpL\nMXFHVWt1RlZQc0R0ODZBYVF3TnN5R2ZDN3ltcUkzNU1FQ3hTdzNPd2lXSlAyZTg3U2E5UG9Pdjcr\nZUs2NVJnCmM3dzNkSXQxZUlyS3B6OWpQV1RPTkJOK0JhWFdvcHNXZ3UvdVd4Q1pnUk9qaXBWVUFK\nNHhrNFRG
 [...]
+        "key": 
"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBMHBBWXlmamRz\nZ0NSL0ZXeEQvWE1vbDNwYjRWazlHSFdqTnR4bkdvWHA3OGxxM2p1CitLd012ZlU2ZDVScmdXbHp6\nMlJjZnFhMHdjbkYrNU1abkdkbzRGaGwycnhnT3ZBV2NSb3ZXS3BUaXNUUkcrQXcKbnFneUZTWjNT\nalhUcE9YUjV4dUJJOWI1c3ZIN3RhbzdBcWFLR2I0V3d1TnA3cTZzcUtRYlRxaUlXcE9JQWtFKwpS\nVnJXblBVdHRvaHlTV08yL2dIbDQ2NlU1S0czdC9TU3lqZVRPZ1ZFU0xoQUhlWlk2dExyTGd1YmdM\nanlLVWE5CkpDcWJLa1laZ2UrdWlhKzVVMzZ6alhYRUdBUEdwWWNrM2Zqb1pYN01zM3hkUzV6Zit6\nUDQzSnVV
 [...]
         "crt": 
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZuakNDQTRhZ0F3SUJBZ0lDRUFFd0RRWUpL\nb1pJaHZjTkFRRUxCUUF3WkRFTE1Ba0dBMVVFQmhNQ1ZWTXgKRVRBUEJnTlZCQWdNQ0VOdmJHOXlZ\nV1J2TVJBd0RnWURWUVFLREFkRGIyMWpZWE4wTVE0d0RBWURWUVFMREFWSgpVRU5FVGpFZ01CNEdB\nMVVFQXd3WFZHVnpkR2x1WnlCSmJuUmxjbTFsWkdsaGRHVWdRMEV3SGhjTk1UWXdPVEl6Ck1qSXpO\nREl4V2hjTk16VXhNVEl6TWpJek5ESXhXakNCaFRFTE1Ba0dBMVVFQmhNQ1ZWTXhFVEFQQmdOVkJB\nZ1QKQ0VOdmJHOXlZV1J2TVE4d0RRWURWUVFIRXdaRVpXNTJaWEl4RURBT0JnTlZCQW9UQjBOdmJX\nTmhjM1F4
 [...]
       },
       "hostname": "*.http-to-https-test.thecdn.example.com"
diff --git a/traffic_router/shared/pom.xml b/traffic_router/shared/pom.xml
index 59a3819..7f0af11 100644
--- a/traffic_router/shared/pom.xml
+++ b/traffic_router/shared/pom.xml
@@ -109,20 +109,6 @@ under the License.
                        <version>1.57</version>
                </dependency>
                <dependency>
-                       <groupId>dnsjava</groupId>
-                       <artifactId>dnsjava</artifactId>
-                       <version>2.1.7</version>
-               </dependency>
-               <dependency>
-                       <groupId>junit</groupId>
-                       <artifactId>junit</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.hamcrest</groupId>
-                       <artifactId>hamcrest-all</artifactId>
-                       <scope>compile</scope>
-               </dependency>
-               <dependency>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                        <version>1.7.5</version>
diff --git a/traffic_router/shared/src/test/java/secure/BindPrivateKeyTest.java 
b/traffic_router/shared/src/test/java/secure/BindPrivateKeyTest.java
index 9da5145..9d149ec 100644
--- a/traffic_router/shared/src/test/java/secure/BindPrivateKeyTest.java
+++ b/traffic_router/shared/src/test/java/secure/BindPrivateKeyTest.java
@@ -19,6 +19,7 @@ import 
com.comcast.cdn.traffic_control.traffic_router.secure.BindPrivateKey;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
@@ -69,7 +70,7 @@ public class BindPrivateKeyTest {
                        "Exponent2: " + 
encode(privateCrtKey.getPrimeExponentQ())+ "\n" +
                        "Coefficient: " + 
encode(privateCrtKey.getCrtCoefficient())+ "\n";
 
-               privateKey = mock(PrivateKey.class);
+               privateKey = Mockito.mock(PrivateKey.class);
                KeyFactory keyFactory = PowerMockito.mock(KeyFactory.class);
 
                PowerMockito.mockStatic(KeyFactory.class);
diff --git 
a/traffic_router/shared/src/test/java/shared/DeliveryServiceCertificatesTest.java
 
b/traffic_router/shared/src/test/java/shared/DeliveryServiceCertificatesTest.java
index d78af4a..6670b0a 100644
--- 
a/traffic_router/shared/src/test/java/shared/DeliveryServiceCertificatesTest.java
+++ 
b/traffic_router/shared/src/test/java/shared/DeliveryServiceCertificatesTest.java
@@ -21,6 +21,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -41,7 +42,7 @@ import static 
org.powermock.api.mockito.PowerMockito.mockStatic;
 public class DeliveryServiceCertificatesTest {
        @Before
        public void before() throws Exception {
-               mockStatic(System.class);
+               PowerMockito.mockStatic(System.class);
                when(System.currentTimeMillis()).thenReturn(1234L);
        }
 

Reply via email to