- sign generated keys with the user
[opensuse:sign.git] / sign.c
1 /*
2  * Copyright (c) 2006, 2007 Michael Schroeder, Novell Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program (see the file COPYING); if not, write to the
15  * Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  ***************************************************************/
19
20 #define MYPORT 5167
21
22 char *host;
23 char *user;
24 char *algouser;
25 int port = MYPORT;
26
27 #define HEADER_SIGNATURES 62
28 #define RPMSIGTAG_DSA   267             /* header only sig */
29 #define RPMSIGTAG_RSA   268             /* header only sig */
30 #define RPMSIGTAG_SHA1  269             /* header only hash */
31 #define RPMSIGTAG_SIZE 1000
32 #define RPMSIGTAG_PGP  1002
33 #define RPMSIGTAG_MD5  1004
34 #define RPMSIGTAG_GPG  1005
35
36 #undef BIG_ENDIAN_HOST
37
38
39 /* sha1.c - SHA1 hash function
40  * sha256.c - SHA256 hash function
41  *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
42  *
43  * Please see below for more legal information!
44  *
45  * This file is part of GnuPG.
46  *
47  * GnuPG is free software; you can redistribute it and/or modify
48  * it under the terms of the GNU General Public License as published by
49  * the Free Software Foundation; either version 2 of the License, or
50  * (at your option) any later version.
51  *
52  * GnuPG is distributed in the hope that it will be useful,
53  * but WITHOUT ANY WARRANTY; without even the implied warranty of
54  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
55  * GNU General Public License for more details.
56  *
57  * You should have received a copy of the GNU General Public License
58  * along with this program; if not, write to the Free Software
59  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
60  */
61
62
63 /*  Test vectors:
64  *
65  *  "abc"
66  *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D
67  *
68  *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
69  *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1
70  */
71
72
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <unistd.h>
77 #include <assert.h>
78 #include <fcntl.h>
79 #include <sys/socket.h>
80 #include <netinet/in.h>
81 #include <arpa/inet.h>
82 #include <netdb.h>
83 #include <time.h>
84 #include <errno.h>
85 #include <sys/stat.h>
86 #include <sys/types.h>
87 #include <pwd.h>
88
89
90 typedef unsigned int u32;
91 typedef unsigned char byte;
92
93 #if defined(__GNUC__) && defined(__i386__)
94 static inline u32
95 rol( u32 x, int n)
96 {
97         __asm__("roll %%cl,%0"
98                 :"=r" (x)
99                 :"0" (x),"c" (n));
100         return x;
101 }
102 #else
103 #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
104 #endif
105
106 typedef struct {
107     u32  h0,h1,h2,h3,h4;
108     u32  nblocks;
109     byte buf[64];
110     int  count;
111 } SHA1_CONTEXT;
112
113 static void
114 burn_stack (int bytes)
115 {
116     char buf[128];
117     
118     memset (buf, 0, sizeof buf);
119     bytes -= sizeof buf;
120     if (bytes > 0)
121         burn_stack (bytes);
122 }
123
124
125 void
126 sha1_init( SHA1_CONTEXT *hd )
127 {
128     hd->h0 = 0x67452301;
129     hd->h1 = 0xefcdab89;
130     hd->h2 = 0x98badcfe;
131     hd->h3 = 0x10325476;
132     hd->h4 = 0xc3d2e1f0;
133     hd->nblocks = 0;
134     hd->count = 0;
135 }
136
137
138 /****************
139  * Transform the message X which consists of 16 32-bit-words
140  */
141 static void
142 sha1_transform( SHA1_CONTEXT *hd, byte *data )
143 {
144     u32 a,b,c,d,e,tm;
145     u32 x[16];
146
147     /* get values from the chaining vars */
148     a = hd->h0;
149     b = hd->h1;
150     c = hd->h2;
151     d = hd->h3;
152     e = hd->h4;
153
154 #ifdef BIG_ENDIAN_HOST
155     memcpy( x, data, 64 );
156 #else
157     { int i;
158       byte *p2;
159       for(i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
160         p2[3] = *data++;
161         p2[2] = *data++;
162         p2[1] = *data++;
163         p2[0] = *data++;
164       }
165     }
166 #endif
167
168
169 #define K1  0x5A827999L
170 #define K2  0x6ED9EBA1L
171 #define K3  0x8F1BBCDCL
172 #define K4  0xCA62C1D6L
173 #define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )
174 #define F2(x,y,z)   ( x ^ y ^ z )
175 #define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )
176 #define F4(x,y,z)   ( x ^ y ^ z )
177
178
179 #define M(i) ( tm =   x[i&0x0f] ^ x[(i-14)&0x0f] \
180                     ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
181                , (x[i&0x0f] = rol(tm,1)) )
182
183 #define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \
184                                       + f( b, c, d )  \
185                                       + k             \
186                                       + m;            \
187                                  b = rol( b, 30 );    \
188                                } while(0)
189     R( a, b, c, d, e, F1, K1, x[ 0] );
190     R( e, a, b, c, d, F1, K1, x[ 1] );
191     R( d, e, a, b, c, F1, K1, x[ 2] );
192     R( c, d, e, a, b, F1, K1, x[ 3] );
193     R( b, c, d, e, a, F1, K1, x[ 4] );
194     R( a, b, c, d, e, F1, K1, x[ 5] );
195     R( e, a, b, c, d, F1, K1, x[ 6] );
196     R( d, e, a, b, c, F1, K1, x[ 7] );
197     R( c, d, e, a, b, F1, K1, x[ 8] );
198     R( b, c, d, e, a, F1, K1, x[ 9] );
199     R( a, b, c, d, e, F1, K1, x[10] );
200     R( e, a, b, c, d, F1, K1, x[11] );
201     R( d, e, a, b, c, F1, K1, x[12] );
202     R( c, d, e, a, b, F1, K1, x[13] );
203     R( b, c, d, e, a, F1, K1, x[14] );
204     R( a, b, c, d, e, F1, K1, x[15] );
205     R( e, a, b, c, d, F1, K1, M(16) );
206     R( d, e, a, b, c, F1, K1, M(17) );
207     R( c, d, e, a, b, F1, K1, M(18) );
208     R( b, c, d, e, a, F1, K1, M(19) );
209     R( a, b, c, d, e, F2, K2, M(20) );
210     R( e, a, b, c, d, F2, K2, M(21) );
211     R( d, e, a, b, c, F2, K2, M(22) );
212     R( c, d, e, a, b, F2, K2, M(23) );
213     R( b, c, d, e, a, F2, K2, M(24) );
214     R( a, b, c, d, e, F2, K2, M(25) );
215     R( e, a, b, c, d, F2, K2, M(26) );
216     R( d, e, a, b, c, F2, K2, M(27) );
217     R( c, d, e, a, b, F2, K2, M(28) );
218     R( b, c, d, e, a, F2, K2, M(29) );
219     R( a, b, c, d, e, F2, K2, M(30) );
220     R( e, a, b, c, d, F2, K2, M(31) );
221     R( d, e, a, b, c, F2, K2, M(32) );
222     R( c, d, e, a, b, F2, K2, M(33) );
223     R( b, c, d, e, a, F2, K2, M(34) );
224     R( a, b, c, d, e, F2, K2, M(35) );
225     R( e, a, b, c, d, F2, K2, M(36) );
226     R( d, e, a, b, c, F2, K2, M(37) );
227     R( c, d, e, a, b, F2, K2, M(38) );
228     R( b, c, d, e, a, F2, K2, M(39) );
229     R( a, b, c, d, e, F3, K3, M(40) );
230     R( e, a, b, c, d, F3, K3, M(41) );
231     R( d, e, a, b, c, F3, K3, M(42) );
232     R( c, d, e, a, b, F3, K3, M(43) );
233     R( b, c, d, e, a, F3, K3, M(44) );
234     R( a, b, c, d, e, F3, K3, M(45) );
235     R( e, a, b, c, d, F3, K3, M(46) );
236     R( d, e, a, b, c, F3, K3, M(47) );
237     R( c, d, e, a, b, F3, K3, M(48) );
238     R( b, c, d, e, a, F3, K3, M(49) );
239     R( a, b, c, d, e, F3, K3, M(50) );
240     R( e, a, b, c, d, F3, K3, M(51) );
241     R( d, e, a, b, c, F3, K3, M(52) );
242     R( c, d, e, a, b, F3, K3, M(53) );
243     R( b, c, d, e, a, F3, K3, M(54) );
244     R( a, b, c, d, e, F3, K3, M(55) );
245     R( e, a, b, c, d, F3, K3, M(56) );
246     R( d, e, a, b, c, F3, K3, M(57) );
247     R( c, d, e, a, b, F3, K3, M(58) );
248     R( b, c, d, e, a, F3, K3, M(59) );
249     R( a, b, c, d, e, F4, K4, M(60) );
250     R( e, a, b, c, d, F4, K4, M(61) );
251     R( d, e, a, b, c, F4, K4, M(62) );
252     R( c, d, e, a, b, F4, K4, M(63) );
253     R( b, c, d, e, a, F4, K4, M(64) );
254     R( a, b, c, d, e, F4, K4, M(65) );
255     R( e, a, b, c, d, F4, K4, M(66) );
256     R( d, e, a, b, c, F4, K4, M(67) );
257     R( c, d, e, a, b, F4, K4, M(68) );
258     R( b, c, d, e, a, F4, K4, M(69) );
259     R( a, b, c, d, e, F4, K4, M(70) );
260     R( e, a, b, c, d, F4, K4, M(71) );
261     R( d, e, a, b, c, F4, K4, M(72) );
262     R( c, d, e, a, b, F4, K4, M(73) );
263     R( b, c, d, e, a, F4, K4, M(74) );
264     R( a, b, c, d, e, F4, K4, M(75) );
265     R( e, a, b, c, d, F4, K4, M(76) );
266     R( d, e, a, b, c, F4, K4, M(77) );
267     R( c, d, e, a, b, F4, K4, M(78) );
268     R( b, c, d, e, a, F4, K4, M(79) );
269
270     /* update chainig vars */
271     hd->h0 += a;
272     hd->h1 += b;
273     hd->h2 += c;
274     hd->h3 += d;
275     hd->h4 += e;
276 }
277
278
279 /* Update the message digest with the contents
280  * of INBUF with length INLEN.
281  */
282 static void
283 sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
284 {
285     if( hd->count == 64 ) { /* flush the buffer */
286         sha1_transform( hd, hd->buf );
287         burn_stack (88+4*sizeof(void*));
288         hd->count = 0;
289         hd->nblocks++;
290     }
291     if( !inbuf )
292         return;
293     if( hd->count ) {
294         for( ; inlen && hd->count < 64; inlen-- )
295             hd->buf[hd->count++] = *inbuf++;
296         sha1_write( hd, NULL, 0 );
297         if( !inlen )
298             return;
299     }
300
301     while( inlen >= 64 ) {
302         sha1_transform( hd, inbuf );
303         hd->count = 0;
304         hd->nblocks++;
305         inlen -= 64;
306         inbuf += 64;
307     }
308     burn_stack (88+4*sizeof(void*));
309     for( ; inlen && hd->count < 64; inlen-- )
310         hd->buf[hd->count++] = *inbuf++;
311 }
312
313
314 /* The routine final terminates the computation and
315  * returns the digest.
316  * The handle is prepared for a new cycle, but adding bytes to the
317  * handle will the destroy the returned buffer.
318  * Returns: 20 bytes representing the digest.
319  */
320
321 static void
322 sha1_final(SHA1_CONTEXT *hd)
323 {
324     u32 t, msb, lsb;
325     byte *p;
326
327     sha1_write(hd, NULL, 0); /* flush */;
328
329     t = hd->nblocks;
330     /* multiply by 64 to make a byte count */
331     lsb = t << 6;
332     msb = t >> 26;
333     /* add the count */
334     t = lsb;
335     if( (lsb += hd->count) < t )
336         msb++;
337     /* multiply by 8 to make a bit count */
338     t = lsb;
339     lsb <<= 3;
340     msb <<= 3;
341     msb |= t >> 29;
342
343     if( hd->count < 56 ) { /* enough room */
344         hd->buf[hd->count++] = 0x80; /* pad */
345         while( hd->count < 56 )
346             hd->buf[hd->count++] = 0;  /* pad */
347     }
348     else { /* need one extra block */
349         hd->buf[hd->count++] = 0x80; /* pad character */
350         while( hd->count < 64 )
351             hd->buf[hd->count++] = 0;
352         sha1_write(hd, NULL, 0);  /* flush */;
353         memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
354     }
355     /* append the 64 bit count */
356     hd->buf[56] = msb >> 24;
357     hd->buf[57] = msb >> 16;
358     hd->buf[58] = msb >>  8;
359     hd->buf[59] = msb      ;
360     hd->buf[60] = lsb >> 24;
361     hd->buf[61] = lsb >> 16;
362     hd->buf[62] = lsb >>  8;
363     hd->buf[63] = lsb      ;
364     sha1_transform( hd, hd->buf );
365     burn_stack (88+4*sizeof(void*));
366
367     p = hd->buf;
368   #ifdef BIG_ENDIAN_HOST
369     #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
370   #else /* little endian */
371     #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;      \
372                       *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
373   #endif
374     X(0);
375     X(1);
376     X(2);
377     X(3);
378     X(4);
379   #undef X
380
381 }
382
383 static byte *
384 sha1_read( SHA1_CONTEXT *hd )
385 {
386     return hd->buf;
387 }
388
389 /*****************************************************************/
390
391 typedef struct {
392     u32  h0,h1,h2,h3,h4,h5,h6,h7;
393     u32  nblocks;
394     byte buf[64];
395     int  count;
396 } SHA256_CONTEXT;
397
398 void
399 sha256_init( SHA256_CONTEXT *hd )
400 {
401     hd->h0 = 0x6a09e667;
402     hd->h1 = 0xbb67ae85;
403     hd->h2 = 0x3c6ef372;
404     hd->h3 = 0xa54ff53a;
405     hd->h4 = 0x510e527f;
406     hd->h5 = 0x9b05688c;
407     hd->h6 = 0x1f83d9ab;
408     hd->h7 = 0x5be0cd19;
409
410     hd->nblocks = 0;
411     hd->count = 0;
412 }
413
414 /****************
415  * Transform the message w which consists of 16 32-bit words
416  */
417 static void
418 sha256_transform( SHA256_CONTEXT *hd, byte *data )
419 {
420   u32 a,b,c,d,e,f,g,h;
421   u32 w[64];
422   int t;
423   static const u32 k[]=
424     {
425       0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
426       0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
427       0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
428       0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
429       0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
430       0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
431       0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
432       0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
433       0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
434       0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
435       0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
436     };
437
438   /* get values from the chaining vars */
439   a = hd->h0;
440   b = hd->h1;
441   c = hd->h2;
442   d = hd->h3;
443   e = hd->h4;
444   f = hd->h5;
445   g = hd->h6;
446   h = hd->h7;
447
448 #ifdef BIG_ENDIAN_HOST
449   memcpy( w, data, 64 );
450 #else
451   {
452     int i;
453     byte *p2;
454
455     for(i=0, p2=(byte*)w; i < 16; i++, p2 += 4 )
456       {
457         p2[3] = *data++;
458         p2[2] = *data++;
459         p2[1] = *data++;
460         p2[0] = *data++;
461       }
462   }
463 #endif
464
465 #define ROTR(x,n) (((x)>>(n)) | ((x)<<(32-(n))))
466 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
467 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
468 #define Sum0(x) (ROTR((x),2) ^ ROTR((x),13) ^ ROTR((x),22))
469 #define Sum1(x) (ROTR((x),6) ^ ROTR((x),11) ^ ROTR((x),25))
470 #define S0(x) (ROTR((x),7) ^ ROTR((x),18) ^ ((x)>>3))
471 #define S1(x) (ROTR((x),17) ^ ROTR((x),19) ^ ((x)>>10))
472
473   for(t=16;t<64;t++)
474     w[t] = S1(w[t-2]) + w[t-7] + S0(w[t-15]) + w[t-16];
475
476   for(t=0;t<64;t++)
477     {
478       u32 t1,t2;
479
480       t1=h+Sum1(e)+Ch(e,f,g)+k[t]+w[t];
481       t2=Sum0(a)+Maj(a,b,c);
482       h=g;
483       g=f;
484       f=e;
485       e=d+t1;
486       d=c;
487       c=b;
488       b=a;
489       a=t1+t2;
490       /* printf("t=%d a=%08lX b=%08lX c=%08lX d=%08lX e=%08lX f=%08lX g=%08lX h=
491 %08lX\n",t,a,b,c,d,e,f,g,h); */
492     }
493
494   /* update chaining vars */
495   hd->h0 += a;
496   hd->h1 += b;
497   hd->h2 += c;
498   hd->h3 += d;
499   hd->h4 += e;
500   hd->h5 += f;
501   hd->h6 += g;
502   hd->h7 += h;
503 }
504
505 /* Update the message digest with the contents
506  * of INBUF with length INLEN.
507  */
508 static void
509 sha256_write( SHA256_CONTEXT *hd, byte *inbuf, size_t inlen)
510 {
511     if( hd->count == 64 ) { /* flush the buffer */
512         sha256_transform( hd, hd->buf );
513         burn_stack (328);
514         hd->count = 0;
515         hd->nblocks++;
516     }
517     if( !inbuf )
518         return;
519     if( hd->count ) {
520         for( ; inlen && hd->count < 64; inlen-- )
521             hd->buf[hd->count++] = *inbuf++;
522         sha256_write( hd, NULL, 0 );
523         if( !inlen )
524             return;
525     }
526
527     while( inlen >= 64 ) {
528         sha256_transform( hd, inbuf );
529         hd->count = 0;
530         hd->nblocks++;
531         inlen -= 64;
532         inbuf += 64;
533     }
534     burn_stack (328);
535     for( ; inlen && hd->count < 64; inlen-- )
536         hd->buf[hd->count++] = *inbuf++;
537 }
538 /* The routine final terminates the computation and
539  * returns the digest.
540  * The handle is prepared for a new cycle, but adding bytes to the
541  * handle will the destroy the returned buffer.
542  * Returns: 32 bytes representing the digest.
543  */
544
545 static void
546 sha256_final(SHA256_CONTEXT *hd)
547 {
548     u32 t, msb, lsb;
549     byte *p;
550
551     sha256_write(hd, NULL, 0); /* flush */;
552
553     t = hd->nblocks;
554     /* multiply by 64 to make a byte count */
555     lsb = t << 6;
556     msb = t >> 26;
557     /* add the count */
558     t = lsb;
559     if( (lsb += hd->count) < t )
560         msb++;
561     /* multiply by 8 to make a bit count */
562     t = lsb;
563     lsb <<= 3;
564     msb <<= 3;
565     msb |= t >> 29;
566
567     if( hd->count < 56 ) { /* enough room */
568         hd->buf[hd->count++] = 0x80; /* pad */
569         while( hd->count < 56 )
570             hd->buf[hd->count++] = 0;  /* pad */
571     }
572     else { /* need one extra block */
573         hd->buf[hd->count++] = 0x80; /* pad character */
574         while( hd->count < 64 )
575             hd->buf[hd->count++] = 0;
576         sha256_write(hd, NULL, 0);  /* flush */;
577         memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
578     }
579     /* append the 64 bit count */
580     hd->buf[56] = msb >> 24;
581     hd->buf[57] = msb >> 16;
582     hd->buf[58] = msb >>  8;
583     hd->buf[59] = msb      ;
584     hd->buf[60] = lsb >> 24;
585     hd->buf[61] = lsb >> 16;
586     hd->buf[62] = lsb >>  8;
587     hd->buf[63] = lsb      ;
588     sha256_transform( hd, hd->buf );
589     burn_stack (328);
590
591     p = hd->buf;
592 #ifdef BIG_ENDIAN_HOST
593 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
594 #else /* little endian */
595 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
596                       *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
597 #endif
598     X(0);
599     X(1);
600     X(2);
601     X(3);
602     X(4);
603     X(5);
604     X(6);
605     X(7);
606 #undef X
607 }
608
609 static byte *
610 sha256_read( SHA256_CONTEXT *hd )
611 {
612     return hd->buf;
613 }
614
615
616 /*****************************************************************/
617
618 struct MD5Context {
619         u32 buf[4];
620         u32 bits[2];
621         byte in[64];
622 };
623
624 typedef struct MD5Context MD5_CTX;
625 static void rpmMD5Transform(u32 buf[4], u32 const in[16]);
626
627 #ifdef BIG_ENDIAN_HOST
628 static void byteReverse(unsigned char *buf, unsigned longs)
629 {
630     u32 t;
631     do {
632         t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
633             ((unsigned) buf[1] << 8 | buf[0]);
634         *(u32 *) buf = t;
635         buf += 4;
636     } while (--longs);
637 }
638 #endif
639
640 /*
641  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
642  * initialization constants.
643  */
644 static void md5_init(struct MD5Context *ctx)
645 {
646     ctx->buf[0] = 0x67452301;
647     ctx->buf[1] = 0xefcdab89;
648     ctx->buf[2] = 0x98badcfe;
649     ctx->buf[3] = 0x10325476;
650     ctx->bits[0] = 0;
651     ctx->bits[1] = 0;
652 }
653
654 static void md5_write(struct MD5Context *ctx, byte const *buf, u32 len)
655 {
656     u32 t;
657
658     t = ctx->bits[0];
659     if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
660         ctx->bits[1]++;         /* Carry from low to high */
661     ctx->bits[1] += len >> 29;
662
663     t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
664     if (t) {
665         unsigned char *p = (unsigned char *) ctx->in + t;
666
667         t = 64 - t;
668         if (len < t) {
669             memcpy(p, buf, len);
670             return;
671         }
672         memcpy(p, buf, t);
673 #ifdef BIG_ENDIAN_HOST
674         byteReverse(ctx->in, 16);
675 #endif
676         rpmMD5Transform(ctx->buf, (u32 *) ctx->in);
677         buf += t;
678         len -= t;
679     }
680     while (len >= 64) {
681         memcpy(ctx->in, buf, 64);
682 #ifdef BIG_ENDIAN_HOST
683         byteReverse(ctx->in, 16);
684 #endif
685         rpmMD5Transform(ctx->buf, (u32 *) ctx->in);
686         buf += 64;
687         len -= 64;
688     }
689     memcpy(ctx->in, buf, len);
690 }
691
692 static void md5_final(byte *digest, struct MD5Context *ctx)
693 {
694     unsigned count;
695     unsigned char *p;
696
697     /* Compute number of bytes mod 64 */
698     count = (ctx->bits[0] >> 3) & 0x3F;
699
700     /* Set the first char of padding to 0x80.  This is safe since there is
701        always at least one byte free */
702     p = ctx->in + count;
703     *p++ = 0x80;
704
705     /* Bytes of padding needed to make 64 bytes */
706     count = 64 - 1 - count;
707
708     /* Pad out to 56 mod 64 */
709     if (count < 8) {
710         /* Two lots of padding:  Pad the first block to 64 bytes */
711         memset(p, 0, count);
712 #ifdef BIG_ENDIAN_HOST
713         byteReverse(ctx->in, 16);
714 #endif
715         rpmMD5Transform(ctx->buf, (u32 *) ctx->in);
716
717         /* Now fill the next block with 56 bytes */
718         memset(ctx->in, 0, 56);
719     } else {
720         /* Pad block to 56 bytes */
721         memset(p, 0, count - 8);
722     }
723 #ifdef BIG_ENDIAN_HOST
724     byteReverse(ctx->in, 14);
725 #endif
726
727     /* Append length in bits and transform */
728     ((u32 *) ctx->in)[14] = ctx->bits[0];
729     ((u32 *) ctx->in)[15] = ctx->bits[1];
730
731     rpmMD5Transform(ctx->buf, (u32 *) ctx->in);
732 #ifdef BIG_ENDIAN_HOST
733     byteReverse((unsigned char *) ctx->buf, 4);
734 #endif
735     memcpy(digest, ctx->buf, 16);
736     memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */
737 }
738
739 /* The four core functions - F1 is optimized somewhat */
740 #undef F1
741 #undef F2
742 #undef F3
743 #undef F4
744
745 /* #define F1(x, y, z) (x & y | ~x & z) */
746 #define F1(x, y, z) (z ^ (x & (y ^ z)))
747 #define F2(x, y, z) F1(z, x, y)
748 #define F3(x, y, z) (x ^ y ^ z)
749 #define F4(x, y, z) (y ^ (x | ~z))
750
751 /* This is the central step in the MD5 algorithm. */
752 #define MD5STEP(f, w, x, y, z, data, s) \
753         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
754
755 /*
756  * The core of the MD5 algorithm, this alters an existing MD5 hash to
757  * reflect the addition of 16 longwords of new data.  md5_write blocks
758  * the data and converts bytes into longwords for this routine.
759  */
760 static void rpmMD5Transform(u32 buf[4], u32 const in[16])
761 {
762     register u32 a, b, c, d;
763
764     a = buf[0];
765     b = buf[1];
766     c = buf[2];
767     d = buf[3];
768
769     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
770     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
771     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
772     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
773     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
774     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
775     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
776     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
777     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
778     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
779     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
780     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
781     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
782     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
783     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
784     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
785
786     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
787     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
788     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
789     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
790     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
791     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
792     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
793     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
794     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
795     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
796     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
797     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
798     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
799     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
800     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
801     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
802
803     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
804     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
805     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
806     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
807     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
808     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
809     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
810     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
811     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
812     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
813     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
814     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
815     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
816     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
817     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
818     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
819
820     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
821     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
822     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
823     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
824     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
825     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
826     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
827     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
828     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
829     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
830     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
831     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
832     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
833     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
834     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
835     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
836
837     buf[0] += a;
838     buf[1] += b;
839     buf[2] += c;
840     buf[3] += d;
841 }
842
843
844
845 /*****************************************************************/
846
847
848
849 #define CRCINIT 0xb704ce
850 #define CRCPOLY 0x864cfb
851
852
853 u32
854 crc24(byte *octets, int len)
855 {
856   u32 crc = CRCINIT;
857   int i;
858
859   while (len-- > 0) {
860     crc ^= (*octets++) << 16;
861     for (i = 0; i < 8; i++) {
862       crc <<= 1;
863       if (crc & 0x1000000)
864         crc ^= CRCPOLY;
865     }
866   }
867   return crc & 0xffffff;
868 }
869
870 void
871 printr64(FILE *f, byte *str, int len)
872 {
873   int a, b, c, i;
874   static byte bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
875
876   i = 0;
877   while (len > 0)
878     {
879       if (++i == 16)
880         {
881           i = 0;
882           putc('\n', f);
883         }
884       a = *str++;
885       b = --len > 0 ? *str++ : 0;
886       c = --len > 0 ? *str++ : 0;
887       --len;
888       putc(bintoasc[a >> 2], f);
889       putc(bintoasc[(a & 3) << 4 | b >> 4], f);
890       putc(len > -2 ? bintoasc[(b & 15) << 2 | c >> 6] : '=', f);
891       putc(len > -1 ? bintoasc[c & 63] : '=', f);
892     }
893     putc('\n', f);
894 }
895
896 ssize_t xread(int fd, void *buf, size_t count)
897 {
898   ssize_t r, r2;
899   r2 = 0;
900   while(count)
901     {
902       r = read(fd, buf, count);
903       if (r <= 0)
904         return r2 ? r2 : r;
905       count -= r;
906       buf += r;
907       r2 += r;
908     }
909   return r2;
910 }
911
912 ssize_t xwrite(int fd, void *buf, size_t count)
913 {
914   ssize_t r, r2;
915   r2 = 0;
916   while(count)
917     {
918       r = write(fd, buf, count);
919       if (r < 0)
920         {
921           perror("write");
922           exit(1);
923         }
924       count -= r;
925       buf += r;
926       r2 += r;
927     }
928   return r2;
929 }
930
931 uid_t uid;
932
933 int opensocket()
934 {
935   static int hostknown;
936   static struct sockaddr_in svt;
937   int sock;
938
939   if (!hostknown)
940     {
941       svt.sin_addr.s_addr = inet_addr(host);
942       svt.sin_family = AF_INET;
943       if (svt.sin_addr.s_addr == -1)
944         {
945           struct hostent *hp;
946           if (!(hp = gethostbyname(host)))
947             {
948               printf("%s: unknown host\n", host);
949               exit(1);
950             }
951           memmove((char *)&svt.sin_addr, (char *)hp->h_addr, hp->h_length);
952           svt.sin_family = hp->h_addrtype;
953         }
954       svt.sin_port = htons(port);
955       hostknown = 1;
956     }
957   if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
958     {
959       perror("socket");
960       exit(1);
961     }
962   if (uid)
963     seteuid(0);
964   for (;;)
965     {
966       if (!bindresvport(sock, (struct sockaddr_in *)0))
967         break;
968       if (errno != EADDRINUSE)
969         {
970           perror("bindresvport");
971           exit(1);
972         }
973       sleep(1);
974     }
975   if (uid)
976     {
977       if (seteuid(uid))
978         {
979           perror("seteuid");
980           exit(1);
981         }
982     }
983   if (connect(sock, (struct sockaddr *)&svt, sizeof(svt)))
984     {
985       perror(host);
986       exit(1);
987     }
988   return sock;
989 }
990
991 int verbose;
992
993 #define HASH_SHA1       0
994 #define HASH_SHA256     1
995
996 char *hashname[] = {"SHA1", "SHA256"};
997 int  hashlen[] = {20, 32};
998 int  hashtag[] = { RPMSIGTAG_GPG, RPMSIGTAG_PGP };
999 int  hashtagh[] = { RPMSIGTAG_DSA, RPMSIGTAG_RSA };
1000 int hashalgo = HASH_SHA1;
1001 char *timearg;
1002 char *privkey;
1003 int noheaderonly;
1004
1005 typedef union {
1006   SHA1_CONTEXT sha1;
1007   SHA256_CONTEXT sha256;
1008 } HASH_CONTEXT;
1009
1010 void hash_init(HASH_CONTEXT *c)
1011 {
1012   if (hashalgo == HASH_SHA1)
1013     sha1_init(&c->sha1);
1014   else if (hashalgo == HASH_SHA256)
1015     sha256_init(&c->sha256);
1016 }
1017
1018 void hash_write(HASH_CONTEXT *c, unsigned char *b, size_t l)
1019 {
1020   if (hashalgo == HASH_SHA1)
1021     sha1_write(&c->sha1, b, l);
1022   else if (hashalgo == HASH_SHA256)
1023     sha256_write(&c->sha256, b, l);
1024 }
1025
1026 void hash_final(HASH_CONTEXT *c)
1027 {
1028   if (hashalgo == HASH_SHA1)
1029     sha1_final(&c->sha1);
1030   else if (hashalgo == HASH_SHA256)
1031     sha256_final(&c->sha256);
1032 }
1033
1034 unsigned char *hash_read(HASH_CONTEXT *c)
1035 {
1036   if (hashalgo == HASH_SHA1)
1037     return sha1_read(&c->sha1);
1038   else if (hashalgo == HASH_SHA256)
1039     return sha256_read(&c->sha256);
1040   return 0;
1041 }
1042
1043 #define MODE_UNSET        0
1044 #define MODE_RPMSIGN      1
1045 #define MODE_CLEARSIGN    2
1046 #define MODE_DETACHEDSIGN 3
1047 #define MODE_KEYID        4
1048 #define MODE_PUBKEY       5
1049 #define MODE_KEYGEN       6
1050
1051 char *modes[] = {"?", "rpm sign", "clear sign", "detached sign"};
1052
1053 void
1054 readprivkey()
1055 {
1056   FILE *fp;
1057   int l, ll;
1058   if ((fp = fopen(privkey, "r")) == 0)
1059     {
1060       perror(privkey);
1061       exit(1);
1062     }
1063   privkey = malloc(8192);
1064   *privkey = 0;
1065   l = 0;
1066   while (l < 8192 && (ll = fread(privkey + l, 1, 8192 - l, fp)) > 0)
1067     l += ll;
1068   fclose(fp);
1069   if (l == 0)
1070     {
1071       fprintf(stderr, "empty private\n");
1072       exit(1);
1073     }
1074   if (l == 8192)
1075     {
1076       fprintf(stderr, "private key too large\n");
1077       exit(1);
1078     }
1079   if (privkey[l - 1] == '\n')
1080     l--;
1081   privkey[l] = 0;
1082 }
1083
1084 int
1085 doreq(int sock, int argc, char **argv, byte *buf, int bufl, int nret)
1086 {
1087   byte *bp;
1088   int i, l, v, outl, errl;
1089
1090   bp = buf + 2;
1091   *bp++ = 0;
1092   *bp++ = 0;
1093   *bp++ = argc >> 8;
1094   *bp++ = argc & 255;
1095   for (i = 0; i < argc; i++)
1096     {
1097       v = strlen(argv[i]);
1098       *bp++ = v >> 8;
1099       *bp++ = v & 255;
1100     }
1101   for (i = 0; i < argc; i++)
1102     {
1103       v = strlen(argv[i]);
1104       if (bp + v > buf + bufl)
1105         {
1106           fprintf(stderr, "request buffer overflow\n");
1107           return -1;
1108         }
1109       memcpy(bp, argv[i], v);
1110       bp += v;
1111     }
1112   v = bp - (buf + 4);
1113   buf[0] = v >> 8;
1114   buf[1] = v & 255;
1115
1116   i = bp - buf;
1117   if (write(sock, buf, i) != i)
1118     {
1119       perror("write");
1120       return -1;
1121     }
1122   l = 0;
1123   for (;;)
1124     {
1125       int ll;
1126       if (l == bufl)
1127         {
1128           fprintf(stderr, "packet too big\n");
1129           return -1;
1130         }
1131       ll = read(sock, buf + l, bufl - l);
1132       if (ll == -1)
1133         {
1134           perror("read");
1135           return -1;
1136         }
1137       if (ll == 0)
1138         break;
1139       l += ll;
1140     }
1141   close(sock);
1142   if (l < 6)
1143     {
1144       fprintf(stderr, "packet too small\n");
1145       return -1;
1146     }
1147   outl = buf[2] << 8 | buf[3];
1148   errl = buf[4] << 8 | buf[5];
1149   if (l != outl + errl + 6)
1150     {
1151       fprintf(stderr, "packet size mismatch %d %d %d\n", l, outl, errl);
1152       return -1;
1153     }
1154   if (errl)
1155     fwrite(buf + 6 + outl, 1, errl, stderr);
1156
1157   if (buf[0] << 8 | buf[1])
1158     return -(buf[0] << 8 | buf[1]);
1159   memmove(buf, buf + 6, outl);
1160   if (nret)
1161     {
1162       if (outl < 2 + 2 * nret)
1163         {
1164           fprintf(stderr, "answer too small\n");
1165           return -1;
1166         }
1167       if (buf[0] != 0 || buf[1] != nret)
1168         {
1169           fprintf(stderr, "bad answer\n");
1170           return -1;
1171         }
1172       l = 2;
1173       for (i = 0; i < nret; i++)
1174         l += 2 + (buf[2 + i * 2] << 8 | buf[2 + i * 2 + 1]);
1175       if (l != outl)
1176         {
1177           fprintf(stderr, "answer size mismatch\n");
1178           return -1;
1179         }
1180     }
1181   return outl;
1182 }
1183
1184 int
1185 rpminsertsig(byte *rpmsig, int *rpmsigsizep, int *rpmsigcntp, int *rpmsigdlenp, int sigtag, byte *newsig, int newsiglen)
1186 {
1187   int rpmsigsize, rpmsigcnt, rpmsigdlen;
1188   int i, myi, tag;
1189   byte *rsp;
1190   u32 before;
1191   int pad;
1192   byte *region = 0;
1193
1194   rpmsigsize = *rpmsigsizep;
1195   rpmsigcnt = *rpmsigcntp;
1196   rpmsigdlen = *rpmsigdlenp;
1197
1198   if (newsiglen > 1024)
1199     {
1200       fprintf(stderr, "signature too big: %d\n", newsiglen);
1201       return -1;
1202     }
1203   rsp = rpmsig;
1204   for (i = 0; i < rpmsigcnt; i++)
1205     {
1206       tag = rsp[0] << 24 | rsp[1] << 16 | rsp[2] << 8 | rsp[3];
1207       // fprintf(stderr, "tag %d\n", tag);
1208       if (i == 0 && tag >= 61 && tag < 64)
1209         region = rsp;
1210       if (tag >= sigtag)
1211         break;
1212       rsp += 16;
1213     }
1214   // fprintf(stderr, "inserting at position %d\n", i);
1215   if (i < rpmsigcnt && tag == sigtag)
1216     abort();
1217
1218   memmove(rsp + 16, rsp, rpmsigsize - i * 16);
1219   memset(rsp, 0, 16);
1220   rsp[2] = sigtag >> 8;
1221   rsp[3] = sigtag & 0xff;
1222   rsp[7] = 7;
1223   rsp[14] = newsiglen >> 8;
1224   rsp[15] = newsiglen & 0xff;
1225
1226   pad = i == rpmsigcnt ? 0 : 3 - ((newsiglen + 3) & 3);
1227   if (i < rpmsigcnt)
1228     {
1229       pad = 3 - ((newsiglen + 3) & 3);
1230       before = rsp[16 + 8] << 24 | rsp[16 + 9] << 16 | rsp[16 + 10] << 8 | rsp[16 + 11];
1231     }
1232   else
1233     {
1234       pad = 0;
1235       if (region)
1236         before = region[8] << 24 | region[9] << 16 | region[10] << 8 | region[11];
1237       else
1238         before = rpmsigdlen;
1239     }
1240   // fprintf(stderr, "before=%d sigdlen=%d\n", before, rpmsigdlen);
1241   rpmsigcnt++;
1242   if (before < rpmsigdlen)
1243     memmove(rpmsig + rpmsigcnt * 16 + before + newsiglen + pad, rpmsig + rpmsigcnt * 16 + before, rpmsigdlen - before);
1244   memmove(rpmsig + rpmsigcnt * 16 + before, newsig, newsiglen);
1245   if (pad)
1246     memset(rpmsig + rpmsigcnt * 16 + before + newsiglen, 0, pad);
1247   rsp[8] = before >> 24;
1248   rsp[9] = before >> 16;
1249   rsp[10] = before >> 8;
1250   rsp[11] = before;
1251   rpmsigdlen += newsiglen + pad;
1252
1253   // now fix up all entries behind us
1254   myi = i;
1255   rsp = rpmsig;
1256   for (i = 0; i < rpmsigcnt; i++, rsp += 16)
1257     {
1258       if (i == myi)
1259         continue;
1260       tag = rsp[8] << 24 | rsp[9] << 16 | rsp[10] << 8 | rsp[11];
1261       if (tag < before)
1262         continue;
1263       tag += newsiglen + pad;
1264       rsp[8] = tag >> 24;
1265       rsp[9] = tag >> 16;
1266       rsp[10] = tag >> 8;
1267       rsp[11] = tag;
1268     }
1269   if (region)
1270     {
1271       if ((region[12] << 24 | region[13] << 16 | region[14] << 8 | region[15]) != 16)
1272         {
1273           fprintf(stderr, "bad region in signature\n");
1274           return -1;
1275         }
1276       rsp = rpmsig + rpmsigcnt * 16 + (region[8] << 24 | region[9] << 16 | region[10] << 8 | region[11]);
1277       tag = rsp[8] << 24 | rsp[9] << 16 | rsp[10] << 8 | rsp[11];
1278       if (-tag != (rpmsigcnt - 1) * 16)
1279         {
1280           fprintf(stderr, "bad region data in signature\n");
1281           return -1;
1282         }
1283       tag -= 16;
1284       rsp[8] = tag >> 24;
1285       rsp[9] = tag >> 16;
1286       rsp[10] = tag >> 8;
1287       rsp[11] = tag;
1288     }
1289   pad = 7 - ((rpmsigdlen + 7) & 7);
1290   if (pad)
1291     memset(rpmsig + rpmsigcnt * 16 + rpmsigdlen, 0, pad);
1292   rpmsigsize = rpmsigcnt * 16 + rpmsigdlen + pad;
1293
1294   *rpmsigsizep = rpmsigsize;
1295   *rpmsigcntp = rpmsigcnt;
1296   *rpmsigdlenp = rpmsigdlen;
1297   return 0;
1298 }
1299
1300 int
1301 sign(char *filename, int isfilter, int mode)
1302 {
1303   u32 signtime;
1304   u32 crc;
1305   byte buf[8192], *bp;
1306   byte *cbuf;
1307   int cbufl;
1308   int l, fd;
1309   int i;
1310   byte hash[5], *p, *ph = 0;
1311   HASH_CONTEXT ctx;
1312   MD5_CTX md5ctx;
1313   HASH_CONTEXT hctx;
1314   int force = 1;
1315   int outl, outlh, errl;
1316   int sock;
1317   int ulen;
1318   byte rpmlead[96];
1319   byte rpmsighead[16], *rsp;
1320   byte *rpmsig = 0;
1321   int rpmsigcnt = 0, rpmsigdlen = 0;
1322   int rpmsigsize = 0, tag;
1323   u32 lensig, lenhdr;
1324   byte rpmmd5sum[16];
1325   byte rpmmd5sum2[16];
1326   byte *hdrin_md5 = 0;
1327   u32 hdrin_size = 0;
1328   u32 rpmdataoff = 0;
1329   char *outfilename = 0;
1330   FILE *fout = 0;
1331   int foutfd;
1332   int getbuildtime = 0;
1333   int buildtimeoff = 0;
1334   byte btbuf[4];
1335   int gotsha1 = 0;
1336
1337   if (mode == MODE_UNSET)
1338     {
1339       force = 0;
1340       if (isfilter)
1341         {
1342           fprintf(stderr, "please specify a mode for filter usage.\n");
1343           exit(1);
1344         }
1345       l = strlen(filename);
1346       if (l > 4 && (!strcmp(filename + l - 4, ".rpm") || !strcmp(filename + l - 4, ".spm")))
1347         mode = MODE_RPMSIGN;
1348       else
1349         mode = MODE_CLEARSIGN;
1350     }
1351   if (isfilter)
1352     fd = 0;
1353   else if ((fd = open(filename, O_RDONLY)) == -1)
1354     {
1355       perror(filename);
1356       exit(1);
1357     }
1358   else
1359     {
1360       outfilename = malloc(strlen(filename) + 16);
1361       if (!outfilename)
1362         {
1363           fprintf(stderr, "out of memory for filename\n");
1364           exit(1);
1365         }
1366       if (mode == MODE_DETACHEDSIGN)
1367         sprintf(outfilename, "%s.asc", filename);
1368       else
1369         sprintf(outfilename, "%s.sIgN%d", filename, getpid());
1370     }
1371   if (!timearg || mode == MODE_KEYID || mode == MODE_PUBKEY)
1372     signtime = (u32)time((time_t)0);
1373   else if (*timearg >= '0' && *timearg <= '9')
1374     signtime = (u32)atoi(timearg);
1375   else if (mode == MODE_RPMSIGN && !strcmp(timearg, "buildtime"))
1376     {
1377       getbuildtime = 1;
1378       signtime = (u32)0;                /* rpmsign && buildtime */
1379     }
1380   else
1381     {
1382       struct stat stb;
1383       if (fstat(fd, &stb))
1384         {
1385           perror("fstat");
1386           exit(1);
1387         }
1388       if (S_ISFIFO(stb.st_mode))
1389         {
1390           fprintf(stderr, "cannot use mtime on pipes\n");
1391           exit(1);
1392         }
1393       signtime = (u32) stb.st_mtime;
1394     }
1395
1396   if (mode == MODE_RPMSIGN)
1397     {
1398       if (read(fd, rpmlead, 96) != 96 || rpmlead[0] != 0xed || rpmlead[1] != 0xab || rpmlead[2] != 0xee || rpmlead[3] != 0xdb)
1399         {
1400           fprintf(stderr, "%s: not a rpm\n", filename);
1401           exit(1);
1402         }
1403       if (rpmlead[4] != 0x03 || rpmlead[0x4e] != 0 || rpmlead[0x4f] != 5)
1404         {
1405           fprintf(stderr, "%s: not a v3 rpm or not new header styles\n", filename);
1406           exit(1);
1407         }
1408       if (read(fd, rpmsighead, 16) != 16 || rpmsighead[0] != 0x8e || rpmsighead[1] != 0xad || rpmsighead[2] != 0xe8 || rpmsighead[3] != 0x01)
1409         {
1410           fprintf(stderr, "%s: bad signature header\n", filename);
1411           exit(1);
1412         }
1413       rpmsigcnt = rpmsighead[8] << 24 | rpmsighead[9] << 16 | rpmsighead[10] << 8 | rpmsighead[11];
1414       rpmsigdlen = rpmsighead[12] << 24 | rpmsighead[13] << 16 | rpmsighead[14] << 8 | rpmsighead[15];
1415       rpmsigsize = rpmsigcnt * 16 + ((rpmsigdlen + 7) & ~7);
1416       rpmsig = malloc(rpmsigsize + 2 * (1024 + 16 + 4));
1417       if (!rpmsig)
1418         {
1419           fprintf(stderr, "%s: no memory for signature area\n", filename);
1420           exit(1);
1421         }
1422       if (xread(fd, rpmsig, rpmsigsize) != rpmsigsize)
1423         {
1424           fprintf(stderr, "%s: read error in signature area\n", filename);
1425           exit(1);
1426         }
1427       rpmdataoff = 96 + 16 + rpmsigsize;
1428       rsp = rpmsig;
1429       for (i = 0; i < rpmsigcnt; i++)
1430         {
1431           tag = rsp[0] << 24 | rsp[1] << 16 | rsp[2] << 8 | rsp[3];
1432           if (tag == hashtag[hashalgo] || tag == hashtagh[hashalgo])
1433             {
1434               fprintf(isfilter ? stderr : stdout, "%s: already signed\n", filename);
1435               close(fd);
1436               free(rpmsig);
1437               if (outfilename)
1438                 free(outfilename);
1439               if (isfilter)
1440                 exit(1);
1441               return 1;
1442             }
1443           if (tag == RPMSIGTAG_SHA1)
1444             gotsha1 = 1;
1445           if (tag == RPMSIGTAG_MD5)
1446             {
1447               if (rsp[4] || rsp[5] || rsp[6] || rsp[7] != 7 || rsp[12] || rsp[13] || rsp[14] || rsp[15] != 16)
1448                 {
1449                   fprintf(stderr, "%s: bad MD5 tag\n", filename);
1450                   exit(1);
1451                 }
1452               hdrin_md5 = rpmsig + rpmsigcnt * 16 + (rsp[8] << 24 | rsp[9] << 16 | rsp[10] << 8 | rsp[11]);
1453             }
1454           if (tag == RPMSIGTAG_SIZE)
1455             {
1456               if (rsp[4] || rsp[5] || rsp[6] || rsp[7] != 4 || rsp[12] || rsp[13] || rsp[14] || rsp[15] != 1)
1457                 {
1458                   fprintf(stderr, "%s: bad SIZE tag\n", filename);
1459                   exit(1);
1460                 }
1461               p = rpmsig + rpmsigcnt * 16 + (rsp[8] << 24 | rsp[9] << 16 | rsp[10] << 8 | rsp[11]);
1462               hdrin_size = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
1463             }
1464           rsp += 16;
1465         }
1466     }
1467
1468
1469   hash_init(&ctx);
1470   if (mode == MODE_CLEARSIGN)
1471     {
1472       int have = 0;
1473       int i, j;
1474       int nl = 0;
1475       int first = 1;
1476
1477       if ((cbuf = malloc(8192)) == 0)
1478         {
1479           fprintf(stderr, "no mem for clearsign buffer\n");
1480           exit(1);
1481         }
1482       cbufl = 8192;
1483       l = read(fd, (char *)cbuf, cbufl);
1484       if (l < 0)
1485         {
1486           perror("read");
1487           exit(1);
1488         }
1489       if (l >= 34 && !strncmp((char *)cbuf, "-----BEGIN PGP SIGNED MESSAGE-----", 34))
1490         {
1491           fprintf(isfilter ? stderr : stdout, "%s: already signed\n", filename);
1492           close(fd);
1493           if (outfilename)
1494             free(outfilename);
1495           if (isfilter)
1496             exit(1);
1497           return(1);
1498         }
1499       for (i = 0; i < l; i++)
1500         {
1501           if (cbuf[i] >= 32 || cbuf[i] == '\t' || cbuf[i] == '\r' || cbuf[i] == '\n')
1502             continue;
1503           first++;
1504         }
1505       if (first > 4 && !force)
1506         {
1507           fprintf(stderr, "%s: won't clearsign binaries\n", filename);
1508           exit(1);
1509         }
1510       sock = opensocket();
1511       if (isfilter)
1512         fout = stdout;
1513       else if ((fout = fopen(outfilename, "w")) == 0)
1514         {
1515           perror(outfilename);
1516           exit(1);
1517         }
1518       foutfd = fileno(fout);
1519       fprintf(fout, "-----BEGIN PGP SIGNED MESSAGE-----\nHash: %s\n\n", hashname[hashalgo]);
1520       while (first || (l = read(fd, (char *)cbuf + have, cbufl - have)) > 0 || (l == 0 && have))
1521         {
1522           first = 0;
1523           if (nl)
1524             hash_write(&ctx, (unsigned char *)"\r\n",  2);
1525           nl = 0;
1526           l += have;
1527           for (i = 0; i < l; i++)
1528             if (cbuf[i] == '\n')
1529               break;
1530           if (i == l && i == cbufl && l != have)
1531             {
1532               cbufl *= 2;
1533               cbuf = realloc(cbuf, cbufl);
1534               if (!cbuf)
1535                 {
1536                   fprintf(stderr, "no mem for clearsign buffer\n");
1537                   exit(1);
1538                 }
1539               have = l;
1540               continue;
1541             }
1542           if (cbuf[0] == '-' || (l > 4 && !strncmp((char *)cbuf, "From ", 5)))
1543             fprintf(fout, "- ");
1544           if (i == l)
1545             {
1546               /* EOF reached, line is unterminated */
1547               cbuf[l] = '\n';
1548               l++;
1549             }
1550           if (i > 20000)
1551             {
1552               fprintf(stderr, "line too long for clearsign\n");
1553               exit(1);
1554             }
1555           fwrite(cbuf, 1, i + 1, fout);
1556           for (j = i - 1; j >= 0; j--)
1557             if (cbuf[j] != '\r' && cbuf[j] != ' ' && cbuf[j] != '\t')
1558               break;
1559           if (j >= 0)
1560             hash_write(&ctx, cbuf, j + 1);
1561           nl = 1;
1562           i++;
1563           if (i < l)
1564             memmove(cbuf, cbuf + i, l - i);
1565           have = l - i;
1566         }
1567       if (l < 0)
1568         {
1569           perror("read");
1570           if (!isfilter)
1571             unlink(outfilename);
1572           exit(1);
1573         }
1574       free(cbuf);
1575       cbuf = 0;
1576       cbufl = 0;
1577     }
1578   else if (mode == MODE_KEYID || mode == MODE_PUBKEY)
1579     {
1580       /* sign empty string */
1581       sock = opensocket();
1582     }
1583   else
1584     {
1585       sock = opensocket();
1586       if (mode == MODE_RPMSIGN)
1587         {
1588           md5_init(&md5ctx);
1589           hash_init(&hctx);
1590         }
1591       lensig = 0;
1592       lenhdr = 0;
1593       while ((l = read(fd, (char *)buf, sizeof(buf))) > 0)
1594         {
1595           if (!lensig && mode == MODE_RPMSIGN)
1596             {
1597               if (l < 16)
1598                 {
1599                   fprintf(stderr, "cannot calculate header size: short read\n");
1600                   exit(1);
1601                 }
1602               lenhdr = 16;
1603               lenhdr += 16 * (buf[8] << 24 |  buf[9] << 16 | buf[10] << 8 | buf[11]);
1604               lenhdr += buf[12] << 24 |  buf[13] << 16 | buf[14] << 8 | buf[15];
1605             }
1606           if (getbuildtime && !lensig)
1607             {
1608               int n;
1609               n = buf[8] << 24 |  buf[9] << 16 | buf[10] << 8 | buf[11];
1610               if ((l - 16) / 16 < n)
1611                 n = (l - 16) / 16;
1612               for (i = 0; i < n; i++)
1613                 if (!memcmp(buf + 16 + 16 * i, "\0\0\003\356\0\0\0\4", 8))
1614                   break;
1615               if (i == n)
1616                 {
1617                   fprintf(stderr, "cannot calculate buildtime: tag not found\n");
1618                   exit(1);
1619                 }
1620               buildtimeoff = 16 + (buf[8] << 24 |  buf[9] << 16 | buf[10] << 8 | buf[11]) * 16;
1621               i = 16 + 16 * i + 8;
1622               buildtimeoff += buf[i] << 24 |  buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3];
1623             }
1624           if (getbuildtime && lensig < buildtimeoff + 4 && lensig + l > buildtimeoff)
1625             {
1626               for (i = 0; i < l; i++)
1627                 if (lensig + i >= buildtimeoff && lensig + i < buildtimeoff + 4)
1628                   btbuf[lensig + i - buildtimeoff] = buf[i];
1629             }
1630           hash_write(&ctx, buf,  l);
1631           if (mode == MODE_RPMSIGN)
1632             {
1633               md5_write(&md5ctx, buf, l);
1634               if (lenhdr)
1635                 {
1636                   if (l >= lenhdr)
1637                     {
1638                       hash_write(&hctx, buf,  lenhdr);
1639                       lenhdr = 0;
1640                     }
1641                   else
1642                     {
1643                       hash_write(&hctx, buf,  l);
1644                       lenhdr -= l;
1645                     }
1646                 }
1647             }
1648           lensig += l;
1649         }
1650       if (mode == MODE_RPMSIGN)
1651         {
1652           md5_final(rpmmd5sum, &md5ctx);
1653           if (lenhdr)
1654             {
1655               fprintf(stderr, "%s: bad header size (%u)\n", filename, lenhdr);
1656               exit(1);
1657             }
1658         }
1659       if (hdrin_size && lensig != hdrin_size)
1660         {
1661           fprintf(stderr, "%s: SIZE checksum error %d %d\n", filename, hdrin_size, lensig);
1662           exit(1);
1663         }
1664       if (hdrin_md5 && memcmp(hdrin_md5, rpmmd5sum, 16))
1665         {
1666           fprintf(stderr, "%s: MD5 checksum error\n", filename);
1667           exit(1);
1668         }
1669       if (getbuildtime && lensig < buildtimeoff + 4)
1670         {
1671           fprintf(stderr, "cannot calculate buildtime: bad data pointer\n");
1672           exit(1);
1673         }
1674       if (getbuildtime)
1675         signtime = (u32)(btbuf[0] << 24 | btbuf[1] << 16 | btbuf[2] << 8 | btbuf[3]);
1676     }
1677
1678   if (verbose && mode != MODE_KEYID && mode != MODE_PUBKEY)
1679     {
1680       if (*user)
1681         fprintf(isfilter ? stderr : stdout, "%s %s user %s\n", modes[mode],  filename, user);
1682       else
1683         fprintf(isfilter ? stderr : stdout, "%s %s\n", modes[mode],  filename);
1684     }
1685
1686   hash[0] = mode == MODE_CLEARSIGN ? 0x01 : 0x00; /* class */
1687   hash[1] = signtime >> 24;
1688   hash[2] = signtime >> 16;
1689   hash[3] = signtime >> 8;
1690   hash[4] = signtime;
1691   hash_write(&ctx, hash, 5);
1692   hash_final(&ctx);
1693   p = hash_read(&ctx);
1694   ph = 0;
1695   outlh = 0;
1696   if (mode == MODE_RPMSIGN)
1697     {
1698       hash_write(&hctx, hash, 5);
1699       hash_final(&hctx);
1700       /* header only seems to work only if there's a header only hash */
1701       if (!noheaderonly && gotsha1)
1702         ph = hash_read(&hctx);
1703     }
1704
1705   ulen = strlen(user);
1706   if (!privkey && !ph)
1707     {
1708       if (ulen + hashlen[hashalgo] * 2 + 1 + 5 * 2 + 4 + 1 + (hashalgo == HASH_SHA1 ? 0 : strlen(hashname[hashalgo]) + 1) > sizeof(buf))
1709         {
1710           fprintf(stderr, "packet too big\n");
1711           if (mode == MODE_CLEARSIGN && !isfilter)
1712             unlink(outfilename);
1713           exit(1);
1714         }
1715       buf[0] = ulen >> 8;
1716       buf[1] = ulen;
1717       buf[2] = 0;
1718       buf[3] = 0;
1719       memmove(buf + 4, user, ulen);
1720       bp = buf + 4 + ulen;
1721       if (hashalgo != HASH_SHA1)
1722         {
1723           strcpy((char *)bp, hashname[hashalgo]);
1724           bp += strlen((char *)bp);
1725           *bp++ = ':';
1726         }
1727       if (mode == MODE_PUBKEY)
1728         {
1729           strcpy((char *)bp, "PUBKEY");
1730           bp += 6;
1731         }
1732       else
1733         {
1734           for (i = 0; i < hashlen[hashalgo]; i++, bp += 2)
1735             sprintf((char *)bp, "%02x", p[i]);
1736           *bp++ = '@';
1737           for (i = 0; i < 5; i++, bp += 2)
1738             sprintf((char *)bp, "%02x", hash[i]);
1739         }
1740       buf[3] = bp - (buf + 4 + ulen);
1741       i = bp - buf;
1742       if (write(sock, buf, i) != i)
1743         {
1744           perror("write");
1745           if (mode == MODE_CLEARSIGN && !isfilter)
1746             unlink(outfilename);
1747           exit(1);
1748         }
1749       l = 0;
1750       for (;;)
1751         {
1752           int ll;
1753           if (l == sizeof(buf))
1754             {
1755               fprintf(stderr, "packet too big\n");
1756               exit(1);
1757             }
1758           ll = read(sock, buf + l, sizeof(buf) - l);
1759           if (ll == -1)
1760             {
1761               perror("read");
1762               if (mode == MODE_CLEARSIGN && !isfilter)
1763                 unlink(outfilename);
1764               exit(1);
1765             }
1766           if (ll == 0)
1767             break;
1768           l += ll;
1769         }
1770       close(sock);
1771       if (l < 6)
1772         {
1773           fprintf(stderr, "packet too small\n");
1774           exit(1);
1775         }
1776       outl = buf[2] << 8 | buf[3];
1777       errl = buf[4] << 8 | buf[5];
1778       if (l != outl + errl + 6)
1779         {
1780           fprintf(stderr, "packet size mismatch %d %d %d\n", l, outl, errl);
1781           if (mode == MODE_CLEARSIGN && !isfilter)
1782             unlink(outfilename);
1783           exit(1);
1784         }
1785       if (errl)
1786         fwrite(buf + 6 + outl, 1, errl, stderr);
1787
1788       if (buf[0] << 8 | buf[1])
1789         {
1790           if (mode == MODE_CLEARSIGN && !isfilter)
1791             unlink(outfilename);
1792           exit(buf[0] << 8 | buf[1]);
1793         }
1794     }
1795   else
1796     {
1797       char *args[5], *bp;
1798       char hashhex[1024];
1799       char hashhexh[1024];
1800       int argc;
1801
1802       if (mode == MODE_PUBKEY)
1803         {
1804           fprintf(stderr, "pubkey mode does not work with a private key\n");
1805           exit(1);
1806         }
1807       if (privkey)
1808         readprivkey();
1809       bp = hashhex;
1810       for (i = 0; i < hashlen[hashalgo]; i++, bp += 2)
1811         sprintf((char *)bp, "%02x", p[i]);
1812       *bp++ = '@';
1813       for (i = 0; i < 5; i++, bp += 2)
1814         sprintf((char *)bp, "%02x", hash[i]);
1815       *bp = 0;
1816       if (ph)
1817         {
1818           bp = hashhexh;
1819           for (i = 0; i < hashlen[hashalgo]; i++, bp += 2)
1820             sprintf((char *)bp, "%02x", ph[i]);
1821           *bp++ = '@';
1822           for (i = 0; i < 5; i++, bp += 2)
1823             sprintf((char *)bp, "%02x", hash[i]);
1824           *bp = 0;
1825         }
1826       args[0] = privkey ? "privsign" : "sign";
1827       args[1] = algouser;
1828       argc = 2;
1829       if (privkey)
1830         args[argc++] = privkey;
1831       args[argc++] = hashhex;
1832       if (ph)
1833         args[argc++] = hashhexh;
1834       l = doreq(sock, argc, args, buf, sizeof(buf), ph ? 2 : 1);
1835       close(sock);
1836       if (l < 0)
1837         {
1838           if (mode == MODE_CLEARSIGN && !isfilter)
1839             unlink(outfilename);
1840           exit(-l);
1841         }
1842       if (buf[0] != 0 || buf[1] != (ph ? 2 : 1))
1843         {
1844           if (mode == MODE_CLEARSIGN && !isfilter)
1845             unlink(outfilename);
1846           fprintf(stderr, "bad return count\n");
1847           exit(1);
1848         }
1849       outl = buf[2] << 8 | buf[3];
1850       outlh = ph ? (buf[4] << 8 | buf[5]) : 0;
1851       if (outl == 0 || (ph && outlh == 0))
1852         {
1853           if (mode == MODE_CLEARSIGN && !isfilter)
1854             unlink(outfilename);
1855           fprintf(stderr, "server returned empty signature\n");
1856           exit(1);
1857         }
1858       if (l != outl + outlh + (ph ? 6 : 4))
1859         {
1860           if (mode == MODE_CLEARSIGN && !isfilter)
1861             unlink(outfilename);
1862           fprintf(stderr, "bad return length\n");
1863           exit(1);
1864         }
1865       if (!ph)
1866         memmove(buf + 6, buf + 4, outl);
1867     }
1868   if (mode == MODE_KEYID)
1869     {
1870       int o;
1871       if (outl < 2)
1872         {
1873           fprintf(stderr, "answer package too short\n");
1874           exit(1);
1875         }
1876       if (buf[6] == 0x88)
1877         o = 8;
1878       else if (buf[6] == 0x89)
1879         o = 9;
1880       else if (buf[6] == 0x90)
1881         o = 11;
1882       else
1883         {
1884           fprintf(stderr, "bad answer package: %02x\n", buf[6]);
1885           exit(1);
1886         }
1887       if (buf[o] == 3)
1888         {
1889           printf("%02X%02X%02X%02X\n", buf[o + 11], buf[o + 12], buf[o + 13], buf[o + 14]);
1890           exit(0);
1891         }
1892       else if (buf[o] == 4)
1893         {
1894           /* assumes sign id is first in unhashed data */
1895           o += (buf[o + 4] << 8) + buf[o + 5];  /* skip over hashed data */
1896           if (buf[o + 9] != 16)
1897             {
1898               fprintf(stderr, "issuer not first in unhashed data\n");
1899               exit(1);
1900             }
1901           printf("%02X%02X%02X%02X\n", buf[o + 14], buf[o + 15], buf[o + 16], buf[o + 17]);
1902           exit(0);
1903         }
1904       else
1905         {
1906           fprintf(stderr, "unknown signature version: %d\n", buf[o]);
1907           exit(1);
1908         }
1909     }
1910   if (isfilter)
1911     {
1912       fout = stdout;
1913       foutfd = 1;
1914     }
1915   else if (mode != MODE_CLEARSIGN)
1916     {
1917       if ((fout = fopen(outfilename, "w")) == 0)
1918         {
1919           perror(outfilename);
1920           exit(1);
1921         }
1922       foutfd = fileno(fout);
1923     }
1924
1925   if (mode == MODE_CLEARSIGN || mode == MODE_DETACHEDSIGN)
1926     {
1927       fprintf(fout, "-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.0.7 (GNU/Linux)\n\n");
1928       printr64(fout, (byte *)buf + 6, outl);
1929       crc = crc24((byte *)(buf) + 6, outl);
1930       hash[0] = crc >> 16;
1931       hash[1] = crc >> 8;
1932       hash[2] = crc;
1933       putc('=', fout);
1934       printr64(fout, hash, 3);
1935       fprintf(fout, "-----END PGP SIGNATURE-----\n");
1936     }
1937   else if (mode == MODE_RPMSIGN)
1938     {
1939       if (rpminsertsig(rpmsig, &rpmsigsize, &rpmsigcnt, &rpmsigdlen, hashtag[hashalgo], buf + 6, outl))
1940         {
1941           if (!isfilter)
1942             unlink(outfilename);
1943           exit(1);
1944         }
1945       if (outlh)
1946         {
1947           if (rpminsertsig(rpmsig, &rpmsigsize, &rpmsigcnt, &rpmsigdlen, hashtagh[hashalgo], buf + 6 + outl, outlh))
1948             {
1949               if (!isfilter)
1950                 unlink(outfilename);
1951               exit(1);
1952             }
1953         }
1954       rpmsighead[8]  = rpmsigcnt >> 24;
1955       rpmsighead[9]  = rpmsigcnt >> 16;
1956       rpmsighead[10] = rpmsigcnt >> 8 ;
1957       rpmsighead[11] = rpmsigcnt;
1958
1959       rpmsighead[12] = rpmsigdlen >> 24;
1960       rpmsighead[13] = rpmsigdlen >> 16;
1961       rpmsighead[14] = rpmsigdlen >> 8 ;
1962       rpmsighead[15] = rpmsigdlen;
1963
1964       if (lseek(fd, rpmdataoff, SEEK_SET) == (off_t)-1)
1965         {
1966           perror("lseek");
1967           if (!isfilter)
1968             unlink(outfilename);
1969           exit(1);
1970         }
1971
1972       xwrite(foutfd, rpmlead, 96);
1973       xwrite(foutfd, rpmsighead, 16);
1974       xwrite(foutfd, rpmsig, rpmsigsize);
1975       md5_init(&md5ctx);
1976       lensig = 0;
1977       while ((l = read(fd, (char *)buf, sizeof(buf))) > 0)
1978         {
1979           md5_write(&md5ctx, buf, l);
1980           xwrite(foutfd, buf, l);
1981           lensig += l;
1982         }
1983       md5_final(rpmmd5sum2, &md5ctx);
1984       if (memcmp(rpmmd5sum2, rpmmd5sum, 16))
1985         {
1986           fprintf(stderr, "rpm has changed, bailing out!\n");
1987           if (!isfilter)
1988             unlink(outfilename);
1989           exit(1);
1990         }
1991       free(rpmsig);
1992     }
1993   else
1994     fwrite(buf + 6, 1, outl, fout);
1995   if (!isfilter)
1996     {
1997       close(fd);
1998       if (fclose(fout))
1999         {
2000           perror("fclose");
2001           unlink(outfilename);
2002           exit(1);
2003         }
2004       if (mode != MODE_DETACHEDSIGN && rename(outfilename, filename))
2005         {
2006           perror("rename");
2007           unlink(outfilename);
2008           exit(1);
2009         }
2010     }
2011   if (outfilename)
2012     free(outfilename);
2013   return 0;
2014 }
2015
2016 void
2017 keygen(char *type, char *expire, char *name, char *email)
2018 {
2019   char *args[6];
2020   byte buf[8192];
2021   int l, publ, privl;
2022   int sock = opensocket();
2023
2024   args[0] = "keygen";
2025   args[1] = algouser;
2026   args[2] = type;
2027   args[3] = expire;
2028   args[4] = name;
2029   args[5] = email;
2030   l = doreq(sock, 6, args, buf, sizeof(buf), 2);
2031   close(sock);
2032   if (l < 0)
2033     exit(-l);
2034   publ = buf[2] << 8 | buf[3];
2035   privl = buf[4] << 8 | buf[5];
2036   if (privkey && strcmp(privkey, "-"))
2037     {
2038       int fout;
2039       char *outfilename = malloc(strlen(privkey) + 16);
2040
2041       sprintf(outfilename, "%s.sIgN%d", privkey, getpid());
2042       if ((fout = open(outfilename, O_WRONLY|O_CREAT|O_TRUNC, 0600)) == -1)
2043         {
2044           perror(outfilename);
2045           exit(1);
2046         }
2047       if (write(fout, buf + 6 + publ, privl) != privl)
2048         {
2049           perror("privkey write error");
2050           exit(1);
2051         }
2052       if (write(fout, "\n", 1) != 1)
2053         {
2054           perror("privkey write error");
2055           exit(1);
2056         }
2057       if (close(fout))
2058         {
2059           perror("privkey write error");
2060           exit(1);
2061         }
2062       if (rename(outfilename, privkey))
2063         {
2064           perror(privkey);
2065           exit(1);
2066         }
2067     }
2068   else
2069     {
2070       if (fwrite(buf + 6 + publ, privl, 1, stdout) != 1)
2071         {
2072           fprintf(stderr, "privkey write error\n");
2073           exit(1);
2074         }
2075       printf("\n");
2076     }
2077   if (fwrite(buf + 6, publ, 1, stdout) != 1)
2078     {
2079       fprintf(stderr, "pubkey write error\n");
2080       exit(1);
2081     }
2082   if (fflush(stdout))
2083     {
2084       fprintf(stderr, "pubkey write error\n");
2085       exit(1);
2086     }
2087   exit(0);
2088 }
2089
2090 int
2091 main(int argc, char **argv)
2092 {
2093   FILE *cfp;
2094   char buf[256], *bp;
2095   int c, l;
2096   int allowuser = 0;
2097   struct passwd *pwd = 0;
2098   int mode = MODE_UNSET;
2099
2100   uid = getuid();
2101   if (uid)
2102     pwd = getpwuid(uid);
2103   user = strdup("");
2104   host = strdup("127.0.0.1");
2105   if ((cfp = fopen("/etc/sign.conf", "r")) == 0)
2106     {
2107       perror("/etc/sign.conf");
2108       exit(1);
2109     }
2110   while (fgets(buf, sizeof(buf), cfp))
2111     {
2112       l = strlen(buf);
2113       if (!l)
2114         continue;
2115       if (buf[l - 1] != '\n')
2116         {
2117           while ((c = getc(cfp)) != EOF)
2118             if (c == '\n')
2119               break;
2120           continue;
2121         }
2122       if (*buf == '#')
2123         continue;
2124       buf[--l] = ' ';
2125       while (l && (buf[l] == ' ' || buf[l] == '\t'))
2126         buf[l--] = 0;
2127       for (bp = buf; *bp && *bp != ':'; bp++)
2128         ;
2129       if (!*bp)
2130         continue;
2131       *bp++ = 0;
2132       while (*bp == ' ' || *bp == '\t')
2133         bp++;
2134       if (!strcmp(buf, "user"))
2135         {
2136           user = strdup(bp);
2137           continue;
2138         }
2139       if (!strcmp(buf, "server"))
2140         {
2141           host = strdup(bp);
2142           continue;
2143         }
2144       if (!strcmp(buf, "port"))
2145         {
2146           port = atoi(bp);
2147           continue;
2148         }
2149       if (!strcmp(buf, "hash"))
2150         {
2151           if (!strcasecmp(bp, "sha1"))
2152             hashalgo = HASH_SHA1;
2153           else if (!strcasecmp(bp, "sha256"))
2154             hashalgo = HASH_SHA256;
2155           else
2156             {
2157               fprintf(stderr, "sign: hash: unknown argument\n");
2158               exit(1);
2159             }
2160         }
2161       if (uid && !allowuser && !strcmp(buf, "allowuser"))
2162         {
2163           if (pwd && !strcmp(pwd->pw_name, bp))
2164             allowuser = 1;
2165           else
2166             {
2167               long int li;
2168               char *ep = 0;
2169               li = strtol(bp, &ep, 10);
2170               if (*ep == 0 && li == (long int)uid)
2171                 allowuser = 1;
2172             }
2173         }
2174     }
2175   fclose(cfp);
2176   if (uid)
2177     {
2178       if (!allowuser)
2179         {
2180           fprintf(stderr, "sign: permission denied\n");
2181           exit(1);
2182         }
2183       if (seteuid(uid))
2184         {
2185           perror("seteuid");
2186           exit(1);
2187         }
2188     }
2189   if (argc == 2 && !strcmp(argv[1], "-t"))
2190     {
2191       char buf[6];
2192       int r;
2193       int sock = opensocket();
2194       if (sock == -1)
2195         exit(1);
2196       if (write(sock, "\0\0\0\0", 4) != 4)
2197         {
2198           perror("write");
2199           exit(1);
2200         }
2201       r = read(sock, buf, 6);
2202       if (r == -1)
2203         {
2204           perror("read");
2205           exit(1);
2206         }
2207       close(sock);
2208       if (r != 6)
2209         exit(1);
2210       exit(buf[0] << 8 | buf[1]);
2211     }
2212   while (argc > 1)
2213     {
2214       if (argc > 2 && !strcmp(argv[1], "-u"))
2215         {
2216           user = argv[2];
2217           argc -= 2;
2218           argv += 2;
2219         }
2220       else if (argc > 2 && !strcmp(argv[1], "-h"))
2221         {
2222           if (!strcasecmp(argv[2], "sha1"))
2223             hashalgo = HASH_SHA1;
2224           else if (!strcasecmp(argv[2], "sha256"))
2225             hashalgo = HASH_SHA256;
2226           else
2227             {
2228               fprintf(stderr, "sign: unknown hash algorithm '%s'\n", argv[2]);
2229               exit(1);
2230             }
2231           argc -= 2;
2232           argv += 2;
2233         }
2234       else if (argc > 1 && !strcmp(argv[1], "-c"))
2235         {
2236           mode = MODE_CLEARSIGN;
2237           argc--;
2238           argv++;
2239         }
2240       else if (argc > 1 && !strcmp(argv[1], "-d"))
2241         {
2242           mode = MODE_DETACHEDSIGN;
2243           argc--;
2244           argv++;
2245         }
2246       else if (argc > 1 && !strcmp(argv[1], "-r"))
2247         {
2248           mode = MODE_RPMSIGN;
2249           argc--;
2250           argv++;
2251         }
2252       else if (argc > 1 && !strcmp(argv[1], "-v"))
2253         {
2254           verbose++;
2255           argc--;
2256           argv++;
2257         }
2258       else if (argc > 1 && !strcmp(argv[1], "--noheaderonly"))
2259         {
2260           noheaderonly = 1;
2261           argc--;
2262           argv++;
2263         }
2264       else if (argc > 1 && !strcmp(argv[1], "-k"))
2265         {
2266           mode = MODE_KEYID;
2267           argc--;
2268           argv++;
2269         }
2270       else if (argc > 1 && !strcmp(argv[1], "-p"))
2271         {
2272           mode = MODE_PUBKEY;
2273           argc--;
2274           argv++;
2275         }
2276       else if (argc > 1 && !strcmp(argv[1], "-g"))
2277         {
2278           mode = MODE_KEYGEN;
2279           argc--;
2280           argv++;
2281         }
2282       else if (argc > 2 && !strcmp(argv[1], "-T"))
2283         {
2284           timearg = argv[2];
2285           argc -= 2;
2286           argv += 2;
2287           if (!*timearg || ((*timearg < '0' || *timearg > '9') && strcmp(timearg, "mtime") && strcmp(timearg, "buildtime")))
2288             {
2289               fprintf(stderr, "illegal time argument: %s\n", timearg);
2290               exit(1);
2291             }
2292         }
2293       else if (argc > 2 && !strcmp(argv[1], "-P"))
2294         {
2295           privkey = argv[2];
2296           argc -= 2;
2297           argv += 2;
2298         }
2299       else if (argc > 1 && !strcmp(argv[1], "--"))
2300         {
2301           argc--;
2302           argv++;
2303           break;
2304         }
2305       else if (argc > 1 && argv[1][0] == '-')
2306         {
2307           fprintf(stderr, "usage: sign [-c|-d|-r] [-u user] <file>\n");
2308           exit(1);
2309         }
2310       else
2311         break;
2312     }
2313   if (hashalgo == HASH_SHA1)
2314     algouser = user;
2315   else
2316     {
2317       algouser = malloc(strlen(user) + strlen(hashname[hashalgo]) + 2);
2318       sprintf(algouser, "%s:%s", hashname[hashalgo], user);
2319     }
2320   if ((mode == MODE_KEYID || mode == MODE_PUBKEY) && argc > 1)
2321     {
2322       fprintf(stderr, "usage: sign [-c|-d|-r] [-u user] <file>\n");
2323       exit(1);
2324     }
2325   if (mode == MODE_KEYGEN)
2326     {
2327       if (argc != 5)
2328         {
2329           fprintf(stderr, "usage: sign -g <type> <expire> <name> <email>\n");
2330           exit(1);
2331         }
2332       keygen(argv[1], argv[2], argv[3], argv[4]);
2333       exit(0);
2334     }
2335   if (privkey && access(privkey, R_OK))
2336     {
2337       perror(privkey);
2338       exit(1);
2339     }
2340   if (argc == 1)
2341     sign("<stdin>", 1, mode);
2342   else while (argc > 1)
2343     {
2344       sign(argv[1], 0, mode);
2345       argv++;
2346       argc--;
2347     }
2348   exit(0);
2349 }
2350