rpm
5.2.1
|
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 = 0; 00027 00028 /*@unchecked@*/ 00029 int _pgp_print = 0; 00030 00031 /*@unchecked@*/ 00032 pgpImplVecs_t * pgpImplVecs = 00033 /* explicit selection (order DOES NOT matter here) */ 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 /* implict selection (order DOES matter) */ 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 /*@unchecked@*/ /*@refcounted@*/ /*@relnull@*/ 00056 static pgpDig _dig = NULL; 00057 00058 /*@unchecked@*/ /*@null@*/ 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 /*@-exportlocal -exportheadervar@*/ 00138 /*@observer@*/ /*@unchecked@*/ 00139 struct pgpValTbl_s pgpKeyServerPrefsTbl[] = { 00140 { 0x80, "No-modify" }, 00141 { -1, "Unknown key server preference" }, 00142 }; 00143 /*@=exportlocal =exportheadervar@*/ 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 /*@globals fileSystem @*/ 00233 /*@modifies fileSystem @*/ 00234 { 00235 if (!_pgp_print) return; 00236 fprintf(stderr, "\n"); 00237 } 00238 00239 static void pgpPrtInt(const char *pre, int i) 00240 /*@globals fileSystem @*/ 00241 /*@modifies fileSystem @*/ 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 /*@globals fileSystem @*/ 00251 /*@modifies fileSystem @*/ 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 /*@globals fileSystem @*/ 00261 /*@modifies fileSystem @*/ 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 /*@globals fileSystem @*/ 00271 /*@modifies fileSystem @*/ 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: /* preferred symmetric algorithms */ 00296 for (i = 1; i < plen; i++) 00297 pgpPrtVal(" ", pgpSymkeyTbl, p[i]); 00298 /*@switchbreak@*/ break; 00299 case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */ 00300 for (i = 1; i < plen; i++) 00301 pgpPrtVal(" ", pgpHashTbl, p[i]); 00302 /*@switchbreak@*/ break; 00303 case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */ 00304 for (i = 1; i < plen; i++) 00305 pgpPrtVal(" ", pgpCompressionTbl, p[i]); 00306 /*@switchbreak@*/ break; 00307 case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */ 00308 for (i = 1; i < plen; i++) 00309 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]); 00310 /*@switchbreak@*/ break; 00311 case PGPSUBTYPE_SIG_CREATE_TIME: 00312 /*@-mods -mayaliasunique @*/ 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 /*@=mods =mayaliasunique @*/ 00320 /*@fallthrough@*/ 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 /*@switchbreak@*/ break; 00330 00331 case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */ 00332 /*@-mods -mayaliasunique @*/ 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 /*@=mods =mayaliasunique @*/ 00340 /*@fallthrough@*/ 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 /*@switchbreak@*/ break; 00371 } 00372 pgpPrtNL(); 00373 p += plen; 00374 hlen -= plen; 00375 } 00376 return 0; 00377 } 00378 00379 /*@-varuse =readonlytrans -nullassign @*/ 00380 /*@observer@*/ /*@unchecked@*/ 00381 static const char * pgpSigRSA[] = { 00382 " m**d =", 00383 NULL, 00384 }; 00385 00386 /*@observer@*/ /*@unchecked@*/ 00387 static const char * pgpSigDSA[] = { 00388 " r =", 00389 " s =", 00390 NULL, 00391 }; 00392 /*@=varuse =readonlytrans =nullassign @*/ 00393 00394 static int pgpPrtSigParams(const pgpPkt pp, pgpPubkeyAlgo pubkey_algo, 00395 pgpSigType sigtype, const rpmuint8_t * p) 00396 /*@globals fileSystem @*/ 00397 /*@modifies fileSystem @*/ 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: /* m**d */ 00412 xx = pgpImplMpiItem(pgpSigRSA[i], _dig, 10+i, p, pend); 00413 /*@switchbreak@*/ break; 00414 default: 00415 xx = 1; 00416 /*@switchbreak@*/ 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: /* r */ 00429 xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend); 00430 /*@switchbreak@*/ break; 00431 case 1: /* s */ 00432 xx = pgpImplMpiItem(pgpSigDSA[i], _dig, 20+i, p, pend); 00433 /*@switchbreak@*/ break; 00434 default: 00435 xx = 1; 00436 /*@switchbreak@*/ 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 /*@globals _digp @*/ 00454 /*@modifies *_digp @*/ 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 /*@-varuse =readonlytrans -nullassign @*/ 00562 /*@observer@*/ /*@unchecked@*/ 00563 static const char * pgpPublicRSA[] = { 00564 " n =", 00565 " e =", 00566 NULL, 00567 }; 00568 00569 #ifdef NOTYET 00570 /*@observer@*/ /*@unchecked@*/ 00571 static const char * pgpSecretRSA[] = { 00572 " d =", 00573 " p =", 00574 " q =", 00575 " u =", 00576 NULL, 00577 }; 00578 #endif 00579 00580 /*@observer@*/ /*@unchecked@*/ 00581 static const char * pgpPublicDSA[] = { 00582 " p =", 00583 " q =", 00584 " g =", 00585 " y =", 00586 NULL, 00587 }; 00588 00589 #ifdef NOTYET 00590 /*@observer@*/ /*@unchecked@*/ 00591 static const char * pgpSecretDSA[] = { 00592 " x =", 00593 NULL, 00594 }; 00595 #endif 00596 00597 /*@observer@*/ /*@unchecked@*/ 00598 static const char * pgpPublicELGAMAL[] = { 00599 " p =", 00600 " g =", 00601 " y =", 00602 NULL, 00603 }; 00604 00605 #ifdef NOTYET 00606 /*@observer@*/ /*@unchecked@*/ 00607 static const char * pgpSecretELGAMAL[] = { 00608 " x =", 00609 NULL, 00610 }; 00611 #endif 00612 /*@=varuse =readonlytrans =nullassign @*/ 00613 00614 static const rpmuint8_t * pgpPrtPubkeyParams(const pgpPkt pp, 00615 pgpPubkeyAlgo pubkey_algo, /*@returned@*/ const rpmuint8_t * p) 00616 /*@globals fileSystem, internalState @*/ 00617 /*@modifies fileSystem, internalState @*/ 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: /* n */ 00627 (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL); 00628 /*@switchbreak@*/ break; 00629 case 1: /* e */ 00630 (void) pgpImplMpiItem(pgpPublicRSA[i], _dig, 30+i, p, NULL); 00631 /*@switchbreak@*/ break; 00632 default: 00633 /*@switchbreak@*/ 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: /* p */ 00642 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL); 00643 /*@switchbreak@*/ break; 00644 case 1: /* q */ 00645 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL); 00646 /*@switchbreak@*/ break; 00647 case 2: /* g */ 00648 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL); 00649 /*@switchbreak@*/ break; 00650 case 3: /* y */ 00651 (void) pgpImplMpiItem(pgpPublicDSA[i], _dig, 40+i, p, NULL); 00652 /*@switchbreak@*/ break; 00653 default: 00654 /*@switchbreak@*/ 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 /*@unused@*/ rpmuint8_t pubkey_algo, 00674 /*@returned@*/ const rpmuint8_t *p) 00675 /*@globals fileSystem @*/ 00676 /*@modifies fileSystem @*/ 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 /*@innerbreak@*/ break; 00692 case 0x01: 00693 pgpPrtVal(" salted ", pgpHashTbl, p[2]); 00694 pgpPrtHex("", p+3, 8); 00695 p += 10; 00696 /*@innerbreak@*/ 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 /*@innerbreak@*/ 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 /* XXX encrypted MPI's need to be handled. */ 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 /*@globals _digp @*/ 00747 /*@modifies *_digp @*/ 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 /*@globals _digp @*/ 00808 /*@modifies *_digp @*/ 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 /* XXX can't deal with these. */ 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 /*@-assignexpose -temptrans @*/ 00876 pp->h = pkt + 1 + plen; 00877 /*@=assignexpose =temptrans @*/ 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 /* Pubkeys only please. */ 00890 if (pp->tag != PGPTAG_PUBLIC_KEY) 00891 return -1; 00892 00893 /* Choose the correct keyid. */ 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 /*@innerbreak@*/ 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 /*@innerbreak@*/ break; 00919 case PGPPUBKEYALGO_DSA: 00920 for (i = 0; i < 4; i++) 00921 se += pgpMpiLen(se); 00922 /*@innerbreak@*/ 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; /* on error */ 00944 (void) pgpPubkeyFingerprint(pkt, (unsigned int)pktlen, keyid); 00945 pkt = _free(pkt); 00946 return 8; /* no. of bytes of pubkey signid */ 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 /* Get the public key fingerprint. */ 00963 if (_digp) { 00964 /*@-mods@*/ 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 /*@=mods@*/ 00970 } 00971 /*@fallthrough@*/ 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 /*@unchecked@*/ 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 /*@-unqualifiedtrans@*/ /* FIX: double indirection */ 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 /*@=unqualifiedtrans@*/ 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 /*@-nullstate@*/ 01044 return; 01045 /*@=nullstate@*/ 01046 } 01047 01048 static void pgpDigFini(void * __dig) 01049 /*@globals fileSystem, internalState @*/ 01050 /*@modifies __dig, fileSystem, internalState @*/ 01051 { 01052 pgpDig dig = __dig; 01053 01054 /* Lose the header tag data. */ 01055 /* XXX this free should be done somewhere else. */ 01056 dig->sig = _free(dig->sig); 01057 01058 /* XXX there's a recursion here ... release and reacquire the lock */ 01059 #ifndef BUGGY 01060 yarnRelease(dig->_item.use); 01061 #endif 01062 /* Dump the signature/pubkey data. */ 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 /*@unchecked@*/ /*@only@*/ /*@null@*/ 01091 rpmioPool _digPool; 01092 01093 static pgpDig digGetPool(/*@null@*/ rpmioPool pool) 01094 /*@globals _digPool, fileSystem @*/ 01095 /*@modifies pool, _digPool, fileSystem @*/ 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(/*@unused@*/ 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 /*@-assignexpose -kepttrans@*/ 01152 dig->sig = sig; 01153 /*@=assignexpose =kepttrans@*/ 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: /* RPMTS_OP_DIGEST */ 01164 sw = &dig->dops; 01165 break; 01166 case 11: /* RPMTS_OP_SIGNATURE */ 01167 sw = &dig->sops; 01168 break; 01169 } 01170 return sw; 01171 } 01172 01173 int pgpSetFindPubkey(pgpDig dig, 01174 int (*findPubkey) (void *ts, /*@null@*/ void *dig), void * _ts) 01175 { 01176 if (dig) { 01177 /*@-assignexpose@*/ 01178 dig->findPubkey = findPubkey; 01179 /*@=assignexpose@*/ 01180 /*@-dependenttrans@*/ 01181 dig->_ts = _ts; 01182 /*@=dependenttrans@*/ 01183 } 01184 return 0; 01185 } 01186 01187 int pgpFindPubkey(pgpDig dig) 01188 { 01189 int rc = 1; /* XXX RPMRC_NOTFOUND */ 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 /*@out@*/ rpmuint8_t *** pppkts, /*@out@*/ int * pnpkts) 01197 /*@modifies *pppkts, *pnpkts @*/ 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 /*@-globstate -incondefs -nullderef @*/ /* _dig annotations are not correct. */ 01238 int pgpPrtPkts(const rpmuint8_t * pkts, size_t pktlen, pgpDig dig, int printing) 01239 /*@globals _dig, _digp, _pgp_print @*/ 01240 /*@modifies _dig, _digp, *_digp, _pgp_print @*/ 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); /* XXX memory leak plugged. */ 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 /*@=globstate =incondefs =nullderef @*/ 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; /* XXX assume failure */ 01296 pgpTag tag = 0; 01297 int rc; 01298 01299 rc = rpmiobSlurp(fn, &iob); 01300 if (rc || iob == NULL) 01301 goto exit; 01302 01303 /* Read unarmored packets. */ 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 /* Truncate blen to actual no. of octets in packet. */ 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 /* Read armored packets, converting to binary. */ 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 /* XXX Ignore clear signed message start. */ 01347 if (rc == PGPARMOR_SIGNED_MESSAGE) 01348 continue; 01349 ec = rc; /* Save the packet type as exit code. */ 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 /*@switchbreak@*/ 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; /* Start of encoded packets */ 01373 pstate++; 01374 /*@switchbreak@*/ break; 01375 case 2: 01376 crcenc = NULL; 01377 if (*t != '=') 01378 continue; 01379 *t++ = '\0'; /* Terminate encoded packets */ 01380 crcenc = t; /* Start of encoded crc */ 01381 pstate++; 01382 /*@switchbreak@*/ 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'; /* Terminate encoded crc */ 01390 t += sizeof("-----END PGP ")-1; 01391 if (t >= te) continue; 01392 01393 if (armortype == NULL) /* XXX can't happen */ 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 /* XXX permitting \r here is not RFC-2440 compliant <shrug> */ 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 /*@notreached@*/ /*@switchbreak@*/ 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; /* XXX iob->b has been stolen */ 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 /*@-globs@*/ 01462 /* Add additional bytes necessary for eol string(s). */ 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 /*@=globs@*/ 01470 01471 nt += 512; /* XXX slop for armor and crc */ 01472 01473 val = t = xmalloc(nt + 1); 01474 *t = '\0'; 01475 t = stpcpy(t, "-----BEGIN PGP "); 01476 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype)); 01477 /*@-globs@*/ 01478 t = stpcpy( stpcpy(t, "-----\nVersion: RPM "), VERSION); 01479 /*@=globs@*/ 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 /*@-globstate@*/ /* XXX b64encode_eolstr needs annotation. */ 01497 return val; 01498 /*@=globstate@*/ 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