rpm 5.3.12
|
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 00022 /*@unchecked@*/ 00023 static int _rpmbc_debug; 00024 00025 #define SPEW(_t, _rc, _dig) \ 00026 { if ((_t) || _rpmbc_debug || _pgp_debug < 0) \ 00027 fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \ 00028 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \ 00029 } 00030 00031 static const char * _pgpHashAlgo2Name(uint32_t algo) 00032 { 00033 return pgpValStr(pgpHashTbl, (rpmuint8_t)algo); 00034 } 00035 00036 static const char * _pgpPubkeyAlgo2Name(uint32_t algo) 00037 { 00038 return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo); 00039 } 00040 00046 static 00047 unsigned char nibble(char c) 00048 /*@*/ 00049 { 00050 if (c >= '0' && c <= '9') 00051 return (unsigned char) (c - '0'); 00052 if (c >= 'A' && c <= 'F') 00053 return (unsigned char)((int)(c - 'A') + 10); 00054 if (c >= 'a' && c <= 'f') 00055 return (unsigned char)((int)(c - 'a') + 10); 00056 return (unsigned char) '\0'; 00057 } 00058 00059 #define _spewMPB(_N, _MPB) \ 00060 { mpbarrett * mpb = &(_MPB); \ 00061 fprintf(stderr, "\t" _N ": "); mpfprintln(stderr, mpb->size, mpb->modl); \ 00062 } 00063 00064 #define _spewMPN(_N, _MPN) \ 00065 { mpnumber * mpn = &(_MPN); \ 00066 fprintf(stderr, "\t" _N ": "); mpfprintln(stderr, mpn->size, mpn->data); \ 00067 } 00068 00069 #ifdef UNUSED 00070 static void rpmbcDumpRSA(const char * msg, rpmbc bc) 00071 { 00072 if (msg) fprintf(stderr, "========== %s\n", msg); 00073 00074 { 00075 _spewMPB(" n", bc->rsa_keypair.n); 00076 _spewMPN(" e", bc->rsa_keypair.e); 00077 _spewMPN(" d", bc->rsa_keypair.d); 00078 _spewMPB(" p", bc->rsa_keypair.p); 00079 _spewMPB(" q", bc->rsa_keypair.q); 00080 _spewMPN("dp", bc->rsa_keypair.dp); 00081 _spewMPN("dq", bc->rsa_keypair.dq); 00082 _spewMPN("qi", bc->rsa_keypair.qi); 00083 } 00084 00085 _spewMPN(" c", bc->c); 00086 _spewMPN("hm", bc->hm); 00087 } 00088 00089 static void rpmbcDumpDSA(const char * msg, rpmbc bc) 00090 { 00091 if (msg) fprintf(stderr, "========== %s\n", msg); 00092 00093 { 00094 _spewMPB(" p", bc->dsa_keypair.param.p); 00095 _spewMPB(" q", bc->dsa_keypair.param.q); 00096 _spewMPN(" g", bc->dsa_keypair.param.g); 00097 _spewMPN(" y", bc->dsa_keypair.y); 00098 } 00099 00100 _spewMPN(" r", bc->r); 00101 _spewMPN(" s", bc->s); 00102 00103 _spewMPN("hm", bc->hm); 00104 00105 } 00106 #endif /* UNUSED */ 00107 00108 static 00109 int rpmbcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00110 /*@modifies dig @*/ 00111 { 00112 rpmbc bc = dig->impl; 00113 size_t nbits = 0; 00114 size_t nb = 0; 00115 const char * prefix = rpmDigestASN1(ctx); 00116 const char * hexstr; 00117 char * tt; 00118 int rc = 1; /* assume failure */ 00119 int xx; 00120 pgpDigParams pubp = pgpGetPubkey(dig); 00121 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00122 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00123 00124 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00125 if (prefix == NULL) 00126 goto exit; 00127 00128 /* 00129 * The no. of bytes for hash + PKCS1 padding is needed. 00130 * Either n or c can be used as the size, but different code paths 00131 * populate n or c indeterminately. So try c, then n, 00132 * and error if the no. of bytes isn't sane. 00133 */ 00134 if (bc->c.size) 00135 nbits = (unsigned) MP_WORDS_TO_BITS(bc->c.size); 00136 else if (bc->rsa_keypair.n.size) 00137 nbits = (unsigned) MP_WORDS_TO_BITS(bc->rsa_keypair.n.size); 00138 nb = (nbits + 7) >> 3; /* XXX overkill */ 00139 if (nb < 64/8 || nb > 65536/8) /* XXX generous "sanity" check */ 00140 goto exit; 00141 00142 /* XXX FIXME: do PKCS1 padding in binary not hex */ 00143 /* XXX FIXME: should this lazy free be done elsewhere? */ 00144 bc->digest = _free(bc->digest); 00145 bc->digestlen = 0; 00146 xx = rpmDigestFinal(ctx, (void **)&bc->digest, &bc->digestlen, 1); 00147 hexstr = tt = xmalloc(2 * nb + 1); 00148 memset(tt, (int) 'f', (2 * nb)); 00149 tt[0] = '0'; tt[1] = '0'; 00150 tt[2] = '0'; tt[3] = '1'; 00151 tt += (2 * nb) - strlen(prefix) - strlen(bc->digest) - 2; 00152 *tt++ = '0'; *tt++ = '0'; 00153 tt = stpcpy(tt, prefix); 00154 tt = stpcpy(tt, bc->digest); 00155 00156 /*@-moduncon -noeffectuncon @*/ 00157 mpnfree(&bc->hm); 00158 mpnzero(&bc->hm); (void) mpnsethex(&bc->hm, hexstr); 00159 /*@=moduncon =noeffectuncon @*/ 00160 00161 hexstr = _free(hexstr); 00162 00163 /* Compare leading 16 bits of digest for quick check. */ 00164 { const char *str = bc->digest; 00165 rpmuint8_t s[2]; 00166 const rpmuint8_t *t = sigp->signhash16; 00167 s[0] = (rpmuint8_t) (nibble(str[0]) << 4) | nibble(str[1]); 00168 s[1] = (rpmuint8_t) (nibble(str[2]) << 4) | nibble(str[3]); 00169 rc = memcmp(s, t, sizeof(sigp->signhash16)); 00170 } 00171 00172 exit: 00173 SPEW(0, !rc, dig); 00174 return rc; 00175 } 00176 00177 static 00178 int rpmbcVerifyRSA(pgpDig dig) 00179 /*@*/ 00180 { 00181 rpmbc bc = dig->impl; 00182 int rc; 00183 00184 rc = rsavrfy(&bc->rsa_keypair.n, &bc->rsa_keypair.e, &bc->c, &bc->hm); 00185 00186 SPEW(0, rc, dig); 00187 return rc; 00188 } 00189 00190 static 00191 int rpmbcSignRSA(/*@unused@*/pgpDig dig) 00192 /*@*/ 00193 { 00194 rpmbc bc = dig->impl; 00195 int rc = 0; /* Assume failure. */ 00196 int failures = 0; 00197 int xx; 00198 00199 mpnzero(&bc->c); 00200 #ifdef SLOWER 00201 xx = rsapri(&bc->rsa_keypair.n, &bc->rsa_keypair.d, &bc->hm, &bc->c); 00202 #else 00203 /* XXX RSA w CRT is ~3x-4x faster for signing. */ 00204 xx = rsapricrt(&bc->rsa_keypair.n, &bc->rsa_keypair.p, &bc->rsa_keypair.q, 00205 &bc->rsa_keypair.dp, &bc->rsa_keypair.dq, &bc->rsa_keypair.qi, 00206 &bc->hm, &bc->c); 00207 #endif 00208 if (xx) failures++; 00209 00210 rc = (failures == 0); 00211 00212 SPEW(!rc, rc, dig); 00213 return rc; 00214 } 00215 00216 static 00217 int rpmbcGenerateRSA(/*@unused@*/pgpDig dig) 00218 /*@*/ 00219 { 00220 rpmbc bc = dig->impl; 00221 int rc = 0; /* Assume failure. */ 00222 int failures = 0; 00223 int xx; 00224 00225 if (bc->nbits == 0) bc->nbits = 1024; /* XXX FIXME */ 00226 00227 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault()); 00228 00229 rsakpFree(&bc->rsa_keypair); 00230 xx = rsakpMake(&bc->rsa_keypair, &bc->rngc, bc->nbits); 00231 if (xx) failures++; 00232 00233 /* generate a random m in the range 0 < m < n */ 00234 mpnzero(&bc->m); 00235 mpbnrnd(&bc->rsa_keypair.n, &bc->rngc, &bc->m); 00236 00237 rc = (failures == 0); 00238 00239 SPEW(!rc, rc, dig); 00240 return rc; 00241 } 00242 00243 static 00244 int rpmbcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00245 /*@modifies dig @*/ 00246 { 00247 rpmbc bc = dig->impl; 00248 int rc; 00249 pgpDigParams pubp = pgpGetPubkey(dig); 00250 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00251 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00252 00253 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00254 bc->digest = _free(bc->digest); 00255 bc->digestlen = 0; 00256 rc = rpmDigestFinal(ctx, (void **)&bc->digest, &bc->digestlen, 0); 00257 00258 /* XXX Truncate to 160bits. */ 00259 rc = mpnsetbin(&bc->hm, bc->digest, 00260 (bc->digestlen > 160/8 ? 160/8 : bc->digestlen)); 00261 rc = memcmp(bc->digest, sigp->signhash16, sizeof(sigp->signhash16)); 00262 00263 SPEW(0, !rc, dig); 00264 return rc; 00265 } 00266 00267 static 00268 int rpmbcVerifyDSA(pgpDig dig) 00269 /*@*/ 00270 { 00271 rpmbc bc = dig->impl; 00272 int rc = 0; /* Assume failure. */ 00273 int failures = 0; 00274 int xx; 00275 00276 xx = dsavrfy(&bc->dsa_keypair.param.p, &bc->dsa_keypair.param.q, 00277 &bc->dsa_keypair.param.g, &bc->hm, &bc->dsa_keypair.y, 00278 &bc->r, &bc->s); 00279 if (!xx) failures++; 00280 00281 rc = (failures == 0); 00282 00283 SPEW(0, rc, dig); 00284 return rc; 00285 } 00286 00287 static 00288 int rpmbcSignDSA(pgpDig dig) 00289 /*@*/ 00290 { 00291 rpmbc bc = dig->impl; 00292 int rc = 0; /* Assume failure. */ 00293 int failures = 0; 00294 int xx; 00295 00296 mpnzero(&bc->r); 00297 mpnzero(&bc->s); 00298 xx = dsasign(&bc->dsa_keypair.param.p, &bc->dsa_keypair.param.q, 00299 &bc->dsa_keypair.param.g, &bc->rngc, &bc->hm, 00300 &bc->dsa_keypair.x, &bc->r, &bc->s); 00301 if (xx) failures++; 00302 00303 rc = (failures == 0); 00304 00305 SPEW(!rc, rc, dig); 00306 return rc; 00307 } 00308 00309 static 00310 int rpmbcGenerateDSA(pgpDig dig) 00311 /*@*/ 00312 { 00313 rpmbc bc = dig->impl; 00314 int rc = 0; /* Assume failure. */ 00315 int failures = 0; 00316 int xx; 00317 00318 if (bc->nbits == 0) bc->nbits = 1024; /* XXX FIXME */ 00319 00320 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault()); 00321 00322 xx = dlkp_pInit(&bc->dsa_keypair); 00323 if (xx) failures++; 00324 xx = dsaparamMake(&bc->dsa_keypair.param, &bc->rngc, bc->nbits); 00325 if (xx) failures++; 00326 00327 xx = dldp_pPair(&bc->dsa_keypair.param, &bc->rngc, &bc->dsa_keypair.x, 00328 &bc->dsa_keypair.y); 00329 if (xx) failures++; 00330 00331 rc = (failures == 0); 00332 00333 SPEW(!rc, rc, dig); 00334 return rc; 00335 } 00336 00337 static 00338 int rpmbcSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00339 /*@*/ 00340 { 00341 int rc = 1; /* XXX always fail. */ 00342 int xx; 00343 pgpDigParams pubp = pgpGetPubkey(dig); 00344 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00345 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00346 00347 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00348 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); 00349 00350 /* Compare leading 16 bits of digest for quick check. */ 00351 00352 SPEW(rc, !rc, dig); 00353 return rc; 00354 } 00355 00356 #ifdef NOTYET 00357 static 00358 int rpmbcVerifyELG(pgpDig dig) 00359 /*@*/ 00360 { 00361 rpmbc bc = dig->impl; 00362 int rc = 0; /* Assume failure. */ 00363 int failures = 0; 00364 int xx; 00365 00366 xx = elgv1vrfy(&bc->elg_keypair.param.p, &bc->elg_keypair.param.n, 00367 &bc->elg_keypair.param.g, &bc->hm, &bc->elg_keypair.y, 00368 &bc->r, &bc->s); 00369 if (xx) failures++; 00370 00371 rc = (failures == 0); 00372 00373 SPEW(!rc, rc, dig); 00374 return rc; 00375 } 00376 00377 static 00378 int rpmbcSignELG(/*@unused@*/pgpDig dig) 00379 /*@*/ 00380 { 00381 rpmbc bc = dig->impl; 00382 int rc = 0; /* Assume failure. */ 00383 int failures = 0; 00384 int xx; 00385 00386 mpnzero(&bc->r); 00387 mpnzero(&bc->s); 00388 xx = elgv1sign(&bc->elg_keypair.param.p, &bc->elg_keypair.param.n, 00389 &bc->elg_keypair.param.g, &bc->rngc, &bc->hm, 00390 &bc->elg_keypair.x, &bc->r, &bc->s); 00391 if (xx) failures++; 00392 00393 rc = (failures == 0); 00394 00395 SPEW(!rc, rc, dig); 00396 return rc; 00397 } 00398 00399 static 00400 int rpmbcGenerateELG(/*@unused@*/pgpDig dig) 00401 /*@*/ 00402 { 00403 static const char P_2048[] = "fd12e8b7e096a28a00fb548035953cf0eba64ceb5dff0f5672d376d59c196da729f6b5586f18e6f3f1a86c73c5b15662f59439613b309e52aa257488619e5f76a7c4c3f7a426bdeac66bf88343482941413cef06256b39c62744dcb97e7b78e36ec6b885b143f6f3ad0a1cd8a5713e338916613892a264d4a47e72b583fbdaf5bce2bbb0097f7e65cbc86d684882e5bb8196d522dcacd6ad00dfbcd8d21613bdb59c485a65a58325d792272c09ad1173e12c98d865adb4c4d676ada79830c58c37c42dff8536e28f148a23f296513816d3dfed0397a3d4d6e1fa24f07e1b01643a68b4274646a3b876e810206eddacea2b9ef7636a1da5880ef654288b857ea3"; 00404 static const char P_1024[] = "e64a3deeddb723e2e4db54c2b09567d196367a86b3b302be07e43ffd7f2e016f866de5135e375bdd2fba6ea9b4299010fafa36dc6b02ba3853cceea07ee94bfe30e0cc82a69c73163be26e0c4012dfa0b2839c97d6cd71eee59a303d6177c6a6740ca63bd04c1ba084d6c369dc2fbfaeebe951d58a4824de52b580442d8cae77"; 00405 00406 rpmbc bc = dig->impl; 00407 int rc = 0; /* Assume failure. */ 00408 int failures = 0; 00409 int xx; 00410 00411 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault()); 00412 00413 xx = 0; 00414 00415 xx = dlkp_pInit(&bc->elg_keypair); 00416 if (xx) failures++; 00417 00418 #ifdef DYING 00419 xx = dldp_pInit(&bc->elg_keypair.param); 00420 if (xx) failures++; 00421 #endif 00422 00423 switch (bc->nbits) { 00424 #ifdef NOTYET 00425 case 2048: 00426 mpbsethex(&bc->elg_keypair.param.p, P_2048); 00427 break; 00428 case 1024: 00429 case 0: 00430 mpbsethex(&bc->elg_keypair.param.p, P_1024); 00431 break; 00432 #endif 00433 default: 00434 xx = dldp_pgonMakeSafe(&bc->elg_keypair.param, &bc->rngc, bc->nbits); 00435 break; 00436 } 00437 #ifdef NOTYET 00438 if (bc->elg_keypair.param.q.size == 0) { 00439 mpnumber q; 00440 00441 mpnzero(&q); 00442 /* set q to half of P */ 00443 mpnset(&q, bc->elg_keypair.param.p.size, bc->elg_keypair.param.p.modl); 00444 mpdivtwo(q.size, q.data); 00445 mpbset(&bc->elg_keypair.param.q, q.size, q.data); 00446 /* set r to 2 */ 00447 mpnsetw(&bc->elg_keypair.param.r, 2); 00448 00449 /* make a generator, order n */ 00450 xx = dldp_pgonGenerator(&bc->elg_keypair.param, &bc->rngc); 00451 00452 } 00453 #endif 00454 if (xx) failures++; 00455 00456 xx = dldp_pPair(&bc->elg_keypair.param, &bc->rngc, 00457 &bc->elg_keypair.x, &bc->elg_keypair.y); 00458 if (xx) failures++; 00459 00460 mpnfree(&bc->r); 00461 mpnfree(&bc->s); 00462 mpnfree(&bc->hm); 00463 00464 #ifdef DYING 00465 dldp_pFree(&bc->elg_params); 00466 #endif 00467 00468 dlkp_pFree(&bc->elg_keypair); 00469 00470 rc = (failures == 0); 00471 00472 SPEW(!rc, rc, dig); 00473 return rc; 00474 } 00475 #endif /* NOTYET */ 00476 00477 static 00478 int rpmbcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00479 /*@*/ 00480 { 00481 int rc = 1; /* XXX always fail. */ 00482 int xx; 00483 pgpDigParams pubp = pgpGetPubkey(dig); 00484 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00485 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00486 00487 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00488 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); 00489 00490 /* Compare leading 16 bits of digest for quick check. */ 00491 00492 SPEW(rc, !rc, dig); 00493 return rc; 00494 } 00495 00496 #ifdef NOTYET 00497 static 00498 int rpmbcVerifyECDSA(pgpDig dig) 00499 /*@*/ 00500 { 00501 int rc = 0; /* XXX always fail. */ 00502 00503 assert(bc->hm); /* XXX FIXME: make sure bc->hm is set */ 00504 00505 SPEW(!rc, rc, dig); 00506 return rc; 00507 } 00508 00509 static 00510 int rpmbcSignECDSA(/*@unused@*/pgpDig dig) 00511 /*@*/ 00512 { 00513 int rc = 0; /* XXX always fail. */ 00514 00515 assert(bc->hm); /* XXX FIXME: make sure bc->hm is set */ 00516 00517 SPEW(!rc, rc, dig); 00518 return rc; 00519 } 00520 00521 static 00522 int rpmbcGenerateECDSA(/*@unused@*/pgpDig dig) 00523 /*@*/ 00524 { 00525 rpmbc bc = dig->impl; 00526 int rc = 0; /* Assume failure. */ 00527 int failures = 0; 00528 int xx; 00529 00530 if (bc->rngc == NULL) 00531 xx = randomGeneratorContextInit(&bc->rngc, randomGeneratorDefault()); 00532 00533 rc = (failures == 0); 00534 00535 SPEW(!rc, rc, dig); 00536 return rc; 00537 } 00538 #endif /* NOTYET */ 00539 00540 static int rpmbcErrChk(pgpDig dig, const char * msg, int rc, unsigned expected) 00541 { 00542 #ifdef REFERENCE 00543 rpmgc gc = dig->impl; 00544 /* Was the return code the expected result? */ 00545 rc = (gcry_err_code(gc->err) != expected); 00546 if (rc) 00547 fail("%s failed: %s\n", msg, gpg_strerror(gc->err)); 00548 /* XXX FIXME: rpmbcStrerror */ 00549 #else 00550 rc = (rc == 0); /* XXX impedance match 1 -> 0 on success */ 00551 #endif 00552 return rc; /* XXX 0 on success */ 00553 } 00554 00555 static int rpmbcAvailableCipher(pgpDig dig, int algo) 00556 { 00557 int rc = 0; /* assume available */ 00558 #ifdef REFERENCE 00559 rc = rpmgbcvailable(dig->impl, algo, 00560 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00561 #endif 00562 return rc; 00563 } 00564 00565 static int rpmbcAvailableDigest(pgpDig dig, int algo) 00566 { 00567 int rc = 0; /* assume available */ 00568 #ifdef REFERENCE 00569 rc = rpmgbcvailable(dig->impl, algo, 00570 (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5)); 00571 #endif 00572 return rc; 00573 } 00574 00575 static int rpmbcAvailablePubkey(pgpDig dig, int algo) 00576 { 00577 int rc = 0; /* assume available */ 00578 #ifdef REFERENCE 00579 rc = rpmbcAvailable(dig->impl, algo, gcry_pk_test_algo(algo)); 00580 #endif 00581 return rc; 00582 } 00583 00584 static int rpmbcVerify(pgpDig dig) 00585 { 00586 int rc = 0; /* assume failure */ 00587 pgpDigParams pubp = pgpGetPubkey(dig); 00588 pgpDigParams sigp = pgpGetSignature(dig); 00589 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00590 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00591 00592 switch (pubp->pubkey_algo) { 00593 default: 00594 break; 00595 case PGPPUBKEYALGO_RSA: 00596 rc = rpmbcVerifyRSA(dig); 00597 break; 00598 case PGPPUBKEYALGO_DSA: 00599 rc = rpmbcVerifyDSA(dig); 00600 break; 00601 #ifdef NOTYET 00602 case PGPPUBKEYALGO_ELGAMAL: 00603 rc = rpmbcVerifyELG(dig); 00604 break; 00605 case PGPPUBKEYALGO_ECDSA: 00606 rc = rpmbcVerifyECDSA(dig); 00607 break; 00608 #endif 00609 } 00610 SPEW(0, rc, dig); /* XXX FIXME: thkp has known BAD signatures. */ 00611 return rc; 00612 } 00613 00614 static int rpmbcSign(pgpDig dig) 00615 { 00616 int rc = 0; /* assume failure */ 00617 pgpDigParams pubp = pgpGetPubkey(dig); 00618 pgpDigParams sigp = pgpGetSignature(dig); 00619 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00620 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00621 00622 switch (pubp->pubkey_algo) { 00623 default: 00624 break; 00625 case PGPPUBKEYALGO_RSA: 00626 rc = rpmbcSignRSA(dig); 00627 break; 00628 case PGPPUBKEYALGO_DSA: 00629 rc = rpmbcSignDSA(dig); 00630 break; 00631 #ifdef NOTYET 00632 case PGPPUBKEYALGO_ELGAMAL: 00633 rc = rpmbcSignELG(dig); 00634 break; 00635 case PGPPUBKEYALGO_ECDSA: 00636 rc = rpmbcSignECDSA(dig); 00637 break; 00638 #endif 00639 } 00640 SPEW(!rc, rc, dig); 00641 return rc; 00642 } 00643 00644 static int rpmbcGenerate(pgpDig dig) 00645 { 00646 int rc = 0; /* assume failure */ 00647 pgpDigParams pubp = pgpGetPubkey(dig); 00648 pgpDigParams sigp = pgpGetSignature(dig); 00649 dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); 00650 dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); 00651 00652 switch (pubp->pubkey_algo) { 00653 default: 00654 break; 00655 case PGPPUBKEYALGO_RSA: 00656 rc = rpmbcGenerateRSA(dig); 00657 break; 00658 case PGPPUBKEYALGO_DSA: 00659 rc = rpmbcGenerateDSA(dig); 00660 break; 00661 #ifdef NOTYET 00662 case PGPPUBKEYALGO_ELGAMAL: 00663 rc = rpmbcGenerateELG(dig); 00664 break; 00665 case PGPPUBKEYALGO_ECDSA: 00666 rc = rpmbcGenerateECDSA(dig); 00667 break; 00668 #endif 00669 } 00670 SPEW(!rc, rc, dig); 00671 return rc; 00672 } 00673 00676 static /*@only@*/ 00677 char * pgpMpiHex(const rpmuint8_t *p) 00678 /*@*/ 00679 { 00680 size_t nb = pgpMpiLen(p); 00681 char * t = xmalloc(2*nb + 1); 00682 (void) pgpHexCvt(t, p+2, nb-2); 00683 return t; 00684 } 00685 00689 static 00690 int pgpMpiSet(const char * pre, unsigned int lbits, 00691 /*@out@*/ void * dest, const rpmuint8_t * p, 00692 /*@null@*/ const rpmuint8_t * pend) 00693 /*@globals fileSystem @*/ 00694 /*@modifies fileSystem @*/ 00695 { 00696 mpnumber * mpn = dest; 00697 unsigned int mbits = pgpMpiBits(p); 00698 unsigned int nbits; 00699 unsigned int nbytes; 00700 char * t; 00701 unsigned int ix; 00702 00703 if (pend != NULL && (p + ((mbits+7) >> 3)) > pend) 00704 return 1; 00705 00706 if (mbits > lbits) 00707 return 1; 00708 00709 nbits = (lbits > mbits ? lbits : mbits); 00710 nbytes = ((nbits + 7) >> 3); 00711 t = xmalloc(2*nbytes+1); 00712 ix = 2 * ((nbits - mbits) >> 3); 00713 00714 if (_pgp_debug) 00715 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix); 00716 if (ix > 0) memset(t, (int)'0', ix); 00717 { const char * s = pgpMpiHex(p); 00718 strcpy(t+ix, s); 00719 s = _free(s); 00720 } 00721 if (_pgp_debug) 00722 fprintf(stderr, "*** %s %s\n", pre, t); 00723 (void) mpnsethex(mpn, t); 00724 t = _free(t); 00725 return 0; 00726 } 00727 00728 static 00729 int rpmbcMpiItem(const char * pre, pgpDig dig, int itemno, 00730 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend) 00731 /*@globals fileSystem @*/ 00732 /*@modifies fileSystem @*/ 00733 { 00734 rpmbc bc = dig->impl; 00735 const char * s = NULL; 00736 int rc = 0; 00737 00738 switch (itemno) { 00739 default: 00740 assert(0); 00741 case 50: /* ECDSA r */ 00742 case 51: /* ECDSA s */ 00743 case 60: /* ECDSA curve OID */ 00744 case 61: /* ECDSA Q */ 00745 break; 00746 case 10: /* RSA m**d */ 00747 (void) mpnsethex(&bc->c, s = pgpMpiHex(p)); 00748 if (_pgp_debug && _pgp_print) 00749 _spewMPN(" c", bc->c); 00750 break; 00751 case 20: /* DSA r */ 00752 rc = pgpMpiSet(pre, 160, &bc->r, p, pend); 00753 if (_pgp_debug && _pgp_print) 00754 _spewMPN(" r", bc->r); 00755 break; 00756 case 21: /* DSA s */ 00757 rc = pgpMpiSet(pre, 160, &bc->s, p, pend); 00758 if (_pgp_debug && _pgp_print) 00759 _spewMPN(" s", bc->s); 00760 break; 00761 case 30: /* RSA n */ 00762 (void) mpbsethex(&bc->rsa_keypair.n, s = pgpMpiHex(p)); 00763 if (_pgp_debug && _pgp_print) 00764 _spewMPB(" n", bc->dsa_keypair.param.n); 00765 break; 00766 case 31: /* RSA e */ 00767 (void) mpnsethex(&bc->rsa_keypair.e, s = pgpMpiHex(p)); 00768 if (_pgp_debug && _pgp_print) 00769 _spewMPN(" e", bc->rsa_keypair.e); 00770 break; 00771 case 40: /* DSA p */ 00772 (void) mpbsethex(&bc->dsa_keypair.param.p, s = pgpMpiHex(p)); 00773 if (_pgp_debug && _pgp_print) 00774 _spewMPB(" p", bc->dsa_keypair.param.p); 00775 break; 00776 case 41: /* DSA q */ 00777 (void) mpbsethex(&bc->dsa_keypair.param.q, s = pgpMpiHex(p)); 00778 if (_pgp_debug && _pgp_print) 00779 _spewMPB(" q", bc->dsa_keypair.param.q); 00780 break; 00781 case 42: /* DSA g */ 00782 (void) mpnsethex(&bc->dsa_keypair.param.g, s = pgpMpiHex(p)); 00783 if (_pgp_debug && _pgp_print) 00784 _spewMPN(" g", bc->dsa_keypair.param.g); 00785 break; 00786 case 43: /* DSA y */ 00787 (void) mpnsethex(&bc->dsa_keypair.y, s = pgpMpiHex(p)); 00788 if (_pgp_debug && _pgp_print) 00789 _spewMPN(" y", bc->dsa_keypair.y); 00790 break; 00791 } 00792 s = _free(s); 00793 return rc; 00794 } 00795 00796 /*@-mustmod@*/ 00797 static 00798 void rpmbcClean(void * impl) 00799 /*@modifies impl @*/ 00800 { 00801 rpmbc bc = impl; 00802 if (bc != NULL) { 00803 bc->nbits = 0; 00804 bc->err = 0; 00805 bc->badok = 0; 00806 bc->digest = _free(bc->digest); 00807 bc->digestlen = 0; 00808 00809 randomGeneratorContextFree(&bc->rngc); 00810 00811 rsakpFree(&bc->rsa_keypair); 00812 00813 dlkp_pFree(&bc->dsa_keypair); 00814 00815 dlkp_pFree(&bc->elg_keypair); 00816 #ifdef NOTYET 00817 dldp_pFree(&bc->elg_params); 00818 #endif 00819 00820 mpnfree(&bc->r); 00821 mpnfree(&bc->s); 00822 mpnfree(&bc->hm); 00823 mpnfree(&bc->m); 00824 mpnfree(&bc->c); 00825 } 00826 } 00827 /*@=mustmod@*/ 00828 00829 static /*@null@*/ 00830 void * rpmbcFree(/*@only@*/ void * impl) 00831 /*@modifies impl @*/ 00832 { 00833 rpmbcClean(impl); 00834 impl = _free(impl); 00835 return NULL; 00836 } 00837 00838 static 00839 void * rpmbcInit(void) 00840 /*@*/ 00841 { 00842 rpmbc bc = xcalloc(1, sizeof(*bc)); 00843 return (void *) bc; 00844 } 00845 00846 struct pgpImplVecs_s rpmbcImplVecs = { 00847 rpmbcSetRSA, 00848 rpmbcSetDSA, 00849 rpmbcSetELG, 00850 rpmbcSetECDSA, 00851 00852 rpmbcErrChk, 00853 rpmbcAvailableCipher, rpmbcAvailableDigest, rpmbcAvailablePubkey, 00854 rpmbcVerify, rpmbcSign, rpmbcGenerate, 00855 00856 rpmbcMpiItem, rpmbcClean, 00857 rpmbcFree, rpmbcInit 00858 }; 00859 00860 int rpmbcExportPubkey(pgpDig dig) 00861 { 00862 uint8_t pkt[8192]; 00863 uint8_t * be = pkt; 00864 size_t pktlen; 00865 time_t now = time(NULL); 00866 uint32_t bt = now; 00867 uint16_t bn; 00868 pgpDigParams pubp = pgpGetPubkey(dig); 00869 rpmbc bc = dig->impl; 00870 int xx; 00871 00872 *be++ = 0x80 | (PGPTAG_PUBLIC_KEY << 2) | 0x01; 00873 be += 2; 00874 00875 *be++ = 0x04; 00876 *be++ = (bt >> 24); 00877 *be++ = (bt >> 16); 00878 *be++ = (bt >> 8); 00879 *be++ = (bt ); 00880 *be++ = pubp->pubkey_algo; 00881 00882 bn = mpbits(bc->dsa_keypair.param.p.size, bc->dsa_keypair.param.p.modl); 00883 bn += 7; bn &= ~7; 00884 *be++ = (bn >> 8); *be++ = (bn ); 00885 xx = i2osp(be, bn/8, bc->dsa_keypair.param.p.modl, bc->dsa_keypair.param.p.size); 00886 be += bn/8; 00887 00888 bn = mpbits(bc->dsa_keypair.param.q.size, bc->dsa_keypair.param.q.modl); 00889 bn += 7; bn &= ~7; 00890 *be++ = (bn >> 8); *be++ = (bn ); 00891 xx = i2osp(be, bn/8, bc->dsa_keypair.param.q.modl, bc->dsa_keypair.param.q.size); 00892 be += bn/8; 00893 00894 bn = mpbits(bc->dsa_keypair.param.g.size, bc->dsa_keypair.param.g.data); 00895 bn += 7; bn &= ~7; 00896 *be++ = (bn >> 8); *be++ = (bn ); 00897 xx = i2osp(be, bn/8, bc->dsa_keypair.param.g.data, bc->dsa_keypair.param.g.size); 00898 be += bn/8; 00899 00900 bn = mpbits(bc->dsa_keypair.y.size, bc->dsa_keypair.y.data); 00901 bn += 7; bn &= ~7; 00902 *be++ = (bn >> 8); *be++ = (bn ); 00903 xx = i2osp(be, bn/8, bc->dsa_keypair.y.data, bc->dsa_keypair.y.size); 00904 be += bn/8; 00905 00906 pktlen = (be - pkt); 00907 bn = pktlen - 3; 00908 pkt[1] = (bn >> 8); 00909 pkt[2] = (bn ); 00910 00911 xx = pgpPubkeyFingerprint(pkt, pktlen, pubp->signid); 00912 00913 dig->pub = memcpy(xmalloc(pktlen), pkt, pktlen); 00914 dig->publen = pktlen; 00915 00916 return 0; 00917 } 00918 00919 int rpmbcExportSignature(pgpDig dig, /*@only@*/ DIGEST_CTX ctx) 00920 { 00921 uint8_t pkt[8192]; 00922 uint8_t * be = pkt; 00923 uint8_t * h; 00924 size_t pktlen; 00925 time_t now = time(NULL); 00926 uint32_t bt; 00927 uint16_t bn; 00928 pgpDigParams pubp = pgpGetPubkey(dig); 00929 pgpDigParams sigp = pgpGetSignature(dig); 00930 rpmbc bc = dig->impl; 00931 int xx; 00932 00933 sigp->tag = PGPTAG_SIGNATURE; 00934 *be++ = 0x80 | (sigp->tag << 2) | 0x01; 00935 be += 2; /* pktlen */ 00936 00937 sigp->hash = be; 00938 *be++ = sigp->version = 0x04; /* version */ 00939 *be++ = sigp->sigtype = PGPSIGTYPE_BINARY; /* sigtype */ 00940 *be++ = sigp->pubkey_algo = pubp->pubkey_algo; /* pubkey_algo */ 00941 *be++ = sigp->hash_algo; /* hash_algo */ 00942 00943 be += 2; /* skip hashd length */ 00944 h = (uint8_t *) be; 00945 00946 *be++ = 1 + 4; /* signature creation time */ 00947 *be++ = PGPSUBTYPE_SIG_CREATE_TIME; 00948 bt = now; 00949 *be++ = sigp->time[0] = (bt >> 24); 00950 *be++ = sigp->time[1] = (bt >> 16); 00951 *be++ = sigp->time[2] = (bt >> 8); 00952 *be++ = sigp->time[3] = (bt ); 00953 00954 *be++ = 1 + 4; /* signature expiration time */ 00955 *be++ = PGPSUBTYPE_SIG_EXPIRE_TIME; 00956 bt = 30 * 24 * 60 * 60; /* XXX 30 days from creation */ 00957 *be++ = sigp->expire[0] = (bt >> 24); 00958 *be++ = sigp->expire[1] = (bt >> 16); 00959 *be++ = sigp->expire[2] = (bt >> 8); 00960 *be++ = sigp->expire[3] = (bt ); 00961 00962 /* key expiration time (only on a self-signature) */ 00963 00964 *be++ = 1 + 1; /* exportable certification */ 00965 *be++ = PGPSUBTYPE_EXPORTABLE_CERT; 00966 *be++ = 0; 00967 00968 *be++ = 1 + 1; /* revocable */ 00969 *be++ = PGPSUBTYPE_REVOCABLE; 00970 *be++ = 0; 00971 00972 /* notation data */ 00973 00974 sigp->hashlen = (be - h); /* set hashed length */ 00975 h[-2] = (sigp->hashlen >> 8); 00976 h[-1] = (sigp->hashlen ); 00977 sigp->hashlen += sizeof(struct pgpPktSigV4_s); 00978 00979 if (sigp->hash != NULL) 00980 xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen); 00981 00982 if (sigp->version == (rpmuint8_t) 4) { 00983 uint8_t trailer[6]; 00984 trailer[0] = sigp->version; 00985 trailer[1] = (rpmuint8_t)0xff; 00986 trailer[2] = (sigp->hashlen >> 24); 00987 trailer[3] = (sigp->hashlen >> 16); 00988 trailer[4] = (sigp->hashlen >> 8); 00989 trailer[5] = (sigp->hashlen ); 00990 xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer)); 00991 } 00992 00993 sigp->signhash16[0] = 0x00; 00994 sigp->signhash16[1] = 0x00; 00995 xx = pgpImplSetDSA(ctx, dig, sigp); /* XXX signhash16 check always fails */ 00996 h = bc->digest; 00997 sigp->signhash16[0] = h[0]; 00998 sigp->signhash16[1] = h[1]; 00999 01000 xx = pgpImplSign(dig); 01001 assert(xx == 1); 01002 01003 be += 2; /* skip unhashed length. */ 01004 h = be; 01005 01006 *be++ = 1 + 8; /* issuer key ID */ 01007 *be++ = PGPSUBTYPE_ISSUER_KEYID; 01008 *be++ = pubp->signid[0]; 01009 *be++ = pubp->signid[1]; 01010 *be++ = pubp->signid[2]; 01011 *be++ = pubp->signid[3]; 01012 *be++ = pubp->signid[4]; 01013 *be++ = pubp->signid[5]; 01014 *be++ = pubp->signid[6]; 01015 *be++ = pubp->signid[7]; 01016 01017 bt = (be - h); /* set unhashed length */ 01018 h[-2] = (bt >> 8); 01019 h[-1] = (bt ); 01020 01021 *be++ = sigp->signhash16[0]; /* signhash16 */ 01022 *be++ = sigp->signhash16[1]; 01023 01024 bn = mpbits(bc->r.size, bc->r.data); 01025 bn += 7; bn &= ~7; 01026 *be++ = (bn >> 8); 01027 *be++ = (bn ); 01028 xx = i2osp(be, bn/8, bc->r.data, bc->r.size); 01029 be += bn/8; 01030 01031 bn = mpbits(bc->s.size, bc->s.data); 01032 bn += 7; bn &= ~7; 01033 *be++ = (bn >> 8); 01034 *be++ = (bn ); 01035 xx = i2osp(be, bn/8, bc->s.data, bc->s.size); 01036 be += bn/8; 01037 01038 pktlen = (be - pkt); /* packet length */ 01039 bn = pktlen - 3; 01040 pkt[1] = (bn >> 8); 01041 pkt[2] = (bn ); 01042 01043 dig->sig = memcpy(xmalloc(pktlen), pkt, pktlen); 01044 dig->siglen = pktlen; 01045 01046 return 0; 01047 01048 }