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