Topic: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

Hello I have few problems to report with cyassl. 0.9.6

Problem 1:

Default setting for SSL_CTX_set_verify per OpenSSL should be SSL_VERIFY_NONE, and this is not what is set in cyassl. See this for refernce: http://publib.boulder.ibm.com/infocente … erify.html


Problem 2:

Using cyassl with HTTP 1.0 connection. In this case client needs to poll until connection is closed. The problem is that on connection end SSL_read should return 0 and in cyassl it always returns error -208.

After some looking through the code I found out that the problem seems to be in recieve function that treats connection closure as error, and connection reset which is the error as not error. This seems to be incorrect.

I would greatly appreciate if you could fix both issues.
#
touskaProject Admin

[Avatar]
2008-05-05 20:28:41 UTC
Hi Boris,

Problem 1: I can't in good conscience default CyaSSL's behavior to SSL_VERIFY_NONE. We only provide a compatibility layer and it's not perfect. In fact, I'd argue our choice is much better. Why have a default behavior for secure sockets that provides no more real security than plain sockets? Why place the burden on the user to do all this checking themselves? And, if you want to mimic OpenSSL behavior we allow this, you just have to be explicit. I haven't heard a good argument to change this policy yet, but feel free to try.

Problem 2: Thanks for the report. You are right, during SSL_read (but not the handshake) socket closure should return 0 and not an error. Even though the standard says this is an error (SSL shutdown should occur first) I'll go along with the OpenSSL man page on this one. But I think socket reset (usually machine reset or network reset and thus not able to do an SSL_shutdown) should also return 0. So I'm going to leave reset as it is unless you can tell me why this is incorrect. I'll check in the closure change by the end of the day.

Thanks for the feedback and reports,
Todd
#
borkraAccepting Donations

[Avatar]
2008-05-06 01:29:53 UTC
Hi Todd,

thanks for fixing issue #2.

Let me try to lay down my case for changing the behavior for both problems.

Problem #1:

Yes you are right default none is insecure. But the problem is if default is not none, you cannot establish SSL connection by default. Certificate was never validated and connection was aborted (and this is a real problem). So as a result I had to spend few hours chasing SSL API trying to figure out why and what is the issue. A lot of people would just cast your library by that time and move on elsewhere. Mimicking OpenSSL brings a lot of value to your library as one could replace existing code using OpenSSL with your stuff in 5 min there is a lot of value in that.

Problem #2:

If connection was reset there is no connection any more, so what SSL_shutdown going to do? Try to reestablish the connection and send a shutdown message? Chances are server will not even link 2 connections together. What's gone is gone...

And after looking into your code SSL_shutdown does not even try to reestablish the connection. So I am completely confused what is the purpose for all of this?

Sockets as far as I know close connection when reset received, so you cannot send anything on this socket any more until connection reestablished.
#
borkraAccepting Donations

[Avatar]
2008-05-06 01:48:35 UTC
Todd,

More on problem #2:

I forgot to mention, that if I am doing HTTPS 1.0 and received 0 - connection closed it means that all data recived, on the other hand if I got error that means I did not get any data or got partial data, my response to this 2 events would be completely different. I 1st case I would process the data in the 2nd case I would ignore it. I hope you see the difference.
#
touskaProject Admin

[Avatar]
2008-05-06 19:21:44 UTC
Connection closed doesn't necessarily mean all data received in SSL. A conforming stack (and user) will call SSL_shutdown after they've sent all data, only then will you know for sure. A socket closure without SSL_shutdown could merely mean an exception handler was called, or the OS was doing cleanup on process shutdown after a fatal error (while data was still buffered to be sent).

The point I was trying to make was that both connection closed and reset are technically errors if the first peer to stop doesn't first send SSL_shutdown(). Though I agree that partial data is an error. I'll try to make sure that CyaSSL always returns an error in this case. BTW, the reason I have reset behave that way is a report from an embedded SSL user asking for more OpenSSL compliance. Is it your understanding that OpenSSL doesn't return 0 on socket reset for an SSL_read?

Thanks for the help.
#
touskaProject Admin

[Avatar]
2008-05-06 19:31:34 UTC
1: Well, that's my failure for not properly (or more easily) documenting the change. Which ever way this ends up, I need to document this behavior better. That's a good point for compliance, but maybe if I have comments at the beginning of the README, around SSL_connect, and in the examples users won't run into this problem in the future. If they do, you're right, I should change it, but I should document just as much about how this is unsafe and how they should use it.

2: I didn't explain SSL_shutdown() very well I think. I was trying to point out that proper SSL shutdown/closure is to call SSL_shutdown(), not close the socket first. I don't try to send an SSL_shutdown if the connection is closed because it's a socket error to try that, it's just to avoid SIGPIPE. But if the connection isn't closed, then I try to send an SSL_shutdown message even if the peer hasn't (which isn't required but is recommended).

See the rest of my comment on the next post, thanks.
#
borkraAccepting Donations

[Avatar]
2008-05-07 04:50:30 UTC
Todd,

regarding SSL_read. I guess I did not explain what I am trying to do correctly.

I am trying to implement HTTPS 1.0 protocol. It is HTTP 1.0 over SSL tunnel.
HTTP 1.0 works as following: you send a request through socket send (1 or many and then wait for reply) reply message is completed when connection is gracefully closed (socket read returns 0, otherwise http transaction failed). You can read RFC 1945 for information on HTTP 1.0.

In the previous messages I described to you how HTTPS 1.0 was implemented using OpenSSL. And it is working flawlessly for years. I am not clear though how do you propose to implement HTTPS 1.0 over cyassl, this connection reset seems to be a problem. As I do not understand how to distinguish graceful connection closure from not graceful one, as per HTTP 1.0 graceful closure signifies the transmission complete event.
#
borkraAccepting Donations

[Avatar]
2008-05-07 06:21:10 UTC
Todd,

Tried your latest CVS code and got a problem. Cannot establish SSL connection. The error happens in the new DoServerKeyExchange. On line

if (messageTotal > sizeof(messageVerify))
    return BUFFER_ERROR;

If you would like to try it yourself the host is: kc-in-f125.google.com
#
touskaProject Admin

[Avatar]
2008-05-07 18:58:22 UTC
Thanks for the report, I've checked in a fix. I'd never seen Ephemeral DH greater than 1024 bit before, I've added support for up to 2240 bit. If people start going to 3072 or higher I guess I'll make the buffer dynamic, I've just tried to avoid doing that with CyaSSL.
#
touskaProject Admin

[Avatar]
2008-05-07 19:03:53 UTC
Fair enough, let's see if the reset on read is really the problem. Can you change a line in ReceiveData() in cyassl_int.c

from:

if (ssl->options.connReset || ssl->options.isClosed)

to:

if (ssl->options.isClosed)


If that better matches OpenSSL behavior then I'll check it in.

Please let me know if that works, thanks.
#
borkraAccepting Donations

[Avatar]
2008-05-07 23:38:36 UTC
Hi Todd,

Yes thank you, change in cyassl_int.c does make it work.

Share

2

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

I am trying to port Wvstreams 4.6.1 to a proprietary core. Wvstreams has dependency on OpenSSL (any version greater than 0.9.7).  I already have CyaSSL 1.5.0 ported to this proprietary core and want to use this instead of porting OpenSSL. 

I understand that CyaSSL has a transition header to support OpenSSL compatibility, but I dont see the OpenSSL API "SSL_has_matching_session_id"  mentioned in the CyaSSL 1.5.0  or the latest version 1.8.0.  I get this error while I try to configure wvstreams. This could be just one of the first API missing, that I have encountered and maybe will have many more if am able to proceed.

I would like to know if anybody has resolved this? Any pointers?

Regards
Pallavi

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

SSL_has_matching_session_id just checks to make sure that the user generated session id is unique.  The chance of collision is 2^256 so it should be.

Can you make a list of the missing functions?  If it's short and they're easy we can probably add them without trouble.

BTW, which proprietary core are you using?

Share

4 (edited by pd 2011-01-25 00:12:37)

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

Hello,

Thanks for the response. Using ST SH4 core.

For now its SSL_has_matching_session_id, POLICY_MAPPING_new, _X509_free', cause these are checked in the configure script of Wvstreams. May be if I can resolve this and proceed from the configure stage to "make", will have more missing functions to report.

I have cut paste below the error regarding the ssl and crypto libraries.

configure:8462: checking for openssl/ssl.h
configure:8483: sh4g++ -c -mboard=mediarefsim -DSINGLE_THREADED -I/home/pallavi/wvdial-SH4/cyassl/include -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include   -I/home/pallavi/wvdial-SH4/cyassl/include conftest.cpp >&5
configure:8490: $? = 0
configure:8507: result: yes
configure:8525: checking for X509_free in -lcrypto
configure:8560: sh4g++ -o conftest -mboard=mediarefsim -DSINGLE_THREADED -I/home/pallavi/wvdial-SH4/cyassl/include -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include   -I/home/pallavi/wvdial-SH4/cyassl/include -L/home/pallavi/wvdial-SH4/cyassl -L/lib   -L/home/pallavi/wvdial-SH4/cyassl conftest.cpp -lcrypto   >&5
/tmp/ccYCDG64.o: In function `_main':
conftest.cpp:(.text+0x1c): undefined reference to `_X509_free'
collect2: ld returned 1 exit status
configure:8567: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "WvStreams"
| #define PACKAGE_TARNAME "wvstreams"
| #define PACKAGE_VERSION "4.6.1"
| #define PACKAGE_STRING "WvStreams 4.6.1"
| #define PACKAGE_BUGREPORT "wvstreams-devel@googlegroups.com"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define ATTR_DEPRECATED __attribute__ ((deprecated))
| #define HAVE_DIRENT_H 1
| #define HAVE_ALLOCA_H 1
| #define HAVE_ALLOCA 1
| #define HAVE_ARGZ_H 1
| #define HAVE_ERRNO_H 1
| #define ETHER_ADDR_LEN 6
| #define VER_STRING_EXTRA " (pallavi@pallavi-Vostro-3400)"
| #define HAVE_DBUS_DBUS_H 1
| #define HAVE_OPENSSL_SSL_H 1
| /* end confdefs.h.  */
|
| /* Override any GCC internal prototype to avoid an error.
|    Use char because int might match the return type of a GCC
|    builtin and then its argument prototype would still apply.  */
| #ifdef __cplusplus
| extern "C"
| #endif
| char X509_free ();
| int
| main ()
| {
| return X509_free ();
|   ;
|   return 0;
| }
configure:8588: result: no
configure:8600: checking for SSL_has_matching_session_id in -lssl
configure:8635: sh4g++ -o conftest -mboard=mediarefsim -DSINGLE_THREADED -I/home/pallavi/wvdial-SH4/cyassl/include -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include   -I/home/pallavi/wvdial-SH4/cyassl/include -L/home/pallavi/wvdial-SH4/cyassl -L/lib   -L/home/pallavi/wvdial-SH4/cyassl conftest.cpp -lssl   >&5
/tmp/ccAGsy1i.o: In function `_main':
conftest.cpp:(.text+0x1c): undefined reference to `_SSL_has_matching_session_id'
collect2: ld returned 1 exit status
configure:8642: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "WvStreams"
| #define PACKAGE_TARNAME "wvstreams"
| #define PACKAGE_VERSION "4.6.1"
| #define PACKAGE_STRING "WvStreams 4.6.1"
| #define PACKAGE_BUGREPORT "wvstreams-devel@googlegroups.com"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define ATTR_DEPRECATED __attribute__ ((deprecated))
| #define HAVE_DIRENT_H 1
| #define HAVE_ALLOCA_H 1
| #define HAVE_ALLOCA 1
| #define HAVE_ARGZ_H 1
| #define HAVE_ERRNO_H 1
| #define ETHER_ADDR_LEN 6
| #define VER_STRING_EXTRA " (pallavi@pallavi-Vostro-3400)"
| #define HAVE_DBUS_DBUS_H 1
| #define HAVE_OPENSSL_SSL_H 1
| /* end confdefs.h.  */
|
| /* Override any GCC internal prototype to avoid an error.
|    Use char because int might match the return type of a GCC
|    builtin and then its argument prototype would still apply.  */
| #ifdef __cplusplus
| extern "C"
| #endif
| char SSL_has_matching_session_id ();
| int
| main ()
| {
| return SSL_has_matching_session_id ();
|   ;
|   return 0;
| }
configure:8663: result: no
configure:8678: checking for POLICY_MAPPING_new in -lssl
configure:8713: sh4g++ -o conftest -mboard=mediarefsim -DSINGLE_THREADED -I/home/pallavi/wvdial-SH4/cyassl/include -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include   -I/home/pallavi/wvdial-SH4/cyassl/include -L/home/pallavi/wvdial-SH4/cyassl -L/lib   -L/home/pallavi/wvdial-SH4/cyassl conftest.cpp -lssl   >&5
/tmp/ccWxVBRw.o: In function `_main':
conftest.cpp:(.text+0x1c): undefined reference to `_POLICY_MAPPING_new'
collect2: ld returned 1 exit status
configure:8720: $? = 1
configure: failed program was:
| /* confdefs.h.  */
| #define PACKAGE_NAME "WvStreams"
| #define PACKAGE_TARNAME "wvstreams"
| #define PACKAGE_VERSION "4.6.1"
| #define PACKAGE_STRING "WvStreams 4.6.1"
| #define PACKAGE_BUGREPORT "wvstreams-devel@googlegroups.com"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define ATTR_DEPRECATED __attribute__ ((deprecated))
| #define HAVE_DIRENT_H 1
| #define HAVE_ALLOCA_H 1
| #define HAVE_ALLOCA 1
| #define HAVE_ARGZ_H 1
| #define HAVE_ERRNO_H 1
| #define ETHER_ADDR_LEN 6
| #define VER_STRING_EXTRA " (pallavi@pallavi-Vostro-3400)"
| #define HAVE_DBUS_DBUS_H 1
| #define HAVE_OPENSSL_SSL_H 1
| /* end confdefs.h.  */
|
| /* Override any GCC internal prototype to avoid an error.
|    Use char because int might match the return type of a GCC
|    builtin and then its argument prototype would still apply.  */
| #ifdef __cplusplus
| extern "C"
| #endif
| char POLICY_MAPPING_new ();
| int
| main ()
| {
| return POLICY_MAPPING_new ();
|   ;
|   return 0;
| }
configure:8741: result: no


Can you help me, with this fix?

Regards
Pallavi

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

If you add those 3 function declarations to cyassl/include/openssl/ssl.h at the bottom and then blank implementations to the bottom of cyassl/src/ssl.c you should get past the ./configure process which will allow you see the total number of missing functions and what they are.  That will allow us to see how much work it is and the best way to proceed.

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

Hi

Has anyone ported OpenVPN to use cyassl?

Thanks

Jeff

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

I know someone put CyaSSL into a VPN, though I'm not sure I ever learned which one.

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

Thanks. I am curious to find out whether the size of OpenVPN can be significantly reduced by using CyaSSL rather than the default one. It would be helpful to see what VPN project CyaSSL has been used in.

It would also be great if it could be a straightforward plugin replacement for OpenSSL - just by changing the library that is used (with OpenSSL defaults enabled by a "#ifdef  OPENSSL_REPLACEMENT" or whatever when building the library itself) and without changing anything in the sources. That way, it would be straightforward to use one instead of the other, and to perform a comparison (size, speed, etc). Is this an unrealistic proposition?

By the way, ctaocrypt/src/rsa.c does not compile, because of this call: "buf = XCALLOC(1, len, heap)" (both on Ubuntu 9.04 and a mipsle cross-compiler). Presumably the configure script should be able to ascertain whether XCALLOC exists? What is the need to use that function anyway?

I had to work around the problem by doing this:

void * XCALLOC (int dummy, size_t num, size_t sz)
{
void *p;
    if (num == 0 || sz == 0)
             return (NULL);
    p = calloc (num, sz);
    if (p == NULL)
    {
      fprintf (stderr, "Unable to allocate %d block(s) of %d byte(s)\n", num, sz);
      exit (1);
    }
    bzero (p, num * sz);
    return (p);
}

Is this okay?

Thanks

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

This is a little cleaner when KEY_GEN is on, it will be in the next release:

    buf = XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
    if (buf == NULL) {
        return -1;
    }
    XMEMSET(buf, 0, len);

Share

Re: CyaSSL as OpenSSL Alternative; Compatibility Layer (old forum post)

Ok, thanks.

Share