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 
00270 /*@unused@*/ static inline /*@null@*/ void *
00271 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p)
00272         /*@modifies p @*/
00273 {
00274     if (p != NULL)      free((void *)p);
00275     return NULL;
00276 }
00277 
00278 static void pgpPrtNL(void)
00279         /*@globals fileSystem @*/
00280         /*@modifies fileSystem @*/
00281 {
00282     if (!_print) return;
00283     fprintf(stderr, "\n");
00284 }
00285 
00286 static void pgpPrtInt(const char *pre, int i)
00287         /*@globals fileSystem @*/
00288         /*@modifies fileSystem @*/
00289 {
00290     if (!_print) return;
00291     if (pre && *pre)
00292         fprintf(stderr, "%s", pre);
00293     fprintf(stderr, " %d", i);
00294 }
00295 
00296 static void pgpPrtStr(const char *pre, const char *s)
00297         /*@globals fileSystem @*/
00298         /*@modifies fileSystem @*/
00299 {
00300     if (!_print) return;
00301     if (pre && *pre)
00302         fprintf(stderr, "%s", pre);
00303     fprintf(stderr, " %s", s);
00304 }
00305 
00306 static void pgpPrtHex(const char *pre, const byte *p, unsigned int plen)
00307         /*@globals fileSystem @*/
00308         /*@modifies fileSystem @*/
00309 {
00310     if (!_print) return;
00311     if (pre && *pre)
00312         fprintf(stderr, "%s", pre);
00313     fprintf(stderr, " %s", pgpHexStr(p, plen));
00314 }
00315 
00316 void pgpPrtVal(const char * pre, pgpValTbl vs, byte val)
00317         /*@globals fileSystem @*/
00318         /*@modifies fileSystem @*/
00319 {
00320     if (!_print) return;
00321     if (pre && *pre)
00322         fprintf(stderr, "%s", pre);
00323     fprintf(stderr, "%s(%u)", pgpValStr(vs, val), (unsigned)val);
00324 }
00325 
00328 /*@unused@*/ static /*@observer@*/
00329 const char * pgpMpiHex(const byte *p)
00330         /*@*/
00331 {
00332     static char prbuf[2048];
00333     char *t = prbuf;
00334     t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2);
00335     return prbuf;
00336 }
00337 
00338 /*@-boundswrite@*/
00342 static int pgpHexSet(const char * pre, int lbits,
00343                 /*@out@*/ mpnumber * mpn, const byte * p, const byte * pend)
00344         /*@globals fileSystem @*/
00345         /*@modifies mpn, fileSystem @*/
00346 {
00347     unsigned int mbits = pgpMpiBits(p);
00348     unsigned int nbits;
00349     unsigned int nbytes;
00350     char * t;
00351     unsigned int ix;
00352 
00353     if ((p + ((mbits+7) >> 3)) > pend)
00354         return 1;
00355 
00356     nbits = (lbits > mbits ? lbits : mbits);
00357     nbytes = ((nbits + 7) >> 3);
00358     t = xmalloc(2*nbytes+1);
00359     ix = 2 * ((nbits - mbits) >> 3);
00360 
00361 if (_debug)
00362 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
00363     if (ix > 0) memset(t, (int)'0', ix);
00364     strcpy(t+ix, pgpMpiHex(p));
00365 if (_debug)
00366 fprintf(stderr, "*** %s %s\n", pre, t);
00367     (void) mpnsethex(mpn, t);
00368     t = _free(t);
00369 if (_debug && _print)
00370 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, mpn->size, mpn->data);
00371     return 0;
00372 }
00373 /*@=boundswrite@*/
00374 
00375 int pgpPrtSubType(const byte *h, unsigned int hlen, pgpSigType sigtype)
00376 {
00377     const byte *p = h;
00378     unsigned plen;
00379     int i;
00380 
00381     while (hlen > 0) {
00382         i = pgpLen(p, &plen);
00383         p += i;
00384         hlen -= i;
00385 
00386         pgpPrtVal("    ", pgpSubTypeTbl, (p[0]&(~PGPSUBTYPE_CRITICAL)));
00387         if (p[0] & PGPSUBTYPE_CRITICAL)
00388             if (_print)
00389                 fprintf(stderr, " *CRITICAL*");
00390         switch (*p) {
00391         case PGPSUBTYPE_PREFER_SYMKEY:  /* preferred symmetric algorithms */
00392             for (i = 1; i < plen; i++)
00393                 pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
00394             /*@switchbreak@*/ break;
00395         case PGPSUBTYPE_PREFER_HASH:    /* preferred hash algorithms */
00396             for (i = 1; i < plen; i++)
00397                 pgpPrtVal(" ", pgpHashTbl, p[i]);
00398             /*@switchbreak@*/ break;
00399         case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */
00400             for (i = 1; i < plen; i++)
00401                 pgpPrtVal(" ", pgpCompressionTbl, p[i]);
00402             /*@switchbreak@*/ break;
00403         case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */
00404             for (i = 1; i < plen; i++)
00405                 pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
00406             /*@switchbreak@*/ break;
00407         case PGPSUBTYPE_SIG_CREATE_TIME:
00408 /*@-mods -mayaliasunique @*/
00409             if (_digp && !(_digp->saved & PGPDIG_SAVED_TIME) &&
00410                 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
00411             {
00412                 _digp->saved |= PGPDIG_SAVED_TIME;
00413                 memcpy(_digp->time, p+1, sizeof(_digp->time));
00414             }
00415 /*@=mods =mayaliasunique @*/
00416             /*@fallthrough@*/
00417         case PGPSUBTYPE_SIG_EXPIRE_TIME:
00418         case PGPSUBTYPE_KEY_EXPIRE_TIME:
00419             if ((plen - 1) == 4) {
00420                 time_t t = pgpGrab(p+1, plen-1);
00421                 if (_print)
00422                    fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00423             } else
00424                 pgpPrtHex("", p+1, plen-1);
00425             /*@switchbreak@*/ break;
00426 
00427         case PGPSUBTYPE_ISSUER_KEYID:   /* issuer key ID */
00428 /*@-mods -mayaliasunique @*/
00429             if (_digp && !(_digp->saved & PGPDIG_SAVED_ID) &&
00430                 (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
00431             {
00432                 _digp->saved |= PGPDIG_SAVED_ID;
00433                 memcpy(_digp->signid, p+1, sizeof(_digp->signid));
00434             }
00435 /*@=mods =mayaliasunique @*/
00436             /*@fallthrough@*/
00437         case PGPSUBTYPE_EXPORTABLE_CERT:
00438         case PGPSUBTYPE_TRUST_SIG:
00439         case PGPSUBTYPE_REGEX:
00440         case PGPSUBTYPE_REVOCABLE:
00441         case PGPSUBTYPE_ARR:
00442         case PGPSUBTYPE_REVOKE_KEY:
00443         case PGPSUBTYPE_NOTATION:
00444         case PGPSUBTYPE_PREFER_KEYSERVER:
00445         case PGPSUBTYPE_PRIMARY_USERID:
00446         case PGPSUBTYPE_POLICY_URL:
00447         case PGPSUBTYPE_KEY_FLAGS:
00448         case PGPSUBTYPE_SIGNER_USERID:
00449         case PGPSUBTYPE_REVOKE_REASON:
00450         case PGPSUBTYPE_FEATURES:
00451         case PGPSUBTYPE_EMBEDDED_SIG:
00452         case PGPSUBTYPE_INTERNAL_100:
00453         case PGPSUBTYPE_INTERNAL_101:
00454         case PGPSUBTYPE_INTERNAL_102:
00455         case PGPSUBTYPE_INTERNAL_103:
00456         case PGPSUBTYPE_INTERNAL_104:
00457         case PGPSUBTYPE_INTERNAL_105:
00458         case PGPSUBTYPE_INTERNAL_106:
00459         case PGPSUBTYPE_INTERNAL_107:
00460         case PGPSUBTYPE_INTERNAL_108:
00461         case PGPSUBTYPE_INTERNAL_109:
00462         case PGPSUBTYPE_INTERNAL_110:
00463         default:
00464             pgpPrtHex("", p+1, plen-1);
00465             /*@switchbreak@*/ break;
00466         }
00467         pgpPrtNL();
00468         p += plen;
00469         hlen -= plen;
00470     }
00471     return 0;
00472 }
00473 
00474 /*@-varuse =readonlytrans @*/
00475 /*@observer@*/ /*@unchecked@*/
00476 static const char * pgpSigRSA[] = {
00477     " m**d =",
00478     NULL,
00479 };
00480 
00481 /*@observer@*/ /*@unchecked@*/
00482 static const char * pgpSigDSA[] = {
00483     "    r =",
00484     "    s =",
00485     NULL,
00486 };
00487 /*@=varuse =readonlytrans @*/
00488 
00489 static int pgpPrtSigParams(const pgpPkt pp, byte pubkey_algo, byte sigtype,
00490                 const byte *p)
00491         /*@globals fileSystem @*/
00492         /*@modifies fileSystem @*/
00493 {
00494     const byte * pend = pp->h + pp->hlen;
00495     int i;
00496 
00497     for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
00498         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00499             if (i >= 1) break;
00500             if (_dig &&
00501         (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
00502             {
00503                 switch (i) {
00504                 case 0:         /* m**d */
00505                     (void) mpnsethex(&_dig->c, pgpMpiHex(p));
00506 if (_debug && _print)
00507 fprintf(stderr, "\t  m**d = "),  mpfprintln(stderr, _dig->c.size, _dig->c.data);
00508                     /*@switchbreak@*/ break;
00509                 default:
00510                     /*@switchbreak@*/ break;
00511                 }
00512             }
00513             pgpPrtStr("", pgpSigRSA[i]);
00514         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00515             if (i >= 2) break;
00516             if (_dig &&
00517         (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
00518             {
00519                 int xx;
00520                 xx = 0;
00521                 switch (i) {
00522                 case 0:         /* r */
00523                     xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->r, p, pend);
00524                     /*@switchbreak@*/ break;
00525                 case 1:         /* s */
00526                     xx = pgpHexSet(pgpSigDSA[i], 160, &_dig->s, p, pend);
00527                     /*@switchbreak@*/ break;
00528                 default:
00529                     xx = 1;
00530                     /*@switchbreak@*/ break;
00531                 }
00532                 if (xx) return xx;
00533             }
00534             pgpPrtStr("", pgpSigDSA[i]);
00535         } else {
00536             if (_print)
00537                 fprintf(stderr, "%7d", i);
00538         }
00539         pgpPrtStr("", pgpMpiStr(p));
00540         pgpPrtNL();
00541     }
00542 
00543     return 0;
00544 }
00545 
00546 int pgpPrtSig(const pgpPkt pp)
00547         /*@globals _digp @*/
00548         /*@modifies *_digp @*/
00549 {
00550     byte version = pp->h[0];
00551     byte * p;
00552     unsigned plen;
00553     int rc;
00554 
00555     switch (version) {
00556     case 3:
00557     {   pgpPktSigV3 v = (pgpPktSigV3)pp->h;
00558         time_t t;
00559 
00560         if (v->hashlen != 5)
00561             return 1;
00562 
00563         pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
00564         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00565         pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
00566         pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
00567         pgpPrtNL();
00568         t = pgpGrab(v->time, sizeof(v->time));
00569         if (_print)
00570             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00571         pgpPrtNL();
00572         pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid));
00573         plen = pgpGrab(v->signhash16, sizeof(v->signhash16));
00574         pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16));
00575         pgpPrtNL();
00576 
00577         if (_digp && _digp->pubkey_algo == 0) {
00578             _digp->version = v->version;
00579             _digp->hashlen = v->hashlen;
00580             _digp->sigtype = v->sigtype;
00581             _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen);
00582             memcpy(_digp->time, v->time, sizeof(_digp->time));
00583             memcpy(_digp->signid, v->signid, sizeof(_digp->signid));
00584             _digp->pubkey_algo = v->pubkey_algo;
00585             _digp->hash_algo = v->hash_algo;
00586             memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16));
00587         }
00588 
00589         p = ((byte *)v) + sizeof(*v);
00590         rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
00591     }   break;
00592     case 4:
00593     {   pgpPktSigV4 v = (pgpPktSigV4)pp->h;
00594 
00595         pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
00596         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00597         pgpPrtVal(" ", pgpHashTbl, v->hash_algo);
00598         pgpPrtVal(" ", pgpSigTypeTbl, v->sigtype);
00599         pgpPrtNL();
00600 
00601         p = &v->hashlen[0];
00602         plen = pgpGrab(v->hashlen, sizeof(v->hashlen));
00603         p += sizeof(v->hashlen);
00604 
00605         if ((p + plen) > (pp->h + pp->hlen))
00606             return 1;
00607 
00608 if (_debug && _print)
00609 fprintf(stderr, "   hash[%u] -- %s\n", plen, pgpHexStr(p, plen));
00610         if (_digp && _digp->pubkey_algo == 0) {
00611             _digp->hashlen = sizeof(*v) + plen;
00612             _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen);
00613         }
00614         (void) pgpPrtSubType(p, plen, v->sigtype);
00615         p += plen;
00616 
00617         plen = pgpGrab(p,2);
00618         p += 2;
00619 
00620         if ((p + plen) > (pp->h + pp->hlen))
00621             return 1;
00622 
00623 if (_debug && _print)
00624 fprintf(stderr, " unhash[%u] -- %s\n", plen, pgpHexStr(p, plen));
00625         (void) pgpPrtSubType(p, plen, v->sigtype);
00626         p += plen;
00627 
00628         plen = pgpGrab(p,2);
00629         pgpPrtHex(" signhash16", p, 2);
00630         pgpPrtNL();
00631 
00632         if (_digp && _digp->pubkey_algo == 0) {
00633             _digp->version = v->version;
00634             _digp->sigtype = v->sigtype;
00635             _digp->pubkey_algo = v->pubkey_algo;
00636             _digp->hash_algo = v->hash_algo;
00637             memcpy(_digp->signhash16, p, sizeof(_digp->signhash16));
00638         }
00639 
00640         p += 2;
00641         if (p > (pp->h + pp->hlen))
00642             return 1;
00643 
00644         rc = pgpPrtSigParams(pp, v->pubkey_algo, v->sigtype, p);
00645     }   break;
00646     default:
00647         rc = 1;
00648         break;
00649     }
00650     return rc;
00651 }
00652 
00653 /*@-varuse =readonlytrans @*/
00654 /*@observer@*/ /*@unchecked@*/
00655 static const char * pgpPublicRSA[] = {
00656     "    n =",
00657     "    e =",
00658     NULL,
00659 };
00660 
00661 #ifdef NOTYET
00662 /*@observer@*/ /*@unchecked@*/
00663 static const char * pgpSecretRSA[] = {
00664     "    d =",
00665     "    p =",
00666     "    q =",
00667     "    u =",
00668     NULL,
00669 };
00670 #endif
00671 
00672 /*@observer@*/ /*@unchecked@*/
00673 static const char * pgpPublicDSA[] = {
00674     "    p =",
00675     "    q =",
00676     "    g =",
00677     "    y =",
00678     NULL,
00679 };
00680 
00681 #ifdef  NOTYET
00682 /*@observer@*/ /*@unchecked@*/
00683 static const char * pgpSecretDSA[] = {
00684     "    x =",
00685     NULL,
00686 };
00687 #endif
00688 
00689 /*@observer@*/ /*@unchecked@*/
00690 static const char * pgpPublicELGAMAL[] = {
00691     "    p =",
00692     "    g =",
00693     "    y =",
00694     NULL,
00695 };
00696 
00697 #ifdef  NOTYET
00698 /*@observer@*/ /*@unchecked@*/
00699 static const char * pgpSecretELGAMAL[] = {
00700     "    x =",
00701     NULL,
00702 };
00703 #endif
00704 /*@=varuse =readonlytrans @*/
00705 
00706 static const byte * pgpPrtPubkeyParams(const pgpPkt pp, byte pubkey_algo,
00707                 /*@returned@*/ const byte *p)
00708         /*@globals fileSystem, internalState @*/
00709         /*@modifies fileSystem, internalState @*/
00710 {
00711     int i;
00712 
00713     for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
00714         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00715             if (i >= 2) break;
00716             if (_dig) {
00717                 switch (i) {
00718                 case 0:         /* n */
00719                     (void) mpbsethex(&_dig->rsa_pk.n, pgpMpiHex(p));
00720 if (_debug && _print)
00721 fprintf(stderr, "\t     n = "),  mpfprintln(stderr, _dig->rsa_pk.n.size, _dig->rsa_pk.n.modl);
00722                     /*@switchbreak@*/ break;
00723                 case 1:         /* e */
00724                     (void) mpnsethex(&_dig->rsa_pk.e, pgpMpiHex(p));
00725 if (_debug && _print)
00726 fprintf(stderr, "\t     e = "),  mpfprintln(stderr, _dig->rsa_pk.e.size, _dig->rsa_pk.e.data);
00727                     /*@switchbreak@*/ break;
00728                 default:
00729                     /*@switchbreak@*/ break;
00730                 }
00731             }
00732             pgpPrtStr("", pgpPublicRSA[i]);
00733         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00734             if (i >= 4) break;
00735             if (_dig) {
00736                 switch (i) {
00737                 case 0:         /* p */
00738                     (void) mpbsethex(&_dig->p, pgpMpiHex(p));
00739 if (_debug && _print)
00740 fprintf(stderr, "\t     p = "),  mpfprintln(stderr, _dig->p.size, _dig->p.modl);
00741                     /*@switchbreak@*/ break;
00742                 case 1:         /* q */
00743                     (void) mpbsethex(&_dig->q, pgpMpiHex(p));
00744 if (_debug && _print)
00745 fprintf(stderr, "\t     q = "),  mpfprintln(stderr, _dig->q.size, _dig->q.modl);
00746                     /*@switchbreak@*/ break;
00747                 case 2:         /* g */
00748                     (void) mpnsethex(&_dig->g, pgpMpiHex(p));
00749 if (_debug && _print)
00750 fprintf(stderr, "\t     g = "),  mpfprintln(stderr, _dig->g.size, _dig->g.data);
00751                     /*@switchbreak@*/ break;
00752                 case 3:         /* y */
00753                     (void) mpnsethex(&_dig->y, pgpMpiHex(p));
00754 if (_debug && _print)
00755 fprintf(stderr, "\t     y = "),  mpfprintln(stderr, _dig->y.size, _dig->y.data);
00756                     /*@switchbreak@*/ break;
00757                 default:
00758                     /*@switchbreak@*/ break;
00759                 }
00760             }
00761             pgpPrtStr("", pgpPublicDSA[i]);
00762         } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
00763             if (i >= 3) break;
00764             pgpPrtStr("", pgpPublicELGAMAL[i]);
00765         } else {
00766             if (_print)
00767                 fprintf(stderr, "%7d", i);
00768         }
00769         pgpPrtStr("", pgpMpiStr(p));
00770         pgpPrtNL();
00771     }
00772 
00773     return p;
00774 }
00775 
00776 static const byte * pgpPrtSeckeyParams(const pgpPkt pp, /*@unused@*/ byte pubkey_algo,
00777                 /*@returned@*/ const byte *p)
00778         /*@globals fileSystem @*/
00779         /*@modifies fileSystem @*/
00780 {
00781     int i;
00782 
00783     switch (*p) {
00784     case 0:
00785         pgpPrtVal(" ", pgpSymkeyTbl, *p);
00786         break;
00787     case 255:
00788         p++;
00789         pgpPrtVal(" ", pgpSymkeyTbl, *p);
00790         switch (p[1]) {
00791         case 0x00:
00792             pgpPrtVal(" simple ", pgpHashTbl, p[2]);
00793             p += 2;
00794             /*@innerbreak@*/ break;
00795         case 0x01:
00796             pgpPrtVal(" salted ", pgpHashTbl, p[2]);
00797             pgpPrtHex("", p+3, 8);
00798             p += 10;
00799             /*@innerbreak@*/ break;
00800         case 0x03:
00801             pgpPrtVal(" iterated/salted ", pgpHashTbl, p[2]);
00802             /*@-shiftnegative -shiftimplementation @*/ /* FIX: unsigned cast */
00803             i = (16 + (p[11] & 0xf)) << ((p[11] >> 4) + 6);
00804             /*@=shiftnegative =shiftimplementation @*/
00805             pgpPrtHex("", p+3, 8);
00806             pgpPrtInt(" iter", i);
00807             p += 11;
00808             /*@innerbreak@*/ break;
00809         }
00810         break;
00811     default:
00812         pgpPrtVal(" ", pgpSymkeyTbl, *p);
00813         pgpPrtHex(" IV", p+1, 8);
00814         p += 8;
00815         break;
00816     }
00817     pgpPrtNL();
00818 
00819     p++;
00820 
00821 #ifdef  NOTYET  /* XXX encrypted MPI's need to be handled. */
00822     for (i = 0; p < &pp->h[pp->hlen]; i++, p += pgpMpiLen(p)) {
00823         if (pubkey_algo == PGPPUBKEYALGO_RSA) {
00824             if (pgpSecretRSA[i] == NULL) break;
00825             pgpPrtStr("", pgpSecretRSA[i]);
00826         } else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
00827             if (pgpSecretDSA[i] == NULL) break;
00828             pgpPrtStr("", pgpSecretDSA[i]);
00829         } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
00830             if (pgpSecretELGAMAL[i] == NULL) break;
00831             pgpPrtStr("", pgpSecretELGAMAL[i]);
00832         } else {
00833             if (_print)
00834                 fprintf(stderr, "%7d", i);
00835         }
00836         pgpPrtStr("", pgpMpiStr(p));
00837         pgpPrtNL();
00838     }
00839 #else
00840     pgpPrtHex(" secret", p, (pp->hlen - (p - pp->h) - 2));
00841     pgpPrtNL();
00842     p += (pp->hlen - (p - pp->h) - 2);
00843 #endif
00844     pgpPrtHex(" checksum", p, 2);
00845     pgpPrtNL();
00846 
00847     return p;
00848 }
00849 
00850 int pgpPrtKey(const pgpPkt pp)
00851         /*@globals _digp @*/
00852         /*@modifies *_digp @*/
00853 {
00854     byte version = pp->h[0];
00855     const byte * p;
00856     unsigned plen;
00857     time_t t;
00858     int rc;
00859 
00860     switch (version) {
00861     case 3:
00862     {   pgpPktKeyV3 v = (pgpPktKeyV3)pp->h;
00863         pgpPrtVal("V3 ", pgpTagTbl, pp->tag);
00864         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00865         t = pgpGrab(v->time, sizeof(v->time));
00866         if (_print)
00867             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00868         plen = pgpGrab(v->valid, sizeof(v->valid));
00869         if (plen != 0)
00870             fprintf(stderr, " valid %u days", plen);
00871         pgpPrtNL();
00872 
00873         if (_digp && _digp->tag == pp->tag) {
00874             _digp->version = v->version;
00875             memcpy(_digp->time, v->time, sizeof(_digp->time));
00876             _digp->pubkey_algo = v->pubkey_algo;
00877         }
00878 
00879         p = ((byte *)v) + sizeof(*v);
00880         p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
00881         rc = 0;
00882     }   break;
00883     case 4:
00884     {   pgpPktKeyV4 v = (pgpPktKeyV4)pp->h;
00885         pgpPrtVal("V4 ", pgpTagTbl, pp->tag);
00886         pgpPrtVal(" ", pgpPubkeyTbl, v->pubkey_algo);
00887         t = pgpGrab(v->time, sizeof(v->time));
00888         if (_print)
00889             fprintf(stderr, " %-24.24s(0x%08x)", ctime(&t), (unsigned)t);
00890         pgpPrtNL();
00891 
00892         if (_digp && _digp->tag == pp->tag) {
00893             _digp->version = v->version;
00894             memcpy(_digp->time, v->time, sizeof(_digp->time));
00895             _digp->pubkey_algo = v->pubkey_algo;
00896         }
00897 
00898         p = ((byte *)v) + sizeof(*v);
00899         p = pgpPrtPubkeyParams(pp, v->pubkey_algo, p);
00900         if (!(pp->tag == PGPTAG_PUBLIC_KEY || pp->tag == PGPTAG_PUBLIC_SUBKEY))
00901             p = pgpPrtSeckeyParams(pp, v->pubkey_algo, p);
00902         rc = 0;
00903     }   break;
00904     default:
00905         rc = 1;
00906         break;
00907     }
00908     return rc;
00909 }
00910 
00911 /*@-boundswrite@*/
00912 int pgpPrtUserID(const pgpPkt pp)
00913         /*@globals _digp @*/
00914         /*@modifies *_digp @*/
00915 {
00916     pgpPrtVal("", pgpTagTbl, pp->tag);
00917     if (_print)
00918         fprintf(stderr, " \"%.*s\"", (int)pp->hlen, (const char *)pp->h);
00919     pgpPrtNL();
00920     if (_digp) {
00921         char * t = memcpy(xmalloc(pp->hlen+1), pp->h, pp->hlen);
00922         t[pp->hlen] = '\0';
00923         _digp->userid = _free(_digp->userid);
00924         _digp->userid = t;
00925     }
00926     return 0;
00927 }
00928 /*@=boundswrite@*/
00929 
00930 int pgpPrtComment(const pgpPkt pp)
00931 {
00932     const byte * h = pp->h;
00933     int i = pp->hlen;
00934 
00935     pgpPrtVal("", pgpTagTbl, pp->tag);
00936     if (_print)
00937         fprintf(stderr, " ");
00938     while (i > 0) {
00939         int j;
00940         if (*h >= ' ' && *h <= 'z') {
00941             j = 0;
00942             while (j < i && h[j] != '\0')
00943                 j++;
00944             while (j < i && h[j] == '\0')
00945                 j++;
00946             if (_print && j)
00947                 fprintf(stderr, "%.*s", (int)strlen((const char *)h), (const char *)h);
00948         } else {
00949             pgpPrtHex("", h, i);
00950             j = i;
00951         }
00952         i -= j;
00953         h += j;
00954     }
00955     pgpPrtNL();
00956     return 0;
00957 }
00958 
00959 int pgpPktLen(const byte *pkt, unsigned int pleft, pgpPkt pp)
00960 {
00961     unsigned int val = *pkt;
00962     unsigned int plen;
00963 
00964     memset(pp, 0, sizeof(*pp));
00965     /* XXX can't deal with these. */
00966     if (!(val & 0x80))
00967         return -1;
00968 
00969     if (val & 0x40) {
00970         pp->tag = (val & 0x3f);
00971         plen = pgpLen(pkt+1, &pp->hlen);
00972     } else {
00973         pp->tag = (val >> 2) & 0xf;
00974         plen = (1 << (val & 0x3));
00975         pp->hlen = pgpGrab(pkt+1, plen);
00976     }
00977 
00978     pp->pktlen = 1 + plen + pp->hlen;
00979     if (pleft > 0 && pp->pktlen > pleft)
00980         return -1;
00981 
00982 /*@-assignexpose@*/
00983     pp->h = pkt + 1 + plen;
00984 /*@=assignexpose@*/
00985 
00986     return pp->pktlen;
00987 }
00988 
00989 int pgpPubkeyFingerprint(const byte * pkt, unsigned int pktlen, byte * keyid)
00990 {
00991     pgpPkt pp = alloca(sizeof(*pp));
00992     int rc = pgpPktLen(pkt, pktlen, pp);
00993     const byte *se;
00994     int i;
00995 
00996     /* Pubkeys only please. */
00997     if (pp->tag != PGPTAG_PUBLIC_KEY)
00998         return -1;
00999 
01000     /* Choose the correct keyid. */
01001     switch (pp->h[0]) {
01002     default:    return -1;
01003     case 3:
01004       { pgpPktKeyV3 v = (pgpPktKeyV3) (pp->h);
01005         se = (byte *)(v + 1);
01006         switch (v->pubkey_algo) {
01007         default:        return -1;
01008         case PGPPUBKEYALGO_RSA:
01009             se += pgpMpiLen(se);
01010             memmove(keyid, (se-8), 8);
01011             /*@innerbreak@*/ break;
01012         }
01013       } break;
01014     case 4:
01015       { pgpPktKeyV4 v = (pgpPktKeyV4) (pp->h);
01016         byte * d = NULL;
01017         size_t dlen = 0;
01018 
01019         se = (byte *)(v + 1);
01020         switch (v->pubkey_algo) {
01021         default:        return -1;
01022         case PGPPUBKEYALGO_RSA:
01023             for (i = 0; i < 2; i++)
01024                 se += pgpMpiLen(se);
01025             /*@innerbreak@*/ break;
01026         case PGPPUBKEYALGO_DSA:
01027             for (i = 0; i < 4; i++)
01028                 se += pgpMpiLen(se);
01029             /*@innerbreak@*/ break;
01030         }
01031         {   DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
01032             (void) rpmDigestUpdate(ctx, pkt, (se-pkt));
01033             (void) rpmDigestFinal(ctx, (void **)&d, &dlen, 0);
01034         }
01035 
01036 /*@-boundswrite@*/
01037         memmove(keyid, (d + (dlen-8)), 8);
01038 /*@=boundswrite@*/
01039         d = _free(d);
01040       } break;
01041     }
01042     return 0;
01043 }
01044 
01045 int pgpExtractPubkeyFingerprint(const char * b64pkt, byte * keyid)
01046 {
01047     const byte * pkt;
01048     ssize_t pktlen;
01049 
01050     if (b64decode(b64pkt, (void **)&pkt, &pktlen))
01051         return -1;      /* on error */
01052     (void) pgpPubkeyFingerprint(pkt, pktlen, keyid);
01053     pkt = _free(pkt);
01054     return 8;   /* no. of bytes of pubkey signid */
01055 }
01056 
01057 int pgpPrtPkt(const byte *pkt, unsigned int pleft)
01058 {
01059     pgpPkt pp = alloca(sizeof(*pp));
01060     int rc = pgpPktLen(pkt, pleft, pp);
01061 
01062     if (rc < 0)
01063         return rc;
01064 
01065     switch (pp->tag) {
01066     case PGPTAG_SIGNATURE:
01067         rc = pgpPrtSig(pp);
01068         break;
01069     case PGPTAG_PUBLIC_KEY:
01070         /* Get the public key fingerprint. */
01071         if (_digp) {
01072 /*@-mods@*/
01073             if (!pgpPubkeyFingerprint(pkt, pp->pktlen, _digp->signid))
01074                 _digp->saved |= PGPDIG_SAVED_ID;
01075             else
01076                 memset(_digp->signid, 0, sizeof(_digp->signid));
01077 /*@=mods@*/
01078         }
01079         /*@fallthrough@*/
01080     case PGPTAG_PUBLIC_SUBKEY:
01081         rc = pgpPrtKey(pp);
01082         break;
01083     case PGPTAG_SECRET_KEY:
01084     case PGPTAG_SECRET_SUBKEY:
01085         rc = pgpPrtKey(pp);
01086         break;
01087     case PGPTAG_USER_ID:
01088         rc = pgpPrtUserID(pp);
01089         break;
01090     case PGPTAG_COMMENT:
01091     case PGPTAG_COMMENT_OLD:
01092         rc = pgpPrtComment(pp);
01093         break;
01094 
01095     case PGPTAG_RESERVED:
01096     case PGPTAG_PUBLIC_SESSION_KEY:
01097     case PGPTAG_SYMMETRIC_SESSION_KEY:
01098     case PGPTAG_COMPRESSED_DATA:
01099     case PGPTAG_SYMMETRIC_DATA:
01100     case PGPTAG_MARKER:
01101     case PGPTAG_LITERAL_DATA:
01102     case PGPTAG_TRUST:
01103     case PGPTAG_PHOTOID:
01104     case PGPTAG_ENCRYPTED_MDC:
01105     case PGPTAG_MDC:
01106     case PGPTAG_PRIVATE_60:
01107     case PGPTAG_PRIVATE_62:
01108     case PGPTAG_CONTROL:
01109     default:
01110         pgpPrtVal("", pgpTagTbl, pp->tag);
01111         pgpPrtHex("", pp->h, pp->hlen);
01112         pgpPrtNL();
01113         rc = 0;
01114         break;
01115     }
01116 
01117     return (rc ? -1 : pp->pktlen);
01118 }
01119 
01120 pgpDig pgpNewDig(void)
01121 {
01122     pgpDig dig = xcalloc(1, sizeof(*dig));
01123     return dig;
01124 }
01125 
01126 /*@-boundswrite@*/
01127 void pgpCleanDig(pgpDig dig)
01128 {
01129     if (dig != NULL) {
01130         int i;
01131         dig->signature.userid = _free(dig->signature.userid);
01132         dig->pubkey.userid = _free(dig->pubkey.userid);
01133         dig->ppkts = _free(dig->ppkts);
01134         dig->npkts = 0;
01135         dig->signature.hash = _free(dig->signature.hash);
01136         dig->pubkey.hash = _free(dig->pubkey.hash);
01137         /*@-unqualifiedtrans@*/ /* FIX: double indirection */
01138         for (i = 0; i < 4; i++) {
01139             dig->signature.params[i] = _free(dig->signature.params[i]);
01140             dig->pubkey.params[i] = _free(dig->pubkey.params[i]);
01141         }
01142         /*@=unqualifiedtrans@*/
01143 
01144         memset(&dig->signature, 0, sizeof(dig->signature));
01145         memset(&dig->pubkey, 0, sizeof(dig->pubkey));
01146 
01147         dig->md5 = _free(dig->md5);
01148         dig->sha1 = _free(dig->sha1);
01149         mpnfree(&dig->hm);
01150         mpnfree(&dig->r);
01151         mpnfree(&dig->s);
01152 
01153         (void) rsapkFree(&dig->rsa_pk);
01154         mpnfree(&dig->m);
01155         mpnfree(&dig->c);
01156         mpnfree(&dig->rsahm);
01157     }
01158 /*@-nullstate@*/
01159     return;
01160 /*@=nullstate@*/
01161 }
01162 /*@=boundswrite@*/
01163 
01164 pgpDig pgpFreeDig(/*@only@*/ /*@null@*/ pgpDig dig)
01165         /*@modifies dig @*/
01166 {
01167     if (dig != NULL) {
01168 
01169         /* DUmp the signature/pubkey data. */
01170         pgpCleanDig(dig);
01171 
01172         /*@-branchstate@*/
01173         if (dig->hdrsha1ctx != NULL)
01174             (void) rpmDigestFinal(dig->hdrsha1ctx, NULL, NULL, 0);
01175         /*@=branchstate@*/
01176         dig->hdrsha1ctx = NULL;
01177 
01178         /*@-branchstate@*/
01179         if (dig->sha1ctx != NULL)
01180             (void) rpmDigestFinal(dig->sha1ctx, NULL, NULL, 0);
01181         /*@=branchstate@*/
01182         dig->sha1ctx = NULL;
01183 
01184         mpbfree(&dig->p);
01185         mpbfree(&dig->q);
01186         mpnfree(&dig->g);
01187         mpnfree(&dig->y);
01188         mpnfree(&dig->hm);
01189         mpnfree(&dig->r);
01190         mpnfree(&dig->s);
01191 
01192 #ifdef  NOTYET
01193         /*@-branchstate@*/
01194         if (dig->hdrmd5ctx != NULL)
01195             (void) rpmDigestFinal(dig->hdrmd5ctx, NULL, NULL, 0);
01196         /*@=branchstate@*/
01197         dig->hdrmd5ctx = NULL;
01198 #endif
01199 
01200         /*@-branchstate@*/
01201         if (dig->md5ctx != NULL)
01202             (void) rpmDigestFinal(dig->md5ctx, NULL, NULL, 0);
01203         /*@=branchstate@*/
01204         dig->md5ctx = NULL;
01205 
01206         mpbfree(&dig->rsa_pk.n);
01207         mpnfree(&dig->rsa_pk.e);
01208         mpnfree(&dig->m);
01209         mpnfree(&dig->c);
01210         mpnfree(&dig->hm);
01211 
01212         dig = _free(dig);
01213     }
01214     return dig;
01215 }
01216 
01217 static int pgpGrabPkts(const byte * pkts, unsigned int pktlen,
01218                 /*@out@*/ byte *** pppkts, /*@out@*/ int * pnpkts)
01219         /*@modifies *pppkts, *pnpkts @*/
01220 {
01221     pgpPkt pp = alloca(sizeof(*pp));
01222     const byte *p;
01223     unsigned int pleft;
01224     int len;
01225     int npkts = 0;
01226     byte ** ppkts;
01227 
01228     for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
01229         if (pgpPktLen(p, pleft, pp) < 0)
01230             return -1;
01231         len = pp->pktlen;
01232         npkts++;
01233     }
01234     if (npkts <= 0)
01235         return -2;
01236 
01237     ppkts = xcalloc(npkts, sizeof(*ppkts));
01238 
01239     npkts = 0;
01240     for (p = pkts, pleft = pktlen; p < (pkts + pktlen); p += len, pleft -= len) {
01241   
01242         if (pgpPktLen(p, pleft, pp) < 0)
01243             return -1;
01244         len = pp->pktlen;
01245         ppkts[npkts++] = (byte *) p;
01246     }
01247 
01248 /*@-branchstate@*/
01249     if (pppkts != NULL)
01250         *pppkts = ppkts;
01251    else
01252         ppkts = _free(ppkts);
01253 /*@=branchstate@*/
01254 
01255     if (pnpkts != NULL)
01256         *pnpkts = npkts;
01257 
01258     return 0;
01259 }
01260 
01261 int pgpPrtPkts(const byte * pkts, unsigned int pktlen, pgpDig dig, int printing)
01262         /*@globals _dig, _digp, _print @*/
01263         /*@modifies _dig, _digp, *_digp, _print @*/
01264 {
01265     pgpPkt pp = alloca(sizeof(*pp));
01266     unsigned int val = *pkts;
01267     unsigned int pleft;
01268     int len;
01269     byte ** ppkts = NULL;
01270     int npkts;
01271     int i;
01272 
01273     _print = printing;
01274     _dig = dig;
01275     if (dig != NULL && (val & 0x80)) {
01276         pgpTag tag = (val & 0x40) ? (val & 0x3f) : ((val >> 2) & 0xf);
01277         _digp = (tag == PGPTAG_SIGNATURE) ? &_dig->signature : &_dig->pubkey;
01278         _digp->tag = tag;
01279     } else
01280         _digp = NULL;
01281 
01282     if (pgpGrabPkts(pkts, pktlen, &ppkts, &npkts) || ppkts == NULL)
01283         return -1;
01284 
01285     if (ppkts != NULL)
01286     for (i = 0, pleft = pktlen; i < npkts; i++, pleft -= len) {
01287         len = pgpPktLen(ppkts[i], pleft, pp);
01288         len = pgpPrtPkt(ppkts[i], pp->pktlen);
01289     }
01290 
01291 /*@-branchstate@*/
01292     if (dig != NULL) {
01293         dig->ppkts = _free(dig->ppkts);         /* XXX memory leak plugged. */
01294         dig->ppkts = ppkts;
01295         dig->npkts = npkts;
01296     } else
01297         ppkts = _free(ppkts);
01298 /*@=branchstate@*/
01299 
01300     return 0;
01301 }
01302 
01303 /*@-boundswrite@*/
01304 pgpArmor pgpReadPkts(const char * fn, const byte ** pkt, size_t * pktlen)
01305 {
01306     const byte * b = NULL;
01307     ssize_t blen;
01308     const char * enc = NULL;
01309     const char * crcenc = NULL;
01310     byte * dec;
01311     byte * crcdec;
01312     size_t declen;
01313     size_t crclen;
01314     uint32_t crcpkt, crc;
01315     const char * armortype = NULL;
01316     char * t, * te;
01317     int pstate = 0;
01318     pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;    /* XXX assume failure */
01319     int rc;
01320 
01321     rc = rpmioSlurp(fn, &b, &blen);
01322     if (rc || b == NULL || blen <= 0) {
01323         goto exit;
01324     }
01325 
01326     if (pgpIsPkt(b)) {
01327 #ifdef NOTYET   /* XXX ASCII Pubkeys only, please. */
01328         ec = 0; /* XXX fish out pkt type. */
01329 #endif
01330         goto exit;
01331     }
01332 
01333 #define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
01334 
01335     for (t = (char *)b; t && *t; t = te) {
01336         if ((te = strchr(t, '\n')) == NULL)
01337             te = t + strlen(t);
01338         else
01339             te++;
01340 
01341         switch (pstate) {
01342         case 0:
01343             armortype = NULL;
01344             if (!TOKEQ(t, "-----BEGIN PGP "))
01345                 continue;
01346             t += sizeof("-----BEGIN PGP ")-1;
01347 
01348             rc = pgpValTok(pgpArmorTbl, t, te);
01349             if (rc < 0) {
01350                 ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE;
01351                 goto exit;
01352             }
01353             if (rc != PGPARMOR_PUBKEY)  /* XXX ASCII Pubkeys only, please. */
01354                 continue;
01355             armortype = t;
01356 
01357             t = strchr(t, '\n');
01358             if (t == NULL)
01359                 continue;
01360             if (t[-1] == '\r')
01361                 --t;
01362             t -= (sizeof("-----")-1);
01363             if (!TOKEQ(t, "-----"))
01364                 continue;
01365             *t = '\0';
01366             pstate++;
01367             /*@switchbreak@*/ break;
01368         case 1:
01369             enc = NULL;
01370             rc = pgpValTok(pgpArmorKeyTbl, t, te);
01371             if (rc >= 0)
01372                 continue;
01373             if (!(*t == '\n' || *t == '\r')) {
01374                 pstate = 0;
01375                 continue;
01376             }
01377             enc = te;           /* Start of encoded packets */
01378             pstate++;
01379             /*@switchbreak@*/ break;
01380         case 2:
01381             crcenc = NULL;
01382             if (*t != '=')
01383                 continue;
01384             *t++ = '\0';        /* Terminate encoded packets */
01385             crcenc = t;         /* Start of encoded crc */
01386             pstate++;
01387             /*@switchbreak@*/ break;
01388         case 3:
01389             pstate = 0;
01390             if (!TOKEQ(t, "-----END PGP ")) {
01391                 ec = PGPARMOR_ERR_NO_END_PGP;
01392                 goto exit;
01393             }
01394             *t = '\0';          /* Terminate encoded crc */
01395             t += sizeof("-----END PGP ")-1;
01396             if (t >= te) continue;
01397 
01398             if (armortype == NULL) /* XXX can't happen */
01399                 continue;
01400             rc = strncmp(t, armortype, strlen(armortype));
01401             if (rc)
01402                 continue;
01403 
01404             t += strlen(armortype);
01405             if (t >= te) continue;
01406 
01407             if (!TOKEQ(t, "-----")) {
01408                 ec = PGPARMOR_ERR_NO_END_PGP;
01409                 goto exit;
01410             }
01411             t += (sizeof("-----")-1);
01412             if (t >= te) continue;
01413             /* XXX permitting \r here is not RFC-2440 compliant <shrug> */
01414             if (!(*t == '\n' || *t == '\r')) continue;
01415 
01416             crcdec = NULL;
01417             crclen = 0;
01418             if (b64decode(crcenc, (void **)&crcdec, &crclen) != 0) {
01419                 ec = PGPARMOR_ERR_CRC_DECODE;
01420                 goto exit;
01421             }
01422             crcpkt = pgpGrab(crcdec, crclen);
01423             crcdec = _free(crcdec);
01424             dec = NULL;
01425             declen = 0;
01426             if (b64decode(enc, (void **)&dec, &declen) != 0) {
01427                 ec = PGPARMOR_ERR_BODY_DECODE;
01428                 goto exit;
01429             }
01430             crc = pgpCRC(dec, declen);
01431             if (crcpkt != crc) {
01432                 ec = PGPARMOR_ERR_CRC_CHECK;
01433                 goto exit;
01434             }
01435             b = _free(b);
01436             b = dec;
01437             blen = declen;
01438             ec = PGPARMOR_PUBKEY;       /* XXX ASCII Pubkeys only, please. */
01439             goto exit;
01440             /*@notreached@*/ /*@switchbreak@*/ break;
01441         }
01442     }
01443     ec = PGPARMOR_NONE;
01444 
01445 exit:
01446     if (ec > PGPARMOR_NONE && pkt)
01447         *pkt = b;
01448     else if (b != NULL)
01449         b = _free(b);
01450     if (pktlen)
01451         *pktlen = blen;
01452     return ec;
01453 }
01454 /*@=boundswrite@*/
01455 
01456 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
01457 {
01458     const char * enc;
01459     char * t;
01460     size_t nt;
01461     char * val;
01462     int lc;
01463 
01464     nt = ((ns + 2) / 3) * 4;
01465     /*@-globs@*/
01466     /* Add additional bytes necessary for eol string(s). */
01467     if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
01468         lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
01469        if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
01470         ++lc;
01471         nt += lc * strlen(b64encode_eolstr);
01472     }
01473     /*@=globs@*/
01474 
01475     nt += 512;  /* XXX slop for armor and crc */
01476 
01477 /*@-boundswrite@*/
01478     val = t = xmalloc(nt + 1);
01479     *t = '\0';
01480     t = stpcpy(t, "-----BEGIN PGP ");
01481     t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
01482     /*@-globs@*/
01483     t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), VERSION);
01484     /*@=globs@*/
01485     t = stpcpy(t, " (beecrypt-4.1.2)\n\n");
01486 
01487     if ((enc = b64encode(s, ns)) != NULL) {
01488         t = stpcpy(t, enc);
01489         enc = _free(enc);
01490         if ((enc = b64crc(s, ns)) != NULL) {
01491             *t++ = '=';
01492             t = stpcpy(t, enc);
01493             enc = _free(enc);
01494         }
01495     }
01496         
01497     t = stpcpy(t, "-----END PGP ");
01498     t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
01499     t = stpcpy(t, "-----\n");
01500 /*@=boundswrite@*/
01501 
01502     return val;
01503 }
01504 
01505 /*@=boundsread@*/

Generated on Wed Feb 6 22:32:15 2008 for rpm by  doxygen 1.5.1