static int pkg_symlink_cksum_readlink(const char *linkbuf, int linklen, const char *root, char *cksum) { const char *lnk; lnk = linkbuf; if (root != NULL) { /* Skip root from checksum, as it is meaningless */ if (strncmp(root, linkbuf, strlen(root)) == 0) { lnk += strlen(root); } } /* Skip heading slashes */ while(*lnk == '/') lnk ++; sha256_buf(lnk, linklen, cksum); return (EPKG_OK); }
static bool pkg_repo_check_fingerprint(struct pkg_repo *repo, struct sig_cert *sc, bool fatal) { struct fingerprint *f = NULL; char hash[SHA256_DIGEST_LENGTH * 2 + 1]; int nbgood = 0; struct sig_cert *s = NULL, *stmp = NULL; struct pkg_repo_meta_key *mk = NULL; if (HASH_COUNT(sc) == 0) { if (fatal) pkg_emit_error("No signature found"); return (false); } /* load fingerprints */ if (repo->trusted_fp == NULL) { if (pkg_repo_load_fingerprints(repo) != EPKG_OK) return (false); } HASH_ITER(hh, sc, s, stmp) { if (s->sig != NULL && s->cert == NULL) { /* * We may want to check meta */ if (repo->meta != NULL && repo->meta->keys != NULL) HASH_FIND_STR(repo->meta->keys, s->name, mk); if (mk != NULL && mk->pubkey != NULL) { s->cert = mk->pubkey; s->certlen = strlen(mk->pubkey); } else { if (fatal) pkg_emit_error("No key with name %s has been found", s->name); return (false); } } else if (s->sig == NULL) { if (fatal) pkg_emit_error("No signature with name %s has been found", s->name); return (false); } s->trusted = false; sha256_buf(s->cert, s->certlen, hash); HASH_FIND_STR(repo->revoked_fp, hash, f); if (f != NULL) { if (fatal) pkg_emit_error("At least one of the " " certificates has been revoked"); return (false); } HASH_FIND_STR(repo->trusted_fp, hash, f); if (f != NULL) { nbgood++; s->trusted = true; } } if (nbgood == 0) { if (fatal) pkg_emit_error("No trusted public keys found"); return (false); } return (true); }