rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmio/rpmpgp.c
Go to the documentation of this file.

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