Skip to content

Commit

Permalink
Enable invalid cert test (#1652)
Browse files Browse the repository at this point in the history
* Enable invalid cert test

* Add docker directory

* Update windowsLinuxAndAndroidBuildMatrixConfig.yaml

Add ACR login task

* Cleanup

* Update ProvisioningTests.java

Re-enable invalid cert tests

* Update iot-e2e-tests/docker/readme.md

Co-authored-by: Sophia Ji Who Choi <113465132+schoims@users.noreply.github.com>

* Cleanup

* Prevent test from running on windows

* Add yaml task to Android

* Remove cert tests from Android build

* Cleanup

Co-authored-by: Sophia Ji Who Choi <113465132+schoims@users.noreply.github.com>
  • Loading branch information
ngastelum-ms and schoims authored Jan 21, 2023
1 parent c634fcd commit c0324f6
Show file tree
Hide file tree
Showing 17 changed files with 428 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,11 @@ public static String getStackTraceFromThrowable(Throwable throwable)
return ExceptionUtils.getStackTrace(throwable);
}

public static boolean isLinux()
{
return System.getProperty("os.name").toLowerCase().contains("linux");
}

public static boolean isAndroid()
{
return IS_ANDROID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,36 @@
package tests.integration.com.microsoft.azure.sdk.iot.iothub.serviceclient;

import com.azure.core.credential.AzureSasCredential;
import com.microsoft.azure.sdk.iot.device.IotHubClientProtocol;
import com.microsoft.azure.sdk.iot.device.auth.IotHubSSLContext;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubMessageTooLargeException;
import com.microsoft.azure.sdk.iot.service.messaging.MessagingClient;
import com.microsoft.azure.sdk.iot.service.registry.Device;
import com.microsoft.azure.sdk.iot.service.ProxyOptions;
import com.microsoft.azure.sdk.iot.service.auth.AuthenticationType;
import com.microsoft.azure.sdk.iot.service.auth.IotHubConnectionString;
import com.microsoft.azure.sdk.iot.service.auth.IotHubConnectionStringBuilder;
import com.microsoft.azure.sdk.iot.service.auth.IotHubServiceSasToken;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubMessageTooLargeException;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubUnauthorizedException;
import com.microsoft.azure.sdk.iot.service.messaging.IotHubServiceClientProtocol;
import com.microsoft.azure.sdk.iot.service.messaging.Message;
import com.microsoft.azure.sdk.iot.service.ProxyOptions;
import com.microsoft.azure.sdk.iot.service.messaging.MessagingClient;
import com.microsoft.azure.sdk.iot.service.messaging.MessagingClientOptions;
import com.microsoft.azure.sdk.iot.service.registry.Device;
import com.microsoft.azure.sdk.iot.service.registry.RegistryClient;
import com.microsoft.azure.sdk.iot.service.registry.RegistryClientOptions;
import com.microsoft.azure.sdk.iot.service.messaging.MessagingClientOptions;
import com.microsoft.azure.sdk.iot.service.auth.IotHubServiceSasToken;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubUnauthorizedException;
import lombok.extern.slf4j.Slf4j;
import com.microsoft.azure.sdk.iot.device.IotHubClientProtocol;
import com.microsoft.azure.sdk.iot.service.auth.AuthenticationType;
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.proxy.HttpProxyServer;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.proxy.impl.DefaultHttpProxyServer;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.IntegrationTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.SasTokenTools;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.TestConstants;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.TestDeviceIdentity;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.Tools;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.*;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.ContinuousIntegrationTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.IotHubTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.StandardTierHubOnlyTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.proxy.HttpProxyServer;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.proxy.impl.DefaultHttpProxyServer;

import javax.net.ssl.SSLContext;
import java.io.IOException;
Expand Down Expand Up @@ -336,11 +332,11 @@ public void messagingClientTokenRenewalWithAzureSasCredential() throws Exception
Tools.disposeTestIdentity(testDeviceIdentity, iotHubConnectionString);
}

@Ignore // The IoT Hub instance we use for this test is currently offline, so this test cannot be run
@Test
@ContinuousIntegrationTest
public void messagingClientValidatesRemoteCertificateWhenSendingTelemetry() throws InterruptedException
{
Assume.assumeTrue(Tools.isLinux());
boolean expectedExceptionWasCaught = false;

MessagingClient messagingClient = new MessagingClient(invalidCertificateServerConnectionString, testInstance.protocol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,24 @@

package tests.integration.com.microsoft.azure.sdk.iot.provisioning;


import com.microsoft.azure.sdk.iot.device.exceptions.IotHubClientException;
import com.microsoft.azure.sdk.iot.device.twin.TwinCollection;
import com.microsoft.azure.sdk.iot.provisioning.service.configs.DeviceCapabilities;
import com.microsoft.azure.sdk.iot.device.DeviceClient;
import com.microsoft.azure.sdk.iot.device.IotHubClientProtocol;
import com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClientTransportProtocol;
import com.microsoft.azure.sdk.iot.provisioning.security.SecurityProvider;
import com.microsoft.azure.sdk.iot.provisioning.security.SecurityProviderTpm;
import com.microsoft.azure.sdk.iot.provisioning.security.exceptions.SecurityProviderException;
import com.microsoft.azure.sdk.iot.provisioning.security.hsm.SecurityProviderTPMEmulator;
import com.microsoft.azure.sdk.iot.provisioning.service.configs.*;
import com.microsoft.azure.sdk.iot.provisioning.service.exceptions.ProvisioningServiceClientException;
import com.microsoft.azure.sdk.iot.service.auth.IotHubConnectionString;
import com.microsoft.azure.sdk.iot.service.twin.Twin;
import com.microsoft.azure.sdk.iot.service.twin.TwinClient;
import com.microsoft.azure.sdk.iot.service.twin.TwinClientOptions;
import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.CorrelationDetailsLoggingAssert;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.Tools;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.X509CertificateGenerator;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.ContinuousIntegrationTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.DeviceProvisioningServiceTest;
import tests.integration.com.microsoft.azure.sdk.iot.helpers.annotations.StandardTierHubOnlyTest;
import tests.integration.com.microsoft.azure.sdk.iot.provisioning.setup.ProvisioningCommon;

import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClientTransportProtocol.*;
import static junit.framework.TestCase.assertNotNull;
Expand Down Expand Up @@ -81,19 +60,19 @@ public void enrollmentGroupRegistration() throws Exception
basicRegistrationFlow(EnrollmentType.GROUP);
}

@Ignore // The DPS instance we use for this test is currently offline, so this test cannot be run
@Test
@ContinuousIntegrationTest
public void individualEnrollmentWithInvalidRemoteServerCertificateFails() throws Exception
{
Assume.assumeTrue(Tools.isLinux());
enrollmentWithInvalidRemoteServerCertificateFails(EnrollmentType.INDIVIDUAL);
}

@Ignore // The DPS instance we use for this test is currently offline, so this test cannot be run
@Test
@ContinuousIntegrationTest
public void groupEnrollmentWithInvalidRemoteServerCertificateFails() throws Exception
{
Assume.assumeTrue(Tools.isLinux());
enrollmentWithInvalidRemoteServerCertificateFails(EnrollmentType.GROUP);
}

Expand Down
91 changes: 91 additions & 0 deletions iot-e2e-tests/docker/docker-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/bin/bash
LOG_INFO="\x1b[33;42;1m[INFO]:\x1b[0m"
LOG_TODO="\x1b[37;43;1m[TODO]:\x1b[0m"
LOG_ERR="\x1b[33;41;1m[ERROR]:\x1b[0m"

echo "============"
echo "Start Docker"
echo "============"
echo "running from $(pwd)"
sudo service docker start

echo "========================"
echo "Extract self-signed cert"
echo "========================"
PROXY_CERT_ZFILE="./haproxy/haproxy.bin"
PROXY_CERT_FILE="./haproxy/haproxy.pem"
if [ -f "$PROXY_CERT_FILE" ];
then
echo -e "$LOG_INFO Use existing Proxy Service Cert found."
elif [ -f "$PROXY_CERT_ZFILE" ];
then
gzip -d -N -k -q -S ".bin" ./haproxy/haproxy.bin
echo -e "$LOG_INFO Proxy Service Cert extracted."
else
echo -e "$LOG_ERR Missing Proxy Service Cert! Check your repo."
exit
fi

echo "==============="
echo "Inspect network"
echo "==============="
ip -4 addr
CVTEST_HOST_IP=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+')
CVTEST_HOST_NETWORK=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+/*\d.')
CVTEST_HOST_SUBNET=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+' | grep -Po '[\d]{1,3}.[\d]{1,3}.[\d]{1,3}')
CVTEST_HOST_SUBNET_MASK=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+/*\d.' | grep -Po '/[\d]{1,2}')
CVTEST_CONTAINER_GW=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')
CVTEST_HOST_WSL_IP=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+')
CVTEST_ROUTE_NET=$(route -n | grep 'eth0' | grep -v 'UG' | awk -F" " '{print $1}' | awk -F"." '{print $1"."$2"."$3"."$4"/29"}')
CVTEST_TST_NET=$CVTEST_HOST_NETWORK
CVTEST_GDE_IP=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+' | awk -F"." '{print $1"."$2"."$3"."$4+3}')
CVTEST_DPS_IP=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+' | awk -F"." '{print $1"."$2"."$3"."$4+4}')
CVTEST_HUB_IP=$(ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+' | awk -F"." '{print $1"."$2"."$3"."$4+5}')
echo "HOST=$CVTEST_HOST_IP"
echo "HOST NETWORK=$CVTEST_HOST_NETWORK"
echo "HOST SUBNET=$CVTEST_HOST_SUBNET"
echo "HOST SUBNET MASK=$CVTEST_HOST_SUBNET_MASK"
echo "Container GW=$CVTEST_CONTAINER_GW"
echo "WSL=$CVTEST_HOST_WSL_IP"
echo "Container NET=$CVTEST_TST_NET"
echo "Container GDE=$CVTEST_GDE_IP"
echo "Container DPS=$CVTEST_DPS_IP"
echo "Container HUB=$CVTEST_HUB_IP"
ping -c 2 $CVTEST_HOST_IP

echo "===================="
echo "Setup docker network"
echo "===================="
docker images
docker ps -a
docker stop invalid-gde invalid-dps invalid-hub e2etest-tpm e2etest-pxy
docker rm invalid-gde invalid-dps invalid-hub e2etest-tpm e2etest-pxy
docker network rm testnet
docker network create -d ipvlan --subnet=$CVTEST_TST_NET -o ipvlan_mode=l2 -o parent=eth0 testnet
docker network ls

echo "======================"
echo "Setup docker instances"
echo "======================"
AZURE_ACR_TOKEN=$(az acr login -n aziotacr -t --output tsv --query accessToken)
echo $AZURE_ACR_TOKEN | docker login aziotacr.azurecr.io --username 00000000-0000-0000-0000-000000000000 --password-stdin
docker run -h invalidcertgde1.westus.cloudapp.azure.com --name invalid-gde --expose=443 --expose=5671 --expose=8883 --network=testnet --ip=$CVTEST_GDE_IP -v $(pwd)/haproxy:/usr/local/etc/haproxy:ro -d aziotacr.azurecr.io/haproxy haproxy -f /usr/local/etc/haproxy/haproxygde.cfg
docker run -h invalidcertdps1.westus.cloudapp.azure.com --name invalid-dps --expose=443 --expose=5671 --expose=8883 --network=testnet --ip=$CVTEST_DPS_IP -v $(pwd)/haproxy:/usr/local/etc/haproxy:ro -d aziotacr.azurecr.io/haproxy haproxy -f /usr/local/etc/haproxy/haproxydps.cfg
docker run -h invalidcertiothub1.westus.cloudapp.azure.com --name invalid-hub --expose=443 --expose=5671 --expose=8883 --network=testnet --ip=$CVTEST_HUB_IP -v $(pwd)/haproxy:/usr/local/etc/haproxy:ro -d aziotacr.azurecr.io/haproxy haproxy -f /usr/local/etc/haproxy/haproxyhub.cfg
docker run --name e2etest-tpm -p 127.0.0.1:2321:2321 -p 127.0.0.1:2322:2322 -d aziotacr.azurecr.io/aziotbld/testtpm
docker run --name e2etest-pxy -p 127.0.0.1:8888:8888 -d aziotacr.azurecr.io/aziotbld/testproxy

echo "================="
echo "Inspect instances"
echo "================="
docker ps -a

echo "========================================================"
echo -e "$LOG_TODO update host file for local E2E Tests"
echo " (on your host Windows OS)"
echo " add/update hosts file with the following entries"
echo " (at C:\Windows\System32\drivers\etc\hosts)"
echo "========================================================"
echo "$(docker inspect invalid-gde | grep -Po -m 1 '"IPAddress": "\K[\d.]+') invalidcertgde1.westus.cloudapp.azure.com"
echo "$(docker inspect invalid-dps | grep -Po -m 1 '"IPAddress": "\K[\d.]+') invalidcertdps1.westus.cloudapp.azure.com"
echo "$(docker inspect invalid-hub | grep -Po -m 1 '"IPAddress": "\K[\d.]+') invalidcertiothub1.westus.cloudapp.azure.com"
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/400.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 400 Bad request
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/403.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 403 Forbidden
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/408.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 408 Request Time-out
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>408 Request Time-out</h1>
Your browser didn't send a complete request in time.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/500.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 500 Internal Server Error
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>500 Internal Server Error</h1>
An internal server error occurred.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/502.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 502 Bad Gateway
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>502 Bad Gateway</h1>
The server returned an invalid or incomplete response.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/503.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
8 changes: 8 additions & 0 deletions iot-e2e-tests/docker/haproxy/errors/504.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
HTTP/1.0 504 Gateway Time-out
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>504 Gateway Time-out</h1>
The server didn't respond in time.
</body></html>
Binary file added iot-e2e-tests/docker/haproxy/haproxy.bin
Binary file not shown.
45 changes: 45 additions & 0 deletions iot-e2e-tests/docker/haproxy/haproxydps.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
global
maxconn 100
tune.ssl.default-dh-param 2048
log /dev/log local0
log /dev/log local1 notice
user haproxy
group haproxy
daemon

# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3

defaults
mode tcp
log global
timeout connect 5000
timeout client 50000
timeout server 50000

frontend hub_fe_https
bind *:443 ssl crt /usr/local/etc/haproxy/haproxy.pem
mode http
default_backend hub_be_https

backend hub_be_https
mode http
http-request set-header Host invalidcertdps1.westus.cloudapp.azure.com
server hub1 invalidcertdps1.westus.cloudapp.azure.com ssl verify none

frontend hub_fe_tcp
bind *:5671 ssl crt /usr/local/etc/haproxy/haproxy.pem
bind *:8883 ssl crt /usr/local/etc/haproxy/haproxy.pem
mode tcp
default_backend hub_be_tcp

backend hub_be_tcp
mode tcp
server hub1 invalidcertdps1.westus.cloudapp.azure.com ssl verify none
45 changes: 45 additions & 0 deletions iot-e2e-tests/docker/haproxy/haproxygde.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
global
maxconn 100
tune.ssl.default-dh-param 2048
log /dev/log local0
log /dev/log local1 notice
user haproxy
group haproxy
daemon

# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3

defaults
mode tcp
log global
timeout connect 5000
timeout client 50000
timeout server 50000

frontend hub_fe_https
bind *:443 ssl crt /usr/local/etc/haproxy/haproxy.pem
mode http
default_backend hub_be_https

backend hub_be_https
mode http
http-request set-header Host invalidcertgde1.westus.cloudapp.azure.com
server hub1 invalidcertgde1.westus.cloudapp.azure.com ssl verify none

frontend hub_fe_tcp
bind *:5671 ssl crt /usr/local/etc/haproxy/haproxy.pem
bind *:8883 ssl crt /usr/local/etc/haproxy/haproxy.pem
mode tcp
default_backend hub_be_tcp

backend hub_be_tcp
mode tcp
server hub1 invalidcertgde1.westus.cloudapp.azure.com ssl verify none
Loading

0 comments on commit c0324f6

Please sign in to comment.