00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "postgres.h"
00032
00033 #include "px.h"
00034 #include "mbuf.h"
00035 #include "pgp.h"
00036
00037 int
00038 pgp_key_alloc(PGP_PubKey **pk_p)
00039 {
00040 PGP_PubKey *pk;
00041
00042 pk = px_alloc(sizeof(*pk));
00043 memset(pk, 0, sizeof(*pk));
00044 *pk_p = pk;
00045 return 0;
00046 }
00047
00048 void
00049 pgp_key_free(PGP_PubKey *pk)
00050 {
00051 if (pk == NULL)
00052 return;
00053
00054 switch (pk->algo)
00055 {
00056 case PGP_PUB_ELG_ENCRYPT:
00057 pgp_mpi_free(pk->pub.elg.p);
00058 pgp_mpi_free(pk->pub.elg.g);
00059 pgp_mpi_free(pk->pub.elg.y);
00060 pgp_mpi_free(pk->sec.elg.x);
00061 break;
00062 case PGP_PUB_RSA_SIGN:
00063 case PGP_PUB_RSA_ENCRYPT:
00064 case PGP_PUB_RSA_ENCRYPT_SIGN:
00065 pgp_mpi_free(pk->pub.rsa.n);
00066 pgp_mpi_free(pk->pub.rsa.e);
00067 pgp_mpi_free(pk->sec.rsa.d);
00068 pgp_mpi_free(pk->sec.rsa.p);
00069 pgp_mpi_free(pk->sec.rsa.q);
00070 pgp_mpi_free(pk->sec.rsa.u);
00071 break;
00072 case PGP_PUB_DSA_SIGN:
00073 pgp_mpi_free(pk->pub.dsa.p);
00074 pgp_mpi_free(pk->pub.dsa.q);
00075 pgp_mpi_free(pk->pub.dsa.g);
00076 pgp_mpi_free(pk->pub.dsa.y);
00077 pgp_mpi_free(pk->sec.dsa.x);
00078 break;
00079 }
00080 memset(pk, 0, sizeof(*pk));
00081 px_free(pk);
00082 }
00083
00084 static int
00085 calc_key_id(PGP_PubKey *pk)
00086 {
00087 int res;
00088 PX_MD *md;
00089 int len;
00090 uint8 hdr[3];
00091 uint8 hash[20];
00092
00093 res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
00094 if (res < 0)
00095 return res;
00096
00097 len = 1 + 4 + 1;
00098 switch (pk->algo)
00099 {
00100 case PGP_PUB_ELG_ENCRYPT:
00101 len += 2 + pk->pub.elg.p->bytes;
00102 len += 2 + pk->pub.elg.g->bytes;
00103 len += 2 + pk->pub.elg.y->bytes;
00104 break;
00105 case PGP_PUB_RSA_SIGN:
00106 case PGP_PUB_RSA_ENCRYPT:
00107 case PGP_PUB_RSA_ENCRYPT_SIGN:
00108 len += 2 + pk->pub.rsa.n->bytes;
00109 len += 2 + pk->pub.rsa.e->bytes;
00110 break;
00111 case PGP_PUB_DSA_SIGN:
00112 len += 2 + pk->pub.dsa.p->bytes;
00113 len += 2 + pk->pub.dsa.q->bytes;
00114 len += 2 + pk->pub.dsa.g->bytes;
00115 len += 2 + pk->pub.dsa.y->bytes;
00116 break;
00117 }
00118
00119 hdr[0] = 0x99;
00120 hdr[1] = len >> 8;
00121 hdr[2] = len & 0xFF;
00122 px_md_update(md, hdr, 3);
00123
00124 px_md_update(md, &pk->ver, 1);
00125 px_md_update(md, pk->time, 4);
00126 px_md_update(md, &pk->algo, 1);
00127
00128 switch (pk->algo)
00129 {
00130 case PGP_PUB_ELG_ENCRYPT:
00131 pgp_mpi_hash(md, pk->pub.elg.p);
00132 pgp_mpi_hash(md, pk->pub.elg.g);
00133 pgp_mpi_hash(md, pk->pub.elg.y);
00134 break;
00135 case PGP_PUB_RSA_SIGN:
00136 case PGP_PUB_RSA_ENCRYPT:
00137 case PGP_PUB_RSA_ENCRYPT_SIGN:
00138 pgp_mpi_hash(md, pk->pub.rsa.n);
00139 pgp_mpi_hash(md, pk->pub.rsa.e);
00140 break;
00141 case PGP_PUB_DSA_SIGN:
00142 pgp_mpi_hash(md, pk->pub.dsa.p);
00143 pgp_mpi_hash(md, pk->pub.dsa.q);
00144 pgp_mpi_hash(md, pk->pub.dsa.g);
00145 pgp_mpi_hash(md, pk->pub.dsa.y);
00146 break;
00147 }
00148
00149 px_md_finish(md, hash);
00150 px_md_free(md);
00151
00152 memcpy(pk->key_id, hash + 12, 8);
00153 memset(hash, 0, 20);
00154
00155 return 0;
00156 }
00157
00158 int
00159 _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
00160 {
00161 int res;
00162 PGP_PubKey *pk;
00163
00164 res = pgp_key_alloc(&pk);
00165 if (res < 0)
00166 return res;
00167
00168
00169 GETBYTE(pkt, pk->ver);
00170 if (pk->ver != 4)
00171 {
00172 res = PXE_PGP_NOT_V4_KEYPKT;
00173 goto out;
00174 }
00175
00176
00177 res = pullf_read_fixed(pkt, 4, pk->time);
00178 if (res < 0)
00179 goto out;
00180
00181
00182 GETBYTE(pkt, pk->algo);
00183
00184 switch (pk->algo)
00185 {
00186 case PGP_PUB_DSA_SIGN:
00187 res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
00188 if (res < 0)
00189 break;
00190 res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
00191 if (res < 0)
00192 break;
00193 res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
00194 if (res < 0)
00195 break;
00196 res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
00197 if (res < 0)
00198 break;
00199
00200 res = calc_key_id(pk);
00201 break;
00202
00203 case PGP_PUB_RSA_SIGN:
00204 case PGP_PUB_RSA_ENCRYPT:
00205 case PGP_PUB_RSA_ENCRYPT_SIGN:
00206 res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
00207 if (res < 0)
00208 break;
00209 res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
00210 if (res < 0)
00211 break;
00212
00213 res = calc_key_id(pk);
00214
00215 if (pk->algo != PGP_PUB_RSA_SIGN)
00216 pk->can_encrypt = 1;
00217 break;
00218
00219 case PGP_PUB_ELG_ENCRYPT:
00220 res = pgp_mpi_read(pkt, &pk->pub.elg.p);
00221 if (res < 0)
00222 break;
00223 res = pgp_mpi_read(pkt, &pk->pub.elg.g);
00224 if (res < 0)
00225 break;
00226 res = pgp_mpi_read(pkt, &pk->pub.elg.y);
00227 if (res < 0)
00228 break;
00229
00230 res = calc_key_id(pk);
00231
00232 pk->can_encrypt = 1;
00233 break;
00234
00235 default:
00236 px_debug("unknown public algo: %d", pk->algo);
00237 res = PXE_PGP_UNKNOWN_PUBALGO;
00238 }
00239
00240 out:
00241 if (res < 0)
00242 pgp_key_free(pk);
00243 else
00244 *pk_p = pk;
00245
00246 return res;
00247 }
00248
00249 #define HIDE_CLEAR 0
00250 #define HIDE_CKSUM 255
00251 #define HIDE_SHA1 254
00252
00253 static int
00254 check_key_sha1(PullFilter *src, PGP_PubKey *pk)
00255 {
00256 int res;
00257 uint8 got_sha1[20];
00258 uint8 my_sha1[20];
00259 PX_MD *md;
00260
00261 res = pullf_read_fixed(src, 20, got_sha1);
00262 if (res < 0)
00263 return res;
00264
00265 res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
00266 if (res < 0)
00267 goto err;
00268 switch (pk->algo)
00269 {
00270 case PGP_PUB_ELG_ENCRYPT:
00271 pgp_mpi_hash(md, pk->sec.elg.x);
00272 break;
00273 case PGP_PUB_RSA_SIGN:
00274 case PGP_PUB_RSA_ENCRYPT:
00275 case PGP_PUB_RSA_ENCRYPT_SIGN:
00276 pgp_mpi_hash(md, pk->sec.rsa.d);
00277 pgp_mpi_hash(md, pk->sec.rsa.p);
00278 pgp_mpi_hash(md, pk->sec.rsa.q);
00279 pgp_mpi_hash(md, pk->sec.rsa.u);
00280 break;
00281 case PGP_PUB_DSA_SIGN:
00282 pgp_mpi_hash(md, pk->sec.dsa.x);
00283 break;
00284 }
00285 px_md_finish(md, my_sha1);
00286 px_md_free(md);
00287
00288 if (memcmp(my_sha1, got_sha1, 20) != 0)
00289 {
00290 px_debug("key sha1 check failed");
00291 res = PXE_PGP_KEYPKT_CORRUPT;
00292 }
00293 err:
00294 memset(got_sha1, 0, 20);
00295 memset(my_sha1, 0, 20);
00296 return res;
00297 }
00298
00299 static int
00300 check_key_cksum(PullFilter *src, PGP_PubKey *pk)
00301 {
00302 int res;
00303 unsigned got_cksum,
00304 my_cksum = 0;
00305 uint8 buf[2];
00306
00307 res = pullf_read_fixed(src, 2, buf);
00308 if (res < 0)
00309 return res;
00310
00311 got_cksum = ((unsigned) buf[0] << 8) + buf[1];
00312 switch (pk->algo)
00313 {
00314 case PGP_PUB_ELG_ENCRYPT:
00315 my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
00316 break;
00317 case PGP_PUB_RSA_SIGN:
00318 case PGP_PUB_RSA_ENCRYPT:
00319 case PGP_PUB_RSA_ENCRYPT_SIGN:
00320 my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
00321 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
00322 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
00323 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
00324 break;
00325 case PGP_PUB_DSA_SIGN:
00326 my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
00327 break;
00328 }
00329 if (my_cksum != got_cksum)
00330 {
00331 px_debug("key cksum check failed");
00332 return PXE_PGP_KEYPKT_CORRUPT;
00333 }
00334 return 0;
00335 }
00336
00337 static int
00338 process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
00339 const uint8 *key, int key_len)
00340 {
00341 int res;
00342 int hide_type;
00343 int cipher_algo;
00344 int bs;
00345 uint8 iv[512];
00346 PullFilter *pf_decrypt = NULL,
00347 *pf_key;
00348 PGP_CFB *cfb = NULL;
00349 PGP_S2K s2k;
00350 PGP_PubKey *pk;
00351
00352
00353 res = _pgp_read_public_key(pkt, &pk);
00354 if (res < 0)
00355 return res;
00356
00357
00358
00359
00360 GETBYTE(pkt, hide_type);
00361 if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
00362 {
00363 if (key == NULL)
00364 return PXE_PGP_NEED_SECRET_PSW;
00365 GETBYTE(pkt, cipher_algo);
00366 res = pgp_s2k_read(pkt, &s2k);
00367 if (res < 0)
00368 return res;
00369
00370 res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
00371 if (res < 0)
00372 return res;
00373
00374 bs = pgp_get_cipher_block_size(cipher_algo);
00375 if (bs == 0)
00376 {
00377 px_debug("unknown cipher algo=%d", cipher_algo);
00378 return PXE_PGP_UNSUPPORTED_CIPHER;
00379 }
00380 res = pullf_read_fixed(pkt, bs, iv);
00381 if (res < 0)
00382 return res;
00383
00384
00385
00386
00387 res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
00388 if (res < 0)
00389 return res;
00390 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
00391 if (res < 0)
00392 return res;
00393 pf_key = pf_decrypt;
00394 }
00395 else if (hide_type == HIDE_CLEAR)
00396 {
00397 pf_key = pkt;
00398 }
00399 else
00400 {
00401 px_debug("unknown hide type");
00402 return PXE_PGP_KEYPKT_CORRUPT;
00403 }
00404
00405
00406 switch (pk->algo)
00407 {
00408 case PGP_PUB_RSA_SIGN:
00409 case PGP_PUB_RSA_ENCRYPT:
00410 case PGP_PUB_RSA_ENCRYPT_SIGN:
00411 res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
00412 if (res < 0)
00413 break;
00414 res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
00415 if (res < 0)
00416 break;
00417 res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
00418 if (res < 0)
00419 break;
00420 res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
00421 if (res < 0)
00422 break;
00423 break;
00424 case PGP_PUB_ELG_ENCRYPT:
00425 res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
00426 break;
00427 case PGP_PUB_DSA_SIGN:
00428 res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
00429 break;
00430 default:
00431 px_debug("unknown public algo: %d", pk->algo);
00432 res = PXE_PGP_KEYPKT_CORRUPT;
00433 }
00434
00435 if (res >= 0)
00436 {
00437 if (hide_type == HIDE_SHA1)
00438 res = check_key_sha1(pf_key, pk);
00439 else
00440 res = check_key_cksum(pf_key, pk);
00441 }
00442 if (res >= 0)
00443 res = pgp_expect_packet_end(pf_key);
00444
00445 if (pf_decrypt)
00446 pullf_free(pf_decrypt);
00447 if (cfb)
00448 pgp_cfb_free(cfb);
00449
00450 if (res < 0)
00451 pgp_key_free(pk);
00452 else
00453 *pk_p = pk;
00454
00455 return res;
00456 }
00457
00458 static int
00459 internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
00460 const uint8 *psw, int psw_len, int pubtype)
00461 {
00462 PullFilter *pkt = NULL;
00463 int res;
00464 uint8 tag;
00465 int len;
00466 PGP_PubKey *enc_key = NULL;
00467 PGP_PubKey *pk = NULL;
00468 int got_main_key = 0;
00469
00470
00471
00472
00473
00474
00475 while (1)
00476 {
00477 res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
00478 if (res <= 0)
00479 break;
00480 res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
00481 if (res < 0)
00482 break;
00483
00484 switch (tag)
00485 {
00486 case PGP_PKT_PUBLIC_KEY:
00487 case PGP_PKT_SECRET_KEY:
00488 if (got_main_key)
00489 {
00490 res = PXE_PGP_MULTIPLE_KEYS;
00491 break;
00492 }
00493 got_main_key = 1;
00494 res = pgp_skip_packet(pkt);
00495 break;
00496
00497 case PGP_PKT_PUBLIC_SUBKEY:
00498 if (pubtype != 0)
00499 res = PXE_PGP_EXPECT_SECRET_KEY;
00500 else
00501 res = _pgp_read_public_key(pkt, &pk);
00502 break;
00503
00504 case PGP_PKT_SECRET_SUBKEY:
00505 if (pubtype != 1)
00506 res = PXE_PGP_EXPECT_PUBLIC_KEY;
00507 else
00508 res = process_secret_key(pkt, &pk, psw, psw_len);
00509 break;
00510
00511 case PGP_PKT_SIGNATURE:
00512 case PGP_PKT_MARKER:
00513 case PGP_PKT_TRUST:
00514 case PGP_PKT_USER_ID:
00515 case PGP_PKT_USER_ATTR:
00516 case PGP_PKT_PRIV_61:
00517 res = pgp_skip_packet(pkt);
00518 break;
00519 default:
00520 px_debug("unknown/unexpected packet: %d", tag);
00521 res = PXE_PGP_UNEXPECTED_PKT;
00522 }
00523 pullf_free(pkt);
00524 pkt = NULL;
00525
00526 if (pk != NULL)
00527 {
00528 if (res >= 0 && pk->can_encrypt)
00529 {
00530 if (enc_key == NULL)
00531 {
00532 enc_key = pk;
00533 pk = NULL;
00534 }
00535 else
00536 res = PXE_PGP_MULTIPLE_SUBKEYS;
00537 }
00538
00539 if (pk)
00540 pgp_key_free(pk);
00541 pk = NULL;
00542 }
00543
00544 if (res < 0)
00545 break;
00546 }
00547
00548 if (pkt)
00549 pullf_free(pkt);
00550
00551 if (res < 0)
00552 {
00553 if (enc_key)
00554 pgp_key_free(enc_key);
00555 return res;
00556 }
00557
00558 if (!enc_key)
00559 res = PXE_PGP_NO_USABLE_KEY;
00560 else
00561 *pk_p = enc_key;
00562 return res;
00563 }
00564
00565 int
00566 pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
00567 const uint8 *key, int key_len, int pubtype)
00568 {
00569 int res;
00570 PullFilter *src;
00571 PGP_PubKey *pk = NULL;
00572
00573 res = pullf_create_mbuf_reader(&src, keypkt);
00574 if (res < 0)
00575 return res;
00576
00577 res = internal_read_key(src, &pk, key, key_len, pubtype);
00578 pullf_free(src);
00579
00580 if (res >= 0)
00581 ctx->pub_key = pk;
00582
00583 return res < 0 ? res : 0;
00584 }