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

Generated on 30 Sep 2013 for rpm by  doxygen 1.4.7