x509certificate2 to load a pfx file, still needs CA in cert store?

D

daed

Hello,

I'm in the process of creating a C# application which connects to a client
side SSL authenticated website. It uses the x509certificate2 class to load a
pfx file (without the need for access to the certificate stores, at least in
theory).

When compiled into a command line client the code works but still appears to
need the Root CA which signed the Client Cert in the Trusted Root CA Local
Machine certifcate store.

Command Line Code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Net;


namespace ConnectToWS
{
class Program
{
static void Main(string[] args)
{
string strValue = "3";

com.webservice myWebService = new com.webservice();

FileStream fs = File.Open("c:\\myCert.pfx", FileMode.Open,
FileAccess.Read);

byte[] buffer = new byte[fs.Length];

int count = fs.Read(buffer, 0, buffer.Length);

fs.Close();

X509Certificate2 cert = new X509Certificate2(buffer, "Password");
myWebService.ClientCertificates.Add(cert);

string strResult = myWebService.myMethod(strValue).ToString();

Console.Write(strResult);

}
}
}

By doctoring the code slightly (see below), I wanted to query the web
service via an aspx page.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Net;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void Button1_Click(object sender, EventArgs e)
{

string strValue = "3";

com.webService myWebService = new com.WebService();

FileStream fs = File.Open("c:\\myCert.pfx", FileMode.Open,
FileAccess.Read);

byte[] buffer = new byte[fs.Length];

int count = fs.Read(buffer, 0, buffer.Length);

fs.Close();

X509Certificate2 cert = new X509Certificate2(buffer, "Password");
myWebService.ClientCertificates.Add(cert);

string strResult = myWebService.Method(strValue).ToString();

Label1.Text = strResult;

}
}

This generates an error when the button is pressed:

System.Security.Authentication.AuthenticationException: The remote
certificate is invalid according to the validation procedure.

[AuthenticationException: The remote certificate is invalid according to the
validation procedure.]
System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken
message, AsyncProtocolRequest asyncRequest, Exception exception) +1036882

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +333
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) +386
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) +293
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) +297

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +364
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) +386
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) +293
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) +297

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +364
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) +386
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) +293
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) +297

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +364
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) +386
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) +293
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) +297

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +364
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest) +386
System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32
readBytes, AsyncProtocolRequest asyncRequest) +293
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) +297

System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken
message, AsyncProtocolRequest asyncRequest) +364
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count,
AsyncProtocolRequest asyncRequest) +313
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,
Byte[] buffer, AsyncProtocolRequest asyncRequest) +138
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult
lazyResult) +120
System.Net.TlsStream.CallProcessAuthentication(Object state) +47
System.Threading.ExecutionContext.runTryCode(Object userData) +66

System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) +0
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state) +166
System.Threading.ExecutionContext.Run(ExecutionContext executionContext,
ContextCallback callback, Object state) +145
System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) +728
System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) +44
System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) +21
System.Net.ConnectStream.WriteHeaders(Boolean async) +266

[WebException: The underlying connection was closed: Could not establish
trust relationship for the SSL/TLS secure channel.]
System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest
request) +54

System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest
request) +4
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String
methodName, Object[] parameters) +172
com.experian.uk.cems.uat.kms.Kms.getExternalKeySet(String name) +47
_Default.Button1_Click(Object sender, EventArgs e) +192
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
+107

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5102

Again I can get rid of this error by installing the Root CA that signed the
client certificate into the Trusted Root CA Local Machine Certificate Store.

Can anyone shed any light into why the CA still needs to be installed in a
cert store even if its included in the pfx file?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top