int gkm_rpc_message_parse (GkmRpcMessage *msg, GkmRpcMessageType type) { const unsigned char *val; size_t len; uint32_t call_id; msg->parsed = 0; /* Pull out the call identifier */ if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &(msg->parsed), &call_id)) { gkm_rpc_warn ("invalid message: couldn't read call identifier"); return 0; } msg->signature = msg->sigverify = NULL; /* If it's an error code then no more processing */ if (call_id == GKM_RPC_CALL_ERROR) { if (type == GKM_RPC_REQUEST) { gkm_rpc_warn ("invalid message: error code in request"); return 0; } return 1; } /* The call id and signature */ if (call_id <= 0 || call_id >= GKM_RPC_CALL_MAX) { gkm_rpc_warn ("invalid message: bad call id: %d", call_id); return 0; } if (type == GKM_RPC_REQUEST) msg->signature = gkm_rpc_calls[call_id].request; else if (type == GKM_RPC_RESPONSE) msg->signature = gkm_rpc_calls[call_id].response; else assert (0 && "invalid message type"); msg->call_id = call_id; msg->call_type = type; msg->sigverify = msg->signature; /* Verify the incoming signature */ if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &(msg->parsed), &val, &len)) { gkm_rpc_warn ("invalid message: couldn't read signature"); return 0; } if ((strlen (msg->signature) != len) || (memcmp (val, msg->signature, len) != 0)) { gkm_rpc_warn ("invalid message: signature doesn't match"); return 0; } return 1; }
static gboolean read_full_item_info (EggBuffer *buffer, gsize *offset, ItemInfo *items, guint n_items) { gchar *reserved; guint32 tmp; gint i, j; g_assert (buffer); g_assert (offset); g_assert (items); for (i = 0; i < n_items; i++) { /* The display name */ if (!buffer_get_utf8_string (buffer, *offset, offset, &items[i].display_name)) return FALSE; /* The secret */ if (!egg_buffer_get_byte_array (buffer, *offset, offset, &items[i].ptr_secret, &items[i].n_secret)) return FALSE; /* The item times */ if (!buffer_get_time (buffer, *offset, offset, &items[i].ctime) || !buffer_get_time (buffer, *offset, offset, &items[i].mtime)) return FALSE; /* Reserved data */ reserved = NULL; if (!buffer_get_utf8_string (buffer, *offset, offset, &reserved)) return FALSE; g_free (reserved); for (j = 0; j < 4; j++) { if (!egg_buffer_get_uint32 (buffer, *offset, offset, &tmp)) return FALSE; } /* The attributes */ if (items[i].attributes) g_hash_table_unref (items[i].attributes); if (!buffer_get_attributes (buffer, *offset, offset, &items[i].attributes, FALSE)) return FALSE; /* The ACLs */ if (!decode_acl (buffer, *offset, offset, &items[i].acl)) return FALSE; } return TRUE; }
static gboolean read_mpi (EggBuffer *req, gsize *offset, gcry_mpi_t *mpi) { const guchar *data; gsize len; gcry_error_t gcry; if (!egg_buffer_get_byte_array (req, *offset, offset, &data, &len)) return FALSE; gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_USG, data, len, NULL); if (gcry) return FALSE; return TRUE; }
gboolean gkd_ssh_agent_proto_read_mpi (EggBuffer *req, gsize *offset, GckAttributes *attrs, CK_ATTRIBUTE_TYPE type) { const guchar *data; gsize len; if (!egg_buffer_get_byte_array (req, *offset, offset, &data, &len)) return FALSE; /* Convert to unsigned format */ if (len >= 2 && data[0] == 0 && (data[1] & 0x80)) { ++data; --len; } gck_attributes_add_data (attrs, type, data, len); return TRUE; }
int gkm_rpc_message_read_space_string (GkmRpcMessage *msg, CK_UTF8CHAR* buffer, CK_ULONG length) { const unsigned char *data; size_t n_data; assert (msg); assert (buffer); assert (length); assert (!msg->signature || gkm_rpc_message_verify_part (msg, "s")); if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data)) return 0; if (n_data != length) { gkm_rpc_warn ("invalid length space padded string received: %d != %d", length, n_data); return 0; } memcpy (buffer, data, length); return 1; }