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.

236 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();