You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
7.6 KiB
235 lines
7.6 KiB
diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c |
|
index c28cb34..f865b16 100644 |
|
--- a/lib/opencdk/kbnode.c |
|
+++ b/lib/opencdk/kbnode.c |
|
@@ -369,12 +369,14 @@ cdk_packet_t cdk_kbnode_get_packet(cdk_kbnode_t node) |
|
* @armor: whether base64 or not |
|
* @buf: the buffer which stores the key sequence |
|
* @buflen: the length of the buffer |
|
+ * @public: non-zero if reading a public key |
|
* |
|
* Tries to read a key node from the memory buffer @buf. |
|
**/ |
|
cdk_error_t |
|
cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node, |
|
- int armor, const byte * buf, size_t buflen) |
|
+ int armor, const byte * buf, size_t buflen, |
|
+ unsigned public) |
|
{ |
|
cdk_stream_t inp; |
|
cdk_error_t rc; |
|
@@ -393,7 +395,7 @@ cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node, |
|
if (armor) |
|
cdk_stream_set_armor_flag(inp, 0); |
|
|
|
- rc = cdk_keydb_get_keyblock(inp, ret_node); |
|
+ rc = cdk_keydb_get_keyblock(inp, ret_node, public); |
|
if (rc) |
|
gnutls_assert(); |
|
cdk_stream_close(inp); |
|
diff --git a/lib/opencdk/keydb.c b/lib/opencdk/keydb.c |
|
index 64eebf0..9112d9a 100644 |
|
--- a/lib/opencdk/keydb.c |
|
+++ b/lib/opencdk/keydb.c |
|
@@ -108,7 +108,7 @@ static cdk_error_t keydb_idx_build(const char *file) |
|
while (!cdk_stream_eof(inp)) { |
|
off_t pos = cdk_stream_tell(inp); |
|
|
|
- rc = cdk_pkt_read(inp, pkt); |
|
+ rc = cdk_pkt_read(inp, pkt, 1); |
|
if (rc) { |
|
_cdk_log_debug |
|
("index build failed packet off=%lu\n", |
|
@@ -816,7 +816,7 @@ cdk_keydb_search(cdk_keydb_search_t st, cdk_keydb_hd_t hd, |
|
|
|
pos = cdk_stream_tell(kr); |
|
|
|
- rc = cdk_keydb_get_keyblock(kr, &knode); |
|
+ rc = cdk_keydb_get_keyblock(kr, &knode, 1); |
|
|
|
if (rc) { |
|
if (rc == CDK_EOF) |
|
@@ -1679,7 +1679,7 @@ add_key_usage(cdk_kbnode_t knode, u32 keyid[2], unsigned int usage) |
|
} |
|
|
|
cdk_error_t |
|
-cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode) |
|
+cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode, unsigned public) |
|
{ |
|
cdk_packet_t pkt; |
|
cdk_kbnode_t knode, node; |
|
@@ -1706,7 +1706,7 @@ cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode) |
|
while (!cdk_stream_eof(inp)) { |
|
cdk_pkt_new(&pkt); |
|
old_off = cdk_stream_tell(inp); |
|
- rc = cdk_pkt_read(inp, pkt); |
|
+ rc = cdk_pkt_read(inp, pkt, public); |
|
if (rc) { |
|
cdk_pkt_release(pkt); |
|
if (rc == CDK_EOF) |
|
@@ -2126,7 +2126,7 @@ cdk_error_t cdk_keydb_check_sk(cdk_keydb_hd_t hd, u32 * keyid) |
|
return rc; |
|
} |
|
cdk_pkt_new(&pkt); |
|
- while (!cdk_pkt_read(db, pkt)) { |
|
+ while (!cdk_pkt_read(db, pkt, 0)) { |
|
if (pkt->pkttype != CDK_PKT_SECRET_KEY && |
|
pkt->pkttype != CDK_PKT_SECRET_SUBKEY) { |
|
cdk_pkt_free(pkt); |
|
@@ -2241,14 +2241,14 @@ cdk_error_t cdk_listkey_next(cdk_listkey_t ctx, cdk_kbnode_t * ret_key) |
|
} |
|
|
|
if (ctx->type && ctx->u.patt[0] == '*') |
|
- return cdk_keydb_get_keyblock(ctx->inp, ret_key); |
|
+ return cdk_keydb_get_keyblock(ctx->inp, ret_key, 1); |
|
else if (ctx->type) { |
|
cdk_kbnode_t node; |
|
struct cdk_keydb_search_s ks; |
|
cdk_error_t rc; |
|
|
|
for (;;) { |
|
- rc = cdk_keydb_get_keyblock(ctx->inp, &node); |
|
+ rc = cdk_keydb_get_keyblock(ctx->inp, &node, 1); |
|
if (rc) { |
|
gnutls_assert(); |
|
return rc; |
|
diff --git a/lib/opencdk/literal.c b/lib/opencdk/literal.c |
|
index 7b4baec..6996774 100644 |
|
--- a/lib/opencdk/literal.c |
|
+++ b/lib/opencdk/literal.c |
|
@@ -67,7 +67,7 @@ static cdk_error_t literal_decode(void *data, FILE * in, FILE * out) |
|
return rc; |
|
|
|
cdk_pkt_new(&pkt); |
|
- rc = cdk_pkt_read(si, pkt); |
|
+ rc = cdk_pkt_read(si, pkt, 1); |
|
if (rc || pkt->pkttype != CDK_PKT_LITERAL) { |
|
cdk_pkt_release(pkt); |
|
cdk_stream_close(si); |
|
diff --git a/lib/opencdk/opencdk.h b/lib/opencdk/opencdk.h |
|
index c06b749..d95cc32 100644 |
|
--- a/lib/opencdk/opencdk.h |
|
+++ b/lib/opencdk/opencdk.h |
|
@@ -553,7 +553,7 @@ extern "C" { |
|
void cdk_pkt_release(cdk_packet_t pkt); |
|
|
|
/* Read or write the given output from or to the stream. */ |
|
- cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt); |
|
+ cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public); |
|
cdk_error_t cdk_pkt_write(cdk_stream_t out, cdk_packet_t pkt); |
|
|
|
/* Sub packet routines */ |
|
@@ -814,7 +814,8 @@ extern "C" { |
|
/* Try to read the next key block from the given input stream. |
|
The key will be returned in @RET_KEY on success. */ |
|
cdk_error_t cdk_keydb_get_keyblock(cdk_stream_t inp, |
|
- cdk_kbnode_t * ret_key); |
|
+ cdk_kbnode_t * ret_key, |
|
+ unsigned public); |
|
|
|
/* Rebuild the key db index if possible. */ |
|
cdk_error_t cdk_keydb_idx_rebuild(cdk_keydb_hd_t db, |
|
@@ -848,7 +849,7 @@ extern "C" { |
|
cdk_error_t cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node, |
|
int armor, |
|
const unsigned char *buf, |
|
- size_t buflen); |
|
+ size_t buflen, unsigned public); |
|
cdk_error_t cdk_kbnode_write_to_mem(cdk_kbnode_t node, |
|
unsigned char *buf, |
|
size_t * r_nbytes); |
|
diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c |
|
index 7a474ff..72624d0 100644 |
|
--- a/lib/opencdk/read-packet.c |
|
+++ b/lib/opencdk/read-packet.c |
|
@@ -571,6 +571,9 @@ read_user_id(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t user_id) |
|
} |
|
|
|
|
|
+#define MAX_PACKET_LEN (1<<24) |
|
+ |
|
+ |
|
static cdk_error_t |
|
read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes) |
|
{ |
|
@@ -610,6 +613,10 @@ read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes) |
|
else |
|
return CDK_Inv_Packet; |
|
|
|
+ if (size >= MAX_PACKET_LEN) { |
|
+ return CDK_Inv_Packet; |
|
+ } |
|
+ |
|
node = cdk_subpkt_new(size); |
|
if (!node) |
|
return CDK_Out_Of_Core; |
|
@@ -958,7 +965,7 @@ static cdk_error_t skip_packet(cdk_stream_t inp, size_t pktlen) |
|
* |
|
* Parse the next packet on the @inp stream and return its contents in @pkt. |
|
**/ |
|
-cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt) |
|
+cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public) |
|
{ |
|
int ctb, is_newctb; |
|
int pkttype; |
|
@@ -1058,6 +1065,10 @@ cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt) |
|
break; |
|
|
|
case CDK_PKT_SECRET_KEY: |
|
+ if (public) { |
|
+ /* read secret key when expecting public */ |
|
+ return gnutls_assert_val(CDK_Inv_Packet); |
|
+ } |
|
pkt->pkt.secret_key = |
|
cdk_calloc(1, sizeof *pkt->pkt.secret_key); |
|
if (!pkt->pkt.secret_key) |
|
@@ -1073,6 +1084,10 @@ cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt) |
|
break; |
|
|
|
case CDK_PKT_SECRET_SUBKEY: |
|
+ if (public) { |
|
+ /* read secret key when expecting public */ |
|
+ return gnutls_assert_val(CDK_Inv_Packet); |
|
+ } |
|
pkt->pkt.secret_key = |
|
cdk_calloc(1, sizeof *pkt->pkt.secret_key); |
|
if (!pkt->pkt.secret_key) |
|
diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c |
|
index 7c05e1f..192737f 100644 |
|
--- a/lib/openpgp/gnutls_openpgp.c |
|
+++ b/lib/openpgp/gnutls_openpgp.c |
|
@@ -479,7 +479,7 @@ int gnutls_openpgp_count_key_names(const gnutls_datum_t * cert) |
|
return 0; |
|
} |
|
|
|
- if (cdk_kbnode_read_from_mem(&knode, 0, cert->data, cert->size)) { |
|
+ if (cdk_kbnode_read_from_mem(&knode, 0, cert->data, cert->size, 1)) { |
|
gnutls_assert(); |
|
return 0; |
|
} |
|
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c |
|
index d5ef272..77e57ab 100644 |
|
--- a/lib/openpgp/pgp.c |
|
+++ b/lib/openpgp/pgp.c |
|
@@ -99,7 +99,7 @@ gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key, |
|
armor = 1; |
|
|
|
rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data, |
|
- data->size); |
|
+ data->size, 1); |
|
if (rc) { |
|
rc = _gnutls_map_cdk_rc(rc); |
|
gnutls_assert(); |
|
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c |
|
index 6aa6fb5..81ec3ab 100644 |
|
--- a/lib/openpgp/privkey.c |
|
+++ b/lib/openpgp/privkey.c |
|
@@ -186,7 +186,7 @@ gnutls_openpgp_privkey_import(gnutls_openpgp_privkey_t key, |
|
armor = 1; |
|
|
|
rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data, |
|
- data->size); |
|
+ data->size, 0); |
|
if (rc != 0) { |
|
rc = _gnutls_map_cdk_rc(rc); |
|
gnutls_assert();
|
|
|