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