Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "postgres.h"
00032
00033 #include "px.h"
00034 #include "mbuf.h"
00035 #include "pgp.h"
00036
00037 static int
00038 read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
00039 {
00040 int res;
00041 PGP_PubKey *pk = NULL;
00042
00043 res = _pgp_read_public_key(pkt, &pk);
00044 if (res < 0)
00045 goto err;
00046
00047
00048 res = pgp_skip_packet(pkt);
00049 if (res < 0)
00050 goto err;
00051
00052
00053 switch (pk->algo)
00054 {
00055 case PGP_PUB_ELG_ENCRYPT:
00056 case PGP_PUB_RSA_ENCRYPT:
00057 case PGP_PUB_RSA_ENCRYPT_SIGN:
00058 memcpy(keyid_buf, pk->key_id, 8);
00059 res = 1;
00060 break;
00061 default:
00062 res = 0;
00063 }
00064
00065 err:
00066 pgp_key_free(pk);
00067 return res;
00068 }
00069
00070 static int
00071 read_pubenc_keyid(PullFilter *pkt, uint8 *keyid_buf)
00072 {
00073 uint8 ver;
00074 int res;
00075
00076 GETBYTE(pkt, ver);
00077 if (ver != 3)
00078 return -1;
00079
00080 res = pullf_read_fixed(pkt, 8, keyid_buf);
00081 if (res < 0)
00082 return res;
00083
00084 return pgp_skip_packet(pkt);
00085 }
00086
00087 static const char hextbl[] = "0123456789ABCDEF";
00088
00089 static int
00090 print_key(uint8 *keyid, char *dst)
00091 {
00092 int i;
00093 unsigned c;
00094
00095 for (i = 0; i < 8; i++)
00096 {
00097 c = keyid[i];
00098 *dst++ = hextbl[(c >> 4) & 0x0F];
00099 *dst++ = hextbl[c & 0x0F];
00100 }
00101 *dst = 0;
00102 return 8 * 2;
00103 }
00104
00105 static const uint8 any_key[] =
00106 {0, 0, 0, 0, 0, 0, 0, 0};
00107
00108
00109
00110
00111 int
00112 pgp_get_keyid(MBuf *pgp_data, char *dst)
00113 {
00114 int res;
00115 PullFilter *src;
00116 PullFilter *pkt = NULL;
00117 int len;
00118 uint8 tag;
00119 int got_pub_key = 0,
00120 got_symenc_key = 0,
00121 got_pubenc_key = 0;
00122 int got_data = 0;
00123 uint8 keyid_buf[8];
00124 int got_main_key = 0;
00125
00126
00127 res = pullf_create_mbuf_reader(&src, pgp_data);
00128 if (res < 0)
00129 return res;
00130
00131 while (1)
00132 {
00133 res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
00134 if (res <= 0)
00135 break;
00136 res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
00137 if (res < 0)
00138 break;
00139
00140 switch (tag)
00141 {
00142 case PGP_PKT_SECRET_KEY:
00143 case PGP_PKT_PUBLIC_KEY:
00144
00145 if (!got_main_key)
00146 {
00147 got_main_key = 1;
00148 res = pgp_skip_packet(pkt);
00149 }
00150 else
00151 res = PXE_PGP_MULTIPLE_KEYS;
00152 break;
00153 case PGP_PKT_SECRET_SUBKEY:
00154 case PGP_PKT_PUBLIC_SUBKEY:
00155 res = read_pubkey_keyid(pkt, keyid_buf);
00156 if (res < 0)
00157 break;
00158 if (res > 0)
00159 got_pub_key++;
00160 break;
00161 case PGP_PKT_PUBENCRYPTED_SESSKEY:
00162 got_pubenc_key++;
00163 res = read_pubenc_keyid(pkt, keyid_buf);
00164 break;
00165 case PGP_PKT_SYMENCRYPTED_DATA:
00166 case PGP_PKT_SYMENCRYPTED_DATA_MDC:
00167
00168 got_data = 1;
00169 break;
00170 case PGP_PKT_SYMENCRYPTED_SESSKEY:
00171 got_symenc_key++;
00172
00173 case PGP_PKT_SIGNATURE:
00174 case PGP_PKT_MARKER:
00175 case PGP_PKT_TRUST:
00176 case PGP_PKT_USER_ID:
00177 case PGP_PKT_USER_ATTR:
00178 case PGP_PKT_PRIV_61:
00179 res = pgp_skip_packet(pkt);
00180 break;
00181 default:
00182 res = PXE_PGP_CORRUPT_DATA;
00183 }
00184
00185 if (pkt)
00186 pullf_free(pkt);
00187 pkt = NULL;
00188
00189 if (res < 0 || got_data)
00190 break;
00191 }
00192
00193 pullf_free(src);
00194 if (pkt)
00195 pullf_free(pkt);
00196
00197 if (res < 0)
00198 return res;
00199
00200
00201 if (got_pub_key && got_pubenc_key)
00202 res = PXE_PGP_CORRUPT_DATA;
00203
00204 if (got_pub_key > 1)
00205 res = PXE_PGP_MULTIPLE_KEYS;
00206
00207 if (got_pubenc_key > 1)
00208 res = PXE_PGP_MULTIPLE_KEYS;
00209
00210
00211
00212
00213 if (res >= 0)
00214 {
00215 if (got_pubenc_key || got_pub_key)
00216 {
00217 if (memcmp(keyid_buf, any_key, 8) == 0)
00218 {
00219 memcpy(dst, "ANYKEY", 7);
00220 res = 6;
00221 }
00222 else
00223 res = print_key(keyid_buf, dst);
00224 }
00225 else if (got_symenc_key)
00226 {
00227 memcpy(dst, "SYMKEY", 7);
00228 res = 6;
00229 }
00230 else
00231 res = PXE_PGP_NO_USABLE_KEY;
00232 }
00233
00234 return res;
00235 }