namespace BIOWrapper {
int write( BIO* b, const char* buf, int num );
+
int read( BIO* b, char* buf, int size );
+
int puts( BIO* b, const char* str );
+
int gets( BIO* b, char* str, int size );
+
long ctrl( BIO* b, int cmod, long arg1, void* arg2 );
template <typename T>
template <typename T>
BIO_METHOD* toBio() {
+ return toBio<T>( BIOWrapper::bio_new<T> );
+}
+
+template <typename T>
+BIO_METHOD* toBio( int ( *newfunc )( BIO* ) ) {
static BIO_METHOD new_method = {
T::typeID,
T::getName(),
BIOWrapper::puts,
BIOWrapper::gets,
BIOWrapper::ctrl,
- BIOWrapper::bio_new<T>,
+ newfunc,
BIOWrapper::free,
NULL,
};
return std::string( mem.get(), len * 2 );
}
-SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
+SlipBIO::SlipBIO() {
+ this->buffer = std::vector<char>( 4096 );
+ this->decodeTarget = 0;
+ this->decodePos = 0;
+ this->rawPos = 0;
+}
+
+void SlipBIO::setTarget( std::shared_ptr<OpensslBIO> target ) {
this->target = target;
+}
+SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
+ this->target = target;
this->buffer = std::vector<char>( 4096 );
this->decodeTarget = 0;
this->decodePos = 0;
}
}
- int totalLen = num + badOnes + 2;
+ int totalLen = num + badOnes + 1; // 2
char* targetPtr = ( char* ) malloc( totalLen );
if( !targetPtr ) {
std::shared_ptr<char> t = std::shared_ptr<char>( targetPtr, free );
int j = 0;
- targetPtr[j++] = ( char )0xC0;
+
+ //targetPtr[j++] = (char)0xC0;
for( int i = 0; i < num; i++ ) {
if( buf[i] == ( char )0xc0 ) {
targetPtr[j++] = ( char )0xC0;
if( target->write( targetPtr, j ) != j ) {
+ std::cout << "sent " << j << std::endl;
throw "Error, target write failed";
}
- std::cout << toHex( targetPtr, j ) << std::endl;
return num;
}
int SlipBIO::read( char* buf, int size ) {
- if( ( unsigned int ) size < buffer.capacity() ) {
- // fail...
- }
-
// while we have no data to decode or unmasking does not yield a full package
- while( decodePos >= rawPos || !unmask() ) {
+ while( !packageLeft && ( decodePos >= rawPos || !unmask() ) ) {
// we have no data, read more
if( buffer.size() - rawPos < 64 ) {
if( len > 0 ) {
rawPos += len;
} else {
- decodeTarget = 0;
- failed = true;
+ return -1;
+ //decodeTarget = 0;
+ //failed = true;
}
}
+ packageLeft = true;
+ int len = std::min( decodeTarget, ( unsigned int ) size );
// a package finished, return it
- std::copy( buffer.data(), buffer.data() + decodeTarget, buf );
+ std::copy( buffer.data(), buffer.data() + len, buf );
// move the buffer contents back
+ std::copy( buffer.data() + len, buffer.data() + decodeTarget, buffer.data() );
+ decodeTarget -= len;
- int len = decodeTarget;
- decodeTarget = 0;
+ if( decodeTarget == 0 ) {
+ packageLeft = false;
+ }
return len;
}
( void ) cmod;
( void ) arg1;
( void ) arg2;
-
- return 0;
+ return target->ctrl( cmod, arg1, arg2 );
}
const char* SlipBIO::getName() {
unsigned int rawPos;
bool failed;
+ bool packageLeft = false;
private:
bool unmask();
public:
SlipBIO( std::shared_ptr<OpensslBIO> target );
+ SlipBIO();
~SlipBIO();
+ void setTarget( std::shared_ptr<OpensslBIO> target );
+
virtual int write( const char* buf, int num );
virtual int read( char* buf, int size );
virtual long ctrl( int cmod, long arg1, void* arg2 );
.PHONY: openssl
openssl:
- ${MAKE} -C ../lib/openssl
+ ${MAKE} -C ../lib openssl
.PHONY: collissiondetect
collissiondetect:
fake_sigalg testdata/test.$alg testdata/test_invalid_sig.$alg
fake_sig testdata/test.$alg testdata/test_false_sig.$alg
done
+
+openssl req -new -newkey rsa:2048 -nodes -subj "/CN=cn" -keyout testdata/server.key -out testdata/server.csr 2> /dev/null
+openssl x509 -in testdata/server.csr -signkey testdata/server.key -req -out testdata/server.crt 2> /dev/null
#include <boost/test/unit_test.hpp>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
#include "bios.h"
+#include "opensslBIO.h"
#include "slipBio.h"
class OpensslBIOVector : public OpensslBIO {
BOOST_CHECK_EQUAL_COLLECTIONS( buf, buf + 2, res3, res3 + 2 );
}
+BOOST_AUTO_TEST_CASE( TestSSLThroughSLIP ) {
+ BIO* bio1, *bio2;
+ BOOST_REQUIRE_EQUAL( BIO_new_bio_pair( &bio1, 8096, &bio2, 8096 ), 1 );
+ BIO* slip1 = BIO_new( toBio<SlipBIO>() );
+ ( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( bio1 ) ) );
+ BIO* slip2 = BIO_new( toBio<SlipBIO>() );
+ ( ( SlipBIO* )slip2->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( bio2 ) ) );
+
+ auto meth = TLSv1_method();
+ auto c_ctx = SSL_CTX_new( meth );
+ auto s_ctx = SSL_CTX_new( meth );
+ //SSL_CTX_set_cipher_list(c_ctx, "ALL");
+ //SSL_CTX_set_cipher_list(s_ctx, "ALL");
+ SSL_CTX_use_certificate_file( s_ctx, "testdata/server.crt", SSL_FILETYPE_PEM );
+ SSL_CTX_use_PrivateKey_file( s_ctx, "testdata/server.key", SSL_FILETYPE_PEM );
+ auto c_ssl = SSL_new( c_ctx );
+ auto s_ssl = SSL_new( s_ctx );
+ auto c_bio = BIO_new( BIO_f_ssl() );
+ auto s_bio = BIO_new( BIO_f_ssl() );
+ SSL_set_connect_state( c_ssl );
+ SSL_set_bio( c_ssl, slip1, slip1 );
+ BIO_set_ssl( c_bio, c_ssl, BIO_NOCLOSE );
+
+ SSL_set_accept_state( s_ssl );
+ SSL_set_bio( s_ssl, slip2, slip2 );
+ BIO_set_ssl( s_bio, s_ssl, BIO_NOCLOSE );
+
+ char data[] = {1, 2, 3, 4, 5};
+ char data2[5];
+ ERR_load_SSL_strings();
+ ERR_load_crypto_strings();
+
+ int res = BIO_write( c_bio, data, 5 );
+ BOOST_CHECK_EQUAL( res, -1 );
+ res = BIO_read( s_bio, data2, sizeof( data2 ) );
+ BOOST_CHECK_EQUAL( res, -1 );
+
+ res = BIO_write( c_bio, data, 5 );
+ BOOST_CHECK_EQUAL( res, -1 );
+
+
+ res = BIO_read( s_bio, data2, sizeof( data2 ) );
+ BOOST_CHECK_EQUAL( res, -1 );
+ res = BIO_write( c_bio, data, 5 );
+ BOOST_CHECK_EQUAL( res, 5 );
+ res = BIO_read( s_bio, data2, sizeof( data2 ) );
+ BOOST_CHECK_EQUAL( res, 5 );
+ BOOST_CHECK_EQUAL_COLLECTIONS( data, data + 5, data2, data2 + 5 );
+}
+
BOOST_AUTO_TEST_SUITE_END()