- Add support for code-signing using x509 certificates

(from Attila Marosi)


svn path=/trunk/boinc/; revision=15958
This commit is contained in:
David Anderson 2008-09-04 12:50:54 +00:00
parent f6b1ae85b9
commit 096337a241
9 changed files with 65 additions and 62 deletions

View File

@ -7170,3 +7170,16 @@ David 4 Sep 2008
sched/
handle_request.C
sched_config.C,h
David 4 Sep 2008
- Add support for code-signing using x509 certificates
(from Attila Marosi)
client/
client_types.C,h
cs_files.C
log_flags.C,h
lib/
Makefile.am
cert_sig.C,h (new)
crypt.C,h

View File

@ -636,7 +636,7 @@ FILE_INFO::FILE_INFO() {
strcpy(signed_xml, "");
strcpy(xml_signature, "");
strcpy(file_signature, "");
certificates = 0;
cert_sigs = 0;
}
FILE_INFO::~FILE_INFO() {
@ -747,7 +747,7 @@ int FILE_INFO::parse(MIOFILE& in, bool from_server) {
continue;
}
if (match_tag(buf, "<signatures>")) {
if (!certificates->parse_miofile_embed(in)) {
if (!cert_sigs->parse_miofile_embed(in)) {
msg_printf(0, MSG_INTERNAL_ERROR,
"FILE_INFO::parse(): cannot parse <signatures>\n");
return ERR_XML_PARSE;

View File

@ -31,7 +31,7 @@
#endif
#include "md5_file.h"
#include "certificate.h"
#include "cert_sig.h"
#include "hostinfo.h"
#include "coproc.h"
#include "miofile.h"
@ -95,7 +95,7 @@ public:
// this is the signature
std::string error_msg; // if permanent error occurs during file xfer,
// it's recorded here
CERTIFICATES* certificates;
CERT_SIGS* cert_sigs;
FILE_INFO();
~FILE_INFO();

View File

@ -36,7 +36,7 @@
#include "crypt.h"
#include "str_util.h"
#include "filesys.h"
#include "certificate.h"
#include "cert_sig.h"
#include "error_numbers.h"
#include "file_names.h"
@ -92,15 +92,15 @@ int CLIENT_STATE::make_project_dirs() {
// Is app signed by one of the Application Certifiers?
//
bool FILE_INFO::verify_file_certs() {
string file;
char file[256];
bool retval = false;
if (!is_dir(CERTIFICATE_DIRECTORY)) return false;
DIRREF dir = dir_open(CERTIFICATE_DIRECTORY);
while (dir_scan(file, dir)) {
if (cert_verify_file(certificates, file.c_str(), CERTIFICATE_DIRECTORY)) {
while (dir_scan(file, dir, sizeof(dir))) {
if (cert_verify_file(cert_sigs, file, CERTIFICATE_DIRECTORY)) {
msg_printf(project, MSG_INFO,
"Signature verified using certificate %s", file.c_str()
"Signature verified using certificate %s", file
);
retval = true;
break;
@ -159,7 +159,7 @@ int FILE_INFO::verify_file(bool strict, bool show_errors) {
if (!strict) return 0;
if (signature_required) {
if (!strlen(file_signature) && !certificates) {
if (!strlen(file_signature) && !cert_sigs) {
msg_printf(project, MSG_INTERNAL_ERROR,
"Application file %s missing signature", name
);

View File

@ -56,7 +56,7 @@ endif
libboinc_a_SOURCES = \
app_ipc.C \
base64.C \
certificate.C \
cert_sig.C \
coproc.C \
crypt.C \
diagnostics.C \

View File

@ -21,40 +21,40 @@
#include <stdbool.h>
#include "miofile.h"
#include "error_numbers.h"
#include "certificate.h"
#include "cert_sig.h"
CERTIFICATE::CERTIFICATE() {
CERT_SIG::CERT_SIG() {
this->clear();
}
CERTIFICATE::~CERTIFICATE() {
CERT_SIG::~CERT_SIG() {
// TODO
}
void CERTIFICATE::clear() {
void CERT_SIG::clear() {
this->type = MD5_HASH; // md5 hash by default
memset(this->subject, 0, sizeof(this->subject));
memset(this->signature, 0, sizeof(this->signature));
}
CERTIFICATES::CERTIFICATES() {
CERT_SIGS::CERT_SIGS() {
// TODO
}
CERTIFICATES::~CERTIFICATES() {
CERT_SIGS::~CERT_SIGS() {
// TODO
}
void CERTIFICATES::clear() {
void CERT_SIGS::clear() {
this->signatures.clear();
}
int CERTIFICATES::count() {
int CERT_SIGS::count() {
return this->signatures.size();
}
int CERTIFICATES::parse(XML_PARSER &xp) {
CERTIFICATE sig;
int CERT_SIGS::parse(XML_PARSER &xp) {
CERT_SIG sig;
int is_tag = false;
int in_entry = false;
int in_sig = false;
@ -62,12 +62,12 @@ int CERTIFICATES::parse(XML_PARSER &xp) {
char tag[4096];
char buf[256];
//printf("CERTIFICATES::parse() starts.\n");
//printf("CERT_SIGS::parse() starts.\n");
//fflush(stdout);
while (!xp.get(tag, sizeof(tag), (bool&)is_tag)) {
if (!strcmp(tag, "/signatures")) {
//printf("CERTIFICATES::parse() ends.\n");
//printf("CERT_SIGS::parse() ends.\n");
//fflush(stdout);
return !in_entry && !in_sig && parsed_one;
}
@ -77,7 +77,7 @@ int CERTIFICATES::parse(XML_PARSER &xp) {
continue;
}
if (!is_tag) {
printf("(CERTIFICATES): unexpected text: %s\n", tag);
printf("(CERT_SIGS): unexpected text: %s\n", tag);
continue;
}
if (in_entry) {
@ -128,12 +128,12 @@ int CERTIFICATES::parse(XML_PARSER &xp) {
return false;
}
int CERTIFICATES::parse_miofile_embed(MIOFILE &mf) {
int CERT_SIGS::parse_miofile_embed(MIOFILE &mf) {
XML_PARSER xp(&mf);
return this->parse(xp);
}
int CERTIFICATES::parse_file(const char* filename) {
int CERT_SIGS::parse_file(const char* filename) {
FILE* f;
int retval;
@ -151,7 +151,7 @@ int CERTIFICATES::parse_file(const char* filename) {
return retval;
}
int CERTIFICATES::parse_buffer(char* buf) {
int CERT_SIGS::parse_buffer(char* buf) {
MIOFILE mf;
int retval;
@ -161,7 +161,7 @@ int CERTIFICATES::parse_buffer(char* buf) {
return retval;
}
int CERTIFICATES::parse_buffer_embed(char* buf) {
int CERT_SIGS::parse_buffer_embed(char* buf) {
MIOFILE mf;
char tag[4096];
int is_tag;
@ -181,16 +181,7 @@ int CERTIFICATES::parse_buffer_embed(char* buf) {
return false;
}
void CERTIFICATES::dump() {
MIOFILE m;
char buf[4096];
m.init_buf_write((char *)buf, 4096);
this->write(m, 4096);
printf("%s", buf);
}
int CERTIFICATES::write(MIOFILE &f) {
int CERT_SIGS::write(MIOFILE &f) {
if (this->signatures.size()==0)
return true;
f.printf("<signatures>\n");

View File

@ -41,9 +41,9 @@ struct CERT_SIG {
class CERT_SIGS {
public:
std::vector<CERT_SIG> cert_sigs;
CERT_SIG();
~CERT_SIG();
std::vector<CERT_SIG> signatures;
CERT_SIGS();
~CERT_SIGS();
//
// Parses an .xml signature file with the following structure:
//
@ -64,12 +64,10 @@ public:
int parse_file(const char* filename);
int parse_buffer(char* buf);
int write(MIOFILE &f);
int write(MIOFILE &f, int max);
// Parses from an already opened MIOFILE, the pointer should have
// passed the opening <signatures> tag (no check is done for that).
int parse_miofile_embed(MIOFILE &mf);
int parse_buffer_embed(char* buf);
void dump();
void clear();
int count(); // return the total number of signatures.
private:

View File

@ -25,9 +25,23 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#include <openssl/ssl.h>
#include <openssl/md5.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include "md5_file.h"
#include "cert_sig.h"
#include "error_numbers.h"
#include "crypt.h"
@ -491,7 +505,9 @@ int check_validity_of_cert(const char *cFile, const unsigned char *md5_md, unsig
return retval;
}
int cert_verify_file(SIGNATURES* signatures, const char* origFile, char* trustLocation) {
int cert_verify_file(
CERT_SIGS* signatures, const char* origFile, char* trustLocation
) {
MD5_CTX md5CTX;
int of, rbytes;
struct stat ostat;

View File

@ -22,24 +22,9 @@
// We use our own data structures (R_RSA_PUBLIC_KEY and R_RSA_PRIVATE_KEY)
// to store keys in either case.
// Only define these here if they haven't been defined elsewhere
#if !(defined(USE_OPENSSL) || defined(USE_RSAEURO))
#define USE_OPENSSL 1
//#define USE_RSAEURO 1
#endif
#include <stdio.h>
#include <string.h>
#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
@ -72,8 +57,6 @@ extern void openssl_to_keys(
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];
@ -138,7 +121,9 @@ extern int check_validity_of_cert(
unsigned char *sfileMsg, const int sfsize, char* caPath
);
class CERT_SIGS;
int cert_verify_file(
SIGNATURES* signatures, const char* origFile, char* trustLocation
CERT_SIGS* signatures, const char* origFile, char* trustLocation
);
#endif