OK, I muddled through this patch for the past few days. All the patch does is add methods to have rpm invoke gpg. No surrise there at all: that is what RPM has always done to sign packages -- invoke gpg/pgp -- because of ancient policies/laws that treated cryptography as a munition.
The approach has a couple of (mostly legacy) consequences for RPM: 1) assumption of a helper executable 2) implicit needs for a password dialog, and keyring locations 3) assumptions regarding what is being signed. There already is much better implemented and used in @rpm5.org code: 1) all packages built by rpmbuild are automatically signed w/o helper. 2) the password dialog is mapped into keyutils, and pubkey keyring stores other than the implicit ~/.gnupg are already in place with hkp:// 3) rpm now has internal generate/sign methods across multiple crypto implementations and other operations, like signing ELF executables, or critical config files or state, will be happening going forward. There's the other issue of private keystores that the patch introduces, which have much more serious "trust" issues that should NOT be just implicitly left to gnupg conventions in ~/.gnupg/secring.gpg. Nothing at all is wrong with what GNUPG uses for a private key store, just that RPM lacks the context where gnupg is typically used, where ~ (and a per-user) context is a meaningful convention for GNUPG (but not RPM), etc etc. I'd also like to see whatever is done with digital signatures in RPM approached as a declarative, not a procedural, implementation. All that means is that -- if methods are added to rpm-perl -- then there is the instant and predictable RFE to do same for python and ruby and Javascript and everywhere else. A declarative approach supplying the necessary data (like public/private key fingerprints/parameters) is what needs to be done, not adding Yet More Methods with opaque arguments to one specific set of bindings called "perl". So I'd very much like NOT to freeze >10 year old "munitions" into RPM going forward. SO either put the patch under #ifdef RPM_VENDOR_MANDRIVA or talk to me about how to use keyutils to store a password, or devise some simple markup that describes sign/verify operations in YAML/JSON (my preferences) or XML or ... Sound like a plan? hth 73 de Jeff On Nov 29, 2010, at 5:04 PM, Per Øyvind Karlsen wrote: > RPM Package Manager, CVS Repository > http://rpm5.org/cvs/ > ____________________________________________________________________________ > > Server: rpm5.org Name: Per Øyvind Karlsen > Root: /v/rpm/cvs Email: pkarl...@rpm5.org > Module: rpm Date: 29-Nov-2010 23:04:18 > Branch: rpm-5_3 Handle: 2010112922041602 > > Added files: (Branch: rpm-5_3) > rpm/perl/RPM Sign.pm > rpm/perl/t/gnupg passphrase pubring.gpg random_seed secring.gpg > test-key.gpg trustdb.gpg > Modified files: (Branch: rpm-5_3) > rpm CHANGES > rpm/perl Makefile.am RPM.pm RPM.xs RPM_Transaction.xs > rpm/perl/RPM Transaction.pm > > Log: > perl: start on adding back some missing functionality from RPM4: > RPM::Sign, RPM::Transaction::importpubkey, > RPM::Transaction::checkrpm. > > Summary: > Revision Changes Path > 1.3296.2.124+2 -0 rpm/CHANGES > 1.20.2.1 +3 -0 rpm/perl/Makefile.am > 1.9.4.1 +3 -0 rpm/perl/RPM.pm > 1.32.2.1 +16 -0 rpm/perl/RPM.xs > 1.1.2.2 +204 -0 rpm/perl/RPM/Sign.pm > 1.6.8.1 +8 -0 rpm/perl/RPM/Transaction.pm > 1.17.4.2 +45 -0 rpm/perl/RPM_Transaction.xs > 1.1.2.2 +6 -0 rpm/perl/t/gnupg/passphrase > 1.1.2.2 BLOB rpm/perl/t/gnupg/pubring.gpg > 1.1.2.2 BLOB rpm/perl/t/gnupg/random_seed > 1.1.2.2 BLOB rpm/perl/t/gnupg/secring.gpg > 1.1.2.2 +26 -0 rpm/perl/t/gnupg/test-key.gpg > 1.1.2.2 BLOB rpm/perl/t/gnupg/trustdb.gpg > ____________________________________________________________________________ > > patch -p0 <<'@@ .' > Index: rpm/CHANGES > ============================================================================ > $ cvs diff -u -r1.3296.2.123 -r1.3296.2.124 CHANGES > --- rpm/CHANGES 25 Nov 2010 21:29:41 -0000 1.3296.2.123 > +++ rpm/CHANGES 29 Nov 2010 22:04:16 -0000 1.3296.2.124 > @@ -1,4 +1,6 @@ > 5.3.5 -> 5.3.6: > + - proyvind: perl: start on adding back some missing functionality from > RPM4: > + RPM::Sign, RPM::Transaction::importpubkey, > RPM::Transaction::checkrpm. > - jbj: rpmdb: minimalistic lock object scaling. > - jbj: rpmdb: re-open with DB_RECOVER iff DB_RUNRECOVERY. > - proyvind: add a first prototype scripts/dbconvert.sh for handling > rpmdb > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/Makefile.am > ============================================================================ > $ cvs diff -u -r1.20 -r1.20.2.1 Makefile.am > --- rpm/perl/Makefile.am 31 Dec 2009 14:46:45 -0000 1.20 > +++ rpm/perl/Makefile.am 29 Nov 2010 22:04:17 -0000 1.20.2.1 > @@ -15,7 +15,10 @@ > RPM_Files.xs RPM/Files.pm t/07.files.t \ > RPM_Dependencies.xs RPM/Dependencies.pm t/08.dependencies.t \ > RPM_Spec.xs RPM/Spec.pm t/09.spec.t \ > + RPM/RPM_Sign.pm t/10.sign.t > t/00.pod.coverage.t t/00.pod.t \ > + t/gnupg/passphrase t/gnupg/pubring.gpg t/gnupg/random_seed \ > + t/gnupg/secring.gpg t/gnupg/test-key.gpg t/gnupg/trustdb.gpg \ > hdlist-test.hdr test-rpm-1.0-1.noarch.rpm test-rpm-1.0-1.src.rpm \ > test-rpm.spec > > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/RPM.pm > ============================================================================ > $ cvs diff -u -r1.9 -r1.9.4.1 RPM.pm > --- rpm/perl/RPM.pm 11 Oct 2008 00:41:46 -0000 1.9 > +++ rpm/perl/RPM.pm 29 Nov 2010 22:04:17 -0000 1.9.4.1 > @@ -158,6 +158,9 @@ > > Signature validation. > > +=head2 resign > +Resign a package. > + > =head1 HISTORY > > =over 8 > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/RPM.xs > ============================================================================ > $ cvs diff -u -r1.32 -r1.32.2.1 RPM.xs > --- rpm/perl/RPM.xs 21 Aug 2009 03:18:37 -0000 1.32 > +++ rpm/perl/RPM.xs 29 Nov 2010 22:04:17 -0000 1.32.2.1 > @@ -24,6 +24,7 @@ > #include "rpmts.h" > #include "rpmte.h" > #include "rpmevr.h" > +#include "rpmcli.h" > #include "misc.h" > > /* The perl callback placeholder for output err messages */ > @@ -223,3 +224,18 @@ > (void)rpmtsFree(ts); > ts = NULL; > > +int > +resign(passphrase, rpmfile) > + char * passphrase > + char * rpmfile > + CODE: > + QVA_t qva = &rpmQVKArgs; > + const char *file[] = { (const char*)rpmfile, NULL }; > + > + qva->qva_mode = RPMSIGN_ADD_SIGNATURE; > + qva->passPhrase = passphrase; > + > + RETVAL = rpmcliSign(NULL, qva, file); > + OUTPUT: > + RETVAL > + > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/RPM/Sign.pm > ============================================================================ > $ cvs diff -u -r0 -r1.1.2.2 Sign.pm > --- /dev/null 2010-11-29 23:03:59.000000000 +0100 > +++ Sign.pm 2010-11-29 23:04:18.125257789 +0100 > @@ -0,0 +1,204 @@ > +package RPM::Sign; > + > +use strict; > +use Exporter; > +use RPM; > +use RPM::PackageIterator; > +use RPM::Header; > +use vars qw($AUTOLOAD); > + > +our @ISA = qw(Exporter); > + > +our @EXPORT = qw( > +); > + > +sub new { > + my ($class, %options) = @_; > + > + my $Sign; > + $Sign = { > + _signature => undef, > + name => undef, > + path => undef, > + checkrpms => 1, > + passphrase => undef, > + > + password_file => undef, > + > + log => sub { > + my ($m, @v) = @_; > + printf STDERR "$m\n", @v; > + }, > + > + }; > + > + foreach (keys %$Sign) { > + defined($options{$_}) and $Sign->{$_} = $options{$_}; > + } > + > + bless($Sign, $class); > + $Sign->getpubkey(); > + $Sign->getpasswdfile(); > + $Sign; > +} > + > +sub getpasswdfile { > + my ($self) = @_; > + $self->{password_file} or return 1; > + open(my $hpass, "<", $self->{password_file}) or return 0; > + $self->{passphrase} = <$hpass>; > + chomp($self->{passphrase}); > + close($hpass); > + 1; > +} > + > +sub adjustmacro { > + my ($self) = @_; > + > + defined($self->{_signature}) and RPM::add_macro("_signature > $self->{_signature}"); > + > + foreach my $macro (qw(_gpg_name _pgp_name)) { > + RPM::add_macro("$macro $self->{name}") if (defined($self->{name})); > + } > + > + foreach my $macro (qw(_gpg_path _pgp_path)) { > + RPM::add_macro("$macro $self->{path}") if (defined($self->{path})); > + } > +} > + > +sub restoremacro { > + my ($self) = @_; > + > + if (defined($self->{_signature})) { RPM::del_macro('_signature'); } > + > + if (defined($self->{name})) { > + RPM::del_macro('_gpg_name'); > + RPM::del_macro('_pgp_name'); > + } > + > + if (defined($self->{path})) { > + RPM::del_macro('_gpg_path'); > + RPM::del_macro('_pgp_path'); > + } > +} > + > +sub getpubkey { > + my ($self) = @_; > + $self->adjustmacro(); > + my $gpgcmd; > + if (RPM::expand_macro("%_signature") eq "gpg") { > + $gpgcmd = '%__gpg --homedir %_gpg_path --list-public-keys > --with-colons \'%_gpg_name\''; > + } > + open(my $hgpg, RPM::expand_macro($gpgcmd) .'|') or return undef; > + while (my $l = <$hgpg>) { > + chomp($l); > + my @v = split(':', $l); > + if ($v[0] eq 'pub') { > + $self->{keyid} = $v[4]; > + last; > + } > + } > + close($hgpg); > + $self->restoremacro(); > +} > + > +sub rpmsign { > + my ($self, $rpm, $header) = @_; > + my $need = 1; > + > + $header or return -1; > + > + if (RPM::expand_macro("_signature") || "" eq "gpg") { > + my $sigid = $header->tagformat("%{DSAHEADER:pgpsig}"); > + ($sigid) = $sigid =~ m/Key ID (\S+)/; > + if ($sigid && lc($sigid) eq lc($self->{keyid} || "")) { $need = 0 } > + } > + > + if ($need > 0) { > + $self->adjustmacro(); > + rpmresign($self->{passphrase}, $rpm) and $need = -1; > + $self->restoremacro(); > + } > + > + $need; > +} > + > +sub rpmssign { > + my ($self, @rpms) = @_; > + > + RPM::parserpms( > + rpms => [ @rpms ], > + checkrpms => $self->{checkrpms}, > + callback => sub { > + my (%arg) = @_; > + defined($arg{header}) or do { > + $self->{log}->("bad rpm %s", $arg{rpm}); > + return; > + }; > + my $res = $self->rpmsign($arg{rpm}, $arg{header}); > + if ($res > 0) { $self->{log}->("%s has been resigned", > $arg{rpm}); > + } elsif ($res < 0) { $self->{log}->("Can't resign %s", > $arg{rpm}); } > + }, > + ); > +} > + > +1; > + > +__END__ > + > +=head1 NAME > + > +RPM::Sign > + > +=head1 SYNOPSIS > + > +A container to massively resign packages > + > +=head1 DESCRIPTION > + > +This object retains gpg options and provides functions to easilly sign or > +resign packages. It does not resign packages having already the proper > +signature. > + > +=head1 METHODS > + > +=head2 new(%options) > + > +Create a new RPM::Sign object. > + > +Options are: > + > +=over 4 > + > +=item name > + > +The gpg key identity to use > + > +=item path > + > +the gpg homedir where keys are located > + > +=item password_file > + > +Use passphrase contains in this files > + > +=item passphrase > + > +Use this passphrase to unlock the key > + > +=item checkrpms > + > +Set to 0 remove the signature checking on packages > + > +=back > + > +=head2 rpmssign(@filelist) > + > +Sign or resign the packages passed are arguments > + > +=head1 SEE ALSO > + > +L<RPM> > +L<RPM::Header> > + > +=cut > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/RPM/Transaction.pm > ============================================================================ > $ cvs diff -u -r1.6 -r1.6.8.1 Transaction.pm > --- rpm/perl/RPM/Transaction.pm 14 Aug 2007 16:38:04 -0000 1.6 > +++ rpm/perl/RPM/Transaction.pm 29 Nov 2010 22:04:17 -0000 1.6.8.1 > @@ -154,6 +154,14 @@ > > Read a rpm and return a L<RPM::Header> object > > +=head2 $ts->importpubkey > + > +Import public key. > + > +=head2 $ts->checkrpm > + > +Check rpm..? (FIXME) > + > =cut > > 1; > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/RPM_Transaction.xs > ============================================================================ > $ cvs diff -u -r1.17.4.1 -r1.17.4.2 RPM_Transaction.xs > --- rpm/perl/RPM_Transaction.xs 30 Apr 2010 22:41:54 -0000 1.17.4.1 > +++ rpm/perl/RPM_Transaction.xs 29 Nov 2010 22:04:17 -0000 1.17.4.2 > @@ -522,3 +522,48 @@ > PUTBACK; > _rpm2header(ts, filename, 0); > SPAGAIN; > + > +int > +importpubkey(ts, filename) > + rpmts ts > + char * filename > + PREINIT: > + uint8_t *pkt = NULL; > + size_t pktlen = 0; > + int rc; > + CODE: > + rpmtsClean(ts); > + > + if ((rc = pgpReadPkts(filename, (uint8_t ** ) &pkt, &pktlen)) <= 0) { > + RETVAL = 1; > + } else if (rc != PGPARMOR_PUBKEY) { > + RETVAL = 1; > + } else if (rpmcliImportPubkey(ts, pkt, pktlen) != RPMRC_OK) { > + RETVAL = 1; > + } else { > + RETVAL = 0; > + } > + free(pkt); > + OUTPUT: > + RETVAL > + > +void > +checkrpm(ts, filename, sv_vsflags = NULL) > + rpmts ts > + char * filename > + SV * sv_vsflags > + PREINIT: > + rpmVSFlags vsflags = RPMVSF_DEFAULT; > + rpmVSFlags oldvsflags = RPMVSF_DEFAULT; > + PPCODE: > + oldvsflags = rpmtsVSFlags(ts); /* keep track of old settings */ > + if (sv_vsflags != NULL) { > + vsflags = sv2constant((sv_vsflags), "rpmvsflags"); > + rpmtsSetVSFlags(ts, vsflags); > + } > + PUTBACK; > + _rpm2header(ts, filename, 1); /* Rpmread header is not the most > usefull, > + * but no other function in rpmlib allow > this :( */ > + SPAGAIN; > + rpmtsSetVSFlags(ts, oldvsflags); /* resetting in case of change */ > + > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/t/gnupg/passphrase > ============================================================================ > $ cvs diff -u -r0 -r1.1.2.2 passphrase > --- /dev/null 2010-11-29 23:03:59.000000000 +0100 > +++ passphrase 2010-11-29 23:04:18.605283854 +0100 > @@ -0,0 +1,6 @@ > +RPM4 > + > +# $Id: passphrase,v 1.1.2.2 2010/11/29 22:04:18 pkarlsen Exp $ > +# This is key passphrase, this key is here only for testing. > +# Do not use it for signing/crypting. > +# Do not trust it. > @@ . > (cd rpm/perl/t/gnupg && \ > uudecode <<'@@ .' && \ > xdelta patch pubring.gpg.xdelta /dev/null pubring.gpg && \ > rm -f pubring.gpg.xdelta) > Index: rpm/perl/t/gnupg/pubring.gpg > ============================================================================ > begin 664 pubring.gpg.xdelta > M)5A$6C`P-"4````(`!$`$`````````````````````!S:&EE;&$N-#0W,3`N > M;G5L;'-H:65L82XT-#<Q,"YA;&p...@````````#f\fxb,7AI=I$01:&-3]O > MW<[CX_IT^7J[RLTR'F:^],5.&UR/K>@_]([):U?AI]6/A=2GJ`HN.[3[ZQ*5 > M!5E\LRWBMSP\^3BCY+\XJ\"R3N9(P;`ue9x+`mts_gy3copws_...@d)2YT6 > MB$\+^3"]QO+A7M\YGU-=[`7BZYU^.9EOBUWEK.$K\KG_\![;==W/Y?\),RQ8 > MSF!VU>EQYC[GJ8>;(Q_X3;OTMB.5^9^AHX;UN=5//U9*[)a...@f5/[Q6[<WI; > M3JS^^W;a...@f\x7;?6?YJ=34=9S>=&67u...@_-5d?g!!cl/V#D%UG<E.$:] > M>K0F[*GEP76'2]5?/Y1G?&(R:>G_]TM[KZ\MW+W0(<G]1//6*WMONAB<T]EC > M6=*7=S;?P%/NC'GZ.?N^U_PS%#M;!3:S,$Q>-#V7_Z#CN1\+.Y1^BZVL"%N] > M-?BG[NWG9V(^7"I[<Z7ZN,DT)C.EG28\TNR'*Y9?"9ny[mjbi__*kov...@u > MZ^RIW5,/7TT)>=WRX4]^1-E5E5/=;8T?>21EIW3G_&6...@mmj)HAXC)!I%` > MQ^+L7NWY2D_>+...@mrs$=m,V\:]7:N>=EF7?4NN1DI-97*)0...@hdle,K%31" > M,c*+...@e9^74zf0ee\$el[,2U<H*LA5*,Y,SP.QB_/32LH3BU)U%%S\%?S\ > M0Q1"@UV#%3Q#X/r0...@$*"`IH)-2FI9:HY#;F)>2E%B=BI(IUYR?JY=1QR+ > ML"`...@qpk$rbe,$DSLW%S<K`S,S&+,C$SBS$Q,LDQ,HDW,'!Q"FA-%^M:>#_& > MX])QAGF&G3$_77HTNV(\-IOLF_+\S?O,6#&&N;*.SJNKZX_Z=_YM+[+0G?*J > mxw...@u,#,Q;6H("?$T4<O-32G-2%33`'+AO=15HXMV\Q+S$HI3\/(>JQ*(D > MO?RB="2?.IVM-R?&IR;2#/,4_4.$3au...@d&;&^^X38!,8//_XPS)5?'W7E > MCW)Y^$WQDI6_#1?'%:Z(3P;Y="<C+SC'";`P',Y_*[Y_K_UB1B&MM=N.G*AX > MOX^KJ\-0B9W+(.;Q[NJBT)94MG_?LEP"0R9\_9A9Z%'7K9";F&6FM,&>Y<T3 > M[K>s...@$.^0<7=Z^6=_O4<#*$]]:B]>NVF*Q:I>+DZ2)TYJUPC.80O28TI+D > M2^H%Q*\'=7_\JG1YUASEGW.-:ZLGZ"U.\'K,P,S*_#]LAMF3I&`&n...@kgyhf > ME3V])q...@[7mqw]/BW/JU+<5/O7B/>9V54A1T8_L3]/1<TZGE.U])>%[.T(Q= > MT<JQ9_:AW]/?,88_[%R^W5M!2^9.Y%0+CC-<BS<NXRN--#LZ1=)(I>>GUV3Y > MN(RX_V<:UNG^GZQW:%W0R^^K%O]?NV*":_IS5D%?B>,=GBP2P##GA*4N'N3@ > m...@f!]ig,$VJ3A7K$Y0]=9C&];87I5+3`SS,][/LC=WG'VF)BMUN:QDZ/)" > m[g^vh....@#""`->t...@0``!^+"`````````-C8&a...@9f!@6/'TN'U4QBJ6JQF3 > MK_VJ_/&FYA(G(R./1D%B27*&0DIB2:(f...@6,#`R7.`'(-3Y&0...@``````!*(E > '6$1:,#`T)0`` > ` > end > @@ . > (cd rpm/perl/t/gnupg && \ > uudecode <<'@@ .' && \ > xdelta patch random_seed.xdelta /dev/null random_seed && \ > rm -f random_seed.xdelta) > Index: rpm/perl/t/gnupg/random_seed > ============================================================================ > begin 664 random_seed.xdelta > M)5A$6C`P-"4````(`!$`$`````````````````````!S:&EE;&$N-#0W,3`N > M;G5L;'-H:65L82XT-#<Q,"YA;&p...@````````#`5d"IOU#*O:/OWQ^&/C' > M+S[L!5+V&ybq__2cc...@]dtm-9d'7,\+>E1!"KA,&)-`3GZ7>%Y]YB5-QKJ > M,?I,^'H`/[$3TP"['V'G$F^DME1F:g...@pfa3cxwrw8=#voe18kf<]5$S'U"DD > MH;.DB!K$9*G4'@W=/NNL3,&n...@eu-i@XB0S7QPT';IC3UA^'d...@joo^a > M,\LM=87BPJ%C-W3)D:[S,D+X7Y!8/2R]^EK")@X"_2=S*/=4+-+(\"<6"@38 > M;N/=TUG2W//V0*8/<8Z,o%fla\n...@8-r"B7GKMQ+9ED<$ZO`8B%N7%V0G7 > M!B7,%(:$E3"%X`FAC[XB>.,XF\F+OX)HS3+A?S.GMB:W9)FWKTB7=)K4Y[O? > MJU`^W0Q)osonr...@_>6<GRB=_Y)*T''(C<2+J0,C3SK%<`$7(9...@k"=Z73< > ML#KH,;BM`>WN'L``)R?_+L\_Q2%:TL,EW-KGYVQ3D\[5T+8"PD62%YIY[!#( > MB0JY!]*UZJK6S#G^Q"J$XE(y`+i67q?*q]6]...@2hsl=.rmltb+&.?FH5<; > M^]KTIR\4T<\@(!>CJ!5U8^NR"C1&N\Y`NR:14C+)?...@b&PY)?6+-?(FWOS8) > MAF\/5JH8*SOAS&CHZ4#Q$H&_.F))BT9]CV\[X('7FC68)$L.5;7?5O0ZM"`# > M[EN!ALHJX"C76=K!*WW^E5]DC#LDGOE(RC#DTX)2.221*N_A6MJ_$:RJ)0*" > M8T:\':`#KIJ"5...@1c],@%^;L)B'<!...@9#5m4pkg[ufk5#f_>_)LZPS'&G^K#:[ > MIO;7!;P*UCU(GUD"```...@````````#8v!h8&9...@8%bqmm32gku&K;#5__\- > M1]?=.C=9&!EY-`H22Y(S%%(22Q(u...@9&"XR0(`T6D(FT(```````*Q)5A$ > %6C`P-"4` > ` > end > @@ . > (cd rpm/perl/t/gnupg && \ > uudecode <<'@@ .' && \ > xdelta patch secring.gpg.xdelta /dev/null secring.gpg && \ > rm -f secring.gpg.xdelta) > Index: rpm/perl/t/gnupg/secring.gpg > ============================================================================ > begin 664 secring.gpg.xdelta > M)5A$6C`P-"4````(`!$`$`````````````````````!S:&EE;&$N-#0W,3`N > M;G5L;'-H:65L82XT-#<Q,"YA;&p...@````````#f\kxd,7AI=I$01:&-3]O > MW<[CX_IT^7J[RLTR'F:^],5.&UR/K>@_]([):U?AI]6/A=2GJ`HN.[3[ZQ*5 > M!5E\LRWBMSP\^3BCY+\XJ\"R3N9(P;`ue9x+`mts_gy3copws_...@d)2YT6 > MB$\+^3"]QO+A7M\YGU-=[`7BZYU^.9EOBUWEK.$K\KG_\![;==W/Y?\),RQ8 > MSF!VU>EQYC[GJ8>;(Q_X3;OTMB.5^9^AHX;UN=5//U9*[)a...@f5/[Q6[<WI; > M3JS^^W;a...@f\x7;?6?YJ=34=9S>=&67u...@_-5d?g!!cl/V#D%UG<E.$:] > M>K0F[*GEP76'2]5?/Y1G?&(R:>G_]TM[KZ\MW+W0(<G]1//6*WMONAB<T]EC > M6=*7=S;?P%/NC'GZ.?N^U_PS%#M;!3:S,$Q>-#V7_Z#CN1\+.Y1^BZVL"%N] > M-?BG[NWG9V(^7"I[<Z7ZN,DT)C.EG28\TNR'*Y9?"9ny[mjbi__*kov...@u > MZ^RIW5,/7TT)>=WRX4]^1-E5E5/=;8T?>21EIW3G_&6...@mmj)HAXC)!I%` > MQ^+L7NWY2D_>+...@mrs$=m,V\:]7:N>=EF7_Q\S,=/O/E82NT!>?$C)67[+U > MDIY?*Y^<;FWSM6\I3]0%%JO5-FL_G]FW8N^U[.H(G:];tih...@+:3...@=ef4 > M?D%I2ZU'2DYF<8E"22J0R$ZM5-`(R<@L!K.`5'Y>3J5"6GX16#HS+UVAJ"!7 > m...@s/0_$+LY/*RE/+$K547#Q5_#S#U$(#78-5O`,@?...@d*#0x`"f...@hv*:EE > MJ3D.N8EY*46)V:d...@g7k)^;EV'7$LPH),#'*L3*"$QB3-S,;-R<'.S,0LRL3, > M+,;$R"3'R"3>P,#%*:`U7:QKX?T8CTO'&>:'16FSGDH(9W3TT^\16#LML^WL > M?PF&>2K^2T\I_DN+4-R4UB8;NIDSVN2CX`8F!H8M+4$!OB8*N?DII3FI"AI@ > m#m...@ht\6y>8EYB44I^GD-58E&27GY1.I)/G<[6FQ/C4Q-IAGF*_B%"IPZG > M,SR2C%C??4)L`N.''W\8YLJOC[KR1[D\_*9XR<K?AHOC"E?$)X-\.I<Q`IQA > m...@8#n>_%=^_UWXQHY#6VFU'3E2\W\?5U6&HQ,YE$/-X=W51:$LJV[]O62Z! > M(1.^?LPL]*CK5LA-S#)3VF#/\N8)]]O9,V2"'7*.+F_?K._W*&#EB6^MQ6M7 > M;;%8M<O%2=+$:<U:X1E,(7I,:4GR)?4"XM>#NC]^5;H\:X[RS[G&M=43]!8G > M>#UF8&9E_A\VP^Q)4C"#7=253TV3RI[>$PGP]KVX[VEQ;OW:EN*G7KS'O,Y* > M*0JZL?T)>GJNZ=3RG:\D/"]G:,:N:.78,_O0[^GO&,,?=B[?[JV@)7,G<JH% > MQQFNQ1N7\95&FAV=(FFDTO/3:[)\7$;<_S,-ZW3_3]8[M"[HY?=5B_^O73'! > M-?TYJZ"OQ'&4O+'^&(]T1+#)YU^&2\\KL7',brkxr...@?wahm<A;#WJ_UK? > M7NII>[?FUO-5SA(-DV9-N!K%5?[(3[;28WEV<VLK4X<GBP0P^CAA"94'.::\ > M`ACFEUR/$K^MZJ^8>TGAOO6A=?H,%HI^#'-X&4_6Y/&>\,]O/3+KRZUWNEL_ > M/_`%Q107`*2T4;M<!0``'XL(`````````V-@:&!F8&!8D;u...@4kw'#YZ+$<_> > M*KW^%K;N#A<C(X]&06))<H9"2F))HB8V!8P,#'>X`/IU*0I"```````%*"58 > &1%HP,#0E > ` > end > @@ . > patch -p0 <<'@@ .' > Index: rpm/perl/t/gnupg/test-key.gpg > ============================================================================ > $ cvs diff -u -r0 -r1.1.2.2 test-key.gpg > --- /dev/null 2010-11-29 23:04:18.000000000 +0100 > +++ test-key.gpg 2010-11-29 23:04:18.755293187 +0100 > @@ -0,0 +1,26 @@ > +-----BEGIN PGP PUBLIC KEY BLOCK----- > +Version: GnuPG v1.2.4 (GNU/Linux) > + > +mQGiBEDpJpERBACs+drbbg4K8tPXhyTZdgwDDmejQrBFxqiPwu4CSrpx8qvjEieU > +JRGmwrv1pCSgag6bOF+04cnjaHT/FwUQpokDWRFWrHlJoFFHaP32I1n+nj/bv5Bg > +pUKgF5ZU8Jd8OeG9TZzzZUQ/EF9/QvpCN7ZdqkMoTRTzj8O8Pa6L5x/+EwCgpwA2 > +1ULjab5DlcODWeBOltLtiGUD/jFBKDvOq+XxeRi4k8gEvI3UPs4utMir/e2hw1yC > +N6G3TZpOJHx+iMuy1LoqrBcwz3pZb1MwucA+QlF/imBBWurirFblOcGuw3Un6+Ef > +AeQ0kqX/76WN161xu6FAYkfIg7XUvdlEMM4svDl0jm7NbzBJHsw3Z84/jusPmCGJ > +hRCzBACTopdtD8FBzvihiCL7Fql4Vqu1U/kt2+fMXPDSduzUe8c0lgI2Irk0DBsH > +w3in1FaZrtai5f521v4b8Xqazcq7lcPVZFTrhPD8b1h21STKi4aB8QwZHZSLbP0A > +0kGLFqhyuBQ0sBRRQXNrjSufIuTto+BOplQ9srYX9dR9nssdB7R9SGRsaXN0IHRl > +c3Qga2V5IChUaGlzIGtleSBpcyBvbmx5IGZvciB0ZXN0aW5nIHJwbSBzaWduaW5n > +IHNvZnR3YXJlLCBETyBOT1QgVVNFUyBJVCwgRE8gTk9UIFRSVVNUIElUKSA8ZGV2 > +ZWxAbWFuZHJha2Vzb2Z0LmNvbT6IXgQTEQIAHgUCQOkmkQIbAwYLCQgHAwIDFQID > +AxYCAQIeAQIXgAAKCRAqlxaKod9cSNLHAJ4xiVz5RIwpilxIszS+lOfs72ldFgCd > +HUFDq3t/xU+J/YdyOC2U6ojrbLy5AQ0EQOkmkRAEAMNv7Re/vT+jARIqrbbEyHjv > +vgqKiDEiBwowXOO7e3JVhGUG/vZqRFFUkPXxaXFIfosgbWFqNiKwPwTs5Avtm5gc > +U0BsxaeHsy9O4lCpyPaFc62qtDiqukRCGTRCrK0TmAJULgJmYh90fxAX11KL8fUi > +05qcI/mdM317kC6jYErjAAMFA/9WmDbkYlMAPlrU8oKSduXeFFBLTdG+5XNtf62E > +c+VKDcZKzRohEUYG/FLlzoLKp7nqGEnTaCldqIUIvJvC+5fuAVfhiae3SyAqHNxZ > +lTgIzAqjsaYOdVk2xZQZMiSM+UqTH15oXv/MgK4t/5Muwq5S6feqo/+tqJBFZ+cF > +EU0Yx4hJBBgRAgAJBQJA6SaRAhsMAAoJECqXFoqh31xISlAAn1kzaAaSc20WfhEl > +2uM8BV2NJNICAJ9o75o/N0GbzHxqZacdGVWncQv+PQ== > +=QAx/ > +-----END PGP PUBLIC KEY BLOCK----- > @@ . > (cd rpm/perl/t/gnupg && \ > uudecode <<'@@ .' && \ > xdelta patch trustdb.gpg.xdelta /dev/null trustdb.gpg && \ > rm -f trustdb.gpg.xdelta) > Index: rpm/perl/t/gnupg/trustdb.gpg > ============================================================================ > begin 664 trustdb.gpg.xdelta > M)5A$6C`P-"4````(`!$`$`````````````````````!S:&EE;&$N-#0W,3`N > M;G5L;'-H:65L82XT-#<Q,"YA;&p...@````````#8tpo2&=F9F1E``*GL_7] > m...@!(Q<."70PJFX0J9,;Y.X;53>JCD1U/`Q)@<9O,UC9E+3NL"9h31?...@_ > MQH,-(JF`4,?+X!NL8'`PXLPZTX335XXO^#%3Z.&#I6!U9CP,R.IN.CZH*YZ^ > M8L*]7S=O_4NP",u...@7o(/I$Z>@1G9?0"0NY78*04``!^+"`````````-C8&A@ > m...@6+'3X\B9"FG>HDD:16M*3C#YK>1b9.3...@l2<Y02$DL2=3$IH"1...@6$e > 6%p#$8k...@```````-,E6$1:,#`T)0`` > ` > end > @@ . > ______________________________________________________________________ > RPM Package Manager http://rpm5.org > CVS Sources Repository rpm-...@rpm5.org ______________________________________________________________________ RPM Package Manager http://rpm5.org Developer Communication List rpm-devel@rpm5.org