GkmDataResult gkm_data_der_read_basic_constraints (GBytes *data, gboolean *is_ca, gint *path_len) { GkmDataResult ret = GKM_DATA_UNRECOGNIZED; GNode *asn = NULL; GNode *node; gulong value; asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data); if (!asn) goto done; ret = GKM_DATA_FAILURE; if (path_len) { node = egg_asn1x_node (asn, "pathLenConstraint", NULL); if (!egg_asn1x_have (node)) *path_len = -1; else if (!egg_asn1x_get_integer_as_ulong (node, &value)) goto done; else *path_len = value; } if (is_ca) { node = egg_asn1x_node (asn, "cA", NULL); if (!egg_asn1x_have (node)) *is_ca = FALSE; else if (!egg_asn1x_get_boolean (node, is_ca)) goto done; } ret = GKM_DATA_SUCCESS; done: egg_asn1x_destroy (asn); if (ret == GKM_DATA_FAILURE) g_message ("invalid basic constraints"); return ret; }
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_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key) { GkmDataResult ret = GKM_DATA_UNRECOGNIZED; gcry_mpi_t n, e, d, p, q, u; gcry_mpi_t tmp; gulong version; GNode *asn = NULL; int res; n = e = d = p = q = u = NULL; asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data); if (!asn) goto done; ret = GKM_DATA_FAILURE; if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version)) goto done; /* We only support simple version */ if (version != 0) { ret = GKM_DATA_UNRECOGNIZED; g_message ("unsupported version of RSA key: %lu", version); goto done; } if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "modulus", NULL), &n) || !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "publicExponent", NULL), &e) || !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "privateExponent", NULL), &d) || !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime1", NULL), &p) || !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime2", NULL), &q) || !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "coefficient", NULL), &u)) goto done; /* Fix up the incoming key so gcrypt likes it */ if (gcry_mpi_cmp (p, q) > 0) { /* P shall be smaller then Q! Swap primes. iqmp becomes u. */ tmp = p; p = q; q = tmp; } else { /* U needs to be recomputed. */ gcry_mpi_invm (u, p, q); } res = gcry_sexp_build (s_key, NULL, SEXP_PRIVATE_RSA, n, e, d, p, q, u); if (res) goto done; g_assert (*s_key); ret = GKM_DATA_SUCCESS; done: egg_asn1x_destroy (asn); gcry_mpi_release (n); gcry_mpi_release (e); gcry_mpi_release (d); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (u); if (ret == GKM_DATA_FAILURE) g_message ("invalid RSA key"); return ret; }