From dc2a236ff40590aed707ff007261befad7c929d5 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 20 Jun 1996 03:10:44 +0000 Subject: [PATCH] handle new sig types always do at least a MD5 CVS patchset: 658 CVS date: 1996/06/20 03:10:44 --- lib/signature.c | 348 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 218 insertions(+), 130 deletions(-) diff --git a/lib/signature.c b/lib/signature.c index f4f8944..d7666de 100644 --- a/lib/signature.c +++ b/lib/signature.c @@ -2,15 +2,12 @@ /* NOTES * - * A PGP 2.6.2 1024 bit key generates a 152 byte signature - * A ViaCryptPGP 2.7.1 1024 bit key generates a 152 byte signature - * A PGP 2.6.2 768 bit key generates a 120 byte signature + * Things have been cleaned up wrt PGP. We can now handle + * signatures of any length (which means you can use any + * size key you like). We also honor PGPPATH finally. * - * This code only only works with 1024 bit keys! - * - * Sometimes we get 151 byte signatures. Not sure why, but if we - * do, we toss it and try once more to get a 152 bytes signature. - * If we still get a 151 byte sig, fail. :-( + * We are aligning the sig section on disk to 8 bytes. + * The lead is already 8 byte aligned. */ #include @@ -22,16 +19,67 @@ #include #include "signature.h" +#include "md5.h" #include "rpmlib.h" #include "rpmerr.h" +static int makeMD5Signature(char *file, int ofd); static int makePGPSignature(char *file, int ofd, char *passPhrase); static int verifyPGPSignature(int fd, void *sig, char *result); static int checkPassPhrase(char *passPhrase); +unsigned short sigLookupType(void) +{ + char *name; + + /* Now we always generate at least a RPMSIG_MD5 */ + + if (! (name = getVar(RPMVAR_SIGTYPE))) { + return RPMSIG_MD5; + } + + if (!strcasecmp(name, "none")) { + return RPMSIG_MD5; + } else if (!strcasecmp(name, "pgp")) { + return RPMSIG_MD5_PGP; + } else { + return RPMSIG_BAD; + } +} + +int verifySignature(int fd, short sig_type, void *sig, char *result) +{ + switch (sig_type) { + case RPMSIG_NONE: + strcpy(result, "No signature information available\n"); + return RPMSIG_NOSIG; + break; + case RPMSIG_PGP262_1024: + if (verifyPGPSignature(fd, sig, result)) { + return RPMSIG_BADSIG; + } + break; + case RPMSIG_MD5: + case RPMSIG_MD5_PGP: + /* XXX */ + fprintf(stderr, "Almost there...\n"); + break; + default: + sprintf(result, "Unimplemented signature type\n"); + return RPMSIG_UNKNOWNSIG; + break; + } + + return RPMSIG_SIGOK; +} + +/* We need to be careful here to do 8 byte alignment */ +/* when reading any of the "new" style signatures. */ + int readSignature(int fd, short sig_type, void **sig) { - unsigned char pgpbuf[256]; + unsigned char buf[2048]; + int length; switch (sig_type) { case RPMSIG_NONE: @@ -40,14 +88,48 @@ int readSignature(int fd, short sig_type, void **sig) } break; case RPMSIG_PGP262_1024: - if (read(fd, pgpbuf, 256) != 256) { + /* These are always 256 bytes */ + if (read(fd, buf, 256) != 256) { return 0; } if (sig) { *sig = malloc(152); - memcpy(*sig, pgpbuf, 152); + memcpy(*sig, buf, 152); } break; + case RPMSIG_MD5: + /* 8 byte aligned */ + if (read(fd, buf, 16) != 16) { + return 0; + } + if (sig) { + *sig = malloc(16); + memcpy(*sig, buf, 16); + } + break; + case RPMSIG_MD5_PGP: + /* 8 byte aligned */ + if (read(fd, buf, 18) != 18) { + return 0; + } + length = buf[16] * 256 + buf[17]; + if (read(fd, buf + 18, length) != length) { + return 0; + } + if (sig) { + *sig = malloc(18 + length); + memcpy(*sig, buf, 18 + length); + } + /* The is the align magic */ + length = (8 - ((length + 18) % 8)) % 8; + if (length) { + if (read(fd, buf, length) != length) { + return 0; + } + } + break; + default: + return 0; } return 1; @@ -55,10 +137,10 @@ int readSignature(int fd, short sig_type, void **sig) int makeSignature(char *file, short sig_type, int ofd, char *passPhrase) { - int res; - switch (sig_type) { case RPMSIG_PGP262_1024: + /* We no longer generate these */ +#if 0 if (! getVar(RPMVAR_PGP_NAME)) { error(RPMERR_SIGGEN, "You must set \"pgp_name:\" in /etc/rpmrc\n"); return RPMERR_SIGGEN; @@ -68,6 +150,30 @@ int makeSignature(char *file, short sig_type, int ofd, char *passPhrase) return makePGPSignature(file, ofd, passPhrase); } return res; +#endif + error(RPMERR_SIGGEN, "Internal error! RPMSIG_PGP262_1024\n"); + return RPMERR_SIGGEN; + break; + case RPMSIG_MD5: + if (makeMD5Signature(file, ofd)) { + error(RPMERR_SIGGEN, "Unable to generate MD5 signature\n"); + return RPMERR_SIGGEN; + } + break; + case RPMSIG_MD5_PGP: + if (! getVar(RPMVAR_PGP_NAME)) { + error(RPMERR_SIGGEN, "You must set \"pgp_name:\" in /etc/rpmrc\n"); + return RPMERR_SIGGEN; + } + if (makeMD5Signature(file, ofd)) { + error(RPMERR_SIGGEN, "Unable to generate MD5 signature\n"); + return RPMERR_SIGGEN; + } + /* makePGPSignature() takes care of 8 byte alignment */ + if (makePGPSignature(file, ofd, passPhrase)) { + error(RPMERR_SIGGEN, "Unable to generate PGP signature\n"); + return RPMERR_SIGGEN; + } break; case RPMSIG_NONE: } @@ -75,100 +181,28 @@ int makeSignature(char *file, short sig_type, int ofd, char *passPhrase) return 0; } -#if 0 -void ttycbreak(void) +static int makeMD5Signature(char *file, int ofd) { - int tty; - - if ((tty = open("/dev/tty", O_RDWR)) < 0) { - fprintf(stderr, "Unable to open tty. Using standard input.\n"); - tty = 0; - } - - -} -#endif - -char *getPassPhrase(char *prompt) -{ - char *pass; + unsigned char sig[16]; - if (! getVar(RPMVAR_PGP_NAME)) { - error(RPMERR_SIGGEN, - "You must set \"pgp_name:\" in your rpmrc file"); - return NULL; - } - - if (prompt) { - pass = getpass(prompt); - } else { - pass = getpass(""); - } - - if (checkPassPhrase(pass)) { - return NULL; - } - - return pass; -} - -static int checkPassPhrase(char *passPhrase) -{ - char name[1024]; - int passPhrasePipe[2]; - FILE *fpipe; - int pid, status; - int fd; - - sprintf(name, "+myname=\"%s\"", getVar(RPMVAR_PGP_NAME)); - - pipe(passPhrasePipe); - if (!(pid = fork())) { - close(0); - close(1); - if (! isVerbose()) { - close(2); - } - if ((fd = open("/dev/null", O_RDONLY)) != 0) { - dup2(fd, 0); - } - if ((fd = open("/dev/null", O_WRONLY)) != 1) { - dup2(fd, 1); - } - dup2(passPhrasePipe[0], 3); - setenv("PGPPASSFD", "3", 1); - if (getVar(RPMVAR_PGP_PATH)) { - setenv("PGPPATH", getVar(RPMVAR_PGP_PATH), 1); - } - execlp("pgp", "pgp", - "+batchmode=on", "+verbose=0", - name, "-sf", - NULL); - error(RPMERR_EXEC, "Couldn't exec pgp"); - exit(RPMERR_EXEC); - } - - fpipe = fdopen(passPhrasePipe[1], "w"); - close(passPhrasePipe[0]); - fprintf(fpipe, "%s\n", passPhrase); - fclose(fpipe); - - waitpid(pid, &status, 0); - if (!WIFEXITED(status) || WEXITSTATUS(status)) { + mdbinfile(file, sig); + if (write(ofd, sig, 16) != 16) { return 1; } - - /* passPhrase is good */ + return 0; } +/* Be sure to handle 8 byte alignment! */ + static int makePGPSignature(char *file, int ofd, char *passPhrase) { + unsigned char length[2]; char name[1024]; char sigfile[1024]; - int pid, status; + int pid, status, len; int fd, inpipe[2]; - unsigned char sigbuf[256]; /* 1024bit sig is 152 bytes */ + unsigned char sigbuf[2048]; /* 1024bit sig is ~152 bytes */ FILE *fpipe; struct stat statbuf; @@ -212,24 +246,42 @@ static int makePGPSignature(char *file, int ofd, char *passPhrase) error(RPMERR_SIGGEN, "pgp failed to write signature"); return 1; } - if (statbuf.st_size != 152) { - /* 151 byte sig hack */ - unlink(sigfile); - error(RPMERR_SIGGEN, "pgp failed to write 152 byte signature"); - return -1; - } + + /* Fill in the length, data, and then 8 byte alignment magic */ + len = statbuf.st_size; + length[0] = len / 256; + length[1] = len % 256; + write(ofd, length, 2); fd = open(sigfile, O_RDONLY); - if (read(fd, sigbuf, 152) != 152) { /* signature is 152 bytes */ + if (read(fd, sigbuf, len) != len) { + unlink(sigfile); + close(fd); + error(RPMERR_SIGGEN, "unable to read the signature"); + return 1; + } + if (write(ofd, sigbuf, len) != len) { unlink(sigfile); close(fd); - error(RPMERR_SIGGEN, "unable to read 152 bytes of signature"); + error(RPMERR_SIGGEN, "unable to write the signature"); return 1; } close(fd); unlink(sigfile); - write(ofd, sigbuf, 256); /* We write an even 256 bytes */ + message(MESS_DEBUG, "Wrote %d bytes of PGP sig\n", len); + + /* Now the alignment */ + len = (8 - ((len + 18) % 8)) % 8; + if (len) { + memset(sigbuf, 0xff, len); + if (write(ofd, sigbuf, len) != len) { + close(fd); + error(RPMERR_SIGGEN, "unable to write the alignment cruft"); + return 1; + } + message(MESS_DEBUG, "Wrote %d bytes of alignment cruft\n", len); + } return 0; } @@ -245,6 +297,7 @@ static int verifyPGPSignature(int fd, void *sig, char *result) /* Write out the signature */ sigfile = tempnam("/var/tmp", "rpmsig"); sfd = open(sigfile, O_WRONLY|O_CREAT|O_TRUNC, 0644); + /* XXX */ write(sfd, sig, 152); close(sfd); @@ -295,40 +348,75 @@ static int verifyPGPSignature(int fd, void *sig, char *result) return(0); } -int verifySignature(int fd, short sig_type, void *sig, char *result) +char *getPassPhrase(char *prompt) { - switch (sig_type) { - case RPMSIG_NONE: - strcpy(result, "No signature information available\n"); - return RPMSIG_NOSIG; - break; - case RPMSIG_PGP262_1024: - if (verifyPGPSignature(fd, sig, result)) { - return RPMSIG_BADSIG; - } - break; - default: - sprintf(result, "Unimplemented signature type\n"); - return RPMSIG_UNKNOWNSIG; - break; + char *pass; + + if (! getVar(RPMVAR_PGP_NAME)) { + error(RPMERR_SIGGEN, + "You must set \"pgp_name:\" in your rpmrc file"); + return NULL; } - return RPMSIG_SIGOK; + if (prompt) { + pass = getpass(prompt); + } else { + pass = getpass(""); + } + + if (checkPassPhrase(pass)) { + return NULL; + } + + return pass; } -unsigned short sigLookupType(void) +static int checkPassPhrase(char *passPhrase) { - char *name; + char name[1024]; + int passPhrasePipe[2]; + FILE *fpipe; + int pid, status; + int fd; - if (! (name = getVar(RPMVAR_SIGTYPE))) { - return RPMSIG_NONE; + sprintf(name, "+myname=\"%s\"", getVar(RPMVAR_PGP_NAME)); + + pipe(passPhrasePipe); + if (!(pid = fork())) { + close(0); + close(1); + if (! isVerbose()) { + close(2); + } + if ((fd = open("/dev/null", O_RDONLY)) != 0) { + dup2(fd, 0); + } + if ((fd = open("/dev/null", O_WRONLY)) != 1) { + dup2(fd, 1); + } + dup2(passPhrasePipe[0], 3); + setenv("PGPPASSFD", "3", 1); + if (getVar(RPMVAR_PGP_PATH)) { + setenv("PGPPATH", getVar(RPMVAR_PGP_PATH), 1); + } + execlp("pgp", "pgp", + "+batchmode=on", "+verbose=0", + name, "-sf", + NULL); + error(RPMERR_EXEC, "Couldn't exec pgp"); + exit(RPMERR_EXEC); } - if (!strcasecmp(name, "none")) { - return RPMSIG_NONE; - } else if (!strcasecmp(name, "pgp")) { - return RPMSIG_PGP262_1024; - } else { - return RPMSIG_BAD; + fpipe = fdopen(passPhrasePipe[1], "w"); + close(passPhrasePipe[0]); + fprintf(fpipe, "%s\n", passPhrase); + fclose(fpipe); + + waitpid(pid, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status)) { + return 1; } + + /* passPhrase is good */ + return 0; } -- 2.7.4