diff options
author | Michael Schroeder <mls@suse.de> | 2013-10-25 14:43:26 +0200 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2013-10-25 14:43:26 +0200 |
commit | eb84c69bbb7f1e38ef381c361d05e35c21e7fbfa (patch) | |
tree | db539cef72341eb6c126dd7309d2245892353c79 /ext/repo_pubkey.c | |
parent | 6289a1aa74db6eab63b17640d8008705423adc64 (diff) | |
download | libsolv-eb84c69bbb7f1e38ef381c361d05e35c21e7fbfa.tar.gz libsolv-eb84c69bbb7f1e38ef381c361d05e35c21e7fbfa.tar.bz2 libsolv-eb84c69bbb7f1e38ef381c361d05e35c21e7fbfa.zip |
add repo_verify_sigdata, refactor solv_parse_sig into solvsig_create/free/verify
Diffstat (limited to 'ext/repo_pubkey.c')
-rw-r--r-- | ext/repo_pubkey.c | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/ext/repo_pubkey.c b/ext/repo_pubkey.c index 3dffa20..5f157d1 100644 --- a/ext/repo_pubkey.c +++ b/ext/repo_pubkey.c @@ -222,7 +222,7 @@ createsigdata(struct pgpsig *sig, unsigned char *p, int l, unsigned char *pubkey const unsigned char *cs; int csl; - if (sig->mpioff < 2 || l <= sig->mpioff) + if (!h || sig->mpioff < 2 || l <= sig->mpioff) return; if ((type >= 0x10 && type <= 0x13) || type == 0x1f || type == 0x18 || type == 0x20 || type == 0x28) { @@ -847,19 +847,14 @@ is_sig_packet(unsigned char *sig, int sigl) return 1; } -Id -solv_parse_sig(FILE *fp, unsigned char **sigpktp, int *sigpktlp, char *keyidstr) +Solvsig * +solvsig_create(FILE *fp) { + Solvsig *ss; unsigned char *sig; int sigl, hl, tag, pktl; struct pgpsig pgpsig; - Id htype; - if (sigpktp) - { - *sigpktp = 0; - *sigpktlp = 0; - } if ((sig = (unsigned char *)solv_slurp(fp, &sigl)) == 0) return 0; if (!is_sig_packet(sig, sigl)) @@ -885,22 +880,27 @@ solv_parse_sig(FILE *fp, unsigned char **sigpktp, int *sigpktlp, char *keyidstr) } memset(&pgpsig, 0, sizeof(pgpsig)); parsesigpacket(&pgpsig, sig + hl, pktl); - htype = pgphashalgo2type(pgpsig.hashalgo); - if (pgpsig.type != 0 || !htype || !pgpsig.haveissuer) + if (pgpsig.type != 0 || !pgpsig.haveissuer) { solv_free(sig); return 0; } - if (sigpktp) - { - *sigpktp = solv_malloc(pktl); - memcpy(*sigpktp, sig + hl, pktl); - *sigpktlp = pktl; - } + ss = solv_calloc(1, sizeof(*ss)); + ss->sigpkt = solv_memdup(sig + hl, pktl); + ss->sigpktl = pktl; solv_free(sig); - if (keyidstr) - solv_bin2hex(pgpsig.issuer, 8, keyidstr); - return htype; + solv_bin2hex(pgpsig.issuer, 8, ss->keyid); + ss->htype = pgphashalgo2type(pgpsig.hashalgo); + ss->created = pgpsig.created; + ss->expires = pgpsig.expires; + return ss; +} + +void +solvsig_free(Solvsig *ss) +{ + solv_free(ss->sigpkt); + solv_free(ss); } #ifdef ENABLE_PGPVRFY @@ -918,7 +918,7 @@ solv_verify_sig(const unsigned char *pubdata, int pubdatal, unsigned char *sigpk if (pgpsig.type != 0) return 0; htype = pgphashalgo2type(pgpsig.hashalgo); - if (htype != solv_chksum_get_type(chk)) + if (!htype || htype != solv_chksum_get_type(chk)) return 0; /* wrong hash type? */ chk2 = solv_chksum_create_clone(chk); createsigdata(&pgpsig, sigpkt, sigpktl, 0, 0, 0, 0, chk2); @@ -930,5 +930,52 @@ solv_verify_sig(const unsigned char *pubdata, int pubdatal, unsigned char *sigpk return res; } +/* warning: does not check key expiry/revokation, like gpgv or rpm */ +/* returns the Id of the pubkey that verified the signature */ +Id +repo_verify_sigdata(Repo *repo, unsigned char *sigdata, int sigdatal, const char *keyid) +{ + Id p; + Solvable *s; + + if (!sigdata || !keyid) + return 0; + FOR_REPO_SOLVABLES(repo, p, s) + { + const char *evr = pool_id2str(s->repo->pool, s->evr); + const char *kidstr; + const unsigned char *pubdata; + int pubdatal; + + if (!evr || strncmp(evr, keyid + 8, 8) != 0) + continue; + kidstr = solvable_lookup_str(s, PUBKEY_KEYID); + if (!kidstr || strcmp(kidstr, keyid) != 0) + continue; + pubdata = repo_lookup_binary(repo, p, PUBKEY_DATA, &pubdatal); + if (solv_pgpvrfy(pubdata, pubdatal, sigdata, sigdatal)) + return p; + } + return 0; +} + +Id +solvsig_verify(Solvsig *ss, Repo *repo, void *chk) +{ + struct pgpsig pgpsig; + void *chk2; + Id p; + + parsesigpacket(&pgpsig, ss->sigpkt, ss->sigpktl); + chk2 = solv_chksum_create_clone(chk); + createsigdata(&pgpsig, ss->sigpkt, ss->sigpktl, 0, 0, 0, 0, chk2); + solv_chksum_free(chk2, 0); + if (!pgpsig.sigdata) + return 0; + p = repo_verify_sigdata(repo, pgpsig.sigdata, pgpsig.sigdatal, ss->keyid); + solv_free(pgpsig.sigdata); + return p; +} + #endif |