|
I find the entire SSLSocket class very neat and clean and very easy to understand the flow. I had my share of issues with CertFindCertificateInStore which I resolved with some trial and error but I am happy I found multiple solutions to fix that thing. Nice!!
However, the <pre>InitializeSecurityContext in ClientHandshakeLoop always fails with a return value 0x80090322Lwhich translates to SEC_E_WRONG_PRINCIPAL.
NOTE: The 3rd parameter of InitializeSecurityContext in ClientHandshake (which is pszServerName) is always my IP or the HostName, where as it is NULL while performing the second time (in method ClientHandshakeLoop). I tried all trial and errors like passing multiple OutBuffers (instead of 1) in AcceptSecurityContext etc. Still the issue remains. I am stuck with issue for almost a couple of days now. Any help is much appreciated. Thank you!
|
|
|
|
|
For all other using this code,
we recently got troubles (we don't know the origin) with this code because decrypt is not well managed when EXTRA_BUFFER is returned by the function. From MSDN, if
SECBUFFER_EXTRA is returned, it means there here some data left uncrypted...so we add a do/while loop around the
DecryptMessage method.
Here is the working code :
int CSslSocket::ReceiveSSL(void* lpBuf, int nBufLen, int nFlags)
{
int rc = 0;
SecPkgContext_StreamSizes Sizes;
SECURITY_STATUS scRet;
DWORD cbIoBufferLength;
DWORD cbData;
SecBufferDesc Message;
SecBuffer Buffers[4];
SecBuffer * pDataBuffer;
SecBuffer * pExtraBuffer;
SecBuffer ExtraBuffer;
BYTE *pDataBuf = NULL;
DWORD dwDataLn = 0;
DWORD dwBufDataLn = 0;
BOOL bCont = TRUE;
if (m_bConInit) {
if (m_dwReceiveBuf) {
if ((DWORD)nBufLen < m_dwReceiveBuf) {
rc = nBufLen;
CopyMemory(lpBuf,m_pbReceiveBuf,rc);
MoveMemory(m_pbReceiveBuf,m_pbReceiveBuf+rc,m_dwReceiveBuf-rc);
m_dwReceiveBuf -= rc;
} else {
rc = m_dwReceiveBuf;
CopyMemory(lpBuf,m_pbReceiveBuf,rc);
delete [] m_pbReceiveBuf;
m_pbReceiveBuf = NULL;
m_dwReceiveBuf = 0;
}
} else {
do {
scRet = m_SecurityFunc.QueryContextAttributes(&m_hContext,SECPKG_ATTR_STREAM_SIZES,&Sizes);
if(scRet != SEC_E_OK) {
break;
}
cbIoBufferLength = Sizes.cbHeader +
Sizes.cbMaximumMessage +
Sizes.cbTrailer;
if (!m_pbIoBuffer) m_pbIoBuffer = new BYTE[cbIoBufferLength];
pDataBuf = new BYTE[cbIoBufferLength];
dwBufDataLn = cbIoBufferLength;
if ((m_pbIoBuffer == NULL) || (pDataBuf == NULL)) {
break;
}
do {
cbData = T_ClassSocket::Receive((char *)(m_pbIoBuffer + m_cbIoBuffer),cbIoBufferLength - m_cbIoBuffer);
if(cbData == SOCKET_ERROR) {
break;
} else if (cbData == 0) {
if(m_cbIoBuffer) {
scRet = SEC_E_INTERNAL_ERROR;
break;
} else {
break;
}
} else {
m_cbIoBuffer += cbData;
}
:) do
{
Buffers[0].pvBuffer = m_pbIoBuffer;
Buffers[0].cbBuffer = m_cbIoBuffer;
Buffers[0].BufferType = SECBUFFER_DATA;
Buffers[1].BufferType = SECBUFFER_EMPTY;
Buffers[2].BufferType = SECBUFFER_EMPTY;
Buffers[3].BufferType = SECBUFFER_EMPTY;
Message.ulVersion = SECBUFFER_VERSION;
Message.cBuffers = 4;
Message.pBuffers = Buffers;
cout << "DecryptMessage " << endl;
scRet = m_SecurityFunc.DecryptMessage(&m_hContext, &Message, 0, NULL);
if (scRet != SEC_E_OK)
{
cout << "DecryptMessage return code" << endl;
cout << scRet << endl;
}
if (scRet == SEC_E_INCOMPLETE_MESSAGE) {
continue;
}
if (scRet == SEC_I_CONTEXT_EXPIRED) {
break;
}
if (scRet != SEC_E_OK && scRet != SEC_I_RENEGOTIATE && scRet != SEC_I_CONTEXT_EXPIRED) {
break;
}
pDataBuffer = NULL;
pExtraBuffer = NULL;
for (int i = 1; i < 4; i++) {
if (pDataBuffer == NULL && Buffers[i].BufferType == SECBUFFER_DATA) {
pDataBuffer = &Buffers[i];
}
if (pExtraBuffer == NULL && Buffers[i].BufferType == SECBUFFER_EXTRA) {
pExtraBuffer = &Buffers[i];
cout << "pExtraBuffer = recryptage " << endl;
}
}
if (pDataBuffer) {
if ((dwDataLn + (pDataBuffer->cbBuffer)) > dwBufDataLn) {
BYTE *bNewDataBuf = new BYTE[dwBufDataLn + (pDataBuffer->cbBuffer)];
CopyMemory(bNewDataBuf, pDataBuf, dwDataLn);
delete[] pDataBuf;
pDataBuf = bNewDataBuf;
dwBufDataLn = dwBufDataLn + (pDataBuffer->cbBuffer);
}
CopyMemory(pDataBuf + dwDataLn, pDataBuffer->pvBuffer, pDataBuffer->cbBuffer);
dwDataLn += pDataBuffer->cbBuffer;
}
if (pExtraBuffer) {
MoveMemory(m_pbIoBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);
m_cbIoBuffer = pExtraBuffer->cbBuffer;
}
else {
m_cbIoBuffer = 0;
bCont = FALSE;
}
:) } while (pExtraBuffer != NULL);
cout << "Fin cryptage " << endl;
if (scRet == SEC_I_RENEGOTIATE) {
scRet = ClientHandshakeLoop(
&m_hCreds,
&m_hContext,
FALSE,
&ExtraBuffer);
if(scRet != SEC_E_OK) {
break;
}
if(ExtraBuffer.pvBuffer) {
MoveMemory(m_pbIoBuffer, ExtraBuffer.pvBuffer, ExtraBuffer.cbBuffer);
m_cbIoBuffer = ExtraBuffer.cbBuffer;
}
if (ExtraBuffer.pvBuffer) delete [] ExtraBuffer.pvBuffer;
}
} while (bCont);
} while (FALSE);
cout << "Fini " << endl;
if (dwDataLn) {
if (dwDataLn > (DWORD)nBufLen) {
m_dwReceiveBuf = dwDataLn - ((DWORD)(nBufLen));
m_pbReceiveBuf = new BYTE[m_dwReceiveBuf];
CopyMemory(lpBuf,pDataBuf,nBufLen);
rc = nBufLen;
CopyMemory(m_pbReceiveBuf,pDataBuf+nBufLen,m_dwReceiveBuf);
} else {
CopyMemory(lpBuf,pDataBuf,dwDataLn);
rc = dwDataLn;
}
}
if (pDataBuf) delete [] pDataBuf;
}
} else {
if (m_bAllowPlainText) rc = T_ClassSocket::Receive((char *)lpBuf, nBufLen);
}
return rc;
}
|
|
|
|
|
Hi Martin.
Please, can I use your SslSocket in commercial application?
Thank you very much for your answer.
Best Regards
B.
|
|
|
|
|
Hallo,
I want to use your class for IMAP. To use TLS I need to connect unsecured, send a command STARTTLS and then enable TLS/SSL.
How can I do this with you class?
Stefan
|
|
|
|
|
If you add:
m_SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1;
to the m_SchannelCredin initialization code in ClientInit and ServerInit, this class with handshake using the TLS protocol. The default seems to be SSLv2, which a lot of servers will no longer accept. See schannel.h for other options.
|
|
|
|
|
Please let me know if Schannel library support DTLS (Datagram Transport Layer Security) protocol?
Deepthi
|
|
|
|
|
Using AES cipher in vista and trying to connect to openssl server with TLS 1.0 version protocol DecryptMessage api fails with SEC_E_DECRYPT_FAILURE error.
SSL handshake is successful and even some of the SSL packets received are decrypted properly. But, after some time DecryptMessage fails with SEC_E_DECRYPT_FAILURE error. After this packet it fails for all other SSL packets.
Please let me know what might be the problem.
Thanks in advance.
|
|
|
|
|
When data more than 4096, it will hangs the server ? Why?
|
|
|
|
|
I found the problem was in the serialization of CMsg object. When data > 4096 the pExtraData will have value and it will hangs the second times CSocket::Receive() function call. Any idea? If data less than 4096 it will be ok since pExtraData will not have value when data < 4096.
|
|
|
|
|
I move the do loop position in the code and seems work
//do
//{
//Problem found here , when serializing the data the program hangs here
cbData = CSocket::Receive(m_pbIoBuffer + m_cbIoBuffer, cbIoBufferLength - m_cbIoBuffer);
...
DUMP(_T("Received cipher text"),m_pbIoBuffer,cbData);
do
{
...
|
|
|
|
|
Hi there.
I 've included ISC_REQ_MANUAL_CRED_VALIDATION which - I believe - will bypass the server's certificate testing (as I want to use the SSL only for an encrypted connection without certificate testing) , and InitializeSecurityContext returns SEC_I_INCOMPLETE_CREDENTIALS.
What to do after that ? How do I supply a certificate to the server If there is no one at the certificate store ?
Michael.
|
|
|
|
|
Hi,
Firstly, thanks to Martin for publishing the class. It's saved me a lot of time.
Although I've looked through all the atricles, I think I need some help with this. I know very little about SChannel or about certificates (and that's the problem ).
What I'm trying to do is write a server application that uses an exportable certificate, with the private key removed, and accesses private key internally by somehow coding it into my application.
My application will not always be running on machines with Internet access, so I don't want to use a CA. I don't need certificates on the client side - only on the server-side.
So, I've managed to use MS Certificate Services to create an exportable certificate and a .PVK file - which I hope contains the private key. I assume there must be a means of extracting the data from the PVK file. The PVK is not for distribution, so I need to somehow hide the key details inside my application, and modify CSslSocket to use this information, rather than get it from the server certificate.
My main objective is to encrypt client/server communications, so they can't easily be sniffed.
I'd be very grateful if someone could tell me how they think this could be done, or if they have a better solution.
Many thanks, in advance.
Andy
|
|
|
|
|
I have compiled the apps using Visual Studio 2005.
Using a free limited time certificate from comodo I am trying to bring up the sslchatserver but when the listen executes it gets to the call to "m_securityFunc.AcquireCredentialsHandle(...)" which returns the error 0x80090304. What does this mean, and what do I do to get around it? Or what did I do wrong to cause it?
Don Fairchild
dfairchild@ctspos.com or donaldfairchild@hotmail.com
|
|
|
|
|
0x80090304 = The Local Security Authority cannot be contacted
From my experience usually there's something wrong with the cert (see event viewer if there's any further error message from SChannel)
Possible reasons:
a) Cert's private key is missing.
b) The certificate of the certificate authority (CA) has not been installed.
HTH
|
|
|
|
|
Hello,
I have downloaded ur application and setup the environment for that application.I also started LSA and server has started correctly.But client can't be connected with the server. In this method, client receives data first in "cbData" then it calls InitializeSecurityContext, it returns SEC_I_CONTINUE_NEEDED.After that it sends data to server and then again comes in start of while loop and again tries to receive data but it never receives any data, due to which it gives error.plz explain me what to do....and what could be the error, i am stuck at this point......plz reply as soon as possible.
thanks in advance.
Mazhar Nazeer.
|
|
|
|
|
I trying to build a solution where SSL client is sending encrypted data. At the server end i want to receive encryped data store it to file and at later stage decrypt it.
My current problem is how to get the CtxtHandle.
Thanks you
|
|
|
|
|
I follow as your help, registration two certificate Server and Client.
I have 2 computer, Windows 2003 for issued certificate, chatsrv/chatclient run on windowsxp.
but when i run chatsrv, in function listen(), always return FALSE at
CertFindCertificateInStore(m_hMyCertStore,
return are:
Status = SEC_E_NO_CREDENTIALS;
please help me
|
|
|
|
|
Hello Martin
I cannot install chatsrv/chatclient on Windows 2003. my system as:
i have 2 computer. 1 for windows 2003, 1 for windows XP.
please help me step-by-step how to implementation chatsrv/chatclient on this system.
i need install chatsrv on windows 2003, chatclient on windows xp.
if i don't using windows's certificate. can i using openssl to make public/private. then, how to manual add public/private to chatsrv/chatclient.
Please help me
Nguyen Trung Tin
|
|
|
|
|
One of every 5 - 20 calls to Receive() leads to invalid value in EBP (usually 0x00000041) and corrupted stack... I've spent a week trying to fix it.. no results.. Smb please help!
|
|
|
|
|
I've been trying to debug the same problem with Send() function by placing
__asm
{
push dword ptr[ebp]; <- this is the old EBP in the stack
push format_string;
call printf;
}
between almost every two lines of the function body and found that it were those _DUMP()s that are causing these EBP changes. In my case it was this one:
DUMP(_T("Plain text to send"),pbMessage,dwCurrLn);
I've removed them and it were not only the crashes that disappeared, but I also got a nice performance boost (4Kb/s vs 150Kb/s).
-- modified at 4:51 Friday 7th April, 2006
|
|
|
|
|
I've built both the ChatServer and the ChatClient successfully. I created my Certificates and was able to start up ChatServer.
But now that it's running, I can't connect with the client or the web browser. All I get from the browser is an acknowledgement of the certificate and the client doesn't connect all.
How would I alter your code to have the WEB BROWSER respond when a connection is attempted? I don't care what it says, it can just say "I am Listening".
Thanx
|
|
|
|
|
Can anybody tell me whether there is a version of the Netscape LDAP SDK for C that supports TLS connections to the directory server?
The version that I have is 4.1 and it supports only SSL version 3.0. It doesnt support TLS 1.0.
Also, can anyone suggest any other client library that is available that supports TLS conections to LDAP server in windows.
thanx,
megha
|
|
|
|
|
My understanding of SSL communication is that the server sends a server certificate to the client for verification. The client verifies it using a root CA certificate. The client may also optionally send a client certificate (different from the root CA certificate) to the server to be verified.
It seems that the root CA certificate is what is in the certificate store you mentioned. In the method CSslSocket::ClientCreateCredentials() of sslSocket.cpp the call to CertFindCertificateInStore() looks up the root CA using the pszUserName parameter in the "MY" part of the store. The store is in the registry at HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates.
For the root CA's that are preinstalled with a browser, wouldn't these be found under "Root" instead of "My"? Also, is my understanding of all this correct?
Thanks.
Stan
|
|
|
|
|
Hi
CSslSocket::Receive function has a bug.
if (pExtraBuffer) {<br />
MoveMemory(m_pbIoBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);<br />
m_cbIoBuffer = pExtraBuffer->cbBuffer;<br />
continue;<br />
}
"continue;" at the end of this part of code is not correct. You should attempt to decrypt this part of message instead of trying to download more in next pass of do-while loop. It quickly leads to errors when there is no more data to receive.
Also I noticed some crash of your code when receiving a big ammounts of data (it happens sometimes, I wans not able to find a solution so far).
Best regards and thanks for your work
Irek
Check out my software at: http://www.ireksoftware.com
|
|
|
|
|