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