Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Refactor the signing repository code so that the key is being asked only once
Baptiste Daroussin committed 12 years ago
commit 95de71757f3c197fdc5a63e3264f77e17175d226
parent 56ffb8d
3 files changed +76 -47
modified libpkg/pkg_repo.c
@@ -505,8 +505,7 @@ read_pkg_file(void *data)
}

static int
-
pack_db(const char *name, const char *archive, char *path,
-
    char *rsa_key_path, pem_password_cb *password_cb)
+
pack_db(const char *name, const char *archive, char *path, struct rsa_key *rsa)
{
	struct packing *pack;
	unsigned char *sigret = NULL;
@@ -515,8 +514,8 @@ pack_db(const char *name, const char *archive, char *path,
	if (packing_init(&pack, archive, TXZ) != EPKG_OK)
		return (EPKG_FATAL);

-
	if (rsa_key_path != NULL) {
-
		if (rsa_sign(path, password_cb, rsa_key_path, &sigret, &siglen) != EPKG_OK) {
+
	if (rsa != NULL) {
+
		if (rsa_sign(path, rsa, &sigret, &siglen) != EPKG_OK) {
			packing_finish(pack);
			return (EPKG_FATAL);
		}
@@ -541,6 +540,7 @@ pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path, bo
{
	char repo_path[MAXPATHLEN + 1];
	char repo_archive[MAXPATHLEN + 1];
+
	struct rsa_key *rsa = NULL;
	struct stat st;
	
	if (!is_dir(path)) {
@@ -548,30 +548,29 @@ pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path, bo
	    return (EPKG_FATAL);
	}

+
	if (rsa_key_path != NULL)
+
		rsa_new(&rsa, password_cb, rsa_key_path);
+

	snprintf(repo_path, sizeof(repo_path), "%s/%s", path, repo_packagesite_file);
	snprintf(repo_archive, sizeof(repo_archive), "%s/%s", path, repo_packagesite_archive);
-
	if (pack_db(repo_packagesite_file, repo_archive, repo_path,
-
			rsa_key_path, password_cb) != EPKG_OK)
+
	if (pack_db(repo_packagesite_file, repo_archive, repo_path, rsa) != EPKG_OK)
		return (EPKG_FATAL);

	snprintf(repo_path, sizeof(repo_path), "%s/%s", path, repo_db_file);
	snprintf(repo_archive, sizeof(repo_archive), "%s/%s", path, repo_db_archive);
-
	if (pack_db(repo_db_file, repo_archive, repo_path,
-
			rsa_key_path, password_cb) != EPKG_OK)
+
	if (pack_db(repo_db_file, repo_archive, repo_path, rsa) != EPKG_OK)
		return (EPKG_FATAL);

	if (filelist) {
		snprintf(repo_path, sizeof(repo_path), "%s/%s", path, repo_filesite_file);
		snprintf(repo_archive, sizeof(repo_archive), "%s/%s", path, repo_filesite_archive);
-
		if (pack_db(repo_filesite_file, repo_archive, repo_path,
-
				rsa_key_path, password_cb) != EPKG_OK)
+
		if (pack_db(repo_filesite_file, repo_archive, repo_path, rsa) != EPKG_OK)
			return (EPKG_FATAL);
	}

	snprintf(repo_path, sizeof(repo_path), "%s/%s", path, repo_digests_file);
	snprintf(repo_archive, sizeof(repo_archive), "%s/%s", path, repo_digests_archive);
-
	if (pack_db(repo_digests_file, repo_archive, repo_path,
-
			rsa_key_path, password_cb) != EPKG_OK)
+
	if (pack_db(repo_digests_file, repo_archive, repo_path, rsa) != EPKG_OK)
		return (EPKG_FATAL);

	/* Now we need to set the equal mtime for all archives in the repo */
@@ -597,5 +596,7 @@ pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path, bo
		}
	}

+
	rsa_free(rsa);
+

	return (EPKG_OK);
}
modified libpkg/private/utils.h
@@ -34,6 +34,7 @@
#include <uthash.h>

#include <openssl/pem.h>
+
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/md5.h>

@@ -63,6 +64,13 @@ struct dns_srvinfo {
	struct dns_srvinfo *next;
};

+
struct rsa_key {
+
	pem_password_cb *pw_cb;
+
	char *path;
+
	RSA *key;
+
};
+

+

void sbuf_init(struct sbuf **);
int sbuf_set(struct sbuf **, const char *);
char * sbuf_get(struct sbuf *);
@@ -78,8 +86,9 @@ int is_conf_file(const char *path, char *newpath, size_t len);
int sha256_file(const char *, char[SHA256_DIGEST_LENGTH * 2 +1]);
int md5_file(const char *, char[MD5_DIGEST_LENGTH * 2 +1]);

-
int rsa_sign(char *path, pem_password_cb *password_cb, char *rsa_key_path,
-
		 unsigned char **sigret, unsigned int *siglen);
+
int rsa_new(struct rsa_key **, pem_password_cb *, char *path);
+
void rsa_free(struct rsa_key *);
+
int rsa_sign(char *path, struct rsa_key *rsa, unsigned char **sigret, unsigned int *siglen);
int rsa_verify(const char *path, const char *key,
		unsigned char *sig, unsigned int sig_len);

modified libpkg/rsa.c
@@ -34,28 +34,27 @@
#include "private/event.h"
#include "private/pkg.h"

-
static RSA *
-
_load_rsa_private_key(char *rsa_key_path, pem_password_cb *password_cb)
+
static int
+
_load_rsa_private_key(struct rsa_key *rsa)
{
	FILE *fp;
-
	RSA *rsa = NULL;

-
	if ((fp = fopen(rsa_key_path, "r")) == 0)
-
		return (NULL);
+
	if ((fp = fopen(rsa->path, "r")) == 0)
+
		return (EPKG_FATAL);

-
	if ((rsa = RSA_new()) == NULL) {
+
	if ((rsa->key = RSA_new()) == NULL) {
		fclose(fp);
-
		return (NULL);
+
		return (EPKG_FATAL);
	}

-
	rsa = PEM_read_RSAPrivateKey(fp, 0, password_cb, rsa_key_path);
-
	if (rsa == NULL) {
+
	rsa->key = PEM_read_RSAPrivateKey(fp, 0, rsa->pw_cb, rsa->path);
+
	if (rsa->key == NULL) {
		fclose(fp);
-
		return (NULL);
+
		return (EPKG_FATAL);
	}

	fclose(fp);
-
	return (rsa);
+
	return (EPKG_OK);
}

static RSA *
@@ -114,45 +113,65 @@ rsa_verify(const char *path, const char *key, unsigned char *sig,
}

int
-
rsa_sign(char *path, pem_password_cb *password_cb, char *rsa_key_path,
-
		unsigned char **sigret, unsigned int *siglen)
+
rsa_sign(char *path, struct rsa_key *rsa, unsigned char **sigret, unsigned int *siglen)
{
	char errbuf[1024];
	int max_len = 0, ret;
-
	RSA *rsa = NULL;
	char sha256[SHA256_DIGEST_LENGTH * 2 +1];

-
	if (access(rsa_key_path, R_OK) == -1) {
-
		pkg_emit_errno("access", rsa_key_path);
-
		return EPKG_FATAL;
+
	if (access(rsa->path, R_OK) == -1) {
+
		pkg_emit_errno("access", rsa->path);
+
		return (EPKG_FATAL);
	}

-
	SSL_load_error_strings();
-

-
	OpenSSL_add_all_algorithms();
-
	OpenSSL_add_all_ciphers();
-

-
	rsa = _load_rsa_private_key(rsa_key_path, password_cb);
-
	if (rsa == NULL) {
-
		pkg_emit_error("can't load key from %s", rsa_key_path);
-
		return EPKG_FATAL;
+
	if (rsa->key == NULL && _load_rsa_private_key(rsa) != EPKG_OK) {
+
		pkg_emit_error("can't load key from %s", rsa->path);
+
		return (EPKG_FATAL);
	}

-
	max_len = RSA_size(rsa);
+
	max_len = RSA_size(rsa->key);
	*sigret = calloc(1, max_len + 1);

	sha256_file(path, sha256);

-
	ret = RSA_sign(NID_sha1, sha256, sizeof(sha256), *sigret, siglen, rsa);
+
	ret = RSA_sign(NID_sha1, sha256, sizeof(sha256), *sigret, siglen, rsa->key);
	if (ret == 0) {
		/* XXX pass back RSA errors correctly */
-
		pkg_emit_error("%s: %s", rsa_key_path,
-
					   ERR_error_string(ERR_get_error(), errbuf));
-
		return EPKG_FATAL;
+
		pkg_emit_error("%s: %s", rsa->path,
+
		   ERR_error_string(ERR_get_error(), errbuf));
+
		return (EPKG_FATAL);
	}

-
	RSA_free(rsa);
-
	ERR_free_strings();
+
	return (EPKG_OK);
+
}
+

+
int
+
rsa_new(struct rsa_key **rsa, pem_password_cb *cb, char *path)
+
{
+
	assert(*rsa == NULL);
+

+
	*rsa = calloc(1, sizeof(struct rsa_key));
+
	(*rsa)->path = path;
+
	(*rsa)->pw_cb = cb;
+

+
	SSL_load_error_strings();
+

+
	OpenSSL_add_all_algorithms();
+
	OpenSSL_add_all_ciphers();

	return (EPKG_OK);
}
+

+
void
+
rsa_free(struct rsa_key *rsa)
+
{
+
	if (rsa == NULL)
+
		return;
+

+
	if (rsa->key != NULL)
+
		RSA_free(rsa->key);
+

+
	free(rsa);
+
	ERR_free_strings();
+
}
+