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