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

# rpmio/rpmpgp.c

Go to the documentation of this file.

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