00001
00005 #include "system.h"
00006
00007 #include "rpmio_internal.h"
00008 #include <rpmlib.h>
00009 #include <rpmmacro.h>
00010 #include "rpmdb.h"
00011
00012 #include "rpmts.h"
00013
00014 #include "misc.h"
00015 #include "legacy.h"
00016 #include "rpmlead.h"
00017 #include "signature.h"
00018 #include "header_internal.h"
00019 #include "debug.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #if !defined(__GLIBC__) && !defined(__APPLE__)
00030 char ** environ = NULL;
00031 #endif
00032
00033 int rpmLookupSignatureType(int action)
00034 {
00035
00036 static int disabled = 0;
00037 int rc = 0;
00038
00039 switch (action) {
00040 case RPMLOOKUPSIG_DISABLE:
00041 disabled = -2;
00042 break;
00043 case RPMLOOKUPSIG_ENABLE:
00044 disabled = 0;
00045
00046 case RPMLOOKUPSIG_QUERY:
00047 if (disabled)
00048 break;
00049
00050 { const char *name = rpmExpand("%{?_signature}", NULL);
00051 if (!(name && *name != '\0'))
00052 rc = 0;
00053 else if (!xstrcasecmp(name, "none"))
00054 rc = 0;
00055 else if (!xstrcasecmp(name, "pgp"))
00056 rc = RPMSIGTAG_PGP;
00057 else if (!xstrcasecmp(name, "pgp5"))
00058 rc = RPMSIGTAG_PGP;
00059 else if (!xstrcasecmp(name, "gpg"))
00060 rc = RPMSIGTAG_GPG;
00061 else
00062 rc = -1;
00063 name = _free(name);
00064 } break;
00065
00066 }
00067 return rc;
00068 }
00069
00070
00071
00072
00073 const char * rpmDetectPGPVersion(pgpVersion * pgpVer)
00074 {
00075
00076
00077
00078
00079 static pgpVersion saved_pgp_version = PGP_UNKNOWN;
00080 const char *pgpbin = rpmGetPath("%{?_pgpbin}", NULL);
00081
00082 if (saved_pgp_version == PGP_UNKNOWN) {
00083 char *pgpvbin;
00084 struct stat st;
00085
00086
00087 if (!(pgpbin && pgpbin[0] != '\0')) {
00088 pgpbin = _free(pgpbin);
00089 saved_pgp_version = -1;
00090 return NULL;
00091 }
00092
00093
00094 pgpvbin = (char *)alloca(strlen(pgpbin) + sizeof("v"));
00095 (void)stpcpy(stpcpy(pgpvbin, pgpbin), "v");
00096
00097
00098 if (stat(pgpvbin, &st) == 0)
00099 saved_pgp_version = PGP_5;
00100 else if (stat(pgpbin, &st) == 0)
00101 saved_pgp_version = PGP_2;
00102 else
00103 saved_pgp_version = PGP_NOTDETECTED;
00104 }
00105
00106
00107 if (pgpVer && pgpbin)
00108 *pgpVer = saved_pgp_version;
00109
00110 return pgpbin;
00111 }
00112
00122 static inline rpmRC printSize(FD_t fd, int siglen, int pad, int datalen)
00123
00124
00125 {
00126 struct stat st;
00127 int fdno = Fileno(fd);
00128
00129
00130 if (fdno == 123456789) {
00131 st.st_size = 0;
00132
00133 st.st_size -= sizeof(struct rpmlead)+siglen+pad+datalen;
00134
00135 } else if (fstat(fdno, &st) < 0)
00136 return RPMRC_FAIL;
00137
00138
00139 rpmMessage(RPMMESS_DEBUG,
00140 _("Expected size: %12d = lead(%d)+sigs(%d)+pad(%d)+data(%d)\n"),
00141 (int)sizeof(struct rpmlead)+siglen+pad+datalen,
00142 (int)sizeof(struct rpmlead), siglen, pad, datalen);
00143
00144 rpmMessage(RPMMESS_DEBUG,
00145 _(" Actual size: %12d\n"), (int)st.st_size);
00146
00147 return RPMRC_OK;
00148 }
00149
00150
00151 static unsigned char header_magic[8] = {
00152 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00153 };
00154
00155 rpmRC rpmReadSignature(FD_t fd, Header * sighp, sigType sig_type,
00156 const char ** msg)
00157 {
00158 char buf[BUFSIZ];
00159 int_32 block[4];
00160 int_32 il;
00161 int_32 dl;
00162 int_32 * ei = NULL;
00163 entryInfo pe;
00164 size_t nb;
00165 int_32 ril = 0;
00166 indexEntry entry = memset(alloca(sizeof(*entry)), 0, sizeof(*entry));
00167 entryInfo info = memset(alloca(sizeof(*info)), 0, sizeof(*info));
00168 unsigned char * dataStart;
00169 unsigned char * dataEnd = NULL;
00170 Header sigh = NULL;
00171 rpmRC rc = RPMRC_FAIL;
00172 int xx;
00173 int i;
00174
00175
00176 if (sighp)
00177 *sighp = NULL;
00178
00179 buf[0] = '\0';
00180
00181
00182 if (sig_type != RPMSIGTYPE_HEADERSIG)
00183 goto exit;
00184
00185 memset(block, 0, sizeof(block));
00186 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
00187 (void) snprintf(buf, sizeof(buf),
00188 _("sigh size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
00189 goto exit;
00190 }
00191 if (memcmp(block, header_magic, sizeof(header_magic))) {
00192 (void) snprintf(buf, sizeof(buf),
00193 _("sigh magic: BAD\n"));
00194 goto exit;
00195 }
00196
00197 il = ntohl(block[2]);
00198
00199 if (il < 0 || il > 32) {
00200 (void) snprintf(buf, sizeof(buf),
00201 _("sigh tags: BAD, no. of tags(%d) out of range\n"), il);
00202 goto exit;
00203 }
00204
00205 dl = ntohl(block[3]);
00206
00207 if (dl < 0 || dl > 8192) {
00208 (void) snprintf(buf, sizeof(buf),
00209 _("sigh data: BAD, no. of bytes(%d) out of range\n"), dl);
00210 goto exit;
00211 }
00212
00213
00214 nb = (il * sizeof(struct entryInfo_s)) + dl;
00215
00216 ei = xmalloc(sizeof(il) + sizeof(dl) + nb);
00217
00218 ei[0] = block[2];
00219 ei[1] = block[3];
00220 pe = (entryInfo) &ei[2];
00221
00222 dataStart = (unsigned char *) (pe + il);
00223 if ((xx = timedRead(fd, (char *)pe, nb)) != nb) {
00224 (void) snprintf(buf, sizeof(buf),
00225 _("sigh blob(%d): BAD, read returned %d\n"), (int)nb, xx);
00226 goto exit;
00227 }
00228
00229
00230 xx = headerVerifyInfo(1, dl, pe, &entry->info, 0);
00231 if (xx != -1) {
00232 (void) snprintf(buf, sizeof(buf),
00233 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00234 0, entry->info.tag, entry->info.type,
00235 entry->info.offset, entry->info.count);
00236 goto exit;
00237 }
00238
00239
00240
00241 if (entry->info.tag == RPMTAG_HEADERSIGNATURES
00242 && entry->info.type == RPM_BIN_TYPE
00243 && entry->info.count == REGION_TAG_COUNT)
00244 {
00245
00246
00247 if (entry->info.offset >= dl) {
00248 (void) snprintf(buf, sizeof(buf),
00249 _("region offset: BAD, tag %d type %d offset %d count %d\n"),
00250 entry->info.tag, entry->info.type,
00251 entry->info.offset, entry->info.count);
00252 goto exit;
00253 }
00254
00255
00256 dataEnd = dataStart + entry->info.offset;
00257
00258
00259 (void) memcpy(info, dataEnd, REGION_TAG_COUNT);
00260
00261 if (info->tag == htonl(RPMTAG_HEADERIMAGE)) {
00262 int_32 stag = htonl(RPMTAG_HEADERSIGNATURES);
00263 info->tag = stag;
00264 memcpy(dataEnd, &stag, sizeof(stag));
00265 }
00266
00267 dataEnd += REGION_TAG_COUNT;
00268
00269 xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
00270 if (xx != -1 ||
00271 !((entry->info.tag == RPMTAG_HEADERSIGNATURES || entry->info.tag == RPMTAG_HEADERIMAGE)
00272 && entry->info.type == RPM_BIN_TYPE
00273 && entry->info.count == REGION_TAG_COUNT))
00274 {
00275 (void) snprintf(buf, sizeof(buf),
00276 _("region trailer: BAD, tag %d type %d offset %d count %d\n"),
00277 entry->info.tag, entry->info.type,
00278 entry->info.offset, entry->info.count);
00279 goto exit;
00280 }
00281
00282
00283 memset(info, 0, sizeof(*info));
00284
00285
00286
00287 ril = entry->info.offset/sizeof(*pe);
00288 if ((entry->info.offset % sizeof(*pe)) || ril > il) {
00289 (void) snprintf(buf, sizeof(buf),
00290 _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
00291 goto exit;
00292 }
00293 }
00294
00295
00296
00297 memset(info, 0, sizeof(*info));
00298
00299 for (i = 1; i < il; i++) {
00300 xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0);
00301 if (xx != -1) {
00302 (void) snprintf(buf, sizeof(buf),
00303 _("sigh tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
00304 i, entry->info.tag, entry->info.type,
00305 entry->info.offset, entry->info.count);
00306 goto exit;
00307 }
00308 }
00309
00310
00311 sigh = headerLoad(ei);
00312 if (sigh == NULL) {
00313 (void) snprintf(buf, sizeof(buf), _("sigh load: BAD\n"));
00314 goto exit;
00315 }
00316 sigh->flags |= HEADERFLAG_ALLOCATED;
00317
00318 { int sigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
00319 int pad = (8 - (sigSize % 8)) % 8;
00320 int_32 * archSize = NULL;
00321
00322
00323 if (pad && (xx = timedRead(fd, (char *)block, pad)) != pad) {
00324 (void) snprintf(buf, sizeof(buf),
00325 _("sigh pad(%d): BAD, read %d bytes\n"), pad, xx);
00326 goto exit;
00327 }
00328
00329
00330 if (headerGetEntry(sigh, RPMSIGTAG_SIZE, NULL,(void **)&archSize, NULL)) {
00331 rc = printSize(fd, sigSize, pad, *archSize);
00332 if (rc != RPMRC_OK)
00333 (void) snprintf(buf, sizeof(buf),
00334 _("sigh sigSize(%d): BAD, fstat(2) failed\n"), sigSize);
00335 }
00336 }
00337
00338 exit:
00339
00340 if (sighp && sigh && rc == RPMRC_OK)
00341 *sighp = headerLink(sigh);
00342 sigh = headerFree(sigh);
00343
00344 if (msg != NULL) {
00345 buf[sizeof(buf)-1] = '\0';
00346 *msg = xstrdup(buf);
00347 }
00348
00349
00350 return rc;
00351 }
00352
00353 int rpmWriteSignature(FD_t fd, Header sigh)
00354 {
00355 static byte buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00356 int sigSize, pad;
00357 int rc;
00358
00359 rc = headerWrite(fd, sigh, HEADER_MAGIC_YES);
00360 if (rc)
00361 return rc;
00362
00363 sigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
00364 pad = (8 - (sigSize % 8)) % 8;
00365 if (pad) {
00366
00367 if (Fwrite(buf, sizeof(buf[0]), pad, fd) != pad)
00368 rc = 1;
00369
00370 }
00371 rpmMessage(RPMMESS_DEBUG, _("Signature: size(%d)+pad(%d)\n"), sigSize, pad);
00372 return rc;
00373 }
00374
00375 Header rpmNewSignature(void)
00376 {
00377 Header sigh = headerNew();
00378 return sigh;
00379 }
00380
00381 Header rpmFreeSignature(Header sigh)
00382 {
00383 return headerFree(sigh);
00384 }
00385
00395 static int makePGPSignature(const char * file, int_32 * sigTagp,
00396 byte ** pktp, int_32 * pktlenp,
00397 const char * passPhrase)
00398
00399
00400
00401
00402 {
00403 char * sigfile = alloca(1024);
00404 int pid, status;
00405 int inpipe[2];
00406 struct stat st;
00407 const char * cmd;
00408 char *const *av;
00409 pgpDig dig = NULL;
00410 pgpDigParams sigp = NULL;
00411 int rc;
00412
00413
00414 (void) stpcpy( stpcpy(sigfile, file), ".sig");
00415
00416
00417 addMacro(NULL, "__plaintext_filename", NULL, file, -1);
00418 addMacro(NULL, "__signature_filename", NULL, sigfile, -1);
00419
00420 inpipe[0] = inpipe[1] = 0;
00421
00422 (void) pipe(inpipe);
00423
00424
00425 if (!(pid = fork())) {
00426 const char *pgp_path = rpmExpand("%{?_pgp_path}", NULL);
00427 const char *path;
00428 pgpVersion pgpVer;
00429
00430 (void) close(STDIN_FILENO);
00431 (void) dup2(inpipe[0], 3);
00432 (void) close(inpipe[1]);
00433
00434 (void) dosetenv("PGPPASSFD", "3", 1);
00435
00436 if (pgp_path && *pgp_path != '\0')
00437 (void) dosetenv("PGPPATH", pgp_path, 1);
00438
00439
00440
00441
00442 unsetenv("MALLOC_CHECK_");
00443 if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
00444 switch(pgpVer) {
00445 case PGP_2:
00446 cmd = rpmExpand("%{?__pgp_sign_cmd}", NULL);
00447 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00448
00449 if (!rc)
00450 rc = execve(av[0], av+1, environ);
00451
00452 break;
00453 case PGP_5:
00454 cmd = rpmExpand("%{?__pgp5_sign_cmd}", NULL);
00455 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00456
00457 if (!rc)
00458 rc = execve(av[0], av+1, environ);
00459
00460 break;
00461 case PGP_UNKNOWN:
00462 case PGP_NOTDETECTED:
00463 errno = ENOENT;
00464 break;
00465 }
00466 }
00467 rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "pgp",
00468 strerror(errno));
00469 _exit(RPMERR_EXEC);
00470 }
00471
00472 delMacro(NULL, "__plaintext_filename");
00473 delMacro(NULL, "__signature_filename");
00474
00475 (void) close(inpipe[0]);
00476 if (passPhrase)
00477 (void) write(inpipe[1], passPhrase, strlen(passPhrase));
00478 (void) write(inpipe[1], "\n", 1);
00479 (void) close(inpipe[1]);
00480
00481 (void)waitpid(pid, &status, 0);
00482 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00483 rpmError(RPMERR_SIGGEN, _("pgp failed\n"));
00484 return 1;
00485 }
00486
00487 if (stat(sigfile, &st)) {
00488
00489 if (sigfile) (void) unlink(sigfile);
00490 rpmError(RPMERR_SIGGEN, _("pgp failed to write signature\n"));
00491 return 1;
00492 }
00493
00494
00495 *pktlenp = st.st_size;
00496 rpmMessage(RPMMESS_DEBUG, _("PGP sig size: %d\n"), *pktlenp);
00497 *pktp = xmalloc(*pktlenp);
00498
00499
00500
00501 { FD_t fd;
00502
00503 rc = 0;
00504 fd = Fopen(sigfile, "r.fdio");
00505 if (fd != NULL && !Ferror(fd)) {
00506 rc = timedRead(fd, *pktp, *pktlenp);
00507 if (sigfile) (void) unlink(sigfile);
00508 (void) Fclose(fd);
00509 }
00510 if (rc != *pktlenp) {
00511
00512 *pktp = _free(*pktp);
00513
00514 rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
00515 return 1;
00516 }
00517 }
00518
00519 rpmMessage(RPMMESS_DEBUG, _("Got %d bytes of PGP sig\n"), *pktlenp);
00520
00521
00522 #ifdef NOTYET
00523
00524 dig = pgpNewDig();
00525
00526 (void) pgpPrtPkts(*pktp, *pktlenp, dig, 0);
00527 sigp = &dig->signature;
00528
00529 dig = pgpFreeDig(dig);
00530 #endif
00531
00532 return 0;
00533 }
00534
00544 static int makeGPGSignature(const char * file, int_32 * sigTagp,
00545 byte ** pktp, int_32 * pktlenp,
00546 const char * passPhrase)
00547
00548
00549
00550
00551 {
00552 char * sigfile = alloca(strlen(file)+sizeof(".sig"));
00553 int pid, status;
00554 int inpipe[2];
00555 FILE * fpipe;
00556 struct stat st;
00557 const char * cmd;
00558 char *const *av;
00559 pgpDig dig = NULL;
00560 pgpDigParams sigp = NULL;
00561 int rc;
00562
00563
00564 (void) stpcpy( stpcpy(sigfile, file), ".sig");
00565
00566
00567 addMacro(NULL, "__plaintext_filename", NULL, file, -1);
00568 addMacro(NULL, "__signature_filename", NULL, sigfile, -1);
00569
00570 inpipe[0] = inpipe[1] = 0;
00571
00572 (void) pipe(inpipe);
00573
00574
00575 if (!(pid = fork())) {
00576 const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);
00577
00578 (void) close(STDIN_FILENO);
00579 (void) dup2(inpipe[0], 3);
00580 (void) close(inpipe[1]);
00581
00582
00583 if (gpg_path && *gpg_path != '\0')
00584 (void) dosetenv("GNUPGHOME", gpg_path, 1);
00585
00586 (void) dosetenv("LC_ALL", "C", 1);
00587
00588 unsetenv("MALLOC_CHECK_");
00589 cmd = rpmExpand("%{?__gpg_sign_cmd}", NULL);
00590 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00591
00592 if (!rc)
00593 rc = execve(av[0], av+1, environ);
00594
00595
00596 rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "gpg",
00597 strerror(errno));
00598 _exit(RPMERR_EXEC);
00599 }
00600
00601 delMacro(NULL, "__plaintext_filename");
00602 delMacro(NULL, "__signature_filename");
00603
00604 fpipe = fdopen(inpipe[1], "w");
00605 (void) close(inpipe[0]);
00606 if (fpipe) {
00607 fprintf(fpipe, "%s\n", (passPhrase ? passPhrase : ""));
00608 (void) fclose(fpipe);
00609 }
00610
00611 (void) waitpid(pid, &status, 0);
00612 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00613 rpmError(RPMERR_SIGGEN, _("gpg exec failed (%d)\n"), WEXITSTATUS(status));
00614 return 1;
00615 }
00616
00617 if (stat(sigfile, &st)) {
00618
00619 if (sigfile) (void) unlink(sigfile);
00620 rpmError(RPMERR_SIGGEN, _("gpg failed to write signature\n"));
00621 return 1;
00622 }
00623
00624
00625 *pktlenp = st.st_size;
00626 rpmMessage(RPMMESS_DEBUG, _("GPG sig size: %d\n"), *pktlenp);
00627 *pktp = xmalloc(*pktlenp);
00628
00629
00630
00631 { FD_t fd;
00632
00633 rc = 0;
00634 fd = Fopen(sigfile, "r.fdio");
00635 if (fd != NULL && !Ferror(fd)) {
00636 rc = timedRead(fd, *pktp, *pktlenp);
00637 if (sigfile) (void) unlink(sigfile);
00638 (void) Fclose(fd);
00639 }
00640 if (rc != *pktlenp) {
00641
00642 *pktp = _free(*pktp);
00643
00644 rpmError(RPMERR_SIGGEN, _("unable to read the signature\n"));
00645 return 1;
00646 }
00647 }
00648
00649 rpmMessage(RPMMESS_DEBUG, _("Got %d bytes of GPG sig\n"), *pktlenp);
00650
00651
00652
00653 dig = pgpNewDig();
00654
00655 (void) pgpPrtPkts(*pktp, *pktlenp, dig, 0);
00656 sigp = &dig->signature;
00657
00658 switch (*sigTagp) {
00659 case RPMSIGTAG_SIZE:
00660 case RPMSIGTAG_MD5:
00661 case RPMSIGTAG_SHA1:
00662 break;
00663 case RPMSIGTAG_GPG:
00664
00665 if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA)
00666 *sigTagp = RPMSIGTAG_PGP;
00667 break;
00668 case RPMSIGTAG_PGP5:
00669 case RPMSIGTAG_PGP:
00670 if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA)
00671 *sigTagp = RPMSIGTAG_GPG;
00672 break;
00673 case RPMSIGTAG_DSA:
00674
00675 if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA)
00676 *sigTagp = RPMSIGTAG_RSA;
00677 break;
00678 case RPMSIGTAG_RSA:
00679 if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA)
00680 *sigTagp = RPMSIGTAG_DSA;
00681 break;
00682 }
00683
00684 dig = pgpFreeDig(dig);
00685
00686 return 0;
00687 }
00688
00697 static int makeHDRSignature(Header sigh, const char * file, int_32 sigTag,
00698 const char * passPhrase)
00699
00700
00701 {
00702 Header h = NULL;
00703 FD_t fd = NULL;
00704 byte * pkt;
00705 int_32 pktlen;
00706 const char * fn = NULL;
00707 const char * SHA1 = NULL;
00708 int ret = -1;
00709
00710 switch (sigTag) {
00711 case RPMSIGTAG_SIZE:
00712 case RPMSIGTAG_MD5:
00713 case RPMSIGTAG_PGP5:
00714 case RPMSIGTAG_PGP:
00715 case RPMSIGTAG_GPG:
00716 goto exit;
00717 break;
00718 case RPMSIGTAG_SHA1:
00719 fd = Fopen(file, "r.fdio");
00720 if (fd == NULL || Ferror(fd))
00721 goto exit;
00722 h = headerRead(fd, HEADER_MAGIC_YES);
00723 if (h == NULL)
00724 goto exit;
00725 (void) Fclose(fd); fd = NULL;
00726
00727 if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
00728 DIGEST_CTX ctx;
00729 void * uh;
00730 int_32 uht, uhc;
00731
00732 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)
00733 || uh == NULL)
00734 {
00735 h = headerFree(h);
00736 goto exit;
00737 }
00738 ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00739 (void) rpmDigestUpdate(ctx, header_magic, sizeof(header_magic));
00740 (void) rpmDigestUpdate(ctx, uh, uhc);
00741 (void) rpmDigestFinal(ctx, (void **)&SHA1, NULL, 1);
00742 uh = headerFreeData(uh, uht);
00743 }
00744 h = headerFree(h);
00745
00746 if (SHA1 == NULL)
00747 goto exit;
00748 if (!headerAddEntry(sigh, RPMSIGTAG_SHA1, RPM_STRING_TYPE, SHA1, 1))
00749 goto exit;
00750 ret = 0;
00751 break;
00752 case RPMSIGTAG_DSA:
00753 fd = Fopen(file, "r.fdio");
00754 if (fd == NULL || Ferror(fd))
00755 goto exit;
00756 h = headerRead(fd, HEADER_MAGIC_YES);
00757 if (h == NULL)
00758 goto exit;
00759 (void) Fclose(fd); fd = NULL;
00760 if (makeTempFile(NULL, &fn, &fd))
00761 goto exit;
00762 if (headerWrite(fd, h, HEADER_MAGIC_YES))
00763 goto exit;
00764 (void) Fclose(fd); fd = NULL;
00765 if (makeGPGSignature(fn, &sigTag, &pkt, &pktlen, passPhrase)
00766 || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
00767 goto exit;
00768 ret = 0;
00769 break;
00770 case RPMSIGTAG_RSA:
00771 fd = Fopen(file, "r.fdio");
00772 if (fd == NULL || Ferror(fd))
00773 goto exit;
00774 h = headerRead(fd, HEADER_MAGIC_YES);
00775 if (h == NULL)
00776 goto exit;
00777 (void) Fclose(fd); fd = NULL;
00778 if (makeTempFile(NULL, &fn, &fd))
00779 goto exit;
00780 if (headerWrite(fd, h, HEADER_MAGIC_YES))
00781 goto exit;
00782 (void) Fclose(fd); fd = NULL;
00783 if (makePGPSignature(fn, &sigTag, &pkt, &pktlen, passPhrase)
00784 || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
00785 goto exit;
00786 ret = 0;
00787 break;
00788 }
00789
00790 exit:
00791 if (fn) {
00792 (void) unlink(fn);
00793 fn = _free(fn);
00794 }
00795 SHA1 = _free(SHA1);
00796 h = headerFree(h);
00797 if (fd != NULL) (void) Fclose(fd);
00798 return ret;
00799 }
00800
00801 int rpmAddSignature(Header sigh, const char * file, int_32 sigTag,
00802 const char * passPhrase)
00803 {
00804 struct stat st;
00805 byte * pkt;
00806 int_32 pktlen;
00807 int ret = -1;
00808
00809 switch (sigTag) {
00810 case RPMSIGTAG_SIZE:
00811 if (stat(file, &st) != 0)
00812 break;
00813 pktlen = st.st_size;
00814 if (!headerAddEntry(sigh, sigTag, RPM_INT32_TYPE, &pktlen, 1))
00815 break;
00816 ret = 0;
00817 break;
00818 case RPMSIGTAG_MD5:
00819 pktlen = 16;
00820 pkt = memset(alloca(pktlen), 0, pktlen);
00821 if (domd5(file, pkt, 0, NULL)
00822 || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
00823 break;
00824 ret = 0;
00825 break;
00826 case RPMSIGTAG_PGP5:
00827 case RPMSIGTAG_PGP:
00828 if (makePGPSignature(file, &sigTag, &pkt, &pktlen, passPhrase)
00829 || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
00830 break;
00831 #ifdef NOTYET
00832
00833 ret = makeHDRSignature(sigh, file, RPMSIGTAG_RSA, passPhrase);
00834 #endif
00835 ret = 0;
00836 break;
00837 case RPMSIGTAG_GPG:
00838 if (makeGPGSignature(file, &sigTag, &pkt, &pktlen, passPhrase)
00839 || !headerAddEntry(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
00840 break;
00841
00842 ret = makeHDRSignature(sigh, file, RPMSIGTAG_DSA, passPhrase);
00843 break;
00844 case RPMSIGTAG_RSA:
00845 case RPMSIGTAG_DSA:
00846 case RPMSIGTAG_SHA1:
00847 ret = makeHDRSignature(sigh, file, sigTag, passPhrase);
00848 break;
00849 }
00850
00851 return ret;
00852 }
00853
00854 static int checkPassPhrase(const char * passPhrase, const int sigTag)
00855
00856
00857 {
00858 int passPhrasePipe[2];
00859 int pid, status;
00860 int rc;
00861 int xx;
00862
00863 passPhrasePipe[0] = passPhrasePipe[1] = 0;
00864
00865 xx = pipe(passPhrasePipe);
00866
00867 if (!(pid = fork())) {
00868 const char * cmd;
00869 char *const *av;
00870 int fdno;
00871
00872 xx = close(STDIN_FILENO);
00873 xx = close(STDOUT_FILENO);
00874 xx = close(passPhrasePipe[1]);
00875 if (! rpmIsVerbose())
00876 xx = close(STDERR_FILENO);
00877 if ((fdno = open("/dev/null", O_RDONLY)) != STDIN_FILENO) {
00878 xx = dup2(fdno, STDIN_FILENO);
00879 xx = close(fdno);
00880 }
00881 if ((fdno = open("/dev/null", O_WRONLY)) != STDOUT_FILENO) {
00882 xx = dup2(fdno, STDOUT_FILENO);
00883 xx = close(fdno);
00884 }
00885 xx = dup2(passPhrasePipe[0], 3);
00886
00887 unsetenv("MALLOC_CHECK_");
00888 switch (sigTag) {
00889 case RPMSIGTAG_DSA:
00890 case RPMSIGTAG_GPG:
00891 { const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);
00892
00893
00894 if (gpg_path && *gpg_path != '\0')
00895 (void) dosetenv("GNUPGHOME", gpg_path, 1);
00896
00897
00898 cmd = rpmExpand("%{?__gpg_check_password_cmd}", NULL);
00899 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00900
00901 if (!rc)
00902 rc = execve(av[0], av+1, environ);
00903
00904
00905 rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "gpg",
00906 strerror(errno));
00907 } break;
00908 case RPMSIGTAG_RSA:
00909 case RPMSIGTAG_PGP5:
00910 case RPMSIGTAG_PGP:
00911 { const char *pgp_path = rpmExpand("%{?_pgp_path}", NULL);
00912 const char *path;
00913 pgpVersion pgpVer;
00914
00915 (void) dosetenv("PGPPASSFD", "3", 1);
00916
00917 if (pgp_path && *pgp_path != '\0')
00918 xx = dosetenv("PGPPATH", pgp_path, 1);
00919
00920
00921 if ((path = rpmDetectPGPVersion(&pgpVer)) != NULL) {
00922 switch(pgpVer) {
00923 case PGP_2:
00924 cmd = rpmExpand("%{?__pgp_check_password_cmd}", NULL);
00925 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00926
00927 if (!rc)
00928 rc = execve(av[0], av+1, environ);
00929
00930 break;
00931 case PGP_5:
00932 cmd = rpmExpand("%{?__pgp5_check_password_cmd}", NULL);
00933 rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
00934
00935 if (!rc)
00936 rc = execve(av[0], av+1, environ);
00937
00938 break;
00939 case PGP_UNKNOWN:
00940 case PGP_NOTDETECTED:
00941 break;
00942 }
00943 }
00944 rpmError(RPMERR_EXEC, _("Could not exec %s: %s\n"), "pgp",
00945 strerror(errno));
00946 _exit(RPMERR_EXEC);
00947 } break;
00948 default:
00949 rpmError(RPMERR_SIGGEN, _("Invalid %%_signature spec in macro file\n"));
00950 _exit(RPMERR_SIGGEN);
00951 break;
00952 }
00953 }
00954
00955 xx = close(passPhrasePipe[0]);
00956 xx = write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
00957 xx = write(passPhrasePipe[1], "\n", 1);
00958 xx = close(passPhrasePipe[1]);
00959
00960 (void) waitpid(pid, &status, 0);
00961
00962 return ((!WIFEXITED(status) || WEXITSTATUS(status)) ? 1 : 0);
00963 }
00964
00965 char * rpmGetPassPhrase(const char * prompt, const int sigTag)
00966 {
00967 char *pass = NULL;
00968 int aok = 0;
00969
00970 switch (sigTag) {
00971 case RPMSIGTAG_DSA:
00972 case RPMSIGTAG_GPG:
00973
00974 { const char *name = rpmExpand("%{?_gpg_name}", NULL);
00975 aok = (name && *name != '\0');
00976 name = _free(name);
00977 }
00978
00979 if (aok)
00980 break;
00981 rpmError(RPMERR_SIGGEN,
00982 _("You must set \"%%_gpg_name\" in your macro file\n"));
00983 break;
00984 case RPMSIGTAG_RSA:
00985 case RPMSIGTAG_PGP5:
00986 case RPMSIGTAG_PGP:
00987
00988 { const char *name = rpmExpand("%{?_pgp_name}", NULL);
00989 aok = (name && *name != '\0');
00990 name = _free(name);
00991 }
00992
00993 if (aok)
00994 break;
00995 rpmError(RPMERR_SIGGEN,
00996 _("You must set \"%%_pgp_name\" in your macro file\n"));
00997 break;
00998 default:
00999
01000
01001
01002 rpmError(RPMERR_SIGGEN, _("Invalid %%_signature spec in macro file\n"));
01003 break;
01004 }
01005
01006 if (aok) {
01007
01008 pass = getpass( (prompt ? prompt : "") );
01009
01010
01011 if (checkPassPhrase(pass, sigTag))
01012 pass = NULL;
01013 }
01014
01015 return pass;
01016 }
01017
01018 static const char * rpmSigString(rpmRC res)
01019
01020 {
01021 const char * str;
01022 switch (res) {
01023 case RPMRC_OK: str = "OK"; break;
01024 case RPMRC_FAIL: str = "BAD"; break;
01025 case RPMRC_NOKEY: str = "NOKEY"; break;
01026 case RPMRC_NOTTRUSTED: str = "NOTRUSTED"; break;
01027 default:
01028 case RPMRC_NOTFOUND: str = "UNKNOWN"; break;
01029 }
01030 return str;
01031 }
01032
01033
01034 static rpmRC
01035 verifySizeSignature(const rpmts ts, char * t)
01036
01037 {
01038 const void * sig = rpmtsSig(ts);
01039 pgpDig dig = rpmtsDig(ts);
01040 rpmRC res;
01041 int_32 size = 0x7fffffff;
01042
01043 *t = '\0';
01044 t = stpcpy(t, _("Header+Payload size: "));
01045
01046 if (sig == NULL || dig == NULL || dig->nbytes == 0) {
01047 res = RPMRC_NOKEY;
01048 t = stpcpy(t, rpmSigString(res));
01049 goto exit;
01050 }
01051
01052 memcpy(&size, sig, sizeof(size));
01053
01054 if (size != dig->nbytes) {
01055 res = RPMRC_FAIL;
01056 t = stpcpy(t, rpmSigString(res));
01057 sprintf(t, " Expected(%d) != (%d)\n", (int)size, (int)dig->nbytes);
01058 } else {
01059 res = RPMRC_OK;
01060 t = stpcpy(t, rpmSigString(res));
01061 sprintf(t, " (%d)", (int)dig->nbytes);
01062 }
01063
01064 exit:
01065 t = stpcpy(t, "\n");
01066 return res;
01067 }
01068
01069
01070
01071 static rpmRC
01072 verifyMD5Signature(const rpmts ts, char * t,
01073 DIGEST_CTX md5ctx)
01074
01075
01076 {
01077 const void * sig = rpmtsSig(ts);
01078 int_32 siglen = rpmtsSiglen(ts);
01079 pgpDig dig = rpmtsDig(ts);
01080 rpmRC res;
01081 byte * md5sum = NULL;
01082 size_t md5len = 0;
01083
01084 *t = '\0';
01085 t = stpcpy(t, _("MD5 digest: "));
01086
01087 if (md5ctx == NULL || sig == NULL || dig == NULL) {
01088 res = RPMRC_NOKEY;
01089 t = stpcpy(t, rpmSigString(res));
01090 goto exit;
01091 }
01092
01093 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01094 (void) rpmDigestFinal(rpmDigestDup(md5ctx),
01095 (void **)&md5sum, &md5len, 0);
01096 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01097 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01098
01099 if (md5len != siglen || memcmp(md5sum, sig, md5len)) {
01100 res = RPMRC_FAIL;
01101 t = stpcpy(t, rpmSigString(res));
01102 t = stpcpy(t, " Expected(");
01103 (void) pgpHexCvt(t, sig, siglen);
01104 t += strlen(t);
01105 t = stpcpy(t, ") != (");
01106 } else {
01107 res = RPMRC_OK;
01108 t = stpcpy(t, rpmSigString(res));
01109 t = stpcpy(t, " (");
01110 }
01111 (void) pgpHexCvt(t, md5sum, md5len);
01112 t += strlen(t);
01113 t = stpcpy(t, ")");
01114
01115 exit:
01116 md5sum = _free(md5sum);
01117 t = stpcpy(t, "\n");
01118 return res;
01119 }
01120
01121
01122
01130 static rpmRC
01131 verifySHA1Signature(const rpmts ts, char * t,
01132 DIGEST_CTX sha1ctx)
01133
01134
01135 {
01136 const void * sig = rpmtsSig(ts);
01137 #ifdef NOTYET
01138 int_32 siglen = rpmtsSiglen(ts);
01139 #endif
01140 pgpDig dig = rpmtsDig(ts);
01141 rpmRC res;
01142 const char * SHA1 = NULL;
01143
01144 *t = '\0';
01145 t = stpcpy(t, _("Header SHA1 digest: "));
01146
01147 if (sha1ctx == NULL || sig == NULL || dig == NULL) {
01148 res = RPMRC_NOKEY;
01149 t = stpcpy(t, rpmSigString(res));
01150 goto exit;
01151 }
01152
01153 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01154 (void) rpmDigestFinal(rpmDigestDup(sha1ctx),
01155 (void **)&SHA1, NULL, 1);
01156 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01157
01158 if (SHA1 == NULL || strlen(SHA1) != strlen(sig) || strcmp(SHA1, sig)) {
01159 res = RPMRC_FAIL;
01160 t = stpcpy(t, rpmSigString(res));
01161 t = stpcpy(t, " Expected(");
01162 t = stpcpy(t, sig);
01163 t = stpcpy(t, ") != (");
01164 } else {
01165 res = RPMRC_OK;
01166 t = stpcpy(t, rpmSigString(res));
01167 t = stpcpy(t, " (");
01168 }
01169 if (SHA1)
01170 t = stpcpy(t, SHA1);
01171 t = stpcpy(t, ")");
01172
01173 exit:
01174 SHA1 = _free(SHA1);
01175 t = stpcpy(t, "\n");
01176 return res;
01177 }
01178
01179
01185 static inline unsigned char nibble(char c)
01186
01187 {
01188 if (c >= '0' && c <= '9')
01189 return (c - '0');
01190 if (c >= 'A' && c <= 'F')
01191 return (c - 'A') + 10;
01192 if (c >= 'a' && c <= 'f')
01193 return (c - 'a') + 10;
01194 return 0;
01195 }
01196
01197
01205 static rpmRC
01206 verifyRSASignature(rpmts ts, char * t,
01207 DIGEST_CTX md5ctx)
01208
01209
01210 {
01211 const void * sig = rpmtsSig(ts);
01212 #ifdef NOTYET
01213 int_32 siglen = rpmtsSiglen(ts);
01214 #endif
01215 int_32 sigtag = rpmtsSigtag(ts);
01216 pgpDig dig = rpmtsDig(ts);
01217 pgpDigParams sigp = rpmtsSignature(ts);
01218 const char * prefix = NULL;
01219 rpmRC res = RPMRC_OK;
01220 int xx;
01221
01222 *t = '\0';
01223 if (dig != NULL && dig->hdrmd5ctx == md5ctx)
01224 t = stpcpy(t, _("Header "));
01225 *t++ = 'V';
01226 switch (sigp->version) {
01227 case 3: *t++ = '3'; break;
01228 case 4: *t++ = '4'; break;
01229 }
01230
01231 if (md5ctx == NULL || sig == NULL || dig == NULL || sigp == NULL) {
01232 res = RPMRC_NOKEY;
01233 }
01234
01235
01236 switch (sigp->pubkey_algo) {
01237 case PGPPUBKEYALGO_RSA:
01238 if (sigtag == RPMSIGTAG_PGP || sigtag == RPMSIGTAG_PGP5 || sigtag == RPMSIGTAG_RSA)
01239 break;
01240
01241 default:
01242 res = RPMRC_NOKEY;
01243 break;
01244 }
01245
01246
01247
01248 switch (sigp->hash_algo) {
01249 case PGPHASHALGO_MD5:
01250 t = stpcpy(t, " RSA/MD5");
01251 prefix = "3020300c06082a864886f70d020505000410";
01252 break;
01253 case PGPHASHALGO_SHA1:
01254 t = stpcpy(t, " RSA/SHA1");
01255 prefix = "3021300906052b0e03021a05000414";
01256 break;
01257 case PGPHASHALGO_RIPEMD160:
01258 res = RPMRC_NOKEY;
01259 prefix = NULL;
01260 break;
01261 case PGPHASHALGO_MD2:
01262 t = stpcpy(t, " RSA/MD2");
01263 prefix = "3020300c06082a864886f70d020205000410";
01264 break;
01265 case PGPHASHALGO_TIGER192:
01266 res = RPMRC_NOKEY;
01267 prefix = NULL;
01268 break;
01269 case PGPHASHALGO_HAVAL_5_160:
01270 res = RPMRC_NOKEY;
01271 prefix = NULL;
01272 break;
01273 case PGPHASHALGO_SHA256:
01274 t = stpcpy(t, " RSA/SHA256");
01275 prefix = "3031300d060960864801650304020105000420";
01276 break;
01277 case PGPHASHALGO_SHA384:
01278 t = stpcpy(t, " RSA/SHA384");
01279 prefix = "3041300d060960864801650304020205000430";
01280 break;
01281 case PGPHASHALGO_SHA512:
01282 t = stpcpy(t, " RSA/SHA512");
01283 prefix = "3051300d060960864801650304020305000440";
01284 break;
01285 default:
01286 res = RPMRC_NOKEY;
01287 prefix = NULL;
01288 break;
01289 }
01290
01291 t = stpcpy(t, _(" signature: "));
01292 if (res != RPMRC_OK) {
01293 goto exit;
01294 }
01295
01296 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01297 { DIGEST_CTX ctx = rpmDigestDup(md5ctx);
01298 byte signhash16[2];
01299 const char * s;
01300
01301 if (sigp->hash != NULL)
01302 xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
01303
01304 #ifdef NOTYET
01305 if (!(sigp->sigtype == PGPSIGTYPE_BINARY || sigp->sigtype == PGP_SIGTYPE_TEXT)) {
01306 int nb = dig->nbytes + sigp->hashlen;
01307 byte trailer[6];
01308 nb = htonl(nb);
01309 trailer[0] = 0x4;
01310 trailer[1] = 0xff;
01311 memcpy(trailer+2, &nb, sizeof(nb));
01312 xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
01313 }
01314 #endif
01315
01316 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1);
01317 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), sigp->hashlen);
01318 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01319
01320
01321 s = dig->md5;
01322 signhash16[0] = (nibble(s[0]) << 4) | nibble(s[1]);
01323 signhash16[1] = (nibble(s[2]) << 4) | nibble(s[3]);
01324 if (memcmp(signhash16, sigp->signhash16, sizeof(signhash16))) {
01325 res = RPMRC_FAIL;
01326 goto exit;
01327 }
01328 }
01329
01330
01331 { unsigned int nbits = MP_WORDS_TO_BITS(dig->c.size);
01332 unsigned int nb = (nbits + 7) >> 3;
01333 const char * hexstr;
01334 char * tt;
01335
01336 assert(prefix != NULL);
01337 hexstr = tt = xmalloc(2 * nb + 1);
01338 memset(tt, 'f', (2 * nb));
01339 tt[0] = '0'; tt[1] = '0';
01340 tt[2] = '0'; tt[3] = '1';
01341 tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2;
01342 *tt++ = '0'; *tt++ = '0';
01343 tt = stpcpy(tt, prefix);
01344 tt = stpcpy(tt, dig->md5);
01345
01346 mpnzero(&dig->rsahm); (void) mpnsethex(&dig->rsahm, hexstr);
01347
01348 hexstr = _free(hexstr);
01349
01350 }
01351
01352
01353 res = rpmtsFindPubkey(ts);
01354 if (res != RPMRC_OK)
01355 goto exit;
01356
01357 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0);
01358 #if HAVE_BEECRYPT_API_H
01359 xx = rsavrfy(&dig->rsa_pk.n, &dig->rsa_pk.e, &dig->c, &dig->rsahm);
01360 #else
01361 xx = rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c);
01362 #endif
01363 if (xx)
01364 res = RPMRC_OK;
01365 else
01366 res = RPMRC_FAIL;
01367 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0);
01368
01369 exit:
01370 t = stpcpy(t, rpmSigString(res));
01371 if (sigp != NULL) {
01372 t = stpcpy(t, ", key ID ");
01373 (void) pgpHexCvt(t, sigp->signid+4, sizeof(sigp->signid)-4);
01374 t += strlen(t);
01375 }
01376 t = stpcpy(t, "\n");
01377 return res;
01378 }
01379
01380
01388
01389 static rpmRC
01390 verifyDSASignature(rpmts ts, char * t,
01391 DIGEST_CTX sha1ctx)
01392
01393
01394 {
01395 const void * sig = rpmtsSig(ts);
01396 #ifdef NOTYET
01397 int_32 siglen = rpmtsSiglen(ts);
01398 #endif
01399 int_32 sigtag = rpmtsSigtag(ts);
01400 pgpDig dig = rpmtsDig(ts);
01401 pgpDigParams sigp = rpmtsSignature(ts);
01402 rpmRC res;
01403 int xx;
01404
01405 *t = '\0';
01406 if (dig != NULL && dig->hdrsha1ctx == sha1ctx)
01407 t = stpcpy(t, _("Header "));
01408 *t++ = 'V';
01409 switch (sigp->version) {
01410 case 3: *t++ = '3'; break;
01411 case 4: *t++ = '4'; break;
01412 }
01413 t = stpcpy(t, _(" DSA signature: "));
01414
01415 if (sha1ctx == NULL || sig == NULL || dig == NULL || sigp == NULL) {
01416 res = RPMRC_NOKEY;
01417 goto exit;
01418 }
01419
01420
01421 if (!((sigtag == RPMSIGTAG_GPG || sigtag == RPMSIGTAG_DSA)
01422 && sigp->pubkey_algo == PGPPUBKEYALGO_DSA
01423 && sigp->hash_algo == PGPHASHALGO_SHA1))
01424 {
01425 res = RPMRC_NOKEY;
01426 goto exit;
01427 }
01428
01429 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
01430 { DIGEST_CTX ctx = rpmDigestDup(sha1ctx);
01431 byte signhash16[2];
01432
01433 if (sigp->hash != NULL)
01434 xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen);
01435
01436 if (sigp->version == 4) {
01437 int nb = sigp->hashlen;
01438 byte trailer[6];
01439 nb = htonl(nb);
01440 trailer[0] = sigp->version;
01441 trailer[1] = 0xff;
01442 memcpy(trailer+2, &nb, sizeof(nb));
01443 xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer));
01444 }
01445 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1);
01446 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), sigp->hashlen);
01447 rpmtsOp(ts, RPMTS_OP_DIGEST)->count--;
01448
01449 mpnzero(&dig->hm); (void) mpnsethex(&dig->hm, dig->sha1);
01450
01451
01452 signhash16[0] = (*dig->hm.data >> 24) & 0xff;
01453 signhash16[1] = (*dig->hm.data >> 16) & 0xff;
01454 if (memcmp(signhash16, sigp->signhash16, sizeof(signhash16))) {
01455 res = RPMRC_FAIL;
01456 goto exit;
01457 }
01458 }
01459
01460
01461 res = rpmtsFindPubkey(ts);
01462 if (res != RPMRC_OK)
01463 goto exit;
01464
01465 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0);
01466 if (dsavrfy(&dig->p, &dig->q, &dig->g,
01467 &dig->hm, &dig->y, &dig->r, &dig->s))
01468 res = RPMRC_OK;
01469 else
01470 res = RPMRC_FAIL;
01471 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_SIGNATURE), 0);
01472
01473 exit:
01474 t = stpcpy(t, rpmSigString(res));
01475 if (sigp != NULL) {
01476 t = stpcpy(t, ", key ID ");
01477 (void) pgpHexCvt(t, sigp->signid+4, sizeof(sigp->signid)-4);
01478 t += strlen(t);
01479 }
01480 t = stpcpy(t, "\n");
01481 return res;
01482 }
01483
01484
01485 rpmRC
01486 rpmVerifySignature(const rpmts ts, char * result)
01487 {
01488 const void * sig = rpmtsSig(ts);
01489 int_32 siglen = rpmtsSiglen(ts);
01490 int_32 sigtag = rpmtsSigtag(ts);
01491 pgpDig dig = rpmtsDig(ts);
01492 rpmRC res;
01493
01494 if (sig == NULL || siglen <= 0 || dig == NULL) {
01495 sprintf(result, _("Verify signature: BAD PARAMETERS\n"));
01496 return RPMRC_NOTFOUND;
01497 }
01498
01499 switch (sigtag) {
01500 case RPMSIGTAG_SIZE:
01501 res = verifySizeSignature(ts, result);
01502 break;
01503 case RPMSIGTAG_MD5:
01504 res = verifyMD5Signature(ts, result, dig->md5ctx);
01505 break;
01506 case RPMSIGTAG_SHA1:
01507 res = verifySHA1Signature(ts, result, dig->hdrsha1ctx);
01508 break;
01509 case RPMSIGTAG_RSA:
01510 res = verifyRSASignature(ts, result, dig->hdrmd5ctx);
01511 break;
01512 case RPMSIGTAG_PGP5:
01513 case RPMSIGTAG_PGP:
01514 res = verifyRSASignature(ts, result,
01515 ((dig->signature.hash_algo == PGPHASHALGO_MD5)
01516 ? dig->md5ctx : dig->sha1ctx));
01517 break;
01518 case RPMSIGTAG_DSA:
01519 res = verifyDSASignature(ts, result, dig->hdrsha1ctx);
01520 break;
01521 case RPMSIGTAG_GPG:
01522 res = verifyDSASignature(ts, result, dig->sha1ctx);
01523 break;
01524 case RPMSIGTAG_LEMD5_1:
01525 case RPMSIGTAG_LEMD5_2:
01526 sprintf(result, _("Broken MD5 digest: UNSUPPORTED\n"));
01527 res = RPMRC_NOTFOUND;
01528 break;
01529 default:
01530 sprintf(result, _("Signature: UNKNOWN (%d)\n"), sigtag);
01531 res = RPMRC_NOTFOUND;
01532 break;
01533 }
01534 return res;
01535 }