-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
signature fixups #306
base: master
Are you sure you want to change the base?
signature fixups #306
Changes from all commits
ea0eb17
59cc5b4
1388de5
9f32c18
dda1c5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -209,17 +209,41 @@ xbps_transaction_fetch(struct xbps_handle *xhp, xbps_object_iterator_t iter) | |
xbps_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); | ||
|
||
/* | ||
* Download binary package and signature if either one | ||
* of them don't exist. | ||
* If this is a remote repository: | ||
* - Make sure the public key exist. | ||
* - Check if the package is not yet in the cache | ||
* and add it to the fetch array to download later. | ||
*/ | ||
if (xbps_repository_is_remote(repoloc) && | ||
!xbps_remote_binpkg_exists(xhp, obj)) { | ||
if (!fetch && !(fetch = xbps_array_create())) { | ||
if (xbps_repository_is_remote(repoloc)) { | ||
struct xbps_repo *repo; | ||
|
||
if ((repo = xbps_rpool_get_repo(repoloc)) == NULL) { | ||
rv = errno; | ||
xbps_error_printf("%s: repository not found in rpool\n", | ||
repoloc); | ||
goto out; | ||
} | ||
xbps_array_add(fetch, obj); | ||
continue; | ||
if (xbps_repo_pubkey(repo) == NULL) { | ||
rv = errno; | ||
xbps_error_printf("%s: failed to get public key: %s\n", | ||
repoloc, strerror(errno)); | ||
goto out; | ||
} | ||
|
||
/* | ||
* Download binary package and signature if either one | ||
* of them don't exist. | ||
*/ | ||
if (!xbps_remote_binpkg_exists(xhp, obj)) { | ||
if (!fetch && !(fetch = xbps_array_create())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Average transaction do fetch package, just creating array on top will be not only more readable, but also faster. |
||
rv = errno; | ||
goto out; | ||
} | ||
xbps_array_add(fetch, obj); | ||
|
||
/* don't add it to the verify list, fetch implies that. */ | ||
continue; | ||
} | ||
} | ||
|
||
/* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,13 +41,20 @@ | |
#include "xbps_api_impl.h" | ||
|
||
static bool | ||
rsa_verify_hash(struct xbps_repo *repo, xbps_data_t pubkey, | ||
rsa_verify_hash(struct xbps_repo *repo, | ||
unsigned char *sig, unsigned int siglen, | ||
unsigned char *sha256) | ||
{ | ||
BIO *bio; | ||
RSA *rsa; | ||
int rv; | ||
xbps_data_t pubkey; | ||
|
||
if ((pubkey = xbps_repo_pubkey(repo)) == NULL) { | ||
xbps_error_printf("%s: failed to get public key: %s\n", | ||
repo->uri, strerror(errno)); | ||
return false; | ||
} | ||
|
||
ERR_load_crypto_strings(); | ||
SSL_load_error_strings(); | ||
|
@@ -75,62 +82,35 @@ bool | |
xbps_verify_signature(struct xbps_repo *repo, const char *sigfile, | ||
unsigned char *digest) | ||
{ | ||
xbps_dictionary_t repokeyd = NULL; | ||
xbps_data_t pubkey; | ||
char *hexfp = NULL; | ||
unsigned char *sig_buf = NULL; | ||
size_t sigbuflen, sigfilelen; | ||
char *rkeyfile = NULL; | ||
bool val = false; | ||
unsigned char buf[512]; | ||
struct stat st; | ||
ssize_t rd = 0; | ||
int fd = -1; | ||
|
||
if (!xbps_dictionary_count(repo->idxmeta)) { | ||
xbps_dbg_printf(repo->xhp, "%s: unsigned repository\n", repo->uri); | ||
return false; | ||
} | ||
hexfp = xbps_pubkey2fp(repo->xhp, | ||
xbps_dictionary_get(repo->idxmeta, "public-key")); | ||
if (hexfp == NULL) { | ||
xbps_dbg_printf(repo->xhp, "%s: incomplete signed repo, missing hexfp obj\n", repo->uri); | ||
if ((fd = open(sigfile, O_RDONLY|O_CLOEXEC)) == -1 || fstat(fd, &st) == -1) { | ||
xbps_error_printf("can't open signature file %s: %s\n", | ||
sigfile, strerror(errno)); | ||
close(fd); | ||
return false; | ||
} | ||
|
||
/* | ||
* Prepare repository RSA public key to verify fname signature. | ||
*/ | ||
rkeyfile = xbps_xasprintf("%s/keys/%s.plist", repo->xhp->metadir, hexfp); | ||
repokeyd = xbps_plist_dictionary_from_file(repo->xhp, rkeyfile); | ||
if (xbps_object_type(repokeyd) != XBPS_TYPE_DICTIONARY) { | ||
xbps_dbg_printf(repo->xhp, "cannot read rkey data at %s: %s\n", | ||
rkeyfile, strerror(errno)); | ||
goto out; | ||
if (st.st_size != sizeof buf) { | ||
xbps_error_printf("invalid signature file %s: size mismatch\n", | ||
sigfile); | ||
(void)close(fd); | ||
return false; | ||
} | ||
|
||
pubkey = xbps_dictionary_get(repokeyd, "public-key"); | ||
if (xbps_object_type(pubkey) != XBPS_TYPE_DATA) | ||
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", | ||
rd = read(fd, buf, sizeof buf); | ||
if (rd == -1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess It would be good if this could be a |
||
xbps_error_printf("can't read signature file %s: %s\n", | ||
sigfile, strerror(errno)); | ||
goto out; | ||
close(fd); | ||
return false; | ||
} | ||
/* | ||
* Verify fname RSA signature. | ||
*/ | ||
if (rsa_verify_hash(repo, pubkey, sig_buf, sigfilelen, digest)) | ||
val = true; | ||
|
||
out: | ||
if (hexfp) | ||
free(hexfp); | ||
if (rkeyfile) | ||
free(rkeyfile); | ||
if (sig_buf) | ||
(void)munmap(sig_buf, sigbuflen); | ||
if (repokeyd) | ||
xbps_object_release(repokeyd); | ||
close(fd); | ||
|
||
return val; | ||
return rsa_verify_hash(repo, buf, sizeof buf, digest); | ||
} | ||
|
||
bool | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enqueue downloading?