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