rpmio/rpmpgp.c

Go to the documentation of this file.
00001 /*@-boundsread@*/
00007 #include "system.h"
00008 #include "rpmio_internal.h"
00009 #include "debug.h"
00010 
00011 /*@access pgpDig @*/
00012 /*@access pgpDigParams @*/
00013 
00014 /*@unchecked@*/
00015 static int _debug = 0;
00016 
00017 /*@unchecked@*/
00018 static int _print = 0;
00019 
00020 /*@unchecked@*/ /*@null@*/
00021 static pgpDig _dig = NULL;
00022 
00023 /*@unchecked@*/ /*@null@*/
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 /*@-exportlocal -exportheadervar@*/
00094 /*@observer@*/ /*@unchecked@*/
00095 struct pgpValTbl_s pgpKeyServerPrefsTbl[] = {
00096     { 0x80,                     "No-modify" },
00097     { -1,                       "Unknown key server preference" },
00098 };
00099 /*@=exportlocal =exportheadervar@*/
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 /*@unused@*/ static inline /*@null@*/ void *
00192 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p)
00193         /*@modifies p @*/
00194 {
00195     if (p != NULL)      free((void *)p);
00196     return NULL;
00197 }
00198 
00199 static void pgpPrtNL(void)
00200         /*@globals fileSystem @*/
00201         /*@modifies fileSystem @*/
00202 {
00203     if (!_print) return;
00204     fprintf(stderr, "\n");
00205 }
00206 
00207 static void pgpPrtInt(const char *pre, int i)
00208         /*@globals fileSystem @*/
00209         /*@modifies fileSystem @*/
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         /*@globals fileSystem @*/
00219         /*@modifies fileSystem @*/
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         /*@globals fileSystem @*/
00229         /*@modifies fileSystem @*/
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         /*@globals fileSystem @*/
00239         /*@modifies fileSystem @*/
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 /*@unused@*/ static /*@observer@*/
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 /*@-boundswrite@*/
00263 static int pgpHexSet(const char * pre, int lbits,
00264                 /*@out@*/ mpnumber * mpn, const byte * p, const byte * pend)
00265         /*@globals fileSystem @*/
00266         /*@modifies mpn, fileSystem @*/
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 /*@=boundswrite@*/
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:  /* preferred symmetric algorithms */
00313             for (i = 1; i < plen; i++)
00314                 pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
00315             /*@switchbreak@*/ break;
00316         case PGPSUBTYPE_PREFER_HASH:    /* preferred hash algorithms */
00317             for (i = 1; i < plen; i++)
00318                 pgpPrtVal(" ", pgpHashTbl, p[i]);
00319             /*@switchbreak@*/ break;
00320         case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
00321             for (i = 1; i < plen; i++)
00322                 pgpPrtVal(" ", pgpCompressionTbl, p[i]);
00323             /*@switchbreak@*/ break;
00324         case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
00325             for (i = 1; i < plen; i++)
00326                 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
00327             /*@switchbreak@*/ break;
00328         case PGPSUBTYPE_SIG_CREATE_TIME:
00329 /*@-mods -mayaliasunique @*/
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 /*@=mods =mayaliasunique @*/
00337             /*@fallthrough@*/
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             /*@switchbreak@*/ break;
00347 
00348         case PGPSUBTYPE_ISSUER_KEYID:   /* issuer key ID */
00349 /*@-mods -mayaliasunique @*/
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 /*@=mods =mayaliasunique @*/
00357             /*@fallthrough@*/
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             /*@switchbreak@*/ break;
00387         }
00388         pgpPrtNL();
00389         p += plen;
00390         hlen -= plen;
00391     }
00392     return 0;
00393 }
00394 
00395 /*@-varuse =readonlytrans @*/
00396 /*@observer@*/ /*@unchecked@*/
00397 static const char * pgpSigRSA[] = {
00398     " m**d =",
00399     NULL,
00400 };
00401 
00402 /*@observer@*/ /*@unchecked@*/
00403 static const char * pgpSigDSA[] = {
00404     "    r =",
00405     "    s =",
00406     NULL,
00407 };
00408 /*@=varuse =readonlytrans @*/
00409 
00410 static int pgpPrtSigParams(/*@unused@*/ pgpTag tag, byte pubkey_algo, byte sigtype,
00411                 const byte *p, const byte *h, unsigned int hlen)
00412         /*@globals fileSystem @*/
00413         /*@modifies fileSystem @*/
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:         /* m**d */
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                     /*@switchbreak@*/ break;
00430                 default:
00431                     /*@switchbreak@*/ 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:         /* r */
00444                     xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->r, p, pend);
00445                     /*@switchbreak@*/ break;
00446                 case 1:         /* s */
00447                     xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->s, p, pend);
00448                     /*@switchbreak@*/ break;
00449                 default:
00450                     xx = 1;
00451                     /*@switchbreak@*/ 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         /*@globals _digp @*/
00469         /*@modifies *_digp @*/
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 /*@-varuse =readonlytrans @*/
00575 /*@observer@*/ /*@unchecked@*/
00576 static const char * pgpPublicRSA[] = {
00577     "    n =",
00578     "    e =",
00579     NULL,
00580 };
00581 
00582 /*@observer@*/ /*@unchecked@*/
00583 static const char * pgpSecretRSA[] = {
00584     "    d =",
00585     "    p =",
00586     "    q =",
00587     "    u =",
00588     NULL,
00589 };
00590 
00591 /*@observer@*/ /*@unchecked@*/
00592 static const char * pgpPublicDSA[] = {
00593     "    p =",
00594     "    q =",
00595     "    g =",
00596     "    y =",
00597     NULL,
00598 };
00599 
00600 /*@observer@*/ /*@unchecked@*/
00601 static const char * pgpSecretDSA[] = {
00602     "    x =",
00603     NULL,
00604 };
00605 
00606 /*@observer@*/ /*@unchecked@*/
00607 static const char * pgpPublicELGAMAL[] = {
00608     "    p =",
00609     "    g =",
00610     "    y =",
00611     NULL,
00612 };
00613 
00614 /*@observer@*/ /*@unchecked@*/
00615 static const char * pgpSecretELGAMAL[] = {
00616     "    x =",
00617     NULL,
00618 };
00619 /*@=varuse =readonlytrans @*/
00620 
00621 static const byte * pgpPrtPubkeyParams(byte pubkey_algo,
00622                 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
00623         /*@globals fileSystem, internalState @*/
00624         /*@modifies fileSystem, internalState @*/
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:         /* n */
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                     /*@switchbreak@*/ break;
00638                 case 1:         /* e */
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                     /*@switchbreak@*/ break;
00643                 default:
00644                     /*@switchbreak@*/ 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:         /* p */
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                     /*@switchbreak@*/ break;
00657                 case 1:         /* q */
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                     /*@switchbreak@*/ break;
00662                 case 2:         /* g */
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                     /*@switchbreak@*/ break;
00667                 case 3:         /* y */
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                     /*@switchbreak@*/ break;
00672                 default:
00673                     /*@switchbreak@*/ 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(/*@unused@*/ byte pubkey_algo,
00692                 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
00693         /*@globals fileSystem @*/
00694         /*@modifies fileSystem @*/
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             /*@innerbreak@*/ break;
00710         case 0x01:
00711             pgpPrtVal(" salted ", pgpHashTbl, p[2]);
00712             pgpPrtHex("", p+3, 8);
00713             p += 10;
00714             /*@innerbreak@*/ break;
00715         case 0x03:
00716             pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
00717             /*@-shiftnegative -shiftimplementation @*/ /* FIX: unsigned cast */
00718             i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
00719             /*@=shiftnegative =shiftimplementation @*/
00720             pgpPrtHex("", p+3, 8);
00721             pgpPrtInt(" iter", i);
00722             p += 11;
00723             /*@innerbreak@*/ 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  /* XXX encrypted MPI's need to be handled. */
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         /*@globals _digp @*/
00767         /*@modifies *_digp @*/
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 /*@-boundswrite@*/
00827 int pgpPrtUserID(pgpTag tag, const byte *h, unsigned int hlen)
00828         /*@globals _digp @*/
00829         /*@modifies *_digp @*/
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 /*@=boundswrite@*/
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, /*@unused@*/ unsigned int pktlen,
00871                 byte * keyid)
00872 {
00873     const byte *s = pkt;
00874     DIGEST_CTX ctx;
00875     byte version;
00876     int rc = -1;        /* assume failure. */
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 /*@-boundswrite@*/
00891             memmove(keyid, s, 8);
00892 /*@=boundswrite@*/
00893             rc = 0;
00894             /*@innerbreak@*/ break;
00895         default:        /* TODO: md5 of mpi bodies (i.e. no length) */
00896             /*@innerbreak@*/ 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             /*@innerbreak@*/ break;
00910         case PGPPUBKEYALGO_DSA:
00911             for (i = 0; i < 4; i++)
00912                 s += pgpMpiLen(s);
00913             /*@innerbreak@*/ 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 /*@-boundswrite@*/
00922         memmove(keyid, s, 8);
00923 /*@=boundswrite@*/
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     /* XXX can't deal with these. */
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         /* Get the public key fingerprint. */
00966         if (_digp) {
00967 /*@-mods@*/
00968             if (!pgpPubkeyFingerprint(pkt, pktlen, _digp->signid))
00969                 _digp->saved |= PGPDIG_SAVED_ID;
00970             else
00971                 memset(_digp->signid, 0, sizeof(_digp->signid));
00972 /*@=mods@*/
00973         }
00974         /*@fallthrough@*/
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 /*@-boundswrite@*/
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         /*@-unqualifiedtrans@*/ /* FIX: double indirection */
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         /*@=unqualifiedtrans@*/
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 /*@-nullstate@*/
01051     return;
01052 /*@=nullstate@*/
01053 }
01054 /*@=boundswrite@*/
01055 
01056 pgpDig pgpFreeDig(/*@only@*/ /*@null@*/ pgpDig dig)
01057         /*@modifies dig @*/
01058 {
01059     if (dig != NULL) {
01060 
01061         /* DUmp the signature/pubkey data. */
01062         pgpCleanDig(dig);
01063 
01064         /*@-branchstate@*/
01065         if (dig->hdrsha1ctx != NULL)
01066             (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
01067         /*@=branchstate@*/
01068         dig->hdrsha1ctx = NULL;
01069 
01070         /*@-branchstate@*/
01071         if (dig->sha1ctx != NULL)
01072             (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
01073         /*@=branchstate@*/
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         /*@-branchstate@*/
01086         if (dig->hdrmd5ctx != NULL)
01087             (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
01088         /*@=branchstate@*/
01089         dig->hdrmd5ctx = NULL;
01090 #endif
01091 
01092         /*@-branchstate@*/
01093         if (dig->md5ctx != NULL)
01094             (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
01095         /*@=branchstate@*/
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         /*@globals _dig, _digp, _print @*/
01111         /*@modifies _dig, _digp, *_digp, _print @*/
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)        /* XXX shouldn't happen */
01132             break;
01133     }
01134     return 0;
01135 }
01136 
01137 /*@-boundswrite@*/
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;    /* XXX assume failure */
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   /* XXX ASCII Pubkeys only, please. */
01162         ec = 0; /* XXX fish out pkt type. */
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)  /* XXX ASCII Pubkeys only, please. */
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             /*@switchbreak@*/ 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;           /* Start of encoded packets */
01207             pstate++;
01208             /*@switchbreak@*/ break;
01209         case 2:
01210             crcenc = NULL;
01211             if (*t != '=')
01212                 continue;
01213             *t++ = '\0';        /* Terminate encoded packets */
01214             crcenc = t;         /* Start of encoded crc */
01215             pstate++;
01216             /*@switchbreak@*/ 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';          /* Terminate encoded crc */
01224             t += sizeof("-----END PGP ")-1;
01225             if (t >= te) continue;
01226 
01227             if (armortype == NULL) /* XXX can't happen */
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             /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
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;       /* XXX ASCII Pubkeys only, please. */
01268             goto exit;
01269             /*@notreached@*/ /*@switchbreak@*/ 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 /*@=boundswrite@*/
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     /*@-globs@*/
01295     /* Add additional bytes necessary for eol string(s). */
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     /*@=globs@*/
01303 
01304     nt += 512;  /* XXX slop for armor and crc */
01305 
01306 /*@-boundswrite@*/
01307     val = t = xmalloc(nt + 1);
01308     *t = '\0';
01309     t = stpcpy(t, "-----BEGIN PGP ");
01310     t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
01311     /*@-globs@*/
01312     t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), VERSION);
01313     /*@=globs@*/
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 /*@=boundswrite@*/
01330 
01331     return val;
01332 }
01333 
01334 /*@=boundsread@*/

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2