L
Lee Gillie
This is absolutely driving me nuts. Any hints would be GREATLY appreciated.
I am trying to negotiate a clear channel socket to SSL. Thing is it
works great on two development computers, but falls flat on its face
when I go to deploy to a server.
I have written both CLIENT and SERVER for FTP. When the client issues
the appropriate command I call the SSLStream.AuthenticateAsClient, while
at the same time the server is calling SSLStream.AuthenticateAsServer.
I have played with using a number of different host names on the client
side, to no avail.
On the server side I reconstitute the server certificate from the
registry, where I have it stored as a binary block of data. A utility
loads the PFX file, which includes the private key, then stores that in
the registry. Later, when the FTP server starts I load the binary data,
and use it to construct the Certificate, which is eventually used to
negotiate SSL. The PFX was built at the server by importing our
certificate, and then exporting to PFX, supplying the password, choosing
to include the private key, and to NOT delete the key after export.
On the two development computers that I went through all of these steps
on (using the PFX generated at the production server), it all works
wonderfully. When I do the same at two different servers, the
negotiation fails. SChannel errors are logged in the system event log.
Event ID 36870, "A fatal error occurred when attempting to access the
SSL server credential private key. The error code returned from the
cryptographic module is 0x80090016."
When the FTP service starts I pull the certificate from the registry as
described above, and verify the chain. All 3 elements on the chain are
valid. The server call to AuthenticateAsServer crashes as such:
09:16:44.97 NegotiateSSLServer unable to authenticate.
09:16:44.99 - System.ComponentModel.Win32Exception: The credentials
supplied to the package were not recognized
09:16:44.99 at
System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule,
String package, CredentialUse intent, SecureCredential scc)
09:16:44.99 at
System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse
credUsage, SecureCredential& secureCredential)
09:16:44.99 at
System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]&
thumbPrint)
09:16:44.99 at System.Net.Security.SecureChannel.GenerateToken(Byte[]
input, Int32 offset, Int32 count, Byte[]& output)
09:16:44.99 at System.Net.Security.SecureChannel.NextMessage(Byte[]
incoming, Int32 offset, Int32 count)
09:16:44.99 at System.Net.Security.SslState.StartSendBlob(Byte[]
incoming, Int32 count, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest)
09:16:44.99 at System.Net.Security.SslState.StartReadFrame(Byte[]
buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
09:16:44.99 at System.Net.Security.SslState.StartReceiveBlob(Byte[]
buffer, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,
Byte[] buffer, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult
lazyResult)
09:16:44.99 at
System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate
serverCertificate, Boolean clientCertificateRequired, SslProtocols
enabledSslProtocols, Boolean checkCertificateRevocation)
09:16:44.99 at
ODP.NMServe.TCPClientSSL.NegotiateSSLServer(X509Certificate2
Certificate, Boolean ClearReceiveBuffer)
I am trying to negotiate a clear channel socket to SSL. Thing is it
works great on two development computers, but falls flat on its face
when I go to deploy to a server.
I have written both CLIENT and SERVER for FTP. When the client issues
the appropriate command I call the SSLStream.AuthenticateAsClient, while
at the same time the server is calling SSLStream.AuthenticateAsServer.
I have played with using a number of different host names on the client
side, to no avail.
On the server side I reconstitute the server certificate from the
registry, where I have it stored as a binary block of data. A utility
loads the PFX file, which includes the private key, then stores that in
the registry. Later, when the FTP server starts I load the binary data,
and use it to construct the Certificate, which is eventually used to
negotiate SSL. The PFX was built at the server by importing our
certificate, and then exporting to PFX, supplying the password, choosing
to include the private key, and to NOT delete the key after export.
On the two development computers that I went through all of these steps
on (using the PFX generated at the production server), it all works
wonderfully. When I do the same at two different servers, the
negotiation fails. SChannel errors are logged in the system event log.
Event ID 36870, "A fatal error occurred when attempting to access the
SSL server credential private key. The error code returned from the
cryptographic module is 0x80090016."
When the FTP service starts I pull the certificate from the registry as
described above, and verify the chain. All 3 elements on the chain are
valid. The server call to AuthenticateAsServer crashes as such:
09:16:44.97 NegotiateSSLServer unable to authenticate.
09:16:44.99 - System.ComponentModel.Win32Exception: The credentials
supplied to the package were not recognized
09:16:44.99 at
System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule,
String package, CredentialUse intent, SecureCredential scc)
09:16:44.99 at
System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse
credUsage, SecureCredential& secureCredential)
09:16:44.99 at
System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]&
thumbPrint)
09:16:44.99 at System.Net.Security.SecureChannel.GenerateToken(Byte[]
input, Int32 offset, Int32 count, Byte[]& output)
09:16:44.99 at System.Net.Security.SecureChannel.NextMessage(Byte[]
incoming, Int32 offset, Int32 count)
09:16:44.99 at System.Net.Security.SslState.StartSendBlob(Byte[]
incoming, Int32 count, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32
count, AsyncProtocolRequest asyncRequest)
09:16:44.99 at System.Net.Security.SslState.StartReadFrame(Byte[]
buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
09:16:44.99 at System.Net.Security.SslState.StartReceiveBlob(Byte[]
buffer, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,
Byte[] buffer, AsyncProtocolRequest asyncRequest)
09:16:44.99 at
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult
lazyResult)
09:16:44.99 at
System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate
serverCertificate, Boolean clientCertificateRequired, SslProtocols
enabledSslProtocols, Boolean checkCertificateRevocation)
09:16:44.99 at
ODP.NMServe.TCPClientSSL.NegotiateSSLServer(X509Certificate2
Certificate, Boolean ClearReceiveBuffer)