rpm 5.2.1

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

- File List
- Globals

rpmio/rpmgc.c
Go to the documentation of this file.

    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