rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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;
76 case PGPHASHALGO_RIPEMD160:
77 hash_algo_name = "ripemd160";
78 break;
79 case PGPHASHALGO_MD2:
80 hash_algo_name = "md2";
81 break;
82 case PGPHASHALGO_TIGER192:
83 hash_algo_name = "tiger";
84 break;
85 case PGPHASHALGO_HAVAL_5_160:
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