00001
00006 #include "system.h"
00007 #include "rpmio_internal.h"
00008 #define _RPMPGP_INTERNAL
00009 #include <rpmbc.h>
00010 #if defined(WITH_NSS)
00011 #include <rpmnss.h>
00012 #endif
00013 #include "debug.h"
00014
00015
00016
00017
00018
00019
00020 int _pgp_debug = 0;
00021
00022
00023 int _pgp_print = 0;
00024
00025
00026 pgpImplVecs_t * pgpImplVecs =
00027 #if defined(WITH_NSS)
00028 &rpmnssImplVecs;
00029 #else
00030 &rpmbcImplVecs;
00031 #endif
00032
00033
00034 static pgpDig _dig = NULL;
00035
00036
00037 static pgpDigParams _digp = NULL;
00038
00039 struct pgpPkt_s {
00040 pgpTag tag;
00041 unsigned int pktlen;
00042 const uint8_t * h;
00043 unsigned int hlen;
00044 };
00045
00046 struct pgpValTbl_s pgpSigTypeTbl[] = {
00047 { PGPSIGTYPE_BINARY, "Binary document signature" },
00048 { PGPSIGTYPE_TEXT, "Text document signature" },
00049 { PGPSIGTYPE_STANDALONE, "Standalone signature" },
00050 { PGPSIGTYPE_GENERIC_CERT, "Generic certification of a User ID and Public Key" },
00051 { PGPSIGTYPE_PERSONA_CERT, "Personal certification of a User ID and Public Key" },
00052 { PGPSIGTYPE_CASUAL_CERT, "Casual certification of a User ID and Public Key" },
00053 { PGPSIGTYPE_POSITIVE_CERT, "Positive certification of a User ID and Public Key" },
00054 { PGPSIGTYPE_SUBKEY_BINDING,"Subkey Binding Signature" },
00055 { PGPSIGTYPE_SIGNED_KEY, "Signature directly on a key" },
00056 { PGPSIGTYPE_KEY_REVOKE, "Key revocation signature" },
00057 { PGPSIGTYPE_SUBKEY_REVOKE, "Subkey revocation signature" },
00058 { PGPSIGTYPE_CERT_REVOKE, "Certification revocation signature" },
00059 { PGPSIGTYPE_TIMESTAMP, "Timestamp signature" },
00060 { -1, "Unknown signature type" },
00061 };
00062
00063 struct pgpValTbl_s pgpPubkeyTbl[] = {
00064 { PGPPUBKEYALGO_RSA, "RSA" },
00065 { PGPPUBKEYALGO_RSA_ENCRYPT,"RSA(Encrypt-Only)" },
00066 { PGPPUBKEYALGO_RSA_SIGN, "RSA(Sign-Only)" },
00067 { PGPPUBKEYALGO_ELGAMAL_ENCRYPT,"Elgamal(Encrypt-Only)" },
00068 { PGPPUBKEYALGO_DSA, "DSA" },
00069 { PGPPUBKEYALGO_EC, "Elliptic Curve" },
00070 { PGPPUBKEYALGO_ECDSA, "ECDSA" },
00071 { PGPPUBKEYALGO_ELGAMAL, "Elgamal" },
00072 { PGPPUBKEYALGO_DH, "Diffie-Hellman (X9.42)" },
00073 { -1, "Unknown public key algorithm" },
00074 };
00075
00076 struct pgpValTbl_s pgpSymkeyTbl[] = {
00077 { PGPSYMKEYALGO_PLAINTEXT, "Plaintext" },
00078 { PGPSYMKEYALGO_IDEA, "IDEA" },
00079 { PGPSYMKEYALGO_TRIPLE_DES, "3DES" },
00080 { PGPSYMKEYALGO_CAST5, "CAST5" },
00081 { PGPSYMKEYALGO_BLOWFISH, "BLOWFISH" },
00082 { PGPSYMKEYALGO_SAFER, "SAFER" },
00083 { PGPSYMKEYALGO_DES_SK, "DES/SK" },
00084 { PGPSYMKEYALGO_AES_128, "AES(128-bit key)" },
00085 { PGPSYMKEYALGO_AES_192, "AES(192-bit key)" },
00086 { PGPSYMKEYALGO_AES_256, "AES(256-bit key)" },
00087 { PGPSYMKEYALGO_TWOFISH, "TWOFISH(256-bit key)" },
00088 { PGPSYMKEYALGO_NOENCRYPT, "no encryption" },
00089 { -1, "Unknown symmetric key algorithm" },
00090 };
00091
00092 struct pgpValTbl_s pgpCompressionTbl[] = {
00093 { PGPCOMPRESSALGO_NONE, "Uncompressed" },
00094 { PGPCOMPRESSALGO_ZIP, "ZIP" },
00095 { PGPCOMPRESSALGO_ZLIB, "ZLIB" },
00096 { PGPCOMPRESSALGO_BZIP2, "BZIP2" },
00097 { -1, "Unknown compression algorithm" },
00098 };
00099
00100 struct pgpValTbl_s pgpHashTbl[] = {
00101 { PGPHASHALGO_MD5, "MD5" },
00102 { PGPHASHALGO_SHA1, "SHA1" },
00103 { PGPHASHALGO_RIPEMD160, "RIPEMD160" },
00104 { PGPHASHALGO_MD2, "MD2" },
00105 { PGPHASHALGO_TIGER192, "TIGER192" },
00106 { PGPHASHALGO_HAVAL_5_160, "HAVAL-5-160" },
00107 { PGPHASHALGO_SHA256, "SHA256" },
00108 { PGPHASHALGO_SHA384, "SHA384" },
00109 { PGPHASHALGO_SHA512, "SHA512" },
00110 { -1, "Unknown hash algorithm" },
00111 };
00112
00113
00114
00115 struct pgpValTbl_s pgpKeyServerPrefsTbl[] = {
00116 { 0x80, "No-modify" },
00117 { -1, "Unknown key server preference" },
00118 };
00119
00120
00121 struct pgpValTbl_s pgpSubTypeTbl[] = {
00122 { PGPSUBTYPE_SIG_CREATE_TIME,"signature creation time" },
00123 { PGPSUBTYPE_SIG_EXPIRE_TIME,"signature expiration time" },
00124 { PGPSUBTYPE_EXPORTABLE_CERT,"exportable certification" },
00125 { PGPSUBTYPE_TRUST_SIG, "trust signature" },
00126 { PGPSUBTYPE_REGEX, "regular expression" },
00127 { PGPSUBTYPE_REVOCABLE, "revocable" },
00128 { PGPSUBTYPE_KEY_EXPIRE_TIME,"key expiration time" },
00129 { PGPSUBTYPE_ARR, "additional recipient request" },
00130 { PGPSUBTYPE_PREFER_SYMKEY, "preferred symmetric algorithms" },
00131 { PGPSUBTYPE_REVOKE_KEY, "revocation key" },
00132 { PGPSUBTYPE_ISSUER_KEYID, "issuer key ID" },
00133 { PGPSUBTYPE_NOTATION, "notation data" },
00134 { PGPSUBTYPE_PREFER_HASH, "preferred hash algorithms" },
00135 { PGPSUBTYPE_PREFER_COMPRESS,"preferred compression algorithms" },
00136 { PGPSUBTYPE_KEYSERVER_PREFERS,"key server preferences" },
00137 { PGPSUBTYPE_PREFER_KEYSERVER,"preferred key server" },
00138 { PGPSUBTYPE_PRIMARY_USERID,"primary user id" },
00139 { PGPSUBTYPE_POLICY_URL, "policy URL" },
00140 { PGPSUBTYPE_KEY_FLAGS, "key flags" },
00141 { PGPSUBTYPE_SIGNER_USERID, "signer's user id" },
00142 { PGPSUBTYPE_REVOKE_REASON, "reason for revocation" },
00143 { PGPSUBTYPE_FEATURES, "features" },
00144 { PGPSUBTYPE_EMBEDDED_SIG, "embedded signature" },
00145
00146 { PGPSUBTYPE_INTERNAL_100, "internal subpkt type 100" },
00147 { PGPSUBTYPE_INTERNAL_101, "internal subpkt type 101" },
00148 { PGPSUBTYPE_INTERNAL_102, "internal subpkt type 102" },
00149 { PGPSUBTYPE_INTERNAL_103, "internal subpkt type 103" },
00150 { PGPSUBTYPE_INTERNAL_104, "internal subpkt type 104" },
00151 { PGPSUBTYPE_INTERNAL_105, "internal subpkt type 105" },
00152 { PGPSUBTYPE_INTERNAL_106, "internal subpkt type 106" },
00153 { PGPSUBTYPE_INTERNAL_107, "internal subpkt type 107" },
00154 { PGPSUBTYPE_INTERNAL_108, "internal subpkt type 108" },
00155 { PGPSUBTYPE_INTERNAL_109, "internal subpkt type 109" },
00156 { PGPSUBTYPE_INTERNAL_110, "internal subpkt type 110" },
00157 { -1, "Unknown signature subkey type" },
00158 };
00159
00160 struct pgpValTbl_s pgpTagTbl[] = {
00161 { PGPTAG_PUBLIC_SESSION_KEY,"Public-Key Encrypted Session Key" },
00162 { PGPTAG_SIGNATURE, "Signature" },
00163 { PGPTAG_SYMMETRIC_SESSION_KEY,"Symmetric-Key Encrypted Session Key" },
00164 { PGPTAG_ONEPASS_SIGNATURE, "One-Pass Signature" },
00165 { PGPTAG_SECRET_KEY, "Secret Key" },
00166 { PGPTAG_PUBLIC_KEY, "Public Key" },
00167 { PGPTAG_SECRET_SUBKEY, "Secret Subkey" },
00168 { PGPTAG_COMPRESSED_DATA, "Compressed Data" },
00169 { PGPTAG_SYMMETRIC_DATA, "Symmetrically Encrypted Data" },
00170 { PGPTAG_MARKER, "Marker" },
00171 { PGPTAG_LITERAL_DATA, "Literal Data" },
00172 { PGPTAG_TRUST, "Trust" },
00173 { PGPTAG_USER_ID, "User ID" },
00174 { PGPTAG_PUBLIC_SUBKEY, "Public Subkey" },
00175 { PGPTAG_COMMENT_OLD, "Comment (from OpenPGP draft)" },
00176 { PGPTAG_PHOTOID, "PGP's photo ID" },
00177 { PGPTAG_ENCRYPTED_MDC, "Integrity protected encrypted data" },
00178 { PGPTAG_MDC, "Manipulaion detection code packet" },
00179 { PGPTAG_PRIVATE_60, "Private #60" },
00180 { PGPTAG_COMMENT, "Comment" },
00181 { PGPTAG_PRIVATE_62, "Private #62" },
00182 { PGPTAG_CONTROL, "Control (GPG)" },
00183 { -1, "Unknown packet tag" },
00184 };
00185
00186 struct pgpValTbl_s pgpArmorTbl[] = {
00187 { PGPARMOR_MESSAGE, "MESSAGE" },
00188 { PGPARMOR_PUBKEY, "PUBLIC KEY BLOCK" },
00189 { PGPARMOR_SIGNATURE, "SIGNATURE" },
00190 { PGPARMOR_SIGNED_MESSAGE, "SIGNED MESSAGE" },
00191 { PGPARMOR_FILE, "ARMORED FILE" },
00192 { PGPARMOR_PRIVKEY, "PRIVATE KEY BLOCK" },
00193 { PGPARMOR_SECKEY, "SECRET KEY BLOCK" },
00194 { -1, "Unknown armor block" }
00195 };
00196
00197 struct pgpValTbl_s pgpArmorKeyTbl[] = {
00198 { PGPARMORKEY_VERSION, "Version: " },
00199 { PGPARMORKEY_COMMENT, "Comment: " },
00200 { PGPARMORKEY_MESSAGEID, "MessageID: " },
00201 { PGPARMORKEY_HASH, "Hash: " },
00202 { PGPARMORKEY_CHARSET, "Charset: " },
00203 { -1, "Unknown armor key" }
00204 };
00205
00206 static void pgpPrtNL(void)
00207
00208
00209 {
00210 if (!_pgp_print) return;
00211 fprintf(stderr, "\n");
00212 }
00213
00214 static void pgpPrtInt(const char *pre, int i)
00215
00216
00217 {
00218 if (!_pgp_print) return;
00219 if (pre && *pre)
00220 fprintf(stderr, "%s", pre);
00221 fprintf(stderr, " %d", i);
00222 }
00223
00224 static void pgpPrtStr(const char *pre, const char *s)
00225
00226
00227 {
00228 if (!_pgp_print) return;
00229 if (pre && *pre)
00230 fprintf(stderr, "%s", pre);
00231 fprintf(stderr, " %s", s);
00232 }
00233
00234 static void pgpPrtHex(const char *pre, const uint8_t * p, size_t plen)
00235
00236
00237 {
00238 if (!_pgp_print) return;
00239 if (pre && *pre)
00240 fprintf(stderr, "%s", pre);
00241 fprintf(stderr, " %s", pgpHexStr(p, plen));
00242 }
00243
00244 void pgpPrtVal(const char * pre, pgpValTbl vs, uint8_t val)
00245
00246
00247 {
00248 if (!_pgp_print) return;
00249 if (pre && *pre)
00250 fprintf(stderr, "%s", pre);
00251 fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
00252 }
00253
00254 int pgpPrtSubType(const uint8_t * h, size_t hlen, pgpSigType sigtype)
00255 {
00256 const uint8_t * p = h;
00257 unsigned plen;
00258 int i;
00259
00260 while (hlen > 0) {
00261 i = pgpLen(p, &plen);
00262 p += i;
00263 hlen -= i;
00264
00265 pgpPrtVal(" ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
00266 if (p[0] & PGPSUBTYPE_CRITICAL)
00267 if (_pgp_print)
00268 fprintf(stderr, " *CRITICAL*");
00269 switch (*p) {
00270 case PGPSUBTYPE_PREFER_SYMKEY:
00271 for (i = 1; i < plen; i++)
00272 pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
00273 break;
00274 case PGPSUBTYPE_PREFER_HASH:
00275 for (i = 1; i < plen; i++)
00276 pgpPrtVal(" ", pgpHashTbl, p[i]);
00277 break;
00278 case PGPSUBTYPE_PREFER_COMPRESS:
00279 for (i = 1; i < plen; i++)
00280 pgpPrtVal(" ", pgpCompressionTbl, p[i]);
00281 break;
00282 case PGPSUBTYPE_KEYSERVER_PREFERS:
00283 for (i = 1; i < plen; i++)
00284 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
00285 break;
00286 case PGPSUBTYPE_SIG_CREATE_TIME:
00287
00288 if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
00289 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
00290 {
00291 _digp->saved |= PGPDIG_SAVED_TIME;
00292 memcpy(_digp->time, p+1, sizeof(_digp->time));
00293 }
00294
00295
00296 case PGPSUBTYPE_SIG_EXPIRE_TIME:
00297 case PGPSUBTYPE_KEY_EXPIRE_TIME:
00298 if ((plen - 1) == 4) {
00299 time_t t = pgpGrab(p+1, plen-1);
00300 if (_pgp_print)
00301 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00302 } else
00303 pgpPrtHex("", p+1, plen-1);
00304 break;
00305
00306 case PGPSUBTYPE_ISSUER_KEYID:
00307
00308 if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
00309 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
00310 {
00311 _digp->saved |= PGPDIG_SAVED_ID;
00312 memcpy(_digp->signid, p+1, sizeof(_digp->signid));
00313 }
00314
00315
00316 case PGPSUBTYPE_EXPORTABLE_CERT:
00317 case PGPSUBTYPE_TRUST_SIG:
00318 case PGPSUBTYPE_REGEX:
00319 case PGPSUBTYPE_REVOCABLE:
00320 case PGPSUBTYPE_ARR:
00321 case PGPSUBTYPE_REVOKE_KEY:
00322 case PGPSUBTYPE_NOTATION:
00323 case PGPSUBTYPE_PREFER_KEYSERVER:
00324 case PGPSUBTYPE_PRIMARY_USERID:
00325 case PGPSUBTYPE_POLICY_URL:
00326 case PGPSUBTYPE_KEY_FLAGS:
00327 case PGPSUBTYPE_SIGNER_USERID:
00328 case PGPSUBTYPE_REVOKE_REASON:
00329 case PGPSUBTYPE_FEATURES:
00330 case PGPSUBTYPE_EMBEDDED_SIG:
00331 case PGPSUBTYPE_INTERNAL_100:
00332 case PGPSUBTYPE_INTERNAL_101:
00333 case PGPSUBTYPE_INTERNAL_102:
00334 case PGPSUBTYPE_INTERNAL_103:
00335 case PGPSUBTYPE_INTERNAL_104:
00336 case PGPSUBTYPE_INTERNAL_105:
00337 case PGPSUBTYPE_INTERNAL_106:
00338 case PGPSUBTYPE_INTERNAL_107:
00339 case PGPSUBTYPE_INTERNAL_108:
00340 case PGPSUBTYPE_INTERNAL_109:
00341 case PGPSUBTYPE_INTERNAL_110:
00342 default:
00343 pgpPrtHex("", p+1, plen-1);
00344 break;
00345 }
00346 pgpPrtNL();
00347 p += plen;
00348 hlen -= plen;
00349 }
00350 return 0;
00351 }
00352
00353
00354
00355 static const char * pgpSigRSA[] = {
00356 " m**d =",
00357 NULL,
00358 };
00359
00360
00361 static const char * pgpSigDSA[] = {
00362 " r =",
00363 " s =",
00364 NULL,
00365 };
00366
00367
00368 static int pgpPrtSigParams(const pgpPkt pp, uint8_t pubkey_algo,
00369 uint8_t sigtype, const uint8_t * p)
00370
00371
00372 {
00373 const uint8_t * pend = pp->h + pp->hlen;
00374 int xx;
00375 int i;
00376
00377 for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
00378 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00379 if (i >= 1) break;
00380 if (_dig &&
00381 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
00382 {
00383 xx = 0;
00384 switch (i) {
00385 case 0:
00386 xx = pgpImplMpiItem(pgpSigRSA[i], _dig, 10+i, p, pend);
00387 break;
00388 default:
00389 xx = 1;
00390 break;
00391 }
00392 if (xx) return xx;
00393 }
00394 pgpPrtStr("", pgpSigRSA[i]);
00395 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00396 if (i >= 2) break;
00397 if (_dig &&
00398 (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
00399 {
00400 xx = 0;
00401 switch (i) {
00402 case 0:
00403 xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend);
00404 break;
00405 case 1:
00406 xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend);
00407 break;
00408 default:
00409 xx = 1;
00410 break;
00411 }
00412 if (xx) return xx;
00413 }
00414 pgpPrtStr("", pgpSigDSA[i]);
00415 } else {
00416 if (_pgp_print)
00417 fprintf(stderr, "%7d", i);
00418 }
00419 pgpPrtStr("", pgpMpiStr(p));
00420 pgpPrtNL();
00421 }
00422
00423 return 0;
00424 }
00425
00426 int pgpPrtSig(const pgpPkt pp)
00427
00428
00429 {
00430 uint8_t version = pp->h[0];
00431 uint8_t * p;
00432 unsigned plen;
00433 int rc;
00434
00435 switch (version) {
00436 case 3:
00437 { pgpPktSigV3 v = (pgpPktSigV3)pp->h;
00438 time_t t;
00439
00440 if (v->hashlen != 5)
00441 return 1;
00442
00443 pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
00444 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00445 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
00446 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
00447 pgpPrtNL();
00448 t = pgpGrab(v->time, sizeof(v->time));
00449 if (_pgp_print)
00450 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00451 pgpPrtNL();
00452 pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
00453 plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
00454 pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
00455 pgpPrtNL();
00456
00457 if (_digp && _digp->pubkey_algo == 0) {
00458 _digp->version = v->version;
00459 _digp->hashlen = v->hashlen;
00460 _digp->sigtype = v->sigtype;
00461 _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
00462 memcpy(_digp->time, v->time, sizeof(_digp->time));
00463 memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
00464 _digp->pubkey_algo = v->pubkey_algo;
00465 _digp->hash_algo = v->hash_algo;
00466 memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
00467 }
00468
00469 p = ((uint8_t *)v) + sizeof(*v);
00470 rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
00471 } break;
00472 case 4:
00473 { pgpPktSigV4 v = (pgpPktSigV4)pp->h;
00474
00475 pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
00476 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00477 pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
00478 pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
00479 pgpPrtNL();
00480
00481 p = &v->hashlen[0];
00482 plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
00483 p += sizeof(v->hashlen);
00484
00485 if ((p + plen) > (pp->h + pp->hlen))
00486 return 1;
00487
00488 if (_pgp_debug && _pgp_print)
00489 fprintf(stderr, " hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
00490 if (_digp && _digp->pubkey_algo == 0) {
00491 _digp->hashlen = sizeof(*v) + plen;
00492 _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
00493 }
00494 (void) pgpPrtSubType(p, plen, v->sigtype);
00495 p += plen;
00496
00497 plen = pgpGrab(p,2);
00498 p += 2;
00499
00500 if ((p + plen) > (pp->h + pp->hlen))
00501 return 1;
00502
00503 if (_pgp_debug && _pgp_print)
00504 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
00505 (void) pgpPrtSubType(p, plen, v->sigtype);
00506 p += plen;
00507
00508 plen = pgpGrab(p,2);
00509 pgpPrtHex(" signhash16", p, 2);
00510 pgpPrtNL();
00511
00512 if (_digp && _digp->pubkey_algo == 0) {
00513 _digp->version = v->version;
00514 _digp->sigtype = v->sigtype;
00515 _digp->pubkey_algo = v->pubkey_algo;
00516 _digp->hash_algo = v->hash_algo;
00517 memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
00518 }
00519
00520 p += 2;
00521 if (p > (pp->h + pp->hlen))
00522 return 1;
00523
00524 rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
00525 } break;
00526 default:
00527 rc = 1;
00528 break;
00529 }
00530 return rc;
00531 }
00532
00533
00534
00535 static const char * pgpPublicRSA[] = {
00536 " n =",
00537 " e =",
00538 NULL,
00539 };
00540
00541 #ifdef NOTYET
00542
00543 static const char * pgpSecretRSA[] = {
00544 " d =",
00545 " p =",
00546 " q =",
00547 " u =",
00548 NULL,
00549 };
00550 #endif
00551
00552
00553 static const char * pgpPublicDSA[] = {
00554 " p =",
00555 " q =",
00556 " g =",
00557 " y =",
00558 NULL,
00559 };
00560
00561 #ifdef NOTYET
00562
00563 static const char * pgpSecretDSA[] = {
00564 " x =",
00565 NULL,
00566 };
00567 #endif
00568
00569
00570 static const char * pgpPublicELGAMAL[] = {
00571 " p =",
00572 " g =",
00573 " y =",
00574 NULL,
00575 };
00576
00577 #ifdef NOTYET
00578
00579 static const char * pgpSecretELGAMAL[] = {
00580 " x =",
00581 NULL,
00582 };
00583 #endif
00584
00585
00586 static const uint8_t * pgpPrtPubkeyParams(const pgpPkt pp, uint8_t pubkey_algo,
00587 const uint8_t * p)
00588
00589
00590 {
00591 int i;
00592
00593 for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
00594 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00595 if (i >= 2) break;
00596 if (_dig) {
00597 switch (i) {
00598 case 0:
00599 (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL);
00600 break;
00601 case 1:
00602 (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL);
00603 break;
00604 default:
00605 break;
00606 }
00607 }
00608 pgpPrtStr("", pgpPublicRSA[i]);
00609 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00610 if (i >= 4) break;
00611 if (_dig) {
00612 switch (i) {
00613 case 0:
00614 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
00615 break;
00616 case 1:
00617 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
00618 break;
00619 case 2:
00620 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
00621 break;
00622 case 3:
00623 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL);
00624 break;
00625 default:
00626 break;
00627 }
00628 }
00629 pgpPrtStr("", pgpPublicDSA[i]);
00630 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
00631 if (i >= 3) break;
00632 pgpPrtStr("", pgpPublicELGAMAL[i]);
00633 } else {
00634 if (_pgp_print)
00635 fprintf(stderr, "%7d", i);
00636 }
00637 pgpPrtStr("", pgpMpiStr(p));
00638 pgpPrtNL();
00639 }
00640
00641 return p;
00642 }
00643
00644 static const uint8_t * pgpPrtSeckeyParams(const pgpPkt pp, uint8_t pubkey_algo,
00645 const uint8_t *p)
00646
00647
00648 {
00649 int i;
00650
00651 switch (*p) {
00652 case 0:
00653 pgpPrtVal(" ", pgpSymkeyTbl, *p);
00654 break;
00655 case 255:
00656 p++;
00657 pgpPrtVal(" ", pgpSymkeyTbl, *p);
00658 switch (p[1]) {
00659 case 0x00:
00660 pgpPrtVal(" simple ", pgpHashTbl, p[2]);
00661 p += 2;
00662 break;
00663 case 0x01:
00664 pgpPrtVal(" salted ", pgpHashTbl, p[2]);
00665 pgpPrtHex("", p+3, 8);
00666 p += 10;
00667 break;
00668 case 0x03:
00669 pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
00670
00671 i = (int)(16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
00672
00673 pgpPrtHex("", p+3, 8);
00674 pgpPrtInt(" iter", i);
00675 p += 11;
00676 break;
00677 }
00678 break;
00679 default:
00680 pgpPrtVal(" ", pgpSymkeyTbl, *p);
00681 pgpPrtHex(" IV", p+1, 8);
00682 p += 8;
00683 break;
00684 }
00685 pgpPrtNL();
00686
00687 p++;
00688
00689 #ifdef NOTYET
00690 for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
00691 if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00692 if (pgpSecretRSA[i] == NULL) break;
00693 pgpPrtStr("", pgpSecretRSA[i]);
00694 } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00695 if (pgpSecretDSA[i] == NULL) break;
00696 pgpPrtStr("", pgpSecretDSA[i]);
00697 } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
00698 if (pgpSecretELGAMAL[i] == NULL) break;
00699 pgpPrtStr("", pgpSecretELGAMAL[i]);
00700 } else {
00701 if (_pgp_print)
00702 fprintf(stderr, "%7d", i);
00703 }
00704 pgpPrtStr("", pgpMpiStr(p));
00705 pgpPrtNL();
00706 }
00707 #else
00708 pgpPrtHex(" secret", p, (pp->hlen - (p - pp->h) - 2));
00709 pgpPrtNL();
00710 p += (pp->hlen - (p - pp->h) - 2);
00711 #endif
00712 pgpPrtHex(" checksum", p, 2);
00713 pgpPrtNL();
00714
00715 return p;
00716 }
00717
00718 int pgpPrtKey(const pgpPkt pp)
00719
00720
00721 {
00722 uint8_t version = pp->h[0];
00723 const uint8_t * p;
00724 unsigned plen;
00725 time_t t;
00726 int rc;
00727
00728 switch (version) {
00729 case 3:
00730 { pgpPktKeyV3 v = (pgpPktKeyV3)pp->h;
00731 pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
00732 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00733 t = pgpGrab(v->time, sizeof(v->time));
00734 if (_pgp_print)
00735 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00736 plen = pgpGrab(v->valid, sizeof(v->valid));
00737 if (plen != 0)
00738 fprintf(stderr, " valid %u days", plen);
00739 pgpPrtNL();
00740
00741 if (_digp && _digp->tag == pp->tag) {
00742 _digp->version = v->version;
00743 memcpy(_digp->time, v->time, sizeof(_digp->time));
00744 _digp->pubkey_algo = v->pubkey_algo;
00745 }
00746
00747 p = ((uint8_t *)v) + sizeof(*v);
00748 p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
00749 rc = 0;
00750 } break;
00751 case 4:
00752 { pgpPktKeyV4 v = (pgpPktKeyV4)pp->h;
00753 pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
00754 pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00755 t = pgpGrab(v->time, sizeof(v->time));
00756 if (_pgp_print)
00757 fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00758 pgpPrtNL();
00759
00760 if (_digp && _digp->tag == pp->tag) {
00761 _digp->version = v->version;
00762 memcpy(_digp->time, v->time, sizeof(_digp->time));
00763 _digp->pubkey_algo = v->pubkey_algo;
00764 }
00765
00766 p = ((uint8_t *)v) + sizeof(*v);
00767 p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
00768 if (!(pp->tag == PGPTAG_PUBLIC_KEY || pp->tag == PGPTAG_PUBLIC_SUBKEY))
00769 p = pgpPrtSeckeyParams(pp, v->pubkey_algo, p);
00770 rc = 0;
00771 } break;
00772 default:
00773 rc = 1;
00774 break;
00775 }
00776 return rc;
00777 }
00778
00779 int pgpPrtUserID(const pgpPkt pp)
00780
00781
00782 {
00783 pgpPrtVal("", pgpTagTbl, pp->tag);
00784 if (_pgp_print)
00785 fprintf(stderr, " \"%.*s\"", (int)pp->hlen, (const char *)pp->h);
00786 pgpPrtNL();
00787 if (_digp) {
00788 char * t = memcpy(xmalloc(pp->hlen+1), pp->h, pp->hlen);
00789 t[pp->hlen] = '\0';
00790 _digp->userid = _free(_digp->userid);
00791 _digp->userid = t;
00792 }
00793 return 0;
00794 }
00795
00796 int pgpPrtComment(const pgpPkt pp)
00797 {
00798 const uint8_t * h = pp->h;
00799 int i = pp->hlen;
00800
00801 pgpPrtVal("", pgpTagTbl, pp->tag);
00802 if (_pgp_print)
00803 fprintf(stderr, " ");
00804 while (i > 0) {
00805 int j;
00806 if (*h >= (uint8_t)' ' && *h <= (uint8_t)'z') {
00807 j = 0;
00808 while (j < i && h[j] != (uint8_t)'\0')
00809 j++;
00810 while (j < i && h[j] == (uint8_t)'\0')
00811 j++;
00812 if (_pgp_print && j)
00813 fprintf(stderr, "%.*s", (int)strlen((const char *)h), (const char *)h);
00814 } else {
00815 pgpPrtHex("", h, i);
00816 j = i;
00817 }
00818 i -= j;
00819 h += j;
00820 }
00821 pgpPrtNL();
00822 return 0;
00823 }
00824
00825 int pgpPktLen(const uint8_t *pkt, size_t pleft, pgpPkt pp)
00826 {
00827 unsigned int val = (unsigned int)*pkt;
00828 unsigned int plen;
00829
00830 memset(pp, 0, sizeof(*pp));
00831
00832 if (!(val & 0x80))
00833 return -1;
00834
00835 if (val & 0x40) {
00836 pp->tag = (val & 0x3f);
00837 plen = pgpLen(pkt+1, &pp->hlen);
00838 } else {
00839 pp->tag = (val >> 2) & 0xf;
00840 plen = (1 << (val & 0x3));
00841 pp->hlen = pgpGrab(pkt+1, plen);
00842 }
00843
00844 pp->pktlen = 1 + plen + pp->hlen;
00845 if (pleft > 0 && pp->pktlen > (unsigned)pleft)
00846 return -1;
00847
00848
00849 pp->h = pkt + 1 + plen;
00850
00851
00852 return pp->pktlen;
00853 }
00854
00855 int pgpPubkeyFingerprint(const uint8_t * pkt, size_t pktlen, uint8_t * keyid)
00856 {
00857 pgpPkt pp = alloca(sizeof(*pp));
00858 int rc = pgpPktLen(pkt, pktlen, pp);
00859 const uint8_t * se;
00860 int i;
00861
00862
00863 if (pp->tag != PGPTAG_PUBLIC_KEY)
00864 return -1;
00865
00866
00867 switch (pp->h[0]) {
00868 default: return -1;
00869 case 3:
00870 { pgpPktKeyV3 v = (pgpPktKeyV3) (pp->h);
00871 se = (uint8_t *)(v + 1);
00872 switch (v->pubkey_algo) {
00873 default: return -1;
00874 case PGPPUBKEYALGO_RSA:
00875 se += pgpMpiLen(se);
00876 memmove(keyid, (se-8), 8);
00877 break;
00878 }
00879 } break;
00880 case 4:
00881 { pgpPktKeyV4 v = (pgpPktKeyV4) (pp->h);
00882 uint8_t * d = NULL;
00883 size_t dlen = 0;
00884
00885 se = (uint8_t *)(v + 1);
00886 switch (v->pubkey_algo) {
00887 default: return -1;
00888 case PGPPUBKEYALGO_RSA:
00889 for (i = 0; i < 2; i++)
00890 se += pgpMpiLen(se);
00891 break;
00892 case PGPPUBKEYALGO_DSA:
00893 for (i = 0; i < 4; i++)
00894 se += pgpMpiLen(se);
00895 break;
00896 }
00897 { DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
00898 (void) rpmDigestUpdate(ctx, pkt, (se-pkt));
00899 (void) rpmDigestFinal(ctx, &d, &dlen, 0);
00900 }
00901
00902 memmove(keyid, (d + (dlen-8)), 8);
00903 d = _free(d);
00904 } break;
00905 }
00906 rc = 0;
00907 return rc;
00908 }
00909
00910 int pgpExtractPubkeyFingerprint(const char * b64pkt, uint8_t * keyid)
00911 {
00912 const uint8_t * pkt;
00913 size_t pktlen;
00914
00915 if (b64decode(b64pkt, (void **)&pkt, &pktlen))
00916 return -1;
00917 (void) pgpPubkeyFingerprint(pkt, (unsigned int)pktlen, keyid);
00918 pkt = _free(pkt);
00919 return 8;
00920 }
00921
00922 int pgpPrtPkt(const uint8_t * pkt, size_t pleft)
00923 {
00924 pgpPkt pp = alloca(sizeof(*pp));
00925 int rc = pgpPktLen(pkt, pleft, pp);
00926
00927 if (rc < 0)
00928 return rc;
00929
00930 switch (pp->tag) {
00931 case PGPTAG_SIGNATURE:
00932 rc = pgpPrtSig(pp);
00933 break;
00934 case PGPTAG_PUBLIC_KEY:
00935
00936 if (_digp) {
00937
00938 if (!pgpPubkeyFingerprint(pkt, pp->pktlen, _digp->signid))
00939 _digp->saved |= PGPDIG_SAVED_ID;
00940 else
00941 memset(_digp->signid, 0, sizeof(_digp->signid));
00942
00943 }
00944
00945 case PGPTAG_PUBLIC_SUBKEY:
00946 rc = pgpPrtKey(pp);
00947 break;
00948 case PGPTAG_SECRET_KEY:
00949 case PGPTAG_SECRET_SUBKEY:
00950 rc = pgpPrtKey(pp);
00951 break;
00952 case PGPTAG_USER_ID:
00953 rc = pgpPrtUserID(pp);
00954 break;
00955 case PGPTAG_COMMENT:
00956 case PGPTAG_COMMENT_OLD:
00957 rc = pgpPrtComment(pp);
00958 break;
00959
00960 case PGPTAG_RESERVED:
00961 case PGPTAG_PUBLIC_SESSION_KEY:
00962 case PGPTAG_SYMMETRIC_SESSION_KEY:
00963 case PGPTAG_COMPRESSED_DATA:
00964 case PGPTAG_SYMMETRIC_DATA:
00965 case PGPTAG_MARKER:
00966 case PGPTAG_LITERAL_DATA:
00967 case PGPTAG_TRUST:
00968 case PGPTAG_PHOTOID:
00969 case PGPTAG_ENCRYPTED_MDC:
00970 case PGPTAG_MDC:
00971 case PGPTAG_PRIVATE_60:
00972 case PGPTAG_PRIVATE_62:
00973 case PGPTAG_CONTROL:
00974 default:
00975 pgpPrtVal("", pgpTagTbl, pp->tag);
00976 pgpPrtHex("", pp->h, pp->hlen);
00977 pgpPrtNL();
00978 rc = 0;
00979 break;
00980 }
00981
00982 return (rc ? -1 : pp->pktlen);
00983 }
00984
00985
00986 pgpVSFlags pgpDigVSFlags;
00987
00988 pgpDig XpgpDigUnlink(pgpDig dig, const char * msg, const char * fn, unsigned ln)
00989 {
00990 if (dig == NULL) return NULL;
00991
00992 if (_pgp_debug && msg != NULL)
00993 fprintf(stderr, "--> dig %p -- %d %s at %s:%u\n", dig, dig->nrefs, msg, fn, ln);
00994
00995 dig->nrefs--;
00996 return NULL;
00997 }
00998
00999 pgpDig XpgpDigLink(pgpDig dig, const char * msg, const char * fn, unsigned ln)
01000 {
01001 if (dig == NULL) return NULL;
01002 dig->nrefs++;
01003
01004
01005 if (_pgp_debug && msg != NULL)
01006 fprintf(stderr, "--> dig %p ++ %d %s at %s:%u\n", dig, dig->nrefs, msg, fn, ln);
01007
01008
01009 return dig;
01010 }
01011
01012 void pgpDigClean(pgpDig dig)
01013 {
01014 if (dig != NULL) {
01015 int i;
01016 dig->signature.userid = _free(dig->signature.userid);
01017 dig->pubkey.userid = _free(dig->pubkey.userid);
01018 memset(&dig->dops, 0, sizeof(dig->dops));
01019 memset(&dig->sops, 0, sizeof(dig->sops));
01020 dig->ppkts = _free(dig->ppkts);
01021 dig->npkts = 0;
01022 dig->signature.hash = _free(dig->signature.hash);
01023 dig->pubkey.hash = _free(dig->pubkey.hash);
01024
01025 for (i = 0; i < 4; i++) {
01026 dig->signature.params[i] = _free(dig->signature.params[i]);
01027 dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
01028 }
01029
01030
01031 memset(&dig->signature, 0, sizeof(dig->signature));
01032 memset(&dig->pubkey, 0, sizeof(dig->pubkey));
01033
01034 dig->md5 = _free(dig->md5);
01035 dig->sha1 = _free(dig->sha1);
01036
01037 pgpImplClean(dig->impl);
01038
01039 }
01040
01041 return;
01042
01043 }
01044
01045 pgpDig pgpDigFree(pgpDig dig)
01046 {
01047 if (dig != NULL) {
01048
01049
01050 if (dig->nrefs > 1)
01051 return pgpDigUnlink(dig, "pgpDigFree");
01052
01053
01054
01055 dig->sig = _free(dig->sig);
01056
01057
01058 pgpDigClean(dig);
01059
01060 if (dig->hdrsha1ctx != NULL)
01061 (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
01062 dig->hdrsha1ctx = NULL;
01063
01064 if (dig->sha1ctx != NULL)
01065 (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
01066 dig->sha1ctx = NULL;
01067
01068 #ifdef NOTYET
01069 if (dig->hdrmd5ctx != NULL)
01070 (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
01071 dig->hdrmd5ctx = NULL;
01072 #endif
01073
01074 if (dig->md5ctx != NULL)
01075 (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
01076 dig->md5ctx = NULL;
01077
01078 dig->impl = pgpImplFree(dig->impl);
01079
01080 (void) pgpDigUnlink(dig, "pgpDigFree");
01081
01082
01083 memset(dig, 0, sizeof(*dig));
01084 dig = _free(dig);
01085
01086 }
01087 return NULL;
01088 }
01089
01090 pgpDig pgpDigNew( pgpVSFlags vsflags)
01091 {
01092 pgpDig dig = xcalloc(1, sizeof(*dig));
01093 dig->vsflags = pgpDigVSFlags;
01094 dig->impl = pgpImplInit();
01095 return pgpDigLink(dig, "pgpDigNew");
01096 }
01097
01098 pgpDigParams pgpGetSignature(pgpDig dig)
01099 {
01100 return (dig ? &dig->signature : NULL);
01101 }
01102
01103 pgpDigParams pgpGetPubkey(pgpDig dig)
01104 {
01105 return (dig ? &dig->pubkey : NULL);
01106 }
01107
01108 uint32_t pgpGetSigtag(pgpDig dig)
01109 {
01110 return (dig ? dig->sigtag : 0);
01111 }
01112
01113 uint32_t pgpGetSigtype(pgpDig dig)
01114 {
01115 return (dig ? dig->sigtype : 0);
01116 }
01117
01118 const void * pgpGetSig(pgpDig dig)
01119 {
01120 return (dig ? dig->sig : NULL);
01121 }
01122
01123 uint32_t pgpGetSiglen(pgpDig dig)
01124 {
01125 return (dig ? dig->siglen : 0);
01126 }
01127
01128 int pgpSetSig(pgpDig dig,
01129 uint32_t sigtag, uint32_t sigtype, const void * sig, uint32_t siglen)
01130 {
01131 if (dig != NULL) {
01132 dig->sigtag = sigtag;
01133 dig->sigtype = (sig ? sigtype : 0);
01134
01135 dig->sig = sig;
01136
01137 dig->siglen = siglen;
01138 }
01139 return 0;
01140 }
01141
01142 void * pgpStatsAccumulator(pgpDig dig, int opx)
01143 {
01144 void * sw = NULL;
01145 switch (opx) {
01146 case 10:
01147 sw = &dig->dops;
01148 break;
01149 case 11:
01150 sw = &dig->sops;
01151 break;
01152 }
01153 return sw;
01154 }
01155
01156 int pgpSetFindPubkey(pgpDig dig,
01157 int (*findPubkey) (void *ts, void *dig), void * _ts)
01158 {
01159 if (dig) {
01160
01161 dig->findPubkey = findPubkey;
01162
01163
01164 dig->_ts = _ts;
01165
01166 }
01167 return 0;
01168 }
01169
01170 int pgpFindPubkey(pgpDig dig)
01171 {
01172 int rc = 1;
01173 if (dig && dig->findPubkey && dig->_ts)
01174 rc = (*dig->findPubkey) (dig->_ts, dig);
01175 return rc;
01176 }
01177
01178 static int pgpGrabPkts(const uint8_t * pkts, size_t pktlen,
01179 uint8_t *** pppkts, int * pnpkts)
01180
01181 {
01182 pgpPkt pp = alloca(sizeof(*pp));
01183 const uint8_t * p;
01184 size_t pleft;
01185 size_t len;
01186 int npkts = 0;
01187 uint8_t ** ppkts;
01188
01189 for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
01190 if (pgpPktLen(p, pleft, pp) < 0)
01191 return -1;
01192 len = pp->pktlen;
01193 npkts++;
01194 }
01195 if (npkts <= 0)
01196 return -2;
01197
01198 ppkts = xcalloc(npkts, sizeof(*ppkts));
01199
01200 npkts = 0;
01201 for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
01202
01203 if (pgpPktLen(p, pleft, pp) < 0)
01204 return -1;
01205 len = pp->pktlen;
01206 ppkts[npkts++] = (uint8_t *) p;
01207 }
01208
01209 if (pppkts != NULL)
01210 *pppkts = ppkts;
01211 else
01212 ppkts = _free(ppkts);
01213
01214 if (pnpkts != NULL)
01215 *pnpkts = npkts;
01216
01217 return 0;
01218 }
01219
01220
01221 int pgpPrtPkts(const uint8_t * pkts, size_t pktlen, pgpDig dig, int printing)
01222
01223
01224 {
01225 pgpPkt pp = alloca(sizeof(*pp));
01226 unsigned int val = (unsigned int)*pkts;
01227 size_t pleft;
01228 int len;
01229 uint8_t ** ppkts = NULL;
01230 int npkts;
01231 int i;
01232
01233 _pgp_print = printing;
01234 _dig = pgpDigLink(dig, "pgpPrtPkts");
01235 if (dig != NULL && (val & 0x80)) {
01236 pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
01237 _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
01238 _digp->tag = tag;
01239 } else
01240 _digp = NULL;
01241
01242 if (pgpGrabPkts(pkts, pktlen, &ppkts, &npkts) || ppkts == NULL) {
01243 _dig = pgpDigFree(_dig);
01244 return -1;
01245 }
01246
01247 if (ppkts != NULL)
01248 for (i = 0, pleft = pktlen; i < npkts; i++, pleft -= len) {
01249 len = pgpPktLen(ppkts[i], pleft, pp);
01250 len = pgpPrtPkt(ppkts[i], pp->pktlen);
01251 }
01252
01253 if (dig != NULL) {
01254 dig->ppkts = _free(dig->ppkts);
01255 dig->ppkts = ppkts;
01256 dig->npkts = npkts;
01257 } else
01258 ppkts = _free(ppkts);
01259
01260 _dig = pgpDigFree(_dig);
01261 return 0;
01262 }
01263
01264
01265 pgpArmor pgpReadPkts(const char * fn, const uint8_t ** pkt, size_t * pktlen)
01266 {
01267 uint8_t * b = NULL;
01268 ssize_t blen;
01269 const char * enc = NULL;
01270 const char * crcenc = NULL;
01271 uint8_t * dec;
01272 uint8_t * crcdec;
01273 size_t declen;
01274 size_t crclen;
01275 uint32_t crcpkt, crc;
01276 const char * armortype = NULL;
01277 char * t, * te;
01278 int pstate = 0;
01279 pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;
01280 pgpTag tag = 0;
01281 int rc;
01282
01283 rc = rpmioSlurp(fn, &b, &blen);
01284 if (rc || b == NULL || blen <= 0) {
01285 goto exit;
01286 }
01287
01288
01289 if (pgpIsPkt(b, &tag)) {
01290 switch (tag) {
01291 default: ec = PGPARMOR_NONE; break;
01292 case PGPTAG_PUBLIC_KEY: ec = PGPARMOR_PUBKEY; break;
01293 case PGPTAG_SIGNATURE: ec = PGPARMOR_SIGNATURE; break;
01294 #ifdef NOTYET
01295 case PGPTAG_SECRET_KEY: ec = PGPARMOR_SECKEY; break;
01296 case PGPTAG_FOO: ec = PGPARMOR_MESSAGE; break;
01297 case PGPTAG_FOO: ec = PGPARMOR_SIGNED_MESSAGE; break;
01298 case PGPTAG_FOO: ec = PGPARMOR_FILE; break;
01299 case PGPTAG_FOO: ec = PGPARMOR_PRIVKEY; break;
01300 #endif
01301 }
01302
01303 if (ec != PGPARMOR_NONE) {
01304 pgpPkt pp = alloca(sizeof(*pp));
01305 blen = pgpPktLen(b, blen, pp);
01306 }
01307 goto exit;
01308 }
01309
01310 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
01311
01312
01313 for (t = (char *)b; t && *t; t = te) {
01314 if ((te = strchr(t, '\n')) == NULL)
01315 te = t + strlen(t);
01316 else
01317 te++;
01318
01319 switch (pstate) {
01320 case 0:
01321 armortype = NULL;
01322 if (!TOKEQ(t, "-----BEGIN PGP "))
01323 continue;
01324 t += sizeof("-----BEGIN PGP ")-1;
01325
01326 rc = pgpValTok(pgpArmorTbl, t, te);
01327 if (rc < 0) {
01328 ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE;
01329 goto exit;
01330 }
01331
01332 if (rc == PGPARMOR_SIGNED_MESSAGE)
01333 continue;
01334 ec = rc;
01335 armortype = t;
01336
01337 t = strchr(t, '\n');
01338 if (t == NULL)
01339 continue;
01340 if (t[-1] == '\r')
01341 --t;
01342 t -= (sizeof("-----")-1);
01343 if (!TOKEQ(t, "-----"))
01344 continue;
01345 *t = '\0';
01346 pstate++;
01347 break;
01348 case 1:
01349 enc = NULL;
01350 rc = pgpValTok(pgpArmorKeyTbl, t, te);
01351 if (rc >= 0)
01352 continue;
01353 if (!(*t == '\n' || *t == '\r')) {
01354 pstate = 0;
01355 continue;
01356 }
01357 enc = te;
01358 pstate++;
01359 break;
01360 case 2:
01361 crcenc = NULL;
01362 if (*t != '=')
01363 continue;
01364 *t++ = '\0';
01365 crcenc = t;
01366 pstate++;
01367 break;
01368 case 3:
01369 pstate = 0;
01370 if (!TOKEQ(t, "-----END PGP ")) {
01371 ec = PGPARMOR_ERR_NO_END_PGP;
01372 goto exit;
01373 }
01374 *t = '\0';
01375 t += sizeof("-----END PGP ")-1;
01376 if (t >= te) continue;
01377
01378 if (armortype == NULL)
01379 continue;
01380 rc = strncmp(t, armortype, strlen(armortype));
01381 if (rc)
01382 continue;
01383
01384 t += strlen(armortype);
01385 if (t >= te) continue;
01386
01387 if (!TOKEQ(t, "-----")) {
01388 ec = PGPARMOR_ERR_NO_END_PGP;
01389 goto exit;
01390 }
01391 t += (sizeof("-----")-1);
01392 if (t >= te) continue;
01393
01394 if (!(*t == '\n' || *t == '\r')) continue;
01395
01396 crcdec = NULL;
01397 crclen = 0;
01398 if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
01399 ec = PGPARMOR_ERR_CRC_DECODE;
01400 goto exit;
01401 }
01402 crcpkt = pgpGrab(crcdec, crclen);
01403 crcdec = _free(crcdec);
01404 dec = NULL;
01405 declen = 0;
01406 if (b64decode(enc, (void **)&dec, &declen) != 0) {
01407 ec = PGPARMOR_ERR_BODY_DECODE;
01408 goto exit;
01409 }
01410 crc = pgpCRC(dec, declen);
01411 if (crcpkt != crc) {
01412 ec = PGPARMOR_ERR_CRC_CHECK;
01413 goto exit;
01414 }
01415 b = _free(b);
01416 b = dec;
01417 blen = declen;
01418 goto exit;
01419 break;
01420 }
01421 }
01422 ec = PGPARMOR_NONE;
01423
01424 exit:
01425 if (ec > PGPARMOR_NONE && pkt)
01426 *pkt = b;
01427 else if (b != NULL)
01428 b = _free(b);
01429 if (pktlen)
01430 *pktlen = blen;
01431 return ec;
01432 }
01433
01434 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
01435 {
01436 const char * enc;
01437 char * t;
01438 size_t nt;
01439 char * val;
01440 int lc;
01441
01442 nt = ((ns + 2) / 3) * 4;
01443
01444
01445 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
01446 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
01447 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
01448 ++lc;
01449 nt += lc * strlen(b64encode_eolstr);
01450 }
01451
01452
01453 nt += 512;
01454
01455 val = t = xmalloc(nt + 1);
01456 *t = '\0';
01457 t = stpcpy(t, "-----BEGIN PGP ");
01458 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
01459
01460 t = stpcpy( stpcpy(t, "-----\nVersion: RPM "), VERSION);
01461
01462 t = stpcpy(t, " (BeeCrypt)\n\n");
01463
01464 if ((enc = b64encode(s, ns)) != NULL) {
01465 t = stpcpy(t, enc);
01466 enc = _free(enc);
01467 if ((enc = b64crc(s, ns)) != NULL) {
01468 *t++ = '=';
01469 t = stpcpy(t, enc);
01470 enc = _free(enc);
01471 }
01472 }
01473
01474 t = stpcpy(t, "-----END PGP ");
01475 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
01476 t = stpcpy(t, "-----\n");
01477
01478
01479 return val;
01480
01481 }
01482
01483 int pgpHashAlgoStringToNumber(const char *name, size_t name_len)
01484 {
01485 size_t i;
01486
01487 if (name == NULL)
01488 return -1;
01489 if (name_len == 0)
01490 name_len = strlen(name);
01491 for (i = 0; i < sizeof(pgpHashTbl)/sizeof(pgpHashTbl[0]); i++)
01492 if (xstrncasecmp(name, pgpHashTbl[i].str, name_len) == 0)
01493 return pgpHashTbl[i].val;
01494 return -1;
01495 }
01496