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
236 lines
7.6 KiB
6 years ago
|
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();
|