 |
|
 |
Compared with the awkward giant animal OpenSSL, which leaks memory like a sift. This is so much better (OpenSSL maybe the only choice for other platforms though).
|
|
|
|
 |
|
 |
Is it possible to use it with event driven sockets that use WSAEventSelect(), WSAWaitForMultipleEvents(), WSAEnumNetworkEvents().
If yes, how?
I try to implant SSL support into my project but it doesn't work. Where to dig? Thanks.
|
|
|
|
 |
|
 |
Yes, you just use the ordinal SOCKET handle in those functions. The SSL_SOCKET can be used only when you need to read/write.
|
|
|
|
 |
|
 |
i need get https with socket
can i using this class for https ?
i test them like below
int argc=3;
char *argv[3] = {"tel","www.google.com", "443"};
but not work correctly
any solution ?
|
|
|
|
 |
|
 |
Thank you! I have another doubt: do you have to call ClientOff() and ServerOff() before or after calling the shutdown()?
When I close a socket I use shutdown(IN SOCKET s, IN int how) and closesocket(IN SOCKET s), I don't understand if I have to call ClientOff() and ServerOff() before shutdown() or after shutdown().
|
|
|
|
 |
|
 |
ClientOff() and ServerOff() initiate the shutdown of the SSL, not of the connection.
Therefore they have to be called before the socket closes.
|
|
|
|
 |
|
 |
So I have to:
1) ClientOff() (or ServerOff() )
2) shutdown()
3) closesocket()
because if I shutdown() before calling ClientOff() (or ServerOff() ) I disable the socket and I cannot shutdown SSL, right?
Excuse me if I ask simple questions, but I know little about SSL and I am trying to experiment with it.
Do you know where I can find examples about working with PCERT_CONTEXT? If I have understood well the examples in your article are about a self generated and signed certificate for the server, and the client doesn't control the certificate that it receives.
I read on a comment that you wrote that with "TrustedCertificate()" is possible to check a certificate, but I don't know how the Client can obtain the PCERT_CONTEXT to pass to "TrustedCertificate()". I would also like to read an example of how to load a trusted certificate in a PCERT_CONTEXT, so that I can pass it to the SSL_SOCKET() constructor (if I need to work with someone who requires a trusted certificate).
Thanks for your help!
|
|
|
|
 |
|
 |
Basically shutdown() is not needed.
ClientOff() and then you can close the socket.
The CERT_CONTEXT (The Certificate) can be obtained by using QueryContextAttributes(). Check VerifySessionCertificate() for details.
|
|
|
|
 |
|
 |
Thank you for your answers!
I managed to make a little application and SSL-connect it with your tel.exe, doing some tests (my application can be server and can be client, I tried with both). I also tried to launch 2 of my applications acting one as server and one as client.
I have some more questions:
1) Sometimes when I try to make a SSL connection between a client and a server the ServerLoop() doesn't end well and in this point:
// Get Some data from the remote site
int rval = recv(X,t + pt,0x10000,0);
if (rval == 0 || rval == -1)
return -1;
it returns -1 here in spite of going to
if (ss == S_OK)
break; // wow!!
This happens often (but not always), expecially when I open client before server or when I have established a connection and than one of the two (client or server) disconnect and reconnect. Sometimes it works and sometimes not, do you have an idea why?
2) When I CloseOff() or ServerOff(), a message is sent from the Server or Client that is stopping to the other end. s_recv() of the application receiving the message doesn't recognize this message as a SSL closing and returns the characters to the application as if it is "normal text" exchange. I think that it should recognize the "ending handshake" here (ss should be SEC_I_CONTEXT_EXPIRED, right?) and not pass it to the application (that doesn't know that string):
if (ss != SEC_E_OK && ss != SEC_I_RENEGOTIATE && ss != SEC_I_CONTEXT_EXPIRED)
return -1;
I made something wrong?
3) How can I load or create a PCCERT_CONTEXT to pass to SSL_SOCKET() different from the tempora self signed one? I read on the article that you can pass it in spite of using the tempora self signed certificate, but I don't know how to create/load a PCCERT_CONTEXT (I also searched a little on the net without success).
4) I tried to setup a Server with tel.exe and connect with my application, than use VerifySessionCertificate(). In this point of the code it breaks:
if(PolicyStatus.dwError) {
Status = PolicyStatus.dwError;
SetLastError(Status);
break;
}
the Status is 2148204809 (via Google I have found that means CertUNTRUSTEDROOT), it is because the certificate is self signed and so it is not trusted, right?
If I try the opposite (my application server and tel.exe client), QueryContextAttributes() fails and exit here:
if (Status != SEC_E_OK)
return Status;
Status has a -2146893042 that seems to have no meaning... I made something wrong?
Many thanks for your help and patience, I'm not sure if it was a good idea to learn SSL !
|
|
|
|
 |
|
|
 |
|
 |
1. thanks, I tried to understand what happens or at least recreate the situation in a precise way, but I failed.
2. exactly! I establish a SSL connection between a client and a server. They exchange messages and all is well. At a certain point one of the two ends, so it executes ClientOff() or ServerOff() (depending who it is). This cause the sending of some data to the other end of the socket (I think it is the "close handshake"), and when the other end of the socket receives this data with s_recv(), after the DecryptMessage() it doesn't recognize it as the "close handshake" and returns the string to the application (who doesn't know what to do with it). If I understood well in this case ss should be SEC_I_CONTEXT_EXPIRED and so I should have "return -1;" and not "return TotalR;"
3. Ok, I'll try, thanks! This article tells how to create a self signed certificate. Do you have also a link where there is an example of loading/obtanining a trusted certificate into PCCERT_CONTEXT so I can try to exchange a trusted certificate instead of create a self signed one and passing this?
4. In the first case (I call VerifySessionCertificate() and I am client) it fails because the certificate it is not verified I think, in the second cose (I call VerifySessionCertificate() and I am server) it seems to fail QueryContextAttributes() that should return the context attributes, so it doesn't even start to control the certificate.
Thanks again!
|
|
|
|
 |
|
 |
Hi, in serverInit() I saw this part commented:
it was to load a certificate, right?
I tried to use it to load a certificate made with makeCert, but I cannot load it.
In the "un" variable (used to load the certificate) you pass the subject of the certificate? And the "cft" variable in CertFindCertificateInStore() contains CERT_FIND_SUBJECT_ATTR?
I tried to work this way, but I cannot retrieve the PCCERT_CONTEXT, I always get the error 2148081668 (Service failed unexpectedly).
modified on Tuesday, August 30, 2011 8:50 AM
|
|
|
|
 |
|
 |
Hi,
on ssl.h there is this declaration:
int s_send(cahr* b, int sz);
but in ssl.cpp there is no implementation.
How do you make this work?
|
|
|
|
 |
|
 |
s_send is obsolete and in newer ssl.rar it's commented.
|
|
|
|
 |
|
|
 |
|
|
 |
|
 |
The routine
ss = QueryContextAttributes(&hCtx,SECPKG_ATTR_STREAM_SIZES,&Sizes);
returns 16,384 for cbMaximumMessage which is correct as RFC 2249 specifies that maximum fragment length of 2^14 bytes.
BUT Microsoft's implimentation actually sends 16,416 bytes!
So add the following line after the above query:
Sizes.cbMaximumMessage += 32;
This fixes the problem with Microsofts buggy implimentation.
|
|
|
|
 |
|
 |
Hi all,
The current source (and the more recent version at http://www.turboirc.com/temp/ssl.rar[^])doesn't work for TLS connections under Windows 7/Windows Server 2008 due to a bug in the way the function DecryptMessage is used.
Actually, the code, and specifically the method SSL_SOCKET::s_recv, doesn't handle correctly the case where DecryptMessage succeeds but returns an empty SECBUFFER_DATA buffer and a non-empty SECBUFFER_EXTRA. In this case, the code now simply returns 0 provoking a connection break, whereas it should loop in order to call DecryptMessage a second time to retrieve plain data.
Here is the corrected version of SSL_SOCKET::s_recv :
int SSL_SOCKET :: s_recv(char* b,int sz)
{
SecPkgContext_StreamSizes Sizes;
SECURITY_STATUS ss = 0;
ss = QueryContextAttributes(&hCtx,SECPKG_ATTR_STREAM_SIZES,&Sizes);
if (FAILED(ss))
return -1;
int TotalR = 0;
int pI = 0;
SecBuffer Buffers[5] = {0};
SecBuffer * pDataBuffer;
SecBuffer * pExtraBuffer;
Z<char> mmsg(Sizes.cbMaximumMessage*10);
if (PendingRecvDataSize)
{
if (sz <= PendingRecvDataSize)
{
memcpy(b,PendingRecvData,sz);
Z<char> dj(PendingRecvDataSize);
memcpy(dj,PendingRecvData,PendingRecvDataSize);
memcpy(PendingRecvData,dj + sz,PendingRecvDataSize - sz);
PendingRecvDataSize -= sz;
return sz;
}
memcpy(b,PendingRecvData,PendingRecvDataSize);
sz = PendingRecvDataSize;
PendingRecvDataSize = 0;
return sz;
}
for(;;)
{
unsigned int dwMessage = Sizes.cbMaximumMessage;
if (dwMessage > Sizes.cbMaximumMessage)
dwMessage = Sizes.cbMaximumMessage;
int rval = 0;
if (ExtraDataSize)
{
memcpy(mmsg + pI,ExtraData,ExtraDataSize);
pI += ExtraDataSize;
ExtraDataSize = 0;
}
else
{
rval = recv_p(mmsg + pI,dwMessage);
if (rval == 0 || rval == -1)
return rval;
pI += rval;
}
Buffers[0].pvBuffer = mmsg;
Buffers[0].cbBuffer = pI;
Buffers[0].BufferType = SECBUFFER_DATA;
Buffers[1].BufferType = SECBUFFER_EMPTY;
Buffers[2].BufferType = SECBUFFER_EMPTY;
Buffers[3].BufferType = SECBUFFER_EMPTY;
sbin.ulVersion = SECBUFFER_VERSION;
sbin.pBuffers = Buffers;
sbin.cBuffers = 4;
ss = DecryptMessage(&hCtx,&sbin,0,NULL);
if (ss == SEC_E_INCOMPLETE_MESSAGE)
continue;
if (ss != SEC_E_OK && ss != SEC_I_RENEGOTIATE && ss != SEC_I_CONTEXT_EXPIRED)
return -1;
pDataBuffer = NULL;
pExtraBuffer = NULL;
for (int i = 0; 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];
}
}
if (pExtraBuffer)
{
ExtraDataSize = pExtraBuffer->cbBuffer;
ExtraData.Resize(ExtraDataSize + 10);
memcpy(ExtraData,pExtraBuffer->pvBuffer,ExtraDataSize);
pI = 0;
}
if (ss == SEC_I_RENEGOTIATE)
{
ss = ClientLoop();
if (FAILED(ss))
return -1;
}
if (pDataBuffer == 0)
break;
else if ( (pDataBuffer->cbBuffer == 0) && ExtraDataSize)
{
continue;
}
TotalR = pDataBuffer->cbBuffer;
if (TotalR <= sz)
{
memcpy(b,pDataBuffer->pvBuffer,TotalR);
}
else
{
TotalR = sz;
memcpy(b,pDataBuffer->pvBuffer,TotalR);
PendingRecvDataSize = pDataBuffer->cbBuffer - TotalR;
PendingRecvData.Resize(PendingRecvDataSize + 100);
PendingRecvData.clear();
memcpy(PendingRecvData,(char*)pDataBuffer->pvBuffer + TotalR,PendingRecvDataSize);
}
break;
}
return TotalR;
}
I hope this will help.
Cheers,
--
Mounir IDRASSI
IDRIX
http://www.idrix.fr[^]
|
|
|
|
 |
|
 |
Hello there - thanks a lot for the fix.
Michael.
|
|
|
|
 |
|
 |
Not work perfectlly on Windows 7. Dont get exact result when pass some string over ssl.
|
|
|
|
 |
|
 |
can i use this on windows mobile as client?
|
|
|
|
 |
|
 |
Yes, the functions should exist in WM 6.x
|
|
|
|
 |
|
 |
I downloaded the new code mentioned in your last message, thank you for posting the update.
I was curious about the VerifySessionCertificate method. It looks like this has been fleshed out in the new version and if my assumptions from reading the code are correct it will error if the certificate is expired, can you tell me if it will also prevent connecting to a server using a self signed certificate? Trying to read through the API documentation has been less than enlightening.
Anything you can tell me about the relevant code? I have a project where this would be extremely helpful, but they've specified that the certificate chain must be validated and prevent the use of invalid/expired/self-signed certificates to prevent middleman attacks.
|
|
|
|
 |
|
 |
Hello there.
VerifySessionCertificate will return an error if the certificate is invalid or not trusted or expired. It is not preventing you to use the certificate if you want to. All browsers, when seeing such a certificate, present a warning to the user but nevertheless have a "continue anyway" button to go on.
The point of all this is to have a valid certificate to ensure that the one you are talking to is really the one it pretends to be. For that, the certificate must be signed by a trusted authority, like comodo, verisign, thawte etc. All of these offer server/client/e-mail/code signing certificates.
|
|
|
|
 |
|
 |
Thanks for your reply!
My project would be a B2B data exchange over SSL (no user interaction), the client simply wants it to prevent sending anything if someone were to try reconfiguring it to point to a different server without a certificate issued by a trusted authority. So if my SSL client service just wanted to prevent sending data to anything without a valid certificate issued by a trusted authority, I assume the code would look like this?
SSL_SOCKET* SX = new SSL_SOCKET(sockfd,0,0);
int n = SX->ClientInit();
if (n == -1)
{
logger->writeLog("SSL Client init failed!");
}
else
{
if (VerifySessionCertificate() != SEC_E_OK)
{
SX->ClientOff();
closesocket(sockfd);
logger->writeLog("VerifySessionCertificate failed!");
}
else
{
}
}
|
|
|
|
 |