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

Generated on Wed Jan 28 12:45:25 2009 for rpm by  doxygen 1.4.7