MKDIR = mkdir -p
-ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
- CFLAGS += -O0
-else
- CFLAGS += -O2
-endif
ifeq (,$(filter nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
BIN="bin/cassiopeia"
LIBS=openssl collissiondetect
-LT_CC=libtool --mode=compile gcc
-LT_CC_DEP=g++
-LT_CXX=libtool --mode=compile g++
-LT_CXX_DEP=g++
-LT_LD=libtool --mode=link g++
-
-CC=${LT_CC}
-CC_DEP=${LT_CC_DEP}
-CXX=${LT_CXX}
-CXX_DEP=${LT_CXX_DEP}
-LD=${LT_LD}
+CC=libtool --mode=compile gcc
+CC_DEP=g++
+CXX=libtool --mode=compile g++
+CXX_DEP=g++
+LD=libtool --mode=link g++
ifneq (,$(filter debug,$(DEB_BUILD_OPTIONS)))
-ADDFLAGS=-DNO_DAEMON
+CFLAGS+=-DNO_DAEMON -g
+endif
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
endif
-CFLAGS=-O3 -g -flto -Wall -Werror -Wextra -pedantic -std=c++11 ${ADDFLAGS}
+CFLAGS+=${ADDFLAGS} -Wall -Werror -Wextra -pedantic -std=c++11 -Ilib/openssl/include -Isrc
CXXFLAGS=$(CFLAGS)
-LDFLAGS=-O3 -g -flto -lmysqlclient -lssl -lcrypto -ldl
+LDFLAGS+=${ADDFLAGS} -L/usr/lib/i386-linux-gnu/ -lssl -lcrypto -ldl -Llib/openssl
SRC_DIR=src
OBJ_DIR=obj
DEP_DIR=dep
-FS_SRC=$(wildcard ${SRC_DIR}/*.cpp)
+FS_SRC=$(filter-out ${SRC_DIR}/mysql--disabled.cpp,$(wildcard ${SRC_DIR}/*.cpp))
FS_BIN=$(wildcard ${SRC_DIR}/app/*.cpp)
FS_LIBS=$(wildcard lib/*/)
FS_OBJ=$(FS_SRC:${SRC_DIR}/%.cpp=${OBJ_DIR}/%.lo)
-rm -rf ${DEP_DIR}
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
# Code to run the package test suite.
- ${MAKE} -C test clean
+ ADDFLAGS="$(ADDFLAGS)" DEB_BUILD_OPTIONS="$(DEB_BUILD_OPTIONS)" ${MAKE} -C test clean
endif
.PHONY: dist-clean
build: cassiopeia
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
- ${MAKE} -C test
+ ADDFLAGS="$(ADDFLAGS)" DEB_BUILD_OPTIONS="$(DEB_BUILD_OPTIONS)" ${MAKE} -C test
endif
.PHONY: install
# --------
-cassiopeia: bin/cassiopeia
+cassiopeia: bin/cassiopeia bin/cassiopeia-signer
+
+bin/cassiopeia: libs ${FS_OBJ} ${OBJ_DIR}/apps/client.lo
+ ${MKDIR} $(shell dirname $@) && ${LD} ${LDFLAGS} -lmysqlclient -o $@ ${FS_OBJ} ${OBJ_DIR}/apps/client.lo
-bin/cassiopeia: libs ${FS_OBJ}
- ${MKDIR} $(shell dirname $@) && ${LT_LD} ${LDFLAGS} -o $@ ${FS_OBJ}
+bin/cassiopeia-signer: libs ${FS_OBJ} ${OBJ_DIR}/apps/signer.lo
+ ${MKDIR} $(shell dirname $@) && ${LD} ${LDFLAGS} -o $@ $(filter-out ${OBJ_DIR}/mysql.lo,${FS_OBJ}) ${OBJ_DIR}/apps/signer.lo
${DEP_DIR}/%.d: ${SRC_DIR}/%.cpp
${MKDIR} $(shell dirname $@) && $(CXX_DEP) $(CXXFLAGS) -M -MF $@ $<
#include "slipBio.h"
#include "remoteSigner.h"
#include "sslUtil.h"
+#include "config.h"
#ifdef NO_DAEMON
#define DAEMON false
#define DAEMON true
#endif
-std::string keyDir;
-std::vector<Profile> profiles;
-std::string sqlHost, sqlUser, sqlPass, sqlDB;
+extern std::string keyDir;
+extern std::vector<Profile> profiles;
+extern std::string sqlHost, sqlUser, sqlPass, sqlDB;
std::string writeBackFile( uint32_t serial, std::string cert ) {
std::string filename = "keys";
return filename;
}
-int parseConfig() {
- std::ifstream config;
-
- if( DAEMON ) {
- config.open( "/etc/cacert/cassiopeia/cassiopeia.conf" );
- } else {
- config.open( "config.txt" );
- }
-
- if( !config.is_open() ) {
- std::cerr << "config missing" << std::endl;
- return 1;
- }
-
- std::string line1;
-
- while( config >> line1 ) {
- if( line1[0] == '#' ) {
- continue;
- }
-
- int splitter = line1.find( "=" );
-
- if( splitter == -1 ) {
- std::cerr << "Ignoring malformed config line: " << line1 << std::endl;
- continue;
- }
-
- std::string key = line1.substr( 0, splitter );
- std::string value = line1.substr( splitter + 1 );
-
- if( key == "key.directory" ) {
- keyDir = value;
- continue;
- } else if( key == "sql.host" ) {
- sqlHost = value;
- } else if( key == "sql.user" ) {
- sqlUser = value;
- } else if( key == "sql.password" ) {
- sqlPass = value;
- } else if( key == "sql.database" ) {
- sqlDB = value;
- }
-
- if( key.compare( 0, 8, "profile." ) == 0 ) {
- int numE = key.find( ".", 9 );
-
- if( numE == 0 ) {
- std::cout << "invalid line: " << line1 << std::endl;
- continue;
- }
-
- unsigned int i = atoi( key.substr( 8, numE - 8 ).c_str() );
- std::string rest = key.substr( numE + 1 );
-
- if( i + 1 > profiles.size() ) {
- profiles.resize( i + 1 );
- }
-
- if( rest == "key" ) {
- profiles[i].key = value;
- } else if( rest == "cert" ) {
- profiles[i].cert = value;
- } else {
- std::cout << "invalid line: " << line1 << std::endl;
- continue;
- }
- }
- }
-
- std::cout << profiles.size() << " profiles loaded." << std::endl;
-
- if( keyDir == "" ) {
- std::cerr << "Missing config property key.directory" << std::endl;
- return -1;
- }
-
- config.close();
-
- return 0;
-}
-
int handlermain( int argc, const char* argv[] );
int main( int argc, const char* argv[] ) {
once = true;
}
- if( parseConfig() != 0 ) {
+ std::string path;
+
+ if( DAEMON ) {
+ path = "/etc/cacert/cassiopeia/cassiopeia.conf";
+ } else {
+ path = "config.txt";
+ }
+
+ if( parseConfig( path ) != 0 ) {
return -1;
}
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <streambuf>
+
+#include "database.h"
+#include "mysql.h"
+#include "simpleOpensslSigner.h"
+#include "util.h"
+#include "bios.h"
+#include "slipBio.h"
+#include "remoteSigner.h"
+#include "sslUtil.h"
+#include "config.h"
+#include "recordHandler.h"
+
+#ifdef NO_DAEMON
+#define DAEMON false
+#else
+#define DAEMON true
+#endif
+
+int handlermain( int argc, const char* argv[] );
+
+int main( int argc, const char* argv[] ) {
+ ( void ) argc;
+ ( void ) argv;
+
+ std::string path;
+
+ if( DAEMON ) {
+ path = "/etc/cacert/cassiopeia/cassiopeia.conf";
+ } else {
+ path = "config.txt";
+ }
+
+
+ if( parseConfig( path ) != 0 ) {
+ return -1;
+ }
+
+ return handlermain( argc, argv );
+}
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <fstream>
+
+#include "sslUtil.h"
+
+std::string keyDir;
+std::vector<Profile> profiles;
+std::string sqlHost, sqlUser, sqlPass, sqlDB;
+
+int parseConfig( std::string path ) {
+ std::ifstream config;
+ config.open( path );
+
+ if( !config.is_open() ) {
+ std::cerr << "config missing" << std::endl;
+ return 1;
+ }
+
+ std::string line1;
+
+ while( std::getline( config, line1 ) ) {
+ if( line1[0] == '#' || line1.size() == 0 ) {
+ continue;
+ }
+
+ int splitter = line1.find( "=" );
+
+ if( splitter == -1 ) {
+ std::cerr << "Ignoring malformed config line: " << line1 << std::endl;
+ continue;
+ }
+
+ std::string key = line1.substr( 0, splitter );
+ std::string value = line1.substr( splitter + 1 );
+
+ if( key == "key.directory" ) {
+ keyDir = value;
+ continue;
+ } else if( key == "sql.host" ) {
+ sqlHost = value;
+ } else if( key == "sql.user" ) {
+ sqlUser = value;
+ } else if( key == "sql.password" ) {
+ sqlPass = value;
+ } else if( key == "sql.database" ) {
+ sqlDB = value;
+ }
+
+ if( key.compare( 0, 8, "profile." ) == 0 ) {
+ int numE = key.find( ".", 9 );
+
+ if( numE == 0 ) {
+ std::cout << "invalid line: " << line1 << std::endl;
+ continue;
+ }
+
+ unsigned int i = atoi( key.substr( 8, numE - 8 ).c_str() );
+ std::string rest = key.substr( numE + 1 );
+
+ if( i + 1 > profiles.size() ) {
+ profiles.resize( i + 1 );
+ }
+
+ if( rest == "key" ) {
+ profiles[i].key = value;
+ } else if( rest == "cert" ) {
+ profiles[i].cert = value;
+ } else if( rest == "ku" ) {
+ profiles[i].ku = value;
+ } else if( rest == "eku" ) {
+ profiles[i].eku = value;
+ } else {
+ std::cout << "invalid line: " << line1 << std::endl;
+ continue;
+ }
+ }
+ }
+
+ for( auto& prof : profiles ) {
+ if( prof.cert != "" && prof.key != "" ) {
+ std::cout << "Loading profile... " << std::endl;
+ prof.ca = loadX509FromFile( prof.cert );
+ prof.caKey = loadPkeyFromFile( prof.key );
+ }
+ }
+
+ std::cout << profiles.size() << " profiles loaded." << std::endl;
+
+ if( keyDir == "" ) {
+ std::cerr << "Missing config property key.directory" << std::endl;
+ return -1;
+ }
+
+ config.close();
+ return 0;
+}
--- /dev/null
+#pragma once
+
+#include <string>
+
+int parseConfig( std::string path );
#include <memory>
#include <vector>
-struct Profile {
- std::string cert;
- std::string key;
-};
-
struct Job {
std::string id;
std::string target;
#include "sslUtil.h"
#include "slipBio.h"
+extern std::vector<Profile> profiles;
+
class RecordHandlerSession {
public:
uint32_t sessid;
( ( SlipBIO* )slip1->ptr )->setTarget( std::shared_ptr<OpensslBIO>( new OpensslBIOWrapper( conn ) ) );
try {
- DefaultRecordHandler* dh = new DefaultRecordHandler( std::shared_ptr<Signer>( new SimpleOpensslSigner() ), slip1 );
+ DefaultRecordHandler* dh = new DefaultRecordHandler( std::shared_ptr<Signer>( new SimpleOpensslSigner( profiles[0] ) ), slip1 );
while( true ) {
dh->handle();
std::shared_ptr<int> SimpleOpensslSigner::lib_ref = ssl_lib_ref;
-std::shared_ptr<X509> loadX509FromFile( std::string filename ) {
- FILE* f = fopen( filename.c_str(), "r" );
-
- if( !f ) {
- return std::shared_ptr<X509>();
- }
-
- X509* key = PEM_read_X509( f, NULL, NULL, 0 );
- fclose( f );
-
- if( !key ) {
- return std::shared_ptr<X509>();
- }
-
- return std::shared_ptr<X509>(
- key,
- []( X509 * ref ) {
- X509_free( ref );
- } );
-}
-
-std::shared_ptr<EVP_PKEY> loadPkeyFromFile( std::string filename ) {
- FILE* f = fopen( filename.c_str(), "r" );
-
- if( !f ) {
- return std::shared_ptr<EVP_PKEY>();
- }
-
- EVP_PKEY* key = PEM_read_PrivateKey( f, NULL, NULL, 0 );
- fclose( f );
-
- if( !key ) {
- return std::shared_ptr<EVP_PKEY>();
- }
-
- return std::shared_ptr<EVP_PKEY>(
- key,
- []( EVP_PKEY * ref ) {
- EVP_PKEY_free( ref );
- } );
-}
-
-SimpleOpensslSigner::SimpleOpensslSigner() {
- caCert = loadX509FromFile( profiles[0].cert );
- caKey = loadPkeyFromFile( profiles[0].key );
+SimpleOpensslSigner::SimpleOpensslSigner( Profile& prof ) : prof( prof ) {
}
SimpleOpensslSigner::~SimpleOpensslSigner() {
}
std::shared_ptr<SignedCertificate> SimpleOpensslSigner::sign( std::shared_ptr<TBSCertificate> cert ) {
- if( !caKey ) {
+ if( !prof.ca ) {
throw "CA-key not found";
}
}
}
- c.setIssuerNameFrom( caCert );
+ c.setIssuerNameFrom( prof.ca );
c.setPubkeyFrom( req );
long int profile = strtol( cert->profile.c_str(), 0, 10 );
std::shared_ptr<BIGNUM> ser = nextSerial( profile );
c.setSerialNumber( ser.get() );
c.setTimes( 0, 60 * 60 * 24 * 10 );
- c.setExtensions( caCert, cert->SANs );
+ c.setExtensions( prof.ca, cert->SANs );
- std::shared_ptr<SignedCertificate> output = c.sign( caKey, cert->md );
+ std::shared_ptr<SignedCertificate> output = c.sign( prof.caKey, cert->md );
return output;
}
#include <openssl/ssl.h>
#include "database.h"
+#include "sslUtil.h"
#include "signer.h"
class SimpleOpensslSigner : public Signer {
private:
static std::shared_ptr<int> lib_ref;
- std::shared_ptr<EVP_PKEY> caKey;
- std::shared_ptr<X509> caCert;
+ Profile& prof;
std::shared_ptr<BIGNUM> nextSerial( uint16_t profile );
public:
- SimpleOpensslSigner();
+ SimpleOpensslSigner( Profile& prof );
~SimpleOpensslSigner();
std::shared_ptr<SignedCertificate> sign( std::shared_ptr<TBSCertificate> cert );
};
#include "slipBio.h"
-#include <iostream>
-
#include <unistd.h>
+#include <iostream>
+
#define BUFFER_SIZE 8192
char hexDigit( char c ) {
CRYPTO_cleanup_all_ex_data();
} );
+std::shared_ptr<X509> loadX509FromFile( std::string filename ) {
+ FILE* f = fopen( filename.c_str(), "r" );
+
+ if( !f ) {
+ return std::shared_ptr<X509>();
+ }
+
+ X509* key = PEM_read_X509( f, NULL, NULL, 0 );
+ fclose( f );
+
+ if( !key ) {
+ return std::shared_ptr<X509>();
+ }
+
+ return std::shared_ptr<X509>(
+ key,
+ []( X509 * ref ) {
+ X509_free( ref );
+ } );
+}
+
+std::shared_ptr<EVP_PKEY> loadPkeyFromFile( std::string filename ) {
+ FILE* f = fopen( filename.c_str(), "r" );
+
+ if( !f ) {
+ return std::shared_ptr<EVP_PKEY>();
+ }
+
+ EVP_PKEY* key = PEM_read_PrivateKey( f, NULL, NULL, 0 );
+ fclose( f );
+
+ if( !key ) {
+ return std::shared_ptr<EVP_PKEY>();
+ }
+
+ return std::shared_ptr<EVP_PKEY>(
+ key,
+ []( EVP_PKEY * ref ) {
+ EVP_PKEY_free( ref );
+ } );
+}
+
int gencb( int a, int b, BN_GENCB* g ) {
( void ) a;
( void ) b;
throw "failed to get attrs";
}
- attr.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
- | INLCR | IGNCR | ICRNL | IXON );
+ attr.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON );
attr.c_oflag &= ~OPOST;
attr.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
attr.c_cflag &= ~( CSIZE | PARENB );
#include <openssl/ssl.h>
#include <memory>
+struct Profile {
+ std::string cert;
+ std::string key;
+ std::string eku;
+ std::string ku;
+
+ std::shared_ptr<X509> ca;
+ std::shared_ptr<EVP_PKEY> caKey;
+};
+
extern std::shared_ptr<int> ssl_lib_ref;
+std::shared_ptr<X509> loadX509FromFile( std::string filename );
+std::shared_ptr<EVP_PKEY> loadPkeyFromFile( std::string filename );
+
std::shared_ptr<SSL_CTX> generateSSLContext( bool server );
std::shared_ptr<BIO> openSerial( const char* name );
BIN="bin/cassiopeia-test"
LIBS=openssl collissiondetect
-LT_CC=libtool --mode=compile gcc
-LT_CC_DEP=g++
-LT_CXX=libtool --mode=compile g++
-LT_CXX_DEP=g++
-LT_LD=libtool --mode=link g++
-
-CC=${LT_CC}
-CC_DEP=${LT_CC_DEP}
-CXX=${LT_CXX}
-CXX_DEP=${LT_CXX_DEP}
-LD=${LT_LD}
+CC=libtool --mode=compile gcc
+CC_DEP=g++
+CXX=libtool --mode=compile g++
+CXX_DEP=g++
+LD=libtool --mode=link g++
ifneq (,$(filter debug,$(DEB_BUILD_OPTIONS)))
-ADDFLAGS=-DNO_DAEMON
+CFLAGS+=-DNO_DAEMON -g
endif
-CFLAGS=-O3 -g -flto -Wall -Werror -Wextra -pedantic -std=c++11 -I../src ${ADDFLAGS}
+CFLAGS+=${ADDFLAGS} -Wall -Werror -Wextra -pedantic -std=c++11 -I../src -I../lib/openssl/include
CXXFLAGS=$(CFLAGS)
-LDFLAGS=-O3 -g -flto -lmysqlclient -lssl -lcrypto -ldl -lboost_unit_test_framework
+LDFLAGS+=${ADDFLAGS} -lmysqlclient -lssl -lcrypto -ldl -lboost_unit_test_framework -L../lib/openssl -L/usr/lib/i386-linux-gnu
SRC_DIR=src
OBJ_DIR=obj
cassiopeia-test: bin/cassiopeia-test
bin/cassiopeia-test: libs ${FS_OBJ}
- ${MKDIR} $(shell dirname $@) && ${LT_LD} ${LDFLAGS} -o $@ ${FS_OBJ} $(filter-out %/main.o,$(wildcard ../obj/*.o))
+ ${MKDIR} $(shell dirname $@) && ${LD} ${LDFLAGS} -o $@ ${FS_OBJ} $(filter-out %/main.o,$(wildcard ../obj/*.o))
${DEP_DIR}/%.d: ${SRC_DIR}/%.cpp
${MKDIR} $(shell dirname $@) && $(CXX_DEP) $(CXXFLAGS) -M -MF $@ $<
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Cassiopeia
-#include <vector>
-
#include <boost/test/unit_test.hpp>
-
-#include "database.h"
-
-std::vector<Profile> profiles;