Revert "Verify repodata signature"
This reverts commit a7830cf780716d71bde396cbe3697994fc94e129.
This commit is contained in:
parent
b4fdc39e67
commit
d2208f91e0
@ -1894,22 +1894,6 @@ int xbps_file_hash_check(const char *file, const char *sha256);
|
|||||||
bool xbps_verify_signature(struct xbps_repo *repo, const char *sigfile,
|
bool xbps_verify_signature(struct xbps_repo *repo, const char *sigfile,
|
||||||
unsigned char *digest);
|
unsigned char *digest);
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies the RSA signature \sig_buf of bytes with hash \a digest
|
|
||||||
* with the RSA public-key associated in \a repo.
|
|
||||||
*
|
|
||||||
* @param[in] repo Repository to use with the RSA public key associated.
|
|
||||||
* @param[in] idxmeta Meta dictionary related to \a repo, containing
|
|
||||||
* public-key field.
|
|
||||||
* @param[in] sig_buf The signature of file content that has hash \digest.
|
|
||||||
* @param[in] sigfilelen The length of signature.
|
|
||||||
* @param[in] digest The digest of file content to verify.
|
|
||||||
*
|
|
||||||
* @return True if the signature is valid, false otherwise.
|
|
||||||
*/
|
|
||||||
bool xbps_verify_digest_signature(struct xbps_repo *repo, xbps_dictionary_t idxmeta,
|
|
||||||
unsigned char *sig_buf, size_t sigfilelen, unsigned char *digest);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies the RSA signature of \a fname with the RSA public-key associated
|
* Verifies the RSA signature of \a fname with the RSA public-key associated
|
||||||
* in \a repo.
|
* in \a repo.
|
||||||
|
@ -149,8 +149,7 @@ int HIDDEN xbps_register_pkg(struct xbps_handle *, xbps_dictionary_t);
|
|||||||
void HIDDEN xbps_transaction_conflicts(struct xbps_handle *, xbps_array_t);
|
void HIDDEN xbps_transaction_conflicts(struct xbps_handle *, xbps_array_t);
|
||||||
char HIDDEN *xbps_archive_get_file(struct archive *, struct archive_entry *);
|
char HIDDEN *xbps_archive_get_file(struct archive *, struct archive_entry *);
|
||||||
xbps_dictionary_t HIDDEN xbps_archive_get_dictionary(struct archive *,
|
xbps_dictionary_t HIDDEN xbps_archive_get_dictionary(struct archive *,
|
||||||
struct archive_entry *, char **bytes);
|
struct archive_entry *);
|
||||||
xbps_dictionary_t HIDDEN get_safe_idxmeta(xbps_dictionary_t full);
|
|
||||||
const char HIDDEN *vpkg_user_conf(struct xbps_handle *, const char *, bool);
|
const char HIDDEN *vpkg_user_conf(struct xbps_handle *, const char *, bool);
|
||||||
xbps_array_t HIDDEN xbps_get_pkg_fulldeptree(struct xbps_handle *,
|
xbps_array_t HIDDEN xbps_get_pkg_fulldeptree(struct xbps_handle *,
|
||||||
const char *, bool);
|
const char *, bool);
|
||||||
|
@ -56,7 +56,7 @@ xbps_archive_get_file(struct archive *ar, struct archive_entry *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xbps_dictionary_t HIDDEN
|
xbps_dictionary_t HIDDEN
|
||||||
xbps_archive_get_dictionary(struct archive *ar, struct archive_entry *entry, char **bytes)
|
xbps_archive_get_dictionary(struct archive *ar, struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
xbps_dictionary_t d = NULL;
|
xbps_dictionary_t d = NULL;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -66,11 +66,7 @@ xbps_archive_get_dictionary(struct archive *ar, struct archive_entry *entry, cha
|
|||||||
|
|
||||||
/* If blob is already a dictionary we are done */
|
/* If blob is already a dictionary we are done */
|
||||||
d = xbps_dictionary_internalize(buf);
|
d = xbps_dictionary_internalize(buf);
|
||||||
if (bytes == NULL) {
|
free(buf);
|
||||||
free(buf);
|
|
||||||
} else {
|
|
||||||
*bytes = buf;
|
|
||||||
}
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,13 +180,13 @@ unpack_archive(struct xbps_handle *xhp,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (strcmp("./props.plist", entry_pname) == 0) {
|
} else if (strcmp("./props.plist", entry_pname) == 0) {
|
||||||
binpkg_propsd = xbps_archive_get_dictionary(ar, entry, NULL);
|
binpkg_propsd = xbps_archive_get_dictionary(ar, entry);
|
||||||
if (binpkg_propsd == NULL) {
|
if (binpkg_propsd == NULL) {
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (strcmp("./files.plist", entry_pname) == 0) {
|
} else if (strcmp("./files.plist", entry_pname) == 0) {
|
||||||
binpkg_filesd = xbps_archive_get_dictionary(ar, entry, NULL);
|
binpkg_filesd = xbps_archive_get_dictionary(ar, entry);
|
||||||
if (binpkg_filesd == NULL) {
|
if (binpkg_filesd == NULL) {
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
76
lib/repo.c
76
lib/repo.c
@ -61,48 +61,11 @@ 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 int
|
|
||||||
repo_verify_index(struct xbps_repo *repo, xbps_dictionary_t idxmeta, unsigned char *digest) {
|
|
||||||
bool verified = false;
|
|
||||||
unsigned char *sig_buf = NULL;
|
|
||||||
size_t sigfilelen = 0;
|
|
||||||
struct archive_entry *entry;
|
|
||||||
|
|
||||||
if (archive_read_next_header(repo->ar, &entry) != ARCHIVE_OK) {
|
|
||||||
xbps_dbg_printf(repo->xhp,
|
|
||||||
"%s: read_next_header %s\n", repo->uri,
|
|
||||||
archive_error_string(repo->ar));
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(archive_entry_pathname(entry), XBPS_REPOIDXMETA_SIG) != 0) {
|
|
||||||
xbps_dbg_printf(repo->xhp,
|
|
||||||
"%s: no signature of %s\n", repo->uri, XBPS_REPOIDX_META);
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigfilelen = (size_t)archive_entry_size(entry);
|
|
||||||
sig_buf = (unsigned char *) xbps_archive_get_file(repo->ar, entry);
|
|
||||||
if (sig_buf == NULL) {
|
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
verified = xbps_verify_digest_signature(repo, idxmeta, sig_buf, sigfilelen, digest);
|
|
||||||
|
|
||||||
free(sig_buf);
|
|
||||||
return verified ? 0 : EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xbps_dictionary_t
|
static xbps_dictionary_t
|
||||||
repo_get_dict(struct xbps_repo *repo, int *verify_error)
|
repo_get_dict(struct xbps_repo *repo)
|
||||||
{
|
{
|
||||||
struct archive_entry *entry;
|
struct archive_entry *entry;
|
||||||
int rv;
|
int rv;
|
||||||
xbps_dictionary_t dict, idxmeta;
|
|
||||||
char *bytes = NULL;
|
|
||||||
unsigned char *digest = NULL;
|
|
||||||
|
|
||||||
if (verify_error != NULL)
|
|
||||||
*verify_error = -1;
|
|
||||||
|
|
||||||
if (repo->ar == NULL)
|
if (repo->ar == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -114,15 +77,7 @@ repo_get_dict(struct xbps_repo *repo, int *verify_error)
|
|||||||
archive_error_string(repo->ar));
|
archive_error_string(repo->ar));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
dict = xbps_archive_get_dictionary(repo->ar, entry, &bytes);
|
return xbps_archive_get_dictionary(repo->ar, entry);
|
||||||
idxmeta = (repo->idxmeta != NULL) ? repo->idxmeta : dict;
|
|
||||||
if (verify_error != NULL && bytes != NULL) {
|
|
||||||
digest = xbps_buffer_hash_raw(bytes, strlen(bytes));
|
|
||||||
*verify_error = repo_verify_index(repo, idxmeta, digest);
|
|
||||||
}
|
|
||||||
free(digest);
|
|
||||||
free(bytes);
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -209,9 +164,6 @@ repo_open_local(struct xbps_repo *repo, const char *repofile)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
int verify_error = -1;
|
|
||||||
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;
|
||||||
@ -235,7 +187,7 @@ repo_open_local(struct xbps_repo *repo, const char *repofile)
|
|||||||
repofile, strerror(rv));
|
repofile, strerror(rv));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((repo->idx = repo_get_dict(repo, NULL)) == NULL) {
|
if ((repo->idx = repo_get_dict(repo)) == NULL) {
|
||||||
xbps_dbg_printf(repo->xhp, "[repo] `%s' failed to internalize "
|
xbps_dbg_printf(repo->xhp, "[repo] `%s' failed to internalize "
|
||||||
" index on archive, removing file.\n", repofile);
|
" index on archive, removing file.\n", repofile);
|
||||||
/* broken archive, remove it */
|
/* broken archive, remove it */
|
||||||
@ -243,26 +195,14 @@ 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);
|
||||||
idxmeta = repo_get_dict(repo, &verify_error);
|
repo->idxmeta = repo_get_dict(repo);
|
||||||
if (idxmeta != NULL) {
|
if (repo->idxmeta != NULL) {
|
||||||
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;
|
repo->idxmeta = idxmeta;
|
||||||
|
|
||||||
return !verify_error || (!repo->is_remote && !repo->is_signed);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -732,7 +732,7 @@ collect_binpkg_files(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod,
|
|||||||
|
|
||||||
entry_pname = archive_entry_pathname(entry);
|
entry_pname = archive_entry_pathname(entry);
|
||||||
if ((strcmp("./files.plist", entry_pname)) == 0) {
|
if ((strcmp("./files.plist", entry_pname)) == 0) {
|
||||||
filesd = xbps_archive_get_dictionary(ar, entry, NULL);
|
filesd = xbps_archive_get_dictionary(ar, entry);
|
||||||
if (filesd == NULL) {
|
if (filesd == NULL) {
|
||||||
rv = EINVAL;
|
rv = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -72,24 +72,28 @@ rsa_verify_hash(struct xbps_repo *repo, xbps_data_t pubkey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_verify_digest_signature(struct xbps_repo *repo, xbps_dictionary_t idxmeta,
|
xbps_verify_signature(struct xbps_repo *repo, const char *sigfile,
|
||||||
unsigned char *sig_buf, size_t sigfilelen, unsigned char *digest)
|
unsigned char *digest)
|
||||||
{
|
{
|
||||||
xbps_dictionary_t repokeyd = NULL;
|
xbps_dictionary_t repokeyd = NULL;
|
||||||
xbps_data_t pubkey;
|
xbps_data_t pubkey;
|
||||||
char *hexfp = NULL, *rkeyfile = NULL;
|
char *hexfp = NULL;
|
||||||
|
unsigned char *sig_buf = NULL;
|
||||||
|
size_t sigbuflen, sigfilelen;
|
||||||
|
char *rkeyfile = NULL;
|
||||||
bool val = false;
|
bool val = false;
|
||||||
|
|
||||||
if (!xbps_dictionary_count(idxmeta)) {
|
if (!xbps_dictionary_count(repo->idxmeta)) {
|
||||||
xbps_dbg_printf(repo->xhp, "%s: unsigned repository\n", repo->uri);
|
xbps_dbg_printf(repo->xhp, "%s: unsigned repository\n", repo->uri);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
hexfp = xbps_pubkey2fp(repo->xhp,
|
hexfp = xbps_pubkey2fp(repo->xhp,
|
||||||
xbps_dictionary_get(idxmeta, "public-key"));
|
xbps_dictionary_get(repo->idxmeta, "public-key"));
|
||||||
if (hexfp == NULL) {
|
if (hexfp == NULL) {
|
||||||
xbps_dbg_printf(repo->xhp, "%s: incomplete signed repo, missing hexfp obj\n", repo->uri);
|
xbps_dbg_printf(repo->xhp, "%s: incomplete signed repo, missing hexfp obj\n", repo->uri);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare repository RSA public key to verify fname signature.
|
* Prepare repository RSA public key to verify fname signature.
|
||||||
*/
|
*/
|
||||||
@ -109,6 +113,12 @@ xbps_verify_digest_signature(struct xbps_repo *repo, xbps_dictionary_t idxmeta,
|
|||||||
pubkey = xbps_dictionary_get(repokeyd, "public-key");
|
pubkey = xbps_dictionary_get(repokeyd, "public-key");
|
||||||
if (xbps_object_type(pubkey) != XBPS_TYPE_DATA)
|
if (xbps_object_type(pubkey) != XBPS_TYPE_DATA)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (!xbps_mmap_file(sigfile, (void *)&sig_buf, &sigbuflen, &sigfilelen)) {
|
||||||
|
xbps_dbg_printf(repo->xhp, "can't open signature file %s: %s\n",
|
||||||
|
sigfile, strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Verify fname RSA signature.
|
* Verify fname RSA signature.
|
||||||
*/
|
*/
|
||||||
@ -120,32 +130,14 @@ out:
|
|||||||
free(hexfp);
|
free(hexfp);
|
||||||
if (rkeyfile)
|
if (rkeyfile)
|
||||||
free(rkeyfile);
|
free(rkeyfile);
|
||||||
|
if (sig_buf)
|
||||||
|
(void)munmap(sig_buf, sigbuflen);
|
||||||
if (repokeyd)
|
if (repokeyd)
|
||||||
xbps_object_release(repokeyd);
|
xbps_object_release(repokeyd);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
xbps_verify_signature(struct xbps_repo *repo, const char *sigfile,
|
|
||||||
unsigned char *digest)
|
|
||||||
{
|
|
||||||
unsigned char *sig_buf = NULL;
|
|
||||||
size_t sigbuflen, sigfilelen;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (xbps_mmap_file(sigfile, (void *)&sig_buf, &sigbuflen, &sigfilelen)) {
|
|
||||||
result = xbps_verify_digest_signature(repo, repo->idxmeta, sig_buf, sigfilelen, digest);
|
|
||||||
} else {
|
|
||||||
xbps_dbg_printf(repo->xhp, "can't open signature file %s: %s\n",
|
|
||||||
sigfile, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig_buf)
|
|
||||||
(void)munmap(sig_buf, sigbuflen);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
|
xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user