[seahorse] pkcs11: use GtkTemplate for the generate dialog.
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse] pkcs11: use GtkTemplate for the generate dialog.
- Date: Sun, 12 Aug 2018 13:57:12 +0000 (UTC)
commit c7f7faf784a908773aa0f4f0fed07838708e1156
Author: Niels De Graef <nielsdegraef gmail com>
Date: Sun Aug 12 14:54:19 2018 +0200
pkcs11: use GtkTemplate for the generate dialog.
common/config.vapi | 6 +
pkcs11/cryptoki.vapi | 397 ++++++++++++++++++++++++++++
pkcs11/meson.build | 8 +-
pkcs11/pkcs11-generate.vala | 294 +++++++++++++++++++++
pkcs11/seahorse-pkcs11-backend.c | 2 -
pkcs11/seahorse-pkcs11-backend.h | 2 -
pkcs11/seahorse-pkcs11-generate.c | 518 -------------------------------------
pkcs11/seahorse-pkcs11-generate.h | 34 ---
pkcs11/seahorse-pkcs11-generate.ui | 295 +++++++++------------
src/application.vala | 4 +-
10 files changed, 829 insertions(+), 731 deletions(-)
---
diff --git a/common/config.vapi b/common/config.vapi
index d5cda88f..6838ebc0 100644
--- a/common/config.vapi
+++ b/common/config.vapi
@@ -52,6 +52,12 @@ namespace Progress {
namespace Pgp.Backend {
public void initialize();
}
+
+[CCode (cheader_filename = "pkcs11/seahorse-pkcs11-backend.h")]
+public class Pkcs11.Backend {
+ public static void initialize();
+ public static Gcr.Collection get_writable_tokens(Pkcs11.Backend? self, ulong with_mechanism);
+}
}
namespace Egg {
diff --git a/pkcs11/cryptoki.vapi b/pkcs11/cryptoki.vapi
new file mode 100644
index 00000000..3fb709a0
--- /dev/null
+++ b/pkcs11/cryptoki.vapi
@@ -0,0 +1,397 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2018 Niels De Graef
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Although there are some VAPI files that take care of the bindings to
+ * Cryptoki, they are woefully inadequate, so maintain our own bindings here
+ * for now.
+ *
+ * Most of these were made by taking some stuff of the header and doing some
+ * regex magix on them.
+ */
+[CCode (cprefix = "CK_")]
+namespace Cryptoki {
+ [CCode (cname = "ulong", cprefix = "CKA_", has_type_id = false)]
+ public enum Attribute {
+ CLASS,
+ TOKEN,
+ PRIVATE,
+ LABEL,
+ APPLICATION,
+ VALUE,
+ OBJECT_ID,
+ CERTIFICATE_TYPE,
+ ISSUER,
+ SERIAL_NUMBER,
+ AC_ISSUER,
+ OWNER,
+ ATTR_TYPES,
+ TRUSTED,
+ CERTIFICATE_CATEGORY,
+ JAVA_MIDP_SECURITY_DOMAIN,
+ URL,
+ HASH_OF_SUBJECT_PUBLIC_KEY,
+ HASH_OF_ISSUER_PUBLIC_KEY,
+ CHECK_VALUE,
+ KEY_TYPE,
+ SUBJECT,
+ ID,
+ SENSITIVE,
+ ENCRYPT,
+ DECRYPT,
+ WRAP,
+ UNWRAP,
+ SIGN,
+ SIGN_RECOVER,
+ VERIFY,
+ VERIFY_RECOVER,
+ DERIVE,
+ START_DATE,
+ END_DATE,
+ MODULUS,
+ MODULUS_BITS,
+ PUBLIC_EXPONENT,
+ PRIVATE_EXPONENT,
+ PRIME_1,
+ PRIME_2,
+ EXPONENT_1,
+ EXPONENT_2,
+ COEFFICIENT,
+ PRIME,
+ SUBPRIME,
+ BASE,
+ PRIME_BITS,
+ SUB_PRIME_BITS,
+ VALUE_BITS,
+ VALUE_LEN,
+ EXTRACTABLE,
+ LOCAL,
+ NEVER_EXTRACTABLE,
+ ALWAYS_SENSITIVE,
+ KEY_GEN_MECHANISM,
+ MODIFIABLE,
+ COPYABLE,
+ ECDSA_PARAMS,
+ EC_PARAMS,
+ EC_POINT,
+ SECONDARY_AUTH,
+ AUTH_PIN_FLAGS,
+ ALWAYS_AUTHENTICATE,
+ WRAP_WITH_TRUSTED,
+ OTP_FORMAT,
+ OTP_LENGTH,
+ OTP_TIME_INTERVAL,
+ OTP_USER_FRIENDLY_MODE,
+ OTP_CHALLENGE_REQUIREMENT,
+ OTP_TIME_REQUIREMENT,
+ OTP_COUNTER_REQUIREMENT,
+ OTP_PIN_REQUIREMENT,
+ OTP_USER_IDENTIFIER,
+ OTP_SERVICE_IDENTIFIER,
+ OTP_SERVICE_LOGO,
+ OTP_SERVICE_LOGO_TYPE,
+ OTP_COUNTER,
+ OTP_TIME,
+ GOSTR3410_PARAMS,
+ GOSTR3411_PARAMS,
+ GOST28147_PARAMS,
+ HW_FEATURE_TYPE,
+ RESET_ON_INIT,
+ HAS_RESET,
+ PIXEL_X,
+ PIXEL_Y,
+ RESOLUTION,
+ CHAR_ROWS,
+ CHAR_COLUMNS,
+ COLOR,
+ BITS_PER_PIXEL,
+ CHAR_SETS,
+ ENCODING_METHODS,
+ MIME_TYPES,
+ MECHANISM_TYPE,
+ REQUIRED_CMS_ATTRIBUTES,
+ DEFAULT_CMS_ATTRIBUTES,
+ SUPPORTED_CMS_ATTRIBUTES,
+ WRAP_TEMPLATE,
+ UNWRAP_TEMPLATE,
+ ALLOWED_MECHANISMS,
+ VENDOR_DEFINED,
+ }
+
+ [CCode (cname = "ulong", cprefix = "CKM_", has_type_id = false)]
+ public enum MechanismType {
+ RSA_PKCS_KEY_PAIR_GEN,
+ RSA_PKCS,
+ RSA_9796,
+ RSA_X_509,
+ MD2_RSA_PKCS,
+ MD5_RSA_PKCS,
+ SHA1_RSA_PKCS,
+ RIPEMD128_RSA_PKCS,
+ RIPEMD160_RSA_PKCS,
+ RSA_PKCS_OAEP,
+ RSA_X9_31_KEY_PAIR_GEN,
+ RSA_X9_31,
+ SHA1_RSA_X9_31,
+ RSA_PKCS_PSS,
+ SHA1_RSA_PKCS_PSS,
+ DSA_KEY_PAIR_GEN,
+ DSA,
+ DSA_SHA1,
+ DH_PKCS_KEY_PAIR_GEN,
+ DH_PKCS_DERIVE,
+ X9_42_DH_KEY_PAIR_GEN,
+ X9_42_DH_DERIVE,
+ X9_42_DH_HYBRID_DERIVE,
+ X9_42_MQV_DERIVE,
+ SHA256_RSA_PKCS,
+ SHA384_RSA_PKCS,
+ SHA512_RSA_PKCS,
+ SHA256_RSA_PKCS_PSS,
+ SHA384_RSA_PKCS_PSS,
+ SHA512_RSA_PKCS_PSS,
+ RC2_KEY_GEN,
+ RC2_ECB,
+ RC2_CBC,
+ RC2_MAC,
+ RC2_MAC_GENERAL,
+ RC2_CBC_PAD,
+ RC4_KEY_GEN,
+ RC4,
+ DES_KEY_GEN,
+ DES_ECB,
+ DES_CBC,
+ DES_MAC,
+ DES_MAC_GENERAL,
+ DES_CBC_PAD,
+ DES2_KEY_GEN,
+ DES3_KEY_GEN,
+ DES3_ECB,
+ DES3_CBC,
+ DES3_MAC,
+ DES3_MAC_GENERAL,
+ DES3_CBC_PAD,
+ CDMF_KEY_GEN,
+ CDMF_ECB,
+ CDMF_CBC,
+ CDMF_MAC,
+ CDMF_MAC_GENERAL,
+ CDMF_CBC_PAD,
+ DES_OFB64,
+ DES_OFB8,
+ DES_CFB64,
+ DES_CFB8,
+ MD2,
+ MD2_HMAC,
+ MD2_HMAC_GENERAL,
+ MD5,
+ MD5_HMAC,
+ MD5_HMAC_GENERAL,
+ SHA_1,
+ SHA_1_HMAC,
+ SHA_1_HMAC_GENERAL,
+ RIPEMD128,
+ RIPEMD128_HMAC,
+ RIPEMD128_HMAC_GENERAL,
+ RIPEMD160,
+ RIPEMD160_HMAC,
+ RIPEMD160_HMAC_GENERAL,
+ SHA256,
+ SHA256_HMAC,
+ SHA256_HMAC_GENERAL,
+ SHA384,
+ SHA384_HMAC,
+ SHA384_HMAC_GENERAL,
+ SHA512,
+ SHA512_HMAC,
+ SHA512_HMAC_GENERAL,
+ SECURID_KEY_GEN,
+ SECURID,
+ HOTP_KEY_GEN,
+ HOTP,
+ ACTI,
+ ACTI_KEY_GEN,
+ CAST_KEY_GEN,
+ CAST_ECB,
+ CAST_CBC,
+ CAST_MAC,
+ CAST_MAC_GENERAL,
+ CAST_CBC_PAD,
+ CAST3_KEY_GEN,
+ CAST3_ECB,
+ CAST3_CBC,
+ CAST3_MAC,
+ CAST3_MAC_GENERAL,
+ CAST3_CBC_PAD,
+ CAST5_KEY_GEN,
+ CAST128_KEY_GEN,
+ CAST5_ECB,
+ CAST128_ECB,
+ CAST5_CBC,
+ CAST128_CBC,
+ CAST5_MAC,
+ CAST128_MAC,
+ CAST5_MAC_GENERAL,
+ CAST128_MAC_GENERAL,
+ CAST5_CBC_PAD,
+ CAST128_CBC_PAD,
+ RC5_KEY_GEN,
+ RC5_ECB,
+ RC5_CBC,
+ RC5_MAC,
+ RC5_MAC_GENERAL,
+ RC5_CBC_PAD,
+ IDEA_KEY_GEN,
+ IDEA_ECB,
+ IDEA_CBC,
+ IDEA_MAC,
+ IDEA_MAC_GENERAL,
+ IDEA_CBC_PAD,
+ GENERIC_SECRET_KEY_GEN,
+ CONCATENATE_BASE_AND_KEY,
+ CONCATENATE_BASE_AND_DATA,
+ CONCATENATE_DATA_AND_BASE,
+ XOR_BASE_AND_DATA,
+ EXTRACT_KEY_FROM_KEY,
+ SSL3_PRE_MASTER_KEY_GEN,
+ SSL3_MASTER_KEY_DERIVE,
+ SSL3_KEY_AND_MAC_DERIVE,
+ SSL3_MASTER_KEY_DERIVE_DH,
+ TLS_PRE_MASTER_KEY_GEN,
+ TLS_MASTER_KEY_DERIVE,
+ TLS_KEY_AND_MAC_DERIVE,
+ TLS_MASTER_KEY_DERIVE_DH,
+ TLS_PRF,
+ SSL3_MD5_MAC,
+ SSL3_SHA1_MAC,
+ MD5_KEY_DERIVATION,
+ MD2_KEY_DERIVATION,
+ SHA1_KEY_DERIVATION,
+ SHA256_KEY_DERIVATION,
+ SHA384_KEY_DERIVATION,
+ SHA512_KEY_DERIVATION,
+ PBE_MD2_DES_CBC,
+ PBE_MD5_DES_CBC,
+ PBE_MD5_CAST_CBC,
+ PBE_MD5_CAST3_CBC,
+ PBE_MD5_CAST5_CBC,
+ PBE_MD5_CAST128_CBC,
+ PBE_SHA1_CAST5_CBC,
+ PBE_SHA1_CAST128_CBC,
+ PBE_SHA1_RC4_128,
+ PBE_SHA1_RC4_40,
+ PBE_SHA1_DES3_EDE_CBC,
+ PBE_SHA1_DES2_EDE_CBC,
+ PBE_SHA1_RC2_128_CBC,
+ PBE_SHA1_RC2_40_CBC,
+ PKCS5_PBKD2,
+ PBA_SHA1_WITH_SHA1_HMAC,
+ WTLS_PRE_MASTER_KEY_GEN,
+ WTLS_MASTER_KEY_DERIVE,
+ WTLS_MASTER_KEY_DERIVE_DH_ECC,
+ WTLS_PRF,
+ WTLS_SERVER_KEY_AND_MAC_DERIVE,
+ WTLS_CLIENT_KEY_AND_MAC_DERIVE,
+ KEY_WRAP_LYNKS,
+ KEY_WRAP_SET_OAEP,
+ CMS_SIG,
+ SKIPJACK_KEY_GEN,
+ SKIPJACK_ECB64,
+ SKIPJACK_CBC64,
+ SKIPJACK_OFB64,
+ SKIPJACK_CFB64,
+ SKIPJACK_CFB32,
+ SKIPJACK_CFB16,
+ SKIPJACK_CFB8,
+ SKIPJACK_WRAP,
+ SKIPJACK_PRIVATE_WRAP,
+ SKIPJACK_RELAYX,
+ KEA_KEY_PAIR_GEN,
+ KEA_KEY_DERIVE,
+ FORTEZZA_TIMESTAMP,
+ BATON_KEY_GEN,
+ BATON_ECB128,
+ BATON_ECB96,
+ BATON_CBC128,
+ BATON_COUNTER,
+ BATON_SHUFFLE,
+ BATON_WRAP,
+ ECDSA_KEY_PAIR_GEN,
+ EC_KEY_PAIR_GEN,
+ ECDSA,
+ ECDSA_SHA1,
+ ECDH1_DERIVE,
+ ECDH1_COFACTOR_DERIVE,
+ ECMQV_DERIVE,
+ JUNIPER_KEY_GEN,
+ JUNIPER_ECB128,
+ JUNIPER_CBC128,
+ JUNIPER_COUNTER,
+ JUNIPER_SHUFFLE,
+ JUNIPER_WRAP,
+ FASTHASH,
+ AES_KEY_GEN,
+ AES_ECB,
+ AES_CBC,
+ AES_MAC,
+ AES_MAC_GENERAL,
+ AES_CBC_PAD,
+ BLOWFISH_KEY_GEN,
+ BLOWFISH_CBC,
+ TWOFISH_KEY_GEN,
+ TWOFISH_CBC,
+ DES_ECB_ENCRYPT_DATA,
+ DES_CBC_ENCRYPT_DATA,
+ DES3_ECB_ENCRYPT_DATA,
+ DES3_CBC_ENCRYPT_DATA,
+ AES_ECB_ENCRYPT_DATA,
+ AES_CBC_ENCRYPT_DATA,
+ GOSTR3410_KEY_PAIR_GEN,
+ GOSTR3410,
+ GOSTR3410_WITH_GOSTR3411,
+ GOSTR3410_KEY_WRAP,
+ GOSTR3410_DERIVE,
+ GOSTR3411,
+ GOSTR3411_HMAC,
+ GOST28147_KEY_GEN,
+ GOST28147_ECB,
+ GOST28147,
+ GOST28147_MAC,
+ GOST28147_KEY_WRAP,
+ DSA_PARAMETER_GEN,
+ DH_PKCS_PARAMETER_GEN,
+ X9_42_DH_PARAMETER_GEN,
+ VENDOR_DEFINED,
+ }
+
+ [CCode (cname = "ulong", cprefix = "CKO_", has_type_id = false)]
+ public enum ObjectClass {
+ DATA,
+ CERTIFICATE,
+ PUBLIC_KEY,
+ PRIVATE_KEY,
+ SECRET_KEY,
+ HW_FEATURE,
+ DOMAIN_PARAMETERS,
+ MECHANISM,
+ OTP_KEY,
+ VENDOR_DEFINED,
+ }
+}
diff --git a/pkcs11/meson.build b/pkcs11/meson.build
index 760b7bf8..4234bab8 100644
--- a/pkcs11/meson.build
+++ b/pkcs11/meson.build
@@ -2,6 +2,7 @@ pkcs11_sources = [
'certificate-der-exporter.vala',
'pkcs11-certificate.vala',
'pkcs11-deleter.vala',
+ 'pkcs11-generate.vala',
'pkcs11-key-deleter.vala',
'pkcs11-module.vala',
'pkcs11-private-key.vala',
@@ -9,8 +10,8 @@ pkcs11_sources = [
'pkcs11-request.vala',
'pkcs11-token.vala',
+ 'cryptoki.vapi',
'seahorse-pkcs11-backend.c',
- 'seahorse-pkcs11-generate.c',
]
pkcs11_deps = [
@@ -20,9 +21,14 @@ pkcs11_deps = [
common_dep,
]
+pkcs11_vala_args = [
+ '--gresources', resources_xml,
+]
+
pkcs11_lib = static_library('seahorse-pkcs11',
pkcs11_sources,
dependencies: pkcs11_deps,
+ vala_args: pkcs11_vala_args,
)
pkcs11_dep = declare_dependency(
diff --git a/pkcs11/pkcs11-generate.vala b/pkcs11/pkcs11-generate.vala
new file mode 100644
index 00000000..8e72cd72
--- /dev/null
+++ b/pkcs11/pkcs11-generate.vala
@@ -0,0 +1,294 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+// FIXME: damn broken bindings
+extern Gcr.CollectionModel gcr_collection_model_new(Gcr.Collection collection,
+ Gcr.CollectionModelMode mode, ...);
+
+[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-pkcs11-generate.ui")]
+public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
+
+ [GtkChild]
+ private Gtk.Entry label_entry;
+
+ private Pkcs11.Token? token;
+ [GtkChild]
+ private Gtk.ComboBox token_box;
+ private Gcr.CollectionModel? token_model;
+
+ private Gck.Mechanism? mechanism;
+ private Gtk.ListStore? mechanism_store;
+ [GtkChild]
+ private Gtk.ComboBox mechanism_box;
+
+ [GtkChild]
+ private Gtk.SpinButton key_bits;
+
+ private Cancellable? cancellable;
+ private Gck.Attributes? pub_attrs;
+ private Gck.Attributes? prv_attrs;
+
+ private enum Column {
+ LABEL,
+ TYPE,
+ N_COLS
+ }
+
+ private struct Mechanism {
+ ulong mechanism_type;
+ unowned string label;
+ }
+ private const Mechanism[] AVAILABLE_MECHANISMS = {
+ { Cryptoki.MechanismType.RSA_PKCS_KEY_PAIR_GEN, N_("RSA") },
+ };
+
+ construct {
+ this.use_header_bar = 1;
+ this.key_bits.set_range(0, int.MAX); /* updated later */
+ this.key_bits.set_increments(128, 128);
+ this.key_bits.set_value(2048);
+
+ // The mechanism
+ this.mechanism_store = new Gtk.ListStore(2, typeof(string), typeof(ulong));
+ this.mechanism_store.set_default_sort_func(on_mechanism_sort);
+ this.mechanism_store.set_sort_column_id(Gtk.TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
Gtk.SortType.ASCENDING);
+ this.mechanism_box.set_model(this.mechanism_store);
+ Gtk.CellRenderer renderer = new Gtk.CellRendererText();
+ this.mechanism_box.pack_start(renderer, true);
+ this.mechanism_box.add_attribute(renderer, "markup", Column.LABEL);
+ this.mechanism_box.changed.connect(on_mechanism_changed);
+
+ // The tokens
+ Gcr.Collection collection = Pkcs11.Backend.get_writable_tokens(null,
Cryptoki.MechanismType.RSA_PKCS_KEY_PAIR_GEN);
+ this.token_model = gcr_collection_model_new(collection, Gcr.CollectionModelMode.LIST,
+ "icon", typeof(Icon), "label", typeof(string),
+ null);
+ this.token_model.set_sort_column_id(1, Gtk.SortType.ASCENDING);
+ this.token_box.set_model(this.token_model);
+ Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf();
+ icon_renderer.stock_size = Gtk.IconSize.BUTTON;
+ this.token_box.pack_start(icon_renderer, false);
+ this.token_box.add_attribute(icon_renderer, "gicon", 0);
+ renderer = new Gtk.CellRendererText();
+ this.token_box.pack_start(renderer, true);
+ this.token_box.add_attribute(renderer, "text", 1);
+ this.token_box.changed.connect(on_token_changed);
+ if (collection.get_length() > 0)
+ this.token_box.active = 0;
+
+ set_default_response (Gtk.ResponseType.OK);
+
+ update_response ();
+ }
+
+ public Generate(Gtk.Window? parent) {
+ GLib.Object(transient_for: parent);
+ }
+
+ ~Generate() {
+ this.token = null;
+ this.token_model = null;
+
+ this.mechanism = null;
+ this.mechanism_store = null;
+
+ this.cancellable = null;
+ this.pub_attrs = this.prv_attrs = null;
+ }
+
+ private void update_response() {
+ set_response_sensitive(Gtk.ResponseType.OK, this.token != null && this.mechanism != null);
+ }
+
+ private unowned string? get_available_mechanism_label (ulong type) {
+ foreach (Mechanism mechanism in AVAILABLE_MECHANISMS) {
+ if (mechanism.mechanism_type == type)
+ return mechanism.label;
+ }
+
+ return null;
+ }
+
+ private void on_token_changed(Gtk.ComboBox combo_box) {
+ this.token = null;
+
+ Gtk.TreeIter iter;
+ if (combo_box.get_active_iter(out iter)) {
+ this.token = (Pkcs11.Token) this.token_model.object_for_iter(iter);
+ }
+
+ bool valid = this.mechanism_store.get_iter_first(out iter);
+ if (this.token != null) {
+ for (uint i = 0; i < this.token.mechanisms.length; i++) {
+ ulong type = this.token.mechanisms.index(i);
+ unowned string? label = get_available_mechanism_label (type);
+ if (label == null)
+ continue;
+ while (valid) {
+ ulong otype;
+ this.mechanism_store.get(iter, Column.TYPE, out otype);
+ if (otype == type)
+ break;
+ valid = this.mechanism_store.remove(ref iter);
+ }
+ if (!valid)
+ this.mechanism_store.append(out iter);
+ this.mechanism_store.set(iter, Column.TYPE, type,
+ Column.LABEL, label);
+ valid = this.mechanism_store.iter_next(ref iter);
+ }
+ }
+ while (valid)
+ valid = this.mechanism_store.remove(ref iter);
+
+ /* Select first mechanism if none are selected */
+ if (!this.mechanism_box.get_active_iter(out iter))
+ if (this.mechanism_store.get_iter_first(out iter))
+ this.mechanism_box.set_active_iter(iter);
+
+ update_response ();
+ }
+
+ private void on_mechanism_changed(Gtk.ComboBox? widget) {
+ this.mechanism = null;
+
+ Gtk.TreeIter iter;
+ if (widget.get_active_iter(out iter)) {
+ this.mechanism = Gck.Mechanism();
+ this.mechanism_store.get(iter, Column.TYPE, out this.mechanism.type);
+
+ Gck.Slot slot = token.slot;
+ Gck.MechanismInfo info = slot.get_mechanism_info(this.mechanism.type);
+
+ ulong min = info.min_key_size;
+ ulong max = info.max_key_size;
+
+ if (min < 512 && max >= 512)
+ min = 512;
+ if (max > 16384 && min <= 16384)
+ max = 16384;
+ this.key_bits.set_range(min, max);
+ }
+
+ this.key_bits.sensitive = (this.mechanism != null);
+
+ update_response();
+ }
+
+ private int on_mechanism_sort (Gtk.TreeModel? model, Gtk.TreeIter a, Gtk.TreeIter b) {
+ string label_a, label_b;
+ model.get(a, Column.LABEL, out label_a);
+ model.get(b, Column.LABEL, out label_b);
+ return label_a.collate(label_b);
+ }
+
+ public override void response (int response_id) {
+ if (response_id == Gtk.ResponseType.OK)
+ generate.begin();
+
+ hide();
+ }
+
+ private async void generate() {
+ assert(this.token != null);
+
+ prepare_generate();
+
+ GLib.TlsInteraction interaction = new Seahorse.Interaction(this.transient_for);
+ Progress.show(this.cancellable, _("Generating key"), false);
+
+ try {
+ Gck.Session session = yield Gck.Session.open_async(this.token.slot,
+ Gck.SessionOptions.READ_WRITE | Gck.SessionOptions.LOGIN_USER,
+ interaction, this.cancellable);
+ Gck.Object pub, priv;
+ yield session.generate_key_pair_async(this.mechanism, this.pub_attrs, this.prv_attrs,
+ this.cancellable, out pub, out priv);
+ yield this.token.load(this.cancellable);
+ this.cancellable = null;
+ this.pub_attrs = this.prv_attrs = null;
+ } catch (Error e) {
+ Util.show_error(null, _("Couldn’t generate private key"), e.message);
+ }
+ }
+
+ private void prepare_generate() {
+ const uchar[] rsa_public_exponent = { 0x01, 0x00, 0x01 }; /* 65537 in bytes */
+
+ Gck.Builder publi = new Gck.Builder(Gck.BuilderFlags.SECURE_MEMORY);
+ Gck.Builder priva = new Gck.Builder(Gck.BuilderFlags.SECURE_MEMORY);
+
+ assert (this.cancellable == null);
+ assert (this.mechanism != null);
+
+ publi.add_ulong(Cryptoki.Attribute.CLASS, Cryptoki.ObjectClass.PUBLIC_KEY);
+ priva.add_ulong(Cryptoki.Attribute.CLASS, Cryptoki.ObjectClass.PRIVATE_KEY);
+
+ publi.add_boolean(Cryptoki.Attribute.TOKEN, true);
+ priva.add_boolean(Cryptoki.Attribute.TOKEN, true);
+
+ priva.add_boolean(Cryptoki.Attribute.PRIVATE, true);
+ priva.add_boolean(Cryptoki.Attribute.SENSITIVE, true);
+
+ string label = this.label_entry.text;
+ publi.add_string(Cryptoki.Attribute.LABEL, label);
+ priva.add_string(Cryptoki.Attribute.LABEL, label);
+
+ if (this.mechanism.type == Cryptoki.MechanismType.RSA_PKCS_KEY_PAIR_GEN) {
+ publi.add_boolean(Cryptoki.Attribute.ENCRYPT, true);
+ publi.add_boolean(Cryptoki.Attribute.VERIFY, true);
+ publi.add_boolean(Cryptoki.Attribute.WRAP, true);
+
+ priva.add_boolean(Cryptoki.Attribute.DECRYPT, true);
+ priva.add_boolean(Cryptoki.Attribute.SIGN, true);
+ priva.add_boolean(Cryptoki.Attribute.UNWRAP, true);
+
+ publi.add_data(Cryptoki.Attribute.PUBLIC_EXPONENT, rsa_public_exponent);
+ publi.add_ulong(Cryptoki.Attribute.MODULUS_BITS, this.key_bits.get_value_as_int());
+ } else {
+ warning("currently no support for this mechanism");
+ }
+
+ this.prv_attrs = priva.steal();
+ this.pub_attrs = publi.steal();
+
+ publi.clear();
+ priva.clear();
+ }
+
+ private static void on_generate_activate(Gtk.Action action) {
+ Generate dialog = new Generate(null);
+ dialog.run();
+ dialog.destroy();
+ }
+
+ private const Gtk.ActionEntry ACTION_ENTRIES[] = {
+ { "pkcs11-generate-key", Gcr.ICON_KEY_PAIR, N_ ("Private key"), "",
+ N_("Used to request a certificate"), on_generate_activate }
+ };
+
+ public static void register () {
+ Gtk.ActionGroup actions = new Gtk.ActionGroup("pkcs11-generate");
+ actions.set_translation_domain(Config.GETTEXT_PACKAGE);
+ actions.add_actions(ACTION_ENTRIES, null);
+ Registry.register_object(actions, "generator");
+ }
+}
diff --git a/pkcs11/seahorse-pkcs11-backend.c b/pkcs11/seahorse-pkcs11-backend.c
index 52074130..fe907635 100644
--- a/pkcs11/seahorse-pkcs11-backend.c
+++ b/pkcs11/seahorse-pkcs11-backend.c
@@ -22,8 +22,6 @@
#include "seahorse-pkcs11-backend.h"
-#include "seahorse-pkcs11-generate.h"
-
#include "pkcs11/seahorse-pkcs11.h"
#include "seahorse-common.h"
diff --git a/pkcs11/seahorse-pkcs11-backend.h b/pkcs11/seahorse-pkcs11-backend.h
index d6195ff6..ddcfd2fc 100644
--- a/pkcs11/seahorse-pkcs11-backend.h
+++ b/pkcs11/seahorse-pkcs11-backend.h
@@ -21,8 +21,6 @@
#ifndef SEAHORSE_PKCS11_BACKEND_H_
#define SEAHORSE_PKCS11_BACKEND_H_
-#include "pkcs11/seahorse-pkcs11.h"
-
#include <gcr/gcr.h>
#define SEAHORSE_PKCS11_STR "pkcs11"
diff --git a/pkcs11/seahorse-pkcs11-generate.ui b/pkcs11/seahorse-pkcs11-generate.ui
index 539c0c48..f240c722 100644
--- a/pkcs11/seahorse-pkcs11-generate.ui
+++ b/pkcs11/seahorse-pkcs11-generate.ui
@@ -1,153 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.0"/>
- <object class="GtkHBox" id="pkcs11-generate">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">7</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkImage" id="key-image">
+ <requires lib="gtk+" version="3.22"/>
+ <template class="SeahorsePkcs11Generate" parent="GtkDialog">
+ <property name="resizable">False</property>
+ <property name="title" translatable="yes">New private key</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="pixel_size">48</property>
- <property name="icon_name">gcr-key-pair</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="label45">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Create a new private key</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkGrid" id="grid2">
+ <object class="GtkBox" id="pkcs11-generate">
<property name="visible">True</property>
+ <property name="orientation">horizontal</property>
<property name="can_focus">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
+ <property name="border_width">7</property>
+ <property name="spacing">12</property>
<child>
- <object class="GtkLabel" id="label1">
+ <object class="GtkImage" id="key-image">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Label:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Stored at:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="key-label">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="activates_default">True</property>
+ <property name="yalign">0</property>
+ <property name="pixel_size">48</property>
+ <property name="icon_name">gcr-key-pair</property>
</object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
</child>
<child>
- <object class="GtkComboBox" id="key-token">
+ <object class="GtkBox" id="vbox1">
<property name="visible">True</property>
+ <property name="orientation">vertical</property>
<property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkExpander" id="expander1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">12</property>
- <property name="left_padding">12</property>
+ <property name="spacing">12</property>
<child>
- <object class="GtkGrid" id="grid1">
+ <object class="GtkLabel" id="label45">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Create a new private key</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
- <object class="GtkLabel" id="label49">
+ <object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Key _Type:</property>
- <property name="use_underline">True</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">Label:</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -157,12 +65,11 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label50">
+ <object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Key _Strength (bits):</property>
- <property name="use_underline">True</property>
+ <property name="label" translatable="yes">Stored at:</property>
+ <property name="halign">end</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -172,9 +79,12 @@
</packing>
</child>
<child>
- <object class="GtkComboBox" id="key-mechanism">
+ <object class="GtkEntry" id="label_entry">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="invisible_char_set">True</property>
+ <property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@@ -184,65 +94,108 @@
</packing>
</child>
<child>
- <object class="GtkSpinButton" id="key-bits">
+ <object class="GtkComboBox" id="token_box">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="invisible_char_set">True</property>
- <property name="climb_rate">64</property>
- <property name="numeric">True</property>
- <property name="activates_default">True</property>
+ <property name="can_focus">False</property>
</object>
<packing>
- <property name="left_attach">1</property>
<property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="left_attach">1</property>
</packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="label48">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Advanced key options</property>
+ <property name="use_underline">True</property>
+ <property name="halign">start</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="left_attach">0</property>
+ <property name="width">2</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="label49">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">Key _Type:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="left_attach">0</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkComboBox" id="mechanism_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="left_attach">1</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="label50">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">Key _Strength (bits):</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="left_attach">0</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkSpinButton" id="key_bits">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="invisible_char_set">True</property>
+ <property name="climb_rate">64</property>
+ <property name="numeric">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="left_attach">1</property>
+ </packing>
</child>
</object>
</child>
</object>
</child>
- <child type="label">
- <object class="GtkLabel" id="label48">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Advanced key options</property>
- <property name="use_underline">True</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
- </object>
+
+ <child type="action">
+ <object class="GtkButton" id="button_cancel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Cancel</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="button_ok">
+ <property name="visible">True</property>
+ <property name="can-default">True</property>
+ <property name="label" translatable="yes">Create</property>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="cancel">button_cancel</action-widget>
+ <action-widget response="ok" default="true">button_ok</action-widget>
+ </action-widgets>
+ </template>
</interface>
diff --git a/src/application.vala b/src/application.vala
index 57bafe36..b07c3c06 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -21,8 +21,6 @@
* <http://www.gnu.org/licenses/>.
*/
-extern void seahorse_pkcs11_backend_initialize();
-
public class Seahorse.Application : Gtk.Application {
private SearchProvider? search_provider;
private uint search_provider_dbus_id = 0;
@@ -50,7 +48,7 @@ public class Seahorse.Application : Gtk.Application {
Pgp.Backend.initialize();
#endif
#if WITH_PKCS11
- seahorse_pkcs11_backend_initialize();
+ Pkcs11.Backend.initialize();
#endif
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]