10 #define _RPMPGP_INTERNAL
32 const char * tpmacro =
"%{?_tmppath}%{!?_tmppath:/var/tmp/}";
33 const char * tempfn = NULL;
34 const char * tfn = NULL;
35 static int _initialized = 0;
40 if (!prefix) prefix =
"";
46 if (
rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
51 ran = (unsigned)
time(NULL);
53 ran = rand() % 100000;
60 sprintf(tfnbuf,
"rpm-tmp.%u", ran++);
61 tempfn =
_free(tempfn);
64 strcpy(tfnbuf,
"rpm-tmp.XXXXXX");
65 tempfn =
_free(tempfn);
66 tempfn =
rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
70 if (*tfn ==
'\0')
goto errxit;
85 fd =
Fopen(tempfn,
"w+x.fdio");
87 }
while ((fd == NULL ||
Ferror(fd)) &&
errno == EEXIST);
89 if (fd == NULL ||
Ferror(fd)) {
97 {
struct stat sb, sb2;
98 if (!stat(tfn, &sb) &&
S_ISLNK(sb.st_mode)) {
103 if (sb.st_nlink != 1) {
108 if (fstat(
Fileno(fd), &sb2) == 0) {
109 if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
122 tempfn =
_free(tempfn);
129 tempfn =
_free(tempfn);
133 if (fd != NULL) (void)
Fclose(fd);
150 const char * passPhrase)
156 char * sigfile = (
char *)
alloca(strlen(file)+
sizeof(
".sig"));
166 const char * pw = NULL;
171 addMacro(NULL,
"__plaintext_filename", NULL, file, -1);
172 addMacro(NULL,
"__signature_filename", NULL, sigfile, -1);
174 inpipe[0] = inpipe[1] = 0;
175 if (pipe(inpipe) < 0) {
180 if (!(pid = fork())) {
181 const char *gpg_path =
rpmExpand(
"%{?_gpg_path}", NULL);
183 (void) dup2(inpipe[0], 3);
184 (void) close(inpipe[1]);
186 if (gpg_path && *gpg_path !=
'\0')
187 (void)
setenv(
"GNUPGHOME", gpg_path, 1);
190 cmd =
rpmExpand(
"%{?__gpg_sign_cmd}", NULL);
191 rc = poptParseArgvString(cmd, NULL, (
const char ***)&av);
193 rc = execve(av[0], av+1,
environ);
200 delMacro(NULL,
"__plaintext_filename");
201 delMacro(NULL,
"__signature_filename");
210 fpipe = fdopen(inpipe[1],
"w");
211 (void) close(inpipe[0]);
213 fprintf(fpipe,
"%s\n", (pw ? pw :
""));
214 (void) fclose(fpipe);
218 (void) memset((
void *)pw, 0, strlen(pw));
223 (void) waitpid(pid, &status, 0);
225 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
230 if (
Stat(sigfile, &st)) {
232 if (sigfile) (void)
Unlink(sigfile);
244 fd =
Fopen(sigfile,
"r.ufdio");
245 if (fd != NULL && !
Ferror(fd)) {
246 rc = (int)
Fread(*pktp,
sizeof((*pktp)[0]), *pktlenp, fd);
247 if (sigfile) (void)
Unlink(sigfile);
251 *pktp =
_free(*pktp);
303 const char * passPhrase)
312 const char * fn = NULL;
330 {
const char * SHA1 = NULL;
331 fd =
Fopen(file,
"r.fdio");
332 if (fd == NULL ||
Ferror(fd))
334 {
const char item[] =
"Header";
344 (void)
Fclose(fd); fd = NULL;
347 unsigned char * hmagic = NULL;
360 if (hmagic && nmagic > 0)
382 fd =
Fopen(file,
"r.fdio");
383 if (fd == NULL ||
Ferror(fd))
385 {
const char item[] =
"Header";
395 (void)
Fclose(fd); fd = NULL;
399 {
const char item[] =
"Header";
409 (void)
Fclose(fd); fd = NULL;
423 fd =
Fopen(file,
"r.fdio");
424 if (fd == NULL ||
Ferror(fd))
426 {
const char item[] =
"Header";
436 (void)
Fclose(fd); fd = NULL;
440 {
const char item[] =
"Header";
450 (void)
Fclose(fd); fd = NULL;
472 if (fd != NULL) (void)
Fclose(fd);
478 const char * passPhrase)
492 if (
Stat(file, &st) != 0)
543 if (!(passPhrase && passPhrase[0]))
549 if (!(pid = fork())) {
554 xx = close(STDIN_FILENO);
555 xx = close(STDOUT_FILENO);
558 xx = close(STDERR_FILENO);
559 if ((fdno = open(
"/dev/null", O_RDONLY)) != STDIN_FILENO) {
560 xx = dup2(fdno, STDIN_FILENO);
563 if ((fdno = open(
"/dev/null", O_WRONLY)) != STDOUT_FILENO) {
564 xx = dup2(fdno, STDOUT_FILENO);
570 {
const char *gpg_path =
rpmExpand(
"%{?_gpg_path}", NULL);
572 if (gpg_path && *gpg_path !=
'\0')
573 (void)
setenv(
"GNUPGHOME", gpg_path, 1);
575 cmd =
rpmExpand(
"%{?__gpg_check_password_cmd}", NULL);
576 rc = poptParseArgvString(cmd, NULL, (
const char ***)&av);
578 rc = execve(av[0], av+1,
environ);
593 xx = (int) write(p[1], pw, strlen(pw));
594 xx = (int) write(p[1],
"\n", 1);
598 (void) memset((
void *)pw, 0, strlen(pw));
603 (void) waitpid(pid, &status, 0);
606 return ((!WIFEXITED(status) || WEXITSTATUS(status)) ? 1 : 0);
634 t =
stpcpy(t,
_(
"Header+Payload size: "));
636 if (sig == NULL || dig == NULL || dig->nbytes == 0) {
642 memcpy(&size, sig,
sizeof(size));
647 sprintf(t,
" Expected(%u) != (%u)\n", (
unsigned)size, (
unsigned)dig->nbytes);
651 sprintf(t,
" (%u)", (
unsigned)dig->nbytes);
670 assert(md5ctx != NULL);
689 if (op != NULL) op->
count--;
692 if (md5len != siglen || memcmp(md5sum, sig, md5len)) {
695 t =
stpcpy(t,
" Expected(");
709 md5sum =
_free(md5sum);
730 const char * SHA1 = NULL;
733 assert(shactx != NULL);
756 || strlen(SHA1) != strlen((
char *)sig)
757 || strcmp(SHA1, (
char *)sig))
761 t =
stpcpy(t,
" Expected(");
762 t =
stpcpy(t, (
char *)sig);
799 fprintf(stderr,
"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, hrsa, sig, sigp);
802 assert(hrsa != NULL);
803 assert(sigp != NULL);
816 if (dig->hrsa == hrsa)
821 switch (sigp->version) {
822 case 3: *t++ =
'3';
break;
823 case 4: *t++ =
'4';
break;
829 if (strcmp(hashname,
"UNKNOWN")) {
834 t =
stpcpy(t,
_(
" signature: "));
840 if (sigp->hash != NULL)
845 trailer[0] = sigp->version;
847 trailer[2] = (sigp->hashlen >> 24);
848 trailer[3] = (sigp->hashlen >> 16);
849 trailer[4] = (sigp->hashlen >> 8);
850 trailer[5] = (sigp->hashlen );
854 if (op != NULL) op->
count--;
874 t =
stpcpy(t,
", key ID ");
875 (void)
pgpHexCvt(t, sigp->signid+4,
sizeof(sigp->signid)-4);
902 fprintf(stderr,
"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, hdsa, sig, sigp);
905 assert(hdsa != NULL);
906 assert(sigp != NULL);
913 if (dig != NULL && dig->hdsa == hdsa)
918 switch (sigp->version) {
919 case 3: *t++ =
'3';
break;
920 case 4: *t++ =
'4';
break;
926 if (strcmp(hashname,
"UNKNOWN") && strcmp(hashname,
"SHA1")) {
931 t =
stpcpy(t,
_(
" signature: "));
937 if (sigp->hash != NULL)
942 trailer[0] = sigp->version;
944 trailer[2] = (sigp->hashlen >> 24);
945 trailer[3] = (sigp->hashlen >> 16);
946 trailer[4] = (sigp->hashlen >> 8);
947 trailer[5] = (sigp->hashlen );
951 if (op != NULL) op->
count--;
976 t =
stpcpy(t,
", key ID ");
977 (void)
pgpHexCvt(t, sigp->signid+4,
sizeof(sigp->signid)-4);
982 fprintf(stderr,
"<-- %s(%p,%p,%p) res %d %s\n", __FUNCTION__, dig, t, hdsa, res, t);
1008 fprintf(stderr,
"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, hecdsa, sig, sigp);
1010 assert(dig != NULL);
1011 assert(hecdsa != NULL);
1012 assert(sigp != NULL);
1016 assert(sig != NULL);
1019 if (dig != NULL && dig->hecdsa == hecdsa)
1024 switch (sigp->version) {
1025 case 3: *t++ =
'3';
break;
1026 case 4: *t++ =
'4';
break;
1032 if (strcmp(hashname,
"UNKNOWN") && strcmp(hashname,
"SHA1")) {
1037 t =
stpcpy(t,
_(
" signature: "));
1043 if (sigp->hash != NULL)
1048 trailer[0] = sigp->version;
1050 trailer[2] = (sigp->hashlen >> 24);
1051 trailer[3] = (sigp->hashlen >> 16);
1052 trailer[4] = (sigp->hashlen >> 8);
1053 trailer[5] = (sigp->hashlen );
1057 if (op != NULL) op->
count--;
1082 t =
stpcpy(t,
", key ID ");
1083 (void)
pgpHexCvt(t, sigp->signid+4,
sizeof(sigp->signid)-4);
1088 fprintf(stderr,
"<-- %s(%p,%p,%p) res %d %s\n", __FUNCTION__, dig, t, hecdsa, res, t);
1105 fprintf(stderr,
"--> %s(%p,%p) sig %p[%u]\n", __FUNCTION__, _dig, result, sig, siglen);
1107 if (dig == NULL || sig == NULL || siglen == 0) {
1108 sprintf(result,
_(
"Verify signature: BAD PARAMETERS\n"));
1120 res =
verifyMD5(dig, result, dig->md5ctx);
1129 res =
verifyRSA(dig, result, dig->hrsa);
1134 res =
verifyDSA(dig, result, dig->hdsa);
1142 sprintf(result,
_(
"Signature: UNKNOWN (%u)\n"), (
unsigned)sigtag);
1149 fprintf(stderr,
"<-- %s(%p,%p) res %d %s\n", __FUNCTION__, _dig, result, res, result);
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
static int makeGPGSignature(const char *file, rpmSigTag *sigTagp, rpmuint8_t **pktp, rpmuint32_t *pktlenp, const char *passPhrase)
Generate GPG signature(s) for a header+payload file.
static rpmRC verifySHA1(pgpDig dig, char *t, DIGEST_CTX shactx)
Verify header immutable region SHA-1 digest.
int rpmAddSignature(Header sigh, const char *file, rpmSigTag sigTag, const char *passPhrase)
Generate signature(s) from a header+payload file, save in signature header.
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
pgpDig pgpDigFree(pgpDig dig)
Destroy a container for parsed OpenPGP packates.
rpmuint32_t pgpGetSiglen(pgpDig dig)
Get signature tag data length, i.e.
OpenPGP constants and structures from RFC-2440.
const char const char * cmd
rpmRC rpmpkgWrite(const char *fn, FD_t fd, void *ptr, const char **msg)
Write item onto file descriptor.
const void * pgpGetSig(pgpDig dig)
Get signature tag data, i.e.
enum rpmSigTag_e rpmSigTag
int rpmCheckPassPhrase(const char *passPhrase)
Check for valid pass phrase by invoking a helper.
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
struct pgpDigParams_s * pgpDigParams
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest context.
int rpmioMkpath(const char *path, mode_t mode, uid_t uid, gid_t gid)
Insure that directories in path exist, creating as needed.
int setenv(const char *name, const char *value, int replace)
int Stat(const char *path, struct stat *st)
stat(2) clone.
static rpmRC verifyECDSA(pgpDig dig, char *t, DIGEST_CTX hecdsa)
Verify ECDSA signature.
void addMacro(MacroContext mc, const char *n, const char *o, const char *b, int level)
Add macro to context.
int dodigest(int dalgo, const char *fn, unsigned char *digest, unsigned dflags, size_t *fsizep)
Return digest and size of a file.
static void rpmlog(int code, const char *fmt,...)
static int pgpImplSetDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
void delMacro(MacroContext mc, const char *n)
Delete macro from context.
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
int pgpFindPubkey(pgpDig dig)
Call find pubkey vector.
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
static int makeHDRSignature(Header sigh, const char *file, rpmSigTag sigTag, const char *passPhrase)
Generate header only signature(s) from a header+payload file.
int rpmTempFile(const char *prefix, const char **fnptr, void *fdptr)
Return file handle for a temporaray file.
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
static char * pgpHexCvt(char *t, const rpmuint8_t *s, size_t nbytes)
Convert to hex.
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
rpmuint32_t pgpGetSigtag(pgpDig dig)
Get signature tag.
The FD_t File Handle data structure.
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
static int pgpImplSetECDSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
Generate and verify rpm package signatures.
static rpmRC verifyRSA(pgpDig dig, char *t, DIGEST_CTX hrsa)
Verify RSA signature.
Header headerFree(Header h)
Dereference a header instance.
rpmRC rpmVerifySignature(void *_dig, char *result)
Verify a signature from a package.
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
const char const bson const bson * op
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
void unsetenv(const char *name)
static const char * rpmSigString(rpmRC res)
int Fclose(FD_t fd)
fclose(3) clone.
Cumulative statistics for an operation.
static rpmRC verifySize(const pgpDig dig, char *t)
static int pgpImplSetRSA(DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
enum pgpPubkeyAlgo_e pgpPubkeyAlgo
9.1.
enum rpmRC_e rpmRC
RPM return codes.
pgpDig pgpDigNew(pgpVSFlags vsflags, pgpPubkeyAlgo pubkey_algo)
Create a container for parsed OpenPGP packates.
int Ferror(FD_t fd)
ferror(3) clone.
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
static const char * prefix[]
Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options.
Methods to handle package elements.
char * stpcpy(char *dest, const char *src)
const char const char size_t size
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
const char * rpmDigestName(DIGEST_CTX ctx)
Return digest name.
static int pgpImplVerify(pgpDig dig)
int pgpPrtPkts(const rpmuint8_t *pkts, size_t pktlen, pgpDig dig, int printing)
Print/parse a OpenPGP packet(s).
int Fileno(FD_t fd)
fileno(3) clone.
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
static rpmRC verifyMD5(pgpDig dig, char *t, DIGEST_CTX md5ctx)
rpmRC rpmpkgRead(const char *fn, FD_t fd, void *ptr, const char **msg)
Read item from file descriptor.
Access RPM indices using Berkeley DB interface(s).
static rpmRC verifyDSA(pgpDig dig, char *t, DIGEST_CTX hdsa)
Verify DSA signature.
void * pgpStatsAccumulator(pgpDig dig, int opx)
Return pgpDig container accumulator structure.
const char * rpmkuPassPhrase(const char *passPhrase)
Return pass phrase from keyutils keyring.
DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
Duplicate a digest context.
int Unlink(const char *path)
unlink(2) clone.