Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

rpmio/rpmpgp.c

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

Generated on Sun Feb 2 23:32:06 2003 for rpm by doxygen1.2.18