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

Discussion in 'ASP .Net Security' started by daed, Jul 20, 2006.

  1. daed

    daed Guest

    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?
     
    daed, Jul 20, 2006
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. andy lim
    Replies:
    9
    Views:
    393
    Lucas Tam
    Apr 17, 2005
  2. Schoolar

    how to retrieve private key from .pfx file?

    Schoolar, Apr 16, 2005, in forum: ASP .Net Security
    Replies:
    0
    Views:
    233
    Schoolar
    Apr 16, 2005
  3. David Chan via .NET 247
    Replies:
    1
    Views:
    350
    Dominick Baier [DevelopMentor]
    Jun 2, 2005
  4. pseongho

    X509Certificate2 in .NET 1.1

    pseongho, May 5, 2006, in forum: ASP .Net Security
    Replies:
    0
    Views:
    298
    pseongho
    May 5, 2006
  5. dpomt
    Replies:
    2
    Views:
    866
    Steven Cheng[MSFT]
    Nov 6, 2006
Loading...

Share This Page