Read also unsigned index-meta
This commit is contained in:
parent
09125769bd
commit
61ef5c3f8a
68
lib/repo.c
68
lib/repo.c
@ -61,7 +61,7 @@ xbps_repo_path_with_name(struct xbps_handle *xhp, const char *url, const char *n
|
|||||||
url, xhp->target_arch ? xhp->target_arch : xhp->native_arch, name);
|
url, xhp->target_arch ? xhp->target_arch : xhp->native_arch, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static int
|
||||||
repo_verify_index(struct xbps_repo *repo, xbps_dictionary_t idxmeta, unsigned char *digest) {
|
repo_verify_index(struct xbps_repo *repo, xbps_dictionary_t idxmeta, unsigned char *digest) {
|
||||||
bool verified = false;
|
bool verified = false;
|
||||||
unsigned char *sig_buf = NULL;
|
unsigned char *sig_buf = NULL;
|
||||||
@ -72,28 +72,28 @@ repo_verify_index(struct xbps_repo *repo, xbps_dictionary_t idxmeta, unsigned ch
|
|||||||
xbps_dbg_printf(repo->xhp,
|
xbps_dbg_printf(repo->xhp,
|
||||||
"%s: read_next_header %s\n", repo->uri,
|
"%s: read_next_header %s\n", repo->uri,
|
||||||
archive_error_string(repo->ar));
|
archive_error_string(repo->ar));
|
||||||
return false;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(archive_entry_pathname(entry), XBPS_REPOIDXMETA_SIG) != 0) {
|
if (strcmp(archive_entry_pathname(entry), XBPS_REPOIDXMETA_SIG) != 0) {
|
||||||
xbps_dbg_printf(repo->xhp,
|
xbps_dbg_printf(repo->xhp,
|
||||||
"%s: no signature of %s\n", repo->uri, XBPS_REPOIDX_META);
|
"%s: no signature of %s\n", repo->uri, XBPS_REPOIDX_META);
|
||||||
return false;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigfilelen = (size_t)archive_entry_size(entry);
|
sigfilelen = (size_t)archive_entry_size(entry);
|
||||||
sig_buf = (unsigned char *) xbps_archive_get_file(repo->ar, entry);
|
sig_buf = (unsigned char *) xbps_archive_get_file(repo->ar, entry);
|
||||||
if (sig_buf == NULL) {
|
if (sig_buf == NULL) {
|
||||||
return false;
|
return EIO;
|
||||||
}
|
}
|
||||||
verified = xbps_verify_digest_signature(repo, idxmeta, sig_buf, sigfilelen, digest);
|
verified = xbps_verify_digest_signature(repo, idxmeta, sig_buf, sigfilelen, digest);
|
||||||
|
|
||||||
free(sig_buf);
|
free(sig_buf);
|
||||||
return verified;
|
return verified ? 0 : EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xbps_dictionary_t
|
static xbps_dictionary_t
|
||||||
repo_get_dict(struct xbps_repo *repo, bool *verified)
|
repo_get_dict(struct xbps_repo *repo, int *verify_error)
|
||||||
{
|
{
|
||||||
struct archive_entry *entry;
|
struct archive_entry *entry;
|
||||||
int rv;
|
int rv;
|
||||||
@ -101,8 +101,8 @@ repo_get_dict(struct xbps_repo *repo, bool *verified)
|
|||||||
char *bytes = NULL;
|
char *bytes = NULL;
|
||||||
unsigned char *digest = NULL;
|
unsigned char *digest = NULL;
|
||||||
|
|
||||||
if (verified != NULL)
|
if (verify_error != NULL)
|
||||||
*verified = false;
|
*verify_error = -1;
|
||||||
|
|
||||||
if (repo->ar == NULL)
|
if (repo->ar == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -116,15 +116,36 @@ repo_get_dict(struct xbps_repo *repo, bool *verified)
|
|||||||
}
|
}
|
||||||
dict = xbps_archive_get_dictionary(repo->ar, entry, &bytes);
|
dict = xbps_archive_get_dictionary(repo->ar, entry, &bytes);
|
||||||
idxmeta = (repo->idxmeta != NULL) ? repo->idxmeta : dict;
|
idxmeta = (repo->idxmeta != NULL) ? repo->idxmeta : dict;
|
||||||
if (verified != NULL && bytes != NULL) {
|
if (verify_error != NULL && bytes != NULL) {
|
||||||
digest = xbps_buffer_hash_raw(bytes, strlen(bytes));
|
digest = xbps_buffer_hash_raw(bytes, strlen(bytes));
|
||||||
*verified = repo_verify_index(repo, idxmeta, digest);
|
*verify_error = repo_verify_index(repo, idxmeta, digest);
|
||||||
}
|
}
|
||||||
free(digest);
|
free(digest);
|
||||||
free(bytes);
|
free(bytes);
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static xbps_dictionary_t
|
||||||
|
get_safe_idxmeta(xbps_dictionary_t full) {
|
||||||
|
static const char *keys[] = {
|
||||||
|
"public-key",
|
||||||
|
"public-key-size",
|
||||||
|
"signature-by",
|
||||||
|
"signature-type",
|
||||||
|
};
|
||||||
|
unsigned fields_count = (sizeof keys)/(sizeof *keys);
|
||||||
|
xbps_dictionary_t safe = xbps_dictionary_create();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < fields_count; ++i) {
|
||||||
|
const char *key = keys[i];
|
||||||
|
xbps_object_t value = xbps_dictionary_get(full, key);
|
||||||
|
xbps_dictionary_set(safe, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return safe;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_repo_lock(struct xbps_handle *xhp, const char *repodir,
|
xbps_repo_lock(struct xbps_handle *xhp, const char *repodir,
|
||||||
int *lockfd, char **lockfname)
|
int *lockfd, char **lockfname)
|
||||||
@ -180,8 +201,9 @@ repo_open_local(struct xbps_repo *repo, const char *repofile)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
bool verified = false;
|
int verify_error = -1;
|
||||||
const char *signature_type = NULL;
|
const char *signature_type = NULL;
|
||||||
|
xbps_dictionary_t idxmeta = NULL;
|
||||||
|
|
||||||
if (fstat(repo->fd, &st) == -1) {
|
if (fstat(repo->fd, &st) == -1) {
|
||||||
rv = errno;
|
rv = errno;
|
||||||
@ -213,14 +235,26 @@ repo_open_local(struct xbps_repo *repo, const char *repofile)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
xbps_dictionary_make_immutable(repo->idx);
|
xbps_dictionary_make_immutable(repo->idx);
|
||||||
repo->idxmeta = repo_get_dict(repo, &verified);
|
idxmeta = repo_get_dict(repo, &verify_error);
|
||||||
if (repo->idxmeta != NULL) {
|
if (idxmeta != NULL) {
|
||||||
if (xbps_dictionary_get_cstring_nocopy(repo->idxmeta, "signature-type", &signature_type))
|
if (verify_error == ENOENT) {
|
||||||
repo->is_signed = true;
|
xbps_dbg_printf(repo->xhp, "Metadata of repo '%s' not signed. Taking safe part.\n", repofile);
|
||||||
xbps_dictionary_make_immutable(repo->idxmeta);
|
idxmeta = get_safe_idxmeta(idxmeta);
|
||||||
|
verify_error = 0;
|
||||||
|
} else if (verify_error) {
|
||||||
|
xbps_warn_printf("Verification of repo's '%s' signature failed. Taking safe part.\n", repofile);
|
||||||
|
idxmeta = get_safe_idxmeta(idxmeta);
|
||||||
|
} else {
|
||||||
|
xbps_dbg_printf(repo->xhp, "Verification of repo's '%s' signature passed.\n", repofile);
|
||||||
}
|
}
|
||||||
|
if (xbps_dictionary_get_cstring_nocopy(idxmeta, "signature-type", &signature_type)) {
|
||||||
|
repo->is_signed = true;
|
||||||
|
}
|
||||||
|
xbps_dictionary_make_immutable(idxmeta);
|
||||||
|
}
|
||||||
|
repo->idxmeta = idxmeta;
|
||||||
|
|
||||||
return verified || (!repo->is_remote && !repo->is_signed);
|
return !verify_error || (!repo->is_remote && !repo->is_signed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
Loading…
Reference in New Issue
Block a user