2008-09-24 21:00:57 UTC
Does wolfSSL 0.9.9 support EV SSL certificates?
when i try a ssl_connect to loginnet.passport.com i get an ssl_failed error .... in beup (msn for nds).
troubleshooting this gave a error in ssl.c:
" /* get response */
while (ssl->options.serverState < neededState)
teller= ProcessReply(ssl);
if ( (ssl->error = teller) < 0) {
CYASSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;}
"
So i think something goed wrong in cyassl_int.c:
int DoProcessReply(SSL* ssl)
which calls e.g.DoProcessReply
I expect the error to occure in there..
the CYASSL_ENTER("ProcessReply()"); and CYASSL_MSG( functions do not give any info on a nds...
I'm not a c++ guru so i have a problem to find what's wrong.
i traces the ssl traffic with wireshark...
you can download the file there:
http://filetrans.be.getronics.com/downl … mp;lang=en
(until 2008-10-04 )
Can someone please tell me what's going wrong?
Is it the EV SSL cert?
Is it a changed ca?
Is it a cipher which is not supported?
Please explain why you conclude this...
thx
Bas
#
touskaProject Admin
[Avatar]
2008-09-24 21:49:30 UTC
wolfSSL supports the certificate just fine. If you go the examples/client directory you can test this on Linux, Windows, or whatever by typing:
./client loginnet.passport.com 443
The server doesn't like the GET format but the SSL connect works and the encrypted response from the server is printed.
Did you change any other lines in wolfSSL? What error are you getting? You never say. wolfSSL isn't written in C++, it's all C.
From the packet capture it looks like you are shutting down the SSL session before you get a response from the server. The client hello is sent in packet 4 at time .3. The next SSL traffic is the client sending a close notify alert (shutdown) at time .8 packet 15. This is before the server even replies at time 1.1 packet 22.
Are you using non-blocking sockets and not restarting the call to SSL_connect?
#
bashendriks123
[Avatar]
2008-09-26 06:25:26 UTC
i tested the code with a wolfSSL 0.9.9 fresh download to see what i needed to change to get it to work.
First i compiled the cyassl 0.9.9 code with visual express 2008 and tested ./client loginnet.passport.com 443
When i changed the lines :
// if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
// err_sys("can't load ca file");
in client.c it worked ok, otherwise i got an can't load ca file error message.
But when i compiled the code in beup (msn for nds) i had to change ctaocrypt\source\random.c because it doesn't know how to compile sleep:
// if (sz)
// sleep(1);
then i get indeed an "TLSv1 Record Layer: Alert (Level: Warning, Description: Close Notify)" because in ssl_connect i get an error in ssl.c on:
case CLIENT_HELLO_SENT :
neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
SERVER_HELLODONE_COMPLETE;
/* get response */
while (ssl->options.serverState < neededState)
if ( (ssl->error = ProcessReply(ssl)) < 0) {
CYASSL_ERROR(ssl->error);
==> this line ==> return SSL_FATAL_ERROR;
}
ssl->options.connectState = FIRST_REPLY_DONE;
CYASSL_MSG("connect state: FIRST_REPLY_DONE");
and so the beup program shutsdown the ssl connection.
In cyassl_int.c the int ProcessReply(SSL* ssl)
function/procedure is defined which calls in the same file:
int DoProcessReply(SSL* ssl)
somewhere in these two someting goes wrong....
The ssl connection is being build up from msn.cpp (part of beup) in authenticate:
"static void authenticate() {
int size;
int response, passSock;
sockaddr_in addr;
char *str;
int ip;
debug->append(strRep("MsnAuthTicket"));
sscanf(recBuf, "USR %*s TWN S %s\r\n", buffer3);
passSock = socket(PF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(443);
ip = (strstr(user.account, "msn.com")) ? Msn_IP : Passport_IP;
addr.sin_addr.s_addr = ip;
connect(passSock, (sockaddr*)&addr, sizeof(addr));
urlEncode(user.account, buffer);
urlEncode(user.password, buffer2);
SSL_METHOD* method = 0;
SSL_CTX* ctx = 0;
SSL* ssl = 0;
method = TLSv1_client_method();
ctx = SSL_CTX_new(method);
SSL_CTX_load_verify_locations(ctx, SSL_Certificate, 0);
ssl = SSL_new(ctx);
SSL_set_fd(ssl, passSock);
debug->append(strRep("MsnPassConnected"));
==> error occure here ==> if (SSL_connect(ssl) != SSL_SUCCESS) {
debug->append(strRep("MsnSSLConnectFailed"), ErrColor);
notState = State_AuthFailed;
if (loginTab->chkAutoerror.selected) loginTab->connect();
} else {
char redir[25];
strcpy(redir, "/login2.srf");
debug->append(strRep("MsnSSLConnected"));
while (true) {
size = snprintf(recBuf, RecBufSize, Passport_GET, redir, buffer, buffer2, buffer3);
if (SSL_write(ssl, recBuf, size) != size) {
debug->append(strRep("MsnSSLSendFailed"), ErrColor);
notState = State_AuthFailed;
break;
}
recBuf[SSL_read(ssl, recBuf, RecBufSize)] = 0;
response = 0;
sscanf(recBuf, "%*s %d", &response);
if (response == 302) {
str = strstr(recBuf, "Location:");
debug->append("Got a 302 transfer. Support for this is still buggy.");
debug->append("If authentication fails, please report this location to the boards:");
debug->append(str);
notState = State_AuthFailed;
break;
} else break;
}
}
if (notState != State_AuthFailed) {
if (response == 200) {
str = strstr(recBuf, "from-PP");
sscanf(str, "from-PP='%s", buffer3);
*index(buffer3, '\'') = 0;
notState = State_Authenticated;
debug->append(strRep("MsnAuth200"));
} else if (response == 401) {
debug->append(strRep("MsnAuth401"), ErrColor);
notState = State_AuthFailed;
}
}
Print("<<%s", recBuf);
==> shutdown ssl occures there==> SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
close(passSock);
recBuf[0] = 0;
recSize = 0;
bufferWaiting = false;
}
"
Can you please tell me:
-does the change in random.c have an effect on the alert.notify and if yes any idea how to fix this?
-any idea why the ssl_connect failes?, does it use the correct statements to build up a ssl connection?
With Kind regards,
Bas
#
touskaProject Admin
[Avatar]
2008-09-26 18:12:19 UTC
You shouldn't have to comment out the lines in client.c, that means you're probably running ./client from the wrong directory.
Can you use a different call then sleep() to get the same effect, it probably isn't causing the problem though?
You still don't say what the actual error is. You can either look directly at the value of ssl->error or you need to call SSL_get_error() to get it. Without knowing the actual error it's hard to say what's going on. The code steps are in the right order, though no error checking is being done so something else could be going wrong too.
#
bashendriks123
[Avatar]
2008-09-27 08:29:14 UTC
Well my c knowlegde is not so good, so finding another sleep functon is not so easy but i will try. (if you have a sleep function for me would be great).
I'm compiling on windows and i already have seen some error reflecting on functions which apperently exist in linux code.
When i use error checking then the error of ssl_get_error is a 2 which should be a ssl_read error.
No other errors appear so ssl_connect gives the error.
i will try to read the ssl-> error and getback on that too.
============
char * itoa(int n, char *buff, int radix)
// convert a positive integer n to char *buff
// for instant, this function work with radix <= 10;
// a little change to run with radix > 10
{
int q, r;
int i = 0;
char tmp[33]; // for radix = 2 and 32 bits computer
do{
q = int(n / radix);
r = n % radix;
n = q;
tmp[i++] = 48 + r;
}while(q > 0);
int j;
for(j = 0; j < i; j++){
buff[j] = tmp[i - j - 1];
}
buff[j] = NULL;
return buff;
}
static void authenticate() {
int size, status, erro, ret, ret14;
int response, passSock;
sockaddr_in addr;
char *str;
int ip;
char erro_buf[5];
char erro_buf7[100];
char erro_buf13[100];
char erro_buf14[100];
/* char msg[] = "hello cyassl!";
char reply[1024];
int input;
int msgSz = sizeof(msg);
*/
status = 0;
debug->append(strRep("MsnAuthTicket"));
sscanf(recBuf, "USR %*s TWN S %s\r\n", buffer3);
passSock = socket(PF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(443);
ip = (strstr(user.account, "msn.com")) ? Msn_IP : Passport_IP;
addr.sin_addr.s_addr = ip;
connect(passSock, (sockaddr*)&addr, sizeof(addr));
urlEncode(user.account, buffer);
urlEncode(user.password, buffer2);
SSL_METHOD* method = 0;
SSL_CTX* ctx = 0;
SSL* ssl = 0;
method = TLSv1_client_method();
ctx = SSL_CTX_new(method);
// SSL_CTX_load_verify_locations(ctx, SSL_Certificate, 0);
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
ssl = SSL_new(ctx);
if (ssl == NULL) {
debug->append("Could not allocate 'ssl' with SSL_new()\n");
};
//SSL_set_fd - connect the SSL object with a file descriptor
status=SSL_set_fd(ssl, passSock);
if (status==0) {debug->append("Could not connect ssl object with file descriptor");}
else
{debug->append("ssl object connected with file descriptor");};
debug->append("passSock: ");
debug->append(itoa ( passSock, erro_buf7, 10 ));
debug->append(strRep("MsnPassConnected"));
//SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server
status=SSL_connect(ssl);
ret=status;
debug->append("status (1-10) : ");
debug->append(itoa ( status, erro_buf13, 10 ), ErrColor);
// if (status != SSL_SUCCESS) {
// erro= SSL_get_error (ssl, status);
erro= SSL_get_error(ssl, 0);
debug->append( itoa ( erro, erro_buf, 10 ), ErrColor);
if (erro == 2)
debug->append("... client would read block");
else
if (erro == 3)
debug->append("... client would write block");
else
debug->append("... client neither read nor write");
if (SSL_connect(ssl) != SSL_SUCCESS) {
debug->append(strRep("MsnSSLConnectFailed"), ErrColor);
notState = State_AuthFailed;
if (loginTab->chkAutoerror.selected) loginTab->connect();
} else {
char redir[25];
strcpy(redir, "/login2.srf");
debug->append(strRep("MsnSSLConnected"));
while (true) {
size = snprintf(recBuf, RecBufSize, Passport_GET, redir, buffer, buffer2, buffer3);
if (SSL_write(ssl, recBuf, size) != size) {
debug->append(strRep("MsnSSLSendFailed"), ErrColor);
notState = State_AuthFailed;
break;
}
recBuf[SSL_read(ssl, recBuf, RecBufSize)] = 0;
response = 0;
sscanf(recBuf, "%*s %d", &response);
if (response == 302) {
str = strstr(recBuf, "Location:");
debug->append("Got a 302 transfer. Support for this is still buggy.");
debug->append("If authentication fails, please report this location to the boards:");
debug->append(str);
notState = State_AuthFailed;
break;
} else break;
}
}
if (notState != State_AuthFailed) {
if (response == 200) {
str = strstr(recBuf, "from-PP");
sscanf(str, "from-PP='%s", buffer3);
*index(buffer3, '\'') = 0;
notState = State_Authenticated;
debug->append(strRep("MsnAuth200"));
} else if (response == 401) {
debug->append(strRep("MsnAuth401"), ErrColor);
notState = State_AuthFailed;
}
}
Print("<<%s", recBuf);
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
close(passSock);
recBuf[0] = 0;
recSize = 0;
bufferWaiting = false;
}
==================
#
touskaProject Admin
[Avatar]
2008-09-29 05:12:54 UTC
The error you're getting from SSL_connect via SSL_get_error is SSL_ERROR_WANT_READ. This is not just an SSL_read error, this can happen on connect too, like you're getting, because connect reads and writes SSL records. You're getting the error because your socket is non-blocking and the data from the server hasn't arrived yet. Just like the packet capture showed. You need to call SSL_connect again once the data is there. From the man page:
If the underlying BIO is non-blocking, SSL_connect() will also return when the underlying BIO could not satisfy the needs of SSL_connect() to continue the handshake, indicating the problem by the return value -1. In this case a call to SSL_get_error() with the return value of SSL_connect() will yield SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling process then must repeat the call after taking appropriate action to satisfy the needs of SSL_connect(). The action depends on the underlying BIO. When using a non-blocking socket, nothing is to be done, but select() can be used to check for the required condition.
The whole page is here: http://openssl.org/docs/ssl/SSL_connect.html
As for Windows code vs. Unix code, if you're compiling for Windows then your compiler needs to define _WIN32, if it's broken (and doesn't) then it will try and compile the Unix code which will obviously not work (like sleep). Which compiler, version, target are you using?
#
bashendriks123
[Avatar]
2008-09-29 07:31:08 UTC
Tod,
thx!!
The ssl connection is made!
I just put the ssl_connect in a while loop.
"//SSL_set_fd - connect the SSL object with a file descriptor
status=SSL_set_fd(ssl, passSock);
if (status==0) {debug->append("Could not connect ssl object with file descriptor");}
else
{debug->append("ssl object connected with file descriptor");};
debug->append("passSock: ");
debug->append(itoa ( passSock, erro_buf7, 10 ));
debug->append(strRep("MsnPassConnected"));
//SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server
status=SSL_connect(ssl);
ret=status;
debug->append("status (1-10) : ");
debug->append(itoa ( status, erro_buf13, 10 ), ErrColor);
// if (status != SSL_SUCCESS) {
// erro= SSL_get_error (ssl, status);
erro= SSL_get_error(ssl, 0);
debug->append( itoa ( erro, erro_buf, 10 ), ErrColor);
if (erro == 2)
debug->append("... client would read block");
else
if (erro == 3)
debug->append("... client would write block");
else
debug->append("... client neither read nor write");
while (status != SSL_SUCCESS )
// && (erro == 2 || erro == 3)
{
debug->append("in de while loop");
//SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server
status=SSL_connect(ssl);
erro= SSL_get_error(ssl, 0);
debug->append( itoa ( erro, erro_buf, 10 ), ErrColor);
};
if (SSL_connect(ssl) != SSL_SUCCESS) {
debug->append(strRep("MsnSSLConnectFailed"), ErrColor);
notState = State_AuthFailed;
if (loginTab->chkAutoerror.selected) loginTab->connect();
} else {"
"Which compiler, version, target are you using? "
I' working on winxp sp3, compiling with devkitpro 1.4.7 for nintendo DS so arm 9 (and arm 7) processor.
#
bashendriks123
[Avatar]
2008-09-30 05:58:24 UTC
i'm still not sure if the ssl connection stays ok...
I still see a tls alert message
can anyone see if this is ok or not?
http://filetrans.be.getronics.com/downl … mp;lang=en
with kind regards,
bas hendriks
#
touskaProject Admin
[Avatar]
2008-09-30 20:48:04 UTC
TLS alerts are a normal part of SSL shutdowns, so the question is, did you shutdown the connection? If not, what error did you get? Are you restarting SSL_read() to get all the data you want with non-blocking sockets?