0x574F4F54
0x574F4F54

Reputation: 440

Simple C# SSL Server: The credentials supplied to the package were not recognized

I'm having a hard time understanding why my simple C# SSL Server code is failing. When I try to 'Authenticate as Server' using a .p12 file I load from the file system, I get an error.

Here's my code:

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 2045);

Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(localEndPoint);

while (true)
{
server.Listen(10);
Socket client = server.Accept();

Stream clientStream = new NetworkStream(client, true);
var clientTlsStream = new SslStream(clientStream, false);

var p12Cert =
    new X509Certificate2(
        @"C:\Repos\ITEL-Trunk\Code\Applications\Server\bin\Debug\Configuration\Certificate_tool_signed_with_ca.p12",
        "Passw0rd");

clientTlsStream.AuthenticateAsServer(p12Cert);

var cr = clientTlsStream.CanRead;

}

And here's the exception detail:

System.ComponentModel.Win32Exception was unhandled
  HResult=-2147467259
  Message=The credentials supplied to the package were not recognized
  Source=System
  ErrorCode=-2147467259
  NativeErrorCode=-2146893043

The X509Certificate2 object indicates that 'Has Private Key = true' and I've tried running as Admininstrator without luck. Other SO questions that I've seen for this revolve around CAPI permissions, but since I'm loading straight from the file system I was not able to apply those answers.

Upvotes: 3

Views: 7060

Answers (1)

0x574F4F54
0x574F4F54

Reputation: 440

I was able to trace this problem back to the way the p12 file was being generated. The .p12 was being created by a Bouncy-Castle based C# utility which was not packaging the certificate and private key correctly. I had to change the Certificate Generator so it properly packages both the Certificate and the CA certificate used to sign it.

After I made the changes to the certificate generator the "credentials supplied to the package were not recognized" exception went away.

Here is the P12 packager code that seems to work:

// Create the PKCS12 store
Pkcs12Store store = new Pkcs12Store();

// Add a Certificate entry
string certCn = cert.SubjectDN.GetValues(X509Name.CN).OfType<string>().Single();
X509CertificateEntry certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry(certCn, certEntry); // use DN as the Alias.

// Add a key entry & cert chain (if applicable)
AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(kp.Private);

X509CertificateEntry[] certChain;
if (_issuerCert != null)
{
    X509CertificateEntry issuerCertEntry = new X509CertificateEntry(_issuerCert);
    certChain = new X509CertificateEntry[] { certEntry, issuerCertEntry};
}
else
{
    certChain = new X509CertificateEntry[] { certEntry };
}

store.SetKeyEntry(certCn, keyEntry, certChain); // Set the friendly name along with the generated certs key and its chain

// Write the p12 file to disk
FileInfo p12File = new FileInfo(pathToP12File);
Directory.CreateDirectory(p12File.DirectoryName);

using (FileStream filestream = new FileStream(pathToP12File, FileMode.Create, FileAccess.ReadWrite))
{
     store.Save(filestream, password.ToCharArray(), new SecureRandom());
}

Upvotes: 4

Related Questions