PostgreSQL Source Code  git master
pgp-pubkey.c File Reference
#include "postgres.h"
#include "mbuf.h"
#include "pgp.h"
#include "px.h"
Include dependency graph for pgp-pubkey.c:

Go to the source code of this file.

Macros

#define HIDE_CLEAR   0
 
#define HIDE_CKSUM   255
 
#define HIDE_SHA1   254
 

Functions

int pgp_key_alloc (PGP_PubKey **pk_p)
 
void pgp_key_free (PGP_PubKey *pk)
 
static int calc_key_id (PGP_PubKey *pk)
 
int _pgp_read_public_key (PullFilter *pkt, PGP_PubKey **pk_p)
 
static int check_key_sha1 (PullFilter *src, PGP_PubKey *pk)
 
static int check_key_cksum (PullFilter *src, PGP_PubKey *pk)
 
static int process_secret_key (PullFilter *pkt, PGP_PubKey **pk_p, const uint8 *key, int key_len)
 
static int internal_read_key (PullFilter *src, PGP_PubKey **pk_p, const uint8 *psw, int psw_len, int pubtype)
 
int pgp_set_pubkey (PGP_Context *ctx, MBuf *keypkt, const uint8 *key, int key_len, int pubtype)
 

Macro Definition Documentation

◆ HIDE_CKSUM

#define HIDE_CKSUM   255

Definition at line 249 of file pgp-pubkey.c.

◆ HIDE_CLEAR

#define HIDE_CLEAR   0

Definition at line 248 of file pgp-pubkey.c.

◆ HIDE_SHA1

#define HIDE_SHA1   254

Definition at line 250 of file pgp-pubkey.c.

Function Documentation

◆ _pgp_read_public_key()

int _pgp_read_public_key ( PullFilter pkt,
PGP_PubKey **  pk_p 
)

Definition at line 158 of file pgp-pubkey.c.

159 {
160  int res;
161  PGP_PubKey *pk;
162 
163  res = pgp_key_alloc(&pk);
164  if (res < 0)
165  return res;
166 
167  /* get version */
168  GETBYTE(pkt, pk->ver);
169  if (pk->ver != 4)
170  {
172  goto out;
173  }
174 
175  /* read time */
176  res = pullf_read_fixed(pkt, 4, pk->time);
177  if (res < 0)
178  goto out;
179 
180  /* pubkey algorithm */
181  GETBYTE(pkt, pk->algo);
182 
183  switch (pk->algo)
184  {
185  case PGP_PUB_DSA_SIGN:
186  res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
187  if (res < 0)
188  break;
189  res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
190  if (res < 0)
191  break;
192  res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
193  if (res < 0)
194  break;
195  res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
196  if (res < 0)
197  break;
198 
199  res = calc_key_id(pk);
200  break;
201 
202  case PGP_PUB_RSA_SIGN:
203  case PGP_PUB_RSA_ENCRYPT:
205  res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
206  if (res < 0)
207  break;
208  res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
209  if (res < 0)
210  break;
211 
212  res = calc_key_id(pk);
213 
214  if (pk->algo != PGP_PUB_RSA_SIGN)
215  pk->can_encrypt = 1;
216  break;
217 
218  case PGP_PUB_ELG_ENCRYPT:
219  res = pgp_mpi_read(pkt, &pk->pub.elg.p);
220  if (res < 0)
221  break;
222  res = pgp_mpi_read(pkt, &pk->pub.elg.g);
223  if (res < 0)
224  break;
225  res = pgp_mpi_read(pkt, &pk->pub.elg.y);
226  if (res < 0)
227  break;
228 
229  res = calc_key_id(pk);
230 
231  pk->can_encrypt = 1;
232  break;
233 
234  default:
235  px_debug("unknown public algo: %d", pk->algo);
237  }
238 
239 out:
240  if (res < 0)
241  pgp_key_free(pk);
242  else
243  *pk_p = pk;
244 
245  return res;
246 }
#define GETBYTE(x, i)
Definition: hstore_gist.c:40
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
Definition: mbuf.c:301
int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi)
Definition: pgp-mpi.c:80
static int calc_key_id(PGP_PubKey *pk)
Definition: pgp-pubkey.c:84
int pgp_key_alloc(PGP_PubKey **pk_p)
Definition: pgp-pubkey.c:38
void pgp_key_free(PGP_PubKey *pk)
Definition: pgp-pubkey.c:48
@ PGP_PUB_RSA_ENCRYPT_SIGN
Definition: pgp.h:68
@ PGP_PUB_RSA_ENCRYPT
Definition: pgp.h:69
@ PGP_PUB_DSA_SIGN
Definition: pgp.h:72
@ PGP_PUB_RSA_SIGN
Definition: pgp.h:70
@ PGP_PUB_ELG_ENCRYPT
Definition: pgp.h:71
void px_debug(const char *fmt,...)
Definition: px.c:149
#define PXE_PGP_UNKNOWN_PUBALGO
Definition: px.h:79
#define PXE_PGP_NOT_V4_KEYPKT
Definition: px.h:84
uint8 time[4]
Definition: pgp.h:189
int can_encrypt
Definition: pgp.h:236
struct PGP_PubKey::@0::@3 rsa
uint8 algo
Definition: pgp.h:190
struct PGP_PubKey::@0::@2 elg
uint8 ver
Definition: pgp.h:188
struct PGP_PubKey::@0::@4 dsa
union PGP_PubKey::@0 pub

References PGP_PubKey::algo, calc_key_id(), PGP_PubKey::can_encrypt, PGP_PubKey::dsa, PGP_PubKey::elg, GETBYTE, pgp_key_alloc(), pgp_key_free(), pgp_mpi_read(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, PGP_PubKey::pub, pullf_read_fixed(), px_debug(), PXE_PGP_NOT_V4_KEYPKT, PXE_PGP_UNKNOWN_PUBALGO, res, PGP_PubKey::rsa, PGP_PubKey::time, and PGP_PubKey::ver.

Referenced by internal_read_key(), process_secret_key(), and read_pubkey_keyid().

◆ calc_key_id()

static int calc_key_id ( PGP_PubKey pk)
static

Definition at line 84 of file pgp-pubkey.c.

85 {
86  int res;
87  PX_MD *md;
88  int len;
89  uint8 hdr[3];
90  uint8 hash[20];
91 
93  if (res < 0)
94  return res;
95 
96  len = 1 + 4 + 1;
97  switch (pk->algo)
98  {
100  len += 2 + pk->pub.elg.p->bytes;
101  len += 2 + pk->pub.elg.g->bytes;
102  len += 2 + pk->pub.elg.y->bytes;
103  break;
104  case PGP_PUB_RSA_SIGN:
105  case PGP_PUB_RSA_ENCRYPT:
107  len += 2 + pk->pub.rsa.n->bytes;
108  len += 2 + pk->pub.rsa.e->bytes;
109  break;
110  case PGP_PUB_DSA_SIGN:
111  len += 2 + pk->pub.dsa.p->bytes;
112  len += 2 + pk->pub.dsa.q->bytes;
113  len += 2 + pk->pub.dsa.g->bytes;
114  len += 2 + pk->pub.dsa.y->bytes;
115  break;
116  }
117 
118  hdr[0] = 0x99;
119  hdr[1] = len >> 8;
120  hdr[2] = len & 0xFF;
121  px_md_update(md, hdr, 3);
122 
123  px_md_update(md, &pk->ver, 1);
124  px_md_update(md, pk->time, 4);
125  px_md_update(md, &pk->algo, 1);
126 
127  switch (pk->algo)
128  {
129  case PGP_PUB_ELG_ENCRYPT:
130  pgp_mpi_hash(md, pk->pub.elg.p);
131  pgp_mpi_hash(md, pk->pub.elg.g);
132  pgp_mpi_hash(md, pk->pub.elg.y);
133  break;
134  case PGP_PUB_RSA_SIGN:
135  case PGP_PUB_RSA_ENCRYPT:
137  pgp_mpi_hash(md, pk->pub.rsa.n);
138  pgp_mpi_hash(md, pk->pub.rsa.e);
139  break;
140  case PGP_PUB_DSA_SIGN:
141  pgp_mpi_hash(md, pk->pub.dsa.p);
142  pgp_mpi_hash(md, pk->pub.dsa.q);
143  pgp_mpi_hash(md, pk->pub.dsa.g);
144  pgp_mpi_hash(md, pk->pub.dsa.y);
145  break;
146  }
147 
148  px_md_finish(md, hash);
149  px_md_free(md);
150 
151  memcpy(pk->key_id, hash + 12, 8);
152  px_memset(hash, 0, 20);
153 
154  return 0;
155 }
unsigned char uint8
Definition: c.h:504
const void size_t len
int pgp_mpi_hash(PX_MD *md, PGP_MPI *n)
Definition: pgp-mpi.c:119
int pgp_load_digest(int code, PX_MD **res)
Definition: pgp.c:173
@ PGP_DIGEST_SHA1
Definition: pgp.h:101
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:123
#define px_md_finish(md, buf)
Definition: px.h:195
#define px_md_free(md)
Definition: px.h:196
#define px_md_update(md, data, dlen)
Definition: px.h:194
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
uint8 key_id[8]
Definition: pgp.h:235
Definition: px.h:100

References PGP_PubKey::algo, PGP_PubKey::dsa, PGP_PubKey::elg, hash(), PGP_PubKey::key_id, len, PGP_DIGEST_SHA1, pgp_load_digest(), pgp_mpi_hash(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, PGP_PubKey::pub, px_md_finish, px_md_free, px_md_update, px_memset(), res, PGP_PubKey::rsa, PGP_PubKey::time, and PGP_PubKey::ver.

Referenced by _pgp_read_public_key().

◆ check_key_cksum()

static int check_key_cksum ( PullFilter src,
PGP_PubKey pk 
)
static

Definition at line 299 of file pgp-pubkey.c.

300 {
301  int res;
302  unsigned got_cksum,
303  my_cksum = 0;
304  uint8 buf[2];
305 
306  res = pullf_read_fixed(src, 2, buf);
307  if (res < 0)
308  return res;
309 
310  got_cksum = ((unsigned) buf[0] << 8) + buf[1];
311  switch (pk->algo)
312  {
313  case PGP_PUB_ELG_ENCRYPT:
314  my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
315  break;
316  case PGP_PUB_RSA_SIGN:
317  case PGP_PUB_RSA_ENCRYPT:
319  my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
320  my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
321  my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
322  my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
323  break;
324  case PGP_PUB_DSA_SIGN:
325  my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
326  break;
327  }
328  if (my_cksum != got_cksum)
329  {
330  px_debug("key cksum check failed");
331  return PXE_PGP_KEYPKT_CORRUPT;
332  }
333  return 0;
334 }
static char * buf
Definition: pg_test_fsync.c:73
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
Definition: pgp-mpi.c:132
#define PXE_PGP_KEYPKT_CORRUPT
Definition: px.h:85
union PGP_PubKey::@1 sec

References PGP_PubKey::algo, buf, PGP_PubKey::dsa, PGP_PubKey::elg, pgp_mpi_cksum(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, pullf_read_fixed(), px_debug(), PXE_PGP_KEYPKT_CORRUPT, res, PGP_PubKey::rsa, and PGP_PubKey::sec.

Referenced by process_secret_key().

◆ check_key_sha1()

static int check_key_sha1 ( PullFilter src,
PGP_PubKey pk 
)
static

Definition at line 253 of file pgp-pubkey.c.

254 {
255  int res;
256  uint8 got_sha1[20];
257  uint8 my_sha1[20];
258  PX_MD *md;
259 
260  res = pullf_read_fixed(src, 20, got_sha1);
261  if (res < 0)
262  return res;
263 
265  if (res < 0)
266  goto err;
267  switch (pk->algo)
268  {
269  case PGP_PUB_ELG_ENCRYPT:
270  pgp_mpi_hash(md, pk->sec.elg.x);
271  break;
272  case PGP_PUB_RSA_SIGN:
273  case PGP_PUB_RSA_ENCRYPT:
275  pgp_mpi_hash(md, pk->sec.rsa.d);
276  pgp_mpi_hash(md, pk->sec.rsa.p);
277  pgp_mpi_hash(md, pk->sec.rsa.q);
278  pgp_mpi_hash(md, pk->sec.rsa.u);
279  break;
280  case PGP_PUB_DSA_SIGN:
281  pgp_mpi_hash(md, pk->sec.dsa.x);
282  break;
283  }
284  px_md_finish(md, my_sha1);
285  px_md_free(md);
286 
287  if (memcmp(my_sha1, got_sha1, 20) != 0)
288  {
289  px_debug("key sha1 check failed");
291  }
292 err:
293  px_memset(got_sha1, 0, 20);
294  px_memset(my_sha1, 0, 20);
295  return res;
296 }
void err(int eval, const char *fmt,...)
Definition: err.c:43

References PGP_PubKey::algo, PGP_PubKey::dsa, PGP_PubKey::elg, err(), PGP_DIGEST_SHA1, pgp_load_digest(), pgp_mpi_hash(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, pullf_read_fixed(), px_debug(), px_md_finish, px_md_free, px_memset(), PXE_PGP_KEYPKT_CORRUPT, res, PGP_PubKey::rsa, and PGP_PubKey::sec.

Referenced by process_secret_key().

◆ internal_read_key()

static int internal_read_key ( PullFilter src,
PGP_PubKey **  pk_p,
const uint8 psw,
int  psw_len,
int  pubtype 
)
static

Definition at line 458 of file pgp-pubkey.c.

460 {
461  PullFilter *pkt = NULL;
462  int res;
463  uint8 tag;
464  int len;
465  PGP_PubKey *enc_key = NULL;
466  PGP_PubKey *pk = NULL;
467  int got_main_key = 0;
468 
469  /*
470  * Search for encryption key.
471  *
472  * Error out on anything fancy.
473  */
474  while (1)
475  {
476  res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
477  if (res <= 0)
478  break;
479  res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
480  if (res < 0)
481  break;
482 
483  switch (tag)
484  {
485  case PGP_PKT_PUBLIC_KEY:
486  case PGP_PKT_SECRET_KEY:
487  if (got_main_key)
488  {
490  break;
491  }
492  got_main_key = 1;
493  res = pgp_skip_packet(pkt);
494  break;
495 
497  if (pubtype != 0)
499  else
500  res = _pgp_read_public_key(pkt, &pk);
501  break;
502 
504  if (pubtype != 1)
506  else
507  res = process_secret_key(pkt, &pk, psw, psw_len);
508  break;
509 
510  case PGP_PKT_SIGNATURE:
511  case PGP_PKT_MARKER:
512  case PGP_PKT_TRUST:
513  case PGP_PKT_USER_ID:
514  case PGP_PKT_USER_ATTR:
515  case PGP_PKT_PRIV_61:
516  res = pgp_skip_packet(pkt);
517  break;
518  default:
519  px_debug("unknown/unexpected packet: %d", tag);
521  }
522  pullf_free(pkt);
523  pkt = NULL;
524 
525  if (pk != NULL)
526  {
527  if (res >= 0 && pk->can_encrypt)
528  {
529  if (enc_key == NULL)
530  {
531  enc_key = pk;
532  pk = NULL;
533  }
534  else
536  }
537 
538  if (pk)
539  pgp_key_free(pk);
540  pk = NULL;
541  }
542 
543  if (res < 0)
544  break;
545  }
546 
547  if (pkt)
548  pullf_free(pkt);
549 
550  if (res < 0)
551  {
552  if (enc_key)
553  pgp_key_free(enc_key);
554  return res;
555  }
556 
557  if (!enc_key)
559  else
560  *pk_p = enc_key;
561  return res;
562 }
void pullf_free(PullFilter *pf)
Definition: mbuf.c:229
int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
Definition: pgp-decrypt.c:129
int pgp_skip_packet(PullFilter *pkt)
Definition: pgp-decrypt.c:1064
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)
Definition: pgp-decrypt.c:223
static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p, const uint8 *key, int key_len)
Definition: pgp-pubkey.c:337
int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
Definition: pgp-pubkey.c:158
@ PGP_PKT_TRUST
Definition: pgp.h:57
@ PGP_PKT_USER_ATTR
Definition: pgp.h:60
@ PGP_PKT_PUBLIC_SUBKEY
Definition: pgp.h:59
@ PGP_PKT_SIGNATURE
Definition: pgp.h:48
@ PGP_PKT_SECRET_SUBKEY
Definition: pgp.h:52
@ PGP_PKT_MARKER
Definition: pgp.h:55
@ PGP_PKT_SECRET_KEY
Definition: pgp.h:50
@ PGP_PKT_PUBLIC_KEY
Definition: pgp.h:51
@ PGP_PKT_USER_ID
Definition: pgp.h:58
@ PGP_PKT_PRIV_61
Definition: pgp.h:63
#define PXE_PGP_EXPECT_PUBLIC_KEY
Definition: px.h:82
#define PXE_PGP_UNEXPECTED_PKT
Definition: px.h:74
#define PXE_PGP_MULTIPLE_KEYS
Definition: px.h:81
#define PXE_PGP_NO_USABLE_KEY
Definition: px.h:86
#define PXE_PGP_EXPECT_SECRET_KEY
Definition: px.h:83
#define PXE_PGP_MULTIPLE_SUBKEYS
Definition: px.h:90

References _pgp_read_public_key(), PGP_PubKey::can_encrypt, len, pgp_create_pkt_reader(), pgp_key_free(), pgp_parse_pkt_hdr(), PGP_PKT_MARKER, PGP_PKT_PRIV_61, PGP_PKT_PUBLIC_KEY, PGP_PKT_PUBLIC_SUBKEY, PGP_PKT_SECRET_KEY, PGP_PKT_SECRET_SUBKEY, PGP_PKT_SIGNATURE, PGP_PKT_TRUST, PGP_PKT_USER_ATTR, PGP_PKT_USER_ID, pgp_skip_packet(), process_secret_key(), pullf_free(), px_debug(), PXE_PGP_EXPECT_PUBLIC_KEY, PXE_PGP_EXPECT_SECRET_KEY, PXE_PGP_MULTIPLE_KEYS, PXE_PGP_MULTIPLE_SUBKEYS, PXE_PGP_NO_USABLE_KEY, PXE_PGP_UNEXPECTED_PKT, and res.

Referenced by pgp_set_pubkey().

◆ pgp_key_alloc()

int pgp_key_alloc ( PGP_PubKey **  pk_p)

Definition at line 38 of file pgp-pubkey.c.

39 {
40  PGP_PubKey *pk;
41 
42  pk = palloc0(sizeof(*pk));
43  *pk_p = pk;
44  return 0;
45 }
void * palloc0(Size size)
Definition: mcxt.c:1346

References palloc0().

Referenced by _pgp_read_public_key().

◆ pgp_key_free()

void pgp_key_free ( PGP_PubKey pk)

Definition at line 48 of file pgp-pubkey.c.

49 {
50  if (pk == NULL)
51  return;
52 
53  switch (pk->algo)
54  {
56  pgp_mpi_free(pk->pub.elg.p);
57  pgp_mpi_free(pk->pub.elg.g);
58  pgp_mpi_free(pk->pub.elg.y);
59  pgp_mpi_free(pk->sec.elg.x);
60  break;
61  case PGP_PUB_RSA_SIGN:
64  pgp_mpi_free(pk->pub.rsa.n);
65  pgp_mpi_free(pk->pub.rsa.e);
66  pgp_mpi_free(pk->sec.rsa.d);
67  pgp_mpi_free(pk->sec.rsa.p);
68  pgp_mpi_free(pk->sec.rsa.q);
69  pgp_mpi_free(pk->sec.rsa.u);
70  break;
71  case PGP_PUB_DSA_SIGN:
72  pgp_mpi_free(pk->pub.dsa.p);
73  pgp_mpi_free(pk->pub.dsa.q);
74  pgp_mpi_free(pk->pub.dsa.g);
75  pgp_mpi_free(pk->pub.dsa.y);
76  pgp_mpi_free(pk->sec.dsa.x);
77  break;
78  }
79  px_memset(pk, 0, sizeof(*pk));
80  pfree(pk);
81 }
void pfree(void *pointer)
Definition: mcxt.c:1520
int pgp_mpi_free(PGP_MPI *mpi)
Definition: pgp-mpi.c:70

References PGP_PubKey::algo, PGP_PubKey::dsa, PGP_PubKey::elg, pfree(), pgp_mpi_free(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, PGP_PubKey::pub, px_memset(), PGP_PubKey::rsa, and PGP_PubKey::sec.

Referenced by _pgp_read_public_key(), internal_read_key(), pgp_free(), process_secret_key(), and read_pubkey_keyid().

◆ pgp_set_pubkey()

int pgp_set_pubkey ( PGP_Context ctx,
MBuf keypkt,
const uint8 key,
int  key_len,
int  pubtype 
)

Definition at line 565 of file pgp-pubkey.c.

567 {
568  int res;
569  PullFilter *src;
570  PGP_PubKey *pk = NULL;
571 
572  res = pullf_create_mbuf_reader(&src, keypkt);
573  if (res < 0)
574  return res;
575 
576  res = internal_read_key(src, &pk, key, key_len, pubtype);
577  pullf_free(src);
578 
579  if (res >= 0)
580  ctx->pub_key = pk;
581 
582  return res < 0 ? res : 0;
583 }
int pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src)
Definition: mbuf.c:336
static int internal_read_key(PullFilter *src, PGP_PubKey **pk_p, const uint8 *psw, int psw_len, int pubtype)
Definition: pgp-pubkey.c:458
PGP_PubKey * pub_key
Definition: pgp.h:164

References internal_read_key(), sort-test::key, PGP_Context::pub_key, pullf_create_mbuf_reader(), pullf_free(), and res.

Referenced by decrypt_internal(), and encrypt_internal().

◆ process_secret_key()

static int process_secret_key ( PullFilter pkt,
PGP_PubKey **  pk_p,
const uint8 key,
int  key_len 
)
static

Definition at line 337 of file pgp-pubkey.c.

339 {
340  int res;
341  int hide_type;
342  int cipher_algo;
343  int bs;
344  uint8 iv[512];
345  PullFilter *pf_decrypt = NULL,
346  *pf_key;
347  PGP_CFB *cfb = NULL;
348  PGP_S2K s2k;
349  PGP_PubKey *pk;
350 
351  /* first read public key part */
352  res = _pgp_read_public_key(pkt, &pk);
353  if (res < 0)
354  return res;
355 
356  /*
357  * is secret key encrypted?
358  */
359  GETBYTE(pkt, hide_type);
360  if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
361  {
362  if (key == NULL)
364  GETBYTE(pkt, cipher_algo);
365  res = pgp_s2k_read(pkt, &s2k);
366  if (res < 0)
367  return res;
368 
369  res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
370  if (res < 0)
371  return res;
372 
373  bs = pgp_get_cipher_block_size(cipher_algo);
374  if (bs == 0)
375  {
376  px_debug("unknown cipher algo=%d", cipher_algo);
378  }
379  res = pullf_read_fixed(pkt, bs, iv);
380  if (res < 0)
381  return res;
382 
383  /*
384  * create decrypt filter
385  */
386  res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
387  if (res < 0)
388  return res;
389  res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
390  if (res < 0)
391  return res;
392  pf_key = pf_decrypt;
393  }
394  else if (hide_type == HIDE_CLEAR)
395  {
396  pf_key = pkt;
397  }
398  else
399  {
400  px_debug("unknown hide type");
401  return PXE_PGP_KEYPKT_CORRUPT;
402  }
403 
404  /* read secret key */
405  switch (pk->algo)
406  {
407  case PGP_PUB_RSA_SIGN:
408  case PGP_PUB_RSA_ENCRYPT:
410  res = pgp_mpi_read(pf_key, &pk->sec.rsa.d);
411  if (res < 0)
412  break;
413  res = pgp_mpi_read(pf_key, &pk->sec.rsa.p);
414  if (res < 0)
415  break;
416  res = pgp_mpi_read(pf_key, &pk->sec.rsa.q);
417  if (res < 0)
418  break;
419  res = pgp_mpi_read(pf_key, &pk->sec.rsa.u);
420  if (res < 0)
421  break;
422  break;
423  case PGP_PUB_ELG_ENCRYPT:
424  res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
425  break;
426  case PGP_PUB_DSA_SIGN:
427  res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
428  break;
429  default:
430  px_debug("unknown public algo: %d", pk->algo);
432  }
433  /* read checksum / sha1 */
434  if (res >= 0)
435  {
436  if (hide_type == HIDE_SHA1)
437  res = check_key_sha1(pf_key, pk);
438  else
439  res = check_key_cksum(pf_key, pk);
440  }
441  if (res >= 0)
442  res = pgp_expect_packet_end(pf_key);
443 
444  if (pf_decrypt)
445  pullf_free(pf_decrypt);
446  if (cfb)
447  pgp_cfb_free(cfb);
448 
449  if (res < 0)
450  pgp_key_free(pk);
451  else
452  *pk_p = pk;
453 
454  return res;
455 }
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:191
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:83
int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)
Definition: pgp-cfb.c:52
int pgp_expect_packet_end(PullFilter *pkt)
Definition: pgp-decrypt.c:1078
struct PullFilterOps pgp_decrypt_filter
Definition: pgp-decrypt.c:314
#define HIDE_CLEAR
Definition: pgp-pubkey.c:248
static int check_key_cksum(PullFilter *src, PGP_PubKey *pk)
Definition: pgp-pubkey.c:299
#define HIDE_CKSUM
Definition: pgp-pubkey.c:249
#define HIDE_SHA1
Definition: pgp-pubkey.c:250
static int check_key_sha1(PullFilter *src, PGP_PubKey *pk)
Definition: pgp-pubkey.c:253
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
Definition: pgp-s2k.c:279
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
Definition: pgp-s2k.c:253
int pgp_get_cipher_block_size(int code)
Definition: pgp.c:147
#define PXE_PGP_NEED_SECRET_PSW
Definition: px.h:87
#define PXE_PGP_UNSUPPORTED_CIPHER
Definition: px.h:70
Definition: pgp.h:123
uint8 key_len
Definition: pgp.h:130
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129

References _pgp_read_public_key(), PGP_PubKey::algo, check_key_cksum(), check_key_sha1(), PGP_PubKey::dsa, PGP_PubKey::elg, GETBYTE, HIDE_CKSUM, HIDE_CLEAR, HIDE_SHA1, PGP_S2K::key, sort-test::key, PGP_S2K::key_len, pgp_cfb_create(), pgp_cfb_free(), pgp_decrypt_filter, pgp_expect_packet_end(), pgp_get_cipher_block_size(), pgp_key_free(), pgp_mpi_read(), PGP_PUB_DSA_SIGN, PGP_PUB_ELG_ENCRYPT, PGP_PUB_RSA_ENCRYPT, PGP_PUB_RSA_ENCRYPT_SIGN, PGP_PUB_RSA_SIGN, pgp_s2k_process(), pgp_s2k_read(), pullf_create(), pullf_free(), pullf_read_fixed(), px_debug(), PXE_PGP_KEYPKT_CORRUPT, PXE_PGP_NEED_SECRET_PSW, PXE_PGP_UNSUPPORTED_CIPHER, res, PGP_PubKey::rsa, and PGP_PubKey::sec.

Referenced by internal_read_key().