Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Refactor the signing repository code so that the key is being asked only once
Baptiste Daroussin committed 12 years ago
commit 95de71757f3c197fdc5a63e3264f77e17175d226
parent 56ffb8dd4e5ff83f8427a2016f32c0ae9b5bb2d3
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();
+
}
+