rpm  5.2.1
rpmgc.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmiotypes.h>
8 #define _RPMGC_INTERNAL
9 #if defined(WITH_GCRYPT)
10 #define _RPMPGP_INTERNAL
11 #include <rpmgc.h>
12 #endif
13 
14 #include "debug.h"
15 
16 #if defined(WITH_GCRYPT)
17 
18 /*@access pgpDig @*/
19 /*@access pgpDigParams @*/
20 
21 /*@-redecl@*/
22 /*@unchecked@*/
23 extern int _pgp_debug;
24 
25 /*@unchecked@*/
26 extern int _pgp_print;
27 /*@=redecl@*/
28 
29 static
30 void rpmgcDump(const char * msg, gcry_sexp_t sexp)
31  /*@*/
32 {
33  size_t nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
34  char * buf = alloca(nb+1);
35 
36 /*@-modunconnomods @*/
37  nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, nb);
38 /*@=modunconnomods @*/
39  buf[nb] = '\0';
40 /*@-modfilesys@*/
41 if (_pgp_debug)
42 fprintf(stderr, "========== %s:\n%s", msg, buf);
43 /*@=modfilesys@*/
44  return;
45 }
46 
47 static
48 gcry_error_t rpmgcErr(/*@unused@*/rpmgc gc, const char * msg, gcry_error_t err)
49  /*@*/
50 {
51 /*@-evalorderuncon -modfilesys -moduncon @*/
52  if (err) {
53  fprintf (stderr, "rpmgc: %s: %s/%s\n",
54  msg, gcry_strsource (err), gcry_strerror (err));
55  }
56 /*@=evalorderuncon =modfilesys =moduncon @*/
57  return err;
58 }
59 
60 static
61 int rpmgcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
62  /*@modifies dig @*/
63 {
64  rpmgc gc = dig->impl;
65  const char * hash_algo_name = NULL;
66  int rc;
67  int xx;
68 
69  switch (sigp->hash_algo) {
70  case PGPHASHALGO_MD5:
71  hash_algo_name = "md5";
72  break;
73  case PGPHASHALGO_SHA1:
74  hash_algo_name = "sha1";
75  break;
77  hash_algo_name = "ripemd160";
78  break;
79  case PGPHASHALGO_MD2:
80  hash_algo_name = "md2";
81  break;
83  hash_algo_name = "tiger";
84  break;
86 #ifdef NOTYET
87  hash_algo_name = "haval";
88 #endif
89  break;
90  case PGPHASHALGO_SHA256:
91  hash_algo_name = "sha256";
92  break;
93  case PGPHASHALGO_SHA384:
94  hash_algo_name = "sha384";
95  break;
96  case PGPHASHALGO_SHA512:
97  hash_algo_name = "sha512";
98  break;
99  case PGPHASHALGO_SHA224:
100 #ifdef NOTYET
101  hash_algo_name = "sha224";
102 #endif
103  break;
104  default:
105  break;
106  }
107  if (hash_algo_name == NULL)
108  return 1;
109 
110  xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 0);
111 
112  /* Set RSA hash. */
113 /*@-moduncon -noeffectuncon @*/
114  { gcry_mpi_t c = NULL;
115  gcry_error_t yy;
116  xx = gcry_mpi_scan(&c, GCRYMPI_FMT_USG, dig->md5, dig->md5len, NULL);
117  yy = rpmgcErr(gc, "RSA c",
118  gcry_sexp_build(&gc->hash, NULL,
119  "(data (flags pkcs1) (hash %s %m))", hash_algo_name, c) );
120  gcry_mpi_release(c);
121 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
122  }
123 /*@=moduncon =noeffectuncon @*/
124 
125  /* Compare leading 16 bits of digest for quick check. */
126  { const rpmuint8_t *s = dig->md5;
127  const rpmuint8_t *t = sigp->signhash16;
128  rc = memcmp(s, t, sizeof(sigp->signhash16));
129 #ifdef DYING
130  if (rc != 0)
131  fprintf(stderr, "*** hash fails: digest(%02x%02x) != signhash(%02x%02x)\n",
132  s[0], s[1], t[0], t[1]);
133 #endif
134  }
135 
136  return rc;
137 }
138 
139 static
140 int rpmgcVerifyRSA(pgpDig dig)
141  /*@*/
142 {
143  rpmgc gc = dig->impl;
144  gcry_error_t err;
145 
146 /*@-moduncon@*/
147  err = rpmgcErr(gc, "RSA gc->sig",
148  gcry_sexp_build(&gc->sig, NULL,
149  "(sig-val (RSA (s %m)))", gc->c) );
150 /*@=moduncon@*/
151 if (_pgp_debug < 0)
152 rpmgcDump("gc->sig", gc->sig);
153 /*@-moduncon@*/
154  err = rpmgcErr(gc, "RSA gc->pkey",
155  gcry_sexp_build(&gc->pkey, NULL,
156  "(public-key (RSA (n %m) (e %m)))", gc->n, gc->e) );
157 /*@=moduncon@*/
158 if (_pgp_debug < 0)
159 rpmgcDump("gc->pkey", gc->pkey);
160 
161  /* Verify RSA signature. */
162 /*@-moduncon@*/
163  err = rpmgcErr(gc, "RSA verify",
164  gcry_pk_verify (gc->sig, gc->hash, gc->pkey) );
165 /*@=moduncon@*/
166 
167  gcry_sexp_release(gc->pkey); gc->pkey = NULL;
168  gcry_sexp_release(gc->hash); gc->hash = NULL;
169  gcry_sexp_release(gc->sig); gc->sig = NULL;
170 
171  return (err ? 0 : 1);
172 }
173 
174 static
175 int rpmgcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
176  /*@modifies dig @*/
177 {
178  rpmgc gc = dig->impl;
179  gcry_error_t err;
180  int xx;
181 
182 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
183  xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0);
184 
185  /* Set DSA hash. */
186  err = rpmgcErr(gc, "DSA gc->hash",
187  gcry_sexp_build(&gc->hash, NULL,
188  "(data (flags raw) (value %b))", dig->sha1len, dig->sha1) );
189 if (_pgp_debug < 0)
190 rpmgcDump("gc->hash", gc->hash);
191 
192  /* Compare leading 16 bits of digest for quick check. */
193  return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16));
194 }
195 
196 static
197 int rpmgcVerifyDSA(pgpDig dig)
198  /*@*/
199 {
200  rpmgc gc = dig->impl;
201  gcry_error_t err;
202 
203 /*@-moduncon -noeffectuncon @*/
204 
205  err = rpmgcErr(gc, "DSA gc->sig",
206  gcry_sexp_build(&gc->sig, NULL,
207  "(sig-val (DSA (r %m) (s %m)))", gc->r, gc->s) );
208 if (_pgp_debug < 0)
209 rpmgcDump("gc->sig", gc->sig);
210  err = rpmgcErr(gc, "DSA gc->pkey",
211  gcry_sexp_build(&gc->pkey, NULL,
212  "(public-key (DSA (p %m) (q %m) (g %m) (y %m)))",
213  gc->p, gc->q, gc->g, gc->y) );
214 if (_pgp_debug < 0)
215 rpmgcDump("gc->pkey", gc->pkey);
216 
217  /* Verify DSA signature. */
218  err = rpmgcErr(gc, "DSA verify",
219  gcry_pk_verify (gc->sig, gc->hash, gc->pkey) );
220 
221  gcry_sexp_release(gc->pkey); gc->pkey = NULL;
222  gcry_sexp_release(gc->hash); gc->hash = NULL;
223  gcry_sexp_release(gc->sig); gc->sig = NULL;
224 
225 /*@=moduncon -noeffectuncon @*/
226 
227  return (err ? 0 : 1);
228 }
229 
230 
231 static
232 int rpmgcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
233  /*@*/
234 {
235  int rc = 1; /* XXX always fail. */
236  int xx;
237 
238 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
239  xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
240 
241  /* Compare leading 16 bits of digest for quick check. */
242 
243  return rc;
244 }
245 
246 static
247 int rpmgcVerifyECDSA(/*@unused@*/pgpDig dig)
248  /*@*/
249 {
250  int rc = 0; /* XXX always fail. */
251 
252  return rc;
253 }
254 
255 /*@-globuse -mustmod @*/
256 static
257 int rpmgcMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
258  const rpmuint8_t * p,
259  /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
260  /*@globals fileSystem @*/
261  /*@modifies dig, fileSystem @*/
262 {
263  rpmgc gc = dig->impl;
264  size_t nb = pgpMpiLen(p);
265  const char * mpiname = "";
266  gcry_mpi_t * mpip = NULL;
267  size_t nscan = 0;
268  gcry_error_t err;
269  int rc = 0;
270 
271  switch (itemno) {
272  default:
273 assert(0);
274  break;
275  case 10: /* RSA m**d */
276  mpiname ="RSA m**d"; mpip = &gc->c;
277  break;
278  case 20: /* DSA r */
279  mpiname = "DSA r"; mpip = &gc->r;
280  break;
281  case 21: /* DSA s */
282  mpiname = "DSA s"; mpip = &gc->s;
283  break;
284  case 30: /* RSA n */
285  mpiname = "RSA n"; mpip = &gc->n;
286  break;
287  case 31: /* RSA e */
288  mpiname = "RSA e"; mpip = &gc->e;
289  break;
290  case 40: /* DSA p */
291  mpiname = "DSA p"; mpip = &gc->p;
292  break;
293  case 41: /* DSA q */
294  mpiname = "DSA q"; mpip = &gc->q;
295  break;
296  case 42: /* DSA g */
297  mpiname = "DSA g"; mpip = &gc->g;
298  break;
299  case 43: /* DSA y */
300  mpiname = "DSA y"; mpip = &gc->y;
301  break;
302  }
303 
304 /*@-moduncon -noeffectuncon @*/
305  err = rpmgcErr(gc, mpiname,
306  gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) );
307 /*@=moduncon =noeffectuncon @*/
308 
309  if (_pgp_debug < 0)
310  { size_t nbits = gcry_mpi_get_nbits(*mpip);
311  unsigned char * hex = NULL;
312  size_t nhex = 0;
313  err = rpmgcErr(gc, "MPI print",
314  gcry_mpi_aprint(GCRYMPI_FMT_HEX, &hex, &nhex, *mpip) );
315  fprintf(stderr, "*** %s\t%5d:%s\n", mpiname, (int)nbits, hex);
316  hex = _free(hex);
317  }
318 
319  return rc;
320 }
321 /*@=globuse =mustmod @*/
322 
323 /*@-mustmod@*/
324 static
325 void rpmgcClean(void * impl)
326  /*@modifies impl @*/
327 {
328  rpmgc gc = impl;
329 /*@-moduncon -noeffectuncon @*/
330  if (gc != NULL) {
331  if (gc->sig) {
332  gcry_sexp_release(gc->sig);
333  gc->sig = NULL;
334  }
335  if (gc->hash) {
336  gcry_sexp_release(gc->hash);
337  gc->hash = NULL;
338  }
339  if (gc->pkey) {
340  gcry_sexp_release(gc->pkey);
341  gc->pkey = NULL;
342  }
343  if (gc->r) {
344  gcry_mpi_release(gc->r);
345  gc->r = NULL;
346  }
347  if (gc->s) {
348  gcry_mpi_release(gc->s);
349  gc->s = NULL;
350  }
351  if (gc->n) {
352  gcry_mpi_release(gc->n);
353  gc->n = NULL;
354  }
355  if (gc->e) {
356  gcry_mpi_release(gc->e);
357  gc->e = NULL;
358  }
359  if (gc->c) {
360  gcry_mpi_release(gc->c);
361  gc->c = NULL;
362  }
363  if (gc->p) {
364  gcry_mpi_release(gc->p);
365  gc->p = NULL;
366  }
367  if (gc->q) {
368  gcry_mpi_release(gc->q);
369  gc->q = NULL;
370  }
371  if (gc->g) {
372  gcry_mpi_release(gc->g);
373  gc->g = NULL;
374  }
375  if (gc->y) {
376  gcry_mpi_release(gc->y);
377  gc->y = NULL;
378  }
379  }
380 /*@=moduncon =noeffectuncon @*/
381 }
382 /*@=mustmod@*/
383 
384 /*@unchecked@*/
385 static int rpmgc_initialized;
386 
387 static /*@null@*/
388 void * rpmgcFree(/*@only@*/ void * impl)
389  /*@globals rpmgc_initialized @*/
390  /*@modifies impl, rpmgc_initialized @*/
391 {
392  rpmgc gc = impl;
393 
394  rpmgcClean(impl);
395 
396  if (--rpmgc_initialized == 0 && _pgp_debug < 0) {
397  gcry_error_t err;
398  err = rpmgcErr(gc, "CLEAR_DEBUG_FLAGS",
399  gcry_control(GCRYCTL_CLEAR_DEBUG_FLAGS, 3));
400  err = rpmgcErr(gc, "SET_VERBOSITY",
401  gcry_control(GCRYCTL_SET_VERBOSITY, 0) );
402  }
403 
404  gc = _free(gc);
405 
406  return NULL;
407 }
408 
409 static
410 void * rpmgcInit(void)
411  /*@globals rpmgc_initialized @*/
412  /*@modifies rpmgc_initialized @*/
413 {
414  rpmgc gc = xcalloc(1, sizeof(*gc));
415 
416  if (rpmgc_initialized++ == 0 && _pgp_debug < 0) {
417  gcry_error_t err;
418  err = rpmgcErr(gc, "SET_VERBOSITY",
419  gcry_control(GCRYCTL_SET_VERBOSITY, 3) );
420  err = rpmgcErr(gc, "SET_DEBUG_FLAGS",
421  gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 3) );
422  }
423 
424  return (void *) gc;
425 }
426 
427 struct pgpImplVecs_s rpmgcImplVecs = {
428  rpmgcSetRSA, rpmgcVerifyRSA,
429  rpmgcSetDSA, rpmgcVerifyDSA,
430  rpmgcSetECDSA, rpmgcVerifyECDSA,
431  rpmgcMpiItem, rpmgcClean,
432  rpmgcFree, rpmgcInit
433 };
434 
435 #endif
436