diff --git a/checkin_notes b/checkin_notes index 3be160667b..253f12835b 100755 --- a/checkin_notes +++ b/checkin_notes @@ -9744,3 +9744,19 @@ David 31 July 2005 boinccmd.vcproj boincmgr.vcproj +David 1 Aug 2005 + - support OpenSSL's crypto libary, preparatory to getting rid of RSAEuro. + For now, there's a #define in lib/crypt.h + that lets you select one or the other. + OpenSSL seems to be working, i.e. you can read keys + and verify file signatures produces with RSAEuro. + + lib/ + Makefile.am + boinc_cmd.C + crypt.C,h + crypt_prog.C + gui_rpc_client.h + gui_rpc_client_ops.C + gui_rpc_client_print.C + hostinfo.C,h diff --git a/lib/Makefile.am b/lib/Makefile.am index 5c05fa89a5..28d82b468f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -11,8 +11,8 @@ bin_PROGRAMS = crypt_prog $(nslprogs) EXTRA_PROGRAMS = md5_test shmem_test msg_test boinc_cmd_SOURCES = \ - boinc_cmd.C \ - gui_rpc_client.h + boinc_cmd.C \ + gui_rpc_client.h boinc_cmd_LDADD = $(lib_LIBRARIES) $(PTHREAD_LIBS) @@ -27,9 +27,9 @@ libboinc_a_SOURCES = \ diagnostics.C \ exception.C \ filesys.C \ - gui_rpc_client.C \ - gui_rpc_client_ops.C \ - gui_rpc_client_print.C \ + gui_rpc_client.C \ + gui_rpc_client_ops.C \ + gui_rpc_client_print.C \ hostinfo.C \ language.C \ md5.c \ @@ -46,18 +46,18 @@ libboinc_a_SOURCES = \ util.C include_HEADERS = \ - app_ipc.h \ - boinc_win.h \ - diagnostics.h \ - exception.h \ - filesys.h \ - hostinfo.h \ - mfile.h \ - miofile.h \ - parse.h \ - prefs.h \ - proxy_info.h \ - util.h + app_ipc.h \ + boinc_win.h \ + diagnostics.h \ + exception.h \ + filesys.h \ + hostinfo.h \ + mfile.h \ + miofile.h \ + parse.h \ + prefs.h \ + proxy_info.h \ + util.h ## install header-files with prefix-subdir BOINC/ to avoid name-conflicts includedir = ${prefix}/include/BOINC/ diff --git a/lib/boinc_cmd.C b/lib/boinc_cmd.C index 97ed8efd9f..6a725e9b31 100644 --- a/lib/boinc_cmd.C +++ b/lib/boinc_cmd.C @@ -294,11 +294,11 @@ int main(int argc, char** argv) { fprintf(stderr, "Unknown op %s\n", op); } } else if (!strcmp(cmd, "--get_proxy_settings")) { - PROXY_INFO pi; + GR_PROXY_INFO pi; retval = rpc.get_proxy_settings(pi); if (!retval) pi.print(); } else if (!strcmp(cmd, "--set_proxy_settings")) { - PROXY_INFO pi; + GR_PROXY_INFO pi; pi.http_server_name = next_arg(argc, argv, i); pi.http_server_port = atoi(next_arg(argc, argv, i)); pi.http_user_name = next_arg(argc, argv, i); diff --git a/lib/crypt.C b/lib/crypt.C index c84db8df13..eb565b8c24 100644 --- a/lib/crypt.C +++ b/lib/crypt.C @@ -25,9 +25,6 @@ #include #include #include -#if HAVE_MALLOC_H -#include -#endif #endif #include "md5_file.h" @@ -224,14 +221,33 @@ int encrypt_private( if (n >= modulus_len-11) { n = modulus_len-11; } +#ifdef USE_RSAEURO retval = RSAPrivateEncrypt(out.data, &out.len, in.data, n, &key); if (retval ) return retval; nbytes_encrypted = retval; +#endif +#ifdef USE_OPENSSL + RSA* rp = RSA_new(); + private_to_openssl(key, rp); + RSA_private_encrypt(n, in.data, out.data, rp, RSA_PKCS1_PADDING); + out.len = RSA_size(rp); + RSA_free(rp); +#endif + return 0; } int decrypt_public(R_RSA_PUBLIC_KEY& key, DATA_BLOCK& in, DATA_BLOCK& out) { +#ifdef USE_RSAEURO return RSAPublicDecrypt(out.data, &out.len, in.data, in.len, &key); +#endif +#ifdef USE_OPENSSL + RSA* rp = RSA_new(); + public_to_openssl(key, rp); + RSA_public_decrypt(in.len, in.data, out.data, rp, RSA_PKCS1_PADDING); + out.len = RSA_size(rp); + return 0; +#endif } int sign_file(const char* path, R_RSA_PRIVATE_KEY& key, DATA_BLOCK& signature) { @@ -365,4 +381,50 @@ int read_key_file(const char* keyfile, R_RSA_PRIVATE_KEY& key) { return 0; } +#ifdef USE_OPENSSL + +static void bn_to_bin(BIGNUM* bn, unsigned char* bin, int n) { + memset(bin, 0, n); + int m = BN_num_bytes(bn); + BN_bn2bin(bn, bin+n-m); +} + +void openssl_to_keys( + RSA* rp, int nbits, R_RSA_PRIVATE_KEY& priv, R_RSA_PUBLIC_KEY& pub +) { + unsigned char buf[256]; + + pub.bits = nbits; + bn_to_bin(rp->n, pub.modulus, sizeof(pub.modulus)); + bn_to_bin(rp->e, pub.exponent, sizeof(pub.exponent)); + + memset(&priv, 0, sizeof(priv)); + priv.bits = nbits; + bn_to_bin(rp->n, priv.modulus, sizeof(priv.modulus)); + bn_to_bin(rp->e, priv.publicExponent, sizeof(priv.publicExponent)); + bn_to_bin(rp->d, priv.exponent, sizeof(priv.exponent)); + bn_to_bin(rp->p, priv.prime[0], sizeof(priv.prime[0])); + bn_to_bin(rp->q, priv.prime[1], sizeof(priv.prime[1])); + bn_to_bin(rp->dmp1, priv.primeExponent[0], sizeof(priv.primeExponent[0])); + bn_to_bin(rp->dmq1, priv.primeExponent[1], sizeof(priv.primeExponent[1])); + bn_to_bin(rp->iqmp, priv.coefficient, sizeof(priv.coefficient)); +} + +void private_to_openssl(R_RSA_PRIVATE_KEY& priv, RSA* rp) { + rp->n = BN_bin2bn(priv.modulus, sizeof(priv.modulus), 0); + rp->e = BN_bin2bn(priv.publicExponent, sizeof(priv.publicExponent), 0); + rp->d = BN_bin2bn(priv.exponent, sizeof(priv.exponent), 0); + rp->p = BN_bin2bn(priv.prime[0], sizeof(priv.prime[0]), 0); + rp->q = BN_bin2bn(priv.prime[1], sizeof(priv.prime[1]), 0); + rp->dmp1 = BN_bin2bn(priv.primeExponent[0], sizeof(priv.primeExponent[0]), 0); + rp->dmq1 = BN_bin2bn(priv.primeExponent[1], sizeof(priv.primeExponent[1]), 0); + rp->iqmp = BN_bin2bn(priv.coefficient, sizeof(priv.coefficient), 0); +} + +void public_to_openssl(R_RSA_PUBLIC_KEY& pub, RSA* rp) { + rp->n = BN_bin2bn(pub.modulus, sizeof(pub.modulus), 0); + rp->e = BN_bin2bn(pub.exponent, sizeof(pub.exponent), 0); +} + +#endif const char *BOINC_RCSID_4f0c2e42ea = "$Id$"; diff --git a/lib/crypt.h b/lib/crypt.h index cb706d9c5b..bacd979abf 100644 --- a/lib/crypt.h +++ b/lib/crypt.h @@ -19,15 +19,59 @@ #ifndef H_CRYPT #define H_CRYPT -// some interface functions for RSAEuro + +// We're set up to use either RSAEuro or the OpenSSL crypto library. +// We use our own data structures (R_RSA_PUBLIC_KEY and R_RSA_PRIVATE_KEY) +// to store keys in either case. + +//#define USE_OPENSSL 1 +#define USE_RSAEURO 1 #include +#ifdef USE_RSAEURO #include "rsaeuro.h" extern "C" { #include "rsa.h" } +#endif + +#ifdef USE_OPENSSL +#include + +#define MAX_RSA_MODULUS_BITS 1024 +#define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8) +#define MAX_RSA_PRIME_BITS ((MAX_RSA_MODULUS_BITS + 1) / 2) +#define MAX_RSA_PRIME_LEN ((MAX_RSA_PRIME_BITS + 7) / 8) + +typedef struct { + unsigned short int bits; /* length in bits of modulus */ + unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ + unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ +} R_RSA_PUBLIC_KEY; + +typedef struct { + unsigned short int bits; /* length in bits of modulus */ + unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ + unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ + unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ + unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ + unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; /* exponents for CRT */ + unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ +} R_RSA_PRIVATE_KEY; + +// functions to convert between OpenSSL's keys (using BIGNUMs) +// and our binary format + +extern void openssl_to_keys( + RSA* rp, int nbits, R_RSA_PRIVATE_KEY& priv, R_RSA_PUBLIC_KEY& pub +); +extern void private_to_openssl(R_RSA_PRIVATE_KEY& priv, RSA* rp); +extern void public_to_openssl(R_RSA_PUBLIC_KEY& pub, RSA* rp); + +#endif + struct KEY { unsigned short int bits; unsigned char data[1]; @@ -53,6 +97,7 @@ int scan_hex_data(FILE* f, DATA_BLOCK&); int print_key_hex(FILE*, KEY* key, int len); int scan_key_hex(FILE*, KEY* key, int len); int sscan_key_hex(const char*, KEY* key, int len); + int encrypt_private( R_RSA_PRIVATE_KEY& key, DATA_BLOCK& in, DATA_BLOCK& out, int& ); @@ -71,7 +116,6 @@ int verify_string( int verify_string2( const char* text, const char* signature, const char* key, bool& ); - int read_key_file(const char* keyfile, R_RSA_PRIVATE_KEY& key); #endif diff --git a/lib/crypt_prog.C b/lib/crypt_prog.C index fbe923cbb8..75700540f2 100644 --- a/lib/crypt_prog.C +++ b/lib/crypt_prog.C @@ -33,8 +33,7 @@ #include #include - -#include "rsaeuro.h" +#include #include "crypt.h" @@ -43,6 +42,7 @@ void die(const char* p) { exit(1); } +#ifdef USE_RSAEURO void better_random_create(R_RANDOM_STRUCT* r) { #ifdef __WINDOWS__ // in case we ever need this on Win @@ -77,12 +77,26 @@ void better_random_create(R_RANDOM_STRUCT* r) { r->bytesNeeded = 0; r->outputAvailable = 16; } +#endif + +unsigned int random_int() { + unsigned int n; + FILE* f = fopen("/dev/random", "r"); + if (!f) { + fprintf(stderr, "can't open /dev/random\n"); + exit(1); + } + fread(&n, sizeof(n), 1, f); + return n; +} int main(int argc, char** argv) { - R_RANDOM_STRUCT randomStruct; R_RSA_PUBLIC_KEY public_key; R_RSA_PRIVATE_KEY private_key; +#ifdef USE_RSAEURO + R_RANDOM_STRUCT randomStruct; R_RSA_PROTO_KEY protoKey; +#endif int n, retval; bool is_valid; DATA_BLOCK signature, in, out; @@ -94,11 +108,14 @@ int main(int argc, char** argv) { exit(1); } if (!strcmp(argv[1], "-genkey")) { + if (argc < 5) { + fprintf(stderr, "missing cmdline args\n"); + exit(1); + } printf("creating keys in %s and %s\n", argv[3], argv[4]); n = atoi(argv[2]); - //R_RandomCreate(&randomStruct); - +#ifdef USE_RSAEURO better_random_create(&randomStruct); protoKey.bits = n; @@ -107,13 +124,19 @@ int main(int argc, char** argv) { &public_key, &private_key, &protoKey, &randomStruct ); if (retval) die("R_GeneratePEMKeys\n"); - +#endif +#ifdef USE_OPENSSL + srand(random_int()); + RSA* rp = RSA_generate_key(n, 65537, 0, 0); + openssl_to_keys(rp, n, private_key, public_key); +#endif fpriv = fopen(argv[3], "w"); if (!fpriv) die("fopen"); fpub = fopen(argv[4], "w"); if (!fpub) die("fopen"); print_key_hex(fpriv, (KEY*)&private_key, sizeof(private_key)); print_key_hex(fpub, (KEY*)&public_key, sizeof(public_key)); + } else if (!strcmp(argv[1], "-sign")) { fpriv = fopen(argv[3], "r"); if (!fpriv) die("fopen"); @@ -153,6 +176,7 @@ int main(int argc, char** argv) { in = out; out.data = buf2; decrypt_public(public_key, in, out); + printf("out: %s\n", out.data); } else { printf("unrecognized command\n"); } diff --git a/lib/gui_rpc_client.h b/lib/gui_rpc_client.h index f0f30e46e2..bb319f4168 100644 --- a/lib/gui_rpc_client.h +++ b/lib/gui_rpc_client.h @@ -32,6 +32,7 @@ #include "miofile.h" #include "prefs.h" +#include "hostinfo.h" #define GUI_RPC_PORT 1043 #define GUI_RPC_PORT_ALT 31416 @@ -268,7 +269,7 @@ public: void clear(); }; -class PROXY_INFO { +class GR_PROXY_INFO { public: bool use_http_proxy; bool use_socks_proxy; @@ -283,14 +284,15 @@ public: std::string socks5_user_name; std::string socks5_user_passwd; - PROXY_INFO(); - ~PROXY_INFO(); + GR_PROXY_INFO(); + ~GR_PROXY_INFO(); int parse(MIOFILE&); void print(); void clear(); }; +#if 0 struct HOST_INFO { int timezone; // local STANDARD time - UTC time (in seconds) char domain_name[256]; @@ -325,6 +327,7 @@ struct HOST_INFO { void print(); void clear(); }; +#endif class CC_STATE { public: @@ -488,8 +491,8 @@ public: bool enabled, double blank_time, DISPLAY_INFO& ); int run_benchmarks(); - int set_proxy_settings(PROXY_INFO&); - int get_proxy_settings(PROXY_INFO&); + int set_proxy_settings(GR_PROXY_INFO&); + int get_proxy_settings(GR_PROXY_INFO&); int get_messages(int seqno, MESSAGES&); int file_transfer_op(FILE_TRANSFER&, const char*); int result_op(RESULT&, const char*); diff --git a/lib/gui_rpc_client_ops.C b/lib/gui_rpc_client_ops.C index 088ffab048..a077e119a9 100644 --- a/lib/gui_rpc_client_ops.C +++ b/lib/gui_rpc_client_ops.C @@ -440,15 +440,15 @@ void MESSAGE::clear() { body.clear(); } -PROXY_INFO::PROXY_INFO() { +GR_PROXY_INFO::GR_PROXY_INFO() { clear(); } -PROXY_INFO::~PROXY_INFO() { +GR_PROXY_INFO::~GR_PROXY_INFO() { clear(); } -int PROXY_INFO::parse(MIOFILE& in) { +int GR_PROXY_INFO::parse(MIOFILE& in) { char buf[4096]; use_http_proxy = false; use_socks_proxy = false; @@ -480,7 +480,7 @@ int PROXY_INFO::parse(MIOFILE& in) { return ERR_XML_PARSE; } -void PROXY_INFO::clear() { +void GR_PROXY_INFO::clear() { use_http_proxy = false; use_socks_proxy = false; use_http_authentication = false; @@ -495,6 +495,7 @@ void PROXY_INFO::clear() { socks5_user_passwd.clear(); } +#if 0 HOST_INFO::HOST_INFO() { clear(); } @@ -568,6 +569,8 @@ void HOST_INFO::clear() { d_free = 0.0; } +#endif + CC_STATE::CC_STATE() { clear(); } @@ -1216,7 +1219,7 @@ int RPC_CLIENT::run_benchmarks() { return rpc.do_rpc("\n"); } -int RPC_CLIENT::set_proxy_settings(PROXY_INFO& pi) { +int RPC_CLIENT::set_proxy_settings(GR_PROXY_INFO& pi) { char buf[1024]; RPC rpc(this); @@ -1250,7 +1253,7 @@ int RPC_CLIENT::set_proxy_settings(PROXY_INFO& pi) { return rpc.do_rpc(buf); } -int RPC_CLIENT::get_proxy_settings(PROXY_INFO& p) { +int RPC_CLIENT::get_proxy_settings(GR_PROXY_INFO& p) { RPC rpc(this); int retval; diff --git a/lib/gui_rpc_client_print.C b/lib/gui_rpc_client_print.C index 8b0f787911..4ff005e578 100644 --- a/lib/gui_rpc_client_print.C +++ b/lib/gui_rpc_client_print.C @@ -145,7 +145,7 @@ void MESSAGE::print() { ); } -void PROXY_INFO::print() { // anyone need this? +void GR_PROXY_INFO::print() { // anyone need this? } void HOST_INFO::print() { @@ -230,4 +230,5 @@ void MESSAGES::print() { printf("%d) -----------\n", i+1); messages[i]->print(); } -} \ No newline at end of file +} + diff --git a/lib/hostinfo.C b/lib/hostinfo.C index b088d08574..0de2fbf1e1 100644 --- a/lib/hostinfo.C +++ b/lib/hostinfo.C @@ -37,6 +37,10 @@ #include "hostinfo.h" +HOST_INFO::HOST_INFO() { + clear_host_info(); +} + // Reset the host info struct to default values // void HOST_INFO::clear_host_info() { diff --git a/lib/hostinfo.h b/lib/hostinfo.h index 1b40fba5b6..9bf9e21508 100644 --- a/lib/hostinfo.h +++ b/lib/hostinfo.h @@ -58,10 +58,12 @@ struct HOST_INFO { double d_total; // Total amount of diskspace in bytes double d_free; // Total amount of available diskspace in bytes + HOST_INFO(); int parse(MIOFILE&); int write(MIOFILE&); int parse_cpu_benchmarks(FILE*); int write_cpu_benchmarks(FILE*); + void print(); bool host_is_running_on_batteries(); bool users_idle(bool check_all_logins, double idle_time_to_run);