Skip to content

Commit

Permalink
Adding primary scenario test for Issue dotnet#366
Browse files Browse the repository at this point in the history
* Added a property in BridgeClientCertificateManager to hold the thumbprint of the ClientCertificate so that a test case can get it.
* Test sets the DnsEndpointIdentity to "localhost" which means this will only work when the Bridge and the test run on the same machine.
* Hong has a PR that adds a resource to the Bridge that will return the server Identity. I will update this PR to use that Resource
   once her PR is merged, before I merge this one.
* Test currently fails due to Issue dotnet#458, added ActiveIssue
  • Loading branch information
StephenBonikowsky committed Oct 23, 2015
1 parent 63878df commit d3fe641
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public static class BridgeClientCertificateManager
private const string ClientCertificateSubject = "WCF Client Certificate";
private const string ClientCertificatePassword = "test"; // this needs to be kept in sync with the Bridge configuration

public static string Thumbprint { get; private set; }

// Dictionary of certificates installed by CertificateManager
// Keyed by the Thumbprint of the certificate
private static Dictionary<string, CertificateCacheEntry> s_myCertificates = new Dictionary<string, CertificateCacheEntry>(StringComparer.OrdinalIgnoreCase);
Expand Down Expand Up @@ -176,6 +178,9 @@ public static void InstallLocalCertificateFromBridge()
}
}

// Set the local variable with the thumbprint so a test case can use it.
Thumbprint = thumbprint;

InstallCertificateToMyStore(certificateToInstall);

// We also need to install the root cert if we install a local cert
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using Infrastructure.Common;

public static partial class Endpoints
Expand Down Expand Up @@ -183,4 +182,13 @@ public static string Tcp_CustomBinding_SslStreamSecurity_Address
return BridgeClient.GetResourceAddress("WcfService.TestResources.TcpTransportSecurityWithSslResource");
}
}

public static string Tcp_ClientCredentialType_Certificate_Address
{
get
{
BridgeClientCertificateManager.InstallLocalCertificateFromBridge();
return BridgeClient.GetResourceAddress("WcfService.TestResources.TcpTransportSecuritySslClientCredentialTypeCertificate");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TestCategories>OuterLoop</TestCategories>
</PropertyGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Security.TransportSecurity.Tests</RootNamespace>
<AssemblyName>Security.TransportSecurity.Tests</AssemblyName>
<SignAssembly>false</SignAssembly>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProjectGuid>{452BA2A7-81AD-4146-AD02-35EC242FF0EB}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Compile Include="Https\ClientCredentialTypeTests.cs" />
<Compile Include="Https\HttpsTests.cs" />
<Compile Include="Tcp\ClientCredentialTypeTests.cs" />
<Compile Include="Tcp\IdentityTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<!-- Compile tests against the contract, but copy our local-built implementation for testing -->
<ProjectReference Include="$(WcfSourceProj)">
<Project>{9e50e7bf-cd6e-4269-a6dd-59fd0bd6c0fd}</Project>
<Name>System.Private.ServiceModel</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Targets>Build;DebugSymbolsProjectOutputGroup</Targets>
</ProjectReference>
<ProjectReference Include='$(WcfScenarioTestCommonProj)'>
<Project>{9098B41C-9C2E-4FC6-B7D8-FC3411736A22}</Project>
<Name>ScenarioTests.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup>
<TestCategories>OuterLoop</TestCategories>
</PropertyGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Security.TransportSecurity.Tests</RootNamespace>
<AssemblyName>Security.TransportSecurity.Tests</AssemblyName>
<SignAssembly>false</SignAssembly>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProjectGuid>{452BA2A7-81AD-4146-AD02-35EC242FF0EB}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Compile Include="Https\ClientCredentialTypeTests.cs" />
<Compile Include="Https\HttpsTests.cs" />
<Compile Include="Tcp\ClientCredentialTypeTests.cs" />
<Compile Include="Tcp\IdentityTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<!-- Compile tests against the contract, but copy our local-built implementation for testing -->
<ProjectReference Include="$(WcfSourceProj)">
<Project>{9e50e7bf-cd6e-4269-a6dd-59fd0bd6c0fd}</Project>
<Name>System.Private.ServiceModel</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Targets>Build;DebugSymbolsProjectOutputGroup</Targets>
</ProjectReference>
<ProjectReference Include='$(WcfScenarioTestCommonProj)'>
<Project>{9098B41C-9C2E-4FC6-B7D8-FC3411736A22}</Project>
<Name>ScenarioTests.Common</Name>
</ProjectReference>
<ProjectReference Include="$(WcfInfrastructureCommonProj)">
<Project>{AFD69665-89A3-42AE-A32E-AB2CBBE6EE7E}</Project>
<Name>Infrastructure.Common</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Infrastructure.Common;
using System;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.ServiceModel.Security;
using Xunit;

public static class Tcp_ClientCredentialTypeTests
Expand All @@ -31,11 +33,11 @@ public static void SameBinding_DefaultSettings_EchoString()
string result = serviceProxy.Echo(testString);
Assert.Equal(testString, result);

factory.Close();
factory.Close();
}
finally
finally
{
ScenarioTestHelpers.CloseCommunicationObjects(factory);
ScenarioTestHelpers.CloseCommunicationObjects(factory);
}
}

Expand Down Expand Up @@ -83,7 +85,7 @@ public static void SameBinding_SecurityModeTransport_EchoString()
string result = serviceProxy.Echo(testString);
Assert.Equal(testString, result);

factory.Close();
factory.Close();
}
finally
{
Expand All @@ -107,9 +109,9 @@ public static void SameBinding_SecurityModeTransport_ClientCredentialTypeCertifi
new SslStreamSecurityBindingElement(), // This is the binding element used when Security.Mode = TransportWithMessageCredentials
new BinaryMessageEncodingBindingElement(),
new TcpTransportBindingElement());

factory = new ChannelFactory<IWcfService>(binding, new EndpointAddress(Endpoints.Tcp_CustomBinding_SslStreamSecurity_Address));

IWcfService serviceProxy = factory.CreateChannel();

string result = serviceProxy.Echo(testString);
Expand All @@ -122,4 +124,47 @@ public static void SameBinding_SecurityModeTransport_ClientCredentialTypeCertifi
ScenarioTestHelpers.CloseCommunicationObjects(factory);
}
}

[Fact]
[ActiveIssue(458)]
[OuterLoop]
public static void TcpClientCredentialType_Certificate_EchoString()
{
string clientCertThumb = null;
EndpointAddress endpointAddress = null;
string testString = "Hello";
NetTcpBinding binding = null;
ChannelFactory<IWcfService> factory = null;
IWcfService serviceProxy = null;

try
{
binding = new NetTcpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;

endpointAddress = new EndpointAddress(new Uri(Endpoints.Tcp_ClientCredentialType_Certificate_Address),
new DnsEndpointIdentity("localhost")); // This Identity will be changed to use the Resource request that retruns the correct identity, pending Hong's merge.
clientCertThumb = BridgeClientCertificateManager.Thumbprint; // ClientCert as given by the Bridge

factory = new ChannelFactory<IWcfService>(binding, endpointAddress);
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.Credentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindByThumbprint,
clientCertThumb);

serviceProxy = factory.CreateChannel();

string result = serviceProxy.Echo(testString);
Assert.Equal(testString, result);

((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using WcfService.CertificateResources;
using WcfTestBridgeCommon;

namespace WcfService.TestResources
{
internal class TcpTransportSecuritySslClientCredentialTypeCertificate : TcpResource
{
protected override string Address { get { return "tcp-server-ssl-security-clientcredentialtype-certificate"; } }

protected override Binding GetBinding()
{
NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
return binding;
}

protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
{
// Ensure the https certificate is installed before this endpoint resource is used
string thumbprint = CertificateResourceHelpers.EnsureSslPortCertificateInstalled(context.BridgeConfiguration);

serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindByThumbprint,
thumbprint);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<Compile Include="TestResources\TcpNoSecurityResource.cs" />
<Compile Include="TestResources\TcpNoSecurityTextResource.cs" />
<Compile Include="TestResources\TcpResource.cs" />
<Compile Include="TestResources\TcpTransportSecuritySslClientCredentialTypeCertificate.cs" />
<Compile Include="TestResources\TcpTransportSecurityWithSslResource.cs" />
<Compile Include="TestResources\TcpVerifyDNSResource.cs" />
<Compile Include="TestResources\HttpsSoap12Resource.cs" />
Expand Down

0 comments on commit d3fe641

Please sign in to comment.