# 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 printf("\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             if (_digp && _digp->tag == PGPTAG_PUBLIC_KEY) {
    00373                 memcpy(_digp->time, p+1, sizeof(_digp->time));
    00374             }
    00375 /*@=mods =mayaliasunique @*/
    00376             /*@fallthrough@*/
    00377         case PGPSUBTYPE_SIG_EXPIRE_TIME:
    00378         case PGPSUBTYPE_KEY_EXPIRE_TIME:
    00379             if ((plen - 1) == 4) {
    00380                 time_t t = pgpGrab(p+1, plen-1);
    00381                 if (_print)
    00382                    fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
    00383             } else
    00384                 pgpPrtHex("", p+1, plen-1);
    00385             /*@switchbreak@*/ break;
    00386
    00387         case PGPSUBTYPE_ISSUER_KEYID:   /* issuer key ID */
    00388 /*@-mods -mayaliasunique @*/
    00389             if (_digp && _digp->tag == PGPTAG_PUBLIC_KEY) {
    00390                 memcpy(_digp->signid, p+1, sizeof(_digp->signid));
    00391             }
    00392 /*@=mods =mayaliasunique @*/
    00393             /*@fallthrough@*/
    00394         case PGPSUBTYPE_EXPORTABLE_CERT:
    00395         case PGPSUBTYPE_TRUST_SIG:
    00396         case PGPSUBTYPE_REGEX:
    00397         case PGPSUBTYPE_REVOCABLE:
    00398         case PGPSUBTYPE_BACKWARD_COMPAT:
    00399         case PGPSUBTYPE_REVOKE_KEY:
    00400         case PGPSUBTYPE_NOTATION:
    00401         case PGPSUBTYPE_PREFER_KEYSERVER:
    00402         case PGPSUBTYPE_PRIMARY_USERID:
    00403         case PGPSUBTYPE_POLICY_URL:
    00404         case PGPSUBTYPE_KEY_FLAGS:
    00405         case PGPSUBTYPE_SIGNER_USERID:
    00406         case PGPSUBTYPE_REVOKE_REASON:
    00407         case PGPSUBTYPE_INTERNAL_100:
    00408         case PGPSUBTYPE_INTERNAL_101:
    00409         case PGPSUBTYPE_INTERNAL_102:
    00410         case PGPSUBTYPE_INTERNAL_103:
    00411         case PGPSUBTYPE_INTERNAL_104:
    00412         case PGPSUBTYPE_INTERNAL_105:
    00413         case PGPSUBTYPE_INTERNAL_106:
    00414         case PGPSUBTYPE_INTERNAL_107:
    00415         case PGPSUBTYPE_INTERNAL_108:
    00416         case PGPSUBTYPE_INTERNAL_109:
    00417         case PGPSUBTYPE_INTERNAL_110:
    00418         default:
    00419             pgpPrtHex("", p+1, plen-1);
    00420             /*@switchbreak@*/ break;
    00421         }
    00422         pgpPrtNL();
    00423         p += plen;
    00424         hlen -= plen;
    00425     }
    00426     return 0;
    00427 }
    00428
    00429 /*@-varuse =readonlytrans @*/
    00430 /*@observer@*/ /*@unchecked@*/
    00431 static const char * pgpSigRSA[] = {
    00432     " m**d =",
    00433     NULL,
    00434 };
    00435
    00436 /*@observer@*/ /*@unchecked@*/
    00437 static const char * pgpSigDSA[] = {
    00438     "    r =",
    00439     "    s =",
    00440     NULL,
    00441 };
    00442 /*@=varuse =readonlytrans @*/
    00443
    00444 static int pgpPrtSigParams(/*@unused@*/ pgpTag tag, byte pubkey_algo, byte sigtype,
    00445                 const byte *p, const byte *h, unsigned int hlen)
    00446         /*@globals fileSystem @*/
    00447         /*@modifies fileSystem @*/
    00448 {
    00449     int i;
    00450
    00451     for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
    00452         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
    00453             if (i >= 1) break;
    00454             /*@-mods@*/
    00455             if (_dig &&
    00456         (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
    00457             {
    00458                 switch (i) {
    00459                 case 0:         /* m**d */
    00460                     mp32nsethex(&_dig->c, pgpMpiHex(p));
    00461 if (_debug && _print)
    00462 printf("\t  m**d = "),  mp32println(_dig->c.size, _dig->c.data);
    00463                     /*@switchbreak@*/ break;
    00464                 default:
    00465                     /*@switchbreak@*/ break;
    00466                 }
    00467             }
    00468             /*@=mods@*/
    00469             pgpPrtStr("", pgpSigRSA[i]);
    00470         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
    00471             if (i >= 2) break;
    00472             /*@-mods@*/
    00473             if (_dig &&
    00474         (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
    00475             {
    00476                 switch (i) {
    00477                 case 0:         /* r */
    00478                     pgpHexSet(pgpSigDSA[i], 160, &_dig->r, p);
    00479                     /*@switchbreak@*/ break;
    00480                 case 1:         /* s */
    00481                     pgpHexSet(pgpSigDSA[i], 160, &_dig->s, p);
    00482                     /*@switchbreak@*/ break;
    00483                 default:
    00484                     /*@switchbreak@*/ break;
    00485                 }
    00486             }
    00487             /*@=mods@*/
    00488             pgpPrtStr("", pgpSigDSA[i]);
    00489         } else {
    00490             if (_print)
    00491                 fprintf(stderr, "%7d", i);
    00492         }
    00493         pgpPrtStr("", pgpMpiStr(p));
    00494         pgpPrtNL();
    00495     }
    00496
    00497     return 0;
    00498 }
    00499
    00500 int pgpPrtSig(pgpTag tag, const byte *h, unsigned int hlen)
    00501 {
    00502     byte version = h[0];
    00503     byte * p;
    00504     unsigned plen;
    00505     int rc;
    00506
    00507     switch (version) {
    00508     case 3:
    00509     {   pgpPktSigV3 v = (pgpPktSigV3)h;
    00510         time_t t;
    00511
    00512         if (v->hashlen != 5) {
    00513             fprintf(stderr, " hashlen(%u) != 5\n", (unsigned)v->hashlen);
    00514             return 1;
    00515         }
    00516
    00517         pgpPrtVal("V3 ", pgpTagTbl, tag);
    00518         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
    00519         pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
    00520         pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
    00521         pgpPrtNL();
    00522         t = pgpGrab(v->time, sizeof(v->time));
    00523         if (_print)
    00524             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
    00525         pgpPrtNL();
    00526         pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
    00527         plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
    00528         pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
    00529         pgpPrtNL();
    00530
    00531 /*@-mods@*/
    00532         if (_digp && _digp->pubkey_algo == 0) {
    00533             _digp->version = v->version;
    00534             _digp->hashlen = v->hashlen;
    00535             _digp->sigtype = v->sigtype;
    00536             _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
    00537             memcpy(_digp->time, v->time, sizeof(_digp->time));
    00538             memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
    00539             _digp->pubkey_algo = v->pubkey_algo;
    00540             _digp->hash_algo = v->hash_algo;
    00541             memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
    00542         }
    00543 /*@=mods@*/
    00544
    00545         p = ((byte *)v) + sizeof(*v);
    00546         rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
    00547     }   break;
    00548     case 4:
    00549     {   pgpPktSigV4 v = (pgpPktSigV4)h;
    00550
    00551         pgpPrtVal("V4 ", pgpTagTbl, tag);
    00552         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
    00553         pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
    00554         pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
    00555         pgpPrtNL();
    00556
    00557         p = &v->hashlen[0];
    00558         plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
    00559         p += sizeof(v->hashlen);
    00560
    00561 if (_debug && _print)
    00562 fprintf(stderr, "   hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
    00563         /*@-mods@*/
    00564         if (_digp && _digp->pubkey_algo == 0) {
    00565             _digp->hashlen = plen;
    00566             _digp->hash = memcpy(xmalloc(plen), p, plen);
    00567         }
    00568         /*@=mods@*/
    00569         (void) pgpPrtSubType(p, plen);
    00570         p += plen;
    00571
    00572         plen = pgpGrab(p,2);
    00573         p += 2;
    00574
    00575 if (_debug && _print)
    00576 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
    00577         (void) pgpPrtSubType(p, plen);
    00578         p += plen;
    00579
    00580         plen = pgpGrab(p,2);
    00581         pgpPrtHex(" signhash16", p, 2);
    00582         pgpPrtNL();
    00583
    00584 /*@-mods@*/
    00585         if (_digp && _digp->pubkey_algo == 0) {
    00586             _digp->version = v->version;
    00587             _digp->sigtype = v->sigtype;
    00588             _digp->pubkey_algo = v->pubkey_algo;
    00589             _digp->hash_algo = v->hash_algo;
    00590             memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
    00591         }
    00592 /*@=mods@*/
    00593
    00594         p += 2;
    00595
    00596         rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen);
    00597     }   break;
    00598     default:
    00599         rc = 1;
    00600         break;
    00601     }
    00602     return rc;
    00603 }
    00604
    00605 /*@-varuse =readonlytrans @*/
    00606 /*@observer@*/ /*@unchecked@*/
    00607 static const char * pgpPublicRSA[] = {
    00608     "    n =",
    00609     "    e =",
    00610     NULL,
    00611 };
    00612
    00613 /*@observer@*/ /*@unchecked@*/
    00614 static const char * pgpSecretRSA[] = {
    00615     "    d =",
    00616     "    p =",
    00617     "    q =",
    00618     "    u =",
    00619     NULL,
    00620 };
    00621
    00622 /*@observer@*/ /*@unchecked@*/
    00623 static const char * pgpPublicDSA[] = {
    00624     "    p =",
    00625     "    q =",
    00626     "    g =",
    00627     "    y =",
    00628     NULL,
    00629 };
    00630
    00631 /*@observer@*/ /*@unchecked@*/
    00632 static const char * pgpSecretDSA[] = {
    00633     "    x =",
    00634     NULL,
    00635 };
    00636
    00637 /*@observer@*/ /*@unchecked@*/
    00638 static const char * pgpPublicELGAMAL[] = {
    00639     "    p =",
    00640     "    g =",
    00641     "    y =",
    00642     NULL,
    00643 };
    00644
    00645 /*@observer@*/ /*@unchecked@*/
    00646 static const char * pgpSecretELGAMAL[] = {
    00647     "    x =",
    00648     NULL,
    00649 };
    00650 /*@=varuse =readonlytrans @*/
    00651
    00652 static const byte * pgpPrtPubkeyParams(byte pubkey_algo,
    00653                 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
    00654         /*@globals fileSystem @*/
    00655         /*@modifies fileSystem @*/
    00656 {
    00657     int i;
    00658
    00659     for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
    00660         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
    00661             if (i >= 2) break;
    00662             /*@-mods@*/
    00663             if (_dig) {
    00664                 switch (i) {
    00665                 case 0:         /* n */
    00666                     mp32bsethex(&_dig->rsa_pk.n, pgpMpiHex(p));
    00667                     /* Get the keyid */
    00668                     if (_digp) {
    00669                         uint32* np = _dig->rsa_pk.n.modl;
    00670                         uint32  nsize = _dig->rsa_pk.n.size;
    00671                         uint32 keyid[2];
    00672                         #if WORDS_BIGENDIAN
    00673                         keyid[0] = np[nsize-2];
    00674                         keyid[1] = np[nsize-1];
    00675                         #else
    00676                         keyid[0] = swapu32(np[nsize-2]);
    00677                         keyid[1] = swapu32(np[nsize-1]);
    00678                         #endif
    00679                         memcpy(_digp->signid, keyid, sizeof(_digp->signid));
    00680                     }
    00681 if (_debug && _print)
    00682 printf("\t     n = "),  mp32println(_dig->rsa_pk.n.size, _dig->rsa_pk.n.modl);
    00683                     /*@switchbreak@*/ break;
    00684                 case 1:         /* e */
    00685                     mp32nsethex(&_dig->rsa_pk.e, pgpMpiHex(p));
    00686 if (_debug && _print)
    00687 printf("\t     e = "),  mp32println(_dig->rsa_pk.e.size, _dig->rsa_pk.e.data);
    00688                     /*@switchbreak@*/ break;
    00689                 default:
    00690                     /*@switchbreak@*/ break;
    00691                 }
    00692             }
    00693             /*@=mods@*/
    00694             pgpPrtStr("", pgpPublicRSA[i]);
    00695         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
    00696             if (i >= 4) break;
    00697             /*@-mods@*/
    00698             if (_dig) {
    00699                 switch (i) {
    00700                 case 0:         /* p */
    00701                     mp32bsethex(&_dig->p, pgpMpiHex(p));
    00702 if (_debug && _print)
    00703 printf("\t     p = "),  mp32println(_dig->p.size, _dig->p.modl);
    00704                     /*@switchbreak@*/ break;
    00705                 case 1:         /* q */
    00706                     mp32bsethex(&_dig->q, pgpMpiHex(p));
    00707 if (_debug && _print)
    00708 printf("\t     q = "),  mp32println(_dig->q.size, _dig->q.modl);
    00709                     /*@switchbreak@*/ break;
    00710                 case 2:         /* g */
    00711                     mp32nsethex(&_dig->g, pgpMpiHex(p));
    00712 if (_debug && _print)
    00713 printf("\t     g = "),  mp32println(_dig->g.size, _dig->g.data);
    00714                     /*@switchbreak@*/ break;
    00715                 case 3:         /* y */
    00716                     mp32nsethex(&_dig->y, pgpMpiHex(p));
    00717 if (_debug && _print)
    00718 printf("\t     y = "),  mp32println(_dig->y.size, _dig->y.data);
    00719                     /*@switchbreak@*/ break;
    00720                 default:
    00721                     /*@switchbreak@*/ break;
    00722                 }
    00723             }
    00724             /*@=mods@*/
    00725             pgpPrtStr("", pgpPublicDSA[i]);
    00726         } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
    00727             if (i >= 3) break;
    00728             pgpPrtStr("", pgpPublicELGAMAL[i]);
    00729         } else {
    00730             if (_print)
    00731                 fprintf(stderr, "%7d", i);
    00732         }
    00733     /*@=mods@*/
    00734         pgpPrtStr("", pgpMpiStr(p));
    00735         pgpPrtNL();
    00736     }
    00737
    00738     return p;
    00739 }
    00740
    00741 static const byte * pgpPrtSeckeyParams(/*@unused@*/ byte pubkey_algo,
    00742                 /*@returned@*/ const byte *p, const byte *h, unsigned int hlen)
    00743         /*@globals fileSystem @*/
    00744         /*@modifies fileSystem @*/
    00745 {
    00746     int i;
    00747
    00748     switch (*p) {
    00749     case 0:
    00750         pgpPrtVal(" ", pgpSymkeyTbl, *p);
    00751         break;
    00752     case 255:
    00753         p++;
    00754         pgpPrtVal(" ", pgpSymkeyTbl, *p);
    00755         switch (p[1]) {
    00756         case 0x00:
    00757             pgpPrtVal(" simple ", pgpHashTbl, p[2]);
    00758             p += 2;
    00759             /*@innerbreak@*/ break;
    00760         case 0x01:
    00761             pgpPrtVal(" salted ", pgpHashTbl, p[2]);
    00762             pgpPrtHex("", p+3, 8);
    00763             p += 10;
    00764             /*@innerbreak@*/ break;
    00765         case 0x03:
    00766             pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
    00767             /*@-shiftnegative@*/ /* FIX: unsigned cast */
    00768             i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
    00769             /*@=shiftnegative@*/
    00770             pgpPrtHex("", p+3, 8);
    00771             pgpPrtInt(" iter", i);
    00772             p += 11;
    00773             /*@innerbreak@*/ break;
    00774         }
    00775         break;
    00776     default:
    00777         pgpPrtVal(" ", pgpSymkeyTbl, *p);
    00778         pgpPrtHex(" IV", p+1, 8);
    00779         p += 8;
    00780         break;
    00781     }
    00782     pgpPrtNL();
    00783
    00784     p++;
    00785
    00786 #ifdef  NOTYET  /* XXX encrypted MPI's need to be handled. */
    00787     for (i = 0; p < &h[hlen]; i++, p += pgpMpiLen(p)) {
    00788         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
    00789             if (pgpSecretRSA[i] == NULL) break;
    00790             pgpPrtStr("", pgpSecretRSA[i]);
    00791         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
    00792             if (pgpSecretDSA[i] == NULL) break;
    00793             pgpPrtStr("", pgpSecretDSA[i]);
    00794         } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
    00795             if (pgpSecretELGAMAL[i] == NULL) break;
    00796             pgpPrtStr("", pgpSecretELGAMAL[i]);
    00797         } else {
    00798             if (_print)
    00799                 fprintf(stderr, "%7d", i);
    00800         }
    00801         pgpPrtStr("", pgpMpiStr(p));
    00802         pgpPrtNL();
    00803     }
    00804 #else
    00805     pgpPrtHex(" secret", p, (hlen - (p - h) - 2));
    00806     pgpPrtNL();
    00807     p += (hlen - (p - h) - 2);
    00808 #endif
    00809     pgpPrtHex(" checksum", p, 2);
    00810     pgpPrtNL();
    00811
    00812     return p;
    00813 }
    00814
    00815 int pgpPrtKey(pgpTag tag, const byte *h, unsigned int hlen)
    00816 {
    00817     byte version = *h;
    00818     const byte * p;
    00819     unsigned plen;
    00820     time_t t;
    00821     int rc;
    00822
    00823     switch (version) {
    00824     case 3:
    00825     {   pgpPktKeyV3 v = (pgpPktKeyV3)h;
    00826         pgpPrtVal("V3 ", pgpTagTbl, tag);
    00827         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
    00828         t = pgpGrab(v->time, sizeof(v->time));
    00829         if (_print)
    00830             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
    00831         plen = pgpGrab(v->valid, sizeof(v->valid));
    00832         if (plen != 0)
    00833             fprintf(stderr, " valid %u days", plen);
    00834         pgpPrtNL();
    00835
    00836 /*@-mods@*/
    00837         if (_digp && _digp->tag == tag) {
    00838             _digp->version = v->version;
    00839             memcpy(_digp->time, v->time, sizeof(_digp->time));
    00840             _digp->pubkey_algo = v->pubkey_algo;
    00841         }
    00842 /*@=mods@*/
    00843
    00844         p = ((byte *)v) + sizeof(*v);
    00845         p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
    00846         rc = 0;
    00847     }   break;
    00848     case 4:
    00849     {   pgpPktKeyV4 v = (pgpPktKeyV4)h;
    00850         pgpPrtVal("V4 ", pgpTagTbl, tag);
    00851         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
    00852         t = pgpGrab(v->time, sizeof(v->time));
    00853         if (_print)
    00854             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
    00855         pgpPrtNL();
    00856
    00857 /*@-mods@*/
    00858         if (_digp && _digp->tag == tag) {
    00859             _digp->version = v->version;
    00860             memcpy(_digp->time, v->time, sizeof(_digp->time));
    00861             _digp->pubkey_algo = v->pubkey_algo;
    00862         }
    00863 /*@=mods@*/
    00864
    00865         p = ((byte *)v) + sizeof(*v);
    00866         p = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen);
    00867         if (!(tag == PGPTAG_PUBLIC_KEY || tag == PGPTAG_PUBLIC_SUBKEY))
    00868             p = pgpPrtSeckeyParams(v->pubkey_algo, p, h, hlen);
    00869         rc = 0;
    00870     }   break;
    00871     default:
    00872         rc = 1;
    00873         break;
    00874     }
    00875     return rc;
    00876 }
    00877
    00878 int pgpPrtUserID(pgpTag tag, const byte *h, unsigned int hlen)
    00879 {
    00880     pgpPrtVal("", pgpTagTbl, tag);
    00881     if (_print)
    00882         fprintf(stderr, " \"%.*s\"", (int)hlen, (const char *)h);
    00883     pgpPrtNL();
    00884 /*@-mods@*/
    00885     if (_digp) {
    00886         char * t;
    00887         _digp->userid = t = memcpy(xmalloc(hlen+1), h, hlen);
    00888         t[hlen] = '\0';
    00889     }
    00890 /*@=mods@*/
    00891     return 0;
    00892 }
    00893
    00894 int pgpPrtComment(pgpTag tag, const byte *h, unsigned int hlen)
    00895 {
    00896     int i = hlen;
    00897
    00898     pgpPrtVal("", pgpTagTbl, tag);
    00899     if (_print)
    00900         fprintf(stderr, " ");
    00901     while (i > 0) {
    00902         int j;
    00903         if (*h >= ' ' && *h <= 'z') {
    00904             if (_print)
    00905                 fprintf(stderr, "%s", (const char *)h);
    00906             j = strlen(h);
    00907             while (h[j] == '\0')
    00908                 j++;
    00909         } else {
    00910             pgpPrtHex("", h, i);
    00911             j = i;
    00912         }
    00913         i -= j;
    00914         h += j;
    00915     }
    00916     pgpPrtNL();
    00917     return 0;
    00918 }
    00919
    00920 int pgpPrtPkt(const byte *pkt)
    00921 {
    00922     unsigned int val = *pkt;
    00923     unsigned int pktlen;
    00924     pgpTag tag;
    00925     unsigned int plen;
    00926     const byte *h;
    00927     unsigned int hlen = 0;
    00928     int rc = 0;
    00929
    00930     /* XXX can't deal with these. */
    00931     if (!(val & 0x80))
    00932         return -1;
    00933
    00934     if (val & 0x40) {
    00935         tag = (val & 0x3f);
    00936         plen = pgpLen(pkt+1, &hlen);
    00937     } else {
    00938         tag = (val >> 2) & 0xf;
    00939         plen = (1 << (val & 0x3));
    00940         hlen = pgpGrab(pkt+1, plen);
    00941     }
    00942
    00943     pktlen = 1 + plen + hlen;
    00944     h = pkt + 1 + plen;
    00945     switch (tag) {
    00946     case PGPTAG_SIGNATURE:
    00947         rc = pgpPrtSig(tag, h, hlen);
    00948         break;
    00949     case PGPTAG_PUBLIC_KEY:
    00950     case PGPTAG_PUBLIC_SUBKEY:
    00951         rc = pgpPrtKey(tag, h, hlen);
    00952         break;
    00953     case PGPTAG_SECRET_KEY:
    00954     case PGPTAG_SECRET_SUBKEY:
    00955         rc = pgpPrtKey(tag, h, hlen);
    00956         break;
    00957     case PGPTAG_USER_ID:
    00958         rc = pgpPrtUserID(tag, h, hlen);
    00959         break;
    00960     case PGPTAG_COMMENT:
    00961     case PGPTAG_COMMENT_OLD:
    00962         rc = pgpPrtComment(tag, h, hlen);
    00963         break;
    00964
    00965     case PGPTAG_RESERVED:
    00966     case PGPTAG_PUBLIC_SESSION_KEY:
    00967     case PGPTAG_SYMMETRIC_SESSION_KEY:
    00968     case PGPTAG_COMPRESSED_DATA:
    00969     case PGPTAG_SYMMETRIC_DATA:
    00970     case PGPTAG_MARKER:
    00971     case PGPTAG_LITERAL_DATA:
    00972     case PGPTAG_TRUST:
    00973     case PGPTAG_PHOTOID:
    00974     case PGPTAG_ENCRYPTED_MDC:
    00975     case PGPTAG_MDC:
    00976     case PGPTAG_PRIVATE_60:
    00977     case PGPTAG_PRIVATE_62:
    00978     case PGPTAG_CONTROL:
    00979     default:
    00980         pgpPrtVal("", pgpTagTbl, tag);
    00981         pgpPrtHex("", h, hlen);
    00982         pgpPrtNL();
    00983         break;
    00984     }
    00985
    00986     return (rc ? -1 : pktlen);
    00987 }
    00988
    00989 struct pgpDig_s * pgpNewDig(void)
    00990 {
    00991     struct pgpDig_s * dig = xcalloc(1, sizeof(*dig));
    00992     return dig;
    00993 }
    00994
    00995 struct pgpDig_s * pgpFreeDig(/*@only@*/ /*@null@*/ struct pgpDig_s * dig)
    00996         /*@modifies dig @*/
    00997 {
    00998     if (dig != NULL) {
    00999         int i;
    01000         dig->signature.userid = _free(dig->signature.userid);
    01001         dig->pubkey.userid = _free(dig->pubkey.userid);
    01002         dig->signature.hash = _free(dig->signature.hash);
    01003         dig->pubkey.hash = _free(dig->pubkey.hash);
    01004         /*@-unqualifiedtrans@*/ /* FIX: double indirection */
    01005         for (i = 0; i < 4; i++) {
    01006             dig->signature.params[i] = _free(dig->signature.params[i]);
    01007             dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
    01008         }
    01009         /*@=unqualifiedtrans@*/
    01010
    01011         /*@-branchstate@*/
    01012         if (dig->md5ctx != NULL)
    01013             (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
    01014         /*@=branchstate@*/
    01015         dig->md5ctx = NULL;
    01016         dig->md5 = _free(dig->md5);
    01017
    01018         /*@-branchstate@*/
    01019         if (dig->sha1ctx != NULL)
    01020             (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
    01021         /*@=branchstate@*/
    01022         dig->sha1ctx = NULL;
    01023         dig->sha1 = _free(dig->sha1);
    01024
    01025         mp32nfree(&dig->hm);
    01026         mp32nfree(&dig->r);
    01027         mp32nfree(&dig->s);
    01028
    01029         (void) rsapkFree(&dig->rsa_pk);
    01030         mp32nfree(&dig->m);
    01031         mp32nfree(&dig->c);
    01032         mp32nfree(&dig->rsahm);
    01033         dig = _free(dig);
    01034     }
    01035     return dig;
    01036 }
    01037
    01038 int pgpPrtPkts(const byte * pkts, unsigned int plen,
    01039                 struct pgpDig_s * dig, int printing)
    01040 {
    01041     unsigned int val = *pkts;
    01042     const byte *p;
    01043     int len;
    01044
    01045     /*@-mods@*/
    01046     _print = printing;
    01047     _dig = dig;
    01048     if (dig != NULL && (val & 0x80)) {
    01049         pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
    01050         _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
    01051         _digp->tag = tag;
    01052     } else
    01053         _digp = NULL;
    01054     /*@=mods@*/
    01055
    01056     for (p = pkts; p < (pkts + plen); p += len) {
    01057         len = pgpPrtPkt(p);
    01058         if (len <= 0)
    01059             return len;
    01060     }
    01061     return 0;
    01062 }
    01063
    01064 pgpArmor pgpReadPkts(const char * fn, const byte ** pkt, size_t * pktlen)
    01065 {
    01066     const byte * b = NULL;
    01067     ssize_t blen;
    01068     const char * enc = NULL;
    01069     const char * crcenc = NULL;
    01070     byte * dec;
    01071     byte * crcdec;
    01072     size_t declen;
    01073     size_t crclen;
    01074     uint32 crcpkt, crc;
    01075     const char * armortype = NULL;
    01076     char * t, * te;
    01077     int pstate = 0;
    01078     pgpArmor ec = PGPARMOR_ERROR;       /* XXX assume failure */
    01079     int rc;
    01080
    01081     rc = rpmioSlurp(fn, &b, &blen);
    01082     if (rc || b == NULL || blen <= 0) {
    01083         goto exit;
    01084     }
    01085
    01086     if (pgpIsPkt(b)) {
    01087 #ifdef NOTYET   /* XXX ASCII Pubkeys only, please. */
    01088         ec = 0; /* XXX fish out pkt type. */
    01089 #endif
    01090         goto exit;
    01091     }
    01092
    01093 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
    01094
    01095     for (t = (char *)b; t && *t; t = te) {
    01096         if ((te = strchr(t, '\n')) == NULL)
    01097             te = t + strlen(t);
    01098         else
    01099             te++;
    01100
    01101         switch (pstate) {
    01102         case 0:
    01103             armortype = NULL;
    01104             if (!TOKEQ(t, "-----BEGIN PGP "))
    01105                 continue;
    01106             t += sizeof("-----BEGIN PGP ")-1;
    01107
    01108             rc = pgpValTok(pgpArmorTbl, t, te);
    01109             if (rc < 0)
    01110                 goto exit;
    01111             if (rc != PGPARMOR_PUBKEY)  /* XXX ASCII Pubkeys only, please. */
    01112                 continue;
    01113             armortype = t;
    01114
    01115             t = te - (sizeof("-----\n")-1);
    01116             if (!TOKEQ(t, "-----\n"))
    01117                 continue;
    01118             *t = '\0';
    01119             pstate++;
    01120             /*@switchbreak@*/ break;
    01121         case 1:
    01122             enc = NULL;
    01123             rc = pgpValTok(pgpArmorKeyTbl, t, te);
    01124             if (rc >= 0)
    01125                 continue;
    01126             if (*t != '\n') {
    01127                 pstate = 0;
    01128                 continue;
    01129             }
    01130             enc = te;           /* Start of encoded packets */
    01131             pstate++;
    01132             /*@switchbreak@*/ break;
    01133         case 2:
    01134             crcenc = NULL;
    01135             if (*t != '=')
    01136                 continue;
    01137             *t++ = '\0';        /* Terminate encoded packets */
    01138             crcenc = t;         /* Start of encoded crc */
    01139             pstate++;
    01140             /*@switchbreak@*/ break;
    01141         case 3:
    01142             pstate = 0;
    01143             if (!TOKEQ(t, "-----END PGP "))
    01144                 goto exit;
    01145             *t = '\0';          /* Terminate encoded crc */
    01146             t += sizeof("-----END PGP ")-1;
    01147
    01148             if (armortype == NULL) /* XXX can't happen */
    01149                 continue;
    01150             rc = strncmp(t, armortype, strlen(armortype));
    01151             if (rc)
    01152                 continue;
    01153
    01154             t = te - (sizeof("-----\n")-1);
    01155             if (!TOKEQ(t, "-----\n"))
    01156                 goto exit;
    01157
    01158             if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0)
    01159                 continue;
    01160             crcpkt = pgpGrab(crcdec, crclen);
    01161             crcdec = _free(crcdec);
    01162             if (b64decode(enc, (void **)&dec, &declen) != 0)
    01163                 goto exit;
    01164             crc = pgpCRC(dec, declen);
    01165             if (crcpkt != crc)
    01166                 goto exit;
    01167             b = _free(b);
    01168             b = dec;
    01169             blen = declen;
    01170             ec = PGPARMOR_PUBKEY;       /* XXX ASCII Pubkeys only, please. */
    01171             goto exit;
    01172             /*@notreached@*/ /*@switchbreak@*/ break;
    01173         }
    01174     }
    01175     ec = PGPARMOR_NONE;
    01176
    01177 exit:
    01178     if (ec > PGPARMOR_NONE && pkt)
    01179         *pkt = b;
    01180     else if (b != NULL)
    01181         b = _free(b);
    01182     if (pktlen)
    01183         *pktlen = blen;
    01184     return ec;
    01185 }