rpm 5.2.1

rpmio/rpmbc.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #define _RPMBC_INTERNAL
00007 #define _RPMPGP_INTERNAL
00008 #include <rpmbc.h>
00009 #include "debug.h"
00010 
00011 /*@access pgpDig @*/
00012 /*@access pgpDigParams @*/
00013 
00014 /*@-redecl@*/
00015 /*@unchecked@*/
00016 extern int _pgp_debug;
00017 
00018 /*@unchecked@*/
00019 extern int _pgp_print;
00020 /*@=redecl@*/
00021 
00027 static
00028 unsigned char nibble(char c)
00029         /*@*/
00030 {
00031     if (c >= '0' && c <= '9')
00032         return (unsigned char) (c - '0');
00033     if (c >= 'A' && c <= 'F')
00034         return (unsigned char)((int)(c - 'A') + 10);
00035     if (c >= 'a' && c <= 'f')
00036         return (unsigned char)((int)(c - 'a') + 10);
00037     return (unsigned char) '\0';
00038 }
00039 
00040 static
00041 int rpmbcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00042         /*@modifies dig @*/
00043 {
00044     rpmbc bc = dig->impl;
00045     unsigned int nbits = (unsigned) MP_WORDS_TO_BITS(bc->c.size);
00046     unsigned int nb = (nbits + 7) >> 3;
00047     const char * prefix = rpmDigestASN1(ctx);
00048     const char * hexstr;
00049     char * tt;
00050     int rc;
00051     int xx;
00052 
00053 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00054     if (prefix == NULL)
00055         return 1;
00056 
00057     xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1);
00058     hexstr = tt = xmalloc(2 * nb + 1);
00059     memset(tt, (int) 'f', (2 * nb));
00060     tt[0] = '0'; tt[1] = '0';
00061     tt[2] = '0'; tt[3] = '1';
00062     tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2;
00063     *tt++ = '0'; *tt++ = '0';
00064     tt = stpcpy(tt, prefix);
00065     tt = stpcpy(tt, dig->md5);
00066 
00067 /*@-moduncon -noeffectuncon @*/
00068     mpnzero(&bc->rsahm);   (void) mpnsethex(&bc->rsahm, hexstr);
00069 /*@=moduncon =noeffectuncon @*/
00070 
00071     hexstr = _free(hexstr);
00072 
00073     /* Compare leading 16 bits of digest for quick check. */
00074     {   const char *str = dig->md5;
00075         rpmuint8_t s[2];
00076         const rpmuint8_t *t = sigp->signhash16;
00077         s[0] = (rpmuint8_t) (nibble(str[0]) << 4) | nibble(str[1]);
00078         s[1] = (rpmuint8_t) (nibble(str[2]) << 4) | nibble(str[3]);
00079         rc = memcmp(s, t, sizeof(sigp->signhash16));
00080 #ifdef  DYING
00081         if (rc != 0)
00082             fprintf(stderr, "*** hash fails: digest(%02x%02x) != signhash(%02x%02x)\n",
00083                 s[0], s[1], t[0], t[1]);
00084 #endif
00085     }
00086     return rc;
00087 }
00088 
00089 static
00090 int rpmbcVerifyRSA(pgpDig dig)
00091         /*@*/
00092 {
00093     rpmbc bc = dig->impl;
00094     int rc;
00095 
00096 /*@-moduncon@*/
00097 #if defined(HAVE_BEECRYPT_API_H)
00098         rc = rsavrfy(&bc->rsa_pk.n, &bc->rsa_pk.e, &bc->c, &bc->rsahm);
00099 #else
00100         rc = rsavrfy(&bc->rsa_pk, &bc->rsahm, &bc->c);
00101 #endif
00102 /*@=moduncon@*/
00103 
00104     return rc;
00105 }
00106 
00107 static
00108 int rpmbcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00109         /*@modifies dig @*/
00110 {
00111     rpmbc bc = dig->impl;
00112     rpmuint8_t signhash16[2];
00113     int xx;
00114 
00115 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00116     xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1);
00117 
00118 /*@-moduncon -noeffectuncon @*/
00119     mpnzero(&bc->hm);   (void) mpnsethex(&bc->hm, dig->sha1);
00120 /*@=moduncon =noeffectuncon @*/
00121 
00122     /* Compare leading 16 bits of digest for quick check. */
00123     signhash16[0] = (rpmuint8_t)((*bc->hm.data >> 24) & 0xff);
00124     signhash16[1] = (rpmuint8_t)((*bc->hm.data >> 16) & 0xff);
00125     return memcmp(signhash16, sigp->signhash16, sizeof(signhash16));
00126 }
00127 
00128 static
00129 int rpmbcVerifyDSA(pgpDig dig)
00130         /*@*/
00131 {
00132     rpmbc bc = dig->impl;
00133     int rc;
00134 
00135 /*@-moduncon@*/
00136     rc = dsavrfy(&bc->p, &bc->q, &bc->g, &bc->hm, &bc->y, &bc->r, &bc->s);
00137 /*@=moduncon@*/
00138 
00139     return rc;
00140 }
00141 
00142 static
00143 int rpmbcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
00144         /*@*/
00145 {
00146     int rc = 1;         /* XXX always fail. */
00147     int xx;
00148 
00149 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00150     xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
00151 
00152     /* Compare leading 16 bits of digest for quick check. */
00153 
00154     return rc;
00155 }
00156 
00157 static
00158 int rpmbcVerifyECDSA(/*@unused@*/pgpDig dig)
00159         /*@*/
00160 {
00161     int rc = 0;         /* XXX always fail. */
00162 
00163     return rc;
00164 }
00165 
00168 static /*@observer@*/
00169 const char * pgpMpiHex(const rpmuint8_t *p)
00170         /*@*/
00171 {
00172     static char prbuf[2048];
00173     char *t = prbuf;
00174     t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2);
00175     return prbuf;
00176 }
00177 
00181 static
00182 int pgpMpiSet(const char * pre, unsigned int lbits,
00183                 /*@out@*/ void * dest, const rpmuint8_t * p,
00184                 /*@null@*/ const rpmuint8_t * pend)
00185         /*@globals fileSystem @*/
00186         /*@modifies fileSystem @*/
00187 {
00188     mpnumber * mpn = dest;
00189     unsigned int mbits = pgpMpiBits(p);
00190     unsigned int nbits;
00191     unsigned int nbytes;
00192     char * t;
00193     unsigned int ix;
00194 
00195     if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
00196         return 1;
00197 
00198     if (mbits > lbits)
00199         return 1;
00200 
00201     nbits = (lbits > mbits ? lbits : mbits);
00202     nbytes = ((nbits + 7) >> 3);
00203     t = xmalloc(2*nbytes+1);
00204     ix = 2 * ((nbits - mbits) >> 3);
00205 
00206 if (_pgp_debug)
00207 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
00208     if (ix > 0) memset(t, (int)'0', ix);
00209     strcpy(t+ix, (const char *) pgpMpiHex(p));
00210 if (_pgp_debug)
00211 fprintf(stderr, "*** %s %s\n", pre, t);
00212     (void) mpnsethex(mpn, t);
00213     t = _free(t);
00214 if (_pgp_debug && _pgp_print)
00215 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, mpn->size, mpn->data);
00216     return 0;
00217 }
00218 
00219 static
00220 int rpmbcMpiItem(const char * pre, pgpDig dig, int itemno,
00221                 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
00222         /*@globals fileSystem @*/
00223         /*@modifies fileSystem @*/
00224 {
00225     rpmbc bc = dig->impl;
00226     int rc = 0;
00227 
00228     switch (itemno) {
00229     default:
00230 assert(0);
00231         break;
00232     case 10:            /* RSA m**d */
00233         (void) mpnsethex(&bc->c, pgpMpiHex(p));
00234 if (_pgp_debug && _pgp_print)
00235 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->c.size, bc->c.data);
00236         break;
00237     case 20:            /* DSA r */
00238         rc = pgpMpiSet(pre, 160, &bc->r, p, pend);
00239         break;
00240     case 21:            /* DSA s */
00241         rc = pgpMpiSet(pre, 160, &bc->s, p, pend);
00242         break;
00243     case 30:            /* RSA n */
00244         (void) mpbsethex(&bc->rsa_pk.n, pgpMpiHex(p));
00245 if (_pgp_debug && _pgp_print)
00246 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->rsa_pk.n.size, bc->rsa_pk.n.modl);
00247         break;
00248     case 31:            /* RSA e */
00249         (void) mpnsethex(&bc->rsa_pk.e, pgpMpiHex(p));
00250 if (_pgp_debug && _pgp_print)
00251 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->rsa_pk.e.size, bc->rsa_pk.e.data);
00252         break;
00253     case 40:            /* DSA p */
00254         (void) mpbsethex(&bc->p, pgpMpiHex(p));
00255 if (_pgp_debug && _pgp_print)
00256 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->p.size, bc->p.modl);
00257         break;
00258     case 41:            /* DSA q */
00259         (void) mpbsethex(&bc->q, pgpMpiHex(p));
00260 if (_pgp_debug && _pgp_print)
00261 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->q.size, bc->q.modl);
00262         break;
00263     case 42:            /* DSA g */
00264         (void) mpnsethex(&bc->g, pgpMpiHex(p));
00265 if (_pgp_debug && _pgp_print)
00266 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->g.size, bc->g.data);
00267         break;
00268     case 43:            /* DSA y */
00269         (void) mpnsethex(&bc->y, pgpMpiHex(p));
00270 if (_pgp_debug && _pgp_print)
00271 fprintf(stderr, "\t %s ", pre),  mpfprintln(stderr, bc->y.size, bc->y.data);
00272         break;
00273     }
00274     return rc;
00275 }
00276 
00277 /*@-mustmod@*/
00278 static
00279 void rpmbcClean(void * impl)
00280         /*@modifies impl @*/
00281 {
00282     rpmbc bc = impl;
00283     if (bc != NULL) {
00284         mpnfree(&bc->hm);
00285         mpnfree(&bc->r);
00286         mpnfree(&bc->s);
00287         (void) rsapkFree(&bc->rsa_pk);
00288         mpnfree(&bc->m);
00289         mpnfree(&bc->c);
00290         mpnfree(&bc->rsahm);
00291     }
00292 }
00293 /*@=mustmod@*/
00294 
00295 static /*@null@*/
00296 void * rpmbcFree(/*@only@*/ void * impl)
00297         /*@modifies impl @*/
00298 {
00299     rpmbc bc = impl;
00300     if (bc != NULL) {
00301         mpbfree(&bc->p);
00302         mpbfree(&bc->q);
00303         mpnfree(&bc->g);
00304         mpnfree(&bc->y);
00305         mpnfree(&bc->hm);
00306         mpnfree(&bc->r);
00307         mpnfree(&bc->s);
00308 
00309         mpbfree(&bc->rsa_pk.n);
00310         mpnfree(&bc->rsa_pk.e);
00311         mpnfree(&bc->m);
00312         mpnfree(&bc->c);
00313         mpnfree(&bc->hm);
00314         bc = _free(bc);
00315     }
00316     return NULL;
00317 }
00318 
00319 static
00320 void * rpmbcInit(void)
00321         /*@*/
00322 {
00323     rpmbc bc = xcalloc(1, sizeof(*bc));
00324     return (void *) bc;
00325 }
00326 
00327 struct pgpImplVecs_s rpmbcImplVecs = {
00328         rpmbcSetRSA, rpmbcVerifyRSA,
00329         rpmbcSetDSA, rpmbcVerifyDSA,
00330         rpmbcSetECDSA, rpmbcVerifyECDSA,
00331         rpmbcMpiItem, rpmbcClean,
00332         rpmbcFree, rpmbcInit
00333 };