OpenSSL support

svn path=/trunk/boinc/; revision=6886
This commit is contained in:
David Anderson 2005-08-01 22:44:40 +00:00
parent 6e87b15913
commit e652c96c1b
11 changed files with 202 additions and 43 deletions

View File

@ -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

View File

@ -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/

View File

@ -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);

View File

@ -25,9 +25,6 @@
#include <cctype>
#include <cstdio>
#include <cstdlib>
#if HAVE_MALLOC_H
#include <malloc.h>
#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$";

View File

@ -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 <cstdio>
#ifdef USE_RSAEURO
#include "rsaeuro.h"
extern "C" {
#include "rsa.h"
}
#endif
#ifdef USE_OPENSSL
#include <openssl/rsa.h>
#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

View File

@ -33,8 +33,7 @@
#include <cstdio>
#include <cstdlib>
#include "rsaeuro.h"
#include <cstring>
#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");
}

View File

@ -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*);

View File

@ -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("<run_benchmarks/>\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;

View File

@ -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();
}
}
}

View File

@ -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() {

View File

@ -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);