static void emit_status_for_each_line (const gchar *line, gpointer user_data) { GcrRecord *record; if (g_str_has_prefix (line, "[GNUPG:] ")) { g_debug ("received status line: %s", line); line += 9; } else { g_message ("gnupg status record was not prefixed appropriately: %s", line); return; } record = _gcr_record_parse_spaces (line, -1); if (!record) { g_message ("couldn't parse status record: %s", line); return; } g_signal_emit (GCR_GNUPG_PROCESS (user_data), signals[STATUS_RECORD], 0, record); _gcr_record_free (record); }
static void teardown (Test *test, gconstpointer unused) { _gcr_record_free (test->record); }
static gboolean parse_v4_signature (const guchar **at, const guchar *end, GcrOpenpgpParseFlags flags, GPtrArray *records) { guint8 sig_type; guint8 key_algo; guint8 hash_algo; guint16 hashed_len; guint16 unhashed_len; guint16 left_bits; GcrRecord *record; GcrRecord *key, *uid; const gchar *keyid; gchar *value; const guchar *stop; gulong timestamp; /* Information to transfer back onto the key record */ SigSubpacket subpkt = { 0, }; subpkt.exportable = 1; if (!read_byte (at, end, &sig_type) || !read_byte (at, end, &key_algo) || !read_byte (at, end, &hash_algo) || !read_uint16 (at, end, &hashed_len)) return FALSE; /* Hashed subpackets which we use */ record = _gcr_record_new (GCR_RECORD_SCHEMA_SIG, GCR_RECORD_SIG_MAX, ':'); stop = *at + hashed_len; if (stop > end || !parse_v4_signature_subpackets (at, stop, record, &subpkt)) { _gcr_record_free (record); _gcr_record_free (subpkt.revocation); return FALSE; } /* Includes unhashed subpackets, which we skip over */ if (!read_uint16 (at, end, &unhashed_len)) { _gcr_record_free (record); _gcr_record_free (subpkt.revocation); return FALSE; } stop = *at + unhashed_len; if (stop > end || !parse_v4_signature_subpackets (at, stop, record, &subpkt) || !read_uint16 (at, end, &left_bits) || !skip_signature_mpis (at, end, key_algo)) { _gcr_record_free (record); _gcr_record_free (subpkt.revocation); return FALSE; } if (subpkt.revocation) { g_ptr_array_add (records, subpkt.revocation); subpkt.revocation = NULL; } /* Fill in information on previous key or subkey */ keyid = _gcr_record_get_raw (record, GCR_RECORD_SIG_KEYID); key = key_or_sub_find_for_self_signature (records, sig_type, keyid); if (key != NULL) { if (subpkt.key_expiry != 0) { if (_gcr_record_get_ulong (key, GCR_RECORD_KEY_TIMESTAMP, ×tamp)) _gcr_record_set_ulong (key, GCR_RECORD_KEY_EXPIRY, timestamp + subpkt.key_expiry); } if (subpkt.key_flags != 0) pub_or_sub_set_key_caps (key, subpkt.key_flags); } if (key && _gcr_record_get_schema (key) == GCR_RECORD_SCHEMA_PUB) { uid = uid_or_uat_find_for_self_signature (records, sig_type); if (uid != NULL) { if (_gcr_record_get_ulong (record, GCR_RECORD_SIG_TIMESTAMP, ×tamp)) _gcr_record_set_ulong (uid, GCR_RECORD_UID_TIMESTAMP, timestamp); } } if (flags & GCR_OPENPGP_PARSE_SIGNATURES) { _gcr_record_set_uint (record, GCR_RECORD_SIG_ALGO, key_algo); value = g_strdup_printf ("%02x%s", (guint)sig_type, subpkt.exportable ? "x" : "l"); _gcr_record_take_raw (record, GCR_RECORD_SIG_CLASS, value); g_ptr_array_add (records, record); } else { _gcr_record_free (record); } return TRUE; }
static gboolean parse_v4_signature_subpacket (const guchar **at, const guchar *end, guint8 sub_type, GcrRecord *record, SigSubpacket *subpkt) { guchar keyid[8]; guint32 when; guint8 byte; gboolean critical; gchar *value; critical = (sub_type & 0x80) ? TRUE : FALSE; sub_type &= ~0xC0; switch (sub_type) { case OPENPGP_SIG_CREATION: if (!read_uint32 (at, end, &when)) return FALSE; _gcr_record_set_ulong (record, GCR_RECORD_SIG_TIMESTAMP, when); return TRUE; case OPENPGP_SIG_ISSUER: if (!read_bytes (at, end, keyid, 8)) return FALSE; value = egg_hex_encode_full (keyid, 8, TRUE, 0, 0); _gcr_record_take_raw (record, GCR_RECORD_SIG_KEYID, value); return TRUE; case OPENPGP_SIG_KEY_EXPIRY: if (!read_uint32 (at, end, &when)) return FALSE; subpkt->key_expiry = when; return TRUE; case OPENPGP_SIG_EXPIRY: if (!read_uint32 (at, end, &when)) return FALSE; _gcr_record_set_ulong (record, GCR_RECORD_SIG_EXPIRY, when); return TRUE; case OPENPGP_SIG_EXPORTABLE: if (!read_byte (at, end, &byte)) return FALSE; if (byte != 0 && byte != 1) return FALSE; subpkt->exportable = (byte == 0 ? FALSE : TRUE); return TRUE; case OPENPGP_SIG_PRIMARY_USERID: if (!read_byte (at, end, &byte)) return FALSE; if (byte != 0 && byte != 1) return FALSE; subpkt->primary = byte; return TRUE; case OPENPGP_SIG_KEY_FLAGS: if (!read_byte (at, end, &byte)) return FALSE; *at = end; /* N octets of flags */ subpkt->key_flags = byte; return TRUE; case OPENPGP_SIG_SIGNER_USERID: value = g_strndup ((gchar *)*at, end - *at); _gcr_record_set_string (record, GCR_RECORD_SIG_USERID, value); g_free (value); return TRUE; case OPENPGP_SIG_REVOCATION_KEY: _gcr_record_free (subpkt->revocation); subpkt->revocation = _gcr_record_new (GCR_RECORD_SCHEMA_RVK, GCR_RECORD_RVK_MAX, ':'); return parse_v4_signature_revocation (at, end, subpkt->revocation); /* Ignored */ case OPENPGP_SIG_SYMMETRIC_ALGOS: case OPENPGP_SIG_HASH_ALGOS: case OPENPGP_SIG_COMPRESSION_ALGOS: case OPENPGP_SIG_REVOCABLE: case OPENPGP_SIG_TRUST: case OPENPGP_SIG_REGULAR_EXPRESSION: case OPENPGP_SIG_NOTATION_DATA: case OPENPGP_SIG_KEYSERVER_PREFS: case OPENPGP_SIG_PREFERRED_KEYSERVER: case OPENPGP_SIG_POLICY_URI: case OPENPGP_SIG_REVOCATION_REASON: case OPENPGP_SIG_FEATURES: case OPENPGP_SIG_TARGET: case OPENPGP_SIG_EMBEDDED_SIGNATURE: *at = end; return TRUE; /* Unrecognized */ default: /* Critical, but not recognized */ if (critical) return FALSE; *at = end; return TRUE; } }