rpm 5.2.1
|
00001 00005 #include "system.h" 00006 00007 #include <rpmiotypes.h> 00008 #define _RPMGC_INTERNAL 00009 #if defined(WITH_GCRYPT) 00010 #define _RPMPGP_INTERNAL 00011 #include <rpmgc.h> 00012 #endif 00013 00014 #include "debug.h" 00015 00016 #if defined(WITH_GCRYPT) 00017 00018 /*@access pgpDig @*/ 00019 /*@access pgpDigParams @*/ 00020 00021 /*@-redecl@*/ 00022 /*@unchecked@*/ 00023 extern int _pgp_debug; 00024 00025 /*@unchecked@*/ 00026 extern int _pgp_print; 00027 /*@=redecl@*/ 00028 00029 static 00030 void rpmgcDump(const char * msg, gcry_sexp_t sexp) 00031 /*@*/ 00032 { 00033 size_t nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); 00034 char * buf = alloca(nb+1); 00035 00036 /*@-modunconnomods @*/ 00037 nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, nb); 00038 /*@=modunconnomods @*/ 00039 buf[nb] = '\0'; 00040 /*@-modfilesys@*/ 00041 if (_pgp_debug) 00042 fprintf(stderr, "========== %s:\n%s", msg, buf); 00043 /*@=modfilesys@*/ 00044 return; 00045 } 00046 00047 static 00048 gcry_error_t rpmgcErr(/*@unused@*/rpmgc gc, const char * msg, gcry_error_t err) 00049 /*@*/ 00050 { 00051 /*@-evalorderuncon -modfilesys -moduncon @*/ 00052 if (err) { 00053 fprintf (stderr, "rpmgc: %s: %s/%s\n", 00054 msg, gcry_strsource (err), gcry_strerror (err)); 00055 } 00056 /*@=evalorderuncon =modfilesys =moduncon @*/ 00057 return err; 00058 } 00059 00060 static 00061 int rpmgcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00062 /*@modifies dig @*/ 00063 { 00064 rpmgc gc = dig->impl; 00065 const char * hash_algo_name = NULL; 00066 int rc; 00067 int xx; 00068 00069 switch (sigp->hash_algo) { 00070 case PGPHASHALGO_MD5: 00071 hash_algo_name = "md5"; 00072 break; 00073 case PGPHASHALGO_SHA1: 00074 hash_algo_name = "sha1"; 00075 break; 00076 case PGPHASHALGO_RIPEMD160: 00077 hash_algo_name = "ripemd160"; 00078 break; 00079 case PGPHASHALGO_MD2: 00080 hash_algo_name = "md2"; 00081 break; 00082 case PGPHASHALGO_TIGER192: 00083 hash_algo_name = "tiger"; 00084 break; 00085 case PGPHASHALGO_HAVAL_5_160: 00086 #ifdef NOTYET 00087 hash_algo_name = "haval"; 00088 #endif 00089 break; 00090 case PGPHASHALGO_SHA256: 00091 hash_algo_name = "sha256"; 00092 break; 00093 case PGPHASHALGO_SHA384: 00094 hash_algo_name = "sha384"; 00095 break; 00096 case PGPHASHALGO_SHA512: 00097 hash_algo_name = "sha512"; 00098 break; 00099 case PGPHASHALGO_SHA224: 00100 #ifdef NOTYET 00101 hash_algo_name = "sha224"; 00102 #endif 00103 break; 00104 default: 00105 break; 00106 } 00107 if (hash_algo_name == NULL) 00108 return 1; 00109 00110 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 0); 00111 00112 /* Set RSA hash. */ 00113 /*@-moduncon -noeffectuncon @*/ 00114 { gcry_mpi_t c = NULL; 00115 gcry_error_t yy; 00116 xx = gcry_mpi_scan(&c, GCRYMPI_FMT_USG, dig->md5, dig->md5len, NULL); 00117 yy = rpmgcErr(gc, "RSA c", 00118 gcry_sexp_build(&gc->hash, NULL, 00119 "(data (flags pkcs1) (hash %s %m))", hash_algo_name, c) ); 00120 gcry_mpi_release(c); 00121 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash); 00122 } 00123 /*@=moduncon =noeffectuncon @*/ 00124 00125 /* Compare leading 16 bits of digest for quick check. */ 00126 { const rpmuint8_t *s = dig->md5; 00127 const rpmuint8_t *t = sigp->signhash16; 00128 rc = memcmp(s, t, sizeof(sigp->signhash16)); 00129 #ifdef DYING 00130 if (rc != 0) 00131 fprintf(stderr, "*** hash fails: digest(%02x%02x) != signhash(%02x%02x)\n", 00132 s[0], s[1], t[0], t[1]); 00133 #endif 00134 } 00135 00136 return rc; 00137 } 00138 00139 static 00140 int rpmgcVerifyRSA(pgpDig dig) 00141 /*@*/ 00142 { 00143 rpmgc gc = dig->impl; 00144 gcry_error_t err; 00145 00146 /*@-moduncon@*/ 00147 err = rpmgcErr(gc, "RSA gc->sig", 00148 gcry_sexp_build(&gc->sig, NULL, 00149 "(sig-val (RSA (s %m)))", gc->c) ); 00150 /*@=moduncon@*/ 00151 if (_pgp_debug < 0) 00152 rpmgcDump("gc->sig", gc->sig); 00153 /*@-moduncon@*/ 00154 err = rpmgcErr(gc, "RSA gc->pkey", 00155 gcry_sexp_build(&gc->pkey, NULL, 00156 "(public-key (RSA (n %m) (e %m)))", gc->n, gc->e) ); 00157 /*@=moduncon@*/ 00158 if (_pgp_debug < 0) 00159 rpmgcDump("gc->pkey", gc->pkey); 00160 00161 /* Verify RSA signature. */ 00162 /*@-moduncon@*/ 00163 err = rpmgcErr(gc, "RSA verify", 00164 gcry_pk_verify (gc->sig, gc->hash, gc->pkey) ); 00165 /*@=moduncon@*/ 00166 00167 gcry_sexp_release(gc->pkey); gc->pkey = NULL; 00168 gcry_sexp_release(gc->hash); gc->hash = NULL; 00169 gcry_sexp_release(gc->sig); gc->sig = NULL; 00170 00171 return (err ? 0 : 1); 00172 } 00173 00174 static 00175 int rpmgcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00176 /*@modifies dig @*/ 00177 { 00178 rpmgc gc = dig->impl; 00179 gcry_error_t err; 00180 int xx; 00181 00182 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00183 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0); 00184 00185 /* Set DSA hash. */ 00186 err = rpmgcErr(gc, "DSA gc->hash", 00187 gcry_sexp_build(&gc->hash, NULL, 00188 "(data (flags raw) (value %b))", dig->sha1len, dig->sha1) ); 00189 if (_pgp_debug < 0) 00190 rpmgcDump("gc->hash", gc->hash); 00191 00192 /* Compare leading 16 bits of digest for quick check. */ 00193 return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16)); 00194 } 00195 00196 static 00197 int rpmgcVerifyDSA(pgpDig dig) 00198 /*@*/ 00199 { 00200 rpmgc gc = dig->impl; 00201 gcry_error_t err; 00202 00203 /*@-moduncon -noeffectuncon @*/ 00204 00205 err = rpmgcErr(gc, "DSA gc->sig", 00206 gcry_sexp_build(&gc->sig, NULL, 00207 "(sig-val (DSA (r %m) (s %m)))", gc->r, gc->s) ); 00208 if (_pgp_debug < 0) 00209 rpmgcDump("gc->sig", gc->sig); 00210 err = rpmgcErr(gc, "DSA gc->pkey", 00211 gcry_sexp_build(&gc->pkey, NULL, 00212 "(public-key (DSA (p %m) (q %m) (g %m) (y %m)))", 00213 gc->p, gc->q, gc->g, gc->y) ); 00214 if (_pgp_debug < 0) 00215 rpmgcDump("gc->pkey", gc->pkey); 00216 00217 /* Verify DSA signature. */ 00218 err = rpmgcErr(gc, "DSA verify", 00219 gcry_pk_verify (gc->sig, gc->hash, gc->pkey) ); 00220 00221 gcry_sexp_release(gc->pkey); gc->pkey = NULL; 00222 gcry_sexp_release(gc->hash); gc->hash = NULL; 00223 gcry_sexp_release(gc->sig); gc->sig = NULL; 00224 00225 /*@=moduncon -noeffectuncon @*/ 00226 00227 return (err ? 0 : 1); 00228 } 00229 00230 00231 static 00232 int rpmgcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00233 /*@*/ 00234 { 00235 int rc = 1; /* XXX always fail. */ 00236 int xx; 00237 00238 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00239 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); 00240 00241 /* Compare leading 16 bits of digest for quick check. */ 00242 00243 return rc; 00244 } 00245 00246 static 00247 int rpmgcVerifyECDSA(/*@unused@*/pgpDig dig) 00248 /*@*/ 00249 { 00250 int rc = 0; /* XXX always fail. */ 00251 00252 return rc; 00253 } 00254 00255 /*@-globuse -mustmod @*/ 00256 static 00257 int rpmgcMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno, 00258 const rpmuint8_t * p, 00259 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend) 00260 /*@globals fileSystem @*/ 00261 /*@modifies dig, fileSystem @*/ 00262 { 00263 rpmgc gc = dig->impl; 00264 size_t nb = pgpMpiLen(p); 00265 const char * mpiname = ""; 00266 gcry_mpi_t * mpip = NULL; 00267 size_t nscan = 0; 00268 gcry_error_t err; 00269 int rc = 0; 00270 00271 switch (itemno) { 00272 default: 00273 assert(0); 00274 break; 00275 case 10: /* RSA m**d */ 00276 mpiname ="RSA m**d"; mpip = &gc->c; 00277 break; 00278 case 20: /* DSA r */ 00279 mpiname = "DSA r"; mpip = &gc->r; 00280 break; 00281 case 21: /* DSA s */ 00282 mpiname = "DSA s"; mpip = &gc->s; 00283 break; 00284 case 30: /* RSA n */ 00285 mpiname = "RSA n"; mpip = &gc->n; 00286 break; 00287 case 31: /* RSA e */ 00288 mpiname = "RSA e"; mpip = &gc->e; 00289 break; 00290 case 40: /* DSA p */ 00291 mpiname = "DSA p"; mpip = &gc->p; 00292 break; 00293 case 41: /* DSA q */ 00294 mpiname = "DSA q"; mpip = &gc->q; 00295 break; 00296 case 42: /* DSA g */ 00297 mpiname = "DSA g"; mpip = &gc->g; 00298 break; 00299 case 43: /* DSA y */ 00300 mpiname = "DSA y"; mpip = &gc->y; 00301 break; 00302 } 00303 00304 /*@-moduncon -noeffectuncon @*/ 00305 err = rpmgcErr(gc, mpiname, 00306 gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) ); 00307 /*@=moduncon =noeffectuncon @*/ 00308 00309 if (_pgp_debug < 0) 00310 { size_t nbits = gcry_mpi_get_nbits(*mpip); 00311 unsigned char * hex = NULL; 00312 size_t nhex = 0; 00313 err = rpmgcErr(gc, "MPI print", 00314 gcry_mpi_aprint(GCRYMPI_FMT_HEX, &hex, &nhex, *mpip) ); 00315 fprintf(stderr, "*** %s\t%5d:%s\n", mpiname, (int)nbits, hex); 00316 hex = _free(hex); 00317 } 00318 00319 return rc; 00320 } 00321 /*@=globuse =mustmod @*/ 00322 00323 /*@-mustmod@*/ 00324 static 00325 void rpmgcClean(void * impl) 00326 /*@modifies impl @*/ 00327 { 00328 rpmgc gc = impl; 00329 /*@-moduncon -noeffectuncon @*/ 00330 if (gc != NULL) { 00331 if (gc->sig) { 00332 gcry_sexp_release(gc->sig); 00333 gc->sig = NULL; 00334 } 00335 if (gc->hash) { 00336 gcry_sexp_release(gc->hash); 00337 gc->hash = NULL; 00338 } 00339 if (gc->pkey) { 00340 gcry_sexp_release(gc->pkey); 00341 gc->pkey = NULL; 00342 } 00343 if (gc->r) { 00344 gcry_mpi_release(gc->r); 00345 gc->r = NULL; 00346 } 00347 if (gc->s) { 00348 gcry_mpi_release(gc->s); 00349 gc->s = NULL; 00350 } 00351 if (gc->n) { 00352 gcry_mpi_release(gc->n); 00353 gc->n = NULL; 00354 } 00355 if (gc->e) { 00356 gcry_mpi_release(gc->e); 00357 gc->e = NULL; 00358 } 00359 if (gc->c) { 00360 gcry_mpi_release(gc->c); 00361 gc->c = NULL; 00362 } 00363 if (gc->p) { 00364 gcry_mpi_release(gc->p); 00365 gc->p = NULL; 00366 } 00367 if (gc->q) { 00368 gcry_mpi_release(gc->q); 00369 gc->q = NULL; 00370 } 00371 if (gc->g) { 00372 gcry_mpi_release(gc->g); 00373 gc->g = NULL; 00374 } 00375 if (gc->y) { 00376 gcry_mpi_release(gc->y); 00377 gc->y = NULL; 00378 } 00379 } 00380 /*@=moduncon =noeffectuncon @*/ 00381 } 00382 /*@=mustmod@*/ 00383 00384 /*@unchecked@*/ 00385 static int rpmgc_initialized; 00386 00387 static /*@null@*/ 00388 void * rpmgcFree(/*@only@*/ void * impl) 00389 /*@globals rpmgc_initialized @*/ 00390 /*@modifies impl, rpmgc_initialized @*/ 00391 { 00392 rpmgc gc = impl; 00393 00394 rpmgcClean(impl); 00395 00396 if (--rpmgc_initialized == 0 && _pgp_debug < 0) { 00397 gcry_error_t err; 00398 err = rpmgcErr(gc, "CLEAR_DEBUG_FLAGS", 00399 gcry_control(GCRYCTL_CLEAR_DEBUG_FLAGS, 3)); 00400 err = rpmgcErr(gc, "SET_VERBOSITY", 00401 gcry_control(GCRYCTL_SET_VERBOSITY, 0) ); 00402 } 00403 00404 gc = _free(gc); 00405 00406 return NULL; 00407 } 00408 00409 static 00410 void * rpmgcInit(void) 00411 /*@globals rpmgc_initialized @*/ 00412 /*@modifies rpmgc_initialized @*/ 00413 { 00414 rpmgc gc = xcalloc(1, sizeof(*gc)); 00415 00416 if (rpmgc_initialized++ == 0 && _pgp_debug < 0) { 00417 gcry_error_t err; 00418 err = rpmgcErr(gc, "SET_VERBOSITY", 00419 gcry_control(GCRYCTL_SET_VERBOSITY, 3) ); 00420 err = rpmgcErr(gc, "SET_DEBUG_FLAGS", 00421 gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 3) ); 00422 } 00423 00424 return (void *) gc; 00425 } 00426 00427 struct pgpImplVecs_s rpmgcImplVecs = { 00428 rpmgcSetRSA, rpmgcVerifyRSA, 00429 rpmgcSetDSA, rpmgcVerifyDSA, 00430 rpmgcSetECDSA, rpmgcVerifyECDSA, 00431 rpmgcMpiItem, rpmgcClean, 00432 rpmgcFree, rpmgcInit 00433 }; 00434 00435 #endif 00436