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
00019
00020
00021
00022
00023 extern int _pgp_debug;
00024
00025
00026 extern int _pgp_print;
00027
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
00037 nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, nb);
00038
00039 buf[nb] = '\0';
00040
00041 if (_pgp_debug)
00042 fprintf(stderr, "========== %s:\n%s", msg, buf);
00043
00044 return;
00045 }
00046
00047 static
00048 gcry_error_t rpmgcErr(rpmgc gc, const char * msg, gcry_error_t err)
00049
00050 {
00051
00052 if (err) {
00053 fprintf (stderr, "rpmgc: %s: %s/%s\n",
00054 msg, gcry_strsource (err), gcry_strerror (err));
00055 }
00056
00057 return err;
00058 }
00059
00060 static
00061 int rpmgcSetRSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00062
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
00113
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
00124
00125
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
00147 err = rpmgcErr(gc, "RSA gc->sig",
00148 gcry_sexp_build(&gc->sig, NULL,
00149 "(sig-val (RSA (s %m)))", gc->c) );
00150
00151 if (_pgp_debug < 0)
00152 rpmgcDump("gc->sig", gc->sig);
00153
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
00158 if (_pgp_debug < 0)
00159 rpmgcDump("gc->pkey", gc->pkey);
00160
00161
00162
00163 err = rpmgcErr(gc, "RSA verify",
00164 gcry_pk_verify (gc->sig, gc->hash, gc->pkey) );
00165
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( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00176
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
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
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
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
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
00226
00227 return (err ? 0 : 1);
00228 }
00229
00230
00231 static
00232 int rpmgcSetECDSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00233
00234 {
00235 int rc = 1;
00236 int xx;
00237
00238 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00239 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
00240
00241
00242
00243 return rc;
00244 }
00245
00246 static
00247 int rpmgcVerifyECDSA(pgpDig dig)
00248
00249 {
00250 int rc = 0;
00251
00252 return rc;
00253 }
00254
00255
00256 static
00257 int rpmgcMpiItem( const char * pre, pgpDig dig, int itemno,
00258 const rpmuint8_t * p,
00259 const rpmuint8_t * pend)
00260
00261
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:
00276 mpiname ="RSA m**d"; mpip = &gc->c;
00277 break;
00278 case 20:
00279 mpiname = "DSA r"; mpip = &gc->r;
00280 break;
00281 case 21:
00282 mpiname = "DSA s"; mpip = &gc->s;
00283 break;
00284 case 30:
00285 mpiname = "RSA n"; mpip = &gc->n;
00286 break;
00287 case 31:
00288 mpiname = "RSA e"; mpip = &gc->e;
00289 break;
00290 case 40:
00291 mpiname = "DSA p"; mpip = &gc->p;
00292 break;
00293 case 41:
00294 mpiname = "DSA q"; mpip = &gc->q;
00295 break;
00296 case 42:
00297 mpiname = "DSA g"; mpip = &gc->g;
00298 break;
00299 case 43:
00300 mpiname = "DSA y"; mpip = &gc->y;
00301 break;
00302 }
00303
00304
00305 err = rpmgcErr(gc, mpiname,
00306 gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) );
00307
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
00322
00323
00324 static
00325 void rpmgcClean(void * impl)
00326
00327 {
00328 rpmgc gc = impl;
00329
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
00381 }
00382
00383
00384
00385 static int rpmgc_initialized;
00386
00387 static
00388 void * rpmgcFree( void * impl)
00389
00390
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
00412
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