Commit 8880153a authored by Jason Williams's avatar Jason Williams
Browse files

Add better cert validation to UWP

Also moves the manual cert to the Connect call.
parent 590be6b1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
        <Button x:Name="rebootDevice" Content="Reboot" Grid.Column="0" HorizontalAlignment="Left" Margin="114,123,0,0" VerticalAlignment="Top" Width="93" Click="RebootDevice_Click" IsEnabled="False" Height="32"/>
        <Button x:Name="shutdownDevice" Content="Shutdown" Grid.Column="0" HorizontalAlignment="Left" Margin="212,123,0,0" VerticalAlignment="Top" Width="93" Click="ShutdownDevice_Click" IsEnabled="False" Height="32"/>

        <TextBlock x:Name="UnsecureCertWarning" Grid.Column="0" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontWeight="Bold" FontSize="16" Margin="12,231,0,0" Height="60" Text="Note: The UWP Sample App does not currently support certificate validation for HTTPS communication" />
        <Button x:Name="loadCert" Content="Add Trusted Certificate" Grid.Column="0" HorizontalAlignment="Left" Margin="12,225,0,0" VerticalAlignment="Top" Width="175" Click="LoadCertificate_Click" Height="32"/>
        <CheckBox x:Name="allowUntrustedCheckbox" Content="Allow Untrusted Connections (Not Recommended)" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="27,257,0,0"></CheckBox>

        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1" Height="1" Margin="15,160,15,0" VerticalAlignment="Top"/>

+81 −37
Original line number Diff line number Diff line
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Security.Cryptography.Certificates;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Microsoft.Tools.WindowsDevicePortal;
using static Microsoft.Tools.WindowsDevicePortal.DevicePortal;
using System.Runtime.CompilerServices;
using Windows.UI.Core;

namespace SampleWdpClient.UniversalWindows
{
@@ -29,6 +24,8 @@ namespace SampleWdpClient.UniversalWindows
        /// </summary>
        private DevicePortal portal;

        private Certificate certificate;

        /// <summary>
        /// The main page constructor.
        /// </summary>
@@ -72,6 +69,8 @@ namespace SampleWdpClient.UniversalWindows

            this.ClearOutput();

            bool allowUntrusted = this.allowUntrustedCheckbox.IsChecked.Value;

            portal = new DevicePortal(
                new DefaultDevicePortalConnection(
                    this.address.Text,
@@ -107,9 +106,14 @@ namespace SampleWdpClient.UniversalWindows
                        }
                    };

                        // TODO: Support proper certificate validation instead of blindly trusting this cert (Issue #154/#145).
                    // If the user wants to allow untrusted connections, make a call to GetRootDeviceCertificate
                    // with acceptUntrustedCerts set to true. This will enable untrusted connections for the
                    // remainder of this session.
                    if (allowUntrusted)
                    {
                        await portal.GetRootDeviceCertificate(true);
                        await portal.Connect();
                    }
                    await portal.Connect(manualCertificate: this.certificate);

                    this.MarshalUpdateCommandOutput(sb.ToString());
                });
@@ -457,5 +461,45 @@ namespace SampleWdpClient.UniversalWindows
        {
            EnableConnectButton();
        }

        /// <summary>
        /// Loads a cert file for cert validation.
        /// </summary>
        /// <param name="sender">The caller of this method.</param>
        /// <param name="e">The arguments associated with this event.</param>
        private async void LoadCertificate_Click(object sender, RoutedEventArgs e)
        {
            await LoadCertificate();
        }

        /// <summary>
        /// Loads a certificates asynchronously (runs on the UI thread).
        /// </summary>
        /// <returns></returns>
        private async Task LoadCertificate()
        {
            try
            {
                FileOpenPicker filePicker = new FileOpenPicker();
                filePicker.SuggestedStartLocation = PickerLocationId.Downloads;
                filePicker.FileTypeFilter.Add(".cer");

                StorageFile file = await filePicker.PickSingleFileAsync();

                if (file != null)
                {
                    IBuffer cerBlob = await FileIO.ReadBufferAsync(file);

                    if (cerBlob != null)
                    {
                        certificate = new Certificate(cerBlob);
                    }
                }
            }
            catch (Exception exception)
            {
                this.commandOutput.Text = "Failed to get cert file: " + exception.Message;
            }
        }
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ namespace XboxWdpDriver
                    }
                }

                X509Certificate2 cert = null;

                IDevicePortalConnection connection = new DefaultDevicePortalConnection(finalConnectionAddress, userName, password);

                DevicePortal portal = new DevicePortal(connection);
@@ -230,7 +232,7 @@ namespace XboxWdpDriver

                    try
                    {
                        connection.SetDeviceCertificate(new System.Security.Cryptography.X509Certificates.X509Certificate2(certFile));
                        cert = new X509Certificate2(certFile);
                    }
                    catch (Exception e)
                    {
@@ -257,7 +259,7 @@ namespace XboxWdpDriver
                    }
                }

                Task connectTask = portal.Connect(updateConnection: false);
                Task connectTask = portal.Connect(updateConnection: false, manualCertificate: cert);
                connectTask.Wait();

                if (portal.ConnectionHttpStatusCode != HttpStatusCode.OK)
+9 −0
Original line number Diff line number Diff line
@@ -16,6 +16,15 @@ namespace Microsoft.Tools.WindowsDevicePortal
    /// </content>
    public partial class DevicePortal
    {
        /// <summary>
        /// Sets the manual certificate.
        /// </summary>
        /// <param name="cert">Manual certificate</param>
        private void SetManualCertificate(X509Certificate2 cert)
        {
            // Do nothing.
        }

        // Disable warning about async method lacking 'await'
#pragma warning disable 1998
        /// <summary>
+0 −18
Original line number Diff line number Diff line
@@ -75,24 +75,6 @@ namespace Microsoft.Tools.WindowsDevicePortal.Tests
            set;
        }

        /// <summary>
        /// Returns certificate data
        /// </summary>
        /// <returns>certificate data</returns>
        public X509Certificate2 GetDeviceCertificate()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Validates and sets the device certificate.
        /// </summary>
        /// <param name="certificate">The device's root certificate.</param>
        public void SetDeviceCertificate(X509Certificate2 certificate)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// The Mock will never update the connection.
        /// </summary>
Loading