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

rpmio/rpmpgp.c

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

Generated on Sun Oct 26 13:02:03 2003 for rpm by doxygen1.2.18