rpm 5.2.1

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

- File List
- Globals

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 };