static const guchar* find_extension (GNode *asn, const guchar *data, gsize n_data, const gchar *oid, gsize *n_extension) { const guchar *value; GNode *node = NULL; gchar *exoid; guint index; int len; len = strlen (oid); for (index = 1; TRUE; ++index) { /* Make sure it is present */ node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, "extnID", NULL); if (node == NULL) return NULL; exoid = egg_asn1x_get_oid_as_string (node); g_assert (exoid); if (strcmp (exoid, oid) == 0) { g_free (exoid); node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, "extnValue", NULL); value = egg_asn1x_get_raw_value (node, n_extension); g_assert (value); return value; } g_free (exoid); } g_assert_not_reached (); }
static gboolean append_extension (GcrCertificateDetailsWidget *self, GNode *asn, const guchar *data, gsize n_data, gint index) { GQuark oid; gchar *display; gsize n_value; const guchar *value; const gchar *text; gboolean critical; GNode *node; /* Make sure it is present */ asn = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL); if (asn == NULL) return FALSE; /* Dig out the OID */ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "extnID", NULL)); g_return_val_if_fail (oid, FALSE); append_heading (self, _("Extension")); /* Extension type */ text = egg_oid_get_description (oid); append_field_and_value (self, _("Identifier"), text, FALSE); /* Extension value */ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "extnValue", NULL), &n_value); /* TODO: Parsing of extensions that we understand */ display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1); append_field_and_value (self, _("Value"), display, TRUE); g_free (display); /* Critical */ node = egg_asn1x_node (asn, "critical", NULL); if (node != NULL) { if (egg_asn1x_get_boolean (node, &critical)) append_field_and_value (self, _("Critical"), critical ? _("Yes") : _("No"), FALSE); } return TRUE; }
static guint calculate_dsa_params_size (gconstpointer data, gsize n_data) { GNode *asn; gsize n_content; asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data, n_data); g_return_val_if_fail (asn, 0); if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL), &n_content)) g_return_val_if_reached (0); egg_asn1x_destroy (asn); /* Removes the complement */ return (n_content / 2) * 2 * 8; }
gboolean gkm_data_asn1_read_mpi (GNode *asn, gcry_mpi_t *mpi) { gcry_error_t gcry; gsize sz; const guchar *buf; g_return_val_if_fail (asn, FALSE); g_return_val_if_fail (mpi, FALSE); buf = egg_asn1x_get_raw_value (asn, &sz); if (!buf) return FALSE; /* Automatically stores in secure memory if DER data is secure */ gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, buf, sz, &sz); if (gcry != 0) return FALSE; return TRUE; }
const guchar* gkm_certificate_get_extension (GkmCertificate *self, GQuark oid, gsize *n_extension, gboolean *critical) { guchar *val; gsize n_val; gint index; g_return_val_if_fail (GKM_IS_CERTIFICATE (self), NULL); g_return_val_if_fail (self->pv->asn1, NULL); g_return_val_if_fail (oid, NULL); g_return_val_if_fail (n_extension, NULL); index = find_certificate_extension (self, oid); if (index <= 0) return NULL; /* Read the critical status */ if (critical) { val = egg_asn1x_get_string_as_raw (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "extensions", index, "critical", NULL), NULL, &n_val); /* * We're pretty liberal in what we accept as critical. The goal * here is not to accidentally mark as non-critical what some * other x509 implementation meant to say critical. */ if (!val || n_val < 1 || g_ascii_toupper (val[0]) != 'T') *critical = FALSE; else *critical = TRUE; g_free (val); } /* And the extension value */ return egg_asn1x_get_raw_value (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "extensions", index, "extnValue", NULL), n_extension); }
static void refresh_display (GcrCertificateDetailsWidget *self) { GtkTextIter start, iter; const guchar *data, *value; gsize n_data, n_value; const gchar *text; gulong version; guint index, size, n_bits; gchar *display; guchar *bits; GNode *asn; GQuark oid; GDate date; gtk_text_buffer_get_start_iter (self->pv->buffer, &start); gtk_text_buffer_get_end_iter (self->pv->buffer, &iter); gtk_text_buffer_delete (self->pv->buffer, &start, &iter); if (!self->pv->certificate) return; data = gcr_certificate_get_der_data (self->pv->certificate, &n_data); g_return_if_fail (data); asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data); g_return_if_fail (asn); /* The subject */ append_heading (self, _("Subject Name")); egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, self); /* The Issuer */ append_heading (self, _("Issuer Name")); egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, self); /* The Issued Parameters */ append_heading (self, _("Issued Certificate")); if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version)) g_return_if_reached (); display = g_strdup_printf ("%lu", version + 1); append_field_and_value (self, _("Version"), display, FALSE); g_free (display); value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_value); g_return_if_fail (value); display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1); append_field_and_value (self, _("Serial Number"), display, TRUE); g_free (display); display = g_malloc0 (128); if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) { if (!g_date_strftime (display, 128, "%Y-%m-%d", &date)) g_return_if_reached (); append_field_and_value (self, _("Not Valid Before"), display, FALSE); } if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) { if (!g_date_strftime (display, 128, "%Y-%m-%d", &date)) g_return_if_reached (); append_field_and_value (self, _("Not Valid After"), display, FALSE); } g_free (display); /* Signature */ append_heading (self, _("Signature")); oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL)); text = egg_oid_get_description (oid); append_field_and_value (self, _("Signature Algorithm"), text, FALSE); value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value); if (value && n_value) { display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1); append_field_and_value (self, _("Signature Parameters"), display, TRUE); g_free (display); } value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signature", NULL), &n_value); g_return_if_fail (value); display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1); append_field_and_value (self, _("Signature"), display, TRUE); g_free (display); /* Public Key Info */ append_heading (self, _("Public Key Info")); oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "algorithm", NULL)); text = egg_oid_get_description (oid); append_field_and_value (self, _("Key Algorithm"), text, FALSE); value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "parameters", NULL), &n_value); if (value && n_value) { display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1); append_field_and_value (self, _("Key Parameters"), display, TRUE); g_free (display); } size = gcr_certificate_get_key_size (self->pv->certificate); if (size > 0) { display = g_strdup_printf ("%u", size); append_field_and_value (self, _("Key Size"), display, FALSE); g_free (display); } bits = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "subjectPublicKey", NULL), NULL, &n_bits); g_return_if_fail (bits); display = egg_hex_encode_full (bits, n_bits / 8, TRUE, ' ', 1); append_field_and_value (self, _("Public Key"), display, TRUE); g_free (display); g_free (bits); /* Fingerprints */ append_heading (self, _("Fingerprints")); append_fingerprint (self, data, n_data, "SHA1", G_CHECKSUM_SHA1); append_fingerprint (self, data, n_data, "MD5", G_CHECKSUM_MD5); /* Extensions */ for (index = 1; TRUE; ++index) { if (!append_extension (self, asn, data, n_data, index)) break; } egg_asn1x_destroy (asn); }
GkmDataResult gkm_data_der_read_private_pkcs8_plain (const guchar *data, gsize n_data, gcry_sexp_t *s_key) { GNode *asn = NULL; GkmDataResult ret; int algorithm; GQuark key_algo; const guchar *keydata; gsize n_keydata; const guchar *params; gsize n_params; ret = GKM_DATA_UNRECOGNIZED; init_quarks (); asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data); if (!asn) goto done; ret = GKM_DATA_FAILURE; algorithm = 0; key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL)); if (!key_algo) goto done; else if (key_algo == OID_PKIX1_RSA) algorithm = GCRY_PK_RSA; else if (key_algo == OID_PKIX1_DSA) algorithm = GCRY_PK_DSA; if (!algorithm) { ret = GKM_DATA_UNRECOGNIZED; goto done; } keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata); if (!keydata) goto done; params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), &n_params); ret = GKM_DATA_SUCCESS; done: if (ret == GKM_DATA_SUCCESS) { switch (algorithm) { case GCRY_PK_RSA: ret = gkm_data_der_read_private_key_rsa (keydata, n_keydata, s_key); break; case GCRY_PK_DSA: /* Try the normal one block format */ ret = gkm_data_der_read_private_key_dsa (keydata, n_keydata, s_key); /* Otherwise try the two part format that everyone seems to like */ if (ret == GKM_DATA_UNRECOGNIZED && params && n_params) ret = gkm_data_der_read_private_key_dsa_parts (keydata, n_keydata, params, n_params, s_key); break; default: g_message ("invalid or unsupported key type in PKCS#8 key"); ret = GKM_DATA_UNRECOGNIZED; break; }; } else if (ret == GKM_DATA_FAILURE) { g_message ("invalid PKCS#8 key"); } egg_asn1x_destroy (asn); return ret; }