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