summaryrefslogtreecommitdiff
path: root/lib/signature.c
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2001-10-19 19:51:18 +0000
committerjbj <devnull@localhost>2001-10-19 19:51:18 +0000
commite2dfa4f2d4f643ff2c47adfc8ae6b4b700c62b8b (patch)
tree6ce514ea2fc730cfdf1b666dffcb7625772dabf6 /lib/signature.c
parente2a842407516209b3447997d19879848d074c3d6 (diff)
downloadlibrpm-tizen-e2dfa4f2d4f643ff2c47adfc8ae6b4b700c62b8b.tar.gz
librpm-tizen-e2dfa4f2d4f643ff2c47adfc8ae6b4b700c62b8b.tar.bz2
librpm-tizen-e2dfa4f2d4f643ff2c47adfc8ae6b4b700c62b8b.zip
- beecrypt is at least as good as pgp/gpg on verify, pull the plug.
CVS patchset: 5124 CVS date: 2001/10/19 19:51:18
Diffstat (limited to 'lib/signature.c')
-rw-r--r--lib/signature.c502
1 files changed, 139 insertions, 363 deletions
diff --git a/lib/signature.c b/lib/signature.c
index e58c9b0d1..651baf858 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -1,4 +1,3 @@
-/*@-mods@*/
/** \ingroup signature
* \file lib/signature.c
*/
@@ -235,7 +234,8 @@ static int makePGPSignature(const char * file, /*@out@*/ void ** sig,
/*@out@*/ int_32 * size, /*@null@*/ const char * passPhrase)
/*@globals rpmGlobalMacroContext,
fileSystem @*/
- /*@modifies *sig, *size, fileSystem @*/
+ /*@modifies *sig, *size, rpmGlobalMacroContext,
+ fileSystem @*/
{
char * sigfile = alloca(1024);
int pid, status;
@@ -337,7 +337,8 @@ static int makeGPGSignature(const char * file, /*@out@*/ void ** sig,
/*@out@*/ int_32 * size, /*@null@*/ const char * passPhrase)
/*@globals rpmGlobalMacroContext,
fileSystem @*/
- /*@modifies *sig, *size, fileSystem @*/
+ /*@modifies *sig, *size, rpmGlobalMacroContext,
+ fileSystem @*/
{
char * sigfile = alloca(1024);
int pid, status;
@@ -453,355 +454,11 @@ int rpmAddSignature(Header h, const char * file, int_32 sigTag,
return ret;
}
-/*@-globuse@*/
-static rpmVerifySignatureReturn
-verifySizeSignature(const char * datafile, int_32 size, /*@out@*/ char * result)
- /*@globals fileSystem @*/
- /*@modifies *result, fileSystem @*/
-{
- struct stat st;
-
- (void) stat(datafile, &st);
- if (size != st.st_size) {
- sprintf(result, "Header+Archive size mismatch.\n"
- "Expected %d, saw %d.\n",
- size, (int)st.st_size);
- return RPMSIG_BAD;
- }
-
- sprintf(result, "Header+Archive size OK: %d bytes\n", size);
- return RPMSIG_OK;
-}
-/*@=globuse@*/
-
-/*@-globuse@*/
-static rpmVerifySignatureReturn
-verifyMD5Signature(const char * datafile, const byte * sig, int siglen,
- const rpmDigest dig, /*@out@*/ char * result, md5func fn)
- /*@globals fileSystem @*/
- /*@modifies *result, fileSystem @*/
-{
- char * t = result;
- byte * md5sum = NULL;
- size_t md5len = 0;
- int res = RPMSIG_BAD;
-
- /*@-branchstate@*/
- if (dig != NULL) {
-/*@-type@*/
- DIGEST_CTX ctx = rpmDigestDup(dig->md5ctx);
- (void) rpmDigestFinal(ctx, (void **)&md5sum, &md5len, 0);
-/*@=type@*/
- } else {
- int xx;
- md5len = 16;
- md5sum = xcalloc(1, md5len);
- xx = fn(datafile, md5sum);
- }
- /*@=branchstate@*/
-
- if (md5len != siglen || memcmp(md5sum, sig, md5len)) {
- res = RPMSIG_BAD;
- t = stpcpy(t, " Expected: ");
- (void) pgpHexCvt(t, sig, siglen);
- t += strlen(t);
- t = stpcpy(t, " Actual: ");
- } else {
- res = RPMSIG_OK;
- t = stpcpy(t, "MD5 sum OK: ");
- }
- (void) pgpHexCvt(t, md5sum, md5len);
-
- md5sum = _free(md5sum);
-
- return res;
-}
-/*@=globuse@*/
-
-static rpmVerifySignatureReturn
-verifyPGPSignature(/*@unused@*/ const char * datafile,
- /*@unused@*/ const byte * sig,
- /*@unused@*/ int siglen,
- const rpmDigest dig, /*@out@*/ char * result)
- /*@modifies *result */
-{
- int res, resbc;
-
- *result = '\0';
-
- /*@-type@*/
- if (rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c)) {
- res = resbc = RPMSIG_OK;
- } else {
- res = resbc = RPMSIG_BAD;
- }
- /*@=type@*/
-
-#ifdef DYING
- { int pid, status, outpipe[2];
-/*@only@*/ /*@null@*/ const char * sigfile = NULL;
- byte buf[BUFSIZ];
- FILE *file;
- const char *path;
- pgpVersion pgpVer;
-
- /* What version do we have? */
- if ((path = rpmDetectPGPVersion(&pgpVer)) == NULL) {
- errno = ENOENT;
- rpmError(RPMERR_EXEC,
- _("Could not run pgp. Use --nopgp to skip PGP checks.\n"));
- _exit(RPMERR_EXEC);
- }
-
- /*
- * Sad but true: pgp-5.0 returns exit value of 0 on bad signature.
- * Instead we have to use the text output to detect a bad signature.
- */
- if (pgpVer == PGP_5)
- res = RPMSIG_BAD;
-
- /* Write out the signature */
-#ifdef DYING
- { const char *tmppath = rpmGetPath("%{_tmppath}", NULL);
- sigfile = tempnam(tmppath, "rpmsig");
- tmppath = _free(tmppath);
- }
- sfd = Fopen(sigfile, "w.fdio");
- if (sfd != NULL && !Ferror(sfd)) {
- (void) Fwrite(sig, sizeof(char), siglen, sfd);
- (void) Fclose(sfd);
- }
-#else
- { FD_t sfd;
- if (!makeTempFile(NULL, &sigfile, &sfd)) {
- (void) Fwrite(sig, sizeof(*sig), siglen, sfd);
- (void) Fclose(sfd);
- sfd = NULL;
- }
- }
-#endif
- if (sigfile == NULL)
- return RPMSIG_BAD;
-
- /* Now run PGP */
- outpipe[0] = outpipe[1] = 0;
- (void) pipe(outpipe);
-
- if (!(pid = fork())) {
- const char *pgp_path = rpmExpand("%{_pgp_path}", NULL);
-
- (void) close(outpipe[0]);
- (void) close(STDOUT_FILENO); /* XXX unnecessary */
- (void) dup2(outpipe[1], STDOUT_FILENO);
-
- if (pgp_path && *pgp_path != '%')
- (void) dosetenv("PGPPATH", pgp_path, 1);
-
- switch (pgpVer) {
- case PGP_5:
- /* Some output (in particular "This signature applies to */
- /* another message") is _always_ written to stderr; we */
- /* want to catch that output, so dup stdout to stderr: */
- { int save_stderr = dup(2);
- (void) dup2(1, 2);
- (void) execlp(path, "pgpv", "+batchmode=on", "+verbose=0",
- /* Write "Good signature..." to stdout: */
- "+OutputInformationFD=1",
- /* Write "WARNING: ... is not trusted to... to stdout: */
- "+OutputWarningFD=1",
- sigfile, "-o", datafile, NULL);
- /* Restore stderr so we can print the error message below. */
- (void) dup2(save_stderr, 2);
- (void) close(save_stderr);
- } break;
- case PGP_2:
- (void) execlp(path, "pgp", "+batchmode=on", "+verbose=0",
- sigfile, datafile, NULL);
- break;
- case PGP_UNKNOWN:
- case PGP_NOTDETECTED:
- break;
- }
-
- rpmError(RPMERR_EXEC,
- _("Could not run pgp. Use --nopgp to skip PGP checks.\n"));
- _exit(RPMERR_EXEC);
- }
-
- (void) close(outpipe[1]);
- file = fdopen(outpipe[0], "r");
- result[0] = '\0';
- if (file) {
- while (fgets(buf, 1024, file)) {
- if (strncmp("File '", buf, 6) &&
- strncmp("Text is assu", buf, 12) &&
- strncmp("This signature applies to another message", buf, 41) &&
- buf[0] != '\n') {
- strcat(result, buf);
- }
- if (!strncmp("WARNING: Can't find the right public key", buf, 40))
- res = RPMSIG_NOKEY;
- else if (!strncmp("Signature by unknown keyid:", buf, 27))
- res = RPMSIG_NOKEY;
- else if (!strncmp("WARNING: The signing key is not trusted", buf, 39))
- res = RPMSIG_NOTTRUSTED;
- else if (!strncmp("Good signature", buf, 14))
- res = RPMSIG_OK;
- }
- (void) fclose(file);
- }
-
- (void) waitpid(pid, &status, 0);
- if (sigfile) (void) unlink(sigfile);
- sigfile = _free(sigfile);
- if (!res && (!WIFEXITED(status) || WEXITSTATUS(status))) {
- res = RPMSIG_BAD;
- }
- }
-
- if (res != resbc) {
- fprintf(stderr, "=============================== RSA verify %s: rc %d\n",
- datafile, resbc);
- (void) pgpPrtPkts(sig, siglen, dig, 1);
- printf("\t n = "); (void) fflush(stdout);
- mp32println(dig->rsa_pk.n.size, dig->rsa_pk.n.modl);
- printf("\t e = "); (void) fflush(stdout);
- mp32println(dig->rsa_pk.e.size, dig->rsa_pk.e.data);
- printf("\t c = "); (void) fflush(stdout);
- mp32println(dig->c.size, dig->c.data);
- printf("\t m = "); (void)fflush(stdout);
- mp32println(dig->rsahm.size, dig->rsahm.data);
- }
-#endif /* DYING */
-
- return res;
-}
-
-static rpmVerifySignatureReturn
-verifyGPGSignature(/*@unused@*/ const char * datafile,
- /*@unused@*/ const byte * sig,
- /*@unused@*/ int siglen,
- const rpmDigest dig, /*@out@*/ char * result)
- /*@modifies *result @*/
-{
- int res, resbc;
-
- *result = '\0';
-
- /*@-type@*/
- if (dsavrfy(&dig->p, &dig->q, &dig->g, &dig->hm, &dig->y, &dig->r, &dig->s))
- res = resbc = RPMSIG_OK;
- else
- res = resbc = RPMSIG_BAD;
- /*@=type@*/
-
-#ifdef DYING
- {
- int pid, status, outpipe[2];
-/*@only@*/ /*@null@*/ const char * sigfile = NULL;
- byte buf[BUFSIZ];
- FILE *file;
- int res = RPMSIG_OK;
-
-/*@-type@*/
-/*@=type@*/
-
- /* Write out the signature */
-#ifdef DYING
- { const char *tmppath = rpmGetPath("%{_tmppath}", NULL);
- sigfile = tempnam(tmppath, "rpmsig");
- tmppath = _free(tmppath);
- }
- sfd = Fopen(sigfile, "w.fdio");
- if (sfd != NULL && !Ferror(sfd)) {
- (void) Fwrite(sig, sizeof(char), siglen, sfd);
- (void) Fclose(sfd);
- }
-#else
- { FD_t sfd;
- if (!makeTempFile(NULL, &sigfile, &sfd)) {
- (void) Fwrite(sig, sizeof(*sig), siglen, sfd);
- (void) Fclose(sfd);
- sfd = NULL;
- }
- }
-#endif
- if (sigfile == NULL)
- return RPMSIG_BAD;
-
- /* Now run GPG */
- outpipe[0] = outpipe[1] = 0;
- (void) pipe(outpipe);
-
- if (!(pid = fork())) {
- const char *gpg_path = rpmExpand("%{_gpg_path}", NULL);
-
- (void) close(outpipe[0]);
- /* gpg version 0.9 sends its output to stderr. */
- (void) dup2(outpipe[1], STDERR_FILENO);
-
- if (gpg_path && *gpg_path != '%')
- (void) dosetenv("GNUPGHOME", gpg_path, 1);
-
- (void) execlp("gpg", "gpg",
- "--batch", "--no-verbose",
- "--verify", sigfile, datafile,
- NULL);
- rpmError(RPMERR_EXEC,
- _("Could not run gpg. Use --nogpg to skip GPG checks.\n"));
- _exit(RPMERR_EXEC);
- }
-
- (void) close(outpipe[1]);
- file = fdopen(outpipe[0], "r");
- result[0] = '\0';
- if (file) {
- while (fgets(buf, 1024, file)) {
- strcat(result, buf);
- if (!xstrncasecmp("gpg: Can't check signature: Public key not found", buf, 48)) {
- res = RPMSIG_NOKEY;
- }
- }
- (void) fclose(file);
- }
-
- (void) waitpid(pid, &status, 0);
- if (sigfile) (void) unlink(sigfile);
- sigfile = _free(sigfile);
- if (!res && (!WIFEXITED(status) || WEXITSTATUS(status))) {
- res = RPMSIG_BAD;
- }
-
- }
-
- if (res != resbc) {
- fprintf(stderr, "=============================== DSA verify %s: rc %d\n",
- datafile, resbc);
- (void) pgpPrtPkts(sig, siglen, dig, 1);
- printf("\t p = "); (void) fflush(stdout);
- mp32println(dig->p.size, dig->p.modl);
- printf("\t q = "); (void) fflush(stdout);
- mp32println(dig->q.size, dig->q.modl);
- printf("\t g = "); (void) fflush(stdout);
- mp32println(dig->g.size, dig->g.data);
- printf("\t y = "); (void) fflush(stdout);
- mp32println(dig->y.size, dig->y.data);
- printf("\t r = "); (void) fflush(stdout);
- mp32println(dig->r.size, dig->r.data);
- printf("\t s = "); (void) fflush(stdout);
- mp32println(dig->s.size, dig->s.data);
- printf("\thm = "); (void) fflush(stdout);
- mp32println(dig->hm.size, dig->hm.data);
- }
-#endif
-
- return res;
-}
-
static int checkPassPhrase(const char * passPhrase, const int sigTag)
/*@globals rpmGlobalMacroContext,
fileSystem @*/
- /*@modifies fileSystem @*/
+ /*@modifies rpmGlobalMacroContext,
+ fileSystem @*/
{
int passPhrasePipe[2];
int pid, status;
@@ -937,31 +594,150 @@ char * rpmGetPassPhrase(const char * prompt, const int sigTag)
return pass;
}
+static rpmVerifySignatureReturn
+verifySizeSignature(/*@unused@*/ const char * fn,
+ const byte * sig,
+ /*@unused@*/ int siglen,
+ const rpmDigest dig, /*@out@*/ char * result)
+ /*@modifies *result @*/
+{
+ char * t = result;
+ int_32 size = *(int_32 *)sig;
+ int res;
+
+ *t = '\0';
+ t = stpcpy(t, "Header+Payload size: ");
+
+ /*@-type@*/
+ if (size != dig->nbytes) {
+ res = RPMSIG_BAD;
+ sprintf(t, "BAD Expected(%d) != (%d)\n", size, dig->nbytes);
+ } else {
+ res = RPMSIG_OK;
+ sprintf(t, "OK (%d)\n", dig->nbytes);
+ }
+ /*@=type@*/
+
+ return res;
+}
+
+static rpmVerifySignatureReturn
+verifyMD5Signature(/*@unused@*/ const char * fn, const byte * sig, int siglen,
+ const rpmDigest dig, /*@out@*/ char * result)
+ /*@modifies *result @*/
+{
+ char * t = result;
+ byte * md5sum = NULL;
+ size_t md5len = 0;
+ int res;
+
+ /*@-type@*/
+ (void) rpmDigestFinal(rpmDigestDup(dig->md5ctx),
+ (void **)&md5sum, &md5len, 0);
+ /*@=type@*/
+
+ *t = '\0';
+ t = stpcpy(t, "MD5 digest: ");
+
+ if (md5len != siglen || memcmp(md5sum, sig, md5len)) {
+ res = RPMSIG_BAD;
+ t = stpcpy(t, "BAD Expected(");
+ (void) pgpHexCvt(t, sig, siglen);
+ t += strlen(t);
+ t = stpcpy(t, ") != (");
+ } else {
+ res = RPMSIG_OK;
+ t = stpcpy(t, "OK (");
+ }
+ (void) pgpHexCvt(t, md5sum, md5len);
+ t += strlen(t);
+ t = stpcpy(t, ")\n");
+
+ md5sum = _free(md5sum);
+
+ return res;
+}
+
+static rpmVerifySignatureReturn
+verifyPGPSignature(/*@unused@*/ const char * fn,
+ /*@unused@*/ const byte * sig,
+ /*@unused@*/ int siglen,
+ const rpmDigest dig, /*@out@*/ char * result)
+ /*@modifies *result */
+{
+ char * t = result;
+ int res;
+
+ *t = '\0';
+ t = stpcpy(t, "V3 RSA/MD5 signature: ");
+
+ /*@-type@*/
+ if (!rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c)) {
+ res = RPMSIG_BAD;
+ t = stpcpy(t, "BAD\n");
+ } else {
+ res = RPMSIG_OK;
+ t = stpcpy(t, "OK\n");
+ }
+ /*@=type@*/
+
+ return res;
+}
+
+static rpmVerifySignatureReturn
+verifyGPGSignature(/*@unused@*/ const char * fn,
+ /*@unused@*/ const byte * sig,
+ /*@unused@*/ int siglen,
+ const rpmDigest dig, /*@out@*/ char * result)
+ /*@modifies *result @*/
+{
+ char * t = result;
+ int res;
+
+ *t = '\0';
+ t = stpcpy(t, "V3 DSA signature: ");
+
+ /*@-type@*/
+ if (!dsavrfy(&dig->p, &dig->q, &dig->g, &dig->hm, &dig->y, &dig->r, &dig->s)) {
+ res = RPMSIG_BAD;
+ t = stpcpy(t, "BAD\n");
+ } else {
+ res = RPMSIG_OK;
+ t = stpcpy(t, "OK\n");
+ }
+ /*@=type@*/
+
+ return res;
+}
+
rpmVerifySignatureReturn
-rpmVerifySignature(const char * file, int_32 sigTag, const void * sig,
+rpmVerifySignature(const char * fn, int_32 sigTag, const void * sig,
int siglen, const rpmDigest dig, char * result)
{
+ int res;
switch (sigTag) {
case RPMSIGTAG_SIZE:
- return verifySizeSignature(file, *(int_32 *)sig, result);
- /*@notreached@*/ break;
+ res = verifySizeSignature(fn, sig, siglen, dig, result);
+ break;
case RPMSIGTAG_MD5:
- return verifyMD5Signature(file, sig, siglen, dig, result, mdbinfile);
- /*@notreached@*/ break;
+ res = verifyMD5Signature(fn, sig, siglen, dig, result);
+ break;
case RPMSIGTAG_PGP5: /* XXX legacy */
case RPMSIGTAG_PGP:
- return verifyPGPSignature(file, sig, siglen, dig, result);
- /*@notreached@*/ break;
+ res = verifyPGPSignature(fn, sig, siglen, dig, result);
+ break;
case RPMSIGTAG_GPG:
- return verifyGPGSignature(file, sig, siglen, dig, result);
- /*@notreached@*/ break;
+ res = verifyGPGSignature(fn, sig, siglen, dig, result);
+ break;
case RPMSIGTAG_LEMD5_1:
case RPMSIGTAG_LEMD5_2:
+ sprintf(result, "Broken MD5 digest: UNSUPPORTED\n");
+ res = RPMSIG_UNKNOWN;
+ break;
default:
- sprintf(result, "Do not know how to verify sig type %d\n", sigTag);
- return RPMSIG_UNKNOWN;
+ sprintf(result, "Signature: UNKNOWN(%d)\n", sigTag);
+ res = RPMSIG_UNKNOWN;
+ break;
}
- /*@notreached@*/
- return RPMSIG_OK;
+ return res;
}
-/*@=mods@*/