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