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

rpmio/rpmpgp.c

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

Generated on Sun Aug 18 10:48:53 2013 for rpm by  doxygen 1.4.4