summaryrefslogtreecommitdiff
path: root/gcr
diff options
context:
space:
mode:
Diffstat (limited to 'gcr')
-rw-r--r--gcr/.gitignore7
-rw-r--r--gcr/Makefile.am376
-rw-r--r--gcr/gcr-base.h55
-rw-r--r--gcr/gcr-base.pc.in16
-rw-r--r--gcr/gcr-base.symbols157
-rw-r--r--gcr/gcr-callback-output-stream.c132
-rw-r--r--gcr/gcr-callback-output-stream.h58
-rw-r--r--gcr/gcr-certificate-basics-widget.c75
-rw-r--r--gcr/gcr-certificate-basics-widget.h62
-rw-r--r--gcr/gcr-certificate-chain.c825
-rw-r--r--gcr/gcr-certificate-chain.h113
-rw-r--r--gcr/gcr-certificate-details-widget.c75
-rw-r--r--gcr/gcr-certificate-details-widget.h62
-rw-r--r--gcr/gcr-certificate-exporter.c567
-rw-r--r--gcr/gcr-certificate-exporter.h74
-rw-r--r--gcr/gcr-certificate-extensions.c295
-rw-r--r--gcr/gcr-certificate-extensions.h88
-rw-r--r--gcr/gcr-certificate-renderer.c909
-rw-r--r--gcr/gcr-certificate-renderer.h77
-rw-r--r--gcr/gcr-certificate-widget.c266
-rw-r--r--gcr/gcr-certificate-widget.h67
-rw-r--r--gcr/gcr-certificate.c1082
-rw-r--r--gcr/gcr-certificate.h130
-rw-r--r--gcr/gcr-collection-model.c1575
-rw-r--r--gcr/gcr-collection-model.h89
-rw-r--r--gcr/gcr-collection.c178
-rw-r--r--gcr/gcr-collection.h82
-rw-r--r--gcr/gcr-column.c66
-rw-r--r--gcr/gcr-column.h55
-rw-r--r--gcr/gcr-combo-selector.c269
-rw-r--r--gcr/gcr-combo-selector.h67
-rw-r--r--gcr/gcr-comparable.c146
-rw-r--r--gcr/gcr-comparable.h54
-rw-r--r--gcr/gcr-crypto-types.xml151
-rw-r--r--gcr/gcr-debug.c111
-rw-r--r--gcr/gcr-debug.h90
-rw-r--r--gcr/gcr-deprecated-base.h73
-rw-r--r--gcr/gcr-deprecated.h48
-rw-r--r--gcr/gcr-dialog-util.c182
-rw-r--r--gcr/gcr-dialog-util.h42
-rw-r--r--gcr/gcr-display-scrolled.c176
-rw-r--r--gcr/gcr-display-scrolled.h57
-rw-r--r--gcr/gcr-display-view.c1243
-rw-r--r--gcr/gcr-display-view.h115
-rw-r--r--gcr/gcr-enum-types.c.template43
-rw-r--r--gcr/gcr-enum-types.h.template28
-rw-r--r--gcr/gcr-failure-renderer.c224
-rw-r--r--gcr/gcr-failure-renderer.h67
-rw-r--r--gcr/gcr-fingerprint.c384
-rw-r--r--gcr/gcr-fingerprint.h49
-rw-r--r--gcr/gcr-gnupg-collection.c754
-rw-r--r--gcr/gcr-gnupg-collection.h70
-rw-r--r--gcr/gcr-gnupg-importer.c333
-rw-r--r--gcr/gcr-gnupg-importer.h67
-rw-r--r--gcr/gcr-gnupg-key.c530
-rw-r--r--gcr/gcr-gnupg-key.h81
-rw-r--r--gcr/gcr-gnupg-process.c1157
-rw-r--r--gcr/gcr-gnupg-process.h103
-rw-r--r--gcr/gcr-gnupg-records.c267
-rw-r--r--gcr/gcr-gnupg-records.h52
-rw-r--r--gcr/gcr-gnupg-renderer.c853
-rw-r--r--gcr/gcr-gnupg-renderer.h77
-rw-r--r--gcr/gcr-gnupg-util.c87
-rw-r--r--gcr/gcr-gnupg-util.h41
-rw-r--r--gcr/gcr-icons.c55
-rw-r--r--gcr/gcr-icons.h46
-rw-r--r--gcr/gcr-import-button.c560
-rw-r--r--gcr/gcr-import-button.h68
-rw-r--r--gcr/gcr-import-interaction.c205
-rw-r--r--gcr/gcr-import-interaction.h94
-rw-r--r--gcr/gcr-importer.c628
-rw-r--r--gcr/gcr-importer.h107
-rw-r--r--gcr/gcr-internal.h37
-rw-r--r--gcr/gcr-key-renderer.c404
-rw-r--r--gcr/gcr-key-renderer.h68
-rw-r--r--gcr/gcr-key-widget.c224
-rw-r--r--gcr/gcr-key-widget.h61
-rw-r--r--gcr/gcr-library.c558
-rw-r--r--gcr/gcr-library.h67
-rw-r--r--gcr/gcr-list-selector-private.h40
-rw-r--r--gcr/gcr-list-selector.c456
-rw-r--r--gcr/gcr-list-selector.h71
-rw-r--r--gcr/gcr-live-search.c672
-rw-r--r--gcr/gcr-live-search.h84
-rw-r--r--gcr/gcr-marshal.list7
-rw-r--r--gcr/gcr-memory-icon.c225
-rw-r--r--gcr/gcr-memory-icon.h66
-rw-r--r--gcr/gcr-memory.c92
-rw-r--r--gcr/gcr-menu-button.c372
-rw-r--r--gcr/gcr-menu-button.h61
-rw-r--r--gcr/gcr-mkoids85
-rw-r--r--gcr/gcr-oids.list22
-rw-r--r--gcr/gcr-openpgp.c1304
-rw-r--r--gcr/gcr-openpgp.h66
-rw-r--r--gcr/gcr-openssh.c491
-rw-r--r--gcr/gcr-openssh.h51
-rw-r--r--gcr/gcr-parser.c2934
-rw-r--r--gcr/gcr-parser.h136
-rw-r--r--gcr/gcr-pkcs11-certificate.c452
-rw-r--r--gcr/gcr-pkcs11-certificate.h79
-rw-r--r--gcr/gcr-pkcs11-import-dialog.c278
-rw-r--r--gcr/gcr-pkcs11-import-dialog.h67
-rw-r--r--gcr/gcr-pkcs11-import-dialog.ui251
-rw-r--r--gcr/gcr-pkcs11-import-interaction.c259
-rw-r--r--gcr/gcr-pkcs11-import-interaction.h45
-rw-r--r--gcr/gcr-pkcs11-importer.c910
-rw-r--r--gcr/gcr-pkcs11-importer.h62
-rw-r--r--gcr/gcr-record.c811
-rw-r--r--gcr/gcr-record.h281
-rw-r--r--gcr/gcr-renderer.c294
-rw-r--r--gcr/gcr-renderer.h85
-rw-r--r--gcr/gcr-secret-exchange.c848
-rw-r--r--gcr/gcr-secret-exchange.h109
-rw-r--r--gcr/gcr-simple-certificate.c185
-rw-r--r--gcr/gcr-simple-certificate.h67
-rw-r--r--gcr/gcr-simple-collection.c208
-rw-r--r--gcr/gcr-simple-collection.h66
-rw-r--r--gcr/gcr-single-collection.c157
-rw-r--r--gcr/gcr-single-collection.h55
-rw-r--r--gcr/gcr-tree-selector.c361
-rw-r--r--gcr/gcr-tree-selector.h70
-rw-r--r--gcr/gcr-trust.c878
-rw-r--r--gcr/gcr-trust.h102
-rw-r--r--gcr/gcr-types.h116
-rw-r--r--gcr/gcr-union-collection.c340
-rw-r--r--gcr/gcr-union-collection.h76
-rw-r--r--gcr/gcr-unlock-options-widget.c515
-rw-r--r--gcr/gcr-unlock-options-widget.h82
-rw-r--r--gcr/gcr-unlock-options-widget.ui117
-rw-r--r--gcr/gcr-unlock-options.h32
-rw-r--r--gcr/gcr-unlock-renderer.c345
-rw-r--r--gcr/gcr-unlock-renderer.h79
-rw-r--r--gcr/gcr-util.c66
-rw-r--r--gcr/gcr-util.h41
-rw-r--r--gcr/gcr-viewer-tool.c130
-rw-r--r--gcr/gcr-viewer-widget.c504
-rw-r--r--gcr/gcr-viewer-widget.h55
-rw-r--r--gcr/gcr-viewer-window.c178
-rw-r--r--gcr/gcr-viewer-window.h64
-rw-r--r--gcr/gcr-viewer.c191
-rw-r--r--gcr/gcr-viewer.desktop.in.in10
-rw-r--r--gcr/gcr-viewer.h87
-rw-r--r--gcr/gcr.h60
-rw-r--r--gcr/gcr.pc.in16
-rw-r--r--gcr/gcr.symbols103
-rw-r--r--gcr/icons/16x16/Makefile.am11
-rw-r--r--gcr/icons/16x16/gcr-key-pair.pngbin878 -> 0 bytes
-rw-r--r--gcr/icons/16x16/gcr-key.pngbin675 -> 0 bytes
-rw-r--r--gcr/icons/16x16/gcr-smart-card.pngbin509 -> 0 bytes
-rw-r--r--gcr/icons/22x22/Makefile.am9
-rw-r--r--gcr/icons/22x22/gcr-smart-card.pngbin662 -> 0 bytes
-rw-r--r--gcr/icons/24x24/Makefile.am11
-rw-r--r--gcr/icons/24x24/gcr-key-pair.pngbin1221 -> 0 bytes
-rw-r--r--gcr/icons/24x24/gcr-key.pngbin875 -> 0 bytes
-rw-r--r--gcr/icons/24x24/gcr-smart-card.pngbin636 -> 0 bytes
-rw-r--r--gcr/icons/256x256/Makefile.am9
-rw-r--r--gcr/icons/256x256/gcr-smart-card.pngbin9294 -> 0 bytes
-rw-r--r--gcr/icons/32x32/Makefile.am11
-rw-r--r--gcr/icons/32x32/gcr-key-pair.pngbin1882 -> 0 bytes
-rw-r--r--gcr/icons/32x32/gcr-key.pngbin1201 -> 0 bytes
-rw-r--r--gcr/icons/32x32/gcr-smart-card.pngbin1093 -> 0 bytes
-rw-r--r--gcr/icons/48x48/Makefile.am11
-rw-r--r--gcr/icons/48x48/gcr-key-pair.pngbin3480 -> 0 bytes
-rw-r--r--gcr/icons/48x48/gcr-key.pngbin2087 -> 0 bytes
-rw-r--r--gcr/icons/48x48/gcr-smart-card.pngbin1684 -> 0 bytes
-rw-r--r--gcr/icons/Makefile.am20
-rw-r--r--gcr/icons/key-and-keypair.svg3921
-rwxr-xr-xgcr/icons/render-icons.py174
-rw-r--r--gcr/icons/src/gcr-smart-card.svg1165
-rw-r--r--gcr/tests/.gitignore5
-rw-r--r--gcr/tests/Makefile.am68
-rw-r--r--gcr/tests/files/RSA_Root_Certificate_1.pem19
-rw-r--r--gcr/tests/files/RSA_Security_1024_v3.pem16
-rw-r--r--gcr/tests/files/RSA_Security_2048_v3.pem22
-rw-r--r--gcr/tests/files/Thawte_Personal_Basic_CA.pem20
-rw-r--r--gcr/tests/files/Thawte_Personal_Freemail_CA.pem21
-rw-r--r--gcr/tests/files/Thawte_Personal_Premium_CA.pem21
-rw-r--r--gcr/tests/files/Thawte_Premium_Server_CA.pem21
-rw-r--r--gcr/tests/files/Thawte_Server_CA.pem20
-rw-r--r--gcr/tests/files/Thawte_Time_Stamping_CA.pem18
-rw-r--r--gcr/tests/files/ca-certificates.crt2560
-rw-r--r--gcr/tests/files/cacert.org.cerbin1857 -> 0 bytes
-rw-r--r--gcr/tests/files/cacert.org.pem41
-rw-r--r--gcr/tests/files/client.crtbin736 -> 0 bytes
-rw-r--r--gcr/tests/files/client.key27
-rw-r--r--gcr/tests/files/client.pem18
-rw-r--r--gcr/tests/files/collabora-ca.cerbin1536 -> 0 bytes
-rwxr-xr-xgcr/tests/files/der-certificate-dsa.cerbin1639 -> 0 bytes
-rw-r--r--gcr/tests/files/der-certificate.crtbin747 -> 0 bytes
-rw-r--r--gcr/tests/files/der-dsa-1024.keybin447 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-PBE-MD5-DES.p8bin677 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-PBE-SHA1-3DES.p8bin678 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-PBE-SHA1-DES.p8bin677 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-PBE-SHA1-RC2-40.p8bin678 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-PBE-SHA1-RC4-128.p8bin673 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-dsa.p8bin335 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-encrypted-pkcs5.p8bin677 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-v2-des.p8bin711 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key-v2-des3.p8bin714 -> 0 bytes
-rw-r--r--gcr/tests/files/der-key.p8bin635 -> 0 bytes
-rw-r--r--gcr/tests/files/der-rsa-1024.keybin609 -> 0 bytes
-rw-r--r--gcr/tests/files/dhansak-collabora.cerbin1200 -> 0 bytes
-rw-r--r--gcr/tests/files/email.p12bin2488 -> 0 bytes
-rw-r--r--gcr/tests/files/generic-dsa.crtbin918 -> 0 bytes
-rw-r--r--gcr/tests/files/generic-dsa.key12
-rw-r--r--gcr/tests/files/generic-dsa.pem22
-rw-r--r--gcr/tests/files/gnupg-homedir/pubring.gpgbin21969 -> 0 bytes
-rw-r--r--gcr/tests/files/gnupg-homedir/secring.gpgbin4398 -> 0 bytes
-rw-r--r--gcr/tests/files/gnupg-homedir/trustdb.gpgbin1400 -> 0 bytes
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-arguments-environ22
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-echo8
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-fail-exit6
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-fail-signal8
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-simple-error9
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-simple-output8
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-status-and-attribute34
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-status-and-output24
-rwxr-xr-xgcr/tests/files/gnupg-mock/mock-with-homedir22
-rw-r--r--gcr/tests/files/openssh_keys.pub2
-rw-r--r--gcr/tests/files/pem-dsa-1024.key12
-rw-r--r--gcr/tests/files/pem-pkcs8.key17
-rw-r--r--gcr/tests/files/pem-rsa-enc.key18
-rw-r--r--gcr/tests/files/personal.p12bin3396 -> 0 bytes
-rw-r--r--gcr/tests/files/pubring.gpgbin21969 -> 0 bytes
-rw-r--r--gcr/tests/files/secring.gpgbin4398 -> 0 bytes
-rwxr-xr-xgcr/tests/files/test-x509-swiss.p7bbin1002 -> 0 bytes
-rw-r--r--gcr/tests/files/unclient.p12bin1476 -> 0 bytes
-rw-r--r--gcr/tests/files/werner-koch.asc71
-rw-r--r--gcr/tests/frob-certificate.c92
-rw-r--r--gcr/tests/frob-combo-selector.c95
-rw-r--r--gcr/tests/frob-gnupg-selector.c95
-rw-r--r--gcr/tests/frob-key.c87
-rw-r--r--gcr/tests/frob-openpgp.c122
-rw-r--r--gcr/tests/frob-parser.c132
-rw-r--r--gcr/tests/frob-tree-selector.c208
-rw-r--r--gcr/tests/frob-unlock-options.c84
-rw-r--r--gcr/tests/frob-unlock.c112
-rw-r--r--gcr/tests/test-certificate-chain.c658
-rw-r--r--gcr/tests/test-certificate.c279
-rw-r--r--gcr/tests/test-fingerprint.c212
-rw-r--r--gcr/tests/test-gnupg-collection.c222
-rw-r--r--gcr/tests/test-gnupg-key.c228
-rw-r--r--gcr/tests/test-gnupg-process.c600
-rw-r--r--gcr/tests/test-memory-icon.c206
-rw-r--r--gcr/tests/test-openpgp.c354
-rw-r--r--gcr/tests/test-openssh.c196
-rw-r--r--gcr/tests/test-parser.c249
-rw-r--r--gcr/tests/test-pkcs11-certificate.c279
-rw-r--r--gcr/tests/test-record.c294
-rw-r--r--gcr/tests/test-secret-exchange.c162
-rw-r--r--gcr/tests/test-simple-certificate.c104
-rw-r--r--gcr/tests/test-trust.c327
-rw-r--r--gcr/tests/test-util.c112
253 files changed, 0 insertions, 50351 deletions
diff --git a/gcr/.gitignore b/gcr/.gitignore
deleted file mode 100644
index ff88723d..00000000
--- a/gcr/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-/gcr.pc
-/gcr-0.pc
-/gcr-3.pc
-/gcr-viewer.desktop
-/gcr-viewer.desktop.in
-/Gcr-3.0.gir
-/Gcr-3.0.typelib
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
deleted file mode 100644
index f1fd40b7..00000000
--- a/gcr/Makefile.am
+++ /dev/null
@@ -1,376 +0,0 @@
-SUBDIRS = . icons tests
-
-# ------------------------------------------------------------------
-# UI BUILDER
-#
-
-uidir = $(datadir)/gcr-@GCR_MAJOR@/ui/
-
-ui_DATA = \
- gcr-pkcs11-import-dialog.ui \
- gcr-unlock-options-widget.ui
-
-# ------------------------------------------------------------------
-# HEADERS
-
-HEADER_BASE_FILES = \
- gcr-base.h \
- gcr-certificate.h \
- gcr-certificate-chain.h \
- gcr-collection.h \
- gcr-comparable.h \
- gcr-deprecated-base.h \
- gcr-fingerprint.h \
- gcr-icons.h \
- gcr-importer.h \
- gcr-import-interaction.h \
- gcr-library.h \
- gcr-parser.h \
- gcr-pkcs11-certificate.h \
- gcr-secret-exchange.h \
- gcr-simple-certificate.h \
- gcr-trust.h \
- gcr-types.h \
- gcr-union-collection.h \
- gcr-unlock-options.h
-
-HEADER_UI_FILES = \
- gcr.h \
- gcr-certificate-basics-widget.h \
- gcr-certificate-details-widget.h \
- gcr-certificate-renderer.h \
- gcr-certificate-widget.h \
- gcr-collection-model.h \
- gcr-column.h \
- gcr-combo-selector.h \
- gcr-deprecated.h \
- gcr-failure-renderer.h \
- gcr-key-renderer.h \
- gcr-key-widget.h \
- gcr-import-button.h \
- gcr-list-selector.h \
- gcr-renderer.h \
- gcr-simple-collection.h \
- gcr-tree-selector.h \
- gcr-unlock-options-widget.h \
- gcr-viewer.h \
- gcr-viewer-widget.h
-
-incdir = $(includedir)/gcr-@GCR_MAJOR@/gcr
-
-inc_HEADERS = \
- $(HEADER_BASE_FILES) \
- $(HEADER_UI_FILES) \
- gcr-enum-types-base.h \
- gcr-enum-types.h
-
-# ------------------------------------------------------------------
-# LIBRARY
-
-INCLUDES = \
- -I$(top_builddir) \
- -I$(top_srcdir) \
- $(GOBJECT_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(LIBGCRYPT_CFLAGS) \
- $(P11_KIT_CFLAGS) \
- -DG_LOG_DOMAIN=\"Gcr\"
-
-lib_LTLIBRARIES = \
- libgcr-base-@GCR_MAJOR@.la \
- libgcr-@GCR_MAJOR@.la
-
-BUILT_BASE_FILES = \
- gcr-marshal.c gcr-marshal.h \
- gcr-enum-types-base.c gcr-enum-types-base.h \
- gcr-oids.c gcr-oids.h
-
-BUILT_UI_FILES = \
- gcr-marshal.c gcr-marshal.h \
- gcr-enum-types.c gcr-enum-types.h \
- gcr-oids.c gcr-oids.h
-
-BUILT_SOURCES = \
- $(BUILT_BASE_FILES) \
- $(BUILT_UI_FILES)
-
-libgcr_base_@GCR_MAJOR@_la_SOURCES = \
- gcr-callback-output-stream.c gcr-callback-output-stream.h \
- gcr-certificate.c gcr-certificate.h \
- gcr-certificate-chain.c gcr-certificate-chain.h \
- gcr-collection.c gcr-collection.h \
- gcr-comparable.c gcr-comparable.h \
- gcr-debug.c gcr-debug.h \
- gcr-fingerprint.c gcr-fingerprint.h \
- gcr-gnupg-collection.c gcr-gnupg-collection.h \
- gcr-gnupg-importer.c gcr-gnupg-importer.h \
- gcr-gnupg-key.c gcr-gnupg-key.h \
- gcr-gnupg-process.c gcr-gnupg-process.h \
- gcr-gnupg-records.c gcr-gnupg-records.h \
- gcr-gnupg-util.c gcr-gnupg-util.h \
- gcr-icons.c gcr-icons.h \
- gcr-importer.c gcr-importer.h \
- gcr-import-interaction.c gcr-import-interaction.h \
- gcr-internal.h \
- gcr-library.c gcr-library.h \
- gcr-memory.c \
- gcr-memory-icon.c gcr-memory-icon.h \
- gcr-openpgp.c gcr-openpgp.h \
- gcr-openssh.c gcr-openssh.h \
- gcr-parser.c gcr-parser.h \
- gcr-pkcs11-certificate.c gcr-pkcs11-certificate.h \
- gcr-pkcs11-importer.c gcr-pkcs11-importer.h \
- gcr-record.c gcr-record.h \
- gcr-secret-exchange.c gcr-secret-exchange.h \
- gcr-simple-certificate.c gcr-simple-certificate.h \
- gcr-simple-collection.c gcr-simple-collection.h \
- gcr-single-collection.c gcr-single-collection.h \
- gcr-trust.c gcr-trust.h \
- gcr-types.h \
- gcr-union-collection.c gcr-union-collection.h \
- gcr-util.c gcr-util.h \
- $(BUILT_BASE_FILES)
-
-libgcr_@GCR_MAJOR@_la_SOURCES = \
- gcr-certificate-basics-widget.c gcr-certificate-basics-widget.h \
- gcr-certificate-details-widget.c gcr-certificate-details-widget.h \
- gcr-certificate-exporter.c gcr-certificate-exporter.h \
- gcr-certificate-extensions.c gcr-certificate-extensions.h \
- gcr-certificate-renderer.c gcr-certificate-renderer.h \
- gcr-certificate-widget.c gcr-certificate-widget.h \
- gcr-collection-model.c gcr-collection-model.h \
- gcr-combo-selector.c gcr-combo-selector.h \
- gcr-debug.c gcr-debug.h \
- gcr-dialog-util.c gcr-dialog-util.h \
- gcr-display-scrolled.c gcr-display-scrolled.h \
- gcr-display-view.c gcr-display-view.h \
- gcr-failure-renderer.c gcr-failure-renderer.h \
- gcr-gnupg-renderer.c gcr-gnupg-renderer.h \
- gcr-gnupg-records.c gcr-gnupg-records.h \
- gcr-import-button.c gcr-import-button.h \
- gcr-key-renderer.c gcr-key-renderer.h \
- gcr-key-widget.c gcr-key-widget.h \
- gcr-list-selector.c gcr-list-selector.h gcr-list-selector-private.h \
- gcr-live-search.c gcr-live-search.h \
- gcr-memory.c \
- gcr-memory-icon.c gcr-memory-icon.h \
- gcr-menu-button.c gcr-menu-button.h \
- gcr-pkcs11-import-interaction.c gcr-pkcs11-import-interaction.h \
- gcr-pkcs11-import-dialog.c gcr-pkcs11-import-dialog.h \
- gcr-record.c gcr-record.h \
- gcr-renderer.c gcr-renderer.h \
- gcr-tree-selector.c gcr-tree-selector.h \
- gcr-unlock-options.h \
- gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
- gcr-unlock-renderer.c gcr-unlock-renderer.h \
- gcr-viewer.c gcr-viewer.h \
- gcr-viewer-widget.c gcr-viewer-widget.h \
- gcr-viewer-window.c gcr-viewer-window.h \
- $(BUILT_UI_FILES)
-
-libgcr_base_@GCR_MAJOR@_la_CFLAGS = \
- -DGCK_API_SUBJECT_TO_CHANGE \
- -DGCR_API_SUBJECT_TO_CHANGE \
- -DP11_KIT_API_SUBJECT_TO_CHANGE \
- -DGCR_COMPILATION
-
-libgcr_@GCR_MAJOR@_la_CFLAGS = \
- $(GTK_CFLAGS) \
- -DUIDIR=\""$(uidir)"\" \
- $(libgcr_base_@GCR_MAJOR@_la_CFLAGS)
-
-libgcr_base_@GCR_MAJOR@_la_LDFLAGS = \
- -version-info $(GCR_LT_RELEASE) \
- -no-undefined \
- -export-symbols-regex '^gcr_*'
-
-libgcr_@GCR_MAJOR@_la_LDFLAGS = \
- $(libgcr_base_@GCR_MAJOR@_la_LDFLAGS)
-
-libgcr_base_@GCR_MAJOR@_la_LIBADD = \
- $(top_builddir)/egg/libegg.la \
- $(top_builddir)/gck/libgck-@GCK_MAJOR@.la \
- $(GOBJECT_LIBS) \
- $(GLIB_LIBS) \
- $(LIBGCRYPT_LIBS) \
- $(P11_KIT_LIBS)
-
-libgcr_@GCR_MAJOR@_la_LIBADD = \
- $(GTK_LIBS) \
- $(libgcr_base_@GCR_MAJOR@_la_LIBADD) \
- $(top_builddir)/egg/libegg-entry-buffer.la \
- $(builddir)/libgcr-base-$(GCR_MAJOR).la
-
-noinst_LTLIBRARIES = libgcr-testable.la
-libgcr_testable_la_SOURCES =
-libgcr_testable_la_LIBADD = \
- $(libgcr_base_@GCR_MAJOR@_la_OBJECTS) \
- $(libgcr_@GCR_MAJOR@_la_OBJECTS) \
- $(libgcr_@GCR_MAJOR@_la_LIBADD)
-libgcr_testable_la_DEPENDENCIES = \
- $(libgcr_base_@GCR_MAJOR@_la_OBJECTS) \
- $(libgcr_@GCR_MAJOR@_la_OBJECTS)
-
-gcr-marshal.h: gcr-marshal.list $(GLIB_GENMARSHAL)
- $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=_gcr_marshal > $@
-
-gcr-marshal.c: gcr-marshal.list $(GLIB_GENMARSHAL)
- $(AM_V_GEN) ( echo "#include \"gcr-marshal.h\"" > $@ && \
- $(GLIB_GENMARSHAL) $< --body --prefix=_gcr_marshal >> $@ )
-
-gcr-enum-types.h: $(HEADER_UI_FILES) gcr-enum-types.h.template
- $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/gcr-enum-types.h.template \
- $(HEADER_UI_FILES) > $@
-
-gcr-enum-types.c: $(HEADER_UI_FILES) gcr-enum-types.c.template
- $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/gcr-enum-types.c.template \
- $(HEADER_UI_FILES) > $@
-
-gcr-enum-types-base.h: $(HEADER_BASE_FILES) gcr-enum-types.h.template
- $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/gcr-enum-types.h.template \
- $(HEADER_BASE_FILES) > $@
-
-gcr-enum-types-base.c: $(HEADER_BASE_FILES) gcr-enum-types.c.template
- $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/gcr-enum-types.c.template \
- $(HEADER_BASE_FILES) > $@
-
-gcr-oids.c: gcr-oids.list gcr-mkoids
- $(AM_V_GEN) sh gcr-mkoids -p GCR -c gcr-oids.c -h gcr-oids.h gcr-oids.list
-
-gcr-oids.h: gcr-oids.c
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = gcr-$(GCR_MAJOR).pc gcr-base-$(GCR_MAJOR).pc
-
-gcr-$(GCR_MAJOR).pc: gcr.pc
- cp gcr.pc gcr-$(GCR_MAJOR).pc
-gcr-base-$(GCR_MAJOR).pc: gcr-base.pc
- cp gcr-base.pc gcr-base-$(GCR_MAJOR).pc
-
-# ----------------------------------------------------------------
-# SYSTEM INTEGRATION
-
-# The new mime system
-mimedir = $(datadir)/mime/packages
-mime_DATA = gcr-crypto-types.xml
-
-if WITH_UPDATE_MIME
-update_mime_database_cmd = update-mime-database $(datadir)/mime/
-
-install-data-hook: update_mime_database
-uninstall-hook: update_mime_database
-
-update_mime_database:
- @-if test -z "$(DESTDIR)"; then \
- echo "Updating MIME database."; \
- $(update_mime_database_cmd); \
- else \
- echo "*** MIME database not updated. After (un)install, run this:"; \
- echo "*** $(update_mime_database_cmd)"; \
- fi
-endif
-
-desktopdir = $(datadir)/applications
-desktop_in_in_files = gcr-viewer.desktop.in.in
-desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
-desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
-@INTLTOOL_DESKTOP_RULE@
-
-# ----------------------------------------------------------------
-# TOOLS
-
-bin_PROGRAMS = gcr-viewer
-
-gcr_viewer_SOURCES = \
- gcr-viewer-tool.c
-
-gcr_viewer_CFLAGS = \
- $(GTK_CFLAGS) \
- -DLOCALEDIR=\""$(datadir)/locale"\" \
- -DGCR_API_SUBJECT_TO_CHANGE
-
-gcr_viewer_LDADD = \
- $(builddir)/libgcr-$(GCR_MAJOR).la \
- $(top_builddir)/gck/libgck-@GCK_MAJOR@.la \
- $(GTK_LIBS)
-
-# ------------------------------------------------------------------
-# INTROSPECTION
-
-if HAVE_INTROSPECTION
-
-include $(INTROSPECTION_MAKEFILE)
-
-INTROSPECTION_GIRS = Gcr-@GCR_MAJOR@.gir
-INTROSPECTION_SCANNER_ARGS = $(INTROSPECTION_FLAGS) --warn-all --add-include-path=$(srcdir) --add-include-path=$(top_builddir)/gck
-INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(top_builddir)/gck
-
-Gcr-@GCR_MAJOR@.gir: libgcr-@GCR_MAJOR@.la
-
-Gcr_@GCR_MAJOR@_gir_PACKAGES = gobject-2.0 gtk+-3.0 p11-kit-1
-Gcr_@GCR_MAJOR@_gir_EXPORT_PACKAGES = gcr-3
-Gcr_@GCR_MAJOR@_gir_INCLUDES = GObject-2.0 Gtk-3.0 Gck-@GCK_MAJOR@
-Gcr_@GCR_MAJOR@_gir_LIBS = libgcr-base-@GCR_MAJOR@.la libgcr-@GCR_MAJOR@.la
-Gcr_@GCR_MAJOR@_gir_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -DGCR_COMPILATION -DGCR_API_SUBJECT_TO_CHANGE
-Gcr_@GCR_MAJOR@_gir_FILES = $(libgcr_base_@GCR_MAJOR@_la_SOURCES) $(libgcr_@GCR_MAJOR@_la_SOURCES)
-Gcr_@GCR_MAJOR@_gir_SCANNERFLAGS = --c-include "gcr.h" --c-include "gcr-base.h"
-
-girdir = $(datadir)/gir-1.0
-gir_DATA = $(INTROSPECTION_GIRS)
-
-typelibsdir = $(libdir)/girepository-1.0
-typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
-
-endif
-
-# ----------------------------------------------------------------
-
-gcr-expected-base.abi: gcr-base.symbols
- $(AM_V_GEN) cpp -P $< | sort > $@
-gcr-expected.abi: gcr.symbols
- $(AM_V_GEN) cpp -P $< | sort > $@
-
-gcr-actual-base.abi: $(builddir)/.libs/libgcr-base-@GCR_MAJOR@.so
- $(AM_V_GEN) $(NM) -D -g --defined-only $< | \
- cut -d ' ' -f 3 | grep -Ev '^(__bss_start|_edata|_end)' | sort > $@
-gcr-actual.abi: $(builddir)/.libs/libgcr-@GCR_MAJOR@.so
- $(AM_V_GEN) $(NM) -D -g --defined-only $< | \
- cut -d ' ' -f 3 | grep -Ev '^(__bss_start|_edata|_end)' | sort > $@
-
-check-symbols: gcr-expected.abi gcr-actual.abi gcr-expected-base.abi gcr-actual-base.abi
- $(AM_V_GEN) diff -U0 --ignore-blank-lines gcr-expected-base.abi gcr-actual-base.abi || \
- (echo "check-symbols: Symbols have CHANGED. Fix gcr-base.symbols"; exit 1)
- $(AM_V_GEN) diff -U0 --ignore-blank-lines gcr-expected.abi gcr-actual.abi || \
- (echo "check-symbols: Symbols have CHANGED. Fix gcr.symbols"; exit 1)
-
-check-local: check-symbols
-
-EXTRA_DIST = \
- gcr.pc.in \
- gcr-base.pc.in \
- gcr-marshal.list \
- gcr-oids.list \
- gcr-mkoids \
- $(ui_DATA) \
- $(conf_DATA) \
- gcr-enum-types.h.template \
- gcr-enum-types.c.template \
- gcr.symbols \
- gcr-base.symbols \
- $(desktop_in_in_files) \
- $(desktop_in_files) \
- $(desktop_DATA) \
- $(mime_DATA)
-
-CLEANFILES = \
- $(BUILT_SOURCES) \
- $(pkgconfig_DATA) \
- gcr-actual.abi \
- gcr-actual-base.abi \
- gcr-expected.abi \
- gcr-expected-base.abi
-
-DISTCLEANFILES = \
- $(desktop_in_files) \
- $(desktop_DATA) \
- $(pkgconfig_DATA)
diff --git a/gcr/gcr-base.h b/gcr/gcr-base.h
deleted file mode 100644
index 69133f11..00000000
--- a/gcr/gcr-base.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_API_SUBJECT_TO_CHANGE
-#error "This API has not yet reached stability."
-#endif
-
-#ifndef __GCR_BASE_H__
-#define __GCR_BASE_H__
-
-#include <glib.h>
-
-#define __GCR_INSIDE_HEADER__
-
-#include "gcr-types.h"
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-chain.h"
-#include "gcr-deprecated-base.h"
-#include "gcr-enum-types-base.h"
-#include "gcr-icons.h"
-#include "gcr-importer.h"
-#include "gcr-library.h"
-#include "gcr-parser.h"
-#include "gcr-pkcs11-certificate.h"
-#include "gcr-secret-exchange.h"
-#include "gcr-simple-certificate.h"
-#include "gcr-simple-collection.h"
-#include "gcr-trust.h"
-#include "gcr-union-collection.h"
-#include "gcr-unlock-options.h"
-
-#undef __GCR_INSIDE_HEADER__
-
-#endif /* __GCR_BASE_H__ */
diff --git a/gcr/gcr-base.pc.in b/gcr/gcr-base.pc.in
deleted file mode 100644
index 629882ab..00000000
--- a/gcr/gcr-base.pc.in
+++ /dev/null
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-pkcs11dir=@P11_MODULE_PATH@
-pkcs11standalonedir=@pkcs11standalonedir@
-
-Name: gcr-base-@GCR_MAJOR@
-Description: GObject library for high level crypto parsing
-Version: @VERSION@
-Requires: glib-2.0 gck-@GCK_MAJOR@ p11-kit-1
-Libs: -L${libdir} -lgcr-base-@GCR_MAJOR@
-Cflags: -I${includedir}/gcr-@GCR_MAJOR@
diff --git a/gcr/gcr-base.symbols b/gcr/gcr-base.symbols
deleted file mode 100644
index 0d48bd1f..00000000
--- a/gcr/gcr-base.symbols
+++ /dev/null
@@ -1,157 +0,0 @@
-/* This file lists all exported symbols. It is used to guarantee that we
- * only consciously change our ABI.
- */
-
-gcr_certificate_compare
-gcr_certificate_chain_add
-gcr_certificate_chain_build
-gcr_certificate_chain_build_async
-gcr_certificate_chain_build_finish
-gcr_certificate_chain_flags_get_type
-gcr_certificate_chain_get_anchor
-gcr_certificate_chain_get_certificate
-gcr_certificate_chain_get_endpoint
-gcr_certificate_chain_get_length
-gcr_certificate_chain_get_status
-gcr_certificate_chain_get_type
-gcr_certificate_chain_new
-gcr_certificate_chain_status_get_type
-gcr_certificate_get_columns
-gcr_certificate_get_der_data
-gcr_certificate_get_expiry_date
-gcr_certificate_get_fingerprint
-gcr_certificate_get_fingerprint_hex
-gcr_certificate_get_icon
-gcr_certificate_get_issued_date
-gcr_certificate_get_issuer_cn
-gcr_certificate_get_issuer_dn
-gcr_certificate_get_issuer_part
-gcr_certificate_get_issuer_raw
-gcr_certificate_get_key_size
-gcr_certificate_get_serial_number
-gcr_certificate_get_serial_number_hex
-gcr_certificate_get_subject_cn
-gcr_certificate_get_subject_dn
-gcr_certificate_get_subject_part
-gcr_certificate_get_subject_raw
-gcr_certificate_get_type
-gcr_certificate_mixin_class_init
-gcr_certificate_mixin_comparable_init
-gcr_certificate_mixin_get_property
-gcr_certificate_is_issuer
-gcr_collection_contains
-gcr_collection_emit_added
-gcr_collection_emit_removed
-gcr_collection_get_length
-gcr_collection_get_objects
-gcr_collection_get_type
-gcr_comparable_compare
-gcr_comparable_get_type
-gcr_comparable_memcmp
-gcr_data_error_get_domain
-gcr_data_error_get_type
-gcr_data_format_get_type
-gcr_error_get_domain
-gcr_fingerprint_from_attributes
-gcr_fingerprint_from_certificate_public_key
-gcr_fingerprint_from_subject_public_key_info
-gcr_icon_for_token
-gcr_importer_create_for_parsed
-gcr_importer_get_interaction
-gcr_importer_get_parser
-gcr_importer_get_prompt_behavior
-gcr_importer_get_slot
-gcr_importer_get_type
-gcr_importer_import
-gcr_importer_import_async
-gcr_importer_import_finish
-gcr_importer_prompt_behavior_get_type
-gcr_importer_queue_and_filter_for_parsed
-gcr_importer_queue_for_parsed
-gcr_importer_register
-gcr_importer_register_well_known
-gcr_importer_set_interaction
-gcr_importer_set_parser
-gcr_importer_set_prompt_behavior
-gcr_importer_set_slot
-gcr_import_interaction_get_type
-gcr_import_interaction_supplement
-gcr_import_interaction_supplement_async
-gcr_import_interaction_supplement_finish
-gcr_import_interaction_supplement_prep
-gcr_parsed_get_attributes
-gcr_parsed_get_data
-gcr_parsed_get_description
-gcr_parsed_get_format
-gcr_parsed_get_label
-gcr_parsed_get_type
-gcr_parsed_ref
-gcr_parsed_unref
-gcr_parser_add_password
-gcr_parser_format_disable
-gcr_parser_format_enable
-gcr_parser_format_supported
-gcr_parser_get_parsed
-gcr_parser_get_parsed_attributes
-gcr_parser_get_parsed_block
-gcr_parser_get_parsed_description
-gcr_parser_get_parsed_format
-gcr_parser_get_parsed_label
-gcr_parser_get_type
-gcr_parser_new
-gcr_parser_parse_data
-gcr_parser_parse_stream
-gcr_parser_parse_stream_async
-gcr_parser_parse_stream_finish
-gcr_pkcs11_add_module
-gcr_pkcs11_add_module_from_file
-gcr_pkcs11_certificate_get_attributes
-gcr_pkcs11_certificate_get_type
-gcr_pkcs11_certificate_lookup_issuer
-gcr_pkcs11_certificate_lookup_issuer_async
-gcr_pkcs11_certificate_lookup_issuer_finish
-gcr_pkcs11_get_modules
-gcr_pkcs11_get_trust_lookup_slots
-gcr_pkcs11_get_trust_lookup_uris
-gcr_pkcs11_get_trust_store_slot
-gcr_pkcs11_get_trust_store_uri
-gcr_pkcs11_initialize
-gcr_pkcs11_initialize_async
-gcr_pkcs11_initialize_finish
-gcr_pkcs11_set_modules
-gcr_pkcs11_set_trust_lookup_uris
-gcr_pkcs11_set_trust_store_uri
-gcr_secret_exchange_begin
-gcr_secret_exchange_get_protocol
-gcr_secret_exchange_get_secret
-gcr_secret_exchange_get_type
-gcr_secret_exchange_new
-gcr_secret_exchange_receive
-gcr_secret_exchange_send
-gcr_simple_certificate_get_type
-gcr_simple_certificate_new
-gcr_simple_certificate_new_static
-gcr_simple_collection_add
-gcr_simple_collection_contains
-gcr_simple_collection_get_type
-gcr_simple_collection_new
-gcr_simple_collection_remove
-gcr_trust_add_pinned_certificate
-gcr_trust_add_pinned_certificate_async
-gcr_trust_add_pinned_certificate_finish
-gcr_trust_is_certificate_anchored
-gcr_trust_is_certificate_anchored_async
-gcr_trust_is_certificate_anchored_finish
-gcr_trust_is_certificate_pinned
-gcr_trust_is_certificate_pinned_async
-gcr_trust_is_certificate_pinned_finish
-gcr_trust_remove_pinned_certificate
-gcr_trust_remove_pinned_certificate_async
-gcr_trust_remove_pinned_certificate_finish
-gcr_union_collection_add
-gcr_union_collection_get_type
-gcr_union_collection_have
-gcr_union_collection_new
-gcr_union_collection_remove
-gcr_union_collection_size
-gcr_union_collection_take
diff --git a/gcr/gcr-callback-output-stream.c b/gcr/gcr-callback-output-stream.c
deleted file mode 100644
index 91bdbf3f..00000000
--- a/gcr/gcr-callback-output-stream.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-callback-output-stream.h"
-#define DEBUG_FLAG GCR_DEBUG_GNUPG
-#include "gcr-debug.h"
-
-#include <glib/gi18n.h>
-
-struct _GcrCallbackOutputStream {
- GOutputStream parent;
- GcrCallbackOutputFunc callback;
- gpointer user_data;
- GDestroyNotify destroy_func;
-};
-
-struct _GcrCallbackOutputStreamClass {
- GOutputStreamClass parent_class;
-};
-
-G_DEFINE_TYPE (GcrCallbackOutputStream, _gcr_callback_output_stream, G_TYPE_OUTPUT_STREAM);
-
-static void
-_gcr_callback_output_stream_init (GcrCallbackOutputStream *self)
-{
-
-}
-
-static gssize
-_gcr_callback_output_stream_write (GOutputStream *stream,
- const void *buffer,
- gsize count,
- GCancellable *cancellable,
- GError **error)
-{
- GcrCallbackOutputStream *self = GCR_CALLBACK_OUTPUT_STREAM (stream);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
- return -1;
- } else if (self->callback == NULL) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("The stream was closed"));
- return -1;
- }
-
- return (self->callback) (buffer, count, cancellable, self->user_data, error);
-}
-
-static gboolean
-_gcr_callback_output_stream_close (GOutputStream *stream,
- GCancellable *cancellable,
- GError **error)
-{
- GcrCallbackOutputStream *self = GCR_CALLBACK_OUTPUT_STREAM (stream);
- if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
- return FALSE;
- } else if (self->callback == NULL) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("The stream was closed"));
- return FALSE;
- }
-
- if (self->destroy_func != NULL)
- (self->destroy_func) (self->user_data);
- self->destroy_func = NULL;
- self->user_data = NULL;
- self->callback = NULL;
-
- return TRUE;
-}
-
-static void
-_gcr_callback_output_stream_dispose (GObject *obj)
-{
- _gcr_callback_output_stream_close (G_OUTPUT_STREAM (obj), NULL, NULL);
- G_OBJECT_CLASS (_gcr_callback_output_stream_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_callback_output_stream_class_init (GcrCallbackOutputStreamClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GOutputStreamClass *output_class = G_OUTPUT_STREAM_CLASS (klass);
-
- gobject_class->dispose = _gcr_callback_output_stream_dispose;
- output_class->write_fn = _gcr_callback_output_stream_write;
- output_class->close_fn = _gcr_callback_output_stream_close;
-}
-
-/**
- * _gcr_callback_output_stream_new: (skip)
- *
- * Returns: (transfer full) (type Gcr.CallbackOutputStream): the new stream
- */
-GOutputStream *
-_gcr_callback_output_stream_new (GcrCallbackOutputFunc callback,
- gpointer user_data,
- GDestroyNotify destroy_func)
-{
- GcrCallbackOutputStream *self;
-
- g_return_val_if_fail (callback, NULL);
-
- self = g_object_new (GCR_TYPE_CALLBACK_OUTPUT_STREAM, NULL);
- self->callback = callback;
- self->user_data = user_data;
- self->destroy_func = destroy_func;
-
- return G_OUTPUT_STREAM (self);
-}
diff --git a/gcr/gcr-callback-output-stream.h b/gcr/gcr-callback-output-stream.h
deleted file mode 100644
index 51d618e5..00000000
--- a/gcr/gcr-callback-output-stream.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_CALLBACK_OUTPUT_STREAM_H
-#define GCR_CALLBACK_OUTPUT_STREAM_H
-
-#include "gcr-base.h"
-#include "gcr-collection.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CALLBACK_OUTPUT_STREAM (_gcr_callback_output_stream_get_type ())
-#define GCR_CALLBACK_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CALLBACK_OUTPUT_STREAM, GcrCallbackOutputStream))
-#define GCR_CALLBACK_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CALLBACK_OUTPUT_STREAM, GcrCallbackOutputStreamClass))
-#define GCR_IS_CALLBACK_OUTPUT_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CALLBACK_OUTPUT_STREAM))
-#define GCR_IS_CALLBACK_OUTPUT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CALLBACK_OUTPUT_STREAM))
-#define GCR_CALLBACK_OUTPUT_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CALLBACK_OUTPUT_STREAM, GcrCallbackOutputStreamClass))
-
-typedef struct _GcrCallbackOutputStream GcrCallbackOutputStream;
-typedef struct _GcrCallbackOutputStreamClass GcrCallbackOutputStreamClass;
-
-GType _gcr_callback_output_stream_get_type (void);
-
-typedef gssize (*GcrCallbackOutputFunc) (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error);
-
-GOutputStream * _gcr_callback_output_stream_new (GcrCallbackOutputFunc callback,
- gpointer user_data,
- GDestroyNotify destroy_func);
-
-G_END_DECLS
-
-#endif /* GCR_CALLBACK_OUTPUT_STREAM_H */
diff --git a/gcr/gcr-certificate-basics-widget.c b/gcr/gcr-certificate-basics-widget.c
deleted file mode 100644
index f1d45283..00000000
--- a/gcr/gcr-certificate-basics-widget.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-#include "gcr-certificate-basics-widget.h"
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-/* These are all stubs for GcrCertificateWidget */
-
-GType
-gcr_certificate_basics_widget_get_type (void)
-{
- return gcr_certificate_widget_get_type ();
-}
-
-/**
- * gcr_certificate_basics_widget_new: (skip)
- *
- * Deprecated: Since 2.30
- *
- * Returns: (transfer full) (type Gcr.CertificateWidget): a new certificate widget
- */
-GcrCertificateBasicsWidget *
-gcr_certificate_basics_widget_new (GcrCertificate *cert)
-{
- return gcr_certificate_widget_new (cert);
-}
-
-/**
- * gcr_certificate_basics_widget_get_certificate: (skip)
- *
- * Deprecated: Since 2.30
- *
- * Returns: (transfer none): the certificate
- */
-GcrCertificate *
-gcr_certificate_basics_widget_get_certificate (GcrCertificateBasicsWidget *basics)
-{
- return gcr_certificate_widget_get_certificate (basics);
-}
-
-/**
- * gcr_certificate_basics_widget_set_certificate: (skip)
- * @basics: the certificate widget
- * @cert: the certificate
- *
- * Deprecated: Since 2.30
- */
-void
-gcr_certificate_basics_widget_set_certificate (GcrCertificateBasicsWidget *basics,
- GcrCertificate *cert)
-{
- return gcr_certificate_widget_set_certificate (basics, cert);
-}
-
-#endif /* GCR_DISABLE_DEPRECATED */
diff --git a/gcr/gcr-certificate-basics-widget.h b/gcr/gcr-certificate-basics-widget.h
deleted file mode 100644
index 4dee8e5d..00000000
--- a/gcr/gcr-certificate-basics-widget.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_CERTIFICATE_BASICS_WIDGET_H__
-#define __GCR_CERTIFICATE_BASICS_WIDGET_H__
-
-/*
- * GcrCertificateBasicsWidget has been replaced with GcrCertificateWidget.
- * These functions are stubs for GcrCertificateWidget.
- */
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-widget.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CERTIFICATE_BASICS_WIDGET (gcr_certificate_basics_widget_get_type ())
-#define GCR_CERTIFICATE_BASICS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_BASICS_WIDGET, GcrCertificateBasicsWidget))
-#define GCR_CERTIFICATE_BASICS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_BASICS_WIDGET, GcrCertificateBasicsWidgetClass))
-#define GCR_IS_CERTIFICATE_BASICS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_BASICS_WIDGET))
-#define GCR_IS_CERTIFICATE_BASICS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_BASICS_WIDGET))
-#define GCR_CERTIFICATE_BASICS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_BASICS_WIDGET, GcrCertificateBasicsWidgetClass))
-
-typedef GcrCertificateWidget GcrCertificateBasicsWidget;
-typedef GcrCertificateWidgetClass GcrCertificateBasicsWidgetClass;
-
-GType gcr_certificate_basics_widget_get_type (void);
-
-GcrCertificateBasicsWidget* gcr_certificate_basics_widget_new (GcrCertificate *cert);
-
-GcrCertificate* gcr_certificate_basics_widget_get_certificate (GcrCertificateBasicsWidget *basics);
-
-void gcr_certificate_basics_widget_set_certificate (GcrCertificateBasicsWidget *basics,
- GcrCertificate *cert);
-
-G_END_DECLS
-
-#endif /* GCR_DISABLE_DEPRECATED */
-
-#endif /* __GCR_CERTIFICATE_BASICS_WIDGET_H__ */
diff --git a/gcr/gcr-certificate-chain.c b/gcr/gcr-certificate-chain.c
deleted file mode 100644
index 78a88323..00000000
--- a/gcr/gcr-certificate-chain.c
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-certificate-chain.h"
-
-#include "gcr-certificate.h"
-#define DEBUG_FLAG GCR_DEBUG_CERTIFICATE_CHAIN
-#include "gcr-debug.h"
-#include "gcr-pkcs11-certificate.h"
-#include "gcr-simple-certificate.h"
-#include "gcr-trust.h"
-
-#include "egg/egg-error.h"
-
-/**
- * SECTION:gcr-certificate-chain
- * @title: GcrCertificateChain
- * @short_description: A certificate chain
- *
- * #GcrCertificateChain represents a chain of certificates, normally used to
- * validate the trust in a certificate. An X.509 certificate chain has one
- * endpoint certificate (the one for which trust is being verified) and then
- * in turn the certificate that issued each previous certificate in the chain.
- *
- * This functionality is for building of certificate chains not for validating
- * them. Use your favorite crypto library to validate trust in a certificate
- * chain once its built.
- *
- * The order of certificates in the chain should be first the endpoint
- * certificates and then the signing certificates.
- *
- * Create a new certificate chain with gcr_certificate_chain_new() and then
- * add the certificates with gcr_certificate_chain_add().
- *
- * You can then use gcr_certificate_chain_build() to build the remainder of
- * the chain. This will lookup missing certificates in PKCS\#11 modules and
- * also check that each certificate in the chain is the signer of the previous
- * one. If a trust anchor, pinned certificate, or self-signed certificate is
- * found, then the chain is considered built. Any extra certificates are
- * removed from the chain.
- *
- * Once the certificate chain has been built, you can access its status
- * through gcr_certificate_chain_get_status(). The status signifies whether
- * the chain is anchored on a trust root, self-signed, incomplete etc. See
- * #GcrCertificateChainStatus for information on the various statuses.
- *
- * It's important to understand that the building of a certificate chain is
- * merely the first step towards verifying trust in a certificate.
- */
-
-
-/**
- * GCR_TYPE_CERTIFICATE_CHAIN_STATUS:
- *
- * The flags #GType for #GcrCertificateChainFlags.
- */
-
-/**
- * GcrCertificateChain:
- *
- * A chain of certificates.
- */
-
-/**
- * GcrCertificateChainClass:
- * @parent_class: The parent class
- *
- * The class for #GcrCertificateChain.
- */
-
-enum {
- PROP_0,
- PROP_STATUS,
- PROP_LENGTH,
-};
-
-struct _GcrCertificateChainPrivate {
- GPtrArray *certificates;
- GcrCertificateChainStatus status;
-
- /* Used in build operation */
- gchar *purpose;
- gchar *peer;
- guint flags;
-};
-
-static GQuark Q_ORIGINAL_CERT = 0;
-static GQuark Q_OPERATION_DATA = 0;
-
-G_DEFINE_TYPE (GcrCertificateChain, gcr_certificate_chain, G_TYPE_OBJECT);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-free_chain_private (gpointer data)
-{
- GcrCertificateChainPrivate *pv = data;
- g_ptr_array_unref (pv->certificates);
- g_free (pv->purpose);
- g_free (pv->peer);
- g_slice_free (GcrCertificateChainPrivate, pv);
-}
-
-static GcrCertificateChainPrivate*
-new_chain_private (void)
-{
- GcrCertificateChainPrivate *pv = g_slice_new0 (GcrCertificateChainPrivate);
- pv->certificates = g_ptr_array_new_with_free_func (g_object_unref);
- return pv;
-}
-
-static GcrCertificateChainPrivate*
-prep_chain_private (GcrCertificateChainPrivate *orig, const gchar *purpose,
- const gchar *peer, guint flags)
-{
- GcrCertificateChainPrivate *pv;
- GcrCertificate *certificate;
- guint i;
-
- g_assert (orig);
- g_assert (purpose);
-
- pv = new_chain_private ();
- for (i = 0; i < orig->certificates->len; ++i) {
- certificate = g_ptr_array_index (orig->certificates, i);
- g_ptr_array_add (pv->certificates, g_object_ref (certificate));
- }
-
- pv->status = orig->status;
- pv->purpose = g_strdup (purpose);
- pv->peer = g_strdup (peer);
- pv->flags = flags;
- return pv;
-}
-
-static GcrCertificateChainPrivate*
-prep_chain_private_thread_safe (GcrCertificateChainPrivate *orig, const gchar *purpose,
- const gchar *peer, guint flags)
-{
- GcrCertificateChainPrivate *pv;
- GcrCertificate *certificate, *safe;
- gconstpointer der;
- gsize n_der;
- guint i;
-
- g_assert (orig);
-
- pv = prep_chain_private (orig, purpose, peer, flags);
-
- for (i = 0; i < pv->certificates->len; ++i) {
- certificate = g_ptr_array_index (pv->certificates, i);
-
- /* We regard these types as thread safe */
- if (GCR_IS_SIMPLE_CERTIFICATE (certificate) ||
- GCR_IS_PKCS11_CERTIFICATE (certificate)) {
- safe = g_object_ref (certificate);
-
- /* Otherwise copy the certificate data */
- } else {
- der = gcr_certificate_get_der_data (certificate, &n_der);
- g_return_val_if_fail (der, NULL);
- safe = gcr_simple_certificate_new (der, n_der);
-
- _gcr_debug ("copying certificate so it's thread safe");
-
- /* Always set the original certificate onto the safe one */
- g_object_set_qdata_full (G_OBJECT (safe), Q_ORIGINAL_CERT,
- g_object_ref (certificate), g_object_unref);
- }
-
- g_ptr_array_index (pv->certificates, i) = safe;
- g_object_unref (certificate);
- }
-
- return pv;
-}
-
-static GcrCertificateChainPrivate*
-cleanup_chain_private (GcrCertificateChainPrivate *pv)
-{
- GcrCertificate *certificate, *orig;
- guint i;
-
- for (i = 0; i < pv->certificates->len; ++i) {
- certificate = g_ptr_array_index (pv->certificates, i);
-
- /* If there's an original certificate set, then replace it back */
- orig = g_object_get_qdata (G_OBJECT (certificate), Q_ORIGINAL_CERT);
- if (orig != NULL) {
- g_ptr_array_index (pv->certificates, i) = g_object_ref (orig);
- g_object_unref (certificate);
- }
- }
-
- return pv;
-}
-
-static gboolean
-perform_build_chain (GcrCertificateChainPrivate *pv, GCancellable *cancellable,
- GError **rerror)
-{
- GError *error = NULL;
- GcrCertificate *certificate;
- gboolean lookups;
- gboolean ret;
- guint length;
- gchar *subject;
-
- g_assert (pv);
- g_assert (pv->certificates);
-
- pv->status = GCR_CERTIFICATE_CHAIN_UNKNOWN;
- lookups = !((pv->flags & GCR_CERTIFICATE_CHAIN_NO_LOOKUPS) == GCR_CERTIFICATE_CHAIN_NO_LOOKUPS);
-
- /* This chain is built */
- if (!pv->certificates->len) {
- _gcr_debug ("empty certificate chain");
- return TRUE;
- }
-
- /* First check for pinned certificates */
- certificate = g_ptr_array_index (pv->certificates, 0);
- if (_gcr_debugging) {
- subject = gcr_certificate_get_subject_dn (certificate);
- _gcr_debug ("first certificate: %s", subject);
- g_free (subject);
- }
-
- if (lookups && pv->peer) {
- ret = gcr_trust_is_certificate_pinned (certificate, pv->purpose,
- pv->peer, cancellable, &error);
- if (!ret && error) {
- _gcr_debug ("failed to lookup pinned certificate: %s",
- egg_error_message (error));
- g_propagate_error (rerror, error);
- return FALSE;
- }
-
- /*
- * This is a pinned certificate and the rest of the chain
- * is irrelevant, so truncate chain and consider built.
- */
- if (ret) {
- _gcr_debug ("found pinned certificate for peer '%s', truncating chain",
- pv->peer);
-
- g_ptr_array_set_size (pv->certificates, 1);
- pv->status = GCR_CERTIFICATE_CHAIN_PINNED;
- return TRUE;
- }
- }
-
- length = 1;
-
- /* The first certificate is always unconditionally in the chain */
- while (pv->status == GCR_CERTIFICATE_CHAIN_UNKNOWN) {
-
- /* Stop the chain if previous was self-signed */
- if (gcr_certificate_is_issuer (certificate, certificate)) {
- _gcr_debug ("found self-signed certificate");
- pv->status = GCR_CERTIFICATE_CHAIN_SELFSIGNED;
- break;
- }
-
- /* Try the next certificate in the chain */
- if (length < pv->certificates->len) {
- certificate = g_ptr_array_index (pv->certificates, length);
- if (_gcr_debugging) {
- subject = gcr_certificate_get_subject_dn (certificate);
- _gcr_debug ("next certificate: %s", subject);
- g_free (subject);
- }
-
- /* No more in chain, try to lookup */
- } else if (lookups) {
- certificate = gcr_pkcs11_certificate_lookup_issuer (certificate,
- cancellable, &error);
- if (error != NULL) {
- _gcr_debug ("failed to lookup issuer: %s", error->message);
- g_propagate_error (rerror, error);
- return FALSE;
-
- } else if (certificate) {
- g_ptr_array_add (pv->certificates, certificate);
- if (_gcr_debugging) {
- subject = gcr_certificate_get_subject_dn (certificate);
- _gcr_debug ("found issuer certificate: %s", subject);
- g_free (subject);
- }
-
- } else {
- _gcr_debug ("no issuer found");
- }
-
- /* No more in chain, and can't lookup */
- } else {
- _gcr_debug ("no more certificates available, and no lookups");
- certificate = NULL;
- }
-
- /* Stop the chain if nothing found */
- if (certificate == NULL) {
- _gcr_debug ("chain is incomplete");
- pv->status = GCR_CERTIFICATE_CHAIN_INCOMPLETE;
- break;
- }
-
- ++length;
-
- /* See if this certificate is an anchor */
- if (lookups) {
- ret = gcr_trust_is_certificate_anchored (certificate, pv->purpose,
- cancellable, &error);
-
- if (!ret && error) {
- _gcr_debug ("failed to lookup anchored certificate: %s",
- egg_error_message (error));
- g_propagate_error (rerror, error);
- return FALSE;
-
- /* Stop the chain at the first anchor */
- } else if (ret) {
- _gcr_debug ("found anchored certificate");
- pv->status = GCR_CERTIFICATE_CHAIN_ANCHORED;
- break;
- }
- }
- }
-
- /* TODO: Need to check each certificate in the chain for distrusted */
-
- /* Truncate to the appropriate length */
- g_assert (length <= pv->certificates->len);
- g_ptr_array_set_size (pv->certificates, length);
- return TRUE;
-}
-
-static void
-thread_build_chain (GSimpleAsyncResult *result, GObject *object,
- GCancellable *cancellable)
-{
- GcrCertificateChainPrivate *pv;
- GError *error = NULL;
-
- pv = g_object_get_qdata (G_OBJECT (result), Q_OPERATION_DATA);
- g_assert (pv);
-
- _gcr_debug ("building asynchronously in another thread");
-
- if (!perform_build_chain (pv, cancellable, &error)) {
- g_simple_async_result_set_from_error (result, error);
- g_clear_error (&error);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gcr_certificate_chain_init (GcrCertificateChain *self)
-{
- self->pv = new_chain_private ();
-}
-
-static void
-gcr_certificate_chain_dispose (GObject *obj)
-{
- GcrCertificateChain *self = GCR_CERTIFICATE_CHAIN (obj);
-
- g_ptr_array_set_size (self->pv->certificates, 0);
- self->pv->status = GCR_CERTIFICATE_CHAIN_UNKNOWN;
-
- G_OBJECT_CLASS (gcr_certificate_chain_parent_class)->dispose (obj);
-}
-
-static void
-gcr_certificate_chain_finalize (GObject *obj)
-{
- GcrCertificateChain *self = GCR_CERTIFICATE_CHAIN (obj);
-
- free_chain_private (self->pv);
- self->pv = NULL;
-
- G_OBJECT_CLASS (gcr_certificate_chain_parent_class)->finalize (obj);
-}
-
-static void
-gcr_certificate_chain_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateChain *self = GCR_CERTIFICATE_CHAIN (obj);
-
- switch (prop_id) {
- case PROP_STATUS:
- g_value_set_enum (value, gcr_certificate_chain_get_status (self));
- break;
- case PROP_LENGTH:
- g_value_set_uint (value, gcr_certificate_chain_get_length (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_certificate_chain_class_init (GcrCertificateChainClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gcr_certificate_chain_parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->dispose = gcr_certificate_chain_dispose;
- gobject_class->finalize = gcr_certificate_chain_finalize;
- gobject_class->get_property = gcr_certificate_chain_get_property;
-
- /**
- * GcrCertificateChain:status:
- *
- * The certificate chain status. See #GcrCertificateChainStatus
- */
- g_object_class_install_property (gobject_class, PROP_STATUS,
- g_param_spec_enum ("status", "Status", "Status of certificate chain",
- GCR_TYPE_CERTIFICATE_CHAIN_STATUS,
- GCR_CERTIFICATE_CHAIN_UNKNOWN, G_PARAM_READABLE));
-
- /**
- * GcrCertificateChain:length:
- *
- * The length of the certificate chain.
- */
- g_object_class_install_property (gobject_class, PROP_LENGTH,
- g_param_spec_uint ("length", "Length", "Length of certificate chain",
- 0, G_MAXUINT, 0, G_PARAM_READABLE));
-
- Q_ORIGINAL_CERT = g_quark_from_static_string ("gcr-certificate-chain-original-cert");
- Q_OPERATION_DATA = g_quark_from_static_string ("gcr-certificate-chain-operation-data");
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * GcrCertificateChainStatus:
- * @GCR_CERTIFICATE_CHAIN_UNKNOWN: The certificate chain's status is unknown.
- * When a chain is not yet built it has this status. If a chain is modified after
- * being built, it has this status.
- * @GCR_CERTIFICATE_CHAIN_INCOMPLETE: A full chain could not be loaded. The
- * chain does not end with a self-signed certificate, a trusted anchor, or a
- * pinned certificate.
- * @GCR_CERTIFICATE_CHAIN_SELFSIGNED: The chain ends with a self-signed
- * certificate. No trust anchor was found.
- * @GCR_CERTIFICATE_CHAIN_DISTRUSTED: The certificate chain contains a revoked
- * or otherwise explicitly distrusted certificate. The entire chain should
- * be distrusted.
- * @GCR_CERTIFICATE_CHAIN_ANCHORED: The chain ends with an anchored
- * certificate. The anchored certificate is not necessarily self-signed.
- * @GCR_CERTIFICATE_CHAIN_PINNED: The chain represents a pinned certificate. A
- * pinned certificate is an exception which trusts a given certificate
- * explicitly for a purpose and communication with a certain peer.
- *
- * The status of a built certificate chain. Will be set to
- * %GCR_CERTIFICATE_CHAIN_UNKNOWN for certificate chains that have not been
- * built.
- */
-
-/**
- * GCR_TYPE_CERTIFICATE_CHAIN_STATUS:
- *
- * The enum #GType for #GcrCertificateChainStatus.
- */
-
-/**
- * GcrCertificateChainFlags:
- * @GCR_CERTIFICATE_CHAIN_NONE: no flags
- * @GCR_CERTIFICATE_CHAIN_NO_LOOKUPS: If this flag is specified then no
- * lookups for anchors or pinned certificates are done, and the resulting chain
- * will be neither anchored or pinned. Additionally no missing certificate
- * authorities are looked up in PKCS\#11.
- *
- * Flags to be used with the gcr_certificate_chain_build() operation.
- */
-
-/**
- * GCR_TYPE_CERTIFICATE_CHAIN_FLAGS:
- *
- * The flags #GType for #GcrCertificateChainFlags.
- */
-
-/**
- * gcr_certificate_chain_new:
- *
- * Create a new #GcrCertificateChain.
- *
- * Returns: (transfer full): a newly allocated certificate chain
- */
-GcrCertificateChain *
-gcr_certificate_chain_new (void)
-{
- return g_object_new (GCR_TYPE_CERTIFICATE_CHAIN, NULL);
-}
-
-/**
- * gcr_certificate_chain_add:
- * @self: the #GcrCertificateChain
- * @certificate: a #GcrCertificate to add to the chain
- *
- * Add @certificate to the chain. The order of certificates in the chain are
- * important. The first certificate should be the endpoint certificate, and
- * then come the signers (certificate authorities) each in turn. If a root
- * certificate authority is present, it should come last.
- *
- * Adding a certificate an already built chain (see
- * gcr_certificate_chain_build()) resets the type of the certificate chain
- * to %GCR_CERTIFICATE_CHAIN_UNKNOWN
- */
-void
-gcr_certificate_chain_add (GcrCertificateChain *self, GcrCertificate *certificate)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_CHAIN (self));
- g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
- g_ptr_array_add (self->pv->certificates, g_object_ref (certificate));
- self->pv->status = GCR_CERTIFICATE_CHAIN_UNKNOWN;
- g_object_notify (G_OBJECT (self), "status");
- g_object_notify (G_OBJECT (self), "length");
-}
-
-/**
- * gcr_certificate_chain_get_status:
- * @self: the #GcrCertificateChain
- *
- * Get the status of a certificate chain. If the certificate chain has not
- * been built, then the status will be %GCR_CERTIFICATE_CHAIN_UNKNOWN.
- *
- * A status of %GCR_CERTIFICATE_CHAIN_ANCHORED does not mean that the
- * certificate chain has been verified, but merely that an anchor has been
- * found.
- *
- * Returns: the status of the certificate chain.
- */
-GcrCertificateChainStatus
-gcr_certificate_chain_get_status (GcrCertificateChain *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), GCR_CERTIFICATE_CHAIN_UNKNOWN);
- return self->pv->status;
-}
-
-/**
- * gcr_certificate_chain_get_anchor:
- * @self: the #GcrCertificateChain
- *
- * If the certificate chain has been built and is of status
- * %GCR_CERTIFICATE_CHAIN_ANCHORED, then this will return the anchor
- * certificate that was found. This is not necessarily a root certificate
- * authority. If an intermediate certificate authority in the chain was
- * found to be anchored, then that certificate will be returned.
- *
- * If an anchor is returned it does not mean that the certificate chain has
- * been verified, but merely that an anchor has been found.
- *
- * Returns: (transfer none): the anchor certificate, or NULL if not anchored.
- */
-GcrCertificate *
-gcr_certificate_chain_get_anchor (GcrCertificateChain *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), NULL);
- if (self->pv->status != GCR_CERTIFICATE_CHAIN_ANCHORED)
- return NULL;
- g_assert (self->pv->certificates->len > 0);
- return GCR_CERTIFICATE (g_ptr_array_index (self->pv->certificates,
- self->pv->certificates->len - 1));
-}
-
-/**
- * gcr_certificate_chain_get_endpoint:
- * @self: the #GcrCertificateChain
- *
- * Get the endpoint certificate in the chain. This is always the first
- * certificate in the chain. The endpoint certificate cannot be anchored.
- *
- * Returns: (transfer none): the endpoint certificate, or %NULL if the chain
- * is empty
- */
-GcrCertificate*
-gcr_certificate_chain_get_endpoint (GcrCertificateChain *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), NULL);
- if (!self->pv->certificates->len)
- return NULL;
- return GCR_CERTIFICATE (g_ptr_array_index (self->pv->certificates, 0));
-}
-
-/**
- * gcr_certificate_chain_get_length:
- * @self: the #GcrCertificateChain
- *
- * Get the length of the certificate chain.
- *
- * Returns: the length of the certificate chain
- */
-guint
-gcr_certificate_chain_get_length (GcrCertificateChain *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), 0);
- return self->pv->certificates->len;
-}
-
-/**
- * gcr_certificate_chain_get_certificate:
- * @self: the #GcrCertificateChain
- * @index: index of the certificate to get
- *
- * Get a certificate in the chain. It is an error to call this function
- * with an invalid index.
- *
- * Returns: (transfer none): the certificate
- */
-GcrCertificate *
-gcr_certificate_chain_get_certificate (GcrCertificateChain *self, guint index)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), NULL);
- g_return_val_if_fail (index < self->pv->certificates->len, NULL);
- return GCR_CERTIFICATE (g_ptr_array_index (self->pv->certificates, index));
-}
-
-/**
- * gcr_certificate_chain_build:
- * @self: the #GcrCertificateChain
- * @purpose: the purpose the certificate chain will be used for
- * @peer: (allow-none): the peer the certificate chain will be used with, or %NULL
- * @flags: chain completion flags
- * @cancellable: a #GCancellable or %NULL
- * @error: a #GError or %NULL
- *
- * Complete a certificate chain. Once a certificate chain has been built
- * its status can be examined.
- *
- * This operation will lookup missing certificates in PKCS\#11
- * modules and also that each certificate in the chain is the signer of the
- * previous one. If a trust anchor, pinned certificate, or self-signed certificate
- * is found, then the chain is considered built. Any extra certificates are
- * removed from the chain.
- *
- * It's important to understand that building of a certificate chain does not
- * constitute verifying that chain. This is merely the first step towards
- * trust verification.
- *
- * The @purpose is a string like %GCR_PURPOSE_CLIENT_AUTH and is the purpose
- * for which the certificate chain will be used. Trust anchors are looked up
- * for this purpose. This argument is required.
- *
- * The @peer is usually the host name of the peer whith which this certificate
- * chain is being used. It is used to look up pinned certificates that have
- * been stored for this peer. If %NULL then no pinned certificates will
- * be considered.
- *
- * If the %GCR_CERTIFICATE_CHAIN_NO_LOOKUPS flag is specified then no
- * lookups for anchors or pinned certificates are done, and the resulting chain
- * will be neither anchored or pinned. Additionally no missing certificate
- * authorities are looked up in PKCS\#11
- *
- * This call will block, see gcr_certificate_chain_build_async() for the
- * asynchronous version.
- *
- * Returns: whether the operation completed successfully
- */
-gboolean
-gcr_certificate_chain_build (GcrCertificateChain *self,
- const gchar *purpose,
- const gchar *peer,
- GcrCertificateChainFlags flags,
- GCancellable *cancellable,
- GError **error)
-{
- GcrCertificateChainPrivate *pv;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), FALSE);
- g_return_val_if_fail (purpose != NULL, FALSE);
-
- pv = prep_chain_private (self->pv, purpose, peer, flags);
-
- ret = perform_build_chain (pv, cancellable, error);
-
- if (ret) {
- free_chain_private (self->pv);
- self->pv = cleanup_chain_private (pv);
- g_object_notify (G_OBJECT (self), "status");
- g_object_notify (G_OBJECT (self), "length");
- } else {
- free_chain_private (pv);
- }
-
- return ret;
-}
-
-/**
- * gcr_certificate_chain_build_async:
- * @self: the #GcrCertificateChain
- * @purpose: the purpose the certificate chain will be used for
- * @peer: (allow-none): the peer the certificate chain will be used with, or %NULL
- * @flags: chain completion flags
- * @cancellable: a #GCancellable or %NULL
- * @callback: this will be called when the operation completes.
- * @user_data: data to pass to the callback
- *
- * Complete a certificate chain. Once a certificate chain has been built
- * its status can be examined.
- *
- * This will lookup missing certificates in PKCS\#11
- * modules and also that each certificate in the chain is the signer of the
- * previous one. If a trust anchor, pinned certificate, or self-signed certificate
- * is found, then the chain is considered built. Any extra certificates are
- * removed from the chain.
- *
- * It's important to understand that building of a certificate chain does not
- * constitute verifying that chain. This is merely the first step towards
- * trust verification.
- *
- * The @purpose is a string like %GCR_PURPOSE_CLIENT_AUTH and is the purpose
- * for which the certificate chain will be used. Trust anchors are looked up
- * for this purpose. This argument is required.
- *
- * The @peer is usually the host name of the peer whith which this certificate
- * chain is being used. It is used to look up pinned certificates that have
- * been stored for this peer. If %NULL then no pinned certificates will
- * be considered.
- *
- * If the %GCR_CERTIFICATE_CHAIN_NO_LOOKUPS flag is specified then no
- * lookups for anchors or pinned certificates are done, and the resulting chain
- * will be neither anchored or pinned. Additionally no missing certificate
- * authorities are looked up in PKCS\#11
- *
- * When the operation is finished, @callback will be called. You can then call
- * gcr_certificate_chain_build_finish() to get the result of the operation.
- */
-void
-gcr_certificate_chain_build_async (GcrCertificateChain *self,
- const gchar *purpose,
- const gchar *peer,
- GcrCertificateChainFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrCertificateChainPrivate *pv;
- GSimpleAsyncResult *result;
-
- g_return_if_fail (GCR_IS_CERTIFICATE_CHAIN (self));
-
- g_return_if_fail (GCR_IS_CERTIFICATE_CHAIN (self));
- g_return_if_fail (purpose);
-
- pv = prep_chain_private_thread_safe (self->pv, purpose, peer, flags);
-
- result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- gcr_certificate_chain_build_async);
- g_object_set_qdata_full (G_OBJECT (result), Q_OPERATION_DATA, pv, free_chain_private);
-
- g_simple_async_result_run_in_thread (result, thread_build_chain,
- G_PRIORITY_DEFAULT, cancellable);
- g_object_unref (result);
-}
-
-/**
- * gcr_certificate_chain_build_finish:
- * @self: the #GcrCertificateChain
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_certificate_chain_build_async().
- *
- * Returns: whether the operation succeeded
- */
-gboolean
-gcr_certificate_chain_build_finish (GcrCertificateChain *self, GAsyncResult *result,
- GError **error)
-{
- GcrCertificateChainPrivate *pv;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE_CHAIN (self), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
- gcr_certificate_chain_build_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- pv = g_object_steal_qdata (G_OBJECT (result), Q_OPERATION_DATA);
- g_return_val_if_fail (pv, FALSE);
-
- free_chain_private (self->pv);
- self->pv = cleanup_chain_private (pv);
-
- g_object_notify (G_OBJECT (self), "status");
- g_object_notify (G_OBJECT (self), "length");
- return TRUE;
-}
diff --git a/gcr/gcr-certificate-chain.h b/gcr/gcr-certificate-chain.h
deleted file mode 100644
index ef8bdcfa..00000000
--- a/gcr/gcr-certificate-chain.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_CERTIFICATE_CHAIN_H__
-#define __GCR_CERTIFICATE_CHAIN_H__
-
-#include <glib-object.h>
-
-#include "gcr-certificate.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-typedef enum {
- GCR_CERTIFICATE_CHAIN_UNKNOWN,
- GCR_CERTIFICATE_CHAIN_INCOMPLETE,
- GCR_CERTIFICATE_CHAIN_DISTRUSTED,
- GCR_CERTIFICATE_CHAIN_SELFSIGNED,
- GCR_CERTIFICATE_CHAIN_PINNED,
- GCR_CERTIFICATE_CHAIN_ANCHORED,
-} GcrCertificateChainStatus;
-
-typedef enum {
- GCR_CERTIFICATE_CHAIN_NONE = 0,
- GCR_CERTIFICATE_CHAIN_NO_LOOKUPS = 1 << 0,
-} GcrCertificateChainFlags;
-
-#define GCR_TYPE_CERTIFICATE_CHAIN (gcr_certificate_chain_get_type ())
-#define GCR_CERTIFICATE_CHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_CHAIN, GcrCertificateChain))
-#define GCR_CERTIFICATE_CHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_CHAIN, GcrCertificateChainClass))
-#define GCR_IS_CERTIFICATE_CHAIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_CHAIN))
-#define GCR_IS_CERTIFICATE_CHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_CHAIN))
-#define GCR_CERTIFICATE_CHAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_CHAIN, GcrCertificateChainClass))
-
-typedef struct _GcrCertificateChain GcrCertificateChain;
-typedef struct _GcrCertificateChainClass GcrCertificateChainClass;
-typedef struct _GcrCertificateChainPrivate GcrCertificateChainPrivate;
-
-struct _GcrCertificateChain {
- GObject parent;
-
- /*< private >*/
- GcrCertificateChainPrivate *pv;
-};
-
-struct _GcrCertificateChainClass {
- GObjectClass parent_class;
-};
-
-GType gcr_certificate_chain_get_type (void) G_GNUC_CONST;
-
-GcrCertificateChain* gcr_certificate_chain_new (void);
-
-void gcr_certificate_chain_add (GcrCertificateChain *self,
- GcrCertificate *certificate);
-
-GcrCertificateChainStatus gcr_certificate_chain_get_status (GcrCertificateChain *self);
-
-GcrCertificate* gcr_certificate_chain_get_anchor (GcrCertificateChain *self);
-
-GcrCertificate* gcr_certificate_chain_get_endpoint (GcrCertificateChain *self);
-
-guint gcr_certificate_chain_get_length (GcrCertificateChain *self);
-
-GcrCertificate* gcr_certificate_chain_get_certificate (GcrCertificateChain *self,
- guint index);
-
-gboolean gcr_certificate_chain_build (GcrCertificateChain *self,
- const gchar *purpose,
- const gchar *peer,
- guint flags,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_certificate_chain_build_async (GcrCertificateChain *self,
- const gchar *purpose,
- const gchar *peer,
- guint flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_certificate_chain_build_finish (GcrCertificateChain *self,
- GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_CERTIFICATE_CHAIN_H__ */
diff --git a/gcr/gcr-certificate-details-widget.c b/gcr/gcr-certificate-details-widget.c
deleted file mode 100644
index 9fc23070..00000000
--- a/gcr/gcr-certificate-details-widget.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-#include "gcr-certificate-details-widget.h"
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-/* These are all stubs for GcrCertificateWidget */
-
-GType
-gcr_certificate_details_widget_get_type (void)
-{
- return gcr_certificate_widget_get_type ();
-}
-
-/**
- * gcr_certificate_details_widget_new: (skip)
- *
- * Deprecated: Since 2.30
- *
- * Returns: (transfer full) (type Gcr.CertificateWidget): a new certificate widget
- */
-GcrCertificateDetailsWidget *
-gcr_certificate_details_widget_new (GcrCertificate *cert)
-{
- return gcr_certificate_widget_new (cert);
-}
-
-/**
- * gcr_certificate_details_widget_get_certificate: (skip)
- *
- * Deprecated: Since 2.30
- *
- * Returns: (transfer none): the certificate
- */
-GcrCertificate*
-gcr_certificate_details_widget_get_certificate (GcrCertificateDetailsWidget *details)
-{
- return gcr_certificate_widget_get_certificate (details);
-}
-
-/**
- * gcr_certificate_details_widget_set_certificate: (skip)
- * @details: the certificate widget
- * @cert: the certificate
- *
- * Deprecated: Since 2.30
- */
-void
-gcr_certificate_details_widget_set_certificate (GcrCertificateDetailsWidget *details,
- GcrCertificate *cert)
-{
- return gcr_certificate_widget_set_certificate (details, cert);
-}
-
-#endif /* GCR_DISABLE_DEPRECATED */
diff --git a/gcr/gcr-certificate-details-widget.h b/gcr/gcr-certificate-details-widget.h
deleted file mode 100644
index 5a3d74b0..00000000
--- a/gcr/gcr-certificate-details-widget.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_CERTIFICATE_DETAILS_WIDGET_H__
-#define __GCR_CERTIFICATE_DETAILS_WIDGET_H__
-
-/*
- * GcrCertificateDetailsWidget has been replaced with GcrCertificateWidget.
- * These functions are stubs for GcrCertificateWidget.
- */
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-widget.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CERTIFICATE_DETAILS_WIDGET (gcr_certificate_details_widget_get_type ())
-#define GCR_CERTIFICATE_DETAILS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_DETAILS_WIDGET, GcrCertificateDetailsWidget))
-#define GCR_CERTIFICATE_DETAILS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_DETAILS_WIDGET, GcrCertificateDetailsWidgetClass))
-#define GCR_IS_CERTIFICATE_DETAILS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_DETAILS_WIDGET))
-#define GCR_IS_CERTIFICATE_DETAILS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_DETAILS_WIDGET))
-#define GCR_CERTIFICATE_DETAILS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_DETAILS_WIDGET, GcrCertificateDetailsWidgetClass))
-
-typedef GcrCertificateWidget GcrCertificateDetailsWidget;
-typedef GcrCertificateWidgetClass GcrCertificateDetailsWidgetClass;
-
-GType gcr_certificate_details_widget_get_type (void);
-
-GcrCertificateDetailsWidget* gcr_certificate_details_widget_new (GcrCertificate *cert);
-
-GcrCertificate* gcr_certificate_details_widget_get_certificate (GcrCertificateDetailsWidget *details);
-
-void gcr_certificate_details_widget_set_certificate (GcrCertificateDetailsWidget *details,
- GcrCertificate *cert);
-
-G_END_DECLS
-
-#endif /* GCR_DISABLE_DEPRECATED */
-
-#endif /* __GCR_CERTIFICATE_DETAILS_WIDGET_H__ */
diff --git a/gcr/gcr-certificate-exporter.c b/gcr/gcr-certificate-exporter.c
deleted file mode 100644
index 7806533e..00000000
--- a/gcr/gcr-certificate-exporter.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-exporter.h"
-
-#include "egg/egg-armor.h"
-#include "egg/egg-openssl.h"
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_CERTIFICATE,
- PROP_LABEL,
- PROP_TRANSIENT_FOR
-};
-
-struct _GcrCertificateExporterPrivate {
-
- /* Setup stuff */
- GcrCertificate *certificate;
- gchar *label;
- GtkWindow *transient_for;
-
- /* Used during operation */
- GtkFileChooser *chooser_dialog;
- GFile *output_file;
- GByteArray *buffer;
- guint buffer_at;
-
- /* Async stuff */
- GAsyncReadyCallback callback;
- gpointer user_data;
- GCancellable *cancellable;
- GError *error;
- gboolean completed;
-};
-
-static const gchar *BAD_FILENAME_CHARS = "/\\<>|?*";
-
-/* Forward declarations */
-static void _gcr_certificate_exporter_async_result_init (GAsyncResultIface *iface);
-static void write_to_outputstream (GcrCertificateExporter *self, GOutputStream *os);
-
-G_DEFINE_TYPE_WITH_CODE (GcrCertificateExporter, _gcr_certificate_exporter, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, _gcr_certificate_exporter_async_result_init));
-
-typedef void (*PrepareDataFunc) (GcrCertificateExporter *self);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-prepare_data_for_der (GcrCertificateExporter *self)
-{
- gconstpointer data;
- gsize n_data;
-
- data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
- g_return_if_fail (data);
-
- self->pv->buffer = g_byte_array_new ();
- g_byte_array_append (self->pv->buffer, data, n_data);
-}
-
-static void
-prepare_data_for_pem (GcrCertificateExporter *self)
-{
- gconstpointer data;
- gpointer encoded;
- gsize n_data, n_encoded;
-
- data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
- g_return_if_fail (data);
-
- self->pv->buffer = g_byte_array_new ();
-
- encoded = egg_armor_write (data, n_data,
- g_quark_from_static_string ("CERTIFICATE"),
- NULL, &n_encoded);
-
- g_byte_array_append (self->pv->buffer, encoded, n_encoded);
- g_free (encoded);
-}
-
-static void
-complete_async_result (GcrCertificateExporter *self)
-{
- g_assert (self->pv->callback);
- g_assert (!self->pv->completed);
-
- if (self->pv->chooser_dialog)
- gtk_widget_hide (GTK_WIDGET (self->pv->chooser_dialog));
-
- self->pv->completed = TRUE;
- (self->pv->callback) (G_OBJECT (self), G_ASYNC_RESULT (self),
- self->pv->user_data);
-}
-
-static void
-on_outputstream_write_ready (GObject *source, GAsyncResult *res, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
- GOutputStream *os = G_OUTPUT_STREAM (source);
- gssize written;
-
- written = g_output_stream_write_finish (os, res, &self->pv->error);
-
- if (self->pv->error) {
- complete_async_result (self);
- return;
- }
-
- g_return_if_fail (written >= 0);
- g_return_if_fail (written <= self->pv->buffer->len - self->pv->buffer_at);
- self->pv->buffer_at += written;
-
- /* Write next bit, or finished */
- write_to_outputstream (self, os);
-}
-
-static void
-on_outputstream_closed (GObject *source, GAsyncResult *res, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
- g_output_stream_close_finish (G_OUTPUT_STREAM (source), res, &self->pv->error);
- complete_async_result (self);
-}
-
-static void
-write_to_outputstream (GcrCertificateExporter *self, GOutputStream *os)
-{
- gtk_widget_hide (GTK_WIDGET (self->pv->chooser_dialog));
- g_assert (GTK_IS_WIDGET (self->pv->chooser_dialog));
-
- /* Are we all done? */
- g_assert (self->pv->buffer_at <= self->pv->buffer->len);
- if (self->pv->buffer_at == self->pv->buffer->len) {
- g_output_stream_close_async (os, G_PRIORITY_DEFAULT,
- self->pv->cancellable,
- on_outputstream_closed, self);
- return;
- }
-
- g_output_stream_write_async (os, self->pv->buffer->data + self->pv->buffer_at,
- self->pv->buffer->len - self->pv->buffer_at,
- G_PRIORITY_DEFAULT, self->pv->cancellable,
- on_outputstream_write_ready, self);
-}
-
-static void
-on_replace_file_ready (GObject *source, GAsyncResult *res, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
- GFile *file = G_FILE (source);
- GFileOutputStream *os;
-
- os = g_file_replace_finish (file, res, &self->pv->error);
-
- if (self->pv->error) {
- complete_async_result (self);
- return;
- }
-
- write_to_outputstream (self, G_OUTPUT_STREAM (os));
-}
-
-static void
-on_replace_dialog_response (GtkDialog *dialog, gint response_id, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
-
- if (response_id == GTK_RESPONSE_ACCEPT) {
- g_file_replace_async (self->pv->output_file, NULL, FALSE, G_FILE_CREATE_NONE,
- G_PRIORITY_DEFAULT, self->pv->cancellable,
- on_replace_file_ready, self);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static void
-on_cancel_replace_dialog (GCancellable *cancellable, gpointer user_data)
-{
- gtk_widget_destroy (user_data);
-}
-
-static void
-on_create_file_ready (GObject *source, GAsyncResult *res, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
- GFileOutputStream *os;
- GtkWidget *dialog;
-
- os = g_file_create_finish (self->pv->output_file, res, &self->pv->error);
-
- /* Try again this time replacing the file */
- if (g_error_matches (self->pv->error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
- g_clear_error (&self->pv->error);
-
- dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (self->pv->chooser_dialog),
- GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE, _("<b>A file already exists with this name.</b>\n\nDo you want to replace it with a new file?"));
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- _("_Replace"), GTK_RESPONSE_ACCEPT, NULL);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (on_replace_dialog_response), self);
- if (self->pv->cancellable)
- g_cancellable_connect (self->pv->cancellable,
- G_CALLBACK (on_cancel_replace_dialog),
- g_object_ref (dialog), g_object_unref);
- gtk_widget_show (dialog);
-
- return;
- }
-
- if (self->pv->error) {
- complete_async_result (self);
- return;
- }
-
- write_to_outputstream (self, G_OUTPUT_STREAM (os));
-}
-
-static void
-on_chooser_dialog_response (GtkDialog *dialog, gint response_id, gpointer user_data)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
- GtkFileFilter *filter;
- PrepareDataFunc prepare_data;
-
- if (response_id != GTK_RESPONSE_ACCEPT) {
- g_set_error (&self->pv->error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("The operation was cancelled."));
- complete_async_result (self);
- return;
- }
-
- if (self->pv->output_file)
- g_object_unref (self->pv->output_file);
- self->pv->output_file = gtk_file_chooser_get_file (self->pv->chooser_dialog);
- g_return_if_fail (self->pv->output_file);
-
- filter = gtk_file_chooser_get_filter (self->pv->chooser_dialog);
- prepare_data = g_object_get_data (G_OBJECT (filter), "prepare-data-func");
- g_assert (prepare_data);
-
- if (self->pv->buffer)
- g_byte_array_free (self->pv->buffer, TRUE);
- self->pv->buffer = NULL;
- self->pv->buffer_at = 0;
-
- /* Prepare the for writing out */
- (prepare_data) (self);
-
- /* Try to open the file */
- g_file_create_async (self->pv->output_file, G_FILE_CREATE_NONE, G_PRIORITY_DEFAULT,
- self->pv->cancellable, on_create_file_ready,
- self);
-}
-
-static void
-on_cancel_chooser_dialog (GCancellable *cancellable, gpointer user_data)
-{
- GtkDialog *dialog = GTK_DIALOG (user_data);
- gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
-}
-
-static void
-exporter_display_chooser (GcrCertificateExporter *self)
-{
- GtkFileFilter* filter;
- GtkWidget *dialog;
- gchar *filename;
-
- g_assert (!self->pv->chooser_dialog);
-
- dialog = gtk_file_chooser_dialog_new (_("Export certificate"),
- NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
-
- self->pv->chooser_dialog = g_object_ref_sink(dialog);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_ACCEPT);
- gtk_file_chooser_set_local_only (self->pv->chooser_dialog, FALSE);
-
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter, _("Certificate files"));
- gtk_file_filter_add_mime_type (filter, "application/x-x509-ca-cert");
- gtk_file_filter_add_mime_type (filter, "application/x-x509-user-cert");
- gtk_file_filter_add_mime_type (filter, "application/pkix-cert");
- gtk_file_filter_add_pattern (filter, "*.cer");
- gtk_file_filter_add_pattern (filter, "*.crt");
- g_object_set_data (G_OBJECT (filter), "prepare-data-func", prepare_data_for_der);
- gtk_file_chooser_add_filter (self->pv->chooser_dialog, filter);
- gtk_file_chooser_set_filter (self->pv->chooser_dialog, filter);
-
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter, _("PEM files"));
- gtk_file_filter_add_mime_type (filter, "text/plain");
- gtk_file_filter_add_pattern (filter, "*.pem");
- g_object_set_data (G_OBJECT (filter), "prepare-data-func", prepare_data_for_pem);
- gtk_file_chooser_add_filter (self->pv->chooser_dialog, filter);
-
- filename = g_strconcat (self->pv->label, ".crt", NULL);
- g_strdelimit (filename, BAD_FILENAME_CHARS, '_');
- gtk_file_chooser_set_current_name (self->pv->chooser_dialog, filename);
- g_free (filename);
-
- g_signal_connect (self->pv->chooser_dialog, "response",
- G_CALLBACK (on_chooser_dialog_response), self);
- if (self->pv->cancellable)
- g_cancellable_connect (self->pv->cancellable,
- G_CALLBACK (on_cancel_chooser_dialog), self, NULL);
-
- gtk_widget_show (GTK_WIDGET (self->pv->chooser_dialog));
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-_gcr_certificate_exporter_init (GcrCertificateExporter *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_EXPORTER,
- GcrCertificateExporterPrivate));
-}
-
-static void
-_gcr_certificate_exporter_dispose (GObject *obj)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (obj);
-
- if (self->pv->certificate)
- g_object_unref (self->pv->certificate);
- self->pv->certificate = NULL;
-
- if (self->pv->cancellable)
- g_object_unref (self->pv->cancellable);
- self->pv->cancellable = NULL;
-
- G_OBJECT_CLASS (_gcr_certificate_exporter_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_certificate_exporter_finalize (GObject *obj)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (obj);
-
- g_free (self->pv->label);
-
- /*
- * Should have been freed in _export_finish, which holds a ref to self
- * so this should never be reached without being finished.
- */
- g_assert (!self->pv->chooser_dialog);
- g_assert (!self->pv->output_file);
- g_assert (!self->pv->buffer);
-
- g_clear_error (&self->pv->error);
-
- G_OBJECT_CLASS (_gcr_certificate_exporter_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_certificate_exporter_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (obj);
- GcrCertificate *cert;
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- cert = g_value_dup_object (value);
- if (self->pv->certificate)
- g_object_unref (self->pv->certificate);
- self->pv->certificate = cert;
- g_object_notify (G_OBJECT (self), "certificate");
- break;
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- break;
- case PROP_TRANSIENT_FOR:
- self->pv->transient_for = g_value_get_object (value);
- g_object_notify (obj, "transient-for");
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_certificate_exporter_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (obj);
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- g_value_set_object (value, self->pv->certificate);
- break;
- case PROP_LABEL:
- g_value_take_string (value, self->pv->label);
- break;
- case PROP_TRANSIENT_FOR:
- g_value_set_object (value, self->pv->transient_for);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_certificate_exporter_class_init (GcrCertificateExporterClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- _gcr_certificate_exporter_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrCertificateExporterPrivate));
-
- gobject_class->dispose = _gcr_certificate_exporter_dispose;
- gobject_class->finalize = _gcr_certificate_exporter_finalize;
- gobject_class->set_property = _gcr_certificate_exporter_set_property;
- gobject_class->get_property = _gcr_certificate_exporter_get_property;
-
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
- GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Label of certificate.",
- _("Certificate"), G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_TRANSIENT_FOR,
- g_param_spec_object ("transient-for", "Transient For", "Transient for this Window",
- GTK_TYPE_WINDOW, G_PARAM_READWRITE));
-}
-
-static GObject*
-_gcr_certificate_exporter_get_source_object (GAsyncResult *result)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_EXPORTER (result), NULL);
- return G_OBJECT (result);
-}
-
-static gpointer
-_gcr_certificate_exporter_get_user_data (GAsyncResult *result)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_EXPORTER (result), NULL);
- return GCR_CERTIFICATE_EXPORTER (result)->pv->user_data;
-}
-
-static void
-_gcr_certificate_exporter_async_result_init (GAsyncResultIface *iface)
-{
- iface->get_source_object = _gcr_certificate_exporter_get_source_object;
- iface->get_user_data = _gcr_certificate_exporter_get_user_data;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-GcrCertificateExporter*
-_gcr_certificate_exporter_new (GcrCertificate *certificate, const gchar *label,
- GtkWindow *transient_for)
-{
- return g_object_new (GCR_TYPE_CERTIFICATE_EXPORTER,
- "certificate", certificate,
- "label", label,
- "transient-for", transient_for,
- NULL);
-}
-
-void
-_gcr_certificate_exporter_export_async (GcrCertificateExporter *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_EXPORTER (self));
- g_return_if_fail (callback);
-
- /* Must not have already started */
- g_return_if_fail (!self->pv->callback);
- g_return_if_fail (!self->pv->cancellable);
-
- self->pv->callback = callback;
- self->pv->user_data = user_data;
- if (cancellable)
- self->pv->cancellable = g_object_ref (cancellable);
-
- exporter_display_chooser (self);
-
- /* Matching in export_finish */
- g_object_ref (self);
-}
-
-gboolean
-_gcr_certificate_exporter_export_finish (GcrCertificateExporter *self,
- GAsyncResult *result,
- GError **error)
-{
- gboolean ret = TRUE;
-
- g_return_val_if_fail (G_ASYNC_RESULT (self) == result, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
- g_return_val_if_fail (self->pv->completed, FALSE);
-
- /* Cleanup all the operation stuff */
- self->pv->callback = NULL;
-
- if (self->pv->chooser_dialog)
- g_object_unref (self->pv->chooser_dialog);
- self->pv->chooser_dialog = NULL;
-
- if (self->pv->output_file)
- g_object_unref (self->pv->output_file);
- self->pv->output_file = NULL;
-
- if (self->pv->buffer)
- g_byte_array_free (self->pv->buffer, TRUE);
- self->pv->buffer = NULL;
- self->pv->buffer_at = 0;
-
- self->pv->completed = FALSE;
-
- if (self->pv->error) {
- g_propagate_error (error, self->pv->error);
- ret = FALSE;
- }
-
- /* Matches in export_async */
- g_object_unref (self);
- return ret;
-}
diff --git a/gcr/gcr-certificate-exporter.h b/gcr/gcr-certificate-exporter.h
deleted file mode 100644
index fd04a20a..00000000
--- a/gcr/gcr-certificate-exporter.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_CERTIFICATE_EXPORTER_H__
-#define __GCR_CERTIFICATE_EXPORTER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CERTIFICATE_EXPORTER (_gcr_certificate_exporter_get_type ())
-#define GCR_CERTIFICATE_EXPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_EXPORTER, GcrCertificateExporter))
-#define GCR_CERTIFICATE_EXPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_EXPORTER, GcrCertificateExporterClass))
-#define GCR_IS_CERTIFICATE_EXPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_EXPORTER))
-#define GCR_IS_CERTIFICATE_EXPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_EXPORTER))
-#define GCR_CERTIFICATE_EXPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_EXPORTER, GcrCertificateExporterClass))
-
-typedef struct _GcrCertificateExporter GcrCertificateExporter;
-typedef struct _GcrCertificateExporterClass GcrCertificateExporterClass;
-typedef struct _GcrCertificateExporterPrivate GcrCertificateExporterPrivate;
-
-struct _GcrCertificateExporter {
- /*< private >*/
- GObject parent;
- GcrCertificateExporterPrivate *pv;
-};
-
-struct _GcrCertificateExporterClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_certificate_exporter_get_type (void);
-
-GcrCertificateExporter* _gcr_certificate_exporter_new (GcrCertificate *certificate,
- const gchar *label,
- GtkWindow *transient_for);
-
-void _gcr_certificate_exporter_export_async (GcrCertificateExporter *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean _gcr_certificate_exporter_export_finish (GcrCertificateExporter *self,
- GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_CERTIFICATE_EXPORTER_H__ */
diff --git a/gcr/gcr-certificate-extensions.c b/gcr/gcr-certificate-extensions.c
deleted file mode 100644
index 8256da23..00000000
--- a/gcr/gcr-certificate-extensions.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-#include "config.h"
-
-#include "gcr-certificate-extensions.h"
-#include "gcr-oids.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-dn.h"
-
-#include <glib/gi18n-lib.h>
-
-gboolean
-_gcr_certificate_extension_basic_constraints (gconstpointer data, gsize n_data,
- gboolean *is_ca, gint *path_len)
-{
- gboolean ret = TRUE;
- GNode *asn = NULL;
- GNode *node;
- gulong value;
-
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data, n_data);
- if (asn == NULL)
- return FALSE;
-
- 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))
- ret = FALSE;
- 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))
- ret = FALSE;
- }
-
- egg_asn1x_destroy (asn);
- return ret;
-}
-
-GQuark*
-_gcr_certificate_extension_extended_key_usage (gconstpointer data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *node;
- GArray *array;
- GQuark oid;
- int i;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data, n_data);
- if (asn == NULL)
- return NULL;
-
- array = g_array_new (TRUE, TRUE, sizeof (GQuark));
- for (i = 0; TRUE; ++i) {
- node = egg_asn1x_node (asn, i + 1, NULL);
- if (node == NULL)
- break;
- oid = egg_asn1x_get_oid_as_quark (node);
- g_array_append_val (array, oid);
- }
-
- egg_asn1x_destroy (asn);
- return (GQuark*)g_array_free (array, FALSE);
-}
-
-gpointer
-_gcr_certificate_extension_subject_key_identifier (gconstpointer data, gsize n_data,
- gsize *n_keyid)
-{
- GNode *asn = NULL;
- gpointer result;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectKeyIdentifier", data, n_data);
- if (asn == NULL)
- return NULL;
-
- result = egg_asn1x_get_string_as_raw (asn, g_realloc, n_keyid);
- egg_asn1x_destroy (asn);
-
- return result;
-}
-
-gboolean
-_gcr_certificate_extension_key_usage (gconstpointer data, gsize n_data,
- gulong *key_usage)
-{
- GNode *asn = NULL;
- gboolean ret = TRUE;
- guint n_bits;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data, n_data);
- if (asn == NULL)
- return FALSE;
-
- ret = egg_asn1x_get_bits_as_ulong (asn, key_usage, &n_bits);
- egg_asn1x_destroy (asn);
- return ret;
-}
-
-static void
-general_name_parse_other (GNode *node, GcrGeneralName *general)
-{
- GNode *decode = NULL;
- GQuark oid;
- gconstpointer value;
- gsize n_value;
-
- general->type = GCR_GENERAL_NAME_OTHER;
- general->description = _("Other Name");
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "type-id", NULL));
- value = egg_asn1x_get_raw_element (egg_asn1x_node (node, "value", NULL), &n_value);
-
- if (value == NULL)
- return;
-
- if (oid == GCR_OID_ALT_NAME_XMPP_ADDR) {
- general->description = _("XMPP Addr");
- decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "UTF8String", value, n_value);
- general->display = egg_asn1x_get_string_as_utf8 (decode, g_realloc);
- } else if (oid == GCR_OID_ALT_NAME_DNS_SRV) {
- general->description = _("DNS SRV");
- decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "IA5String", value, n_value);
- general->display = egg_asn1x_get_string_as_utf8 (decode, g_realloc);
- }
-
- egg_asn1x_destroy (decode);
-}
-
-static void
-general_name_parse_rfc822 (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_RFC822;
- general->description = _("Email");
- general->display = egg_asn1x_get_string_as_utf8 (node, g_realloc);
-}
-
-static void
-general_name_parse_dns (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_DNS;
- general->description = _("DNS");
- general->display = egg_asn1x_get_string_as_utf8 (node, g_realloc);
-}
-
-static void
-general_name_parse_x400 (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_X400;
- general->description = _("X400 Address");
-}
-
-static void
-general_name_parse_dn (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_DNS;
- general->description = _("Directory Name");
- general->display = egg_dn_read (node);
-}
-
-static void
-general_name_parse_edi (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_EDI;
- general->description = _("EDI Party Name");
-}
-
-static void
-general_name_parse_uri (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_URI;
- general->description = _("URI");
- general->display = egg_asn1x_get_string_as_utf8 (node, g_realloc);
-}
-
-static void
-general_name_parse_ip (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_IP;
- general->description = _("IP Address");
- general->display = egg_asn1x_get_string_as_utf8 (node, g_realloc);
-}
-
-static void
-general_name_parse_registered (GNode *node, GcrGeneralName *general)
-{
- general->type = GCR_GENERAL_NAME_REGISTERED_ID;
- general->description = _("Registered ID");
- general->display = egg_asn1x_get_oid_as_string (node);
-}
-
-GArray*
-_gcr_certificate_extension_subject_alt_name (gconstpointer data, gsize n_data)
-{
- GNode *asn = NULL;
- guint count, i;
- const gchar *node_name;
- GArray *names;
- GcrGeneralName general;
- GNode *choice;
-
- _gcr_oids_init ();
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectAltName", data, n_data);
- if (asn == NULL)
- return NULL;
-
- names = g_array_new (FALSE, TRUE, sizeof (GcrGeneralName));
- count = egg_asn1x_count (asn);
-
- for (i = 0; i < count; i++) {
- choice = egg_asn1x_get_choice (egg_asn1x_node (asn, i + 1, NULL));
- g_return_val_if_fail (choice, NULL);
-
- node_name = egg_asn1x_name (choice);
- g_return_val_if_fail (node_name, NULL);
-
- memset (&general, 0, sizeof (general));
-
- if (g_str_equal (node_name, "otherName"))
- general_name_parse_other (choice, &general);
-
- else if (g_str_equal (node_name, "rfc822Name"))
- general_name_parse_rfc822 (choice, &general);
-
- else if (g_str_equal (node_name, "dNSName"))
- general_name_parse_dns (choice, &general);
-
- else if (g_str_equal (node_name, "x400Address"))
- general_name_parse_x400 (choice, &general);
-
- else if (g_str_equal (node_name, "directoryName"))
- general_name_parse_dn (choice, &general);
-
- else if (g_str_equal (node_name, "ediPartyName"))
- general_name_parse_edi (choice, &general);
-
- else if (g_str_equal (node_name, "uniformResourceIdentifier"))
- general_name_parse_uri (choice, &general);
-
- else if (g_str_equal (node_name, "IPAddress"))
- general_name_parse_ip (choice, &general);
-
- else if (g_str_equal (node_name, "registeredID"))
- general_name_parse_registered (choice, &general);
-
- general.raw = egg_asn1x_get_raw_element (choice, &general.n_raw);
- g_array_append_val (names, general);
- }
-
- egg_asn1x_destroy (asn);
- return names;
-}
-
-void
-_gcr_general_names_free (GArray *names)
-{
- guint i;
-
- for (i = 0; names && i < names->len; i++)
- g_free (g_array_index (names, GcrGeneralName, i).display);
- g_array_free (names, TRUE);
-}
diff --git a/gcr/gcr-certificate-extensions.h b/gcr/gcr-certificate-extensions.h
deleted file mode 100644
index 9101008d..00000000
--- a/gcr/gcr-certificate-extensions.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_CERTIFICATE_EXTENSIONS_H
-#define GCR_CERTIFICATE_EXTENSIONS_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-gboolean _gcr_certificate_extension_basic_constraints (gconstpointer data,
- gsize n_data,
- gboolean *is_ca,
- gint *path_len);
-
-GQuark* _gcr_certificate_extension_extended_key_usage (gconstpointer data,
- gsize n_data);
-
-gpointer _gcr_certificate_extension_subject_key_identifier (gconstpointer data,
- gsize n_data,
- gsize *n_keyid);
-
-typedef enum {
- GCR_KEY_USAGE_DIGITAL_SIGNATURE = 1 << 0,
- GCR_KEY_USAGE_NON_REPUDIATION = 1 << 1,
- GCR_KEY_USAGE_KEY_ENCIPHERMENT = 1 << 2,
- GCR_KEY_USAGE_DATA_ENCIPHERMENT = 1 << 3,
- GCR_KEY_USAGE_KEY_AGREEMENT = 1 << 4,
- GCR_KEY_USAGE_KEY_CERT_SIGN = 1 << 5,
- GCR_KEY_USAGE_CRL_SIGN = 1 << 6,
-} GcrCertificateExtensionKeyUsage;
-
-gboolean _gcr_certificate_extension_key_usage (gconstpointer data,
- gsize n_data,
- gulong *key_usage);
-
-typedef enum {
- GCR_GENERAL_NAME_OTHER,
- GCR_GENERAL_NAME_RFC822,
- GCR_GENERAL_NAME_DNS,
- GCR_GENERAL_NAME_X400,
- GCR_GENERAL_NAME_DN,
- GCR_GENERAL_NAME_EDI,
- GCR_GENERAL_NAME_URI,
- GCR_GENERAL_NAME_IP,
- GCR_GENERAL_NAME_REGISTERED_ID,
-} GcrGeneralNameType;
-
-typedef struct {
- GcrGeneralNameType type;
- const gchar *description;
- gchar *display;
- gconstpointer raw;
- gsize n_raw;
-} GcrGeneralName;
-
-GArray * _gcr_certificate_extension_subject_alt_name (gconstpointer data,
- gsize n_data);
-
-void _gcr_general_names_free (GArray *names);
-
-G_END_DECLS
-
-#endif /* GCR_CERTIFICATE_H */
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
deleted file mode 100644
index 7995917e..00000000
--- a/gcr/gcr-certificate-renderer.c
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-exporter.h"
-#include "gcr-certificate-extensions.h"
-#include "gcr-certificate-renderer.h"
-#include "gcr-display-view.h"
-#include "gcr-fingerprint.h"
-#include "gcr-icons.h"
-#include "gcr-oids.h"
-#include "gcr-simple-certificate.h"
-#include "gcr-renderer.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-dn.h"
-#include "egg/egg-oid.h"
-#include "egg/egg-hex.h"
-
-#include "gck/gck.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-/**
- * GcrCertificateRenderer:
- *
- * An implementation of #GcrRenderer which renders certificates.
- */
-
-/**
- * GcrCertificateRendererClass:
- * @parent_class: The parent class.
- *
- * The class for #GcrCertificateRenderer.
- */
-
-enum {
- PROP_0,
- PROP_CERTIFICATE,
- PROP_LABEL,
- PROP_ATTRIBUTES
-};
-
-struct _GcrCertificateRendererPrivate {
- GcrCertificate *opt_cert;
- GckAttributes *opt_attrs;
- guint key_size;
- gchar *label;
-};
-
-static void gcr_renderer_iface_init (GcrRendererIface *iface);
-static void gcr_renderer_certificate_iface_init (GcrCertificateIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
- GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_renderer_certificate_iface_init);
-);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gchar*
-calculate_label (GcrCertificateRenderer *self)
-{
- gchar *label;
-
- if (self->pv->label)
- return g_strdup (self->pv->label);
-
- if (self->pv->opt_attrs) {
- if (gck_attributes_find_string (self->pv->opt_attrs, CKA_LABEL, &label))
- return label;
- }
-
- label = gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self));
- if (label != NULL)
- return label;
-
- return g_strdup (_("Certificate"));
-}
-
-static gboolean
-append_extension_basic_constraints (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- gboolean is_ca = FALSE;
- gint path_len = -1;
- gchar *number;
-
- if (!_gcr_certificate_extension_basic_constraints (data, n_data, &is_ca, &path_len))
- return FALSE;
-
- _gcr_display_view_append_heading (view, renderer, _("Basic Constraints"));
-
- _gcr_display_view_append_value (view, renderer, _("Certificate Authority"),
- is_ca ? _("Yes") : _("No"), FALSE);
-
- number = g_strdup_printf ("%d", path_len);
- _gcr_display_view_append_value (view, renderer, _("Max Path Length"),
- path_len < 0 ? _("Unlimited") : number, FALSE);
- g_free (number);
-
- return TRUE;
-}
-
-static gboolean
-append_extension_extended_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- GQuark *oids;
- GString *text;
- guint i;
-
- oids = _gcr_certificate_extension_extended_key_usage (data, n_data);
- if (oids == NULL)
- return FALSE;
-
- _gcr_display_view_append_heading (view, renderer, _("Extended Key Usage"));
-
- text = g_string_new ("");
- for (i = 0; oids[i] != 0; i++) {
- if (i > 0)
- g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
- g_string_append (text, egg_oid_get_description (oids[i]));
- }
-
- g_free (oids);
-
- _gcr_display_view_append_value (view, renderer, _("Allowed Purposes"),
- text->str, FALSE);
-
- g_string_free (text, TRUE);
-
- return TRUE;
-}
-
-static gboolean
-append_extension_subject_key_identifier (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- gpointer keyid;
- gsize n_keyid;
-
- keyid = _gcr_certificate_extension_subject_key_identifier (data, n_data, &n_keyid);
- if (keyid == NULL)
- return FALSE;
-
- _gcr_display_view_append_heading (view, renderer, _("Subject Key Identifier"));
- _gcr_display_view_append_hex (view, renderer, _("Key Identifier"), keyid, n_keyid);
-
- g_free (keyid);
-
- return TRUE;
-}
-
-static const struct {
- guint usage;
- const gchar *description;
-} usage_descriptions[] = {
- { GCR_KEY_USAGE_DIGITAL_SIGNATURE, N_("Digital signature") },
- { GCR_KEY_USAGE_KEY_ENCIPHERMENT, N_("Key encipherment") },
- { GCR_KEY_USAGE_DATA_ENCIPHERMENT, N_("Data encipherment") },
- { GCR_KEY_USAGE_KEY_AGREEMENT, N_("Key agreement") },
- { GCR_KEY_USAGE_KEY_CERT_SIGN, N_("Certificate signature") },
- { GCR_KEY_USAGE_CRL_SIGN, N_("Revocation list signature") }
-};
-
-static gboolean
-append_extension_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- gulong key_usage;
- GString *text;
- guint i;
-
- if (!_gcr_certificate_extension_key_usage (data, n_data, &key_usage))
- return FALSE;
-
- text = g_string_new ("");
-
- for (i = 0; i < G_N_ELEMENTS (usage_descriptions); i++) {
- if (key_usage & usage_descriptions[i].usage) {
- if (text->len > 0)
- g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
- g_string_append (text, gettext (usage_descriptions[i].description));
- }
- }
-
- _gcr_display_view_append_heading (view, renderer, _("Key Usage"));
- _gcr_display_view_append_value (view, renderer, _("Usages"), text->str, FALSE);
-
- g_string_free (text, TRUE);
-
- return TRUE;
-}
-
-static gboolean
-append_extension_subject_alt_name (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- GArray *general_names;
- GcrGeneralName *general;
- guint i;
-
- general_names = _gcr_certificate_extension_subject_alt_name (data, n_data);
- if (general_names == NULL)
- return FALSE;
-
- _gcr_display_view_append_heading (view, renderer, _("Subject Alternative Names"));
-
- for (i = 0; i < general_names->len; i++) {
- general = &g_array_index (general_names, GcrGeneralName, i);
- if (general->display == NULL)
- _gcr_display_view_append_hex (view, renderer, general->description,
- general->raw, general->n_raw);
- else
- _gcr_display_view_append_value (view, renderer, general->description,
- general->display, FALSE);
- }
-
- _gcr_general_names_free (general_names);
-
- return TRUE;
-}
-
-
-static gboolean
-append_extension_hex (GcrCertificateRenderer *self, GcrDisplayView *view,
- GQuark oid, gconstpointer data, gsize n_data)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- const gchar *text;
-
- _gcr_display_view_append_heading (view, renderer, _("Extension"));
-
- /* Extension type */
- text = egg_oid_get_description (oid);
- _gcr_display_view_append_value (view, renderer, _("Identifier"), text, FALSE);
- _gcr_display_view_append_hex (view, renderer, _("Value"), data, n_data);
-
- return TRUE;
-}
-
-static gboolean
-append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
- GNode *asn, const guchar *data, gsize n_data, gint index)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- GNode *node;
- GQuark oid;
- gsize n_value;
- const guchar *value;
- gboolean critical;
- gboolean ret = FALSE;
-
- /* Make sure it is present */
- node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
- if (node == NULL)
- return FALSE;
-
- /* Dig out the OID */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
- g_return_val_if_fail (oid, FALSE);
-
- /* Extension value */
- value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
-
- /* The custom parsers */
- if (oid == GCR_OID_BASIC_CONSTRAINTS)
- ret = append_extension_basic_constraints (self, view, value, n_value);
- else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
- ret = append_extension_extended_key_usage (self, view, value, n_value);
- else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
- ret = append_extension_subject_key_identifier (self, view, value, n_value);
- else if (oid == GCR_OID_KEY_USAGE)
- ret = append_extension_key_usage (self, view, value, n_value);
- else if (oid == GCR_OID_SUBJECT_ALT_NAME)
- ret = append_extension_subject_alt_name (self, view, value, n_value);
-
- /* Otherwise the default raw display */
- if (ret == FALSE)
- ret = append_extension_hex (self, view, oid, value, n_value);
-
- /* Critical */
- if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
- _gcr_display_view_append_value (view, renderer, _("Critical"),
- critical ? _("Yes") : _("No"), FALSE);
- }
-
- return ret;
-}
-
-typedef struct _on_parsed_dn_args {
- GcrCertificateRenderer *renderer;
- GcrDisplayView *view;
-} on_parsed_dn_args;
-
-static void
-on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
- gsize n_value, gpointer user_data)
-{
- GcrCertificateRenderer *self = ((on_parsed_dn_args*)user_data)->renderer;
- GcrDisplayView *view = ((on_parsed_dn_args*)user_data)->view;
- const gchar *attr;
- const gchar *desc;
- gchar *field = NULL;
- gchar *display;
-
- g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
-
- attr = egg_oid_get_name (oid);
- desc = egg_oid_get_description (oid);
-
- /* Combine them into something sane */
- if (attr && desc) {
- if (strcmp (attr, desc) == 0)
- field = g_strdup (attr);
- else
- field = g_strdup_printf ("%s (%s)", attr, desc);
- } else if (!attr && !desc) {
- field = g_strdup ("");
- } else if (attr) {
- field = g_strdup (attr);
- } else if (desc) {
- field = g_strdup (desc);
- } else {
- g_assert_not_reached ();
- }
-
- display = egg_dn_print_value (oid, value, n_value);
- if (display == NULL)
- display = g_strdup ("");
-
- _gcr_display_view_append_value (view, GCR_RENDERER (self), field, display, FALSE);
- g_free (field);
- g_free (display);
-}
-
-static gboolean
-on_delete_unref_dialog (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- g_object_unref (widget);
- return FALSE;
-}
-
-static void
-on_export_completed (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- GtkWindow *parent = GTK_WINDOW (user_data);
- GcrCertificateExporter *exporter = GCR_CERTIFICATE_EXPORTER (source);
- GError *error = NULL;
- GtkWidget *dialog;
-
- if (!_gcr_certificate_exporter_export_finish (exporter, result, &error)) {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- dialog = gtk_message_dialog_new_with_markup (parent,
- GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK, "<big>%s</big>\n\n%s",
- _("Couldn't export the certificate."),
- error->message);
- gtk_widget_show (dialog);
- g_signal_connect (dialog, "delete-event",
- G_CALLBACK (on_delete_unref_dialog), NULL);
- }
- }
-
- /* Matches ref in on_certificate_export */
- if (parent)
- g_object_unref (parent);
-}
-
-static void
-on_certificate_export (GtkMenuItem *menuitem, gpointer user_data)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (user_data);
- GcrCertificateExporter *exporter;
- gchar *label;
- GtkWidget *parent;
-
- label = calculate_label (self);
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
- if (parent && !GTK_IS_WINDOW (parent))
- parent = NULL;
-
- exporter = _gcr_certificate_exporter_new (GCR_CERTIFICATE (self), label,
- GTK_WINDOW (parent));
-
- g_free (label);
-
- _gcr_certificate_exporter_export_async (exporter, NULL, on_export_completed,
- parent ? g_object_ref (parent) : NULL);
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gcr_certificate_renderer_init (GcrCertificateRenderer *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
-}
-
-static void
-gcr_certificate_renderer_dispose (GObject *obj)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
-
- if (self->pv->opt_cert)
- g_object_unref (self->pv->opt_cert);
- self->pv->opt_cert = NULL;
-
- G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->dispose (obj);
-}
-
-static void
-gcr_certificate_renderer_finalize (GObject *obj)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
-
- g_assert (!self->pv->opt_cert);
-
- if (self->pv->opt_attrs)
- gck_attributes_unref (self->pv->opt_attrs);
- self->pv->opt_attrs = NULL;
-
- g_free (self->pv->label);
- self->pv->label = NULL;
-
- G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
-}
-
-static void
-gcr_certificate_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- gcr_certificate_renderer_set_certificate (self, g_value_get_object (value));
- break;
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- case PROP_ATTRIBUTES:
- gcr_certificate_renderer_set_attributes (self, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- g_value_set_object (value, self->pv->opt_cert);
- break;
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->opt_attrs);
- break;
- default:
- gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
- break;
- }
-}
-
-static void
-gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- _gcr_oids_init ();
-
- gcr_certificate_renderer_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrCertificateRendererPrivate));
-
- gobject_class->dispose = gcr_certificate_renderer_dispose;
- gobject_class->finalize = gcr_certificate_renderer_finalize;
- gobject_class->set_property = gcr_certificate_renderer_set_property;
- gobject_class->get_property = gcr_certificate_renderer_get_property;
-
- /**
- * GcrCertificateRenderer:certificate:
- *
- * The certificate to display. May be %NULL.
- */
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
- GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
-
- /**
- * GcrCertificateRenderer:attributes:
- *
- * The certificate attributes to display. One of the attributes must be
- * a CKA_VALUE type attribute which contains a DER encoded certificate.
- */
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-
- /**
- * GcrCertificateRenderer:label:
- *
- * The label to display.
- */
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Certificate Label",
- "", G_PARAM_READWRITE));
-
- gcr_certificate_mixin_class_init (gobject_class);
-
- /* Register this as a renderer which can be loaded */
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
- gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, registered);
- gck_attributes_unref (registered);
-}
-
-static void
-gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
-{
- GcrCertificateRenderer *self;
- gconstpointer data, value;
- gsize n_data, n_value, n_raw;
- GcrDisplayView *view;
- on_parsed_dn_args args;
- const gchar *text;
- GcrCertificate *cert;
- gpointer raw;
- gconstpointer number;
- gulong version;
- guint bits, index;
- gchar *display;
- GNode *asn;
- GQuark oid;
- GDate date;
- GIcon *icon;
-
- self = GCR_CERTIFICATE_RENDERER (renderer);
-
- if (GCR_IS_DISPLAY_VIEW (viewer)) {
- view = GCR_DISPLAY_VIEW (viewer);
-
- } else {
- g_warning ("GcrCertificateRenderer only works with internal specific "
- "GcrViewer returned by gcr_viewer_new().");
- return;
- }
-
- _gcr_display_view_begin (view, renderer);
- cert = GCR_CERTIFICATE (self);
-
- data = gcr_certificate_get_der_data (cert, &n_data);
- if (!data) {
- _gcr_display_view_end (view, renderer);
- return;
- }
-
- icon = gcr_certificate_get_icon (cert);
- _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
- g_object_unref (icon);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- g_return_if_fail (asn);
-
- display = calculate_label (self);
- _gcr_display_view_append_title (view, renderer, display);
- g_free (display);
-
- display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
- _gcr_display_view_append_content (view, renderer, _("Identity"), display);
- g_free (display);
-
- display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
- _gcr_display_view_append_content (view, renderer, _("Verified by"), display);
- g_free (display);
-
- if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
- display = g_malloc0 (128);
- if (!g_date_strftime (display, 128, "%x", &date))
- g_return_if_reached ();
- _gcr_display_view_append_content (view, renderer, _("Expires"), display);
- g_free (display);
- }
-
- _gcr_display_view_start_details (view, renderer);
-
- args.renderer = self;
- args.view = view;
-
- /* The subject */
- _gcr_display_view_append_heading (view, renderer, _("Subject Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, &args);
-
- /* The Issuer */
- _gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, &args);
-
- /* The Issued Parameters */
- _gcr_display_view_append_heading (view, renderer, _("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);
- _gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
- g_free (display);
-
- number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_raw);
- g_return_if_fail (number != NULL);
- _gcr_display_view_append_hex (view, renderer, _("Serial Number"), number, n_raw);
-
- 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 ();
- _gcr_display_view_append_value (view, renderer, _("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 ();
- _gcr_display_view_append_value (view, renderer, _("Not Valid After"), display, FALSE);
- }
- g_free (display);
-
- /* Fingerprints */
- _gcr_display_view_append_heading (view, renderer, _("Certificate Fingerprints"));
-
- _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
- _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
-
- /* Signature */
- _gcr_display_view_append_heading (view, renderer, _("Signature"));
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
- text = egg_oid_get_description (oid);
- _gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
- if (value && n_value)
- _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"), value, n_value);
-
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
- g_return_if_fail (raw);
- _gcr_display_view_append_hex (view, renderer, _("Signature"), raw, bits / 8);
- g_free (raw);
-
- /* Public Key Info */
- _gcr_display_view_append_heading (view, renderer, _("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);
- _gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "algorithm", "parameters", NULL), &n_value);
- if (value && n_value)
- _gcr_display_view_append_hex (view, renderer, _("Key Parameters"), value, n_value);
-
- bits = gcr_certificate_get_key_size (cert);
- if (bits > 0) {
- display = g_strdup_printf ("%u", bits);
- _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
- g_free (display);
- }
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate",
- "subjectPublicKeyInfo", NULL), &n_value);
- raw = gcr_fingerprint_from_subject_public_key_info (value, n_value, G_CHECKSUM_SHA1, &n_raw);
- _gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
- g_free (raw);
-
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "subjectPublicKey", NULL), NULL, &bits);
- g_return_if_fail (raw);
- _gcr_display_view_append_hex (view, renderer, _("Public Key"), raw, bits / 8);
- g_free (raw);
-
- /* Extensions */
- for (index = 1; TRUE; ++index) {
- if (!append_extension (self, view, asn, data, n_data, index))
- break;
- }
-
- egg_asn1x_destroy (asn);
- _gcr_display_view_end (view, renderer);
-}
-
-static void
-gcr_certificate_renderer_populate_popup (GcrRenderer *self, GcrViewer *viewer,
- GtkMenu *menu)
-{
- GtkWidget *item;
-
- item = gtk_separator_menu_item_new ();
- gtk_widget_show (item);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("Export Certificate...");
- gtk_widget_show (item);
- g_signal_connect_data (item, "activate", G_CALLBACK (on_certificate_export),
- g_object_ref (self), (GClosureNotify)g_object_unref, 0);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-}
-
-static void
-gcr_renderer_iface_init (GcrRendererIface *iface)
-{
- iface->populate_popup = gcr_certificate_renderer_populate_popup;
- iface->render_view = gcr_certificate_renderer_render;
-}
-
-static const guchar *
-gcr_certificate_renderer_get_der_data (GcrCertificate *cert,
- gsize *n_data)
-{
- GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
- GckAttribute *attr;
-
- g_assert (n_data);
-
- if (self->pv->opt_cert)
- return gcr_certificate_get_der_data (self->pv->opt_cert, n_data);
-
- if (self->pv->opt_attrs) {
- attr = gck_attributes_find (self->pv->opt_attrs, CKA_VALUE);
- g_return_val_if_fail (attr, NULL);
- *n_data = attr->length;
- return attr->value;
- }
-
- return NULL;
-}
-
-static void
-gcr_renderer_certificate_iface_init (GcrCertificateIface *iface)
-{
- iface->get_der_data = gcr_certificate_renderer_get_der_data;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_certificate_renderer_new:
- * @certificate: The certificate to display
- *
- * Create a new certificate renderer to display the certificate.
- *
- * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
- * should be released with g_object_unref()
- */
-GcrCertificateRenderer *
-gcr_certificate_renderer_new (GcrCertificate *certificate)
-{
- return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "certificate", certificate, NULL);
-}
-
-/**
- * gcr_certificate_renderer_new_for_attributes:
- * @label: (allow-none): the label to display
- * @attrs: The attributes to display
- *
- * Create a new certificate renderer to display the label and attributes. One
- * of the attributes should be a CKA_VALUE type attribute containing a DER
- * encoded certificate.
- *
- * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
- * should be released with g_object_unref()
- */
-GcrCertificateRenderer *
-gcr_certificate_renderer_new_for_attributes (const gchar *label, struct _GckAttributes *attrs)
-{
- return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "label", label, "attributes", attrs, NULL);
-}
-
-/**
- * gcr_certificate_renderer_get_certificate:
- * @self: The renderer
- *
- * Get the certificate displayed in the renderer. If no certificate was
- * explicitly set, then the renderer will return itself since it acts as
- * a valid certificate.
- *
- * Returns: (transfer none): The certificate, owned by the renderer.
- */
-GcrCertificate *
-gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
- if (self->pv->opt_cert)
- return self->pv->opt_cert;
- return GCR_CERTIFICATE (self);
-}
-
-/**
- * gcr_certificate_renderer_set_certificate:
- * @self: The renderer
- * @certificate: (allow-none): the certificate to display
- *
- * Set a certificate to display in the renderer.
- */
-void
-gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self, GcrCertificate *certificate)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
-
- if (self->pv->opt_cert)
- g_object_unref (self->pv->opt_cert);
- self->pv->opt_cert = certificate;
- if (self->pv->opt_cert)
- g_object_ref (self->pv->opt_cert);
-
- if (self->pv->opt_attrs) {
- gck_attributes_unref (self->pv->opt_attrs);
- self->pv->opt_attrs = NULL;
- }
-
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- g_object_notify (G_OBJECT (self), "certificate");
-}
-
-/**
- * gcr_certificate_renderer_get_attributes:
- * @self: The renderer
- *
- * Get the PKCS\#11 attributes, if any, set for this renderer to display.
- *
- * Returns: (allow-none) (transfer none): the attributes, owned by the renderer
- */
-GckAttributes *
-gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
- return self->pv->opt_attrs;
-}
-
-/**
- * gcr_certificate_renderer_set_attributes:
- * @self: The renderer
- * @attrs: (allow-none): attributes to set
- *
- * Set the PKCS\#11 attributes for this renderer to display. One of the attributes
- * should be a CKA_VALUE type attribute containing a DER encoded certificate.
- */
-void
-gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttributes *attrs)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
-
- gck_attributes_unref (self->pv->opt_attrs);
- self->pv->opt_attrs = attrs;
-
- if (self->pv->opt_attrs)
- gck_attributes_ref (self->pv->opt_attrs);
-
- if (self->pv->opt_cert) {
- g_object_unref (self->pv->opt_cert);
- g_object_notify (G_OBJECT (self), "certificate");
- self->pv->opt_cert = NULL;
- }
-
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- g_object_notify (G_OBJECT (self), "attributes");
-
-}
diff --git a/gcr/gcr-certificate-renderer.h b/gcr/gcr-certificate-renderer.h
deleted file mode 100644
index 6167dd5a..00000000
--- a/gcr/gcr-certificate-renderer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_CERTIFICATE_RENDERER_H__
-#define __GCR_CERTIFICATE_RENDERER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-certificate.h"
-#include "gcr-renderer.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CERTIFICATE_RENDERER (gcr_certificate_renderer_get_type ())
-#define GCR_CERTIFICATE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRenderer))
-#define GCR_CERTIFICATE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererClass))
-#define GCR_IS_CERTIFICATE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_RENDERER))
-#define GCR_IS_CERTIFICATE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_RENDERER))
-#define GCR_CERTIFICATE_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererClass))
-
-typedef struct _GcrCertificateRenderer GcrCertificateRenderer;
-typedef struct _GcrCertificateRendererClass GcrCertificateRendererClass;
-typedef struct _GcrCertificateRendererPrivate GcrCertificateRendererPrivate;
-
-struct _GcrCertificateRenderer {
- GObject parent;
-
- /*< private >*/
- GcrCertificateRendererPrivate *pv;
-};
-
-struct _GcrCertificateRendererClass {
- GObjectClass parent_class;
-};
-
-GType gcr_certificate_renderer_get_type (void);
-
-GcrCertificateRenderer* gcr_certificate_renderer_new (GcrCertificate *certificate);
-
-GcrCertificateRenderer* gcr_certificate_renderer_new_for_attributes (const gchar *label,
- struct _GckAttributes *attrs);
-
-GcrCertificate* gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self);
-
-void gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self,
- GcrCertificate *certificate);
-
-GckAttributes* gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self);
-
-void gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self,
- GckAttributes *attrs);
-
-G_END_DECLS
-
-#endif /* __GCR_CERTIFICATE_RENDERER_H__ */
diff --git a/gcr/gcr-certificate-widget.c b/gcr/gcr-certificate-widget.c
deleted file mode 100644
index 6ffdd443..00000000
--- a/gcr/gcr-certificate-widget.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-certificate.h"
-#include "gcr-certificate-renderer.h"
-#include "gcr-certificate-widget.h"
-#include "gcr-renderer.h"
-#include "gcr-viewer.h"
-
-#include "gck/gck.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-certificate-widget
- * @title: GcrCertificateWidget
- * @short_description: Certificate widget and renderer
- *
- * A #GcrCertificateWidget can be used to display a certificate. The widget
- * is normally in a collapsed state showing only details, but can be expanded
- * by the user.
- *
- * Use gcr_certificate_widget_new() to create a new certificate widget. Only
- * one certificate can be displayed. A #GcrCertificateWidget contains a
- * #GcrViewer internally and #GcrCertificateRenderer is used to render the
- * certificate to the viewer. To show more than one certificate in a view,
- * create the viewer and add renderers to it.
- */
-
-/**
- * GcrCertificateWidget:
- *
- * A widget that displays a certificate.
- */
-
-/**
- * GcrCertificateWidgetClass:
- *
- * The class for #GcrCertificateWidget
- */
-
-enum {
- PROP_0,
- PROP_CERTIFICATE,
- PROP_ATTRIBUTES
-};
-
-struct _GcrCertificateWidget {
- /*< private >*/
- GtkAlignment parent;
- GcrCertificateWidgetPrivate *pv;
-};
-
-struct _GcrCertificateWidgetClass {
- /*< private >*/
- GtkAlignmentClass parent_class;
-};
-
-struct _GcrCertificateWidgetPrivate {
- GcrViewer *viewer;
- GcrCertificateRenderer *renderer;
-};
-
-G_DEFINE_TYPE (GcrCertificateWidget, gcr_certificate_widget, GTK_TYPE_ALIGNMENT);
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-gcr_certificate_widget_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GObject *obj = G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->constructor (type, n_props, props);
- GcrCertificateWidget *self = NULL;
-
- g_return_val_if_fail (obj, NULL);
-
- self = GCR_CERTIFICATE_WIDGET (obj);
-
- self->pv->viewer = gcr_viewer_new_scrolled ();
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->viewer));
- gtk_widget_show (GTK_WIDGET (self->pv->viewer));
-
- gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (self->pv->renderer));
- return obj;
-}
-
-static void
-gcr_certificate_widget_init (GcrCertificateWidget *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_WIDGET, GcrCertificateWidgetPrivate));
- self->pv->renderer = gcr_certificate_renderer_new (NULL);
-}
-
-static void
-gcr_certificate_widget_finalize (GObject *obj)
-{
- GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
-
- g_assert (self->pv->renderer);
- g_object_unref (self->pv->renderer);
- self->pv->renderer = NULL;
-
- g_assert (self->pv->viewer);
- self->pv->viewer = NULL;
-
- G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->finalize (obj);
-}
-
-static void
-gcr_certificate_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- gcr_certificate_widget_set_certificate (self, g_value_get_object (value));
- break;
- case PROP_ATTRIBUTES:
- gcr_certificate_widget_set_attributes (self, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_certificate_widget_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrCertificateWidget *self = GCR_CERTIFICATE_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_CERTIFICATE:
- g_value_set_object (value, gcr_certificate_widget_get_certificate (self));
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, gcr_certificate_widget_get_attributes (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_certificate_widget_class_init (GcrCertificateWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gcr_certificate_widget_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrCertificateWidgetPrivate));
-
- gobject_class->constructor = gcr_certificate_widget_constructor;
- gobject_class->finalize = gcr_certificate_widget_finalize;
- gobject_class->set_property = gcr_certificate_widget_set_property;
- gobject_class->get_property = gcr_certificate_widget_get_property;
-
- g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
- g_param_spec_object("certificate", "Certificate", "Certificate to display.",
- GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Attributes which contain the certificate",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_certificate_widget_new:
- * @certificate: (allow-none): certificate to display, or %NULL
- *
- * Create a new certificate widget which displays a given certificate.
- *
- * Returns: (transfer full): a newly allocated #GcrCertificateWidget, which
- * should be freed with g_object_unref()
- */
-GcrCertificateWidget *
-gcr_certificate_widget_new (GcrCertificate *certificate)
-{
- return g_object_new (GCR_TYPE_CERTIFICATE_WIDGET, "certificate", certificate, NULL);
-}
-
-/**
- * gcr_certificate_widget_get_certificate:
- * @self: The certificate widget
- *
- * Get the certificate displayed in the widget.
- *
- * Returns: (allow-none) (transfer none): the certificate
- */
-GcrCertificate *
-gcr_certificate_widget_get_certificate (GcrCertificateWidget *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_WIDGET (self), NULL);
- return gcr_certificate_renderer_get_certificate (self->pv->renderer);
-}
-
-/**
- * gcr_certificate_widget_set_certificate:
- * @self: The certificate widget
- * @certificate: (allow-none): the certificate to display
- *
- * Set the certificate displayed in the widget
- */
-void
-gcr_certificate_widget_set_certificate (GcrCertificateWidget *self, GcrCertificate *certificate)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_WIDGET (self));
- gcr_certificate_renderer_set_certificate (self->pv->renderer, certificate);
-}
-
-/**
- * gcr_certificate_widget_get_attributes:
- * @self: The certificate widget
- *
- * Get the attributes displayed in the widget. The attributes should contain
- * a certificate.
- *
- * Returns: (allow-none) (transfer none): the attributes, owned by the widget
- */
-GckAttributes *
-gcr_certificate_widget_get_attributes (GcrCertificateWidget *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE_WIDGET (self), NULL);
- return gcr_certificate_renderer_get_attributes (self->pv->renderer);
-}
-
-/**
- * gcr_certificate_widget_set_attributes:
- * @self: The certificate widget
- * @attrs: (allow-none): the attributes to display
- *
- * Set the attributes displayed in the widget. The attributes should contain
- * a certificate.
- */
-void
-gcr_certificate_widget_set_attributes (GcrCertificateWidget *self, GckAttributes* attrs)
-{
- g_return_if_fail (GCR_IS_CERTIFICATE_WIDGET (self));
- gcr_certificate_renderer_set_attributes (self->pv->renderer, attrs);
-}
diff --git a/gcr/gcr-certificate-widget.h b/gcr/gcr-certificate-widget.h
deleted file mode 100644
index 3ad2f194..00000000
--- a/gcr/gcr-certificate-widget.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_CERTIFICATE_WIDGET_H__
-#define __GCR_CERTIFICATE_WIDGET_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-certificate.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_CERTIFICATE_WIDGET (gcr_certificate_widget_get_type ())
-#define GCR_CERTIFICATE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_WIDGET, GcrCertificateWidget))
-#define GCR_CERTIFICATE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_WIDGET, GcrCertificateWidgetClass))
-#define GCR_IS_CERTIFICATE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_WIDGET))
-#define GCR_IS_CERTIFICATE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_WIDGET))
-#define GCR_CERTIFICATE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_WIDGET, GcrCertificateWidgetClass))
-
-typedef struct _GcrCertificateWidget GcrCertificateWidget;
-typedef struct _GcrCertificateWidgetClass GcrCertificateWidgetClass;
-typedef struct _GcrCertificateWidgetPrivate GcrCertificateWidgetPrivate;
-
-/*
- * TODO: GcrCertificateWidget and GcrCertificateWidgetClass are hidden until
- * we can figure out what they should be derived from.
- */
-
-GType gcr_certificate_widget_get_type (void);
-
-GcrCertificateWidget* gcr_certificate_widget_new (GcrCertificate *certificate);
-
-GcrCertificate* gcr_certificate_widget_get_certificate (GcrCertificateWidget *self);
-
-void gcr_certificate_widget_set_certificate (GcrCertificateWidget *self,
- GcrCertificate *certificate);
-
-GckAttributes* gcr_certificate_widget_get_attributes (GcrCertificateWidget *self);
-
-void gcr_certificate_widget_set_attributes (GcrCertificateWidget *self,
- GckAttributes* attrs);
-
-G_END_DECLS
-
-#endif /* __GCR_CERTIFICATE_WIDGET_H__ */
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
deleted file mode 100644
index 95b513c3..00000000
--- a/gcr/gcr-certificate.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-certificate.h"
-#include "gcr-comparable.h"
-#include "gcr-icons.h"
-#include "gcr-internal.h"
-#include "gcr-oids.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-dn.h"
-#include "egg/egg-hex.h"
-
-#include <string.h>
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-certificate
- * @title: GcrCertificate
- * @short_description: Represents an X.509 certificate
- *
- * This is an interface that represents an X.509 certificate. Objects can
- * implement this interface to make a certificate usable with the GCR
- * library.
- *
- * Various methods are available to parse out relevant bits of the certificate.
- * However no verification of the validity of a certificate is done here. Use
- * your favorite crypto library to do this.
- *
- * You can use #GcrSimpleCertificate to simply load a certificate for which
- * you already have the raw certificate data.
- *
- * The #GcrCertificate interface has several properties that must be implemented.
- * You can use a mixin to implement these properties if desired. See the
- * gcr_certificate_mixin_class_init() and gcr_certificate_mixin_get_property()
- * functions.
- *
- * All certificates are comparable. If implementing a #GcrCertificate, you can
- * use GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE() to implement the #GcrComparable
- * interface.
- */
-
-/**
- * GcrCertificate:
- *
- * An object which holds a certificate.
- */
-
-/**
- * GcrCertificateIface:
- * @parent: the parent interface type
- * @get_der_data: a method which returns the RAW der data of the certificate
- *
- * The interface that implementors of #GcrCertificate must implement.
- */
-
-/**
- * GCR_CERTIFICATE_COLUMNS:
- *
- * The columns that are valid for a certificate. This is to be used with
- * the #GcrTreeSelector or #GcrCollectionModel.
- *
- * This is an array of #GcrColumn, owned by the gcr library.
- */
-
-/*
- * The DER data in this structure is owned by the derived class.
- * It is only valid for the duration of the current call stack
- * after we call gcr_certificate_get_der_data(). We shouldn't
- * save it anywhere else.
- *
- * We keep the pointer around and compare it so that if the derived
- * class returns exactly the same pointer and size, then we can
- * keep from parsing things over again.
- */
-
-typedef struct _GcrCertificateInfo {
- gconstpointer der;
- gsize n_der;
- GNode *asn1;
- guint key_size;
-} GcrCertificateInfo;
-
-/* Forward declarations */
-
-static gconstpointer _gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data);
-static gconstpointer _gcr_certificate_get_issuer_const (GcrCertificate *self, gsize *n_data);
-
-enum {
- PROP_FIRST = 0x0007000,
- PROP_LABEL,
- PROP_MARKUP,
- PROP_DESCRIPTION,
- PROP_ICON,
- PROP_SUBJECT,
- PROP_ISSUER,
- PROP_EXPIRY
-};
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static GQuark CERTIFICATE_INFO = 0;
-
-static void
-certificate_info_free (gpointer data)
-{
- GcrCertificateInfo *info = data;
- if (info) {
- g_assert (info->asn1);
- egg_asn1x_destroy (info->asn1);
- g_free (info);
- }
-}
-
-static GcrCertificateInfo*
-certificate_info_load (GcrCertificate *cert)
-{
- GcrCertificateInfo *info;
- GNode *asn1;
- gconstpointer der;
- gsize n_der;
-
- g_assert (GCR_IS_CERTIFICATE (cert));
-
- der = gcr_certificate_get_der_data (cert, &n_der);
- g_return_val_if_fail (der, NULL);
-
- info = g_object_get_qdata (G_OBJECT (cert), CERTIFICATE_INFO);
- if (info != NULL) {
- if (n_der == info->n_der && der == info->der)
- return info;
- }
-
- /* Cache is invalid or non existent */
- asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", der, n_der);
- if (asn1 == NULL) {
- g_warning ("a derived class provided an invalid or unparseable X.509 DER certificate data.");
- return NULL;
- }
-
- info = g_new0 (GcrCertificateInfo, 1);
- info->der = der;
- info->n_der = n_der;
- info->asn1 = asn1;
-
- g_object_set_qdata_full (G_OBJECT (cert), CERTIFICATE_INFO, info, certificate_info_free);
- return info;
-}
-
-static guint
-calculate_rsa_key_size (gconstpointer data, gsize n_data)
-{
- GNode *asn;
- gsize n_content;
-
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data, n_data);
- g_return_val_if_fail (asn, 0);
-
- if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL), &n_content))
- g_return_val_if_reached (0);
-
- egg_asn1x_destroy (asn);
-
- /* Removes the complement */
- return (n_content / 2) * 2 * 8;
-}
-
-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;
-}
-
-static guint
-calculate_key_size (GcrCertificateInfo *info)
-{
- GNode *asn;
- gconstpointer data, params;
- gsize n_data, n_params;
- guint key_size = 0, n_bits;
- guchar *key = NULL;
- GQuark oid;
-
- data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
- g_return_val_if_fail (data != NULL, 0);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
- g_return_val_if_fail (asn, 0);
-
- /* Figure out the algorithm */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
- g_return_val_if_fail (oid, 0);
-
- /* RSA keys are stored in the main subjectPublicKey field */
- if (oid == GCR_OID_PKIX1_RSA) {
-
- /* A bit string so we cannot process in place */
- key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
- g_return_val_if_fail (key, 0);
- key_size = calculate_rsa_key_size (key, n_bits / 8);
- g_free (key);
-
- /* The DSA key size is discovered by the prime in params */
- } else if (oid == GCR_OID_PKIX1_DSA) {
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
- key_size = calculate_dsa_params_size (params, n_params);
-
- } else {
- g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
- }
-
- egg_asn1x_destroy (asn);
-
- return key_size;
-}
-
-static GChecksum*
-digest_certificate (GcrCertificate *self, GChecksumType type)
-{
- GChecksum *digest;
- gconstpointer der;
- gsize n_der;
-
- g_assert (GCR_IS_CERTIFICATE (self));
-
- der = gcr_certificate_get_der_data (self, &n_der);
- g_return_val_if_fail (der, NULL);
-
- digest = g_checksum_new (type);
- g_return_val_if_fail (digest, NULL);
-
- g_checksum_update (digest, der, n_der);
- return digest;
-}
-
-static gchar*
-calculate_markup (GcrCertificate *self)
-{
- gchar *label = NULL;
- gchar *issuer;
- gchar *markup;
-
- g_object_get (self, "label", &label, NULL);
- issuer = gcr_certificate_get_issuer_cn (self);
-
- if (issuer)
- markup = g_markup_printf_escaped ("%s\n<small>Issued by: %s</small>", label, issuer);
- else
- markup = g_markup_printf_escaped ("%s\n<small>Issued by: <i>No name</i></small>", label);
-
- g_free (label);
- g_free (issuer);
- return markup;
-}
-
-static void
-on_transform_date_to_string (const GValue *src, GValue *dest)
-{
- static const gsize len = 256;
- GDate *date;
- gchar *result;
-
- g_return_if_fail (G_VALUE_TYPE (src) == G_TYPE_DATE);
-
- date = g_value_get_boxed (src);
- g_return_if_fail (date);
-
- result = g_malloc0 (len);
- if (!g_date_strftime (result, len, "%x", date)) {
- g_free (result);
- result = NULL;
- }
-
- g_value_take_string (dest, result);
-}
-
-/* ---------------------------------------------------------------------------------
- * INTERFACE
- */
-
-static void
-gcr_certificate_default_init (GcrCertificateIface *iface)
-{
- static volatile gsize initialized = 0;
-
- if (g_once_init_enter (&initialized)) {
- _gcr_oids_init ();
-
- CERTIFICATE_INFO = g_quark_from_static_string ("_gcr_certificate_certificate_info");
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("label", "Label", "Certificate label",
- "", G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("description", "Description", "Description of object being rendered",
- "", G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("markup", "Markup", "Markup which describes object being rendered",
- "", G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_object ("icon", "Icon", "Icon for the object being rendered",
- G_TYPE_ICON, G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("subject", "Subject", "Common name of subject",
- "", G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("issuer", "Issuer", "Common name of issuer",
- "", G_PARAM_READABLE));
-
- g_object_interface_install_property (iface,
- g_param_spec_boxed ("expiry", "Expiry", "Certificate expiry",
- G_TYPE_DATE, G_PARAM_READABLE));
-
- g_once_init_leave (&initialized, 1);
- }
-}
-
-typedef GcrCertificateIface GcrCertificateInterface;
-
-G_DEFINE_INTERFACE (GcrCertificate, gcr_certificate, GCR_TYPE_COMPARABLE);
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_certificate_get_columns: (skip)
- *
- * Get the columns appropriate for a certificate
- *
- * Returns: (transfer none): the columns
- */
-const GcrColumn*
-gcr_certificate_get_columns (void)
-{
- static GcrColumn columns[] = {
- { "icon", /* later */ 0, /* later */ 0, NULL, 0 },
- { "label", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Name"),
- GCR_COLUMN_SORTABLE },
- { "issuer", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Issued By"),
- GCR_COLUMN_SORTABLE },
- { "expiry", /* later */ 0, G_TYPE_STRING, NC_("column", "Expires"),
- GCR_COLUMN_SORTABLE, on_transform_date_to_string },
- { NULL }
- };
-
- columns[0].property_type = columns[0].column_type = G_TYPE_ICON;
- columns[3].property_type = G_TYPE_DATE;
- return columns;
-}
-
-/**
- * gcr_certificate_compare:
- * @first: (allow-none): the certificate to compare
- * @other: (allow-none): the certificate to compare against
- *
- * Compare one certificate against another. If the certificates are equal
- * then zero is returned. If one certificate is %NULL or not a certificate,
- * then a non-zero value is returned.
- *
- * The return value is useful in a stable sort, but has no user logical
- * meaning.
- *
- * Returns: zero if the certificates match, non-zero otherwise.
- */
-gint
-gcr_certificate_compare (GcrComparable *first, GcrComparable *other)
-{
- gconstpointer data1, data2;
- gsize size1, size2;
-
- if (!GCR_IS_CERTIFICATE (first))
- first = NULL;
- if (!GCR_IS_CERTIFICATE (other))
- other = NULL;
-
- if (first == other)
- return TRUE;
- if (!first)
- return 1;
- if (!other)
- return -1;
-
- data1 = gcr_certificate_get_der_data (GCR_CERTIFICATE (first), &size1);
- data2 = gcr_certificate_get_der_data (GCR_CERTIFICATE (other), &size2);
-
- return gcr_comparable_memcmp (data1, size1, data2, size2);
-}
-
-
-/**
- * gcr_certificate_get_der_data:
- * @self: a #GcrCertificate
- * @n_data: a pointer to a location to store the size of the resulting DER data.
- *
- * Gets the raw DER data for an X.509 certificate.
- *
- * Returns: (array length=n_data): raw DER data of the X.509 certificate
- **/
-const guchar *
-gcr_certificate_get_der_data (GcrCertificate *self,
- gsize *n_data)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
- g_return_val_if_fail (GCR_CERTIFICATE_GET_INTERFACE (self)->get_der_data, NULL);
- return GCR_CERTIFICATE_GET_INTERFACE (self)->get_der_data (self, n_data);
-}
-
-/**
- * gcr_certificate_get_issuer_cn:
- * @self: a #GcrCertificate
- *
- * Get the common name of the issuer of this certificate.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: The allocated issuer CN, or NULL if no issuer CN present.
- */
-gchar*
-gcr_certificate_get_issuer_cn (GcrCertificate *self)
-{
- return gcr_certificate_get_issuer_part (self, "cn");
-}
-
-/**
- * gcr_certificate_get_issuer_part:
- * @self: a #GcrCertificate
- * @part: a DN type string or OID.
- *
- * Get a part of the DN of the issuer of this certificate.
- *
- * Examples of a @part might be the 'OU' (organizational unit)
- * or the 'CN' (common name). Only the value of that part
- * of the DN is returned.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: (allow-none): the allocated part of the issuer DN, or %NULL if no
- * such part is present
- */
-gchar *
-gcr_certificate_get_issuer_part (GcrCertificate *self, const char *part)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (part != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_dn_read_part (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL), part);
-}
-
-static gconstpointer
-_gcr_certificate_get_issuer_const (GcrCertificate *self, gsize *n_data)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", NULL), n_data);
-}
-
-/**
- * gcr_certificate_get_issuer_raw:
- * @self: a #GcrCertificate
- * @n_data: The length of the returned data.
- *
- * Get the raw DER data for the issuer DN of the certificate.
- *
- * The data should be freed by using g_free() when no longer required.
- *
- * Returns: (transfer full) (array length=n_data): allocated memory containing
- * the raw issuer
- */
-guchar *
-gcr_certificate_get_issuer_raw (GcrCertificate *self,
- gsize *n_data)
-{
- gconstpointer data;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
-
- data = _gcr_certificate_get_issuer_const (self, n_data);
- return g_memdup (data, data ? *n_data : 0);
-}
-
-/**
- * gcr_certificate_is_issuer:
- * @self: a #GcrCertificate
- * @issuer: a possible issuer #GcrCertificate
- *
- * Check if @issuer could be the issuer of this certificate. This is done by
- * comparing the relevant subject and issuer fields. No signature check is
- * done. Proper verification of certificates must be done via a crypto
- * library.
- *
- * Returns: whether @issuer could be the issuer of the certificate.
- */
-gboolean
-gcr_certificate_is_issuer (GcrCertificate *self, GcrCertificate *issuer)
-{
- gconstpointer subject_dn, issuer_dn;
- gsize n_subject_dn, n_issuer_dn;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), FALSE);
- g_return_val_if_fail (GCR_IS_CERTIFICATE (issuer), FALSE);
-
- subject_dn = _gcr_certificate_get_subject_const (issuer, &n_subject_dn);
- g_return_val_if_fail (subject_dn, FALSE);
-
- issuer_dn = _gcr_certificate_get_issuer_const (self, &n_issuer_dn);
- g_return_val_if_fail (issuer_dn, FALSE);
-
- return (n_issuer_dn == n_subject_dn &&
- memcmp (issuer_dn, subject_dn, n_issuer_dn) == 0);
-}
-
-/**
- * gcr_certificate_get_issuer_dn:
- * @self: a #GcrCertificate
- *
- * Get the full issuer DN of the certificate as a (mostly)
- * readable string.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: The allocated issuer DN of the certificate.
- */
-gchar*
-gcr_certificate_get_issuer_dn (GcrCertificate *self)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_dn_read (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL));
-}
-
-/**
- * gcr_certificate_get_subject_cn:
- * @self: a #GcrCertificate
- *
- * Get the common name of the subject of this certificate.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: The allocated subject CN, or NULL if no subject CN present.
- */
-gchar*
-gcr_certificate_get_subject_cn (GcrCertificate *self)
-{
- return gcr_certificate_get_subject_part (self, "cn");
-}
-
-/**
- * gcr_certificate_get_subject_part:
- * @self: a #GcrCertificate
- * @part: a DN type string or OID.
- *
- * Get a part of the DN of the subject of this certificate.
- *
- * Examples of a @part might be the 'OU' (organizational unit)
- * or the 'CN' (common name). Only the value of that part
- * of the DN is returned.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: (allow-none): the allocated part of the subject DN, or %NULL if no
- * such part is present.
- */
-gchar*
-gcr_certificate_get_subject_part (GcrCertificate *self, const char *part)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (part != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_dn_read_part (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", "rdnSequence", NULL), part);
-}
-
-/**
- * gcr_certificate_get_subject_dn:
- * @self: a #GcrCertificate
- *
- * Get the full subject DN of the certificate as a (mostly)
- * readable string.
- *
- * The string returned should be freed by the caller when no longer
- * required.
- *
- * Returns: The allocated subject DN of the certificate.
- */
-gchar*
-gcr_certificate_get_subject_dn (GcrCertificate *self)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_dn_read (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", "rdnSequence", NULL));
-}
-
-static gconstpointer
-_gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", NULL), n_data);
-}
-
-/**
- * gcr_certificate_get_subject_raw:
- * @self: a #GcrCertificate
- * @n_data: The length of the returned data.
- *
- * Get the raw DER data for the subject DN of the certificate.
- *
- * The data should be freed by using g_free() when no longer required.
- *
- * Returns: (transfer full) (array length=n_data): allocated memory containing
- * the raw subject
- */
-guchar *
-gcr_certificate_get_subject_raw (GcrCertificate *self, gsize *n_data)
-{
- GcrCertificateInfo *info;
- gconstpointer data;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- data = _gcr_certificate_get_subject_const (self, n_data);
- return g_memdup (data, data ? *n_data : 0);
-}
-
-/**
- * gcr_certificate_get_issued_date:
- * @self: a #GcrCertificate
- *
- * Get the issued date of this certificate.
- *
- * The #GDate returned should be freed by the caller using
- * g_date_free() when no longer required.
- *
- * Returns: An allocated issued date of this certificate.
- */
-GDate*
-gcr_certificate_get_issued_date (GcrCertificate *self)
-{
- GcrCertificateInfo *info;
- GDate *date;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- date = g_date_new ();
- if (!egg_asn1x_get_time_as_date (egg_asn1x_node (info->asn1, "tbsCertificate", "validity", "notBefore", NULL), date)) {
- g_date_free (date);
- return NULL;
- }
-
- return date;
-}
-
-/**
- * gcr_certificate_get_expiry_date:
- * @self: a #GcrCertificate
- *
- * Get the expiry date of this certificate.
- *
- * The #GDate returned should be freed by the caller using
- * g_date_free() when no longer required.
- *
- * Returns: An allocated expiry date of this certificate.
- */
-GDate*
-gcr_certificate_get_expiry_date (GcrCertificate *self)
-{
- GcrCertificateInfo *info;
- GDate *date;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- date = g_date_new ();
- if (!egg_asn1x_get_time_as_date (egg_asn1x_node (info->asn1, "tbsCertificate", "validity", "notAfter", NULL), date)) {
- g_date_free (date);
- return NULL;
- }
-
- return date;
-}
-
-/**
- * gcr_certificate_get_key_size:
- * @self: a #GcrCertificate
- *
- * Get the key size in bits of the public key represented
- * by this certificate.
- *
- * Returns: The key size of the certificate.
- */
-guint
-gcr_certificate_get_key_size (GcrCertificate *self)
-{
- GcrCertificateInfo *info;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), 0);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, 0);
-
- if (!info->key_size)
- info->key_size = calculate_key_size (info);
-
- return info->key_size;
-}
-
-/**
- * gcr_certificate_get_fingerprint:
- * @self: a #GcrCertificate
- * @type: the type of algorithm for the fingerprint.
- * @n_length: The length of the resulting fingerprint.
- *
- * Calculate the fingerprint for this certificate.
- *
- * You can pass G_CHECKSUM_SHA1 or G_CHECKSUM_MD5 as the @type
- * parameter.
- *
- * The caller should free the returned data using g_free() when
- * it is no longer required.
- *
- * Returns: (array length=n_length): the raw binary fingerprint
- **/
-guchar *
-gcr_certificate_get_fingerprint (GcrCertificate *self, GChecksumType type, gsize *n_length)
-{
- GChecksum *sum;
- guchar *digest;
- gssize length;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_length != NULL, NULL);
-
- sum = digest_certificate (self, type);
- g_return_val_if_fail (sum, NULL);
- length = g_checksum_type_get_length (type);
- g_return_val_if_fail (length > 0, NULL);
- digest = g_malloc (length);
- *n_length = length;
- g_checksum_get_digest (sum, digest, n_length);
- g_checksum_free (sum);
-
- return digest;
-}
-
-/**
- * gcr_certificate_get_fingerprint_hex:
- * @self: a #GcrCertificate
- * @type: the type of algorithm for the fingerprint.
- *
- * Calculate the fingerprint for this certificate, and return it
- * as a hex string.
- *
- * You can pass G_CHECKSUM_SHA1 or G_CHECKSUM_MD5 as the @type
- * parameter.
- *
- * The caller should free the returned data using g_free() when
- * it is no longer required.
- *
- * Returns: an allocated hex string which contains the fingerprint.
- */
-gchar*
-gcr_certificate_get_fingerprint_hex (GcrCertificate *self, GChecksumType type)
-{
- GChecksum *sum;
- guchar *digest;
- gsize n_digest;
- gssize length;
- gchar *hex;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- sum = digest_certificate (self, type);
- g_return_val_if_fail (sum, NULL);
- length = g_checksum_type_get_length (type);
- g_return_val_if_fail (length > 0, NULL);
- digest = g_malloc (length);
- n_digest = length;
- g_checksum_get_digest (sum, digest, &n_digest);
- hex = egg_hex_encode_full (digest, n_digest, TRUE, ' ', 1);
- g_checksum_free (sum);
- g_free (digest);
- return hex;
-}
-
-/**
- * gcr_certificate_get_serial_number:
- * @self: a #GcrCertificate
- * @n_length: the length of the returned data.
- *
- * Get the raw binary serial number of the certificate.
- *
- * The caller should free the returned data using g_free() when
- * it is no longer required.
- *
- * Returns: (array length=n_length): the raw binary serial number.
- */
-guchar *
-gcr_certificate_get_serial_number (GcrCertificate *self, gsize *n_length)
-{
- GcrCertificateInfo *info;
- const guchar *serial;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_length != NULL, NULL);
-
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
-
- serial = egg_asn1x_get_integer_as_raw (egg_asn1x_node (info->asn1, "tbsCertificate", "serialNumber", NULL), n_length);
- return g_memdup (serial, *n_length);
-}
-
-/**
- * gcr_certificate_get_serial_number_hex:
- * @self: a #GcrCertificate
- *
- * Get the serial number of the certificate as a hex string.
- *
- * The caller should free the returned data using g_free() when
- * it is no longer required.
- *
- * Returns: an allocated string containing the serial number as hex.
- */
-gchar*
-gcr_certificate_get_serial_number_hex (GcrCertificate *self)
-{
- guchar *serial;
- gsize n_serial;
- gchar *hex;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
-
- serial = gcr_certificate_get_serial_number (self, &n_serial);
- if (serial == NULL)
- return NULL;
-
- hex = egg_hex_encode (serial, n_serial);
- g_free (serial);
- return hex;
-}
-
-/**
- * gcr_certificate_get_icon:
- * @self: The certificate
- *
- * Get the icon for a certificate.
- *
- * Returns: (transfer full): the icon for this certificate, which should be
- * released with g_object_unref()
- */
-GIcon *
-gcr_certificate_get_icon (GcrCertificate *self)
-{
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), FALSE);
- return g_themed_icon_new (GCR_ICON_CERTIFICATE);
-}
-
-/* -----------------------------------------------------------------------------
- * MIXIN
- */
-
-/**
- * GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE:
- *
- * Implement the GcrComparable interface. Use this macro like this:
- *
- * <informalexample><programlisting>
- * G_DEFINE_TYPE_WITH_CODE (MyCertificate, my_certificate, G_TYPE_OBJECT,
- * GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
- * G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, my_certificate_iface_init);
- * );
- * </programlisting></informalexample>
- */
-
-/**
- * gcr_certificate_mixin_comparable_init: (skip)
- * @iface: The interface
- *
- * Initialize a #GcrComparableIface to compare the current certificate.
- * In general it's easier to use the GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE()
- * macro instead of this function.
- */
-void
-gcr_certificate_mixin_comparable_init (GcrComparableIface *iface)
-{
- iface->compare = gcr_certificate_compare;
-}
-
-/**
- * gcr_certificate_mixin_class_init: (skip)
- * @object_class: The GObjectClass for this class
- *
- * Initialize the certificate mixin for the class. This mixin implements the
- * various required properties for the certificate.
- *
- * Call this function near the end of your derived class_init function. The
- * derived class must implement the #GcrCertificate interface.
- */
-void
-gcr_certificate_mixin_class_init (GObjectClass *object_class)
-{
- if (!g_object_class_find_property (object_class, "description"))
- g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
- if (!g_object_class_find_property (object_class, "markup"))
- g_object_class_override_property (object_class, PROP_MARKUP, "markup");
- if (!g_object_class_find_property (object_class, "label"))
- g_object_class_override_property (object_class, PROP_LABEL, "label");
- if (!g_object_class_find_property (object_class, "icon"))
- g_object_class_override_property (object_class, PROP_ICON, "icon");
- if (!g_object_class_find_property (object_class, "subject"))
- g_object_class_override_property (object_class, PROP_SUBJECT, "subject");
- if (!g_object_class_find_property (object_class, "issuer"))
- g_object_class_override_property (object_class, PROP_ISSUER, "issuer");
- if (!g_object_class_find_property (object_class, "expiry"))
- g_object_class_override_property (object_class, PROP_EXPIRY, "expiry");
-
- _gcr_initialize_library ();
-}
-
-/**
- * gcr_certificate_mixin_get_property: (skip)
- * @obj: The object
- * @prop_id: The property id
- * @value: The value to fill in.
- * @pspec: The param specification.
- *
- * Implementation to get various required certificate properties. This should
- * be called from your derived class get_property function, or used as a
- * get_property virtual function.
- *
- * Example of use as called from derived class get_property function:
- *
- * <informalexample><programlisting>
- * static void
- * my_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec)
- * {
- * switch (prop_id) {
- *
- * ...
- *
- * default:
- * gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
- * break;
- * }
- *}
- * </programlisting></informalexample>
- *
- * Example of use as get_property function:
- *
- * <informalexample><programlisting>
- * static void
- * my_class_init (MyClass *klass)
- * {
- * GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- * gobject_class->get_property = gcr_certificate_mixin_get_property;
- *
- * ...
- * }
- * </programlisting></informalexample>
-
- */
-void
-gcr_certificate_mixin_get_property (GObject *obj, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- GcrCertificate *cert = GCR_CERTIFICATE (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, gcr_certificate_get_subject_cn (cert));
- break;
- case PROP_SUBJECT:
- g_value_take_string (value, gcr_certificate_get_subject_cn (cert));
- break;
- case PROP_ICON:
- g_value_set_object (value, gcr_certificate_get_icon (cert));
- break;
- case PROP_DESCRIPTION:
- g_value_set_string (value, _("Certificate"));
- break;
- case PROP_MARKUP:
- g_value_take_string (value, calculate_markup (cert));
- break;
- case PROP_ISSUER:
- g_value_take_string (value, gcr_certificate_get_issuer_cn (cert));
- break;
- case PROP_EXPIRY:
- g_value_take_boxed (value, gcr_certificate_get_expiry_date (cert));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
diff --git a/gcr/gcr-certificate.h b/gcr/gcr-certificate.h
deleted file mode 100644
index d60be227..00000000
--- a/gcr/gcr-certificate.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_CERTIFICATE_H__
-#define __GCR_CERTIFICATE_H__
-
-#include "gcr-types.h"
-#include "gcr-column.h"
-#include "gcr-comparable.h"
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GCR_CERTIFICATE_COLUMNS (gcr_certificate_get_columns ())
-#define GCR_TYPE_CERTIFICATE (gcr_certificate_get_type ())
-#define GCR_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE, GcrCertificate))
-#define GCR_IS_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE))
-#define GCR_CERTIFICATE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_CERTIFICATE, GcrCertificateIface))
-
-typedef struct _GcrCertificate GcrCertificate;
-typedef struct _GcrCertificateIface GcrCertificateIface;
-
-struct _GcrCertificateIface {
- GTypeInterface parent;
-
- const guchar * (*get_der_data) (GcrCertificate *self,
- gsize *n_data);
-
- /*< private >*/
- gpointer dummy1;
- gpointer dummy2;
- gpointer dummy3;
- gpointer dummy5;
- gpointer dummy6;
- gpointer dummy7;
- gpointer dummy8;
-};
-
-GType gcr_certificate_get_type (void);
-
-const guchar * gcr_certificate_get_der_data (GcrCertificate *self,
- gsize *n_data);
-
-const GcrColumn* gcr_certificate_get_columns (void);
-
-gint gcr_certificate_compare (GcrComparable *first,
- GcrComparable *other);
-
-gchar* gcr_certificate_get_issuer_cn (GcrCertificate *self);
-
-gchar* gcr_certificate_get_issuer_dn (GcrCertificate *self);
-
-gchar* gcr_certificate_get_issuer_part (GcrCertificate *self,
- const gchar *part);
-
-guchar * gcr_certificate_get_issuer_raw (GcrCertificate *self,
- gsize *n_data);
-
-gboolean gcr_certificate_is_issuer (GcrCertificate *self,
- GcrCertificate *issuer);
-
-gchar* gcr_certificate_get_subject_cn (GcrCertificate *self);
-
-gchar* gcr_certificate_get_subject_dn (GcrCertificate *self);
-
-gchar* gcr_certificate_get_subject_part (GcrCertificate *self,
- const gchar *part);
-
-guchar * gcr_certificate_get_subject_raw (GcrCertificate *self,
- gsize *n_data);
-
-GDate* gcr_certificate_get_issued_date (GcrCertificate *self);
-
-GDate* gcr_certificate_get_expiry_date (GcrCertificate *self);
-
-guchar* gcr_certificate_get_serial_number (GcrCertificate *self,
- gsize *n_length);
-
-gchar* gcr_certificate_get_serial_number_hex (GcrCertificate *self);
-
-guint gcr_certificate_get_key_size (GcrCertificate *self);
-
-guchar* gcr_certificate_get_fingerprint (GcrCertificate *self,
- GChecksumType type,
- gsize *n_length);
-
-gchar* gcr_certificate_get_fingerprint_hex (GcrCertificate *self,
- GChecksumType type);
-
-GIcon* gcr_certificate_get_icon (GcrCertificate *self);
-
-#define GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE() \
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COMPARABLE, gcr_certificate_mixin_comparable_init)
-
-void gcr_certificate_mixin_comparable_init (GcrComparableIface *iface);
-
-void gcr_certificate_mixin_class_init (GObjectClass *object_class);
-
-void gcr_certificate_mixin_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-G_END_DECLS
-
-#endif /* __GCR_CERTIFICATE_H__ */
diff --git a/gcr/gcr-collection-model.c b/gcr/gcr-collection-model.c
deleted file mode 100644
index 79493e08..00000000
--- a/gcr/gcr-collection-model.c
+++ /dev/null
@@ -1,1575 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection-model.h"
-
-#include <gtk/gtk.h>
-
-#include <string.h>
-#include <unistd.h>
-
-/**
- * SECTION:gcr-collection-model
- * @title: GcrCollectionModel
- * @short_description: A GtkTreeModel that represents a collection
- *
- * This is an implementation of #GtkTreeModel which represents the objects in
- * the a #GcrCollection. As objects are added or removed from the collection,
- * rows are added and removed from this model.
- *
- * The row values come from the properties of the objects in the collection. Use
- * gcr_collection_model_new() to create a new collection model. To have more
- * control over the values use a set of #GcrColumn structures to define the
- * columns. This can be done with gcr_collection_model_new_full() or
- * gcr_collection_model_set_columns().
- *
- * Each row can have a selected state, which is represented by a boolean column.
- * The selected state can be toggled with gcr_collection_model_toggle_selected()
- * or set with gcr_collection_model_set_selected_objects() and retrieved with
- * gcr_collection_model_get_selected_objects().
- *
- * To determine which object a row represents and vice versa, use the
- * gcr_collection_model_iter_for_object() or gcr_collection_model_object_for_iter()
- * functions.
- */
-
-/**
- * GcrCollectionModel:
- *
- * A #GtkTreeModel which contains a row for each object in a #GcrCollection.
- */
-
-/**
- * GcrCollectionModelClass:
- * @parent_class: The parent class
- *
- * The class for #GcrCollectionModel.
- */
-
-#define COLLECTION_MODEL_STAMP 0xAABBCCDD
-
-enum {
- PROP_0,
- PROP_COLLECTION,
- PROP_COLUMNS
-};
-
-typedef struct {
- GObject *object;
- GSequenceIter *parent;
- GSequence *children;
-} GcrCollectionRow;
-
-typedef struct {
- GtkTreeIterCompareFunc sort_func;
- gpointer user_data;
- GDestroyNotify destroy_func;
-} GcrCollectionSortClosure;
-
-typedef struct _GcrCollectionColumn {
- gchar *property;
- GType *type;
- GtkTreeIterCompareFunc sort_func;
- gpointer sort_data;
- GDestroyNotify sort_destroy;
-} GcrCollectionColumn;
-
-struct _GcrCollectionModelPrivate {
- GcrCollection *collection;
- GHashTable *selected;
- GSequence *root_sequence;
- GHashTable *object_to_seq;
-
- const GcrColumn *columns;
- guint n_columns;
-
- /* Sort information */
- gint sort_column_id;
- GtkSortType sort_order_type;
- GcrCollectionSortClosure *column_sort_closures;
- GcrCollectionSortClosure default_sort_closure;
-
- /* Sequence ordering information */
- GCompareDataFunc order_current;
- gpointer order_argument;
-};
-
-/* Forward declarations */
-static void gcr_collection_model_tree_model_init (GtkTreeModelIface *iface);
-static void gcr_collection_model_tree_sortable_init (GtkTreeSortableIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GcrCollectionModel, gcr_collection_model, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, gcr_collection_model_tree_model_init)
- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE, gcr_collection_model_tree_sortable_init)
-);
-
-typedef gint (*CompareValueFunc) (const GValue *va,
- const GValue *vb);
-
-static gint
-compare_int_value (const GValue *va,
- const GValue *vb)
-{
- gint a = g_value_get_int (va);
- gint b = g_value_get_int (vb);
- if (a > b) return 1;
- else if (a < b) return -1;
- return 0;
-}
-
-static gint
-compare_uint_value (const GValue *va,
- const GValue *vb)
-{
- guint a = g_value_get_uint (va);
- guint b = g_value_get_uint (vb);
- if (a > b) return 1;
- else if (a < b) return -1;
- return 0;
-}
-
-static gint
-compare_long_value (const GValue *va,
- const GValue *vb)
-{
- glong a = g_value_get_long (va);
- glong b = g_value_get_long (vb);
- if (a > b) return 1;
- else if (a < b) return -1;
- return 0;
-}
-
-static gint
-compare_ulong_value (const GValue *va,
- const GValue *vb)
-{
- gulong a = g_value_get_ulong (va);
- gulong b = g_value_get_ulong (vb);
- if (a > b) return 1;
- else if (a < b) return -1;
- return 0;
-}
-
-static gint
-compare_string_value (const GValue *va,
- const GValue *vb)
-{
- const gchar *a = g_value_get_string (va);
- const gchar *b = g_value_get_string (vb);
- gchar *case_a;
- gchar *case_b;
- gboolean ret;
-
- if (a == b)
- return 0;
- else if (!a)
- return -1;
- else if (!b)
- return 1;
-
- case_a = g_utf8_casefold (a, -1);
- case_b = g_utf8_casefold (b, -1);
- ret = g_utf8_collate (case_a, case_b);
- g_free (case_a);
- g_free (case_b);
-
- return ret;
-}
-
-static gint
-compare_date_value (const GValue *va,
- const GValue *vb)
-{
- GDate *a = g_value_get_boxed (va);
- GDate *b = g_value_get_boxed (vb);
-
- if (a == b)
- return 0;
- else if (!a)
- return -1;
- else if (!b)
- return 1;
- else
- return g_date_compare (a, b);
-}
-
-static CompareValueFunc
-lookup_compare_func (GType type)
-{
- switch (type) {
- case G_TYPE_INT:
- return compare_int_value;
- case G_TYPE_UINT:
- return compare_uint_value;
- case G_TYPE_LONG:
- return compare_long_value;
- case G_TYPE_ULONG:
- return compare_ulong_value;
- case G_TYPE_STRING:
- return compare_string_value;
- }
-
- if (type == G_TYPE_DATE)
- return compare_date_value;
-
- return NULL;
-}
-
-static gint
-order_sequence_by_closure (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (user_data);
- GcrCollectionSortClosure *closure = self->pv->order_argument;
- const GcrCollectionRow *row_a = a;
- const GcrCollectionRow *row_b = b;
- GtkTreeIter iter_a;
- GtkTreeIter iter_b;
-
- g_assert (closure);
- g_assert (closure->sort_func);
-
- if (!gcr_collection_model_iter_for_object (self, row_a->object, &iter_a))
- g_return_val_if_reached (0);
- if (!gcr_collection_model_iter_for_object (self, row_b->object, &iter_b))
- g_return_val_if_reached (0);
-
- return (closure->sort_func) (GTK_TREE_MODEL (self),
- &iter_a, &iter_b, closure->user_data);
-}
-
-static gint
-order_sequence_by_closure_reverse (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- return 0 - order_sequence_by_closure (a, b, user_data);
-}
-
-static gint
-order_sequence_as_unsorted (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- const GcrCollectionRow *row_a = a;
- const GcrCollectionRow *row_b = b;
- return GPOINTER_TO_INT (row_a->object) - GPOINTER_TO_INT (row_b->object);
-}
-
-static gint
-order_sequence_as_unsorted_reverse (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- const GcrCollectionRow *row_a = a;
- const GcrCollectionRow *row_b = b;
- return GPOINTER_TO_INT (row_b->object) - GPOINTER_TO_INT (row_a->object);
-}
-
-static void
-lookup_object_property (GObject *object,
- const gchar *property_name,
- GValue *value)
-{
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name))
- g_object_get_property (object, property_name, value);
-
- /* Other types have sane defaults */
- else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
- g_value_set_string (value, "");
-}
-
-static gint
-order_sequence_by_property (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- const GcrCollectionRow *row_a = a;
- const GcrCollectionRow *row_b = b;
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (user_data);
- const GcrColumn *column = self->pv->order_argument;
- GValue value_a = { 0, };
- GValue value_b = { 0, };
- CompareValueFunc compare;
- gint ret;
-
- g_assert (column);
-
- /* Sort according to property values */
- column = &self->pv->columns[self->pv->sort_column_id];
- g_value_init (&value_a, column->property_type);
- lookup_object_property (row_a->object, column->property_name, &value_a);
- g_value_init (&value_b, column->property_type);
- lookup_object_property (row_b->object, column->property_name, &value_b);
-
- compare = lookup_compare_func (column->property_type);
- g_assert (compare != NULL);
-
- ret = (compare) (&value_a, &value_b);
-
- g_value_unset (&value_a);
- g_value_unset (&value_b);
-
- return ret;
-}
-
-static gint
-order_sequence_by_property_reverse (gconstpointer a,
- gconstpointer b,
- gpointer user_data)
-{
- return 0 - order_sequence_by_property (a, b, user_data);
-}
-
-static GHashTable*
-selected_hash_table_new (void)
-{
- return g_hash_table_new (g_direct_hash, g_direct_equal);
-}
-
-static gboolean
-sequence_iter_to_tree (GcrCollectionModel *self,
- GSequenceIter *seq,
- GtkTreeIter *iter)
-{
- GcrCollectionRow *row;
-
- g_return_val_if_fail (seq != NULL, FALSE);
-
- if (g_sequence_iter_is_end (seq))
- return FALSE;
-
- row = g_sequence_get (seq);
- g_return_val_if_fail (row != NULL && G_IS_OBJECT (row->object), FALSE);
-
- memset (iter, 0, sizeof (*iter));
- iter->stamp = COLLECTION_MODEL_STAMP;
- iter->user_data = row->object;
- iter->user_data2 = seq;
- return TRUE;
-}
-
-static GSequenceIter *
-sequence_iter_for_tree (GcrCollectionModel *self,
- GtkTreeIter *iter)
-{
- g_return_val_if_fail (iter != NULL, NULL);
- g_return_val_if_fail (iter->stamp == COLLECTION_MODEL_STAMP, NULL);
- return iter->user_data2;
-}
-
-static GtkTreePath *
-sequence_iter_to_path (GcrCollectionModel *self,
- GSequenceIter *seq)
-{
- GcrCollectionRow *row;
- GtkTreePath *path;
-
- path = gtk_tree_path_new ();
- while (seq) {
- gtk_tree_path_prepend_index (path, g_sequence_iter_get_position (seq));
- row = g_sequence_get (seq);
- seq = row->parent;
- }
- return path;
-}
-
-static GSequence *
-child_sequence_for_tree (GcrCollectionModel *self,
- GtkTreeIter *iter)
-{
- GcrCollectionRow *row;
- GSequenceIter *seq;
-
- if (iter == NULL) {
- return self->pv->root_sequence;
- } else {
- seq = sequence_iter_for_tree (self, iter);
- g_return_val_if_fail (seq != NULL, NULL);
- row = g_sequence_get (seq);
- return row->children;
- }
-}
-
-static void
-on_object_notify (GObject *object, GParamSpec *spec, GcrCollectionModel *self)
-{
- GtkTreeIter iter;
- GtkTreePath *path;
- gboolean found = FALSE;
- guint i;
-
- g_return_if_fail (spec->name);
-
- for (i = 0; i < self->pv->n_columns - 1; ++i) {
- g_assert (self->pv->columns[i].property_name);
- if (g_str_equal (self->pv->columns[i].property_name, spec->name)) {
- found = TRUE;
- break;
- }
- }
-
- /* Tell the tree view that this row changed */
- if (found) {
- if (!gcr_collection_model_iter_for_object (self, object, &iter))
- g_return_if_reached ();
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), &iter);
- g_return_if_fail (path);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (self), path, &iter);
- gtk_tree_path_free (path);
- }
-}
-
-static void
-on_object_gone (gpointer unused, GObject *was_object)
-{
- g_warning ("object contained in GcrCollection and included in GcrCollectionModel "
- "was destroyed before it was removed from the collection");
-}
-
-static void on_collection_added (GcrCollection *collection,
- GObject *object,
- gpointer user_data);
-
-static void on_collection_removed (GcrCollection *collection,
- GObject *object,
- gpointer user_data);
-
-static void add_object_to_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GSequenceIter *parent,
- GObject *object,
- gboolean emit);
-
-static void remove_object_from_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GSequenceIter *seq,
- GObject *object,
- gboolean emit);
-
-static void
-add_children_to_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GSequenceIter *parent,
- GcrCollection *collection,
- gboolean emit)
-{
- GList *children, *l;
-
- children = gcr_collection_get_objects (collection);
- for (l = children; l; l = g_list_next (l))
- add_object_to_sequence (self, sequence, parent, l->data, emit);
- g_list_free (children);
-
- /* Now listen in for any changes */
- g_signal_connect_after (collection, "added", G_CALLBACK (on_collection_added), self);
- g_signal_connect_after (collection, "removed", G_CALLBACK (on_collection_removed), self);
-}
-
-static void
-add_object_to_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GSequenceIter *parent,
- GObject *object,
- gboolean emit)
-{
- GcrCollectionRow *row;
- GSequenceIter *seq;
- GtkTreeIter iter;
- GtkTreePath *path;
-
- g_assert (GCR_IS_COLLECTION_MODEL (self));
- g_assert (G_IS_OBJECT (object));
- g_assert (self->pv->order_current);
-
- if (g_hash_table_lookup (self->pv->object_to_seq, object)) {
- g_warning ("object was already added to the GcrCollectionModel. Perhaps "
- "a loop exists in a tree structure?");
- return;
- }
-
- row = g_slice_new0 (GcrCollectionRow);
- row->object = object;
- row->parent = parent;
- row->children = NULL;
-
- seq = g_sequence_insert_sorted (sequence, row, self->pv->order_current, self);
- g_hash_table_insert (self->pv->object_to_seq, object, seq);
- g_object_weak_ref (G_OBJECT (object), (GWeakNotify)on_object_gone, self);
- g_signal_connect (object, "notify", G_CALLBACK (on_object_notify), self);
-
- if (emit) {
- if (!sequence_iter_to_tree (self, seq, &iter))
- g_assert_not_reached ();
- path = sequence_iter_to_path (self, seq);
- g_assert (path != NULL);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (self), path, &iter);
- gtk_tree_path_free (path);
- }
-
- if (GCR_IS_COLLECTION (object)) {
- row->children = g_sequence_new (NULL);
- add_children_to_sequence (self, row->children, seq,
- GCR_COLLECTION (object), emit);
- }
-}
-
-static void
-on_collection_added (GcrCollection *collection,
- GObject *object,
- gpointer user_data)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (user_data);
- GSequence *sequence;
- GSequenceIter *parent;
- GcrCollectionRow *row;
-
- if (collection == self->pv->collection) {
- sequence = self->pv->root_sequence;
- parent = NULL;
- } else {
- parent = g_hash_table_lookup (self->pv->object_to_seq, G_OBJECT (collection));
- row = g_sequence_get (parent);
- g_assert (row->children);
- sequence = row->children;
- }
-
- add_object_to_sequence (self, sequence, parent, object, TRUE);
-}
-
-static void
-remove_children_from_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GcrCollection *collection,
- gboolean emit)
-{
- GSequenceIter *seq, *next;
- GcrCollectionRow *row;
-
- g_signal_handlers_disconnect_by_func (collection, on_collection_added, self);
- g_signal_handlers_disconnect_by_func (collection, on_collection_removed, self);
-
- for (seq = g_sequence_get_begin_iter (sequence);
- !g_sequence_iter_is_end (seq); seq = next) {
- next = g_sequence_iter_next (seq);
- row = g_sequence_get (seq);
- remove_object_from_sequence (self, sequence, seq, row->object, emit);
- }
-}
-
-static void
-remove_object_from_sequence (GcrCollectionModel *self,
- GSequence *sequence,
- GSequenceIter *seq,
- GObject *object,
- gboolean emit)
-{
- GcrCollectionRow *row;
- GtkTreePath *path = NULL;
-
- if (emit) {
- path = sequence_iter_to_path (self, seq);
- g_assert (path != NULL);
- }
-
- row = g_sequence_get (seq);
- g_assert (row->object == object);
-
- g_object_weak_unref (object, on_object_gone, self);
- g_signal_handlers_disconnect_by_func (object, on_object_notify, self);
-
- if (row->children) {
- g_assert (GCR_IS_COLLECTION (object));
- remove_children_from_sequence (self, row->children, GCR_COLLECTION (object), emit);
- g_assert (g_sequence_get_length (row->children) == 0);
- g_sequence_free (row->children);
- row->children = NULL;
- }
-
- if (self->pv->selected)
- g_hash_table_remove (self->pv->selected, object);
- if (!g_hash_table_remove (self->pv->object_to_seq, object))
- g_assert_not_reached ();
-
- g_sequence_remove (seq);
- g_slice_free (GcrCollectionRow, row);
-
- /* Fire signal for this removed row */
- if (path != NULL) {
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), path);
- gtk_tree_path_free (path);
- }
-
-}
-
-static void
-on_collection_removed (GcrCollection *collection,
- GObject *object,
- gpointer user_data)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (user_data);
- GSequenceIter *seq;
- GSequence *sequence;
-
- seq = g_hash_table_lookup (self->pv->object_to_seq, object);
- g_return_if_fail (seq != NULL);
-
- sequence = g_sequence_iter_get_sequence (seq);
- g_assert (sequence != NULL);
-
- remove_object_from_sequence (self, sequence, seq, object, TRUE);
-}
-
-static void
-free_owned_columns (gpointer data)
-{
- GcrColumn *columns;
- g_assert (data);
-
- /* Only the property column is in use */
- for (columns = data; columns->property_name; ++columns)
- g_free ((gchar*)columns->property_name);
- g_free (data);
-}
-
-static GtkTreeModelFlags
-gcr_collection_model_real_get_flags (GtkTreeModel *model)
-{
- return GTK_TREE_MODEL_ITERS_PERSIST;
-}
-
-static gint
-gcr_collection_model_real_get_n_columns (GtkTreeModel *model)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- return self->pv->n_columns;
-}
-
-static GType
-gcr_collection_model_real_get_column_type (GtkTreeModel *model,
- gint column_id)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- g_return_val_if_fail (column_id >= 0 && column_id <= self->pv->n_columns, 0);
-
- /* The last is the selected column */
- if (column_id == self->pv->n_columns)
- return G_TYPE_BOOLEAN;
-
- return self->pv->columns[column_id].column_type;
-}
-
-static gboolean
-gcr_collection_model_real_get_iter (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- const gint *indices;
- GSequence *sequence;
- GSequenceIter *seq;
- GcrCollectionRow *row;
- gint count;
- gint i;
-
- sequence = self->pv->root_sequence;
- seq = NULL;
-
- indices = gtk_tree_path_get_indices_with_depth (path, &count);
- if (count == 0)
- return FALSE;
-
- for (i = 0; i < count; i++) {
- if (!sequence)
- return FALSE;
- seq = g_sequence_get_iter_at_pos (sequence, indices[i]);
- if (g_sequence_iter_is_end (seq))
- return FALSE;
- row = g_sequence_get (seq);
- sequence = row->children;
- }
-
- return sequence_iter_to_tree (self, seq, iter);
-}
-
-static GtkTreePath*
-gcr_collection_model_real_get_path (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequenceIter *seq;
-
- if (iter == NULL)
- return gtk_tree_path_new ();
-
- seq = sequence_iter_for_tree (self, iter);
- g_return_val_if_fail (seq != NULL, NULL);
- return sequence_iter_to_path (self, seq);
-}
-
-static void
-gcr_collection_model_real_get_value (GtkTreeModel *model,
- GtkTreeIter *iter,
- gint column_id,
- GValue *value)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GObject *object;
- GValue original;
- const GcrColumn *column;
- GParamSpec *spec;
-
- object = gcr_collection_model_object_for_iter (self, iter);
- g_return_if_fail (G_IS_OBJECT (object));
- g_return_if_fail (column_id >= 0 && column_id < self->pv->n_columns);
-
- /* The selected column? Last one */
- if (column_id == self->pv->n_columns - 1) {
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, gcr_collection_model_is_selected (self, iter));
- return;
- }
-
- /* Figure out which property */
- column = &self->pv->columns[column_id];
- g_assert (column->property_name);
- g_value_init (value, column->column_type);
-
- /* Lookup the property on the object */
- spec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), column->property_name);
- if (spec != NULL) {
- /* A transformer is specified, or mismatched types */
- if (column->transformer || column->column_type != column->property_type) {
- memset (&original, 0, sizeof (original));
- g_value_init (&original, column->property_type);
- g_object_get_property (object, column->property_name, &original);
-
- if (column->transformer) {
- (column->transformer) (&original, value);
- } else {
- g_warning ("%s property of %s class was of type %s instead of type %s"
- " and cannot be converted due to lack of transformer",
- column->property_name, G_OBJECT_TYPE_NAME (object),
- g_type_name (column->property_type),
- g_type_name (column->column_type));
- spec = NULL;
- }
-
- /* Simple, no transformation necessary */
- } else {
- g_object_get_property (object, column->property_name, value);
- }
- }
-
- if (spec == NULL) {
-
- /* All the number types have sane defaults */
- if (column->column_type == G_TYPE_STRING)
- g_value_set_string (value, "");
- }
-}
-
-static gboolean
-gcr_collection_model_real_iter_next (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequenceIter *seq = sequence_iter_for_tree (self, iter);
- g_return_val_if_fail (seq != NULL, FALSE);
- return sequence_iter_to_tree (self, g_sequence_iter_next (seq), iter);
-}
-
-static gboolean
-gcr_collection_model_real_iter_children (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreeIter *parent)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequence *sequence = child_sequence_for_tree (self, parent);
- return sequence && sequence_iter_to_tree (self, g_sequence_get_begin_iter (sequence), iter);
-}
-
-static gboolean
-gcr_collection_model_real_iter_has_child (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequence *sequence = child_sequence_for_tree (self, iter);
- return sequence && !g_sequence_iter_is_end (g_sequence_get_begin_iter (sequence));
-}
-
-static gint
-gcr_collection_model_real_iter_n_children (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequence *sequence = child_sequence_for_tree (self, iter);
- return sequence ? g_sequence_get_length (sequence) : 0;
-}
-
-static gboolean
-gcr_collection_model_real_iter_nth_child (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequence *sequence;
- GSequenceIter *seq;
-
- sequence = child_sequence_for_tree (self, parent);
- if (sequence == NULL)
- return FALSE;
- seq = g_sequence_get_iter_at_pos (sequence, n);
- return sequence_iter_to_tree (self, seq, iter);
-}
-
-static gboolean
-gcr_collection_model_real_iter_parent (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreeIter *child)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (model);
- GSequenceIter *seq;
- GcrCollectionRow *row;
-
- seq = sequence_iter_for_tree (self, child);
- g_return_val_if_fail (seq != NULL, FALSE);
- row = g_sequence_get (seq);
- if (row->parent == NULL)
- return FALSE;
- return sequence_iter_to_tree (self, row->parent, iter);
-}
-
-static void
-gcr_collection_model_real_ref_node (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- /* Nothing to do */
-}
-
-static void
-gcr_collection_model_real_unref_node (GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- /* Nothing to do */
-}
-
-static void
-gcr_collection_model_tree_model_init (GtkTreeModelIface *iface)
-{
- iface->get_flags = gcr_collection_model_real_get_flags;
- iface->get_n_columns = gcr_collection_model_real_get_n_columns;
- iface->get_column_type = gcr_collection_model_real_get_column_type;
- iface->get_iter = gcr_collection_model_real_get_iter;
- iface->get_path = gcr_collection_model_real_get_path;
- iface->get_value = gcr_collection_model_real_get_value;
- iface->iter_next = gcr_collection_model_real_iter_next;
- iface->iter_children = gcr_collection_model_real_iter_children;
- iface->iter_has_child = gcr_collection_model_real_iter_has_child;
- iface->iter_n_children = gcr_collection_model_real_iter_n_children;
- iface->iter_nth_child = gcr_collection_model_real_iter_nth_child;
- iface->iter_parent = gcr_collection_model_real_iter_parent;
- iface->ref_node = gcr_collection_model_real_ref_node;
- iface->unref_node = gcr_collection_model_real_unref_node;
-}
-
-static void
-collection_resort_sequence (GcrCollectionModel *self,
- GSequenceIter *parent,
- GSequence *sequence)
-{
- GPtrArray *previous;
- GSequenceIter *seq, *next;
- gint *new_order;
- GtkTreePath *path;
- GtkTreeIter iter;
- GcrCollectionRow *row;
- gint index;
- gint i;
-
- /* Make note of how things stand, and at same time resort all kids */
- previous = g_ptr_array_new ();
- for (seq = g_sequence_get_begin_iter (sequence);
- !g_sequence_iter_is_end (seq); seq = next) {
- next = g_sequence_iter_next (seq);
- row = g_sequence_get (seq);
- if (row->children)
- collection_resort_sequence (self, seq, row->children);
- g_ptr_array_add (previous, row->object);
- }
-
- if (previous->len == 0) {
- g_ptr_array_free (previous, TRUE);
- return;
- }
-
- /* Actually perform the sort */
- g_sequence_sort (sequence, self->pv->order_current, self);
-
- /* Now go through and map out how things changed */
- new_order = g_new0 (gint, previous->len);
- for (i = 0; i < previous->len; i++) {
- seq = g_hash_table_lookup (self->pv->object_to_seq, previous->pdata[i]);
- g_assert (seq != NULL);
- index = g_sequence_iter_get_position (seq);
- g_assert (index >= 0 && index < previous->len);
- new_order[index] = i;
- }
-
- g_ptr_array_free (previous, TRUE);
-
- path = sequence_iter_to_path (self, parent);
- if (parent == NULL) {
- gtk_tree_model_rows_reordered (GTK_TREE_MODEL (self), path, NULL, new_order);
- } else {
- if (!sequence_iter_to_tree (self, parent, &iter))
- g_assert_not_reached ();
- gtk_tree_model_rows_reordered (GTK_TREE_MODEL (self), path, &iter, new_order);
- }
- gtk_tree_path_free (path);
- g_free (new_order);
-}
-
-static gboolean
-gcr_collection_model_get_sort_column_id (GtkTreeSortable *sortable,
- gint *sort_column_id,
- GtkSortType *order)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (sortable);
-
- if (order)
- *order = self->pv->sort_order_type;
- if (sort_column_id)
- *sort_column_id = self->pv->sort_column_id;
- return (self->pv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
- self->pv->sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID);
-}
-
-static void
-gcr_collection_model_set_sort_column_id (GtkTreeSortable *sortable,
- gint sort_column_id,
- GtkSortType order)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (sortable);
- GCompareDataFunc func;
- gpointer argument;
- const GcrColumn *column;
- gboolean reverse;
-
- reverse = (order == GTK_SORT_DESCENDING);
-
- if (sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID) {
- func = reverse ? order_sequence_as_unsorted_reverse : order_sequence_as_unsorted;
- argument = NULL;
-
- } else if (sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID) {
- func = reverse ? order_sequence_by_closure_reverse : order_sequence_by_closure;
- argument = &self->pv->default_sort_closure;
-
- } else if (sort_column_id >= 0 && sort_column_id < self->pv->n_columns) {
- if (self->pv->column_sort_closures[sort_column_id].sort_func) {
- func = reverse ? order_sequence_by_closure_reverse : order_sequence_by_closure;
- argument = &self->pv->column_sort_closures[sort_column_id];
- } else {
- column = &self->pv->columns[sort_column_id];
- if (!(column->flags & GCR_COLUMN_SORTABLE))
- return;
- if (!lookup_compare_func (column->property_type)) {
- g_warning ("no sort implementation defined for type '%s' on column '%s'",
- g_type_name (column->property_type), column->property_name);
- return;
- }
-
- func = reverse ? order_sequence_by_property_reverse : order_sequence_by_property;
- argument = (gpointer)column;
- }
- } else {
- g_warning ("invalid sort_column_id passed to gtk_tree_sortable_set_sort_column_id(): %d",
- sort_column_id);
- return;
- }
-
- if (sort_column_id != self->pv->sort_column_id ||
- order != self->pv->sort_order_type) {
- self->pv->sort_column_id = sort_column_id;
- self->pv->sort_order_type = order;
- gtk_tree_sortable_sort_column_changed (sortable);
- }
-
- if (func != self->pv->order_current ||
- argument != self->pv->order_argument) {
- self->pv->order_current = func;
- self->pv->order_argument = (gpointer)argument;
- collection_resort_sequence (self, NULL, self->pv->root_sequence);
- }
-}
-
-static void
-clear_sort_closure (GcrCollectionSortClosure *closure)
-{
- if (closure->destroy_func)
- (closure->destroy_func) (closure->user_data);
- closure->sort_func = NULL;
- closure->destroy_func = NULL;
- closure->user_data = NULL;
-}
-
-static void
-set_sort_closure (GcrCollectionSortClosure *closure,
- GtkTreeIterCompareFunc func,
- gpointer data,
- GDestroyNotify destroy)
-{
- clear_sort_closure (closure);
- closure->sort_func = func;
- closure->user_data = data;
- closure->destroy_func = destroy;
-}
-
-static void
-gcr_collection_model_set_sort_func (GtkTreeSortable *sortable,
- gint sort_column_id,
- GtkTreeIterCompareFunc func,
- gpointer data,
- GDestroyNotify destroy)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (sortable);
-
- g_return_if_fail (sort_column_id >= 0 && sort_column_id < self->pv->n_columns);
-
- set_sort_closure (&self->pv->column_sort_closures[sort_column_id],
- func, data, destroy);
-
- /* Resorts if necessary */
- if (self->pv->sort_column_id == sort_column_id) {
- gcr_collection_model_set_sort_column_id (sortable,
- self->pv->sort_column_id,
- self->pv->sort_order_type);
- }
-}
-
-static void
-gcr_collection_model_set_default_sort_func (GtkTreeSortable *sortable,
- GtkTreeIterCompareFunc func,
- gpointer data, GDestroyNotify destroy)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (sortable);
-
- set_sort_closure (&self->pv->default_sort_closure,
- func, data, destroy);
-
- /* Resorts if necessary */
- if (self->pv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID) {
- gcr_collection_model_set_sort_column_id (sortable,
- self->pv->sort_column_id,
- self->pv->sort_order_type);
- }
-}
-
-static gboolean
-gcr_collection_model_has_default_sort_func (GtkTreeSortable *sortable)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (sortable);
-
- return (self->pv->default_sort_closure.sort_func != NULL);
-}
-
-static void
-gcr_collection_model_tree_sortable_init (GtkTreeSortableIface *iface)
-{
- iface->get_sort_column_id = gcr_collection_model_get_sort_column_id;
- iface->set_sort_column_id = gcr_collection_model_set_sort_column_id;
- iface->set_sort_func = gcr_collection_model_set_sort_func;
- iface->set_default_sort_func = gcr_collection_model_set_default_sort_func;
- iface->has_default_sort_func = gcr_collection_model_has_default_sort_func;
-}
-
-static void
-gcr_collection_model_init (GcrCollectionModel *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_COLLECTION_MODEL, GcrCollectionModelPrivate);
-
- self->pv->root_sequence = g_sequence_new (NULL);
- self->pv->object_to_seq = g_hash_table_new (g_direct_hash, g_direct_equal);
- self->pv->sort_column_id = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID;
- self->pv->sort_order_type = GTK_SORT_ASCENDING;
- self->pv->order_current = order_sequence_as_unsorted;
-}
-
-static void
-gcr_collection_model_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (object);
- GcrColumn *columns;
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_return_if_fail (self->pv->collection == NULL);
- self->pv->collection = g_value_dup_object (value);
-
- /* During construction, so we don't emit anything */
- if (self->pv->collection) {
- add_children_to_sequence (self, self->pv->root_sequence,
- NULL, self->pv->collection, FALSE);
- }
- break;
-
- case PROP_COLUMNS:
- columns = g_value_get_pointer (value);
- if (columns)
- gcr_collection_model_set_columns (self, columns);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_collection_model_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (object);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_value_set_object (value, self->pv->collection);
- break;
-
- case PROP_COLUMNS:
- g_value_set_pointer (value, (gpointer)self->pv->columns);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_collection_model_dispose (GObject *object)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (object);
-
- /* Disconnect from all rows */
- if (self->pv->collection) {
- remove_children_from_sequence (self, self->pv->root_sequence,
- self->pv->collection, FALSE);
- g_object_unref (self->pv->collection);
- self->pv->collection = NULL;
- }
-
- G_OBJECT_CLASS (gcr_collection_model_parent_class)->dispose (object);
-}
-
-static void
-gcr_collection_model_finalize (GObject *object)
-{
- GcrCollectionModel *self = GCR_COLLECTION_MODEL (object);
- guint i;
-
- g_assert (!self->pv->collection);
-
- g_assert (g_sequence_get_length (self->pv->root_sequence) == 0);
- g_sequence_free (self->pv->root_sequence);
- g_assert (g_hash_table_size (self->pv->object_to_seq) == 0);
- g_hash_table_destroy (self->pv->object_to_seq);
-
- if (self->pv->selected) {
- g_assert (g_hash_table_size (self->pv->selected) == 0);
- g_hash_table_destroy (self->pv->selected);
- self->pv->selected = NULL;
- }
-
- self->pv->columns = NULL;
- for (i = 0; i < self->pv->n_columns; i++)
- clear_sort_closure (&self->pv->column_sort_closures[i]);
- g_free (self->pv->column_sort_closures);
- clear_sort_closure (&self->pv->default_sort_closure);
-
- G_OBJECT_CLASS (gcr_collection_model_parent_class)->finalize (object);
-}
-
-static void
-gcr_collection_model_class_init (GcrCollectionModelClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gcr_collection_model_parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->dispose = gcr_collection_model_dispose;
- gobject_class->finalize = gcr_collection_model_finalize;
- gobject_class->set_property = gcr_collection_model_set_property;
- gobject_class->get_property = gcr_collection_model_get_property;
-
- g_object_class_install_property (gobject_class, PROP_COLLECTION,
- g_param_spec_object ("collection", "Object Collection", "Collection to get objects from",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_COLUMNS,
- g_param_spec_pointer ("columns", "Columns", "Columns for the model",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (klass, sizeof (GcrCollectionModelPrivate));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_collection_model_new: (skip)
- * @collection: The collection to represent
- * @...: The column names and types.
- *
- * Create a new #GcrCollectionModel. The variable argument list should contain
- * pairs of property names, and #GType values. The variable argument list should
- * be terminated with %NULL.
- *
- * Returns: (transfer full): a newly allocated model, which should be released
- * with g_object_unref().
- */
-GcrCollectionModel*
-gcr_collection_model_new (GcrCollection *collection, ...)
-{
- GcrColumn column;
- GcrCollectionModel *self;
- const gchar *arg;
- GArray *array;
- va_list va;
-
- /* With a null terminator */
- array = g_array_new (TRUE, TRUE, sizeof (GcrColumn));
-
- va_start (va, collection);
- while ((arg = va_arg (va, const gchar*)) != NULL) {
- memset (&column, 0, sizeof (column));
- column.property_name = g_strdup (arg);
- column.property_type = va_arg (va, GType);
- column.column_type = column.property_type;
- g_array_append_val (array, column);
- }
- va_end (va);
-
- self = gcr_collection_model_new_full (collection, (GcrColumn*)array->data);
- g_object_set_data_full (G_OBJECT (self), "gcr_collection_model_new",
- g_array_free (array, FALSE), free_owned_columns);
- return self;
-}
-
-/**
- * gcr_collection_model_new_full: (skip)
- * @collection: The collection to represent
- * @columns: The columns the model should contain
- *
- * Create a new #GcrCollectionModel.
- *
- * Returns: (transfer full): a newly allocated model, which should be released
- * with g_object_unref()
- */
-GcrCollectionModel*
-gcr_collection_model_new_full (GcrCollection *collection, const GcrColumn *columns)
-{
- GcrCollectionModel *self = g_object_new (GCR_TYPE_COLLECTION_MODEL, "collection", collection, NULL);
- gcr_collection_model_set_columns (self, columns);
- return self;
-}
-
-/**
- * gcr_collection_model_set_columns: (skip)
- * @self: The model
- * @columns: The columns the model should contain
- *
- * Set the columns that the model should contain. @columns is an array of
- * #GcrColumn structures, with the last one containing %NULL for all values.
- *
- * This function can only be called once, and only if the model was not created
- * without a set of columns. This function cannot be called after the model
- * has been added to a view.
- *
- * The columns are accessed as static data. They should continue to remain
- * in memory for longer than the GcrCollectionModel object.
- *
- * Returns: The number of columns
- */
-guint
-gcr_collection_model_set_columns (GcrCollectionModel *self,
- const GcrColumn *columns)
-{
- const GcrColumn *col;
- guint n_columns;
-
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), 0);
- g_return_val_if_fail (columns, 0);
- g_return_val_if_fail (self->pv->n_columns == 0, 0);
-
- /* Count the number of columns, extra column for selected */
- for (col = columns, n_columns = 1; col->property_name; ++col)
- ++n_columns;
-
- /* We expect the columns to stay around */
- self->pv->columns = columns;
- self->pv->n_columns = n_columns;
- self->pv->column_sort_closures = g_new0 (GcrCollectionSortClosure, self->pv->n_columns);
-
- return n_columns - 1;
-}
-
-/**
- * gcr_collection_model_get_collection:
- * @self: a collection model
- *
- * Get the collection which this model represents
- *
- * Returns: (transfer none): the collection, owned by the model
- */
-GcrCollection *
-gcr_collection_model_get_collection (GcrCollectionModel *self)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), NULL);
- return self->pv->collection;
-}
-
-/**
- * gcr_collection_model_object_for_iter:
- * @self: The model
- * @iter: The row
- *
- * Get the object that is represented by the given row in the model.
- *
- * Returns: (transfer none): The object, owned by the model.
- */
-GObject *
-gcr_collection_model_object_for_iter (GcrCollectionModel *self, const GtkTreeIter *iter)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), NULL);
- g_return_val_if_fail (iter != NULL, NULL);
- g_return_val_if_fail (iter->stamp == COLLECTION_MODEL_STAMP, NULL);
- g_return_val_if_fail (G_IS_OBJECT (iter->user_data), NULL);
-
- return G_OBJECT (iter->user_data);
-}
-
-/**
- * gcr_collection_model_iter_for_object:
- * @self: The model
- * @object: The object
- * @iter: The row for the object
- *
- * Set @iter to the row for the given object. If the object is not in this
- * model, then %FALSE will be returned.
- *
- * Returns: %TRUE if the object was present.
- */
-gboolean
-gcr_collection_model_iter_for_object (GcrCollectionModel *self, GObject *object,
- GtkTreeIter *iter)
-{
- GSequenceIter *seq;
-
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), FALSE);
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
-
- seq = g_hash_table_lookup (self->pv->object_to_seq, object);
- if (seq == NULL)
- return FALSE;
-
- return sequence_iter_to_tree (self, seq, iter);
-}
-
-/**
- * gcr_collection_model_column_for_selected:
- * @self: The model
- *
- * Get the column identifier for the column that contains the values
- * of the selected state.
- *
- * Returns: The column identifier.
- */
-gint
-gcr_collection_model_column_for_selected (GcrCollectionModel *self)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), 0);
- g_assert (self->pv->n_columns > 0);
- return self->pv->n_columns - 1;
-}
-
-/**
- * gcr_collection_model_toggle_selected:
- * @self: The model
- * @iter: The row
- *
- * Toggle the selected state of a given row.
- */
-void
-gcr_collection_model_toggle_selected (GcrCollectionModel *self, GtkTreeIter *iter)
-{
- GObject *object;
-
- g_return_if_fail (GCR_IS_COLLECTION_MODEL (self));
-
- object = gcr_collection_model_object_for_iter (self, iter);
- g_return_if_fail (G_IS_OBJECT (object));
-
- if (!self->pv->selected)
- self->pv->selected = selected_hash_table_new ();
-
- if (g_hash_table_lookup (self->pv->selected, object))
- g_hash_table_remove (self->pv->selected, object);
- else
- g_hash_table_insert (self->pv->selected, object, object);
-}
-
-/**
- * gcr_collection_model_change_selected:
- * @self: The model
- * @iter: The row
- * @selected: Whether the row should be selected or not.
- *
- * Set whether a given row is toggled selected or not.
- */
-void
-gcr_collection_model_change_selected (GcrCollectionModel *self, GtkTreeIter *iter, gboolean selected)
-{
- GtkTreePath *path;
- GObject *object;
-
- g_return_if_fail (GCR_IS_COLLECTION_MODEL (self));
-
- object = gcr_collection_model_object_for_iter (self, iter);
- g_return_if_fail (G_IS_OBJECT (object));
-
- if (!self->pv->selected)
- self->pv->selected = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- if (selected)
- g_hash_table_insert (self->pv->selected, object, object);
- else
- g_hash_table_remove (self->pv->selected, object);
-
- /* Tell the view that this row changed */
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), iter);
- g_return_if_fail (path);
- gtk_tree_model_row_changed (GTK_TREE_MODEL (self), path, iter);
- gtk_tree_path_free (path);
-}
-
-/**
- * gcr_collection_model_is_selected:
- * @self: The model
- * @iter: The row
- *
- * Check whether a given row has been toggled as selected.
- *
- * Returns: Whether the row has been selected.
- */
-gboolean
-gcr_collection_model_is_selected (GcrCollectionModel *self, GtkTreeIter *iter)
-{
- GObject *object;
-
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), FALSE);
-
- object = gcr_collection_model_object_for_iter (self, iter);
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
-
- if (!self->pv->selected)
- return FALSE;
-
- return g_hash_table_lookup (self->pv->selected, object) ? TRUE : FALSE;
-}
-
-/**
- * gcr_collection_model_get_selected_objects:
- * @self: the collection model
- *
- * Get a list of checked/selected objects.
- *
- * Returns: (transfer container) (element-type GLib.Object): a list of selected
- * objects, which should be freed with g_list_free()
- */
-GList *
-gcr_collection_model_get_selected_objects (GcrCollectionModel *self)
-{
- GHashTableIter iter;
- GList *result = NULL;
- gpointer key;
-
- g_return_val_if_fail (GCR_IS_COLLECTION_MODEL (self), NULL);
-
- if (!self->pv->selected)
- return NULL;
-
- g_hash_table_iter_init (&iter, self->pv->selected);
- while (g_hash_table_iter_next (&iter, &key, NULL))
- result = g_list_prepend (result, key);
- return result;
-}
-
-/**
- * gcr_collection_model_set_selected_objects:
- * @self: the collection model
- * @selected: (element-type GLib.Object): a list of objects to select
- *
- * Set the checked/selected objects.
- */
-void
-gcr_collection_model_set_selected_objects (GcrCollectionModel *self,
- GList *selected)
-{
- GHashTable *newly_selected;
- GList *old_selection;
- GtkTreeIter iter;
- GList *l;
-
- old_selection = gcr_collection_model_get_selected_objects (self);
- newly_selected = selected_hash_table_new ();
-
- /* Select all the objects in selected which aren't already selected */
- for (l = selected; l; l = g_list_next (l)) {
- if (!self->pv->selected || !g_hash_table_lookup (self->pv->selected, l->data)) {
- if (!gcr_collection_model_iter_for_object (self, l->data, &iter))
- g_return_if_reached ();
- gcr_collection_model_change_selected (self, &iter, TRUE);
- }
-
- /* Note that we've seen this one */
- g_hash_table_insert (newly_selected, l->data, l->data);
- }
-
- /* Unselect all the objects which aren't supposed to be selected */
- for (l = old_selection; l; l = g_list_next (l)) {
- if (!g_hash_table_lookup (newly_selected, l->data)) {
- if (!gcr_collection_model_iter_for_object (self, l->data, &iter))
- g_return_if_reached ();
- gcr_collection_model_change_selected (self, &iter, FALSE);
- }
- }
-
- g_list_free (old_selection);
- g_hash_table_destroy (newly_selected);
-}
diff --git a/gcr/gcr-collection-model.h b/gcr/gcr-collection-model.h
deleted file mode 100644
index fcd98e1b..00000000
--- a/gcr/gcr-collection-model.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GCR_COLLECTION_MODEL_H__
-#define __GCR_COLLECTION_MODEL_H__
-
-#include <gtk/gtk.h>
-
-#include "gcr-collection.h"
-#include "gcr-column.h"
-
-#define GCR_TYPE_COLLECTION_MODEL (gcr_collection_model_get_type ())
-#define GCR_COLLECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION_MODEL, GcrCollectionModel))
-#define GCR_COLLECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION_MODEL, GcrCollectionModelClass))
-#define GCR_IS_COLLECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION_MODEL))
-#define GCR_IS_COLLECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION_MODEL))
-#define GCR_COLLECTION_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION_MODEL, GcrCollectionModelClass))
-
-typedef struct _GcrCollectionModel GcrCollectionModel;
-typedef struct _GcrCollectionModelClass GcrCollectionModelClass;
-typedef struct _GcrCollectionModelPrivate GcrCollectionModelPrivate;
-
-struct _GcrCollectionModel {
- GObject parent;
-
- /*< private >*/
- GcrCollectionModelPrivate *pv;
-};
-
-struct _GcrCollectionModelClass {
- GObjectClass parent_class;
-};
-
-GType gcr_collection_model_get_type (void);
-
-GcrCollectionModel* gcr_collection_model_new (GcrCollection *collection,
- ...) G_GNUC_NULL_TERMINATED;
-
-GcrCollectionModel* gcr_collection_model_new_full (GcrCollection *collection,
- const GcrColumn *columns);
-
-guint gcr_collection_model_set_columns (GcrCollectionModel *self,
- const GcrColumn *columns);
-
-GcrCollection * gcr_collection_model_get_collection (GcrCollectionModel *self);
-
-GObject* gcr_collection_model_object_for_iter (GcrCollectionModel *self,
- const GtkTreeIter *iter);
-
-gboolean gcr_collection_model_iter_for_object (GcrCollectionModel *self,
- GObject *object,
- GtkTreeIter *iter);
-
-gint gcr_collection_model_column_for_selected (GcrCollectionModel *self);
-
-void gcr_collection_model_toggle_selected (GcrCollectionModel *self,
- GtkTreeIter *iter);
-
-void gcr_collection_model_change_selected (GcrCollectionModel *self,
- GtkTreeIter *iter,
- gboolean selected);
-
-gboolean gcr_collection_model_is_selected (GcrCollectionModel *self,
- GtkTreeIter *iter);
-
-GList* gcr_collection_model_get_selected_objects (GcrCollectionModel *self);
-
-void gcr_collection_model_set_selected_objects (GcrCollectionModel *self,
- GList *selected);
-
-#endif /* __GCR_COLLECTION_MODEL_H__ */
diff --git a/gcr/gcr-collection.c b/gcr/gcr-collection.c
deleted file mode 100644
index 08bbedbb..00000000
--- a/gcr/gcr-collection.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection.h"
-
-/**
- * SECTION:gcr-collection
- * @title: GcrCollection
- * @short_description: A collection of objects.
- *
- * A #GcrCollection is used to group a set of objects. This is an abstract
- * interface which can be used to determine which objects show up in a selector
- * or other user interface element.
- *
- * Use gcr_simple_collection_new() to create a concrete implementation of this
- * interface which you can add objects to.
- */
-
-/**
- * GcrCollection:
- *
- * A #GcrCollection is used to group a set of objects.
- */
-
-enum {
- ADDED,
- REMOVED,
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-
-typedef GcrCollectionIface GcrCollectionInterface;
-
-G_DEFINE_INTERFACE (GcrCollection, gcr_collection, G_TYPE_OBJECT);
-
-static void
-gcr_collection_default_init (GcrCollectionIface *iface)
-{
- static volatile gsize initialized = 0;
-
- if (g_once_init_enter (&initialized)) {
-
- /**
- * GcrCollection::added:
- * @self: the collection
- * @object: (type GLib.Object): object that was added
- *
- * This signal is emitted when an object is added to the collection.
- */
- signals[ADDED] = g_signal_new ("added", GCR_TYPE_COLLECTION,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrCollectionIface, added),
- NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- /**
- * GcrCollection::removed:
- * @self: the collection
- * @object: (type GLib.Object): object that was removed
- *
- * This signal is emitted when an object is removed from the collection.
- */
- signals[REMOVED] = g_signal_new ("removed", GCR_TYPE_COLLECTION,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrCollectionIface, removed),
- NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- g_once_init_leave (&initialized, 1);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-
-/**
- * gcr_collection_get_length:
- * @self: The collection
- *
- * Get the number of objects in this collection.
- *
- * Returns: The number of objects.
- */
-guint
-gcr_collection_get_length (GcrCollection *self)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION (self), 0);
- g_return_val_if_fail (GCR_COLLECTION_GET_INTERFACE (self)->get_length, 0);
- return GCR_COLLECTION_GET_INTERFACE (self)->get_length (self);
-}
-
-/**
- * gcr_collection_get_objects:
- * @self: The collection
- *
- * Get a list of the objects in this collection.
- *
- * Returns: (transfer container) (element-type GLib.Object): a list of the objects
- * in this collection, which should be freed with g_list_free()
- */
-GList*
-gcr_collection_get_objects (GcrCollection *self)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION (self), 0);
- g_return_val_if_fail (GCR_COLLECTION_GET_INTERFACE (self)->get_objects, 0);
- return GCR_COLLECTION_GET_INTERFACE (self)->get_objects (self);
-}
-
-/**
- * gcr_collection_contains:
- * @self: the collection
- * @object: object to check
- *
- * Check whether the collection contains an object or not.
- *
- * Returns: whether the collection contains this object
- */
-gboolean
-gcr_collection_contains (GcrCollection *self,
- GObject *object)
-{
- g_return_val_if_fail (GCR_IS_COLLECTION (self), FALSE);
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (GCR_COLLECTION_GET_INTERFACE (self)->contains, FALSE);
- return GCR_COLLECTION_GET_INTERFACE (self)->contains (self, object);
-}
-
-/**
- * gcr_collection_emit_added:
- * @self: The collection
- * @object: The object that was added
- *
- * Emit the GcrCollection::added signal for the given object. This function
- * is used by implementors of this interface.
- */
-void
-gcr_collection_emit_added (GcrCollection *self, GObject *object)
-{
- g_return_if_fail (GCR_IS_COLLECTION (self));
- g_signal_emit (self, signals[ADDED], 0, object);
-}
-
-/**
- * gcr_collection_emit_removed:
- * @self: The collection
- * @object: The object that was removed
- *
- * Emit the GcrCollection::removed signal for the given object. This function
- * is used by implementors of this interface.
- */
-void
-gcr_collection_emit_removed (GcrCollection *self, GObject *object)
-{
- g_return_if_fail (GCR_IS_COLLECTION (self));
- g_signal_emit (self, signals[REMOVED], 0, object);
-}
diff --git a/gcr/gcr-collection.h b/gcr/gcr-collection.h
deleted file mode 100644
index 2616394c..00000000
--- a/gcr/gcr-collection.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_COLLECTION_H__
-#define __GCR_COLLECTION_H__
-
-#include "gcr-types.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_COLLECTION (gcr_collection_get_type())
-#define GCR_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrCollection))
-#define GCR_IS_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
-#define GCR_COLLECTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_COLLECTION, GcrCollectionIface))
-
-typedef struct _GcrCollection GcrCollection;
-typedef struct _GcrCollectionIface GcrCollectionIface;
-
-struct _GcrCollectionIface {
- GTypeInterface parent;
-
- /* signals */
- void (*added) (GcrCollection *self, GObject *object);
-
- void (*removed) (GcrCollection *self, GObject *object);
-
- /* virtual */
- guint (*get_length) (GcrCollection *self);
-
- GList* (*get_objects) (GcrCollection *self);
-
- gboolean (*contains) (GcrCollection *self,
- GObject *object);
-
- /*< private >*/
- gpointer dummy1;
- gpointer dummy2;
- gpointer dummy3;
- gpointer dummy5;
- gpointer dummy6;
- gpointer dummy7;
- gpointer dummy8;
-};
-
-GType gcr_collection_get_type (void);
-
-guint gcr_collection_get_length (GcrCollection *self);
-
-GList* gcr_collection_get_objects (GcrCollection *self);
-
-gboolean gcr_collection_contains (GcrCollection *self,
- GObject *object);
-
-void gcr_collection_emit_added (GcrCollection *self,
- GObject *object);
-
-void gcr_collection_emit_removed (GcrCollection *self,
- GObject *object);
-
-G_END_DECLS
-
-#endif /* __GCR_COLLECTION_H__ */
diff --git a/gcr/gcr-column.c b/gcr/gcr-column.c
deleted file mode 100644
index 254f55ce..00000000
--- a/gcr/gcr-column.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-column.h"
-
-/**
- * SECTION:gcr-column
- * @title: GcrColumn
- * @short_description: Column information for selector or model.
- *
- * A #GcrColumn is used with #GcrTreeSelector or #GcrCollectionModel to define
- * the columns to display.
- */
-
-/**
- * GcrColumnFlags:
- * @GCR_COLUMN_NONE: No column flags
- * @GCR_COLUMN_HIDDEN: Don't display this column.
- * @GCR_COLUMN_SORTABLE: This column is sortable.
- *
- * Flags to be used with #GcrColumn
- */
-
-/**
- * GcrColumn:
- * @property_name: The name of the property this column will display
- * @property_type: The type of the property
- * @column_type: The eventual type of the column
- * @label: The display label for the column
- * @flags: Flags from #GcrColumnFlags
- * @transformer: A transformer function used to convert the value from
- * the property type to the column type. Can be %NULL if the types
- * are the same.
- * @user_data: User data associated with the column
- *
- * Represents a column to display in a #GcrCollectionModel or #GcrTreeSelector.
- *
- * The label should be set as a translatable string with a context of
- * <code>"column"</code>. This should be done with with this macro:
- *
- * <informalexample><programlisting>
- * NC_("column", "My Column Name")
- * </programlisting></informalexample>
- */
diff --git a/gcr/gcr-column.h b/gcr/gcr-column.h
deleted file mode 100644
index 65ee6a60..00000000
--- a/gcr/gcr-column.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_COLUMN_H__
-#define __GCR_COLUMN_H__
-
-#include "gcr-types.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
- GCR_COLUMN_NONE = 0,
- GCR_COLUMN_HIDDEN = 1 << 1,
- GCR_COLUMN_SORTABLE = 1 << 2,
-} GcrColumnFlags;
-
-typedef struct _GcrColumn {
- const gchar *property_name; /* The property to retrieve */
- GType property_type; /* The property type */
- GType column_type; /* The resulting property type for this column */
-
- const gchar *label; /* The label for this column, or NULL */
- GcrColumnFlags flags; /* Column flags */
-
- GValueTransform transformer; /* The way to transform to this type or NULL */
-
- gpointer user_data;
-
- /*< private >*/
- gpointer reserved;
-} GcrColumn;
-
-G_END_DECLS
-
-#endif /* __GCR_COLUMN_H__ */
diff --git a/gcr/gcr-combo-selector.c b/gcr/gcr-combo-selector.c
deleted file mode 100644
index 56e06fe9..00000000
--- a/gcr/gcr-combo-selector.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection-model.h"
-#include "gcr-internal.h"
-#include "gcr-combo-selector.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <string.h>
-
-/**
- * SECTION:gcr-combo-selector
- * @title: GcrComboSelector
- * @short_description: A selector widget to select a single certificate or key.
- *
- * The #GcrComboSelector can be used to select a certificate or key. It allows
- * the user to select one object from the selector at a time.
- */
-
-/**
- * GcrComboSelector:
- *
- * A combo selector widget.
- */
-
-/**
- * GcrComboSelectorClass:
- *
- * The class for #GcrComboSelector.
- */
-
-enum {
- PROP_0,
- PROP_COLLECTION
-};
-
-struct _GcrComboSelectorPrivate {
- GcrCollection *collection;
- GcrCollectionModel *model;
-};
-
-G_DEFINE_TYPE (GcrComboSelector, gcr_combo_selector, GTK_TYPE_COMBO_BOX);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-gcr_combo_selector_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GcrComboSelector *self = GCR_COMBO_SELECTOR (G_OBJECT_CLASS (gcr_combo_selector_parent_class)->constructor(type, n_props, props));
- GtkCellRenderer *cell;
-
- g_return_val_if_fail (self, NULL);
-
- self->pv->model = gcr_collection_model_new (self->pv->collection,
- "icon", G_TYPE_ICON,
- "markup", G_TYPE_STRING,
- NULL);
-
- gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (self->pv->model));
-
- /* The icon */
- cell = gtk_cell_renderer_pixbuf_new ();
- g_object_set (cell, "stock-size", GTK_ICON_SIZE_DND, NULL);
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), cell, FALSE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self), cell, "gicon", 0);
-
- /* The markup */
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), cell, TRUE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self), cell, "markup", 1);
-
- return G_OBJECT (self);
-}
-
-static void
-gcr_combo_selector_init (GcrComboSelector *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_COMBO_SELECTOR, GcrComboSelectorPrivate);
-}
-
-static void
-gcr_combo_selector_dispose (GObject *obj)
-{
- GcrComboSelector *self = GCR_COMBO_SELECTOR (obj);
-
- if (self->pv->model)
- g_object_unref (self->pv->model);
- self->pv->model = NULL;
-
- if (self->pv->collection)
- g_object_unref (self->pv->collection);
- self->pv->collection = NULL;
-
- G_OBJECT_CLASS (gcr_combo_selector_parent_class)->dispose (obj);
-}
-
-static void
-gcr_combo_selector_finalize (GObject *obj)
-{
- GcrComboSelector *self = GCR_COMBO_SELECTOR (obj);
-
- g_assert (!self->pv->collection);
- g_assert (!self->pv->model);
-
- G_OBJECT_CLASS (gcr_combo_selector_parent_class)->finalize (obj);
-}
-
-static void
-gcr_combo_selector_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrComboSelector *self = GCR_COMBO_SELECTOR (obj);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_return_if_fail (!self->pv->collection);
- self->pv->collection = g_value_dup_object (value);
- g_return_if_fail (self->pv->collection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_combo_selector_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrComboSelector *self = GCR_COMBO_SELECTOR (obj);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_value_set_object (value, gcr_combo_selector_get_collection (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_combo_selector_class_init (GcrComboSelectorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructor = gcr_combo_selector_constructor;
- gobject_class->dispose = gcr_combo_selector_dispose;
- gobject_class->finalize = gcr_combo_selector_finalize;
- gobject_class->set_property = gcr_combo_selector_set_property;
- gobject_class->get_property = gcr_combo_selector_get_property;
-
- g_type_class_add_private (gobject_class, sizeof (GcrComboSelectorPrivate));
-
- /**
- * GcrComboSelector:collection:
- *
- * The collection which contains the objects to display in the selector.
- */
- g_object_class_install_property (gobject_class, PROP_COLLECTION,
- g_param_spec_object ("collection", "Collection", "Collection to select from",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_combo_selector_new:
- * @collection: The collection that contains the objects to display
- *
- * Create a new #GcrTreeSelector.
- *
- * Returns: A newly allocated selector, which should be released with
- * g_object_unref().
- */
-GcrComboSelector*
-gcr_combo_selector_new (GcrCollection *collection)
-{
- return g_object_new (GCR_TYPE_COMBO_SELECTOR,
- "collection", collection,
- NULL);
-}
-
-/**
- * gcr_combo_selector_get_collection:
- * @self: The selector
- *
- * Get the collection that this selector is displaying objects from.
- *
- * Returns: (transfer none): The collection, owned by the selector.
- */
-GcrCollection *
-gcr_combo_selector_get_collection (GcrComboSelector *self)
-{
- g_return_val_if_fail (GCR_IS_COMBO_SELECTOR (self), NULL);
- return self->pv->collection;
-}
-
-/**
- * gcr_combo_selector_get_selected:
- * @self: The selector
- *
- * Get the selected object in the selector, or %NULL if nothing selected.
- *
- * Returns: (transfer none): the selected object, owned by the selector, or %NULL
- */
-GObject *
-gcr_combo_selector_get_selected (GcrComboSelector *self)
-{
- GtkTreeIter iter;
-
- g_return_val_if_fail (GCR_IS_COMBO_SELECTOR (self), NULL);
- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self), &iter);
-
- return gcr_collection_model_object_for_iter (self->pv->model, &iter);
-}
-
-/**
- * gcr_combo_selector_set_selected:
- * @self: The selector
- * @selected: (allow-none): the object to select or %NULL
- *
- * Set the currently selected object in the selector, or clear the selection
- * if selected is set to %NULL.
- */
-void
-gcr_combo_selector_set_selected (GcrComboSelector *self, GObject *selected)
-{
- GtkTreeIter iter;
-
- g_return_if_fail (GCR_IS_COMBO_SELECTOR (self));
-
- if (selected) {
- if (!gcr_collection_model_iter_for_object (self->pv->model, selected, &iter))
- g_return_if_reached ();
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), &iter);
- } else {
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), NULL);
- }
-}
diff --git a/gcr/gcr-combo-selector.h b/gcr/gcr-combo-selector.h
deleted file mode 100644
index 2e519a08..00000000
--- a/gcr/gcr-combo-selector.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_COMBO_SELECTOR_H__
-#define __GCR_COMBO_SELECTOR_H__
-
-#include "gcr-types.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_COMBO_SELECTOR (gcr_combo_selector_get_type ())
-#define GCR_COMBO_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COMBO_SELECTOR, GcrComboSelector))
-#define GCR_COMBO_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COMBO_SELECTOR, GcrComboSelectorClass))
-#define GCR_IS_COMBO_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COMBO_SELECTOR))
-#define GCR_IS_COMBO_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COMBO_SELECTOR))
-#define GCR_COMBO_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COMBO_SELECTOR, GcrComboSelectorClass))
-
-typedef struct _GcrComboSelector GcrComboSelector;
-typedef struct _GcrComboSelectorClass GcrComboSelectorClass;
-typedef struct _GcrComboSelectorPrivate GcrComboSelectorPrivate;
-
-struct _GcrComboSelector {
- GtkComboBox parent;
-
- /*< private >*/
- GcrComboSelectorPrivate *pv;
-};
-
-struct _GcrComboSelectorClass {
- /*< private >*/
- GtkComboBoxClass parent_class;
-};
-
-GType gcr_combo_selector_get_type (void);
-
-GcrComboSelector* gcr_combo_selector_new (GcrCollection *collection);
-
-GcrCollection* gcr_combo_selector_get_collection (GcrComboSelector *self);
-
-GObject* gcr_combo_selector_get_selected (GcrComboSelector *self);
-
-void gcr_combo_selector_set_selected (GcrComboSelector *self,
- GObject *selected);
-
-G_END_DECLS
-
-#endif /* __GCR_COMBO_SELECTOR_H__ */
diff --git a/gcr/gcr-comparable.c b/gcr/gcr-comparable.c
deleted file mode 100644
index fddbdd1f..00000000
--- a/gcr/gcr-comparable.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-comparable.h"
-
-#include <string.h>
-
-/**
- * SECTION:gcr-comparable
- * @title: GcrComparable
- * @short_description: Interface for comparing objects
- *
- * The #GcrComparable interface is implemented by objects when they should be
- * comparable against one another.
- */
-
-/**
- * GcrComparable:
- *
- * The #GcrComparable interface is implemented by comparable objects.
- */
-
-/**
- * GcrComparableIface:
- *
- * The interface to implement for #GcrComparable
- */
-
-/* ---------------------------------------------------------------------------------
- * INTERFACE
- */
-
-static void
-gcr_comparable_base_init (gpointer g_class)
-{
- static volatile gsize initialized = 0;
-
- if (g_once_init_enter (&initialized)) {
- /* Add properties and signals to the interface */
- g_once_init_leave (&initialized, 1);
- }
-}
-
-GType
-gcr_comparable_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (GcrComparableIface),
- gcr_comparable_base_init, /* base init */
- NULL, /* base finalize */
- NULL, /* class_init */
- NULL, /* class finalize */
- NULL, /* class data */
- 0,
- 0, /* n_preallocs */
- NULL, /* instance init */
- };
- type = g_type_register_static (G_TYPE_INTERFACE, "GcrComparableIface", &info, 0);
- g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
- }
-
- return type;
-}
-
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_comparable_compare:
- * @self: The comparable object
- * @other: Another comparable object
- *
- * Compare whether two objects represent the same thing. The return value can
- * also be used to sort the objects.
- *
- * Returns: Zero if the two objects represent the same thing, non-zero if not.
- */
-gint
-gcr_comparable_compare (GcrComparable *self, GcrComparable *other)
-{
- g_return_val_if_fail (GCR_IS_COMPARABLE (self), -1);
- g_return_val_if_fail (GCR_COMPARABLE_GET_INTERFACE (self)->compare, -1);
- g_return_val_if_fail (G_IS_OBJECT (self), -1);
- return GCR_COMPARABLE_GET_INTERFACE (self)->compare (self, other);
-}
-
-/**
- * gcr_comparable_memcmp: (skip)
- * @mem1: First block of memory
- * @size1: Length of first block
- * @mem2: Second lock of memory
- * @size2: Length of second block
- *
- * Compare two blocks of memory. The return value can be used to sort
- * the blocks of memory.
- *
- * Returns: Zero if the blocks are identical, non-zero if not.
- */
-gint
-gcr_comparable_memcmp (gconstpointer mem1, gsize size1,
- gconstpointer mem2, gsize size2)
-{
- gint result;
-
- if (mem1 == mem2 && size1 == size2)
- return 0;
-
- if (!mem1)
- return 1;
- if (!mem2)
- return -1;
-
- result = memcmp (mem1, mem2, MIN (size1, size2));
- if (result != 0)
- return result;
-
- if (size1 == size2)
- return 0;
- if (size1 < size2)
- return -1;
- return 1;
-}
diff --git a/gcr/gcr-comparable.h b/gcr/gcr-comparable.h
deleted file mode 100644
index 39f1d8ad..00000000
--- a/gcr/gcr-comparable.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_COMPARABLE_H__
-#define __GCR_COMPARABLE_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_COMPARABLE (gcr_comparable_get_type())
-#define GCR_COMPARABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COMPARABLE, GcrComparable))
-#define GCR_IS_COMPARABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COMPARABLE))
-#define GCR_COMPARABLE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_COMPARABLE, GcrComparableIface))
-
-typedef struct _GcrComparable GcrComparable;
-typedef struct _GcrComparableIface GcrComparableIface;
-
-struct _GcrComparableIface {
- GTypeInterface parent;
- gint (*compare) (GcrComparable *self, GcrComparable *other);
-};
-
-GType gcr_comparable_get_type (void);
-
-gint gcr_comparable_compare (GcrComparable *self,
- GcrComparable *other);
-
-gint gcr_comparable_memcmp (gconstpointer mem1,
- gsize size1,
- gconstpointer mem2,
- gsize size2);
-
-G_END_DECLS
-
-#endif /* __GCR_COMPARABLE_H__ */
diff --git a/gcr/gcr-crypto-types.xml b/gcr/gcr-crypto-types.xml
deleted file mode 100644
index b911ccd9..00000000
--- a/gcr/gcr-crypto-types.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
-
- <!-- Non standard: Common practice -->
- <mime-type type="application/x-pem-file">
- <comment>Openssl PEM format</comment>
- <acronym>PEM</acronym>
- <sub-class-of type="text/plain"/>
- <glob weight="50" pattern="*.pem"/>
- </mime-type>
-
- <!-- Defined in: http://www.ietf.org/rfc/rfc2585.txt -->
- <mime-type type="application/pkix-cert">
- <comment>X.509 Certificate</comment>
- <glob weight="75" pattern="*.cer"/>
-
- <!-- Non standard: Common practice -->
- <glob weight="55" pattern="*.crt"/>
- <glob weight="55" pattern="*.cert"/>
-
- <!-- Non standard: Common practice -->
- <alias type="application/x-x509-ca-cert"/>
- <alias type="application/x-x509-user-cert"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkix-cert+pem">
- <comment>X.509 Certificate in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN CERTIFICATE-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Defined in: http://www.ietf.org/rfc/rfc2585.txt -->
- <mime-type type="application/pkix-crl">
- <comment>Certificate Revocation List</comment>
- <acronym>CRL</acronym>
- <expanded-acronym>Certificate Revocation List</expanded-acronym>
- <glob weight="75" pattern="*.crl"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkix-crl+pem">
- <comment>Certificate Revocation List in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN X509 CRL-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Non standard: Common practice -->
- <mime-type type="application/x-pkcs12">
- <comment>PKCS#12 Personal Key and Certificates</comment>
- <acronym>PKCS#12</acronym>
- <glob weight="75" pattern="*.p12"/>
-
- <!-- Non standard: Microsoft practice -->
- <glob weight="55" pattern="*.pfx"/>
-
- <!-- Non standard: Rare practice, unclear this actually got into a spec -->
- <alias type="application/pkcs12"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkcs12+pem">
- <comment>PKCS#12 Personal Key and Certificates in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN PKCS12-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Defined in: http://www.ietf.org/rfc/rfc5958.txt -->
- <mime-type type="application/pkcs8">
- <comment>PKCS#8 Personal Key</comment>
- <acronym>PKCS#8</acronym>
- <glob weight="75" pattern="*.p8"/>
-
- <!-- Non standard: Gnome keyring practice -->
- <glob weight="55" pattern="*.pkcs8"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkcs8+pem">
- <comment>PKCS#8 Personal Key in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN PRIVATE KEY-----" offset="0"/>
- <match type="string" value="-----BEGIN ENCRYPTED PRIVATE KEY-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Defined in: http://www.ietf.org/rfc/rfc2311.txt -->
- <mime-type type="application/pkcs7-mime">
- <comment>PKCS#7 Message and Certificates</comment>
- <acronym>PKCS#7</acronym>
- <glob pattern="*.p7c"/>
- <glob pattern="*.p7m"/>
-
- <!-- Not standard: Microsoft practice -->
- <glob pattern="*.spc"/>
- <glob pattern="*.p7b"/>
-
- <!-- Non standard: Microsoft practice -->
- <alias type="application/x-pkcs7-certificates"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkcs7-mime+pem">
- <comment>PKCS#7 Message and Certificates in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN PKCS7-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Defined in http://www.ietf.org/rfc/rfc2311.txt -->
- <mime-type type="application/pkcs7-signature">
- <comment>PKCS#7 Signature</comment>
- <acronym>PKCS#7</acronym>
- <glob pattern="*.p7s"/>
- </mime-type>
-
- <!-- Defined in http://www.ietf.org/rfc/rfc2311.txt -->
- <mime-type type="application/pkcs10">
- <comment>PKCS#10 Certificate Request</comment>
- <acronym>PKCS#10</acronym>
- <glob pattern="*.p10"/>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/pkcs10+pem">
- <comment>PKCS#10 Certificate Request in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN CERTIFICATE REQUEST-----" offset="0"/>
- <match type="string" value="-----BEGIN NEW CERTIFICATE REQUEST-----" offset="0"/>
- </magic>
- </mime-type>
-
- <!-- Non standard: OpenSSL PEM format -->
- <mime-type type="application/x-pem-key">
- <comment>Private Key in PEM format</comment>
- <sub-class-of type="application/x-pem-file"/>
- <magic priority="75">
- <match type="string" value="-----BEGIN RSA PRIVATE KEY-----" offset="0"/>
- <match type="string" value="-----BEGIN DSA PRIVATE KEY-----" offset="0"/>
- </magic>
- </mime-type>
-</mime-info>
diff --git a/gcr/gcr-debug.c b/gcr/gcr-debug.c
deleted file mode 100644
index fea8fee8..00000000
--- a/gcr/gcr-debug.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/*
- * Copyright (C) 2007 Collabora Ltd.
- * Copyright (C) 2007 Nokia Corporation
- *
- * This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include "gcr-debug.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#ifdef WITH_DEBUG
-
-static GcrDebugFlags current_flags = 0;
-
-static GDebugKey keys[] = {
- { "library", GCR_DEBUG_LIBRARY },
- { "certificate-chain", GCR_DEBUG_CERTIFICATE_CHAIN },
- { "parse", GCR_DEBUG_PARSE },
- { "gnupg", GCR_DEBUG_GNUPG },
- { "trust", GCR_DEBUG_TRUST },
- { "import", GCR_DEBUG_IMPORT },
- { 0, }
-};
-
-static void
-debug_set_flags (GcrDebugFlags new_flags)
-{
- current_flags |= new_flags;
-}
-
-void
-_gcr_debug_set_flags (const gchar *flags_string)
-{
- guint nkeys;
-
- for (nkeys = 0; keys[nkeys].value; nkeys++);
-
- if (flags_string)
- debug_set_flags (g_parse_debug_string (flags_string, keys, nkeys));
-}
-
-gboolean
-_gcr_debug_flag_is_set (GcrDebugFlags flag)
-{
- return (flag & current_flags) != 0;
-}
-
-void
-_gcr_debug_message (GcrDebugFlags flag, const gchar *format, ...)
-{
- static gsize initialized_flags = 0;
- gchar *message;
- va_list args;
-
- if (g_once_init_enter (&initialized_flags)) {
- _gcr_debug_set_flags (g_getenv ("GCR_DEBUG"));
- g_once_init_leave (&initialized_flags, 1);
- }
-
- va_start (args, format);
- message = g_strdup_vprintf (format, args);
- va_end (args);
-
- if (flag & current_flags)
- g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s", message);
-
- g_free (message);
-}
-
-#else /* !WITH_DEBUG */
-
-gboolean
-_gcr_debug_flag_is_set (GcrDebugFlags flag)
-{
- return FALSE;
-}
-
-void
-_gcr_debug_message (GcrDebugFlags flag, const gchar *format, ...)
-{
-}
-
-void
-_gcr_debug_set_flags (const gchar *flags_string)
-{
-}
-
-#endif /* !WITH_DEBUG */
diff --git a/gcr/gcr-debug.h b/gcr/gcr-debug.h
deleted file mode 100644
index 20bc35f4..00000000
--- a/gcr/gcr-debug.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007 Nokia Corporation
- * Copyright (C) 2007-2011 Collabora Ltd.
- *
- * This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef GCR_DEBUG_H
-#define GCR_DEBUG_H
-
-#include "config.h"
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-/* Please keep this enum in sync with #keys in gcr-debug.c */
-typedef enum {
- GCR_DEBUG_LIBRARY = 1 << 1,
- GCR_DEBUG_CERTIFICATE_CHAIN = 1 << 2,
- GCR_DEBUG_PARSE = 1 << 3,
- GCR_DEBUG_GNUPG = 1 << 4,
- GCR_DEBUG_TRUST = 1 << 5,
- GCR_DEBUG_IMPORT = 1 << 6,
-} GcrDebugFlags;
-
-gboolean _gcr_debug_flag_is_set (GcrDebugFlags flag);
-
-void _gcr_debug_set_flags (const gchar *flags_string);
-
-void _gcr_debug_message (GcrDebugFlags flag,
- const gchar *format,
- ...) G_GNUC_PRINTF (2, 3);
-
-G_END_DECLS
-
-#endif /* GCR_DEBUG_H */
-
-/* -----------------------------------------------------------------------------
- * Below this point is outside the GCR_DEBUG_H guard - so it can take effect
- * more than once. So you can do:
- *
- * #define DEBUG_FLAG GCR_DEBUG_ONE_THING
- * #include "gcr-debug.h"
- * ...
- * DEBUG ("if we're debugging one thing");
- * ...
- * #undef DEBUG_FLAG
- * #define DEBUG_FLAG GCR_DEBUG_OTHER_THING
- * #include "gcr-debug.h"
- * ...
- * DEBUG ("if we're debugging the other thing");
- * ...
- */
-
-#ifdef DEBUG_FLAG
-#ifdef WITH_DEBUG
-
-#undef _gcr_debug
-#define _gcr_debug(format, ...) \
- _gcr_debug_message (DEBUG_FLAG, "%s: " format, G_STRFUNC, ##__VA_ARGS__)
-
-#undef _gcr_debugging
-#define _gcr_debugging \
- _gcr_debug_flag_is_set (DEBUG_FLAG)
-
-#else /* !defined (WITH_DEBUG) */
-
-#undef _gcr_debug
-#define _gcr_debug(format, ...) \
- do {} while (0)
-
-#undef _gcr_debugging
-#define _gcr_debugging 0
-
-#endif /* !defined (WITH_DEBUG) */
-
-#endif /* defined (DEBUG_FLAG) */
diff --git a/gcr/gcr-deprecated-base.h b/gcr/gcr-deprecated-base.h
deleted file mode 100644
index 6ecfd904..00000000
--- a/gcr/gcr-deprecated-base.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_BASE_DEPRECATED_H_
-#define GCR_BASE_DEPRECATED_H_
-#ifndef GCR_DISABLE_DEPRECATED
-#ifndef __GI_SCANNER__
-
-#include <glib.h>
-
-#include "gcr-importer.h"
-#include "gcr-parser.h"
-#include "gcr-simple-collection.h"
-
-G_BEGIN_DECLS
-
-#define GCR_ERROR (gcr_error_get_domain ())
-
-GQuark gcr_error_get_domain (void) G_GNUC_CONST;
-
-gboolean gcr_simple_collection_contains (GcrSimpleCollection *self,
- GObject *object);
-
-GcrParser * gcr_importer_get_parser (GcrImporter *self);
-
-void gcr_importer_set_parser (GcrImporter *self,
- GcrParser *parser);
-
-GckSlot * gcr_importer_get_slot (GcrImporter *self);
-
-void gcr_importer_set_slot (GcrImporter *self,
- GckSlot *slot);
-
-typedef enum {
- GCR_IMPORTER_PROMPT_NEEDED,
- GCR_IMPORTER_PROMPT_ALWAYS,
- GCR_IMPORTER_PROMPT_NEVER
-} GcrImporterPromptBehavior;
-
-GcrImporterPromptBehavior gcr_importer_get_prompt_behavior (GcrImporter *self);
-
-void gcr_importer_set_prompt_behavior (GcrImporter *self,
- GcrImporterPromptBehavior behavior);
-
-G_END_DECLS
-
-#endif /* __GI_SCANNER__ */
-#endif /* GCR_DISABLE_DEPRECATED */
-#endif /* GCRTYPES_H_ */
diff --git a/gcr/gcr-deprecated.h b/gcr/gcr-deprecated.h
deleted file mode 100644
index 3447c845..00000000
--- a/gcr/gcr-deprecated.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_DEPRECATED_H_
-#define GCR_DEPRECATED_H_
-#ifndef GCR_DISABLE_DEPRECATED
-#ifndef __GI_SCANNER__
-
-#include <glib.h>
-
-#include "gcr-certificate-basics-widget.h"
-#include "gcr-certificate-details-widget.h"
-#include "gcr-viewer.h"
-
-G_BEGIN_DECLS
-
-void gcr_renderer_render (GcrRenderer *self,
- GcrViewer *viewer);
-
-G_END_DECLS
-
-#endif /* __GI_SCANNER__ */
-#endif /* GCR_DISABLE_DEPRECATED */
-#endif /* GCRTYPES_H_ */
diff --git a/gcr/gcr-dialog-util.c b/gcr/gcr-dialog-util.c
deleted file mode 100644
index c142c351..00000000
--- a/gcr/gcr-dialog-util.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-dialog-util.h"
-
-#include <string.h>
-
-typedef struct {
- GtkDialog *dialog;
- gint response_id;
- gboolean was_modal;
- gboolean destroyed;
- gulong response_sig;
- gulong unmap_sig;
- gulong delete_sig;
- gulong destroy_sig;
-} DialogRunClosure;
-
-static void
-dialog_run_closure_free (gpointer data)
-{
- DialogRunClosure *closure = data;
- g_object_unref (closure->dialog);
- g_assert (closure->response_sig == 0);
- g_assert (closure->unmap_sig == 0);
- g_assert (closure->delete_sig == 0);
- g_assert (closure->destroy_sig == 0);
- g_free (closure);
-}
-
-static void
-complete_async_result (GSimpleAsyncResult *res)
-{
- DialogRunClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
-
- g_object_ref (res);
-
- if (!closure->destroyed) {
- if (!closure->was_modal)
- gtk_window_set_modal (GTK_WINDOW (closure->dialog), FALSE);
-
- g_signal_handler_disconnect (closure->dialog, closure->response_sig);
- closure->response_sig = 0;
- g_signal_handler_disconnect (closure->dialog, closure->unmap_sig);
- closure->unmap_sig = 0;
- g_signal_handler_disconnect (closure->dialog, closure->delete_sig);
- closure->delete_sig = 0;
- g_signal_handler_disconnect (closure->dialog, closure->destroy_sig);
- closure->destroy_sig = 0;
- }
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-on_dialog_unmap (GtkDialog *dialog,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-
- complete_async_result (res);
-}
-
-static void
-on_dialog_response (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- DialogRunClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
-
- closure->response_id = response_id;
- complete_async_result (res);
-}
-
-static gint
-on_dialog_delete (GtkDialog *dialog,
- GdkEventAny *event,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- complete_async_result (res);
- return TRUE; /* Do not destroy */
-}
-
-static void
-on_dialog_destroy (GtkDialog *dialog,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- DialogRunClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
-
- /* complete will be called by run_unmap_handler */
- closure->destroyed = TRUE;
-}
-
-void
-_gcr_dialog_util_run_async (GtkDialog *dialog,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- DialogRunClosure *closure;
-
- g_return_if_fail (GTK_IS_DIALOG (dialog));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- res = g_simple_async_result_new (G_OBJECT (dialog), callback, user_data,
- _gcr_dialog_util_run_async);
- closure = g_new0 (DialogRunClosure, 1);
-
- closure->dialog = g_object_ref (dialog);
- closure->response_id = GTK_RESPONSE_NONE;
- closure->was_modal = gtk_window_get_modal (GTK_WINDOW (dialog));
- if (!closure->was_modal)
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
- if (!gtk_widget_get_visible (GTK_WIDGET (dialog)))
- gtk_widget_show (GTK_WIDGET (dialog));
-
- g_simple_async_result_set_op_res_gpointer (res, closure, dialog_run_closure_free);
-
- closure->response_sig = g_signal_connect_data (dialog, "response",
- G_CALLBACK (on_dialog_response),
- g_object_ref (res),
- (GClosureNotify)g_object_unref, 0);
-
- closure->unmap_sig = g_signal_connect_data (dialog, "unmap",
- G_CALLBACK (on_dialog_unmap),
- g_object_ref (res),
- (GClosureNotify)g_object_unref, 0);
-
- closure->delete_sig = g_signal_connect_data (dialog, "delete-event",
- G_CALLBACK (on_dialog_delete),
- g_object_ref (res),
- (GClosureNotify)g_object_unref, 0);
-
- closure->destroy_sig = g_signal_connect_data (dialog, "destroy",
- G_CALLBACK (on_dialog_destroy),
- g_object_ref (res),
- (GClosureNotify)g_object_unref, 0);
-
- g_object_unref (res);
-}
-
-
-gint
-_gcr_dialog_util_run_finish (GtkDialog *dialog,
- GAsyncResult *result)
-{
- DialogRunClosure *closure;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (dialog),
- _gcr_dialog_util_run_async), GTK_RESPONSE_NONE);
-
- closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- return closure->response_id;
-}
diff --git a/gcr/gcr-dialog-util.h b/gcr/gcr-dialog-util.h
deleted file mode 100644
index 4be48fd6..00000000
--- a/gcr/gcr-dialog-util.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_DIALOG_UTIL_H
-#define GCR_DIALOG_UTIL_H
-
-#include <gtk/gtk.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-void _gcr_dialog_util_run_async (GtkDialog *dialog,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gint _gcr_dialog_util_run_finish (GtkDialog *dialog,
- GAsyncResult *result);
-
-G_END_DECLS
-
-#endif /* __GCR_TOKEN_MANAGER_H__ */
diff --git a/gcr/gcr-display-scrolled.c b/gcr/gcr-display-scrolled.c
deleted file mode 100644
index 49d2dd98..00000000
--- a/gcr/gcr-display-scrolled.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-
-#include "config.h"
-
-#include "gcr-display-scrolled.h"
-#include "gcr-viewer.h"
-
-static void _gcr_display_scrolled_viewer_iface (GcrViewerIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrDisplayScrolled, _gcr_display_scrolled, GTK_TYPE_SCROLLED_WINDOW,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEWER, _gcr_display_scrolled_viewer_iface));
-
-struct _GcrDisplayScrolledPrivate {
- GcrViewer *internal;
-};
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-_gcr_display_scrolled_init (GcrDisplayScrolled *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledPrivate));
- self->pv->internal = gcr_viewer_new ();
-}
-
-static void
-_gcr_display_scrolled_constructed (GObject *object)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (object);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self), GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->internal));
- gtk_widget_show (GTK_WIDGET (self->pv->internal));
-}
-
-static void
-_gcr_display_scrolled_get_preferred_height (GtkWidget *widget, gint *minimal_height,
- gint *natural_height)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (widget);
- gint minimal, natural;
-
- GTK_WIDGET_CLASS (_gcr_display_scrolled_parent_class)->get_preferred_height (widget,
- minimal_height,
- natural_height);
-
- minimal = 0;
- natural = 0;
-
- gtk_widget_get_preferred_height (GTK_WIDGET (self->pv->internal),
- &minimal, &natural);
-
- /* This is messy, we add a extra for the etching height */
- *minimal_height = MAX (minimal + 3, *minimal_height);
- *natural_height = MAX (natural + 3, *natural_height);
-}
-
-static void
-_gcr_display_scrolled_get_preferred_width (GtkWidget *widget, gint *minimal_width,
- gint *natural_width)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (widget);
- gint minimal, natural;
-
- GTK_WIDGET_CLASS (_gcr_display_scrolled_parent_class)->get_preferred_width (widget,
- minimal_width,
- natural_width);
-
- minimal = 0;
- natural = 0;
-
- gtk_widget_get_preferred_width (GTK_WIDGET (self->pv->internal),
- &minimal, &natural);
-
- /* This is messy, we add a extra for the scrollbar width, etching */
- *minimal_width = MAX (minimal + 32, *minimal_width);
- *natural_width = MAX (natural + 32, *natural_width);
-}
-
-static void
-_gcr_display_scrolled_class_init (GcrDisplayScrolledClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- widget_class->get_preferred_height = _gcr_display_scrolled_get_preferred_height;
- widget_class->get_preferred_width = _gcr_display_scrolled_get_preferred_width;
-
- object_class->constructed = _gcr_display_scrolled_constructed;
-
- g_type_class_add_private (klass, sizeof (GcrDisplayScrolledPrivate));
-}
-
-static void
-_gcr_display_scrolled_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
- gcr_viewer_add_renderer (self->pv->internal, renderer);
-}
-
-static void
-_gcr_display_scrolled_real_insert_renderer (GcrViewer *viewer,
- GcrRenderer *renderer,
- GcrRenderer *before)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
- gcr_viewer_insert_renderer (self->pv->internal, renderer, before);
-}
-
-static void
-_gcr_display_scrolled_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
- gcr_viewer_remove_renderer (self->pv->internal, renderer);
-}
-
-static guint
-_gcr_display_scrolled_real_count_renderers (GcrViewer *viewer)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
- return gcr_viewer_count_renderers (self->pv->internal);
-}
-
-static GcrRenderer*
-_gcr_display_scrolled_real_get_renderer (GcrViewer *viewer, guint index_)
-{
- GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
- return gcr_viewer_get_renderer (self->pv->internal, index_);
-}
-
-static void
-_gcr_display_scrolled_viewer_iface (GcrViewerIface *iface)
-{
- iface->add_renderer = _gcr_display_scrolled_real_add_renderer;
- iface->insert_renderer = _gcr_display_scrolled_real_insert_renderer;
- iface->remove_renderer = _gcr_display_scrolled_real_remove_renderer;
- iface->count_renderers = _gcr_display_scrolled_real_count_renderers;
- iface->get_renderer = _gcr_display_scrolled_real_get_renderer;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-GcrDisplayScrolled*
-_gcr_display_scrolled_new (void)
-{
- return g_object_new (GCR_TYPE_DISPLAY_SCROLLED, NULL);
-}
diff --git a/gcr/gcr-display-scrolled.h b/gcr/gcr-display-scrolled.h
deleted file mode 100644
index 8c4a4ae8..00000000
--- a/gcr/gcr-display-scrolled.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_DISPLAY_SCROLLED_H__
-#define __GCR_DISPLAY_SCROLLED_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_DISPLAY_SCROLLED (_gcr_display_scrolled_get_type ())
-#define GCR_DISPLAY_SCROLLED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolled))
-#define GCR_DISPLAY_SCROLLED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledClass))
-#define GCR_IS_DISPLAY_SCROLLED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_DISPLAY_SCROLLED))
-#define GCR_IS_DISPLAY_SCROLLED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_DISPLAY_SCROLLED))
-#define GCR_DISPLAY_SCROLLED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledClass))
-
-typedef struct _GcrDisplayScrolled GcrDisplayScrolled;
-typedef struct _GcrDisplayScrolledClass GcrDisplayScrolledClass;
-typedef struct _GcrDisplayScrolledPrivate GcrDisplayScrolledPrivate;
-
-struct _GcrDisplayScrolled {
- /*< private >*/
- GtkScrolledWindow parent;
- GcrDisplayScrolledPrivate *pv;
-};
-
-struct _GcrDisplayScrolledClass {
- GtkScrolledWindowClass parent_class;
-};
-
-GType _gcr_display_scrolled_get_type (void);
-
-GcrDisplayScrolled* _gcr_display_scrolled_new (void);
-
-G_END_DECLS
-
-#endif /* __GCR_DISPLAY_SCROLLED_H__ */
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
deleted file mode 100644
index 8010a689..00000000
--- a/gcr/gcr-display-view.c
+++ /dev/null
@@ -1,1243 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-display-view.h"
-#include "gcr-renderer.h"
-#include "gcr-viewer.h"
-
-#include "egg/egg-oid.h"
-#include "egg/egg-hex.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-static void _gcr_display_view_viewer_iface (GcrViewerIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrDisplayView, _gcr_display_view, GTK_TYPE_TEXT_VIEW,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEWER, _gcr_display_view_viewer_iface));
-
-#define ZWSP "\342\200\213"
-#define NORMAL_MARGIN 10
-#define FIELD_MARGIN 17
-#define COLUMN_MARGIN 6
-#define ICON_MARGIN 8
-#define MESSAGE_PADDING 8
-
-typedef struct _GcrDisplayItem {
- GcrDisplayView *display_view;
- GcrRenderer *renderer;
- gboolean expanded;
- gboolean details;
- GtkTextMark *beginning;
- GtkTextMark *ending;
- GtkWidget *details_widget;
- GtkTextChildAnchor *area_anchor;
- GtkTextTag *extra_tag;
- gint field_width;
- GdkPixbuf *pixbuf;
- GtkTextTag *field_tag;
- GtkTextTag *details_tag;
- gulong data_changed_id;
-} GcrDisplayItem;
-
-struct _GcrDisplayViewPrivate {
- GtkTextBuffer *buffer;
- GPtrArray *renderers;
- GHashTable *items;
- GtkTextTag *title_tag;
- GtkTextTag *content_tag;
- GtkTextTag *heading_tag;
- GtkTextTag *message_tag;
- GtkTextTag *monospace_tag;
- GtkTextTag *area_tag;
- GcrDisplayItem *current_item;
- gint text_height;
- GdkCursor *cursor;
-
- gboolean have_measurements;
- gint minimal_width;
- gint natural_width;
- gint minimal_height;
- gint natural_height;
-};
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-ensure_measurements (GcrDisplayView *self)
-{
- PangoLayout *layout;
- PangoRectangle extents;
- gint icon_width;
- gint icon_height;
- GHashTableIter iter;
- GcrDisplayItem *item;
- gpointer value;
- gboolean expanded;
-
- if (self->pv->have_measurements)
- return;
-
- /* See if anything is expanded? */
- expanded = FALSE;
- g_hash_table_iter_init (&iter, self->pv->items);
- while (g_hash_table_iter_next (&iter, NULL, &value)) {
- item = value;
- if (item->expanded) {
- expanded = TRUE;
- break;
- }
- }
-
- /*
- * We use a string in our widget font as the basis for our measurements.
- * These are just estimates of what we need, and what looks goodish.
- * There's room here for improvement. If this is causes problems for
- * you or bothers you, scratch that itch:
- */
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "0123456789");
- pango_layout_get_extents (layout, NULL, &extents);
- pango_extents_to_pixels (&extents, NULL);
- g_object_unref (layout);
-
- if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &icon_width, &icon_height)) {
- icon_width = 48;
- icon_height = 48;
- }
-
- if (expanded) {
- /* If expanded, display more 10 lines at least */
- self->pv->minimal_height = extents.height * 14;
- self->pv->natural_height = extents.height * 25;
- } else {
- /* If not expanded we can get by with 9 lines */
- self->pv->minimal_height = extents.height * 8;
- self->pv->natural_height = extents.height * 9;
- }
-
- self->pv->minimal_width = icon_width + (extents.width * 5);
- self->pv->natural_width = icon_width + (extents.width * 8);
- self->pv->have_measurements = TRUE;
-}
-
-static void
-ensure_text_height (GcrDisplayView *self)
-{
- PangoRectangle extents;
- PangoLayout *layout;
-
- if (self->pv->text_height > 0)
- return;
-
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "Wp");
- pango_layout_get_extents (layout, NULL, &extents);
- pango_extents_to_pixels (&extents, NULL);
- g_object_unref (layout);
-
- self->pv->text_height = extents.height;
-}
-
-static void
-recalculate_and_resize (GcrDisplayView *self)
-{
- self->pv->have_measurements = FALSE;
- gtk_widget_queue_resize (GTK_WIDGET (self));
-}
-
-static GtkTextTagTable*
-create_tag_table (GcrDisplayView *self)
-{
- GtkTextTagTable *tags;
- gint width, height;
-
- g_assert (GCR_IS_DISPLAY_VIEW (self));
-
- tags = gtk_text_tag_table_new ();
-
- if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &width, &height))
- width = 48;
-
- self->pv->title_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "title",
- "scale", PANGO_SCALE_LARGE,
- "right-margin", (ICON_MARGIN * 2) + width,
- "pixels-below-lines", 6,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- gtk_text_tag_table_add (tags, self->pv->title_tag);
-
- self->pv->content_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "content",
- "right-margin", (ICON_MARGIN * 2) + width,
- "left-margin", FIELD_MARGIN,
- "pixels-below-lines", 3,
- "wrap-mode", GTK_WRAP_WORD,
- NULL);
- gtk_text_tag_table_add (tags, self->pv->content_tag);
-
- self->pv->message_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "message",
- "right-margin", (ICON_MARGIN * 2) + width,
- "rise", 3 * PANGO_SCALE,
- "pixels-below-lines", 3,
- "wrap-mode", GTK_WRAP_WORD,
- NULL);
- gtk_text_tag_table_add (tags, self->pv->message_tag);
-
- self->pv->heading_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "heading",
- "pixels-above-lines", 9,
- "pixels-below-lines", 3,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- gtk_text_tag_table_add (tags, self->pv->heading_tag);
-
- self->pv->monospace_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "monospace",
- "family", "monospace",
- NULL);
- gtk_text_tag_table_add (tags, self->pv->monospace_tag);
-
- self->pv->area_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "name", "area",
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
- gtk_text_tag_table_add (tags, self->pv->area_tag);
-
- return tags;
-}
-
-static void
-on_expander_realize (GtkWidget *widget, gpointer user_data)
-{
- GdkCursor *cursor = gdk_cursor_new (GDK_ARROW);
- gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
- g_object_unref (cursor);
-}
-
-static void
-on_expander_expanded (GObject *object, GParamSpec *param_spec, gpointer user_data)
-{
- GtkExpander *expander = GTK_EXPANDER (object);
- GcrDisplayItem *item = user_data;
- item->expanded = gtk_expander_get_expanded (expander);
- gcr_renderer_render_view (item->renderer, GCR_VIEWER (item->display_view));
- recalculate_and_resize (item->display_view);
-}
-
-static void
-style_display_item (GtkWidget *widget, GcrDisplayItem *item)
-{
- GtkStyleContext *style;
- GdkRGBA color;
-
- style = gtk_widget_get_style_context (GTK_WIDGET (widget));
- gtk_style_context_save (style);
-
- gtk_style_context_add_class (style, GTK_STYLE_CLASS_VIEW);
- gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &color);
-
- gtk_style_context_restore (style);
-
- color.red = 255;
- color.green = 0;
- color.blue = 0;
- gtk_widget_override_background_color (item->details_widget, GTK_STATE_FLAG_NORMAL, &color);
-}
-
-static GcrDisplayItem*
-create_display_item (GcrDisplayView *self, GcrRenderer *renderer)
-{
- GcrDisplayItem *item;
- GtkTextTagTable *tags;
- GtkTextIter iter;
- GtkWidget *widget;
- GtkWidget *label;
- GtkWidget *alignment;
- gchar *text;
-
- item = g_new0 (GcrDisplayItem, 1);
- item->display_view = self;
- item->renderer = renderer;
-
- tags = gtk_text_buffer_get_tag_table (self->pv->buffer);
-
- g_assert (!item->field_tag);
- item->field_width = 0;
- item->field_tag = g_object_new (GTK_TYPE_TEXT_TAG,
- "left-margin", item->field_width + FIELD_MARGIN,
- "indent", item->field_width,
- "pixels-below-lines", 3,
- "wrap-mode", GTK_WRAP_WORD_CHAR,
- NULL);
- gtk_text_tag_table_add (tags, item->field_tag);
-
- g_assert (!item->details_tag);
- item->details_tag = g_object_new (GTK_TYPE_TEXT_TAG, NULL);
- gtk_text_tag_table_add (tags, item->details_tag);
-
- /*
- * Add two lines space that delimit this from later items. The
- * item will live between the two zero width spaces.
- */
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
- gtk_text_buffer_insert (self->pv->buffer, &iter, "\n\n", -1);
- if (!gtk_text_iter_backward_char (&iter))
- g_assert_not_reached ();
-
- /* The mark that determines the beginning of this item, with left gravity. */
- item->beginning = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, TRUE);
- g_object_ref (item->beginning);
-
- /* The mark that determines the end of this item, with right gravity. */
- item->ending = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, FALSE);
- g_object_ref (item->ending);
-
- widget = gtk_expander_new_with_mnemonic ("");
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- text = g_strdup_printf ("<b>%s</b>", _("_Details"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), text);
- g_signal_connect (widget, "notify::expanded", G_CALLBACK (on_expander_expanded), item);
- g_signal_connect (widget, "realize", G_CALLBACK (on_expander_realize), NULL);
- item->expanded = gtk_expander_get_expanded (GTK_EXPANDER (widget));
- g_free (text);
-
- alignment = gtk_alignment_new (0.5, 0.5, 0.5, 0.5);
- gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 9, 0, 0);
- gtk_container_add (GTK_CONTAINER (alignment), widget);
- gtk_widget_show_all (alignment);
-
- item->details_widget = gtk_event_box_new ();
- gtk_event_box_set_visible_window (GTK_EVENT_BOX (item->details_widget), FALSE);
- gtk_container_add (GTK_CONTAINER (item->details_widget), alignment);
- g_signal_connect (item->details_widget, "realize", G_CALLBACK (on_expander_realize), NULL);
- g_object_ref (item->details_widget);
-
- if (gtk_widget_get_realized (GTK_WIDGET (self)))
- style_display_item (GTK_WIDGET (self), item);
-
- return item;
-}
-
-static void
-destroy_display_item (gpointer data)
-{
- GcrDisplayItem *item = data;
- GtkTextIter iter, end;
- GtkTextTagTable *tags;
- GcrDisplayView *self;
-
- g_assert (item);
-
- g_assert (GCR_IS_DISPLAY_VIEW (item->display_view));
- self = item->display_view;
-
- tags = gtk_text_buffer_get_tag_table (self->pv->buffer);
- gtk_text_tag_table_remove (tags, item->field_tag);
- gtk_text_tag_table_remove (tags, item->details_tag);
-
- g_object_unref (item->field_tag);
- g_object_unref (item->details_tag);
-
- if (item->pixbuf)
- g_object_unref (item->pixbuf);
- item->pixbuf = NULL;
-
- g_assert (item->details_widget);
- g_object_unref (item->details_widget);
- item->details_widget = NULL;
-
- g_clear_object (&item->area_anchor);
-
- g_return_if_fail (!gtk_text_mark_get_deleted (item->beginning));
- g_return_if_fail (!gtk_text_mark_get_deleted (item->ending));
-
- /* Setup iters to encompass our delemiter characters see create_display_item() */
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
- gtk_text_iter_backward_char (&iter);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &end, item->ending);
- gtk_text_iter_forward_char (&end);
- gtk_text_buffer_delete (self->pv->buffer, &iter, &end);
-
- gtk_text_buffer_delete_mark (self->pv->buffer, item->beginning);
- gtk_text_buffer_delete_mark (self->pv->buffer, item->ending);
-
- g_object_unref (item->beginning);
- g_object_unref (item->ending);
-
- g_free (item);
-}
-
-static GcrDisplayItem*
-lookup_display_item (GcrDisplayView *self, GcrRenderer *renderer)
-{
- GcrDisplayItem *item = g_hash_table_lookup (self->pv->items, renderer);
- g_return_val_if_fail (item, NULL);
- g_assert (item->display_view == self);
- return item;
-}
-
-static GcrDisplayItem*
-find_item_at_iter (GcrDisplayView *self, GtkTextIter *iter)
-{
- GHashTableIter hi;
- GcrDisplayItem *item;
- gpointer value;
- GtkTextIter start, end;
-
- g_hash_table_iter_init (&hi, self->pv->items);
- while (g_hash_table_iter_next (&hi, NULL, &value)) {
- item = value;
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->beginning);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &end, item->ending);
-
- if (gtk_text_iter_compare (iter, &start) >= 0 &&
- gtk_text_iter_compare (iter, &end) < 0)
- return item;
- }
-
- return NULL;
-}
-
-static void
-on_renderer_data_changed (GcrRenderer *renderer,
- gpointer user_data)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (user_data);
-
- /* Item may be removed, but not yet destroyed */
- if (!g_hash_table_lookup (self->pv->items, renderer))
- return;
-
- /* Just ask the renderer to render itself on us */
- gcr_renderer_render_view (renderer, GCR_VIEWER (self));
-}
-
-static void
-paint_item_icon (GcrDisplayView *self,
- GcrDisplayItem *item,
- GdkRectangle *visible,
- cairo_t *cr)
-{
- GtkTextIter iter;
- GdkRectangle location;
- GtkTextView *view;
-
- if (item->pixbuf == NULL)
- return;
-
- view = GTK_TEXT_VIEW (self);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
- gtk_text_view_get_iter_location (view, &iter, &location);
-
- location.height = gdk_pixbuf_get_height (item->pixbuf);
- location.width = gdk_pixbuf_get_width (item->pixbuf);
- location.x = visible->width - location.width - ICON_MARGIN;
-
- if (!gdk_rectangle_intersect (visible, &location, NULL))
- return;
-
- gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
- location.x, location.y,
- &location.x, &location.y);
-
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y);
- cairo_rectangle (cr, location.x, location.y, location.width, location.height);
- cairo_fill (cr);
- cairo_restore (cr);
-}
-
-static void
-paint_item_border (GcrDisplayView *self,
- GcrDisplayItem *item,
- GtkStyleContext *context,
- GdkRectangle *visible,
- gint index,
- cairo_t *cr)
-{
- GdkRGBA color;
- GtkTextView *view;
- GtkTextIter iter, end;
- GdkRectangle location;
-
- if (index == 0)
- return;
-
- view = GTK_TEXT_VIEW (self);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &end, item->ending);
-
- /* Don't paint for non-visible items */
- if (gtk_text_iter_compare (&iter, &end) == 0)
- return;
-
- ensure_text_height (self);
-
- gtk_style_context_get_background_color (context,
- GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED,
- &color);
-
- gtk_text_view_get_iter_location (view, &iter, &location);
-
- location.height = 2;
- location.width = visible->width - (NORMAL_MARGIN * 2);
- location.x = NORMAL_MARGIN;
- location.y -= self->pv->text_height / 2;
-
- if (!gdk_rectangle_intersect (visible, &location, NULL))
- return;
-
- gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
- location.x, location.y,
- &location.x, &location.y);
-
- cairo_save (cr);
- cairo_set_source_rgb (cr, color.red, color.green, color.blue);
- cairo_set_line_width (cr, 0.5);
- cairo_move_to (cr, location.x, location.y);
- cairo_line_to (cr, location.x + location.width, location.y);
- cairo_stroke (cr);
- cairo_restore (cr);
-}
-
-static void
-paint_extras (GcrDisplayView *self, cairo_t *cr)
-{
- GdkRectangle visible;
- GcrDisplayItem *item;
- GtkStyleContext *context;
- guint i;
-
- gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (self), &visible);
- context = gtk_widget_get_style_context (GTK_WIDGET (self));
-
- for (i = 0; i < self->pv->renderers->len; i++) {
- item = g_hash_table_lookup (self->pv->items, self->pv->renderers->pdata[i]);
- g_assert (item != NULL);
- paint_item_icon (self, item, &visible, cr);
- paint_item_border (self, item, context, &visible, i, cr);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-_gcr_display_view_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GObject *obj = G_OBJECT_CLASS (_gcr_display_view_parent_class)->constructor (type, n_props, props);
- GcrDisplayView *self = NULL;
- GtkTextView *view = NULL;
- GtkTextTagTable *tags;
-
- g_return_val_if_fail (obj, NULL);
-
- self = GCR_DISPLAY_VIEW (obj);
- view = GTK_TEXT_VIEW (obj);
-
- tags = create_tag_table (self);
- self->pv->buffer = gtk_text_buffer_new (tags);
- g_object_unref (tags);
-
- gtk_text_view_set_buffer (view, self->pv->buffer);
- gtk_text_view_set_editable (view, FALSE);
- gtk_text_view_set_left_margin (view, NORMAL_MARGIN);
- gtk_text_view_set_right_margin (view, NORMAL_MARGIN);
- gtk_text_view_set_cursor_visible (view, FALSE);
-
- return obj;
-}
-
-static void
-_gcr_display_view_init (GcrDisplayView *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_DISPLAY_VIEW, GcrDisplayViewPrivate));
- self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, destroy_display_item);
- self->pv->renderers = g_ptr_array_new_with_free_func (g_object_unref);
-}
-
-static void
-_gcr_display_view_dispose (GObject *obj)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (obj);
- GcrRenderer *renderer;
- GcrDisplayItem *item;
-
- while (self->pv->renderers->len) {
- renderer = g_ptr_array_index (self->pv->renderers, 0);
- item = g_hash_table_lookup (self->pv->items, renderer);
- g_return_if_fail (item);
- g_signal_handler_disconnect (renderer, item->data_changed_id);
- if (!g_hash_table_remove (self->pv->items, renderer))
- g_return_if_reached ();
- g_ptr_array_remove_index_fast (self->pv->renderers, 0);
- }
-
- if (self->pv->buffer)
- g_object_unref (self->pv->buffer);
- self->pv->buffer = NULL;
-
- g_assert (g_hash_table_size (self->pv->items) == 0);
-
- G_OBJECT_CLASS (_gcr_display_view_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_display_view_finalize (GObject *obj)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (obj);
-
- if (self->pv->buffer)
- g_object_unref (self->pv->buffer);
- self->pv->buffer = NULL;
-
- g_assert (g_hash_table_size (self->pv->items) == 0);
- g_hash_table_destroy (self->pv->items);
- self->pv->items = NULL;
-
- g_assert (self->pv->renderers);
- g_assert (self->pv->renderers->len == 0);
- g_ptr_array_free (self->pv->renderers, TRUE);
- self->pv->renderers = NULL;
-
- g_assert (self->pv->content_tag);
- g_object_unref (self->pv->content_tag);
- self->pv->content_tag = NULL;
-
- g_assert (self->pv->heading_tag);
- g_object_unref (self->pv->heading_tag);
- self->pv->heading_tag = NULL;
-
- g_assert (self->pv->monospace_tag);
- g_object_unref (self->pv->monospace_tag);
- self->pv->monospace_tag = NULL;
-
- g_assert (self->pv->title_tag);
- g_object_unref (self->pv->title_tag);
- self->pv->title_tag = NULL;
-
- g_clear_object (&self->pv->cursor);
-
- G_OBJECT_CLASS (_gcr_display_view_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_display_view_realize (GtkWidget *widget)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
- GHashTableIter iter;
- GdkDisplay *display;
- gpointer value;
-
- if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->realize)
- GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->realize (widget);
-
- /* Set style on all the items */
- g_hash_table_iter_init (&iter, self->pv->items);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- style_display_item (widget, value);
-
- if (!self->pv->cursor) {
- display = gtk_widget_get_display (GTK_WIDGET (self));
- self->pv->cursor = gdk_cursor_new_for_display (display, GDK_ARROW);
- }
-
- gdk_window_set_cursor (gtk_text_view_get_window (GTK_TEXT_VIEW (self), GTK_TEXT_WINDOW_WIDGET),
- self->pv->cursor);
-}
-
-static gboolean
-_gcr_display_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
-{
- GtkTextView *text_view = GTK_TEXT_VIEW (widget);
- GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
- GcrDisplayItem *item;
- gboolean handled = FALSE;
- GtkTextIter iter;
- gint x, y;
-
- if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->button_press_event)
- handled = GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->button_press_event (
- widget, event);
-
- if (event->window == gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT)) {
- gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_TEXT,
- event->x, event->y, &x, &y);
- gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
-
- item = find_item_at_iter (self, &iter);
- self->pv->current_item = item;
- }
-
- return handled;
-}
-
-static gboolean
-_gcr_display_view_draw (GtkWidget *widget, cairo_t *cr)
-{
- GdkWindow *window;
- gboolean handled = TRUE;
-
- /* Have GtkTextView draw the text first. */
- if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->draw)
- handled = GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->draw (widget, cr);
-
- window = gtk_text_view_get_window (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_TEXT);
- if (gtk_cairo_should_draw_window (cr, window))
- paint_extras (GCR_DISPLAY_VIEW (widget), cr);
-
- return handled;
-}
-
-static void
-_gcr_display_get_preferred_height (GtkWidget *widget, gint *minimal_height,
- gint *natural_height)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
- ensure_measurements (self);
- *minimal_height = self->pv->minimal_height;
- *natural_height = self->pv->natural_height;
-}
-
-static void
-_gcr_display_get_preferred_width (GtkWidget *widget, gint *minimal_width,
- gint *natural_width)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
- ensure_measurements (self);
- *minimal_width = self->pv->minimal_width;
- *natural_width = self->pv->natural_width;
-}
-
-static void
-_gcr_display_view_populate_popup (GtkTextView *text_view, GtkMenu *menu)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (text_view);
-
- if (GTK_TEXT_VIEW_CLASS (_gcr_display_view_parent_class)->populate_popup)
- GTK_TEXT_VIEW_CLASS (_gcr_display_view_parent_class)->populate_popup (text_view, menu);
-
- /* Ask the current renderer to add menu items */
- if (self->pv->current_item)
- gcr_renderer_popuplate_popup (self->pv->current_item->renderer,
- GCR_VIEWER (self), menu);
-}
-
-static void
-_gcr_display_view_class_init (GcrDisplayViewClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS (klass);
-
- _gcr_display_view_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrDisplayViewPrivate));
-
- gobject_class->constructor = _gcr_display_view_constructor;
- gobject_class->dispose = _gcr_display_view_dispose;
- gobject_class->finalize = _gcr_display_view_finalize;
-
- widget_class->realize = _gcr_display_view_realize;
- widget_class->button_press_event = _gcr_display_view_button_press_event;
- widget_class->get_preferred_height = _gcr_display_get_preferred_height;
- widget_class->get_preferred_width = _gcr_display_get_preferred_width;
- widget_class->draw = _gcr_display_view_draw;
-
- text_view_class->populate_popup = _gcr_display_view_populate_popup;
-}
-
-static void
-_gcr_display_view_real_insert_renderer (GcrViewer *viewer,
- GcrRenderer *renderer,
- GcrRenderer *before)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
- GcrDisplayItem *item;
- guint i;
-
- if (before != NULL)
- g_return_if_fail (g_hash_table_lookup (self->pv->items, before) != NULL);
-
- item = create_display_item (self, renderer);
- g_object_ref (renderer);
-
- /* Insert it at the right place */
- if (before != NULL) {
- g_ptr_array_add (self->pv->renderers, NULL);
- for (i = self->pv->renderers->len; i > 0; i--) {
- self->pv->renderers->pdata[i] = self->pv->renderers->pdata[i - 1];
- if (self->pv->renderers->pdata[i] == before) {
- self->pv->renderers->pdata[i - 1] = renderer;
- break;
- }
- }
-
- /* Must have been found */
- g_assert (i > 0);
-
- /* No before, just add to end */
- } else {
- g_ptr_array_add (self->pv->renderers, renderer);
- }
-
- g_hash_table_insert (self->pv->items, renderer, item);
-
- gcr_renderer_render_view (renderer, viewer);
- item->data_changed_id = g_signal_connect (renderer, "data-changed",
- G_CALLBACK (on_renderer_data_changed), self);
-}
-
-static void
-_gcr_display_view_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
-{
- _gcr_display_view_real_insert_renderer (viewer, renderer, NULL);
-}
-
-static void
-_gcr_display_view_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
- GcrDisplayItem *item;
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- /* Unhook the callback */
- g_signal_handler_disconnect (renderer, item->data_changed_id);
-
- /* Destroys the display item */
- g_assert (item->display_view == self);
- g_hash_table_remove (self->pv->items, renderer);
-
- /* Unrefs the renderer */
- if (!g_ptr_array_remove (self->pv->renderers, renderer))
- g_return_if_reached ();
-}
-
-static guint
-_gcr_display_view_real_count_renderers (GcrViewer *viewer)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
- return self->pv->renderers->len;
-}
-
-static GcrRenderer*
-_gcr_display_view_real_get_renderer (GcrViewer *viewer, guint index_)
-{
- GcrDisplayView *self = GCR_DISPLAY_VIEW (viewer);
- g_return_val_if_fail (index_ < self->pv->renderers->len, NULL);
- return g_ptr_array_index (self->pv->renderers, index_);
-}
-
-static void
-_gcr_display_view_viewer_iface (GcrViewerIface *iface)
-{
- iface->add_renderer = (gpointer)_gcr_display_view_real_add_renderer;
- iface->insert_renderer = (gpointer)_gcr_display_view_real_insert_renderer;
- iface->remove_renderer = (gpointer)_gcr_display_view_real_remove_renderer;
- iface->count_renderers = (gpointer)_gcr_display_view_real_count_renderers;
- iface->get_renderer = (gpointer)_gcr_display_view_real_get_renderer;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-GcrDisplayView*
-_gcr_display_view_new (void)
-{
- return g_object_new (GCR_TYPE_DISPLAY_VIEW, NULL);
-}
-
-void
-_gcr_display_view_begin (GcrDisplayView *self,
- GcrRenderer *renderer)
-{
- GtkTextIter start, iter;
- GcrDisplayItem *item;
- GList *widgets, *l;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- /* Remove the details widget so it doesn't get destroyed */
- if (gtk_widget_get_parent (item->details_widget))
- gtk_container_remove (GTK_CONTAINER (self), item->details_widget);
-
- /* Remove area widgets so they don't get destroyed unnecessarily */
- if (item->area_anchor) {
- g_assert (!gtk_text_child_anchor_get_deleted (item->area_anchor));
- widgets = gtk_text_child_anchor_get_widgets (item->area_anchor);
- for (l = widgets; l != NULL; l = g_list_next (l))
- gtk_container_remove (GTK_CONTAINER (self), l->data);
- g_list_free (widgets);
- g_object_unref (item->area_anchor);
- item->area_anchor = NULL;
- }
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->beginning);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
-
- item->extra_tag = NULL;
- item->field_width = 0;
- item->details = FALSE;
-}
-
-void
-_gcr_display_view_end (GcrDisplayView *self,
- GcrRenderer *renderer)
-{
- GcrDisplayItem *item;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-}
-
-void
-_gcr_display_view_start_details (GcrDisplayView *self, GcrRenderer *renderer)
-{
- GtkTextChildAnchor *anchor;
- GcrDisplayItem *item;
- GtkTextIter iter;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->details) {
- g_warning ("A GcrRenderer implementation has called %s twice in one render",
- G_STRFUNC);
- return;
- }
-
- item->extra_tag = item->details_tag;
- item->details = TRUE;
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- anchor = gtk_text_buffer_create_child_anchor (self->pv->buffer, &iter);
- gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), item->details_widget, anchor);
- gtk_widget_show_all (item->details_widget);
- gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1);
-}
-
-void
-_gcr_display_view_append_content (GcrDisplayView *self, GcrRenderer *renderer,
- const gchar *content, const gchar *details)
-{
- GcrDisplayItem *item;
- GtkTextIter iter;
- gchar *memory = NULL;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (content);
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->details && !item->expanded)
- return;
-
- if (details)
- content = memory = g_strdup_printf ("%s: %s", content, details);
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, content, -1,
- self->pv->content_tag, item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
- item->extra_tag, NULL);
-
- g_free (memory);
-}
-
-void
-_gcr_display_view_append_value (GcrDisplayView *self, GcrRenderer *renderer, const gchar *field,
- const gchar *value, gboolean monospace)
-{
- GcrDisplayItem *item;
- PangoRectangle extents;
- PangoTabArray *tabs;
- PangoLayout *layout;
- GtkTextIter iter;
- gchar *text;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (field);
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->details && !item->expanded)
- return;
-
- text = g_strdup_printf ("%s:", field);
- if (value == NULL)
- value = "";
-
- /* Measure the width of the field */
- layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), text);
- pango_layout_get_extents (layout, NULL, &extents);
- pango_extents_to_pixels (&extents, NULL);
- g_object_unref (layout);
-
- /* An estimate of the text height */
- self->pv->text_height = extents.height;
-
- /* Make the tab wide enough to accomodate */
- if (extents.width > item->field_width) {
- item->field_width = extents.width + COLUMN_MARGIN;
- tabs = pango_tab_array_new (1, TRUE);
- pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, item->field_width);
- g_object_set (item->field_tag,
- "left-margin", FIELD_MARGIN,
- "indent", 0 - item->field_width,
- "tabs", tabs,
- NULL);
- pango_tab_array_free (tabs);
- }
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, text, -1,
- item->field_tag, item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\t", 1,
- item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, value, -1, item->field_tag,
- monospace ? self->pv->monospace_tag : item->extra_tag,
- monospace ? item->extra_tag : NULL, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
- item->extra_tag, NULL);
-
- g_free (text);
-}
-
-void
-_gcr_display_view_append_hex (GcrDisplayView *self, GcrRenderer *renderer,
- const gchar *field, gconstpointer value, gsize n_value)
-{
- gchar *display;
-
- display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
- _gcr_display_view_append_value (self, renderer, field, display, TRUE);
- g_free (display);
-}
-
-void
-_gcr_display_view_append_title (GcrDisplayView *self, GcrRenderer *renderer, const gchar *title)
-{
- GcrDisplayItem *item;
- GtkTextIter iter;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (title);
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->details && !item->expanded)
- return;
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, title, -1,
- self->pv->title_tag, item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
- item->extra_tag, NULL);
-}
-
-void
-_gcr_display_view_append_heading (GcrDisplayView *self, GcrRenderer *renderer, const gchar *heading)
-{
- GcrDisplayItem *item;
- GtkTextIter iter;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (heading);
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->details && !item->expanded)
- return;
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, heading, -1,
- self->pv->heading_tag, item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
- item->extra_tag, NULL);
-}
-
-void
-_gcr_display_view_append_fingerprint (GcrDisplayView *self, GcrRenderer *renderer, const guchar *data,
- gsize n_data, const gchar *name, GChecksumType type)
-{
- GChecksum *checksum;
- guint8 *buffer;
- gsize n_buffer;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
-
- checksum = g_checksum_new (type);
- g_return_if_fail (checksum);
- g_checksum_update (checksum, data, n_data);
-
- n_buffer = g_checksum_type_get_length (type);
- g_return_if_fail (n_buffer);
- buffer = g_malloc0 (n_buffer);
-
- g_checksum_get_digest (checksum, buffer, &n_buffer);
- g_checksum_free (checksum);
-
- _gcr_display_view_append_hex (self, renderer, name, buffer, n_buffer);
-
- g_free (buffer);
-}
-
-void
-_gcr_display_view_append_message (GcrDisplayView *self,
- GcrRenderer *renderer,
- GtkMessageType message_type,
- const gchar *message)
-{
- const gchar *stock_id = NULL;
- GtkWidget *image = NULL;
- GcrDisplayItem *item;
- GtkTextChildAnchor *anchor;
- GtkTextIter iter;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (GCR_IS_RENDERER (renderer));
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- switch (message_type) {
- case GTK_MESSAGE_INFO:
- stock_id = GTK_STOCK_DIALOG_INFO;
- break;
-
- case GTK_MESSAGE_QUESTION:
- stock_id = GTK_STOCK_DIALOG_QUESTION;
- break;
-
- case GTK_MESSAGE_WARNING:
- stock_id = GTK_STOCK_DIALOG_WARNING;
- break;
-
- case GTK_MESSAGE_ERROR:
- stock_id = GTK_STOCK_DIALOG_ERROR;
- break;
-
- case GTK_MESSAGE_OTHER:
- break;
-
- default:
- g_warning ("unknown GtkMessageType: %u", message_type);
- break;
- }
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
-
- if (stock_id != NULL) {
- image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
- gtk_misc_set_padding (GTK_MISC (image), MESSAGE_PADDING, 0);
- gtk_widget_show (image);
-
- anchor = gtk_text_buffer_create_child_anchor (self->pv->buffer, &iter);
- gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), image, anchor);
- }
-
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, message, -1,
- self->pv->message_tag, item->extra_tag, NULL);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n", 1,
- item->extra_tag, NULL);
-}
-
-void
-_gcr_display_view_set_icon (GcrDisplayView *self, GcrRenderer *renderer, GIcon *icon)
-{
- GcrDisplayItem *item;
- GdkScreen *screen;
- GtkIconTheme *icon_theme;
- GtkSettings *settings;
- gint width, height;
- GtkIconInfo *info;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item);
-
- if (item->pixbuf)
- g_object_unref (item->pixbuf);
- item->pixbuf = NULL;
-
- if (!icon)
- return;
-
- screen = gtk_widget_get_screen (GTK_WIDGET (self));
- icon_theme = gtk_icon_theme_get_for_screen (screen);
- settings = gtk_settings_get_for_screen (screen);
-
- if (!gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_DIALOG, &width, &height))
- g_return_if_reached ();
-
- info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon, MIN (width, height),
- GTK_ICON_LOOKUP_USE_BUILTIN);
-
- if (info) {
- GtkStyleContext *style = gtk_widget_get_style_context (GTK_WIDGET (self));
- item->pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, FALSE, NULL);
- gtk_icon_info_free (info);
- }
-}
-
-void
-_gcr_display_view_add_widget_area (GcrDisplayView *self,
- GcrRenderer *renderer,
- GtkWidget *area)
-{
- GtkTextIter iter, start;
- GcrDisplayItem *item;
-
- g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
- g_return_if_fail (GTK_IS_WIDGET (area));
-
- item = lookup_display_item (self, renderer);
- g_return_if_fail (item != NULL);
- g_return_if_fail (item->area_anchor == NULL);
-
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->ending);
- iter = start;
-
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, "\n" ZWSP, -1, self->pv->area_tag, NULL);
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
-
- item->area_anchor = gtk_text_buffer_create_child_anchor (self->pv->buffer, &iter);
- g_object_ref (item->area_anchor);
- gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self), area, item->area_anchor);
- gtk_text_buffer_insert_with_tags (self->pv->buffer, &iter, ZWSP "\n", -1, self->pv->area_tag, NULL);
-}
diff --git a/gcr/gcr-display-view.h b/gcr/gcr-display-view.h
deleted file mode 100644
index 0882624f..00000000
--- a/gcr/gcr-display-view.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_DISPLAY_VIEW_H__
-#define __GCR_DISPLAY_VIEW_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-certificate.h"
-#include "gcr-types.h"
-#include "gcr-viewer.h"
-
-G_BEGIN_DECLS
-
-#define GCR_DISPLAY_VIEW_LINE_BREAK 0x2028
-
-#define GCR_TYPE_DISPLAY_VIEW (_gcr_display_view_get_type ())
-#define GCR_DISPLAY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_DISPLAY_VIEW, GcrDisplayView))
-#define GCR_DISPLAY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_DISPLAY_VIEW, GcrDisplayViewClass))
-#define GCR_IS_DISPLAY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_DISPLAY_VIEW))
-#define GCR_IS_DISPLAY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_DISPLAY_VIEW))
-#define GCR_DISPLAY_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_DISPLAY_VIEW, GcrDisplayViewClass))
-
-typedef struct _GcrDisplayView GcrDisplayView;
-typedef struct _GcrDisplayViewClass GcrDisplayViewClass;
-typedef struct _GcrDisplayViewPrivate GcrDisplayViewPrivate;
-
-struct _GcrDisplayView {
- /*< private >*/
- GtkTextView parent;
- GcrDisplayViewPrivate *pv;
-};
-
-struct _GcrDisplayViewClass {
- GtkTextViewClass parent_class;
-};
-
-GType _gcr_display_view_get_type (void);
-
-GcrDisplayView* _gcr_display_view_new (void);
-
-void _gcr_display_view_begin (GcrDisplayView *self,
- GcrRenderer *renderer);
-
-void _gcr_display_view_end (GcrDisplayView *self,
- GcrRenderer *renderer);
-
-void _gcr_display_view_append_value (GcrDisplayView *self,
- GcrRenderer *renderer,
- const gchar *field,
- const gchar *value,
- gboolean monospace);
-
-void _gcr_display_view_append_hex (GcrDisplayView *self,
- GcrRenderer *renderer,
- const gchar *field,
- gconstpointer value,
- gsize n_value);
-
-void _gcr_display_view_append_title (GcrDisplayView *self,
- GcrRenderer *renderer,
- const gchar *title);
-
-void _gcr_display_view_append_content (GcrDisplayView *self,
- GcrRenderer *renderer,
- const gchar *content,
- const gchar *details);
-
-void _gcr_display_view_start_details (GcrDisplayView *self,
- GcrRenderer *renderer);
-
-void _gcr_display_view_append_heading (GcrDisplayView *self,
- GcrRenderer *renderer,
- const gchar *heading);
-
-void _gcr_display_view_append_fingerprint (GcrDisplayView *self,
- GcrRenderer *renderer,
- const guchar *data,
- gsize n_data,
- const gchar *name,
- GChecksumType type);
-
-void _gcr_display_view_append_message (GcrDisplayView *self,
- GcrRenderer *renderer,
- GtkMessageType message_type,
- const gchar *message);
-
-void _gcr_display_view_set_icon (GcrDisplayView *self,
- GcrRenderer *renderer,
- GIcon *icon);
-
-void _gcr_display_view_add_widget_area (GcrDisplayView *self,
- GcrRenderer *render,
- GtkWidget *area);
-
-G_END_DECLS
-
-#endif /* __GCR_DISPLAY_VIEW_H__ */
diff --git a/gcr/gcr-enum-types.c.template b/gcr/gcr-enum-types.c.template
deleted file mode 100644
index d6095351..00000000
--- a/gcr/gcr-enum-types.c.template
+++ /dev/null
@@ -1,43 +0,0 @@
-/*** BEGIN file-header ***/
-
-#include <glib-object.h>
-
-#ifndef GCR_COMPILATION
-#define GCR_COMPILATION
-#endif
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-#include "@filename@"
-/* enumerations from "@filename@" */
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType @enum_name@_get_type (void) G_GNUC_CONST;
-
-GType
-@enum_name@_get_type (void)
-{
- static GType etype = 0;
- if (G_UNLIKELY(etype == 0)) {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
- }
- return etype;
-}
-
-/*** END value-tail ***/
-
-/*** BEGIN file-tail ***/
- /**/
-/*** END file-tail ***/
diff --git a/gcr/gcr-enum-types.h.template b/gcr/gcr-enum-types.h.template
deleted file mode 100644
index 91d5a606..00000000
--- a/gcr/gcr-enum-types.h.template
+++ /dev/null
@@ -1,28 +0,0 @@
-/*** BEGIN file-header ***/
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_ENUM_TYPES_H__
-#define __GCR_ENUM_TYPES_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-
-/* enumerations from "@filename@" */
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType @enum_name@_get_type (void) G_GNUC_CONST;
-#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
-/*** END value-header ***/
-
-/*** BEGIN file-tail ***/
-G_END_DECLS
-
-#endif /* __GCR_ENUM_TYPES_H__ */
-/*** END file-tail ***/
diff --git a/gcr/gcr-failure-renderer.c b/gcr/gcr-failure-renderer.c
deleted file mode 100644
index 4cf84bd7..00000000
--- a/gcr/gcr-failure-renderer.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-display-view.h"
-#include "gcr-icons.h"
-#include "gcr-parser.h"
-#include "gcr-failure-renderer.h"
-
-#include "egg/egg-entry-buffer.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ATTRIBUTES
-};
-
-struct _GcrFailureRendererPrivate {
- gchar *label;
- GError *error;
-};
-
-static void gcr_renderer_iface_init (GcrRendererIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrFailureRenderer, gcr_failure_renderer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
-);
-
-static void
-gcr_failure_renderer_init (GcrFailureRenderer *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_FAILURE_RENDERER,
- GcrFailureRendererPrivate));
-}
-
-static void
-gcr_failure_renderer_finalize (GObject *obj)
-{
- GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
-
- g_error_free (self->pv->error);
- g_free (self->pv->label);
-
- G_OBJECT_CLASS (gcr_failure_renderer_parent_class)->finalize (obj);
-}
-
-static void
-gcr_failure_renderer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- case PROP_ATTRIBUTES:
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_failure_renderer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, self->pv->label);
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_failure_renderer_class_init (GcrFailureRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (GcrFailureRendererPrivate));
-
- gobject_class->finalize = gcr_failure_renderer_finalize;
- gobject_class->set_property = gcr_failure_renderer_set_property;
- gobject_class->get_property = gcr_failure_renderer_get_property;
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Failure Label",
- "", G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Renderer attributes",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-}
-
-static void
-gcr_failure_renderer_render (GcrRenderer *renderer,
- GcrViewer *viewer)
-{
- GcrFailureRenderer *self = GCR_FAILURE_RENDERER (renderer);
- GcrDisplayView *view;
- gchar *display;
- GIcon *icon;
-
- if (GCR_IS_DISPLAY_VIEW (viewer)) {
- view = GCR_DISPLAY_VIEW (viewer);
-
- } else {
- g_warning ("GcrFailureRenderer only works with internal specific "
- "GcrViewer returned by gcr_viewer_new().");
- return;
- }
-
- _gcr_display_view_begin (view, renderer);
-
- if (g_error_matches (self->pv->error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED))
- icon = g_themed_icon_new ("dialog-warning");
- else
- icon = g_themed_icon_new ("dialog-error");
- _gcr_display_view_set_icon (view, renderer, icon);
- g_object_unref (icon);
-
- _gcr_display_view_append_title (view, renderer, self->pv->label);
-
- if (self->pv->label)
- display = g_strdup_printf (_("Could not display '%s'"), self->pv->label);
- else
- display = g_strdup (_("Could not display file"));
- _gcr_display_view_append_content (view, renderer, display, NULL);
- g_free (display);
-
- if (self->pv->error->message)
- _gcr_display_view_append_value (view, renderer, _("Reason"),
- self->pv->error->message, FALSE);
-
- _gcr_display_view_end (view, renderer);
-}
-
-static void
-gcr_renderer_iface_init (GcrRendererIface *iface)
-{
- iface->render_view = gcr_failure_renderer_render;
-}
-
-/**
- * gcr_failure_renderer_new:
- * @label: (allow-none): the label for the failure
- * @error: the error to display
- *
- * Create a new renderer for an error.
- *
- * Returns: (transfer full) (type Gcr.FailureRenderer): the new renderer
- */
-GcrRenderer *
-gcr_failure_renderer_new (const gchar *label,
- GError *error)
-{
- GcrFailureRenderer *renderer;
-
- renderer = g_object_new (GCR_TYPE_FAILURE_RENDERER,
- "label", label,
- NULL);
-
- renderer->pv->error = g_error_copy (error);
- return GCR_RENDERER (renderer);
-}
-
-/**
- * gcr_failure_renderer_new_unsupported:
- * @label: the label for the failure
- *
- * Create a new renderer for unsupported data.
- *
- * Returns: (transfer full): the new renderer
- */
-GcrRenderer *
-gcr_failure_renderer_new_unsupported (const gchar *label)
-{
- GcrRenderer *renderer;
- GError *error;
-
- error = g_error_new (GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
- _("Cannot display a file of this type."));
-
- renderer = gcr_failure_renderer_new (label, error);
-
- g_error_free (error);
- return renderer;
-}
diff --git a/gcr/gcr-failure-renderer.h b/gcr/gcr-failure-renderer.h
deleted file mode 100644
index 9b70f36f..00000000
--- a/gcr/gcr-failure-renderer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_FAILURE_RENDERER_H__
-#define __GCR_FAILURE_RENDERER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-renderer.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_FAILURE_RENDERER (gcr_failure_renderer_get_type ())
-#define GCR_FAILURE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_FAILURE_RENDERER, GcrFailureRenderer))
-#define GCR_FAILURE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_FAILURE_RENDERER, GcrFailureRendererClass))
-#define GCR_IS_FAILURE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_FAILURE_RENDERER))
-#define GCR_IS_FAILURE_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_FAILURE_RENDERER))
-#define GCR_FAILURE_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_FAILURE_RENDERER, GcrFailureRendererClass))
-
-typedef struct _GcrFailureRenderer GcrFailureRenderer;
-typedef struct _GcrFailureRendererClass GcrFailureRendererClass;
-typedef struct _GcrFailureRendererPrivate GcrFailureRendererPrivate;
-
-struct _GcrFailureRenderer {
- /*< private >*/
- GObject parent;
- GcrFailureRendererPrivate *pv;
-};
-
-struct _GcrFailureRendererClass {
- /*< private >*/
- GObjectClass parent_class;
-};
-
-GType gcr_failure_renderer_get_type (void);
-
-GcrRenderer * gcr_failure_renderer_new (const gchar *label,
- GError *error);
-
-GcrRenderer * gcr_failure_renderer_new_unsupported (const gchar *label);
-
-G_END_DECLS
-
-#endif /* __GCR_FAILURE_RENDERER_H__ */
diff --git a/gcr/gcr-fingerprint.c b/gcr/gcr-fingerprint.c
deleted file mode 100644
index 39d93195..00000000
--- a/gcr/gcr-fingerprint.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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 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 License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-fingerprint.h"
-#include "gcr-oids.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-
-#include <glib.h>
-#include <gcrypt.h>
-
-/**
- * SECTION:gcr-fingerprint
- * @title: Key Fingerprints
- * @short_description: Fingerprints for public and private keys
- *
- * These functions generate key fingerprints for public keys, certificates and
- * key data. The fingerprints are created so that they they will be identical
- * for a key and its corresponding certificate.
- *
- * Note that in the case of certificates these are not fingerprints of the
- * actual certificate data, but rather of the public key contained in a
- * certificate.
- *
- * These fingerprints are created using the subjectPublicKeyInfo ASN.1 structure.
- */
-
-/**
- * gcr_fingerprint_from_subject_public_key_info:
- * @key_info: (array length=n_key_info): DER encoded subjectPublicKeyInfo structure
- * @n_key_info: length of DER encoded structure
- * @checksum_type: the type of fingerprint to create
- * @n_fingerprint: the length of fingerprint returned
- *
- * Create a key fingerprint for a DER encoded subjectPublicKeyInfo.
- *
- * Returns: (transfer full) (allow-none) (array length=n_fingerprint): the
- * fingerprint or %NULL if the input was invalid.
- */
-guchar *
-gcr_fingerprint_from_subject_public_key_info (const guchar *key_info,
- gsize n_key_info,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- GChecksum *check;
- guint8 *fingerprint;
-
- g_return_val_if_fail (key_info, NULL);
- g_return_val_if_fail (n_key_info, NULL);
- g_return_val_if_fail (n_fingerprint, NULL);
-
- check = g_checksum_new (checksum_type);
- g_return_val_if_fail (check, NULL);
-
- g_checksum_update (check, key_info, n_key_info);
-
- *n_fingerprint = g_checksum_type_get_length (checksum_type);
- fingerprint = g_malloc (*n_fingerprint);
- g_checksum_get_digest (check, fingerprint, n_fingerprint);
-
- g_checksum_free (check);
- return fingerprint;
-}
-
-static gboolean
-rsa_subject_public_key_from_attributes (GckAttributes *attrs, GNode *info_asn)
-{
- GckAttribute *modulus;
- GckAttribute *exponent;
- GNode *key_asn;
- GNode *params_asn;
- gpointer key, params;
- gsize n_key, n_params;
-
- _gcr_oids_init ();
-
- modulus = gck_attributes_find (attrs, CKA_MODULUS);
- exponent = gck_attributes_find (attrs, CKA_PUBLIC_EXPONENT);
- if (modulus == NULL || exponent == NULL)
- return FALSE;
-
- key_asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey");
- g_return_val_if_fail (key_asn, FALSE);
-
- params_asn = egg_asn1x_create (pk_asn1_tab, "RSAParameters");
- g_return_val_if_fail (params_asn, FALSE);
-
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL),
- modulus->value, modulus->length, NULL);
-
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL),
- exponent->value, exponent->length, NULL);
-
- key = egg_asn1x_encode (key_asn, g_realloc, &n_key);
- egg_asn1x_destroy (key_asn);
-
- egg_asn1x_set_null (params_asn);
-
- params = egg_asn1x_encode (params_asn, g_realloc, &n_params);
- egg_asn1x_destroy (params_asn);
-
- egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
- key, n_key * 8, g_free);
-
- egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_RSA);
- egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL),
- params, n_params, g_free);
-
- return TRUE;
-}
-
-static gboolean
-dsa_subject_public_key_from_private (GNode *key_asn, GckAttribute *ap,
- GckAttribute *aq, GckAttribute *ag, GckAttribute *ax)
-{
- gcry_mpi_t mp, mq, mg, mx, my;
- size_t n_buffer;
- gcry_error_t gcry;
- unsigned char *buffer;
-
- gcry = gcry_mpi_scan (&mp, GCRYMPI_FMT_USG, ap->value, ap->length, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- gcry = gcry_mpi_scan (&mq, GCRYMPI_FMT_USG, aq->value, aq->length, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- gcry = gcry_mpi_scan (&mg, GCRYMPI_FMT_USG, ag->value, ag->length, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- gcry = gcry_mpi_scan (&mx, GCRYMPI_FMT_USG, ax->value, ax->length, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* Calculate the public part from the private */
- my = gcry_mpi_snew (gcry_mpi_get_nbits (mx));
- g_return_val_if_fail (my, FALSE);
- gcry_mpi_powm (my, mg, mx, mp);
-
- gcry = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &n_buffer, my);
- g_return_val_if_fail (gcry == 0, FALSE);
- egg_asn1x_set_integer_as_raw (key_asn, buffer, n_buffer, gcry_free);
-
- gcry_mpi_release (mp);
- gcry_mpi_release (mq);
- gcry_mpi_release (mg);
- gcry_mpi_release (mx);
- gcry_mpi_release (my);
-
- return TRUE;
-}
-
-static gboolean
-dsa_subject_public_key_from_attributes (GckAttributes *attrs,
- gulong klass,
- GNode *info_asn)
-{
- GckAttribute *value, *g, *q, *p;
- GNode *key_asn, *params_asn;
- gpointer key, params;
- gsize n_key, n_params;
-
- _gcr_oids_init ();
-
- p = gck_attributes_find (attrs, CKA_PRIME);
- q = gck_attributes_find (attrs, CKA_SUBPRIME);
- g = gck_attributes_find (attrs, CKA_BASE);
- value = gck_attributes_find (attrs, CKA_VALUE);
-
- if (p == NULL || q == NULL || g == NULL || value == NULL)
- return FALSE;
-
- key_asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicPart");
- g_return_val_if_fail (key_asn, FALSE);
-
- params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters");
- g_return_val_if_fail (params_asn, FALSE);
-
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL), p->value, p->length, NULL);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL), q->value, q->length, NULL);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL), g->value, g->length, NULL);
-
- /* Are these attributes for a public or private key? */
- if (klass == CKO_PRIVATE_KEY) {
-
- /* We need to calculate the public from the private key */
- if (!dsa_subject_public_key_from_private (key_asn, p, q, g, value))
- g_return_val_if_reached (FALSE);
-
- } else if (klass == CKO_PUBLIC_KEY) {
- egg_asn1x_set_integer_as_usg (key_asn, value->value, value->length, NULL);
-
- } else {
- g_assert_not_reached ();
- }
-
- key = egg_asn1x_encode (key_asn, g_realloc, &n_key);
- egg_asn1x_destroy (key_asn);
-
- params = egg_asn1x_encode (params_asn, g_realloc, &n_params);
- egg_asn1x_destroy (params_asn);
-
- egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
- key, n_key * 8, g_free);
- egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL),
- params, n_params, g_free);
-
- egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA);
-
- return TRUE;
-}
-
-static gpointer
-fingerprint_from_key_attributes (GckAttributes *attrs,
- gulong klass,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- gpointer fingerprint = NULL;
- gboolean ret = FALSE;
- GNode *info_asn;
- gpointer info;
- gulong key_type;
- gsize n_info;
-
- if (!gck_attributes_find_ulong (attrs, CKA_KEY_TYPE, &key_type))
- return NULL;
-
- info_asn = egg_asn1x_create (pkix_asn1_tab, "SubjectPublicKeyInfo");
- g_return_val_if_fail (info_asn, NULL);
-
- if (key_type == CKK_RSA)
- ret = rsa_subject_public_key_from_attributes (attrs, info_asn);
-
- else if (key_type == CKK_DSA)
- ret = dsa_subject_public_key_from_attributes (attrs, klass, info_asn);
-
- else
- ret = FALSE;
-
- if (ret) {
- info = egg_asn1x_encode (info_asn, g_realloc, &n_info);
- fingerprint = gcr_fingerprint_from_subject_public_key_info (info, n_info,
- checksum_type,
- n_fingerprint);
- g_free (info);
- }
-
- egg_asn1x_destroy (info_asn);
- return fingerprint;
-}
-
-static guchar *
-fingerprint_from_cert_value (const guchar *der_data,
- gsize n_der_data,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- guchar *fingerprint;
- GNode *cert_asn;
- gconstpointer info;
- gsize n_info;
-
- cert_asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate",
- der_data, n_der_data);
- if (cert_asn == NULL)
- return NULL;
-
- info = egg_asn1x_get_raw_element (egg_asn1x_node (cert_asn, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_info);
- g_return_val_if_fail (info != NULL, NULL);
-
- fingerprint = gcr_fingerprint_from_subject_public_key_info (info, n_info,
- checksum_type,
- n_fingerprint);
-
- egg_asn1x_destroy (cert_asn);
- return fingerprint;
-}
-
-static guchar *
-fingerprint_from_cert_attributes (GckAttributes *attrs,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- GckAttribute *attr;
-
- attr = gck_attributes_find (attrs, CKA_VALUE);
- if (attr == NULL)
- return NULL;
-
- return fingerprint_from_cert_value (attr->value, attr->length, checksum_type,
- n_fingerprint);
-}
-
-/**
- * gcr_fingerprint_from_attributes:
- * @attrs: attributes for key or certificate
- * @checksum_type: the type of fingerprint to create
- * @n_fingerprint: the length of fingerprint returned
- *
- * Create a key fingerprint for a certificate, public key or private key.
- * Note that this is not a fingerprint of certificate data, which you would
- * use gcr_certificate_get_fingerprint() for.
- *
- * Returns: (transfer full) (allow-none) (array length=n_fingerprint): the
- * fingerprint or %NULL if the input was invalid.
- */
-guchar *
-gcr_fingerprint_from_attributes (GckAttributes *attrs,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- gulong klass;
-
- g_return_val_if_fail (attrs, FALSE);
- g_return_val_if_fail (n_fingerprint, FALSE);
-
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
- return NULL;
-
- if (klass == CKO_CERTIFICATE)
- return fingerprint_from_cert_attributes (attrs, checksum_type,
- n_fingerprint);
-
- else if (klass == CKO_PUBLIC_KEY || klass == CKO_PRIVATE_KEY)
- return fingerprint_from_key_attributes (attrs, klass,
- checksum_type,
- n_fingerprint);
-
- else
- return NULL;
-}
-
-/**
- * gcr_fingerprint_from_certificate_public_key:
- * @certificate: the certificate
- * @checksum_type: the type of fingerprint to create
- * @n_fingerprint: the length of fingerprint returned
- *
- * Create a key fingerprint for a certificate's public key. Note that this is
- * not a fingerprint of certificate data, which you would use
- * gcr_certificate_get_fingerprint() for.
- *
- * Returns: (transfer full) (allow-none) (array length=n_fingerprint): the
- * fingerprint or %NULL if the input was invalid.
- */
-guchar *
-gcr_fingerprint_from_certificate_public_key (GcrCertificate *certificate,
- GChecksumType checksum_type,
- gsize *n_fingerprint)
-{
- const guchar *der_data;
- gsize n_der_data;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), NULL);
-
- der_data = gcr_certificate_get_der_data (certificate, &n_der_data);
- g_return_val_if_fail (der_data != NULL, NULL);
-
- return fingerprint_from_cert_value (der_data, n_der_data, checksum_type,
- n_fingerprint);
-}
diff --git a/gcr/gcr-fingerprint.h b/gcr/gcr-fingerprint.h
deleted file mode 100644
index 84cc41f9..00000000
--- a/gcr/gcr-fingerprint.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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 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 License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_FINGERPRINT_H
-#define GCR_FINGERPRINT_H
-
-#include <glib.h>
-
-#include "gcr-types.h"
-#include "gcr-certificate.h"
-
-guchar * gcr_fingerprint_from_subject_public_key_info (const guchar *key_info,
- gsize n_key_info,
- GChecksumType checksum_type,
- gsize *n_fingerprint);
-
-guchar * gcr_fingerprint_from_attributes (GckAttributes *attrs,
- GChecksumType checksum_type,
- gsize *n_fingerprint);
-
-guchar * gcr_fingerprint_from_certificate_public_key (GcrCertificate *certificate,
- GChecksumType checksum_type,
- gsize *n_fingerprint);
-
-#endif /* GCR_FINGERPRINT_H_ */
diff --git a/gcr/gcr-gnupg-collection.c b/gcr/gcr-gnupg-collection.c
deleted file mode 100644
index fe730a20..00000000
--- a/gcr/gcr-gnupg-collection.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-callback-output-stream.h"
-#include "gcr-collection.h"
-#define DEBUG_FLAG GCR_DEBUG_GNUPG
-#include "gcr-debug.h"
-#include "gcr-gnupg-collection.h"
-#include "gcr-gnupg-key.h"
-#include "gcr-gnupg-process.h"
-#include "gcr-gnupg-records.h"
-#include "gcr-gnupg-util.h"
-#include "gcr-internal.h"
-#include "gcr-record.h"
-#include "gcr-util.h"
-
-#include <sys/wait.h>
-#include <string.h>
-
-enum {
- PROP_0,
- PROP_DIRECTORY
-};
-
-struct _GcrGnupgCollectionPrivate {
- GHashTable *items; /* char *keyid -> GcrGnupgKey* */
- gchar *directory;
-};
-
-/* Forward declarations */
-static void _gcr_collection_iface (GcrCollectionIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrGnupgCollection, _gcr_gnupg_collection, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, _gcr_collection_iface)
-);
-
-
-static void
-_gcr_gnupg_collection_init (GcrGnupgCollection *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_COLLECTION,
- GcrGnupgCollectionPrivate);
-
- self->pv->items = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
-}
-
-static void
-_gcr_gnupg_collection_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (obj);
-
- switch (prop_id) {
- case PROP_DIRECTORY:
- g_return_if_fail (!self->pv->directory);
- self->pv->directory = g_value_dup_string (value);
- if (self->pv->directory && !g_path_is_absolute (self->pv->directory)) {
- g_warning ("gnupg collection directory path should be absolute: %s",
- self->pv->directory);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_collection_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (obj);
-
- switch (prop_id) {
- case PROP_DIRECTORY:
- g_value_set_string (value, self->pv->directory);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_collection_dispose (GObject *obj)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (obj);
-
- g_hash_table_remove_all (self->pv->items);
-
- G_OBJECT_CLASS (_gcr_gnupg_collection_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_gnupg_collection_finalize (GObject *obj)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (obj);
-
- g_assert (self->pv->items);
- g_assert (g_hash_table_size (self->pv->items) == 0);
- g_hash_table_destroy (self->pv->items);
- self->pv->items = NULL;
-
- g_free (self->pv->directory);
- self->pv->directory = NULL;
-
- G_OBJECT_CLASS (_gcr_gnupg_collection_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_gnupg_collection_class_init (GcrGnupgCollectionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->get_property = _gcr_gnupg_collection_get_property;
- gobject_class->set_property = _gcr_gnupg_collection_set_property;
- gobject_class->dispose = _gcr_gnupg_collection_dispose;
- gobject_class->finalize = _gcr_gnupg_collection_finalize;
-
- /**
- * GcrGnupgCollection:directory:
- *
- * Directory to load the gnupg keys from, or %NULL for default
- * ~/.gnupg/ directory.
- */
- g_object_class_install_property (gobject_class, PROP_DIRECTORY,
- g_param_spec_string ("directory", "Directory", "Gnupg Directory",
- NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (gobject_class, sizeof (GcrGnupgCollectionPrivate));
- _gcr_initialize_library ();
-}
-
-static guint
-gcr_gnupg_collection_real_get_length (GcrCollection *coll)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (coll);
- return g_hash_table_size (self->pv->items);
-}
-
-static GList*
-gcr_gnupg_collection_real_get_objects (GcrCollection *coll)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (coll);
- return g_hash_table_get_values (self->pv->items);
-}
-
-static gboolean
-gcr_gnupg_collection_real_contains (GcrCollection *collection,
- GObject *object)
-{
- GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (collection);
- GcrGnupgKey *key;
-
- if (!GCR_IS_GNUPG_KEY (object))
- return FALSE;
- key = g_hash_table_lookup (self->pv->items,
- _gcr_gnupg_key_get_keyid (GCR_GNUPG_KEY (object)));
- if (key != NULL && G_OBJECT (key) == object)
- return TRUE;
- return FALSE;
-}
-
-static void
-_gcr_collection_iface (GcrCollectionIface *iface)
-{
- iface->get_length = gcr_gnupg_collection_real_get_length;
- iface->get_objects = gcr_gnupg_collection_real_get_objects;
- iface->contains = gcr_gnupg_collection_real_contains;
-}
-
-/**
- * _gcr_gnupg_collection_new:
- * @directory: (allow-none): The gnupg home directory.
- *
- * Create a new GcrGnupgCollection.
- *
- * The gnupg home directory is where the keyring files live. If directory is
- * %NULL then the default gnupg home directory is used.
- *
- * Returns: (transfer full) (type Gcr.GnupgCollection): A newly allocated collection.
- */
-GcrCollection*
-_gcr_gnupg_collection_new (const gchar *directory)
-{
- return g_object_new (GCR_TYPE_GNUPG_COLLECTION,
- "directory", directory,
- NULL);
-}
-
-/*
- * We have to run the gnupg process twice to list the public and then the
- * secret keys. These phases are tracked by GcrLoadingPhase. If the first
- * phase completes successfully (using gpg --list-keys) then we move on to
- * the second phase where the secret keys are loaded (using gpg --list-secret-keys)
- *
- * If a key is loaded as a public key by the public phase, it can be updated by
- * the secret phase. A key discovered in the secret phase must have a public
- * counterpart already loaded by the public phase.
- */
-
-typedef enum {
- GCR_LOADING_PHASE_PUBLIC = 1,
- GCR_LOADING_PHASE_SECRET = 2,
-} GcrLoadingPhase;
-
-/*
- * We use @difference to track the keys that were in the collection before
- * the load process, and then remove any not found, at the end of the load
- * process. Strings are directly used from collection->pv->items keys.
- */
-
-typedef struct {
- GcrGnupgCollection *collection; /* reffed pointer back to collection */
- GcrLoadingPhase loading_phase; /* Whether loading public or private */
- GPtrArray *records; /* GcrRecord* not yet made into a key */
- GcrGnupgProcess *process; /* The gnupg process itself */
- GCancellable *cancel; /* Cancellation for process */
- GString *out_data; /* Pending output not yet parsed into colons */
- GHashTable *difference; /* Hashset gchar *keyid -> gchar *keyid */
-
- guint error_sig;
- guint status_sig;
- GOutputStream *output;
- GOutputStream *outattr;
-
- GQueue *attribute_queue; /* Queue of unprocessed GcrRecord* status records */
- GByteArray *attribute_buf; /* Buffer of unprocessed attribute data received */
- GHashTable *attributes; /* Processed attributes waiting for a matching key */
-} GcrGnupgCollectionLoad;
-
-/* Forward declarations */
-static void spawn_gnupg_list_process (GcrGnupgCollectionLoad *load, GSimpleAsyncResult *res);
-
-static void
-_gcr_gnupg_collection_load_free (gpointer data)
-{
- GcrGnupgCollectionLoad *load = data;
- g_assert (load);
-
- g_ptr_array_unref (load->records);
- g_string_free (load->out_data, TRUE);
- g_hash_table_destroy (load->difference);
- g_object_unref (load->collection);
-
- if (load->process) {
- if (load->error_sig)
- g_signal_handler_disconnect (load->process, load->error_sig);
- if (load->status_sig)
- g_signal_handler_disconnect (load->process, load->status_sig);
- g_object_unref (load->process);
- }
-
- g_output_stream_close (load->output, NULL, NULL);
- g_object_unref (load->output);
- g_output_stream_close (load->outattr, NULL, NULL);
- g_object_unref (load->outattr);
-
- if (load->cancel)
- g_object_unref (load->cancel);
-
- if (load->attribute_queue) {
- while (!g_queue_is_empty (load->attribute_queue))
- _gcr_record_free (g_queue_pop_head (load->attribute_queue));
- g_queue_free (load->attribute_queue);
- }
- if (load->attribute_buf)
- g_byte_array_unref (load->attribute_buf);
- if (load->attributes)
- g_hash_table_destroy (load->attributes);
-
- g_slice_free (GcrGnupgCollectionLoad, load);
-}
-
-static void
-process_records_as_public_key (GcrGnupgCollectionLoad *load, GPtrArray *records,
- const gchar *keyid)
-{
- GPtrArray *attr_records = NULL;
- const gchar *fingerprint;
- gchar *orig_fingerprint;
- GcrGnupgKey *key;
- guint i;
-
- /* Add in any attributes we have loaded */
- fingerprint = _gcr_gnupg_records_get_fingerprint (records);
- if (fingerprint && load->attributes)
- attr_records = g_hash_table_lookup (load->attributes, fingerprint);
- if (attr_records) {
- _gcr_debug ("adding %d user id attribute(s) to key/fingerprint: %s/%s",
- (gint)attr_records->len, keyid, fingerprint);
-
- if (!g_hash_table_lookup_extended (load->attributes, fingerprint,
- (gpointer*)&orig_fingerprint, NULL))
- g_assert_not_reached ();
- if (!g_hash_table_steal (load->attributes, fingerprint))
- g_assert_not_reached ();
- g_free (orig_fingerprint);
-
- /* Move all the attribute records over to main records set */
- for (i = 0; i < attr_records->len; i++)
- g_ptr_array_add (records, attr_records->pdata[i]);
-
- /* Shallow free of attr_records array */
- g_free (g_ptr_array_free (attr_records, FALSE));
- }
-
- /* Note that we've seen this keyid */
- g_hash_table_remove (load->difference, keyid);
-
- key = g_hash_table_lookup (load->collection->pv->items, keyid);
-
- /* Already have this key, just update */
- if (key) {
- _gcr_debug ("updating public key: %s", keyid);
- _gcr_gnupg_key_set_public_records (key, records);
-
- /* Add a new key */
- } else {
- key = _gcr_gnupg_key_new (records, NULL);
- _gcr_debug ("creating public key: %s", keyid);
- g_hash_table_insert (load->collection->pv->items, g_strdup (keyid), key);
- gcr_collection_emit_added (GCR_COLLECTION (load->collection), G_OBJECT (key));
- }
-}
-
-static void
-process_records_as_secret_key (GcrGnupgCollectionLoad *load, GPtrArray *records,
- const gchar *keyid)
-{
- GcrGnupgKey *key;
-
- key = g_hash_table_lookup (load->collection->pv->items, keyid);
-
- /* Don't have this key */
- if (key == NULL) {
- g_message ("Secret key seen but no public key for: %s", keyid);
-
- /* Tell the private key that it's a secret one */
- } else {
- _gcr_debug ("adding secret records to key: %s", keyid);
- _gcr_gnupg_key_set_secret_records (key, records);
- }
-}
-
-static void
-process_records_as_key (GcrGnupgCollectionLoad *load)
-{
- GPtrArray *records;
- const gchar *keyid;
- GQuark schema;
-
- g_assert (load->records->len);
-
- records = load->records;
- load->records = g_ptr_array_new_with_free_func (_gcr_record_free);
-
- keyid = _gcr_gnupg_records_get_keyid (records);
- if (keyid) {
- schema = _gcr_record_get_schema (records->pdata[0]);
-
- /* A public key */
- if (schema == GCR_RECORD_SCHEMA_PUB)
- process_records_as_public_key (load, records, keyid);
-
- /* A secret key */
- else if (schema == GCR_RECORD_SCHEMA_SEC)
- process_records_as_secret_key (load, records, keyid);
-
- else
- g_assert_not_reached ();
-
- } else {
- g_warning ("parsed gnupg data had no keyid");
- }
-
- g_ptr_array_unref (records);
-}
-
-static gboolean
-process_outstanding_attribute (GcrGnupgCollectionLoad *load, GcrRecord *record)
-{
- const gchar *fingerprint;
- GPtrArray *records;
- GcrRecord *xa1;
- guint length;
-
- if (!_gcr_record_get_uint (record, GCR_RECORD_ATTRIBUTE_LENGTH, &length))
- g_return_val_if_reached (FALSE);
- fingerprint = _gcr_record_get_raw (record, GCR_RECORD_ATTRIBUTE_KEY_FINGERPRINT);
- g_return_val_if_fail (fingerprint != NULL, FALSE);
-
- /* Do we have enough data for this attribute? */
- if (!load->attribute_buf || load->attribute_buf->len < length) {
- _gcr_debug ("not enough attribute data in buffer: %u", length);
- return FALSE;
- }
-
- if (!load->attributes)
- load->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify)g_ptr_array_unref);
-
- records = g_hash_table_lookup (load->attributes, fingerprint);
- if (!records) {
- records = g_ptr_array_new_with_free_func (_gcr_record_free);
- g_hash_table_insert (load->attributes, g_strdup (fingerprint), records);
- }
-
- _gcr_debug ("new attribute of length %d for key with fingerprint %s",
- length, fingerprint);
-
- xa1 = _gcr_gnupg_build_xa1_record (record, load->attribute_buf->data, length);
- g_ptr_array_add (records, xa1);
-
- /* Did we use up all the attribute data? Get rid of the buffer */
- if (length == load->attribute_buf->len) {
- g_byte_array_unref (load->attribute_buf);
- load->attribute_buf = NULL;
-
- /* Otherwise clear out the used data from buffer */
- } else {
- g_byte_array_remove_range (load->attribute_buf, 0, length);
- }
-
- return TRUE;
-}
-
-static void
-process_outstanding_attributes (GcrGnupgCollectionLoad *load)
-{
- GcrRecord *record;
-
- if (load->attribute_queue == NULL)
- return;
-
- _gcr_debug ("%d outstanding attribute records",
- (gint)g_queue_get_length (load->attribute_queue));
-
- for (;;) {
- record = g_queue_peek_head (load->attribute_queue);
- if (record == NULL)
- break;
- if (!process_outstanding_attribute (load, record))
- break;
- g_queue_pop_head (load->attribute_queue);
- _gcr_record_free (record);
- }
-}
-
-static void
-on_line_parse_output (const gchar *line, gpointer user_data)
-{
- GcrGnupgCollectionLoad *load = user_data;
- GcrRecord *record;
- GQuark schema;
-
- _gcr_debug ("output: %s", line);
-
- record = _gcr_record_parse_colons (line, -1);
- if (!record) {
- g_warning ("invalid gnupg output line: %s", line);
- return;
- }
-
- schema = _gcr_record_get_schema (record);
-
- /*
- * Each time we see a line with 'pub' or 'sec' schema we assume that
- * it's a new key being listed.
- */
- if (schema == GCR_RECORD_SCHEMA_PUB || schema == GCR_RECORD_SCHEMA_SEC) {
- _gcr_debug ("start of new key");
- if (load->records->len)
- process_records_as_key (load);
- g_assert (!load->records->len);
- g_ptr_array_add (load->records, record);
- record = NULL;
-
- /*
- * 'uid' and 'fpr' schema lines get added to the key that came before.
- */
- } else if (schema == GCR_RECORD_SCHEMA_UID ||
- schema == GCR_RECORD_SCHEMA_FPR) {
- if (load->records->len) {
- g_ptr_array_add (load->records, record);
- record = NULL;
- }
- }
-
- if (record != NULL)
- _gcr_record_free (record);
-}
-
-
-static gssize
-on_gnupg_process_output_data (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
-
- g_string_append_len (load->out_data, buffer, count);
- _gcr_util_parse_lines (load->out_data, FALSE, on_line_parse_output, load);
- return count;
-}
-
-static void
-on_gnupg_process_error_line (GcrGnupgProcess *process, const gchar *line,
- gpointer user_data)
-{
- g_printerr ("%s\n", line);
-}
-
-static void
-on_gnupg_process_status_record (GcrGnupgProcess *process, GcrRecord *record,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
-
- if (GCR_RECORD_SCHEMA_ATTRIBUTE != _gcr_record_get_schema (record))
- return;
-
- if (!load->attribute_queue)
- load->attribute_queue = g_queue_new ();
-
- g_queue_push_tail (load->attribute_queue, _gcr_record_copy (record));
- process_outstanding_attributes (load);
-}
-
-static gssize
-on_gnupg_process_attribute_data (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
-
- /* If we don't have a buffer, just claim this one */
- if (!load->attribute_buf)
- load->attribute_buf = g_byte_array_new ();
-
- g_byte_array_append (load->attribute_buf, buffer, count);
-
- process_outstanding_attributes (load);
- return count;
-}
-
-static void
-on_gnupg_process_completed (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
- GHashTableIter iter;
- GError *error = NULL;
- GObject *object;
- gpointer keyid;
-
- if (!_gcr_gnupg_process_run_finish (GCR_GNUPG_PROCESS (source), result, &error)) {
- g_simple_async_result_set_from_error (res, error);
- g_simple_async_result_complete (res);
- g_object_unref (res);
- g_clear_error (&error);
- return;
- }
-
- /* Process any remaining output */
- _gcr_util_parse_lines (load->out_data, TRUE, on_line_parse_output, load);
-
- /* Process last bit as a key, if any */
- if (load->records->len)
- process_records_as_key (load);
-
- /* If we completed loading public keys, then go and load secret */
- switch (load->loading_phase) {
- case GCR_LOADING_PHASE_PUBLIC:
- _gcr_debug ("public load phase completed");
- load->loading_phase = GCR_LOADING_PHASE_SECRET;
- spawn_gnupg_list_process (load, res);
- g_object_unref (res);
- return;
- case GCR_LOADING_PHASE_SECRET:
- _gcr_debug ("secret load phase completed");
- /* continue below */
- break;
- default:
- g_assert_not_reached ();
- }
-
- /* Remove any keys that we still have in the difference */
- g_hash_table_iter_init (&iter, load->difference);
- while (g_hash_table_iter_next (&iter, &keyid, NULL)) {
- object = g_hash_table_lookup (load->collection->pv->items, keyid);
- if (object != NULL) {
- g_object_ref (object);
- _gcr_debug ("removing key no longer present in keyring: %s", (gchar*)keyid);
- g_hash_table_remove (load->collection->pv->items, keyid);
- gcr_collection_emit_removed (GCR_COLLECTION (load->collection), object);
- g_object_unref (object);
- }
- }
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-spawn_gnupg_list_process (GcrGnupgCollectionLoad *load, GSimpleAsyncResult *res)
-{
- GcrGnupgProcessFlags flags = 0;
- GPtrArray *argv;
-
- argv = g_ptr_array_new ();
-
- switch (load->loading_phase) {
- case GCR_LOADING_PHASE_PUBLIC:
- _gcr_debug ("starting public load phase");
- g_ptr_array_add (argv, (gpointer)"--list-keys");
- /* Load photos in public phase */
- flags = GCR_GNUPG_PROCESS_WITH_ATTRIBUTES |
- GCR_GNUPG_PROCESS_WITH_STATUS;
- break;
- case GCR_LOADING_PHASE_SECRET:
- _gcr_debug ("starting secret load phase");
- g_ptr_array_add (argv, (gpointer)"--list-secret-keys");
- break;
- default:
- g_assert_not_reached ();
- }
-
- g_ptr_array_add (argv, (gpointer)"--fixed-list-mode");
- g_ptr_array_add (argv, (gpointer)"--with-colons");
- g_ptr_array_add (argv, (gpointer)"--with-fingerprint");
- g_ptr_array_add (argv, NULL);
-
- /* res is unreffed in on_gnupg_process_completed */
- _gcr_gnupg_process_run_async (load->process, (const gchar**)argv->pdata, NULL, flags,
- load->cancel, on_gnupg_process_completed,
- g_object_ref (res));
-
- g_ptr_array_unref (argv);
-}
-
-/**
- * _gcr_gnupg_collection_load_async:
- * @self: The collection
- * @cancellable: Cancellation object or %NULL
- * @callback: Callback to call when result is ready
- * @user_data: Data for callback
- *
- * Start an operation to load or reload the list of gnupg keys in this
- * collection.
- */
-void
-_gcr_gnupg_collection_load_async (GcrGnupgCollection *self, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *res;
- GcrGnupgCollectionLoad *load;
- GHashTableIter iter;
- gpointer keyid;
-
- g_return_if_fail (GCR_IS_GNUPG_COLLECTION (self));
-
- /* TODO: Cancellation not yet implemented */
-
- res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- _gcr_gnupg_collection_load_async);
-
- load = g_slice_new0 (GcrGnupgCollectionLoad);
- load->records = g_ptr_array_new_with_free_func (_gcr_record_free);
- load->out_data = g_string_sized_new (1024);
- load->collection = g_object_ref (self);
- load->cancel = cancellable ? g_object_ref (cancellable) : cancellable;
-
- load->output = _gcr_callback_output_stream_new (on_gnupg_process_output_data, res, NULL);
- load->outattr = _gcr_callback_output_stream_new (on_gnupg_process_attribute_data, res, NULL);
-
- load->process = _gcr_gnupg_process_new (self->pv->directory, NULL);
- _gcr_gnupg_process_set_output_stream (load->process, load->output);
- _gcr_gnupg_process_set_attribute_stream (load->process, load->outattr);
- load->error_sig = g_signal_connect (load->process, "error-line", G_CALLBACK (on_gnupg_process_error_line), res);
- load->status_sig = g_signal_connect (load->process, "status-record", G_CALLBACK (on_gnupg_process_status_record), res);
-
- /*
- * Track all the keys we currently have, at end remove those that
- * didn't get listed by the gpg process.
- */
- load->difference = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_iter_init (&iter, self->pv->items);
- while (g_hash_table_iter_next (&iter, &keyid, NULL))
- g_hash_table_insert (load->difference, keyid, keyid);
-
- g_simple_async_result_set_op_res_gpointer (res, load,
- _gcr_gnupg_collection_load_free);
-
- load->loading_phase = GCR_LOADING_PHASE_PUBLIC;
- spawn_gnupg_list_process (load, res);
-
- g_object_unref (res);
-}
-
-/**
- * _gcr_gnupg_collection_load_finish:
- * @self: The collection
- * @result: The result passed to the callback
- * @error: Location to raise an error on failure.
- *
- * Get the result of an operation to load or reload the list of gnupg keys
- * in this collection.
- */
-gboolean
-_gcr_gnupg_collection_load_finish (GcrGnupgCollection *self, GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_COLLECTION (self), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
- _gcr_gnupg_collection_load_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
diff --git a/gcr/gcr-gnupg-collection.h b/gcr/gcr-gnupg-collection.h
deleted file mode 100644
index a626cef9..00000000
--- a/gcr/gcr-gnupg-collection.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_GNUPG_COLLECTION_H
-#define GCR_GNUPG_COLLECTION_H
-
-#include "gcr-base.h"
-#include "gcr-collection.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_GNUPG_COLLECTION (_gcr_gnupg_collection_get_type ())
-#define GCR_GNUPG_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_GNUPG_COLLECTION, GcrGnupgCollection))
-#define GCR_GNUPG_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_GNUPG_COLLECTION, GcrGnupgCollectionClass))
-#define GCR_IS_GNUPG_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_GNUPG_COLLECTION))
-#define GCR_IS_GNUPG_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_GNUPG_COLLECTION))
-#define GCR_GNUPG_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_GNUPG_COLLECTION, GcrGnupgCollectionClass))
-
-typedef struct _GcrGnupgCollection GcrGnupgCollection;
-typedef struct _GcrGnupgCollectionClass GcrGnupgCollectionClass;
-typedef struct _GcrGnupgCollectionPrivate GcrGnupgCollectionPrivate;
-
-struct _GcrGnupgCollection {
- /*< private >*/
- GObject parent;
- GcrGnupgCollectionPrivate *pv;
-};
-
-struct _GcrGnupgCollectionClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_gnupg_collection_get_type (void);
-
-GcrCollection* _gcr_gnupg_collection_new (const gchar *directory);
-
-void _gcr_gnupg_collection_load_async (GcrGnupgCollection *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean _gcr_gnupg_collection_load_finish (GcrGnupgCollection *self,
- GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* GCR_GNUPG_COLLECTION_H */
diff --git a/gcr/gcr-gnupg-importer.c b/gcr/gcr-gnupg-importer.c
deleted file mode 100644
index db0fd39d..00000000
--- a/gcr/gcr-gnupg-importer.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-gnupg-importer.h"
-#include "gcr-gnupg-process.h"
-#include "gcr-internal.h"
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ICON,
- PROP_IMPORTED,
- PROP_DIRECTORY,
- PROP_INTERACTION
-};
-
-struct _GcrGnupgImporterPrivate {
- GcrGnupgProcess *process;
- GMemoryInputStream *packets;
- GTlsInteraction *interaction;
- GArray *imported;
-};
-
-static void gcr_gnupg_importer_iface (GcrImporterIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrGnupgImporter, _gcr_gnupg_importer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_IMPORTER, gcr_gnupg_importer_iface);
-);
-
-static void
-_gcr_gnupg_importer_init (GcrGnupgImporter *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_IMPORTER, GcrGnupgImporterPrivate);
- self->pv->packets = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new ());
- self->pv->imported = g_array_new (TRUE, TRUE, sizeof (gchar *));
-}
-
-static void
-_gcr_gnupg_importer_dispose (GObject *obj)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
-
- if (self->pv->process)
- g_object_run_dispose (G_OBJECT (self->pv->process));
- g_clear_object (&self->pv->process);
- g_clear_object (&self->pv->packets);
- g_clear_object (&self->pv->interaction);
-
- G_OBJECT_CLASS (_gcr_gnupg_importer_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_gnupg_importer_finalize (GObject *obj)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
-
- g_array_free (self->pv->imported, TRUE);
-
- G_OBJECT_CLASS (_gcr_gnupg_importer_parent_class)->finalize (obj);
-}
-
-static gchar *
-calculate_label (GcrGnupgImporter *self)
-{
- const gchar *directory;
-
- directory = _gcr_gnupg_process_get_directory (self->pv->process);
- if (directory == NULL)
- return g_strdup (_("GnuPG Keyring"));
- else
- return g_strdup_printf (_("GnuPG Keyring: %s"), directory);
-}
-
-static GIcon *
-calculate_icon (GcrGnupgImporter *self)
-{
- const gchar *directory;
-
- directory = _gcr_gnupg_process_get_directory (self->pv->process);
- if (directory == NULL)
- return g_themed_icon_new ("user-home");
- else
- return g_themed_icon_new ("folder");
-}
-
-static gboolean
-on_process_status_record (GcrGnupgProcess *process,
- GcrRecord *record,
- gpointer user_data)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (user_data);
- const gchar *value;
- gchar *fingerprint;
-
- if (_gcr_record_get_schema (record) != GCR_RECORD_SCHEMA_IMPORT_OK)
- return TRUE;
-
- value = _gcr_record_get_raw (record, GCR_RECORD_IMPORT_FINGERPRINT);
- if (value != NULL && value[0] != 0) {
- fingerprint = g_strdup (value);
- g_array_append_val (self->pv->imported, fingerprint);
- }
-
- return TRUE;
-}
-
-static void
-_gcr_gnupg_importer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_DIRECTORY:
- self->pv->process = _gcr_gnupg_process_new (g_value_get_string (value),
- NULL);
- _gcr_gnupg_process_set_input_stream (self->pv->process, G_INPUT_STREAM (self->pv->packets));
- g_signal_connect (self->pv->process, "status-record", G_CALLBACK (on_process_status_record), self);
- break;
- case PROP_INTERACTION:
- g_clear_object (&self->pv->interaction);
- self->pv->interaction = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_importer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ICON:
- g_value_take_object (value, calculate_icon (self));
- break;
- case PROP_IMPORTED:
- g_value_set_boxed (value, _gcr_gnupg_importer_get_imported (self));
- break;
- case PROP_DIRECTORY:
- g_value_set_string (value, _gcr_gnupg_process_get_directory (self->pv->process));
- break;
- case PROP_INTERACTION:
- g_value_set_object (value, self->pv->interaction);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_importer_class_init (GcrGnupgImporterClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- gobject_class->dispose = _gcr_gnupg_importer_dispose;
- gobject_class->finalize = _gcr_gnupg_importer_finalize;
- gobject_class->set_property = _gcr_gnupg_importer_set_property;
- gobject_class->get_property = _gcr_gnupg_importer_get_property;
-
- g_type_class_add_private (gobject_class, sizeof (GcrGnupgImporterPrivate));
-
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
-
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
-
- g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
-
- g_object_class_install_property (gobject_class, PROP_IMPORTED,
- g_param_spec_boxed ("imported", "Imported", "Fingerprints of imported keys",
- G_TYPE_STRV, G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class, PROP_DIRECTORY,
- g_param_spec_string ("directory", "Directory", "Directory to import keys to",
- NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
- gcr_importer_register (GCR_TYPE_GNUPG_IMPORTER, registered);
- gck_attributes_unref (registered);
-
- _gcr_initialize_library ();
-}
-
-static GList *
-_gcr_gnupg_importer_create_for_parsed (GcrParsed *parsed)
-{
- GcrImporter *self;
-
- if (gcr_parsed_get_format (parsed) != GCR_FORMAT_OPENPGP_PACKET)
- return NULL;
-
- self = _gcr_gnupg_importer_new (NULL);
- if (!gcr_importer_queue_for_parsed (self, parsed))
- g_assert_not_reached ();
-
- return g_list_append (NULL, self);
-}
-
-static gboolean
-_gcr_gnupg_importer_queue_for_parsed (GcrImporter *importer,
- GcrParsed *parsed)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (importer);
- gconstpointer block;
- gsize n_block;
-
- if (gcr_parsed_get_format (parsed) != GCR_FORMAT_OPENPGP_PACKET)
- return FALSE;
-
- block = gcr_parsed_get_data (parsed, &n_block);
- g_return_val_if_fail (block, FALSE);
-
- g_memory_input_stream_add_data (self->pv->packets, g_memdup (block, n_block),
- n_block, g_free);
- return TRUE;
-}
-
-static void
-on_process_run_complete (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
-
- if (!_gcr_gnupg_process_run_finish (GCR_GNUPG_PROCESS (source), result, &error))
- g_simple_async_result_take_error (res, error);
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-_gcr_gnupg_importer_import_async (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (importer);
- GSimpleAsyncResult *res;
- const gchar *argv[] = { "--import", NULL };
-
- res = g_simple_async_result_new (G_OBJECT (importer), callback, user_data,
- _gcr_gnupg_importer_import_async);
-
- _gcr_gnupg_process_run_async (self->pv->process, argv, NULL,
- GCR_GNUPG_PROCESS_WITH_STATUS,
- cancellable, on_process_run_complete,
- g_object_ref (res));
-
- g_object_unref (res);
-}
-
-static gboolean
-_gcr_gnupg_importer_import_finish (GcrImporter *importer,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (importer),
- _gcr_gnupg_importer_import_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-gcr_gnupg_importer_iface (GcrImporterIface *iface)
-{
- iface->create_for_parsed = _gcr_gnupg_importer_create_for_parsed;
- iface->queue_for_parsed = _gcr_gnupg_importer_queue_for_parsed;
- iface->import_async = _gcr_gnupg_importer_import_async;
- iface->import_finish = _gcr_gnupg_importer_import_finish;
-}
-
-/**
- * _gcr_gnupg_importer_new:
- * @directory: (allow-none): the directory to import to, or %NULL for default
- *
- * Returns: (transfer full) (type Gcr.GnupgImporter): the new importer
- */
-GcrImporter *
-_gcr_gnupg_importer_new (const gchar *directory)
-{
- return g_object_new (GCR_TYPE_GNUPG_IMPORTER,
- "directory", directory,
- NULL);
-}
-
-const gchar **
-_gcr_gnupg_importer_get_imported (GcrGnupgImporter *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_IMPORTER (self), NULL);
- return (const gchar **)self->pv->imported->data;
-}
diff --git a/gcr/gcr-gnupg-importer.h b/gcr/gcr-gnupg-importer.h
deleted file mode 100644
index 8511af84..00000000
--- a/gcr/gcr-gnupg-importer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_GNUPG_IMPORTER_H__
-#define __GCR_GNUPG_IMPORTER_H__
-
-#include "gcr-importer.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_GNUPG_IMPORTER (_gcr_gnupg_importer_get_type ())
-#define GCR_GNUPG_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_GNUPG_IMPORTER, GcrGnupgImporter))
-#define GCR_GNUPG_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_GNUPG_IMPORTER, GcrGnupgImporterClass))
-#define GCR_IS_GNUPG_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_GNUPG_IMPORTER))
-#define GCR_IS_GNUPG_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_GNUPG_IMPORTER))
-#define GCR_GNUPG_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_GNUPG_IMPORTER, GcrGnupgImporterClass))
-
-typedef struct _GcrGnupgImporter GcrGnupgImporter;
-typedef struct _GcrGnupgImporterClass GcrGnupgImporterClass;
-typedef struct _GcrGnupgImporterPrivate GcrGnupgImporterPrivate;
-
-struct _GcrGnupgImporter {
- GObject parent;
-
- /*< private >*/
- GcrGnupgImporterPrivate *pv;
-};
-
-struct _GcrGnupgImporterClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_gnupg_importer_get_type (void) G_GNUC_CONST;
-
-GcrImporter * _gcr_gnupg_importer_new (const gchar *directory);
-
-const gchar ** _gcr_gnupg_importer_get_imported (GcrGnupgImporter *self);
-
-G_END_DECLS
-
-#endif /* __GCR_IMPORTER_H__ */
diff --git a/gcr/gcr-gnupg-key.c b/gcr/gcr-gnupg-key.c
deleted file mode 100644
index 1d1bc420..00000000
--- a/gcr/gcr-gnupg-key.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-gnupg-key.h"
-#include "gcr-gnupg-records.h"
-#include "gcr-record.h"
-#include "gcr-memory-icon.h"
-
-#include "gck/gck.h"
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_KEYID,
- PROP_PUBLIC_RECORDS,
- PROP_SECRET_RECORDS,
- PROP_LABEL,
- PROP_MARKUP,
- PROP_DESCRIPTION,
- PROP_SHORT_KEYID,
- PROP_ICON
-};
-
-struct _GcrGnupgKeyPrivate {
- GPtrArray *public_records;
- GPtrArray *secret_records;
- GIcon *icon;
-};
-
-G_DEFINE_TYPE (GcrGnupgKey, _gcr_gnupg_key, G_TYPE_OBJECT);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-/* Copied from GPGME */
-static void
-parse_user_id (const gchar *uid, gchar **name, gchar **email, gchar **comment)
-{
- gchar *src, *tail, *x;
- int in_name = 0;
- int in_email = 0;
- int in_comment = 0;
-
- *name = NULL;
- *email = NULL;
- *comment = NULL;
-
- x = tail = src = g_strdup (uid);
-
- while (*src) {
- if (in_email) {
- /* Not legal but anyway. */
- if (*src == '<')
- in_email++;
- else if (*src == '>') {
- if (!--in_email && !*email) {
- *email = tail;
- *src = 0;
- tail = src + 1;
- }
- }
- } else if (in_comment) {
- if (*src == '(')
- in_comment++;
- else if (*src == ')') {
- if (!--in_comment && !*comment) {
- *comment = tail;
- *src = 0;
- tail = src + 1;
- }
- }
- } else if (*src == '<') {
- if (in_name) {
- if (!*name) {
- *name = tail;
- *src = 0;
- tail = src + 1;
- }
- in_name = 0;
- } else
- tail = src + 1;
-
- in_email = 1;
- } else if (*src == '(') {
- if (in_name) {
- if (!*name) {
- *name = tail;
- *src = 0;
- tail = src + 1;
- }
- in_name = 0;
- }
- in_comment = 1;
- } else if (!in_name && *src != ' ' && *src != '\t') {
- in_name = 1;
- }
- src++;
- }
-
- if (in_name) {
- if (!*name) {
- *name = tail;
- *src = 0;
- tail = src + 1;
- }
- }
-
- /* Let unused parts point to an EOS. */
- *name = g_strdup (*name ? *name : "");
- *email = g_strdup (*email ? *email : "");
- *comment = g_strdup (*comment ? *comment : "");
-
- g_strstrip (*name);
- g_strstrip (*email);
- g_strstrip (*comment);
-
- g_free (x);
-}
-
-static gchar *
-calculate_name (GcrGnupgKey *self)
-{
- GcrRecord* record;
-
- record = _gcr_records_find (self->pv->public_records, GCR_RECORD_SCHEMA_UID);
- g_return_val_if_fail (record, NULL);
-
- return _gcr_record_get_string (record, GCR_RECORD_UID_USERID);
-}
-
-static gchar *
-calculate_markup (GcrGnupgKey *self)
-{
- gchar *markup = NULL;
- gchar *uid, *name, *email, *comment;
-
- uid = calculate_name (self);
- if (uid == NULL)
- return NULL;
-
- parse_user_id (uid, &name, &email, &comment);
- if (comment != NULL && comment[0] != '\0')
- markup = g_markup_printf_escaped ("%s\n<small>%s \'%s\'</small>", name, email, comment);
- else
- markup = g_markup_printf_escaped ("%s\n<small>%s</small>", name, email);
- g_free (name);
- g_free (email);
- g_free (comment);
- g_free (uid);
-
- return markup;
-}
-
-static void
-_gcr_gnupg_key_init (GcrGnupgKey *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_KEY, GcrGnupgKeyPrivate));
-}
-
-static void
-_gcr_gnupg_key_finalize (GObject *obj)
-{
- GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
-
- if (self->pv->public_records)
- g_ptr_array_free (self->pv->public_records, TRUE);
- if (self->pv->secret_records)
- g_ptr_array_free (self->pv->secret_records, TRUE);
-
- G_OBJECT_CLASS (_gcr_gnupg_key_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_gnupg_key_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
-
- switch (prop_id) {
- case PROP_PUBLIC_RECORDS:
- _gcr_gnupg_key_set_public_records (self, g_value_get_boxed (value));
- break;
- case PROP_SECRET_RECORDS:
- _gcr_gnupg_key_set_secret_records (self, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_key_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
-
- switch (prop_id) {
- case PROP_PUBLIC_RECORDS:
- g_value_set_boxed (value, self->pv->public_records);
- break;
- case PROP_SECRET_RECORDS:
- g_value_set_boxed (value, self->pv->secret_records);
- break;
- case PROP_KEYID:
- g_value_set_string (value, _gcr_gnupg_key_get_keyid (self));
- break;
- case PROP_LABEL:
- g_value_take_string (value, calculate_name (self));
- break;
- case PROP_DESCRIPTION:
- g_value_set_string (value, _("PGP Key"));
- break;
- case PROP_MARKUP:
- g_value_take_string (value, calculate_markup (self));
- break;
- case PROP_SHORT_KEYID:
- g_value_set_string (value, _gcr_gnupg_records_get_short_keyid (self->pv->public_records));
- break;
- case PROP_ICON:
- g_value_set_object (value, _gcr_gnupg_key_get_icon (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_key_class_init (GcrGnupgKeyClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- _gcr_gnupg_key_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrGnupgKeyPrivate));
-
- gobject_class->finalize = _gcr_gnupg_key_finalize;
- gobject_class->set_property = _gcr_gnupg_key_set_property;
- gobject_class->get_property = _gcr_gnupg_key_get_property;
-
- /**
- * GcrGnupgKey:public-records:
- *
- * Public key data. Should always be present.
- */
- g_object_class_install_property (gobject_class, PROP_PUBLIC_RECORDS,
- g_param_spec_boxed ("public-records", "Public Records", "Public Key Colon Records",
- G_TYPE_PTR_ARRAY, G_PARAM_READWRITE));
-
- /**
- * GcrGnupgKey:secret-records:
- *
- * Secret key data. The keyid of this data must match public-dataset.
- * If present, this key represents a secret key.
- */
- g_object_class_install_property (gobject_class, PROP_SECRET_RECORDS,
- g_param_spec_boxed ("secret-records", "Secret Records", "Secret Key Colon Records",
- G_TYPE_PTR_ARRAY, G_PARAM_READWRITE));
-
- /**
- * GcrGnupgKey:keyid:
- *
- * Key identifier.
- */
- g_object_class_install_property (gobject_class, PROP_KEYID,
- g_param_spec_string ("keyid", "Key ID", "Key identifier",
- "", G_PARAM_READABLE));
-
- /**
- * GcrGnupgKey:label:
- *
- * User readable label for this key.
- */
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Key label",
- "", G_PARAM_READABLE));
-
- /**
- * GcrGnupgKey::description:
- *
- * Description of type of key.
- */
- g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
- g_param_spec_string ("description", "Description", "Description of object type",
- "", G_PARAM_READABLE));
-
- /**
- * GcrGnupgKey:markup:
- *
- * User readable markup which contains key label.
- */
- g_object_class_install_property (gobject_class, PROP_MARKUP,
- g_param_spec_string ("markup", "Markup", "Markup which describes key",
- "", G_PARAM_READABLE));
-
- /**
- * GcrGnupgKey:short-keyid:
- *
- * User readable key identifier.
- */
- g_object_class_install_property (gobject_class, PROP_SHORT_KEYID,
- g_param_spec_string ("short-keyid", "Short Key ID", "Display key identifier",
- "", G_PARAM_READABLE));
-
- /**
- * GcrGnupgKey:icon:
- *
- * Icon for this key.
- */
- g_object_class_install_property (gobject_class, PROP_ICON,
- g_param_spec_object ("icon", "Icon", "Icon for this key",
- G_TYPE_ICON, G_PARAM_READABLE));
-}
-
-/**
- * _gcr_gnupg_key_new:
- * @pubset: array of GcrRecord* representing public part of key
- * @secset: (allow-none): array of GcrRecord* representing secret part of key.
- *
- * Create a new GcrGnupgKey for the record data passed. If the secret part
- * of the key is set, then this represents a secret key; otherwise it represents
- * a public key.
- *
- * Returns: (transfer full): A newly allocated key.
- */
-GcrGnupgKey*
-_gcr_gnupg_key_new (GPtrArray *pubset, GPtrArray *secset)
-{
- g_return_val_if_fail (pubset, NULL);
- return g_object_new (GCR_TYPE_GNUPG_KEY,
- "public-records", pubset,
- "secret-records", secset,
- NULL);
-}
-
-/**
- * _gcr_gnupg_key_get_public_records:
- * @self: The key
- *
- * Get the record data this key is based on.
- *
- * Returns: (transfer none): An array of GcrRecord*.
- */
-GPtrArray*
-_gcr_gnupg_key_get_public_records (GcrGnupgKey *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
- return self->pv->public_records;
-}
-
-/**
- * _gcr_gnupg_key_set_public_records:
- * @self: The key
- * @records: The new array of GcrRecord*
- *
- * Change the record data that this key is based on.
- */
-void
-_gcr_gnupg_key_set_public_records (GcrGnupgKey *self, GPtrArray *records)
-{
- GObject *obj;
-
- g_return_if_fail (GCR_IS_GNUPG_KEY (self));
- g_return_if_fail (records);
-
- /* Check that it matches previous */
- if (self->pv->public_records) {
- const gchar *old_keyid = _gcr_gnupg_records_get_keyid (self->pv->public_records);
- const gchar *new_keyid = _gcr_gnupg_records_get_keyid (records);
-
- if (g_strcmp0 (old_keyid, new_keyid) != 0) {
- g_warning ("it is an error to change a gnupg key so that the "
- "fingerprint is no longer the same: %s != %s",
- old_keyid, new_keyid);
- return;
- }
- }
-
- g_ptr_array_ref (records);
- if (self->pv->public_records)
- g_ptr_array_unref (self->pv->public_records);
- self->pv->public_records = records;
-
- obj = G_OBJECT (self);
- g_object_freeze_notify (obj);
- g_object_notify (obj, "public-records");
- g_object_notify (obj, "label");
- g_object_notify (obj, "markup");
- g_object_thaw_notify (obj);
-}
-
-/**
- * _gcr_gnupg_key_get_secret_records:
- * @self: The key
- *
- * Get the record secret data this key is based on. %NULL if a public key.
- *
- * Returns: (transfer none) (allow-none): An array of GcrColons*.
- */
-GPtrArray*
-_gcr_gnupg_key_get_secret_records (GcrGnupgKey *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
- return self->pv->secret_records;
-}
-
-/**
- * _gcr_gnupg_key_set_secret_records:
- * @self: The key
- * @records: (allow-none): The new array of GcrRecord*
- *
- * Set the secret data for this key. %NULL if public key.
- */
-void
-_gcr_gnupg_key_set_secret_records (GcrGnupgKey *self, GPtrArray *records)
-{
- GObject *obj;
-
- g_return_if_fail (GCR_IS_GNUPG_KEY (self));
-
- /* Check that it matches public key */
- if (self->pv->public_records && records) {
- const gchar *pub_keyid = _gcr_gnupg_records_get_keyid (self->pv->public_records);
- const gchar *sec_keyid = _gcr_gnupg_records_get_keyid (records);
-
- if (g_strcmp0 (pub_keyid, sec_keyid) != 0) {
- g_warning ("it is an error to create a gnupg key so that the "
- "fingerprint of thet pub and sec parts are not the same: %s != %s",
- pub_keyid, sec_keyid);
- return;
- }
- }
-
- if (records)
- g_ptr_array_ref (records);
- if (self->pv->secret_records)
- g_ptr_array_unref (self->pv->secret_records);
- self->pv->secret_records = records;
-
- obj = G_OBJECT (self);
- g_object_freeze_notify (obj);
- g_object_notify (obj, "secret-records");
- g_object_thaw_notify (obj);
-}
-
-/**
- * _gcr_gnupg_key_get_keyid:
- * @self: The key
- *
- * Get the keyid for this key.
- *
- * Returns: (transfer none): The keyid.
- */
-const gchar*
-_gcr_gnupg_key_get_keyid (GcrGnupgKey *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
- return _gcr_gnupg_records_get_keyid (self->pv->public_records);
-}
-
-/**
- * _gcr_gnupg_key_get_icon:
- * @self: A gnupg key.
- *
- * Get the display icon for this key.
- *
- * Return value: (transfer none): The icon, owned by the key.
- */
-GIcon*
-_gcr_gnupg_key_get_icon (GcrGnupgKey *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
-
- if (self->pv->icon == NULL) {
- self->pv->icon = _gcr_gnupg_records_get_icon (self->pv->public_records);
- if (self->pv->icon == NULL) {
- if (self->pv->secret_records)
- self->pv->icon = g_themed_icon_new ("gcr-key-pair");
- else
- self->pv->icon = g_themed_icon_new ("gcr-key");
- }
- }
-
- return self->pv->icon;
-}
-
-/**
- * _gcr_gnupg_key_get_columns:
- *
- * Get the columns that we should display for gnupg keys.
- *
- * Returns: (transfer none): The columns, NULL terminated, should not be freed.
- */
-const GcrColumn*
-_gcr_gnupg_key_get_columns (void)
-{
- static GcrColumn columns[] = {
- { "icon", /* later */ 0, /* later */ 0, NULL, 0, NULL, 0 },
- { "label", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Name"),
- GCR_COLUMN_SORTABLE, NULL, 0 },
- { "short-keyid", G_TYPE_STRING, G_TYPE_STRING, NC_("column", "Key ID"),
- GCR_COLUMN_SORTABLE, NULL, 0 },
- { NULL }
- };
-
- columns[0].property_type = columns[0].column_type = G_TYPE_ICON;
- return columns;
-}
diff --git a/gcr/gcr-gnupg-key.h b/gcr/gcr-gnupg-key.h
deleted file mode 100644
index 2c120af2..00000000
--- a/gcr/gcr-gnupg-key.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_GNUPG_KEY_H
-#define GCR_GNUPG_KEY_H
-
-#include <glib-object.h>
-
-#include "gcr-column.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_GNUPG_KEY_COLUMNS (_gcr_gnupg_key_get_columns ())
-#define GCR_TYPE_GNUPG_KEY (_gcr_gnupg_key_get_type ())
-#define GCR_GNUPG_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_GNUPG_KEY, GcrGnupgKey))
-#define GCR_GNUPG_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_GNUPG_KEY, GcrGnupgKeyClass))
-#define GCR_IS_GNUPG_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_GNUPG_KEY))
-#define GCR_IS_GNUPG_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_GNUPG_KEY))
-#define GCR_GNUPG_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_GNUPG_KEY, GcrGnupgKeyClass))
-
-typedef struct _GcrGnupgKey GcrGnupgKey;
-typedef struct _GcrGnupgKeyClass GcrGnupgKeyClass;
-typedef struct _GcrGnupgKeyPrivate GcrGnupgKeyPrivate;
-
-struct _GcrGnupgKey {
- /*< private >*/
- GObject parent;
- GcrGnupgKeyPrivate *pv;
-};
-
-struct _GcrGnupgKeyClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_gnupg_key_get_type (void);
-
-const GcrColumn* _gcr_gnupg_key_get_columns (void);
-
-GcrGnupgKey* _gcr_gnupg_key_new (GPtrArray *pubset,
- GPtrArray *secset);
-
-const gchar* _gcr_gnupg_key_get_keyid (GcrGnupgKey *self);
-
-GPtrArray* _gcr_gnupg_key_get_public_records (GcrGnupgKey *self);
-
-void _gcr_gnupg_key_set_public_records (GcrGnupgKey *self,
- GPtrArray *records);
-
-GPtrArray* _gcr_gnupg_key_get_secret_records (GcrGnupgKey *self);
-
-void _gcr_gnupg_key_set_secret_records (GcrGnupgKey *self,
- GPtrArray *records);
-
-GIcon* _gcr_gnupg_key_get_icon (GcrGnupgKey *self);
-
-G_END_DECLS
-
-#endif /* __GCR_GNUPG_KEY_H__ */
diff --git a/gcr/gcr-gnupg-process.c b/gcr/gcr-gnupg-process.c
deleted file mode 100644
index 81423da4..00000000
--- a/gcr/gcr-gnupg-process.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#define DEBUG_FLAG GCR_DEBUG_GNUPG
-#include "gcr-debug.h"
-#include "gcr-gnupg-process.h"
-#include "gcr-marshal.h"
-#include "gcr-util.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-/**
- * GcrGnupgProcessFlags:
- * @GCR_GNUPG_PROCESS_NONE: No flags
- * @GCR_GNUPG_PROCESS_RESPECT_LOCALE: Respect the user's locale when running gnupg.
- * @GCR_GNUPG_PROCESS_WITH_STATUS: Ask the process to send status records.
- * @GCR_GNUPG_PROCESS_WITH_ATTRIBUTES: Ask the process to output attribute data.
- *
- * Flags for running a gnupg process.
- */
-
-enum {
- PROP_0,
- PROP_DIRECTORY,
- PROP_EXECUTABLE,
- PROP_INPUT_STREAM,
- PROP_OUTPUT_STREAM,
- PROP_ATTRIBUTE_STREAM
-};
-
-enum {
- FD_INPUT,
- FD_OUTPUT,
- FD_ERROR,
- FD_STATUS,
- FD_ATTRIBUTE,
- NUM_FDS
-};
-
-enum {
- ERROR_LINE,
- STATUS_RECORD,
- NUM_SIGNALS
-};
-
-static gint signals[NUM_SIGNALS] = { 0, };
-
-typedef struct _GnupgSource {
- GSource source;
- GPollFD polls[NUM_FDS]; /* The various fd's we're listening to */
-
- GcrGnupgProcess *process; /* Pointer back to the process object */
-
- GByteArray *input_buf;
- GString *error_buf;
- GString *status_buf;
- guint source_sig;
-
- GPid child_pid;
- guint child_sig;
-
- GCancellable *cancellable;
- guint cancel_sig;
-} GnupgSource;
-
-struct _GcrGnupgProcessPrivate {
- gchar *directory;
- gchar *executable;
-
- GInputStream *input;
- GOutputStream *output;
- GOutputStream *attributes;
-
- gboolean running;
- gboolean complete;
- GError *error;
-
- GAsyncReadyCallback async_callback;
- gpointer user_data;
-};
-
-/* Forward declarations */
-static void _gcr_gnupg_process_init_async (GAsyncResultIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrGnupgProcess, _gcr_gnupg_process, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, _gcr_gnupg_process_init_async));
-
-static void
-_gcr_gnupg_process_init (GcrGnupgProcess *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_PROCESS,
- GcrGnupgProcessPrivate);
-}
-
-static void
-_gcr_gnupg_process_constructed (GObject *obj)
-{
- GcrGnupgProcess *self = GCR_GNUPG_PROCESS (obj);
-
- if (G_OBJECT_CLASS (_gcr_gnupg_process_parent_class)->constructed)
- G_OBJECT_CLASS (_gcr_gnupg_process_parent_class)->constructed (obj);
-
- if (!self->pv->executable)
- self->pv->executable = g_strdup (GPG_EXECUTABLE);
-}
-
-static void
-_gcr_gnupg_process_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgProcess *self = GCR_GNUPG_PROCESS (obj);
-
- switch (prop_id) {
- case PROP_DIRECTORY:
- g_value_set_string (value, self->pv->directory);
- break;
- case PROP_EXECUTABLE:
- g_value_set_string (value, self->pv->executable);
- break;
- case PROP_INPUT_STREAM:
- g_value_set_object (value, _gcr_gnupg_process_get_input_stream (self));
- break;
- case PROP_OUTPUT_STREAM:
- g_value_set_object (value, _gcr_gnupg_process_get_output_stream (self));
- break;
- case PROP_ATTRIBUTE_STREAM:
- g_value_set_object (value, _gcr_gnupg_process_get_attribute_stream (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_process_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgProcess *self = GCR_GNUPG_PROCESS (obj);
-
- switch (prop_id) {
- case PROP_DIRECTORY:
- g_return_if_fail (!self->pv->directory);
- self->pv->directory = g_value_dup_string (value);
- break;
- case PROP_EXECUTABLE:
- g_return_if_fail (!self->pv->executable);
- self->pv->executable = g_value_dup_string (value);
- break;
- case PROP_INPUT_STREAM:
- _gcr_gnupg_process_set_input_stream (self, g_value_get_object (value));
- break;
- case PROP_OUTPUT_STREAM:
- _gcr_gnupg_process_set_output_stream (self, g_value_get_object (value));
- break;
- case PROP_ATTRIBUTE_STREAM:
- _gcr_gnupg_process_set_attribute_stream (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_process_dispose (GObject *obj)
-{
- GcrGnupgProcess *self = GCR_GNUPG_PROCESS (obj);
-
- g_clear_object (&self->pv->input);
- g_clear_object (&self->pv->output);
- g_clear_object (&self->pv->attributes);
-
- G_OBJECT_CLASS (_gcr_gnupg_process_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_gnupg_process_finalize (GObject *obj)
-{
- GcrGnupgProcess *self = GCR_GNUPG_PROCESS (obj);
-
- g_assert (!self->pv->running);
- g_free (self->pv->directory);
- g_free (self->pv->executable);
- g_clear_error (&self->pv->error);
-
- G_OBJECT_CLASS (_gcr_gnupg_process_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_gnupg_process_class_init (GcrGnupgProcessClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructed = _gcr_gnupg_process_constructed;
- gobject_class->get_property = _gcr_gnupg_process_get_property;
- gobject_class->set_property = _gcr_gnupg_process_set_property;
- gobject_class->dispose = _gcr_gnupg_process_dispose;
- gobject_class->finalize = _gcr_gnupg_process_finalize;
-
- /**
- * GcrGnupgProcess:directory:
- *
- * Directory to run as gnupg home directory, or %NULL for default
- * ~/.gnupg/ directory.
- */
- g_object_class_install_property (gobject_class, PROP_DIRECTORY,
- g_param_spec_string ("directory", "Directory", "Gnupg Directory",
- NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /**
- * GcrGnupgProcess:executable:
- *
- * Path to the gnupg executable, or %NULL for default.
- */
- g_object_class_install_property (gobject_class, PROP_EXECUTABLE,
- g_param_spec_string ("executable", "Executable", "Gnupg Executable",
- GPG_EXECUTABLE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /**
- * GcrGnupgProcess:input-stream:
- *
- * Input for gnupg, or %NULL for no input.
- */
- g_object_class_install_property (gobject_class, PROP_INPUT_STREAM,
- g_param_spec_object ("input-stream", "Input Stream", "Input Stream",
- G_TYPE_INPUT_STREAM, G_PARAM_READWRITE));
-
- /**
- * GcrGnupgProcess:output-stream:
- *
- * Output from gnupg, or %NULL for ignored output.
- */
- g_object_class_install_property (gobject_class, PROP_OUTPUT_STREAM,
- g_param_spec_object ("output-stream", "Output Stream", "Output Stream",
- G_TYPE_OUTPUT_STREAM, G_PARAM_READWRITE));
-
- /**
- * GcrGnupgProcess:attribute-stream:
- *
- * Output of attribute data from gnupg, or %NULL for ignored attributes.
- */
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTE_STREAM,
- g_param_spec_object ("attribute-stream", "Attribute Stream", "Attribute Stream",
- G_TYPE_OUTPUT_STREAM, G_PARAM_READWRITE));
-
- /**
- * GcrGnupgProcess::error-line:
- * @line: a line of error output.
- *
- * Signal emitted when a line of error output is available from the
- * gnupg process.
- */
- signals[ERROR_LINE] = g_signal_new ("error-line", GCR_TYPE_GNUPG_PROCESS,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrGnupgProcessClass, error_line),
- NULL, NULL, _gcr_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- /**
- * GcrGnupgProcess::status-record:
- * @record: a status record.
- *
- * Signal emitted when a status record is available from the gnupg process.
- */
- signals[STATUS_RECORD] = g_signal_new ("status-record", GCR_TYPE_GNUPG_PROCESS,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrGnupgProcessClass, status_record),
- NULL, NULL, _gcr_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, GCR_TYPE_RECORD);
-
- g_type_class_add_private (gobject_class, sizeof (GcrGnupgProcessPrivate));
-}
-
-static gpointer
-_gcr_gnupg_process_get_user_data (GAsyncResult *result)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_PROCESS (result), NULL);
- return GCR_GNUPG_PROCESS (result)->pv->user_data;
-}
-
-static GObject*
-_gcr_gnupg_process_get_source_object (GAsyncResult *result)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_PROCESS (result), NULL);
- return G_OBJECT (result);
-}
-
-static void
-_gcr_gnupg_process_init_async (GAsyncResultIface *iface)
-{
- iface->get_source_object = _gcr_gnupg_process_get_source_object;
- iface->get_user_data = _gcr_gnupg_process_get_user_data;
-}
-
-/**
- * _gcr_gnupg_process_new:
- * @directory: (allow-none): The gnupg home directory
- * @executable: (allow-none): The gpg executable
- *
- * Create a new GcrGnupgProcess.
- *
- * The gnupg home directory is where the keyring files live. If directory is
- * %NULL then the default gnupg home directory is used.
- *
- * The executable will default to the compiled in path if a %NULL executable
- * argument is used.
- *
- * Returns: (transfer full): A newly allocated process.
- */
-GcrGnupgProcess*
-_gcr_gnupg_process_new (const gchar *directory, const gchar *executable)
-{
- return g_object_new (GCR_TYPE_GNUPG_PROCESS,
- "directory", directory,
- "executable", executable,
- NULL);
-}
-
-const gchar *
-_gcr_gnupg_process_get_directory (GcrGnupgProcess *self)
-{
- g_return_val_if_fail (GCR_GNUPG_PROCESS (self), NULL);
- return self->pv->directory;
-}
-
-GInputStream *
-_gcr_gnupg_process_get_input_stream (GcrGnupgProcess *self)
-{
- g_return_val_if_fail (GCR_GNUPG_PROCESS (self), NULL);
- return self->pv->input;
-}
-
-void
-_gcr_gnupg_process_set_input_stream (GcrGnupgProcess *self,
- GInputStream *input)
-{
- g_return_if_fail (GCR_GNUPG_PROCESS (self));
- g_return_if_fail (input == NULL || G_INPUT_STREAM (input));
-
- if (input)
- g_object_ref (input);
- if (self->pv->input)
- g_object_unref (self->pv->input);
- self->pv->input = input;
- g_object_notify (G_OBJECT (self), "input-stream");
-}
-
-GOutputStream *
-_gcr_gnupg_process_get_output_stream (GcrGnupgProcess *self)
-{
- g_return_val_if_fail (GCR_GNUPG_PROCESS (self), NULL);
- return self->pv->output;
-}
-
-void
-_gcr_gnupg_process_set_output_stream (GcrGnupgProcess *self,
- GOutputStream *output)
-{
- g_return_if_fail (GCR_GNUPG_PROCESS (self));
- g_return_if_fail (output == NULL || G_OUTPUT_STREAM (output));
-
- if (output)
- g_object_ref (output);
- if (self->pv->output)
- g_object_unref (self->pv->output);
- self->pv->output = output;
- g_object_notify (G_OBJECT (self), "output-stream");
-}
-
-GOutputStream *
-_gcr_gnupg_process_get_attribute_stream (GcrGnupgProcess *self)
-{
- g_return_val_if_fail (GCR_GNUPG_PROCESS (self), NULL);
- return self->pv->attributes;
-}
-
-void
-_gcr_gnupg_process_set_attribute_stream (GcrGnupgProcess *self,
- GOutputStream *output)
-{
- g_return_if_fail (GCR_GNUPG_PROCESS (self));
- g_return_if_fail (output == NULL || G_OUTPUT_STREAM (output));
-
- if (output)
- g_object_ref (output);
- if (self->pv->attributes)
- g_object_unref (self->pv->attributes);
- self->pv->attributes = output;
- g_object_notify (G_OBJECT (self), "attribute-stream");
-}
-
-static void
-run_async_ready_callback (GcrGnupgProcess *self)
-{
- GAsyncReadyCallback callback;
- gpointer user_data;
-
- _gcr_debug ("running async callback");
-
- /* Remove these before completing */
- callback = self->pv->async_callback;
- user_data = self->pv->user_data;
- self->pv->async_callback = NULL;
- self->pv->user_data = NULL;
-
- if (callback != NULL)
- (callback) (G_OBJECT (self), G_ASYNC_RESULT (self), user_data);
-}
-
-static gboolean
-on_run_async_ready_callback_later (gpointer user_data)
-{
- run_async_ready_callback (GCR_GNUPG_PROCESS (user_data));
- return FALSE; /* Don't run this callback again */
-}
-
-static void
-run_async_ready_callback_later (GcrGnupgProcess *self)
-{
- _gcr_debug ("running async callback later");
- g_idle_add_full (G_PRIORITY_DEFAULT, on_run_async_ready_callback_later,
- g_object_ref (self), g_object_unref);
-}
-
-static void
-complete_run_process (GcrGnupgProcess *self)
-{
- g_return_if_fail (self->pv->running);
- g_return_if_fail (!self->pv->complete);
-
- self->pv->running = FALSE;
- self->pv->complete = TRUE;
-
- if (self->pv->error == NULL) {
- _gcr_debug ("completed process");
- } else {
- _gcr_debug ("completed process with error: %s",
- self->pv->error->message);
- }
-}
-
-static gboolean
-complete_source_is_done (GnupgSource *gnupg_source)
-{
- _gcr_debug ("all fds closed and process exited, completing");
-
- g_assert (gnupg_source->child_sig == 0);
- g_assert (gnupg_source->source_sig == 0);
-
- complete_run_process (gnupg_source->process);
- run_async_ready_callback (gnupg_source->process);
-
- /* All done, the source can go away now */
- g_source_unref ((GSource*)gnupg_source);
- return TRUE;
-}
-
-static void
-close_fd (int *fd)
-{
- g_assert (fd);
- if (*fd >= 0) {
- _gcr_debug ("closing fd: %d", *fd);
- close (*fd);
- }
- *fd = -1;
-}
-
-static void
-close_poll (GSource *source, GPollFD *poll)
-{
- g_source_remove_poll (source, poll);
- close_fd (&poll->fd);
- poll->revents = 0;
-}
-
-static gboolean
-unused_callback (gpointer data)
-{
- /* Never called */
- g_assert_not_reached ();
- return FALSE;
-}
-
-static gboolean
-on_gnupg_source_prepare (GSource *source, gint *timeout_)
-{
- GnupgSource *gnupg_source = (GnupgSource*)source;
- gint i;
-
- for (i = 0; i < NUM_FDS; ++i) {
- if (gnupg_source->polls[i].fd >= 0)
- return FALSE;
- }
-
- /* If none of the FDs are valid, then process immediately */
- return TRUE;
-}
-
-static gboolean
-on_gnupg_source_check (GSource *source)
-{
- GnupgSource *gnupg_source = (GnupgSource*)source;
- gint i;
-
- for (i = 0; i < NUM_FDS; ++i) {
- if (gnupg_source->polls[i].fd >= 0 && gnupg_source->polls[i].revents != 0)
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-on_gnupg_source_finalize (GSource *source)
-{
- GnupgSource *gnupg_source = (GnupgSource*)source;
- gint i;
-
- if (gnupg_source->cancel_sig)
- g_signal_handler_disconnect (gnupg_source->cancellable, gnupg_source->cancel_sig);
- if (gnupg_source->cancellable)
- g_object_unref (gnupg_source->cancellable);
-
- for (i = 0; i < NUM_FDS; ++i)
- close_fd (&gnupg_source->polls[i].fd);
-
- g_object_unref (gnupg_source->process);
- if (gnupg_source->input_buf)
- g_byte_array_free (gnupg_source->input_buf, TRUE);
- g_string_free (gnupg_source->error_buf, TRUE);
- g_string_free (gnupg_source->status_buf, TRUE);
-
- g_assert (!gnupg_source->child_pid);
- g_assert (!gnupg_source->child_sig);
-}
-
-static gboolean
-read_output (int fd, GByteArray *buffer)
-{
- guchar block[1024];
- gssize result;
-
- g_return_val_if_fail (fd >= 0, FALSE);
-
- do {
- result = read (fd, block, sizeof (block));
- if (result < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return FALSE;
- } else {
- g_byte_array_append (buffer, block, result);
- }
- } while (result == sizeof (block));
-
- return TRUE;
-}
-
-static gboolean
-write_input (int fd, GByteArray *buffer)
-{
- gssize result;
-
- g_return_val_if_fail (fd >= 0, FALSE);
-
- for (;;) {
- result = write (fd, buffer->data, buffer->len);
- if (result < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return FALSE;
- } else {
- g_byte_array_remove_range (buffer, 0, result);
- return TRUE;
- }
- }
-}
-
-static void
-emit_status_for_each_line (const gchar *line, gpointer user_data)
-{
- GcrRecord *record;
-
- if (g_str_has_prefix (line, "[GNUPG:] ")) {
- _gcr_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
-emit_error_for_each_line (const gchar *line, gpointer user_data)
-{
- _gcr_debug ("received error line: %s", line);
- g_signal_emit (GCR_GNUPG_PROCESS (user_data), signals[ERROR_LINE], 0, line);
-}
-
-static gboolean
-on_gnupg_source_input (GcrGnupgProcess *self,
- GnupgSource *gnupg_source,
- gint fd)
-{
- gssize read;
-
- if (gnupg_source->input_buf == NULL ||
- gnupg_source->input_buf->len == 0) {
- if (self->pv->input == NULL)
- return FALSE;
- if (!gnupg_source->input_buf)
- gnupg_source->input_buf = g_byte_array_new ();
- g_byte_array_set_size (gnupg_source->input_buf, 4096);
- read = g_input_stream_read (self->pv->input,
- gnupg_source->input_buf->data,
- gnupg_source->input_buf->len,
- gnupg_source->cancellable, NULL);
- g_byte_array_set_size (gnupg_source->input_buf, read < 0 ? 0 : read);
- if (read < 0)
- return FALSE;
- if (read == 0)
- return FALSE;
- }
-
- if (!write_input (fd, gnupg_source->input_buf)) {
- g_warning ("couldn't write output data to gnupg process");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-on_gnupg_source_status (GcrGnupgProcess *self,
- GnupgSource *gnupg_source,
- gint fd)
-{
- GByteArray *buffer = g_byte_array_new ();
- gboolean result = TRUE;
-
- if (!read_output (fd, buffer)) {
- g_warning ("couldn't read status data from gnupg process");
- result = FALSE;
- } else {
- g_string_append_len (gnupg_source->status_buf, (gchar*)buffer->data, buffer->len);
- _gcr_util_parse_lines (gnupg_source->status_buf, buffer->len == 0,
- emit_status_for_each_line, self);
- }
-
- g_byte_array_unref (buffer);
- return result;
-}
-
-static gboolean
-on_gnupg_source_attribute (GcrGnupgProcess *self,
- GnupgSource *gnupg_source,
- gint fd)
-{
- GByteArray *buffer = g_byte_array_new ();
- gboolean result = TRUE;
-
- if (!read_output (fd, buffer)) {
- g_warning ("couldn't read attribute data from gnupg process");
- result = FALSE;
- } else if (buffer->len > 0) {
- _gcr_debug ("received %d bytes of attribute data", (gint)buffer->len);
- if (self->pv->attributes != NULL)
- g_output_stream_write_all (self->pv->attributes, buffer->data,
- buffer->len, NULL,
- gnupg_source->cancellable, NULL);
- }
-
- g_byte_array_unref (buffer);
- return result;
-}
-
-static gboolean
-on_gnupg_source_output (GcrGnupgProcess *self,
- GnupgSource *gnupg_source,
- gint fd)
-{
- GByteArray *buffer = g_byte_array_new ();
- gboolean result = TRUE;
-
- if (!read_output (fd, buffer)) {
- g_warning ("couldn't read output data from gnupg process");
- result = FALSE;
- } else if (buffer->len > 0) {
- _gcr_debug ("received %d bytes of output data", (gint)buffer->len);
- if (self->pv->output != NULL)
- g_output_stream_write_all (self->pv->output, buffer->data, buffer->len,
- NULL, gnupg_source->cancellable, NULL);
- }
-
- g_byte_array_unref (buffer);
- return result;
-}
-
-static gboolean
-on_gnupg_source_error (GcrGnupgProcess *self,
- GnupgSource *gnupg_source,
- gint fd,
- gboolean last)
-{
- GByteArray *buffer = g_byte_array_new ();
- gboolean result = TRUE;
-
- if (!read_output (fd, buffer)) {
- g_warning ("couldn't read error data from gnupg process");
- result = FALSE;
- } else {
- g_string_append_len (gnupg_source->error_buf, (gchar*)buffer->data, buffer->len);
- _gcr_util_parse_lines (gnupg_source->error_buf, last,
- emit_error_for_each_line, gnupg_source->process);
- }
-
- g_byte_array_unref (buffer);
- return result;
-}
-
-static gboolean
-on_gnupg_source_dispatch (GSource *source, GSourceFunc unused, gpointer user_data)
-{
- GnupgSource *gnupg_source = (GnupgSource*)source;
- GcrGnupgProcess *self = gnupg_source->process;
- GPollFD *poll;
- guint i;
-
- /* Standard input, no support yet */
- poll = &gnupg_source->polls[FD_INPUT];
- if (poll->fd >= 0) {
- if (poll->revents & G_IO_OUT)
- if (!on_gnupg_source_input (self, gnupg_source, poll->fd))
- poll->revents |= G_IO_HUP;
- if (poll->revents & G_IO_HUP)
- close_poll (source, poll);
- poll->revents = 0;
- }
-
- /* Status output */
- poll = &gnupg_source->polls[FD_STATUS];
- if (poll->fd >= 0) {
- if (poll->revents & G_IO_IN)
- if (!on_gnupg_source_status (self, gnupg_source, poll->fd))
- poll->revents |= G_IO_HUP;
- if (poll->revents & G_IO_HUP)
- close_poll (source, poll);
- poll->revents = 0;
- }
-
- /* Attribute output */
- poll = &gnupg_source->polls[FD_ATTRIBUTE];
- if (poll->fd >= 0) {
- if (poll->revents & G_IO_IN)
- if (!on_gnupg_source_attribute (self, gnupg_source, poll->fd))
- poll->revents |= G_IO_HUP;
- if (poll->revents & G_IO_HUP)
- close_poll (source, poll);
- poll->revents = 0;
- }
-
- /* Standard output */
- poll = &gnupg_source->polls[FD_OUTPUT];
- if (poll->fd >= 0) {
- if (poll->revents & G_IO_IN)
- if (!on_gnupg_source_output (self, gnupg_source, poll->fd))
- poll->revents |= G_IO_HUP;
- if (poll->revents & G_IO_HUP)
- close_poll (source, poll);
- poll->revents = 0;
- }
-
- /* Standard error */
- poll = &gnupg_source->polls[FD_ERROR];
- if (poll->fd >= 0) {
- if (poll->revents & G_IO_IN)
- if (!on_gnupg_source_error (self, gnupg_source, poll->fd,
- (poll->revents & G_IO_HUP) ? TRUE : FALSE))
- poll->revents |= G_IO_HUP;
- if (poll->revents & G_IO_HUP)
- close_poll (source, poll);
- poll->revents = 0;
- }
-
- for (i = 0; i < NUM_FDS; ++i) {
- if (gnupg_source->polls[i].fd >= 0)
- return TRUE;
- }
-
- /* Because we return below */
- gnupg_source->source_sig = 0;
-
- if (!gnupg_source->child_pid)
- complete_source_is_done (gnupg_source);
-
- return FALSE; /* Disconnect this source */
-}
-
-static GSourceFuncs gnupg_source_funcs = {
- on_gnupg_source_prepare,
- on_gnupg_source_check,
- on_gnupg_source_dispatch,
- on_gnupg_source_finalize,
-};
-
-static void
-on_gnupg_process_child_exited (GPid pid, gint status, gpointer user_data)
-{
- GnupgSource *gnupg_source = user_data;
- GcrGnupgProcess *self = gnupg_source->process;
- GError *error = NULL;
- gint code;
- guint i;
-
- _gcr_debug ("process exited: %d", (int)pid);
-
- g_spawn_close_pid (gnupg_source->child_pid);
- gnupg_source->child_pid = 0;
- gnupg_source->child_sig = 0;
-
- if (WIFEXITED (status)) {
- code = WEXITSTATUS (status);
- if (code != 0) {
- error = g_error_new (G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
- _("Gnupg process exited with code: %d"), code);
- }
- } else if (WIFSIGNALED (status)) {
- code = WTERMSIG (status);
- /* Ignore cases where we've signaled the process because we were cancelled */
- if (!g_error_matches (self->pv->error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- error = g_error_new (G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
- _("Gnupg process was terminated with signal: %d"), code);
- }
-
- /* Take this as the async result error */
- if (error && !self->pv->error) {
- _gcr_debug ("%s", error->message);
- self->pv->error = error;
-
- /* Already have an error, just print out message */
- } else if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- for (i = 0; i < NUM_FDS; ++i) {
- if (gnupg_source->polls[i].fd >= 0)
- return;
- }
-
- complete_source_is_done (gnupg_source);
-}
-
-static void
-on_gnupg_process_child_setup (gpointer user_data)
-{
- int *child_fds = user_data;
- long val;
- guint i;
-
- /*
- * Clear close-on-exec flag for these file descriptors, so that
- * gnupg can write to them
- */
-
- for (i = 0; i < NUM_FDS; i++) {
- if (child_fds[i] >= 0) {
- val = fcntl (child_fds[i], F_GETFD);
- fcntl (child_fds[i], F_SETFD, val & ~FD_CLOEXEC);
- }
- }
-}
-
-static void
-on_cancellable_cancelled (GCancellable *cancellable, gpointer user_data)
-{
- GnupgSource *gnupg_source = user_data;
-
- g_assert (gnupg_source->process);
-
- _gcr_debug ("process cancelled");
-
- /* Set an error, which is respected when this actually completes. */
- if (gnupg_source->process->pv->error == NULL)
- gnupg_source->process->pv->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("The operation was cancelled"));
-
- /* Try and kill the child process */
- if (gnupg_source->child_pid) {
- _gcr_debug ("sending term signal to process: %d",
- (int)gnupg_source->child_pid);
- kill (gnupg_source->child_pid, SIGTERM);
- }
-}
-
-/**
- * _gcr_gnupg_process_run_async:
- * @self: The process
- * @argv: (array zero-terminated=1): The arguments for the process, not including executable, terminated with %NULL.
- * @envp: (allow-none) (array zero-terminated=1): The environment for new process, terminated with %NULL.
- * @flags: Flags for starting the process.
- * @cancellable: (allow-none): Cancellation object
- * @callback: Will be called when operation completes.
- * @user_data: (closure): Data passed to callback.
- *
- * Run the gpg process. Only one 'run' operation can run per GcrGnupgProcess
- * object. The GcrGnupgProcess:output_data and GcrGnupgProcess:error_line
- * signals will be emitted when data is received from the gpg process.
- *
- * Unless the %GCR_GNUPG_PROCESS_RESPECT_LOCALE flag is specified, the process
- * will be run in the 'C' locale. If the %GCR_GNUPG_PROCESS_WITH_STATUS or
- * %GCR_GNUPG_PROCESS_WITH_ATTRIBUTES flags are set, then the gpg process
- * will be status and attribute output respectively. The
- * GcrGnupgProcess:status_record and GcrGnupgProcess:attribute_data signals
- * will provide this data.
- */
-void
-_gcr_gnupg_process_run_async (GcrGnupgProcess *self, const gchar **argv, const gchar **envp,
- GcrGnupgProcessFlags flags, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GError *error = NULL;
- GPtrArray *args;
- GPtrArray *envs;
- int child_fds[NUM_FDS];
- int status_fds[2] = { -1, -1 };
- int attribute_fds[2] = { -1, -1 };
- int output_fd = -1;
- int error_fd = -1;
- int input_fd = -1;
- GnupgSource *gnupg_source;
- GSource *source;
- GPid pid;
- guint i;
-
- g_return_if_fail (GCR_IS_GNUPG_PROCESS (self));
- g_return_if_fail (argv);
- g_return_if_fail (callback);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- g_return_if_fail (self->pv->running == FALSE);
- g_return_if_fail (self->pv->complete == FALSE);
- g_return_if_fail (self->pv->executable);
-
- self->pv->async_callback = callback;
- self->pv->user_data = user_data;
-
- for (i = 0; i < NUM_FDS; i++)
- child_fds[i] = -1;
-
- /* The command needs to be updated with these status and attribute fds */
- args = g_ptr_array_new_with_free_func (g_free);
- g_ptr_array_add (args, g_strdup (self->pv->executable));
-
- /* Spawn/child will close all other attributes, besides thesthose in child_fds */
- child_fds[FD_INPUT] = 0;
- child_fds[FD_OUTPUT] = 1;
- child_fds[FD_ERROR] = 2;
-
- if (flags & GCR_GNUPG_PROCESS_WITH_STATUS) {
- if (pipe (status_fds) < 0)
- g_return_if_reached ();
- child_fds[FD_STATUS] = status_fds[1];
- g_ptr_array_add (args, g_strdup ("--status-fd"));
- g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_STATUS]));
- }
- if (flags & GCR_GNUPG_PROCESS_WITH_ATTRIBUTES) {
- if (pipe (attribute_fds) < 0)
- g_return_if_reached ();
- child_fds[FD_ATTRIBUTE] = attribute_fds[1];
- g_ptr_array_add (args, g_strdup ("--attribute-fd"));
- g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_ATTRIBUTE]));
- }
-
- if (self->pv->directory) {
- g_ptr_array_add (args, g_strdup ("--homedir"));
- g_ptr_array_add (args, g_strdup (self->pv->directory));
- }
-
- /* All the remaining arguments */
- for (i = 0; argv[i] != NULL; i++)
- g_ptr_array_add (args, g_strdup (argv[i]));
- g_ptr_array_add (args, NULL);
-
- envs = g_ptr_array_new ();
- for (i = 0; envp && envp[i] != NULL; i++) {
- if (flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE ||
- !g_str_has_prefix (envp[i], "LOCALE="))
- g_ptr_array_add (envs, (gpointer)envp[i]);
- }
- if (!(flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE))
- g_ptr_array_add (envs, (gpointer)"LOCALE=C");
- g_ptr_array_add (envs, NULL);
-
- if (_gcr_debugging) {
- gchar *command = g_strjoinv (" ", (gchar**)args->pdata);
- gchar *environ = g_strjoinv (", ", (gchar**)envs->pdata);
- _gcr_debug ("running command: %s", command);
- _gcr_debug ("process environment: %s", environ);
- g_free (command);
- g_free (environ);
- }
-
- g_spawn_async_with_pipes (self->pv->directory, (gchar**)args->pdata,
- (gchar**)envs->pdata, G_SPAWN_DO_NOT_REAP_CHILD,
- on_gnupg_process_child_setup, child_fds,
- &pid, &input_fd, &output_fd, &error_fd, &error);
-
- g_ptr_array_free (args, TRUE);
- g_ptr_array_free (envs, TRUE);
-
- /* Close 'wrong' ends of extra file descriptors */
- close_fd (&(status_fds[1]));
- close_fd (&(attribute_fds[1]));
-
- self->pv->complete = FALSE;
- self->pv->running = TRUE;
-
- if (error) {
- close_fd (&(status_fds[0]));
- close_fd (&(attribute_fds[0]));
- g_assert (!self->pv->error);
- self->pv->error = error;
- complete_run_process (self);
- run_async_ready_callback_later (self);
- return;
- }
-
- _gcr_debug ("process started: %d", (int)pid);
-
- source = g_source_new (&gnupg_source_funcs, sizeof (GnupgSource));
-
- /* Initialize the source */
- gnupg_source = (GnupgSource*)source;
- for (i = 0; i < NUM_FDS; i++)
- gnupg_source->polls[i].fd = -1;
- gnupg_source->error_buf = g_string_sized_new (128);
- gnupg_source->status_buf = g_string_sized_new (128);
- gnupg_source->process = g_object_ref (self);
- gnupg_source->child_pid = pid;
-
- gnupg_source->polls[FD_INPUT].fd = input_fd;
- if (input_fd >= 0) {
- gnupg_source->polls[FD_INPUT].events = G_IO_HUP | G_IO_OUT;
- g_source_add_poll (source, &gnupg_source->polls[FD_INPUT]);
- }
- gnupg_source->polls[FD_OUTPUT].fd = output_fd;
- if (output_fd >= 0) {
- gnupg_source->polls[FD_OUTPUT].events = G_IO_HUP | G_IO_IN;
- g_source_add_poll (source, &gnupg_source->polls[FD_OUTPUT]);
- }
- gnupg_source->polls[FD_ERROR].fd = error_fd;
- if (error_fd >= 0) {
- gnupg_source->polls[FD_ERROR].events = G_IO_HUP | G_IO_IN;
- g_source_add_poll (source, &gnupg_source->polls[FD_ERROR]);
- }
- gnupg_source->polls[FD_STATUS].fd = status_fds[0];
- if (status_fds[0] >= 0) {
- gnupg_source->polls[FD_STATUS].events = G_IO_HUP | G_IO_IN;
- g_source_add_poll (source, &gnupg_source->polls[FD_STATUS]);
- }
- gnupg_source->polls[FD_ATTRIBUTE].fd = attribute_fds[0];
- if (attribute_fds[0] >= 0) {
- gnupg_source->polls[FD_ATTRIBUTE].events = G_IO_HUP | G_IO_IN;
- g_source_add_poll (source, &gnupg_source->polls[FD_ATTRIBUTE]);
- }
-
- if (cancellable) {
- gnupg_source->cancellable = g_object_ref (cancellable);
- gnupg_source->cancel_sig = g_cancellable_connect (cancellable,
- G_CALLBACK (on_cancellable_cancelled),
- g_source_ref (source),
- (GDestroyNotify)g_source_unref);
- }
-
- g_source_set_callback (source, unused_callback, NULL, NULL);
- gnupg_source->source_sig = g_source_attach (source, g_main_context_default ());
-
- /* This assumes the outstanding reference to source */
- g_assert (!gnupg_source->child_sig);
- gnupg_source->child_sig = g_child_watch_add_full (G_PRIORITY_DEFAULT, pid,
- on_gnupg_process_child_exited,
- g_source_ref (source),
- (GDestroyNotify)g_source_unref);
-
- /* source is unreffed in complete_if_source_is_done() */
-}
-
-/**
- * _gcr_gnupg_process_run_finish:
- * @self: The process
- * @result: The result passed to the callback
- * @error: Location to raise an error on failure.
- *
- * Get the result of running a gnupg process.
- *
- * Return value: Whether the Gnupg process was run or not.
- */
-gboolean
-_gcr_gnupg_process_run_finish (GcrGnupgProcess *self, GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_PROCESS (self), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
- g_return_val_if_fail (G_ASYNC_RESULT (self) == result, FALSE);
- g_return_val_if_fail (self->pv->complete, FALSE);
-
- /* This allows the process to run again... */
- self->pv->complete = FALSE;
-
- g_assert (!self->pv->running);
- g_assert (!self->pv->async_callback);
- g_assert (!self->pv->user_data);
-
- if (self->pv->error) {
- g_propagate_error (error, self->pv->error);
- self->pv->error = NULL;
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/gcr/gcr-gnupg-process.h b/gcr/gcr-gnupg-process.h
deleted file mode 100644
index 61e4894b..00000000
--- a/gcr/gcr-gnupg-process.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_GNUPG_PROCESS_H
-#define GCR_GNUPG_PROCESS_H
-
-#include "gcr-base.h"
-#include "gcr-record.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_GNUPG_PROCESS (_gcr_gnupg_process_get_type ())
-#define GCR_GNUPG_PROCESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_GNUPG_PROCESS, GcrGnupgProcess))
-#define GCR_GNUPG_PROCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_GNUPG_PROCESS, GcrGnupgProcessClass))
-#define GCR_IS_GNUPG_PROCESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_GNUPG_PROCESS))
-#define GCR_IS_GNUPG_PROCESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_GNUPG_PROCESS))
-#define GCR_GNUPG_PROCESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_GNUPG_PROCESS, GcrGnupgProcessClass))
-
-typedef struct _GcrGnupgProcess GcrGnupgProcess;
-typedef struct _GcrGnupgProcessClass GcrGnupgProcessClass;
-typedef struct _GcrGnupgProcessPrivate GcrGnupgProcessPrivate;
-
-struct _GcrGnupgProcess {
- /*< private >*/
- GObject parent;
- GcrGnupgProcessPrivate *pv;
-};
-
-struct _GcrGnupgProcessClass {
- GObjectClass parent_class;
-
- /* signals */
- gboolean (*error_line) (GcrGnupgProcess *self, const gchar *line);
-
- gboolean (*status_record) (GcrGnupgProcess *self, GcrRecord *record);
-};
-
-typedef enum {
- GCR_GNUPG_PROCESS_NONE = 0,
- GCR_GNUPG_PROCESS_RESPECT_LOCALE = 1 << 0,
- GCR_GNUPG_PROCESS_WITH_STATUS = 1 << 1,
- GCR_GNUPG_PROCESS_WITH_ATTRIBUTES = 1 << 2
-} GcrGnupgProcessFlags;
-
-GType _gcr_gnupg_process_get_type (void) G_GNUC_CONST;
-
-GcrGnupgProcess* _gcr_gnupg_process_new (const gchar *directory,
- const gchar *executable);
-
-const gchar * _gcr_gnupg_process_get_directory (GcrGnupgProcess *self);
-
-GInputStream * _gcr_gnupg_process_get_input_stream (GcrGnupgProcess *self);
-
-void _gcr_gnupg_process_set_input_stream (GcrGnupgProcess *self,
- GInputStream *input);
-
-GOutputStream * _gcr_gnupg_process_get_output_stream (GcrGnupgProcess *self);
-
-void _gcr_gnupg_process_set_output_stream (GcrGnupgProcess *self,
- GOutputStream *output);
-
-GOutputStream * _gcr_gnupg_process_get_attribute_stream (GcrGnupgProcess *self);
-
-void _gcr_gnupg_process_set_attribute_stream (GcrGnupgProcess *self,
- GOutputStream *output);
-
-void _gcr_gnupg_process_run_async (GcrGnupgProcess *self,
- const gchar **argv,
- const gchar **envp,
- GcrGnupgProcessFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean _gcr_gnupg_process_run_finish (GcrGnupgProcess *self,
- GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* GCR_GNUPG_PROCESS_H */
diff --git a/gcr/gcr-gnupg-records.c b/gcr/gcr-gnupg-records.c
deleted file mode 100644
index e634b1f1..00000000
--- a/gcr/gcr-gnupg-records.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-gnupg-records.h"
-#include "gcr-record.h"
-#include "gcr-memory-icon.h"
-
-#include "gck/gck.h"
-
-#include <glib/gi18n-lib.h>
-
-/* Copied from GPGME */
-gboolean
-_gcr_gnupg_records_parse_user_id (const gchar *user_id,
- gchar **rname,
- gchar **remail,
- gchar **rcomment)
-{
- gchar *src, *tail, *x;
- int in_name = 0;
- int in_email = 0;
- int in_comment = 0;
- gboolean anything;
- const gchar *name = NULL;
- const gchar *email = NULL;
- const gchar *comment = NULL;
-
- x = tail = src = g_strdup (user_id);
-
- while (*src) {
- if (in_email) {
- /* Not legal but anyway. */
- if (*src == '<')
- in_email++;
- else if (*src == '>') {
- if (!--in_email && !email) {
- email = tail;
- *src = 0;
- tail = src + 1;
- }
- }
- } else if (in_comment) {
- if (*src == '(')
- in_comment++;
- else if (*src == ')') {
- if (!--in_comment && !comment) {
- comment = tail;
- *src = 0;
- tail = src + 1;
- }
- }
- } else if (*src == '<') {
- if (in_name) {
- if (!name) {
- name = tail;
- *src = 0;
- tail = src + 1;
- }
- in_name = 0;
- } else
- tail = src + 1;
-
- in_email = 1;
- } else if (*src == '(') {
- if (in_name) {
- if (!name) {
- name = tail;
- *src = 0;
- tail = src + 1;
- }
- in_name = 0;
- }
- in_comment = 1;
- } else if (!in_name && *src != ' ' && *src != '\t') {
- in_name = 1;
- }
- src++;
- }
-
- if (in_name) {
- if (!name) {
- name = tail;
- *src = 0;
- tail = src + 1;
- }
- }
-
- anything = FALSE;
-
- if (rname) {
- *rname = g_strdup (name);
- if (name) {
- g_strstrip (*rname);
- anything = TRUE;
- }
- }
-
- if (remail) {
- *remail = g_strdup (email);
- if (email) {
- g_strstrip (*remail);
- anything = TRUE;
- }
- }
-
- if (rcomment) {
- *rcomment = g_strdup (comment);
- if (comment) {
- g_strstrip (*rcomment);
- anything = TRUE;
- }
- }
-
- g_free (x);
- return anything;
-}
-
-const gchar *
-_gcr_gnupg_records_get_keyid (GPtrArray *records)
-{
- GcrRecord *record;
-
- record = _gcr_records_find (records, GCR_RECORD_SCHEMA_PUB);
- if (record != NULL)
- return _gcr_record_get_raw (record, GCR_RECORD_KEY_KEYID);
- record = _gcr_records_find (records, GCR_RECORD_SCHEMA_SEC);
- if (record != NULL)
- return _gcr_record_get_raw (record, GCR_RECORD_KEY_KEYID);
- return NULL;
-}
-
-const gchar *
-_gcr_gnupg_records_get_short_keyid (GPtrArray *records)
-{
- const gchar *keyid;
- gsize length;
-
- keyid = _gcr_gnupg_records_get_keyid (records);
- if (keyid == NULL)
- return NULL;
-
- length = strlen (keyid);
- if (length > 8)
- keyid += (length - 8);
-
- return keyid;
-}
-
-gchar *
-_gcr_gnupg_records_get_user_id (GPtrArray *records)
-{
- GcrRecord *record;
-
- record = _gcr_records_find (records, GCR_RECORD_SCHEMA_UID);
- if (record != NULL)
- return _gcr_record_get_string (record, GCR_RECORD_UID_USERID);
- return NULL;
-}
-
-const gchar *
-_gcr_gnupg_records_get_fingerprint (GPtrArray *records)
-{
- GcrRecord *record;
-
- record = _gcr_records_find (records, GCR_RECORD_SCHEMA_FPR);
- if (record != NULL)
- return _gcr_record_get_raw (record, GCR_RECORD_FPR_FINGERPRINT);
- return NULL;
-}
-
-#define TYPE_IMAGE 0x01
-#define IMAGE_HEADER_LEN 0x10
-#define IMAGE_JPEG_SIG "\x10\x00\x01\x01"
-#define IMAGE_JPEG_SIG_LEN 4
-
-static void
-add_emblem_to_icon (GIcon **icon,
- const gchar *emblem_name)
-{
- GIcon *emblem_icon;
- GIcon *result;
- GEmblem *emblem;
-
- emblem_icon = g_themed_icon_new (emblem_name);
- emblem = g_emblem_new_with_origin (emblem_icon, G_EMBLEM_ORIGIN_LIVEMETADATA);
- result = g_emblemed_icon_new (*icon, emblem);
- g_object_unref (*icon);
- *icon = result;
- g_object_unref (emblem);
- g_object_unref (emblem_icon);
-}
-
-GIcon *
-_gcr_gnupg_records_get_icon (GPtrArray *records)
-{
- GcrRecord *record;
- gchar validity;
- guchar *data;
- gsize n_data;
- guint type;
- GIcon *icon;
- guint i;
-
- for (i = 0; i < records->len; i++) {
- record = records->pdata[i];
- if (GCR_RECORD_SCHEMA_XA1 != _gcr_record_get_schema (record))
- continue;
- if (!_gcr_record_get_uint (record, GCR_RECORD_XA1_TYPE, &type))
- continue;
- if (type != TYPE_IMAGE)
- continue;
-
- data = _gcr_record_get_base64 (record, GCR_RECORD_XA1_DATA, &n_data);
- g_return_val_if_fail (data != NULL, NULL);
-
- /* Header is 16 bytes long */
- if (n_data <= IMAGE_HEADER_LEN) {
- g_free (data);
- continue;
- }
-
- /* These are the header bytes. See gnupg doc/DETAILS */
- g_assert (IMAGE_JPEG_SIG_LEN < IMAGE_HEADER_LEN);
- if (memcmp (data, IMAGE_JPEG_SIG, IMAGE_JPEG_SIG_LEN) != 0) {
- g_free (data);
- continue;
- }
-
- icon = G_ICON (_gcr_memory_icon_new_full ("image/jpeg", data,
- n_data, IMAGE_HEADER_LEN,
- g_free));
-
- validity = _gcr_record_get_char (record, GCR_RECORD_XA1_TRUST);
- if (validity != 0 && validity != 'm' && validity != 'f' && validity != 'u')
- add_emblem_to_icon (&icon, "dialog-question");
-
- /* We have a valid header */
- return icon;
- }
-
- if (_gcr_records_find (records, GCR_RECORD_SCHEMA_SEC))
- return g_themed_icon_new ("gcr-key-pair");
- else
- return g_themed_icon_new ("gcr-key");
-
- return NULL;
-}
diff --git a/gcr/gcr-gnupg-records.h b/gcr/gcr-gnupg-records.h
deleted file mode 100644
index 4a61ff97..00000000
--- a/gcr/gcr-gnupg-records.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef GCR_GNUPG_RECORDS_H
-#define GCR_GNUPG_RECORDS_H
-
-#include <gio/gio.h>
-
-#include "gcr-record.h"
-
-G_BEGIN_DECLS
-
-const gchar * _gcr_gnupg_records_get_keyid (GPtrArray *records);
-
-const gchar * _gcr_gnupg_records_get_short_keyid (GPtrArray *records);
-
-const gchar * _gcr_gnupg_records_get_fingerprint (GPtrArray *records);
-
-gchar * _gcr_gnupg_records_get_user_id (GPtrArray *records);
-
-gboolean _gcr_gnupg_records_parse_user_id (const gchar *user_id,
- gchar **name,
- gchar **email,
- gchar **comment);
-
-GIcon * _gcr_gnupg_records_get_icon (GPtrArray *records);
-
-G_END_DECLS
-
-#endif /* __GCR_GNUPG_RECORD_H__ */
diff --git a/gcr/gcr-gnupg-renderer.c b/gcr/gcr-gnupg-renderer.c
deleted file mode 100644
index 663e32c9..00000000
--- a/gcr/gcr-gnupg-renderer.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-display-view.h"
-#include "gcr-icons.h"
-#include "gcr-gnupg-records.h"
-#include "gcr-gnupg-renderer.h"
-#include "gcr-openpgp.h"
-#include "gcr-simple-certificate.h"
-#include "gcr-renderer.h"
-#include "gcr-types.h"
-
-#include "gck/gck.h"
-
-#include "egg/egg-hex.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-#include <stdlib.h>
-
-enum {
- PROP_0,
- PROP_RECORDS,
- PROP_LABEL,
- PROP_ATTRIBUTES
-};
-
-struct _GcrGnupgRendererPrivate {
- GPtrArray *records;
- GckAttributes *attrs;
- gchar *label;
-};
-
-static void _gcr_gnupg_renderer_iface_init (GcrRendererIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrGnupgRenderer, _gcr_gnupg_renderer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, _gcr_gnupg_renderer_iface_init);
-);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gchar *
-calculate_label (GcrGnupgRenderer *self)
-{
- gchar *userid;
- gchar *label;
-
- if (self->pv->attrs) {
- if (gck_attributes_find_string (self->pv->attrs, CKA_LABEL, &label))
- return label;
- }
-
- userid = _gcr_gnupg_records_get_user_id (self->pv->records);
- if (userid != NULL) {
- if (!_gcr_gnupg_records_parse_user_id (userid, &label, NULL, NULL))
- label = NULL;
- }
-
- if (label != NULL)
- return label;
-
- if (self->pv->label)
- return g_strdup (self->pv->label);
-
- return g_strdup (_("PGP Key"));
-}
-
-static void
-_gcr_gnupg_renderer_init (GcrGnupgRenderer *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_RENDERER,
- GcrGnupgRendererPrivate));
-}
-
-static void
-_gcr_gnupg_renderer_finalize (GObject *obj)
-{
- GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
-
- gck_attributes_unref (self->pv->attrs);
- g_free (self->pv->label);
- if (self->pv->records)
- g_ptr_array_unref (self->pv->records);
-
- G_OBJECT_CLASS (_gcr_gnupg_renderer_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_gnupg_renderer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_RECORDS:
- _gcr_gnupg_renderer_set_records (self, g_value_get_boxed (value));
- break;
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- case PROP_ATTRIBUTES:
- _gcr_gnupg_renderer_set_attributes (self, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_renderer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_RECORDS:
- g_value_set_object (value, self->pv->records);
- break;
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->attrs);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_gnupg_renderer_class_init (GcrGnupgRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- _gcr_gnupg_renderer_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrGnupgRendererPrivate));
-
- gobject_class->finalize = _gcr_gnupg_renderer_finalize;
- gobject_class->set_property = _gcr_gnupg_renderer_set_property;
- gobject_class->get_property = _gcr_gnupg_renderer_get_property;
-
- g_object_class_install_property (gobject_class, PROP_RECORDS,
- g_param_spec_boxed ("records", "Records", "Gnupg records to display",
- G_TYPE_PTR_ARRAY, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Certificate Label",
- "", G_PARAM_READWRITE));
-
- /* Register this as a renderer which can be loaded */
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
- gcr_renderer_register (GCR_TYPE_GNUPG_RENDERER, registered);
- gck_attributes_unref (registered);
-}
-
-static const gchar *
-name_for_algo (guint algo)
-{
- switch (algo)
- {
- case GCR_OPENPGP_ALGO_RSA:
- case GCR_OPENPGP_ALGO_RSA_E:
- case GCR_OPENPGP_ALGO_RSA_S:
- return _("RSA");
- case GCR_OPENPGP_ALGO_ELG_E:
- return _("Elgamal");
- case GCR_OPENPGP_ALGO_DSA:
- return _("DSA");
- default:
- return NULL;
- }
-}
-
-static const gchar *
-capability_for_code (gchar code)
-{
- switch (code) {
- case 'e': case 'E':
- return _("Encrypt");
- case 's': case 'S':
- return _("Sign");
- case 'c': case 'C':
- return _("Certify");
- case 'a': case 'A':
- return _("Authenticate");
- case 'D':
- return _("Disabled");
- default:
- return NULL;
- }
-}
-
-static gchar *
-capabilities_for_codes (const gchar *codes)
-{
- const gchar *cap;
- GString *result;
- guint i;
-
- result = g_string_new ("");
- for (i = 0; codes[i] != 0; i++) {
- if (result->len)
- g_string_append_unichar (result, GCR_DISPLAY_VIEW_LINE_BREAK);
- cap = capability_for_code (codes[i]);
- if (cap != NULL)
- g_string_append (result, cap);
- else
- g_string_append_c (result, codes[i]);
- }
- return g_string_free (result, FALSE);
-}
-
-static const gchar *
-status_for_code (gchar code)
-{
- switch (code) {
- case 'o':
- return _("Unknown");
- case 'i':
- return _("Invalid");
- case 'd':
- return _("Disabled");
- case 'r':
- return _("Revoked");
- case 'e':
- return _("Expired");
- case 'q': case '-':
- return _("Undefined trust");
- case 'n':
- return _("Distrusted");
- case 'm':
- return _("Marginally trusted");
- case 'f':
- return _("Fully trusted");
- case 'u':
- return _("Ultimately trusted");
- default:
- return NULL;
- }
-}
-
-static const gchar *
-message_for_code (gchar code,
- GtkMessageType *message_type)
-{
- *message_type = GTK_MESSAGE_OTHER;
- switch (code) {
- case 'o':
- *message_type = GTK_MESSAGE_QUESTION;
- return _("The information in this key has not yet been verified");
- case 'i':
- *message_type = GTK_MESSAGE_ERROR;
- return _("This key is invalid");
- case 'd':
- *message_type = GTK_MESSAGE_WARNING;
- return _("This key has been disabled");
- case 'r':
- *message_type = GTK_MESSAGE_ERROR;
- return _("This key has been revoked");
- case 'e':
- *message_type = GTK_MESSAGE_ERROR;
- return _("This key has expired");
- case 'q': case '-':
- return NULL;
- case 'n':
- *message_type = GTK_MESSAGE_WARNING;
- return _("This key is distrusted");
- case 'm':
- *message_type = GTK_MESSAGE_OTHER;
- return _("This key is marginally trusted");
- case 'f':
- *message_type = GTK_MESSAGE_OTHER;
- return _("This key is fully trusted");
- case 'u':
- *message_type = GTK_MESSAGE_OTHER;
- return _("This key is ultimately trusted");
- default:
- return NULL;
- }
-}
-
-static void
-append_key_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record,
- const gchar *title)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- const gchar *value;
- gchar *display;
- GDateTime *date;
- gchar code;
- guint algo;
- guint bits;
-
- _gcr_display_view_append_heading (view, renderer, title);
-
- /* Key ID */
- value = _gcr_record_get_raw (record, GCR_RECORD_KEY_KEYID);
- if (value != NULL)
- _gcr_display_view_append_value (view, renderer, _("Key ID"), value, TRUE);
-
- /* Algorithm */
- if (_gcr_record_get_uint (record, GCR_RECORD_KEY_ALGO, &algo)) {
- display = NULL;
- value = name_for_algo (algo);
- if (value == NULL)
- value = display = g_strdup_printf ("%u", algo);
- _gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
- g_free (display);
- }
-
- /* Key Size */
- if (_gcr_record_get_uint (record, GCR_RECORD_KEY_BITS, &bits)) {
- display = g_strdup_printf ("%u", bits);
- _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
- g_free (display);
- }
-
- /* Created */
- date = _gcr_record_get_date (record, GCR_RECORD_KEY_TIMESTAMP);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-
- /* Expiry */
- date = _gcr_record_get_date (record, GCR_RECORD_KEY_EXPIRY);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-
- /* Capabilities */
- value = _gcr_record_get_raw (record, GCR_RECORD_PUB_CAPS);
- if (value != NULL) {
- display = capabilities_for_codes (value);
- _gcr_display_view_append_value (view, renderer, _("Capabilities"), display, FALSE);
- g_free (display);
- }
-
- /* Owner Trust */
- code = _gcr_record_get_char (record, GCR_RECORD_KEY_OWNERTRUST);
- if (code != 0) {
- display = NULL;
- value = status_for_code (code);
- if (value == NULL) {
- value = display = g_new0 (gchar, 2);
- display[0] = code;
- }
- _gcr_display_view_append_value (view, renderer, _("Owner trust"), value, FALSE);
- g_free (display);
- }
-}
-
-static void
-append_uid_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- gchar *userid;
- gchar *name;
- gchar *comment;
- gchar *email;
- GDateTime *date;
- gchar *display;
-
- _gcr_display_view_append_heading (view, renderer, _("User ID"));
-
- userid = _gcr_record_get_string (record, GCR_RECORD_UID_USERID);
- if (userid == NULL) {
- _gcr_display_view_append_value (view, renderer, _("Value"), _("Unknown"), FALSE);
- return;
- }
-
- if (_gcr_gnupg_records_parse_user_id (userid, &name, &email, &comment)) {
- if (name != NULL)
- _gcr_display_view_append_value (view, renderer, _("Name"), name, FALSE);
- g_free (name);
- if (email != NULL)
- _gcr_display_view_append_value (view, renderer, _("Email"), email, FALSE);
- g_free (email);
- if (comment != NULL)
- _gcr_display_view_append_value (view, renderer, _("Comment"), comment, FALSE);
- g_free (comment);
-
- /* Unparseable user id */
- } else {
- _gcr_display_view_append_value (view, renderer, _("Value"), userid, FALSE);
- }
-
- /* Created */
- date = _gcr_record_get_date (record, GCR_RECORD_UID_TIMESTAMP);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-
- /* Expiry */
- date = _gcr_record_get_date (record, GCR_RECORD_UID_EXPIRY);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-
- g_free (userid);
-}
-
-static void
-append_uat_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- gchar **parts;
- gchar *display;
- const gchar *value;
- GDateTime *date;
-
- _gcr_display_view_append_heading (view, renderer, _("User Attribute"));
-
- /* Size */
- value = _gcr_record_get_raw (record, GCR_RECORD_UAT_COUNT_SIZE);
- if (value != NULL) {
- parts = g_strsplit (value, " ", 2);
- if (parts && parts[0] && parts[1])
- _gcr_display_view_append_value (view, renderer, _("Size"), parts[1], FALSE);
- g_strfreev (parts);
- }
-
- /* Created */
- date = _gcr_record_get_date (record, GCR_RECORD_KEY_TIMESTAMP);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-
- /* Expiry */
- date = _gcr_record_get_date (record, GCR_RECORD_KEY_EXPIRY);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
- g_free (display);
- g_date_time_unref (date);
- }
-}
-
-static const gchar *
-signature_klass_string (const gchar *klass)
-{
- char *end;
- guint val;
-
- val = strtoul (klass, &end, 16);
- if (end != klass + 2)
- return NULL;
-
- switch (val) {
- case 0x00:
- return _("Signature of a binary document");
- case 0x01:
- return _("Signature of a canonical text document");
- case 0x02:
- return _("Standalone signature");
- case 0x10:
- return _("Generic certification of key");
- case 0x11:
- return _("Persona certification of key");
- case 0x12:
- return _("Casual certification of key");
- case 0x13:
- return _("Positive certification of key");
- case 0x18:
- return _("Subkey binding signature");
- case 0x19:
- return _("Primary key binding signature");
- case 0x1F:
- return _("Signature directly on key");
- case 0x20:
- return _("Key revocation signature");
- case 0x28:
- return _("Subkey revocation signature");
- case 0x30:
- return _("Certification revocation signature");
- case 0x40:
- return _("Timestamp signature");
- case 0x50:
- return _("Third-party confirmation signature");
- default:
- return NULL;
- }
-}
-
-static void
-append_sig_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record,
- const gchar *keyid)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- const gchar *sigid;
- gchar *display;
- const gchar *value;
- const gchar *klass;
- guint algo;
-
- /* Hide self-signatures. There's so many of them */
- sigid = _gcr_record_get_raw (record, GCR_RECORD_SIG_KEYID);
- if (sigid && keyid && g_str_equal (sigid, keyid))
- return;
-
- _gcr_display_view_append_heading (view, renderer, _("Signature"));
-
- /* Key ID */
- if (sigid != NULL)
- _gcr_display_view_append_value (view, renderer, _("Key ID"), sigid, TRUE);
-
- /* Algorithm */
- if (_gcr_record_get_uint (record, GCR_RECORD_SIG_ALGO, &algo)) {
- display = NULL;
- value = name_for_algo (algo);
- if (value == NULL)
- value = display = g_strdup_printf ("%u", algo);
- _gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
- g_free (display);
- }
-
- /* User ID */
- display = _gcr_record_get_string (record, GCR_RECORD_SIG_USERID);
- if (display != NULL)
- _gcr_display_view_append_value (view, renderer, _("User ID"), display, FALSE);
- g_free (display);
-
- /* Signature class */
- klass = _gcr_record_get_raw (record, GCR_RECORD_SIG_CLASS);
- if (klass != NULL) {
- value = NULL;
- if (strlen (klass) >= 2) {
- value = signature_klass_string (klass);
- if (value != NULL) {
- _gcr_display_view_append_value (view, renderer, _("Class"), value, FALSE);
- if (klass[2] == 'l')
- _gcr_display_view_append_value (view, renderer, _("Type"), _("Local only"), FALSE);
- else if (klass[2] == 'x')
- _gcr_display_view_append_value (view, renderer, _("Type"), _("Exportable"), FALSE);
- }
- }
- if (value == NULL)
- _gcr_display_view_append_value (view, renderer, _("Class"), klass, FALSE);
- }
-}
-
-static void
-append_rvk_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- const gchar *value;
- gchar *display;
- guint algo;
-
- _gcr_display_view_append_heading (view, renderer, _("Revocation Key"));
-
- /* Algorithm */
- if (_gcr_record_get_uint (record, GCR_RECORD_RVK_ALGO, &algo)) {
- display = NULL;
- value = name_for_algo (algo);
- if (value == NULL)
- value = display = g_strdup_printf ("%u", algo);
- _gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
- g_free (display);
- }
-
- value = _gcr_record_get_raw (record, GCR_RECORD_RVK_FINGERPRINT);
- if (value != NULL)
- _gcr_display_view_append_value (view, renderer, _("Fingerprint"), value, TRUE);
-}
-
-static void
-append_fpr_record (GcrGnupgRenderer *self,
- GcrDisplayView *view,
- GcrRecord *record,
- GQuark last_schema)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- const gchar *value;
- gpointer raw;
- gsize n_raw;
-
- if (last_schema != GCR_RECORD_SCHEMA_PUB &&
- last_schema != GCR_RECORD_SCHEMA_SUB &&
- last_schema != GCR_RECORD_SCHEMA_SEC &&
- last_schema != GCR_RECORD_SCHEMA_SSB)
- return;
-
- value = _gcr_record_get_raw (record, GCR_RECORD_FPR_FINGERPRINT);
- if (value != NULL) {
- raw = egg_hex_decode (value, -1, &n_raw);
- if (raw != NULL)
- _gcr_display_view_append_hex (view, renderer, _("Fingerprint"), raw, n_raw);
- else
- _gcr_display_view_append_value (view, renderer, _("Fingerprint"), value, TRUE);
- g_free (raw);
- }
-}
-
-static void
-_gcr_gnupg_renderer_render (GcrRenderer *renderer,
- GcrViewer *viewer)
-{
- GtkMessageType message_type;
- GcrGnupgRenderer *self;
- GcrDisplayView *view;
- GDateTime *date;
- const gchar *value;
- gchar *display;
- gchar *userid;
- gchar *email;
- gchar *comment;
- GIcon *icon;
- GQuark schema;
- GQuark last_schema;
- gchar code;
- guint i;
-
- self = GCR_GNUPG_RENDERER (renderer);
-
- if (GCR_IS_DISPLAY_VIEW (viewer)) {
- view = GCR_DISPLAY_VIEW (viewer);
-
- } else {
- g_warning ("GcrGnupgRenderer only works with internal specific "
- "GcrViewer returned by gcr_viewer_new().");
- return;
- }
-
- _gcr_display_view_begin (view, renderer);
-
- if (self->pv->records == NULL || self->pv->records->len == 0) {
- _gcr_display_view_end (view, renderer);
- return;
- }
-
- icon = _gcr_gnupg_records_get_icon (self->pv->records);
- _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
- g_object_unref (icon);
-
- display = calculate_label (self);
- _gcr_display_view_append_title (view, renderer, display);
- g_free (display);
-
- userid = _gcr_gnupg_records_get_user_id (self->pv->records);
- if (userid != NULL) {
- if (_gcr_gnupg_records_parse_user_id (userid, NULL, &email, &comment)) {
- if (email != NULL)
- _gcr_display_view_append_content (view, renderer, _("Email"), email);
- g_free (email);
- if (comment != NULL)
- _gcr_display_view_append_content (view, renderer, _("Comment"), comment);
- g_free (comment);
- }
- g_free (userid);
- }
-
- code = _gcr_record_get_char (self->pv->records->pdata[0], GCR_RECORD_TRUST);
- if (code != 'e') {
- date = _gcr_record_get_date (self->pv->records->pdata[0], GCR_RECORD_KEY_EXPIRY);
- if (date != NULL) {
- display = g_date_time_format (date, "%x");
- _gcr_display_view_append_content (view, renderer, _("Expires"), display);
- g_date_time_unref (date);
- g_free (display);
- }
- }
-
- /* The warning or status */
- value = message_for_code (code, &message_type);
- if (value != NULL)
- _gcr_display_view_append_message (view, renderer, message_type, value);
-
- _gcr_display_view_start_details (view, renderer);
-
- value = _gcr_gnupg_records_get_keyid (self->pv->records);
- last_schema = 0;
-
- for (i = 0; i < self->pv->records->len; i++) {
- schema = _gcr_record_get_schema (self->pv->records->pdata[i]);
- if (schema == GCR_RECORD_SCHEMA_PUB)
- append_key_record (self, view, self->pv->records->pdata[i], _("Public Key"));
- else if (schema == GCR_RECORD_SCHEMA_SUB)
- append_key_record (self, view, self->pv->records->pdata[i], _("Public Subkey"));
- else if (schema == GCR_RECORD_SCHEMA_SEC)
- append_key_record (self, view, self->pv->records->pdata[i], _("Secret Key"));
- else if (schema == GCR_RECORD_SCHEMA_SSB)
- append_key_record (self, view, self->pv->records->pdata[i], _("Secret Subkey"));
- else if (schema == GCR_RECORD_SCHEMA_UID)
- append_uid_record (self, view, self->pv->records->pdata[i]);
- else if (schema == GCR_RECORD_SCHEMA_UAT)
- append_uat_record (self, view, self->pv->records->pdata[i]);
- else if (schema == GCR_RECORD_SCHEMA_SIG)
- append_sig_record (self, view, self->pv->records->pdata[i], value);
- else if (schema == GCR_RECORD_SCHEMA_RVK)
- append_rvk_record (self, view, self->pv->records->pdata[i]);
- else if (schema == GCR_RECORD_SCHEMA_FPR)
- append_fpr_record (self, view, self->pv->records->pdata[i], last_schema);
- last_schema = schema;
- }
-
- _gcr_display_view_end (view, renderer);
-}
-
-static void
-_gcr_gnupg_renderer_iface_init (GcrRendererIface *iface)
-{
- iface->render_view = _gcr_gnupg_renderer_render;
-}
-
-GcrGnupgRenderer *
-_gcr_gnupg_renderer_new (GPtrArray *records)
-{
- g_return_val_if_fail (records != NULL, NULL);
-
- return g_object_new (GCR_TYPE_GNUPG_RENDERER,
- "records", records,
- NULL);
-}
-
-GcrGnupgRenderer *
-_gcr_gnupg_renderer_new_for_attributes (const gchar *label,
- GckAttributes *attrs)
-{
- g_return_val_if_fail (attrs != NULL, NULL);
-
- return g_object_new (GCR_TYPE_GNUPG_RENDERER,
- "label", label,
- "attributes", attrs,
- NULL);
-}
-
-GPtrArray *
-_gcr_gnupg_renderer_get_records (GcrGnupgRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_RENDERER (self), NULL);
- return self->pv->records;
-}
-
-void
-_gcr_gnupg_renderer_set_records (GcrGnupgRenderer *self,
- GPtrArray *records)
-{
- g_return_if_fail (GCR_IS_GNUPG_RENDERER (self));
-
- if (records)
- g_ptr_array_ref (records);
- if (self->pv->records)
- g_ptr_array_unref (self->pv->records);
- self->pv->records = records;
-
- if (self->pv->attrs) {
- gck_attributes_unref (self->pv->attrs);
- self->pv->attrs = NULL;
- g_object_notify (G_OBJECT (self), "attributes");
- }
-
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- g_object_notify (G_OBJECT (self), "records");
-}
-
-GckAttributes*
-_gcr_gnupg_renderer_get_attributes (GcrGnupgRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_GNUPG_RENDERER (self), NULL);
- return self->pv->attrs;
-}
-
-void
-_gcr_gnupg_renderer_set_attributes (GcrGnupgRenderer *self,
- GckAttributes *attrs)
-{
- GckAttribute *attr;
- GPtrArray *records;
-
- g_return_if_fail (GCR_IS_GNUPG_RENDERER (self));
-
- attr = gck_attributes_find (attrs, CKA_VALUE);
- g_return_if_fail (attr != NULL);
- records = _gcr_records_parse_colons (attr->value, attr->length);
- g_return_if_fail (records != NULL);
-
- if (attrs)
- gck_attributes_ref (attrs);
- gck_attributes_unref (self->pv->attrs);
- self->pv->attrs = attrs;
-
- if (self->pv->records)
- g_ptr_array_unref (self->pv->records);
- self->pv->records = records;
- g_object_notify (G_OBJECT (self), "records");
-
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- g_object_notify (G_OBJECT (self), "attributes");
-
-}
diff --git a/gcr/gcr-gnupg-renderer.h b/gcr/gcr-gnupg-renderer.h
deleted file mode 100644
index 0d09c313..00000000
--- a/gcr/gcr-gnupg-renderer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_GNUPG_RENDERER_H__
-#define __GCR_GNUPG_RENDERER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-record.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_GNUPG_RENDERER (_gcr_gnupg_renderer_get_type ())
-#define GCR_GNUPG_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_GNUPG_RENDERER, GcrGnupgRenderer))
-#define GCR_GNUPG_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_GNUPG_RENDERER, GcrGnupgRendererClass))
-#define GCR_IS_GNUPG_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_GNUPG_RENDERER))
-#define GCR_IS_GNUPG_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_GNUPG_RENDERER))
-#define GCR_GNUPG_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_GNUPG_RENDERER, GcrGnupgRendererClass))
-
-typedef struct _GcrGnupgRenderer GcrGnupgRenderer;
-typedef struct _GcrGnupgRendererClass GcrGnupgRendererClass;
-typedef struct _GcrGnupgRendererPrivate GcrGnupgRendererPrivate;
-
-struct _GcrGnupgRenderer {
- GObject parent;
-
- /*< private >*/
- GcrGnupgRendererPrivate *pv;
-};
-
-struct _GcrGnupgRendererClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_gnupg_renderer_get_type (void);
-
-GcrGnupgRenderer * _gcr_gnupg_renderer_new (GPtrArray *records);
-
-GcrGnupgRenderer * _gcr_gnupg_renderer_new_for_attributes (const gchar *label,
- GckAttributes *attrs);
-
-GPtrArray * _gcr_gnupg_renderer_get_records (GcrGnupgRenderer *self);
-
-void _gcr_gnupg_renderer_set_records (GcrGnupgRenderer *self,
- GPtrArray *records);
-
-GckAttributes * _gcr_gnupg_renderer_get_attributes (GcrGnupgRenderer *self);
-
-void _gcr_gnupg_renderer_set_attributes (GcrGnupgRenderer *self,
- GckAttributes *attrs);
-
-G_END_DECLS
-
-#endif /* __GCR_GNUPG_RENDERER_H__ */
diff --git a/gcr/gcr-gnupg-util.c b/gcr/gcr-gnupg-util.c
deleted file mode 100644
index b85836b5..00000000
--- a/gcr/gcr-gnupg-util.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "egg/egg-hex.h"
-
-#include "gcr-gnupg-util.h"
-
-#include <gcrypt.h>
-
-/**
- * _gcr_gnupg_build_xa1_record:
- * @meta: Status metadata record about the attribute data.
- * @attribute: Pointer to attribute data.
- * @n_attribute: Length of attribute data.
- *
- * Build a record for attribute data. We use this records to convert attribute
- * data into something we can keep with an array of GcrRecord.
- *
- * Returns: (transfer full): The newly allocated record.
- */
-GcrRecord*
-_gcr_gnupg_build_xa1_record (GcrRecord *meta, gpointer attribute,
- gsize n_attribute)
-{
- gchar hash[20];
- gchar *hex;
- gchar status = 0;
- GcrRecord *record;
- guint flags, type;
- const gchar *created, *expiry;
-
- g_return_val_if_fail (meta, NULL);
-
- record = _gcr_record_new (GCR_RECORD_SCHEMA_XA1, GCR_RECORD_XA1_MAX, ':');
-
- gcry_md_hash_buffer (GCRY_MD_RMD160, hash, attribute, n_attribute);
- hex = egg_hex_encode_full (hash, sizeof (hash), TRUE, 0, 1);
- _gcr_record_take_raw (record, GCR_RECORD_XA1_FINGERPRINT, hex);
-
- if (!_gcr_record_get_uint (meta, GCR_RECORD_ATTRIBUTE_FLAGS, &flags))
- flags = 0;
-
- if (_gcr_record_get_uint (meta, GCR_RECORD_ATTRIBUTE_TYPE, &type))
- _gcr_record_set_uint (record, GCR_RECORD_XA1_TYPE, type);
-
- created = _gcr_record_get_raw (meta, GCR_RECORD_ATTRIBUTE_TIMESTAMP);
- if (created == NULL)
- _gcr_record_set_raw (record, GCR_RECORD_XA1_TIMESTAMP, created);
-
- expiry = _gcr_record_get_raw (meta, GCR_RECORD_ATTRIBUTE_EXPIRY);
- if (expiry != NULL)
- _gcr_record_set_raw (record, GCR_RECORD_XA1_EXPIRY, expiry);
-
- /* These values are from gnupg doc/DETAILS */
- if (flags & 0x02)
- status = 'r';
- else if (flags & 0x04)
- status = 'e';
- else if (flags & 0x01)
- status = 'P';
- if (status != 0)
- _gcr_record_set_char (record, GCR_RECORD_XA1_TRUST, status);
-
- _gcr_record_set_base64 (record, GCR_RECORD_XA1_DATA, attribute, n_attribute);
-
- return record;
-}
diff --git a/gcr/gcr-gnupg-util.h b/gcr/gcr-gnupg-util.h
deleted file mode 100644
index 5910bfbd..00000000
--- a/gcr/gcr-gnupg-util.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_GNUPG_UTIL_H
-#define GCR_GNUPG_UTIL_H
-
-#include <glib.h>
-
-#include "gcr-record.h"
-
-G_BEGIN_DECLS
-
-GcrRecord* _gcr_gnupg_build_xa1_record (GcrRecord *meta,
- gpointer attribute,
- gsize n_attribute);
-
-G_END_DECLS
-
-#endif /* __GCR_GNUPG_KEY_H__ */
diff --git a/gcr/gcr-icons.c b/gcr/gcr-icons.c
deleted file mode 100644
index e375d009..00000000
--- a/gcr/gcr-icons.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-base.h"
-#include "gcr-icons.h"
-
-/**
- * gcr_icon_for_token:
- * @token_info: the token info
- *
- * Get an appropriate icon for the token
- *
- * Returns: (transfer full): the icon
- */
-GIcon *
-gcr_icon_for_token (GckTokenInfo *token_info)
-{
- GIcon *icon;
-
- g_return_val_if_fail (token_info != NULL, NULL);
-
- if (g_strcmp0 (token_info->manufacturer_id, "Gnome Keyring") == 0)
- icon = g_themed_icon_new (GCR_ICON_HOME_DIRECTORY);
-
- else if (g_strcmp0 (token_info->manufacturer_id, "Mozilla Foundation") == 0 &&
- g_strcmp0 (token_info->model, "NSS 3") == 0)
- icon = g_themed_icon_new (GCR_ICON_HOME_DIRECTORY);
-
- else
- icon = g_themed_icon_new (GCR_ICON_SMART_CARD);
-
- return icon;
-}
diff --git a/gcr/gcr-icons.h b/gcr/gcr-icons.h
deleted file mode 100644
index 7fb4f6c1..00000000
--- a/gcr/gcr-icons.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_ICONS_H__
-#define __GCR_ICONS_H__
-
-#include <gck/gck.h>
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GCR_ICON_CERTIFICATE "application-certificate"
-#define GCR_ICON_KEY "gcr-key"
-#define GCR_ICON_KEY_PAIR "gcr-key-pair"
-#define GCR_ICON_SMART_CARD "gcr-smart-card"
-#define GCR_ICON_HOME_DIRECTORY "user-home"
-
-GIcon * gcr_icon_for_token (GckTokenInfo *token_info);
-
-G_END_DECLS
-
-#endif /* __GCR_SMART_CARD_H__ */
diff --git a/gcr/gcr-import-button.c b/gcr/gcr-import-button.c
deleted file mode 100644
index b25f20cf..00000000
--- a/gcr/gcr-import-button.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-import-button.h"
-#include "gcr-internal.h"
-#include "gcr-marshal.h"
-#include "gcr-parser.h"
-#include "gcr-pkcs11-import-interaction.h"
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL
-};
-
-/**
- * SECTION:gcr-import-button
- * @title: GcrImportButton
- * @short_description: Button which imports parsed certificates and keys
- *
- * A button which imports keys and certificates. Shows a spinner when the
- * button is activated. When more than one importer is available shows
- * a drop down to select which to import to.
- */
-
-/**
- * GcrImportButton:
- *
- * Button which imports parsed certificates and keys.
- */
-
-/**
- * GcrImportButtonClass:
- * @parent_class: The parent class
- * @imported: Emitted when the import completes, or fails.
- *
- * Class for #GcrImportButton.
- */
-
-struct _GcrImportButtonPrivate {
- GList *queued;
- GList *importers;
- gboolean ready;
- gboolean created;
- gboolean importing;
- gchar *imported;
- GtkWidget *spinner;
- GtkWidget *arrow;
- GtkWidget *label;
- GCancellable *cancellable;
- GtkMenu *menu;
-};
-
-enum {
- IMPORTED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static GQuark QUARK_IMPORTER = 0;
-
-G_DEFINE_TYPE (GcrImportButton, gcr_import_button, GTK_TYPE_BUTTON);
-
-static void
-gcr_import_button_init (GcrImportButton *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_IMPORT_BUTTON, GcrImportButtonPrivate);
- self->pv->cancellable = g_cancellable_new ();
- self->pv->label = gtk_label_new ("");
-}
-
-static void
-update_import_button (GcrImportButton *self)
-{
- gchar *message;
- gchar *label;
-
- /* Initializing, set a spinner */
- if (self->pv->queued && !self->pv->ready) {
- gtk_widget_show (self->pv->spinner);
- gtk_spinner_start (GTK_SPINNER (self->pv->spinner));
- gtk_widget_hide (self->pv->arrow);
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Initializing..."));
-
- /* Importing, set a spinner */
- } else if (self->pv->importing) {
- gtk_widget_show (self->pv->spinner);
- gtk_spinner_start (GTK_SPINNER (self->pv->spinner));
- gtk_widget_hide (self->pv->arrow);
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Import is in progress..."));
-
- } else if (self->pv->imported) {
- gtk_widget_hide (self->pv->spinner);
- gtk_spinner_stop (GTK_SPINNER (self->pv->spinner));
- gtk_widget_hide (self->pv->arrow);
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- message = g_strdup_printf (_("Imported to: %s"), self->pv->imported);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), message);
- g_free (message);
-
- /* Not importing, but have importers */
- } else if (self->pv->importers) {
-
- gtk_widget_hide (self->pv->spinner);
- gtk_spinner_stop (GTK_SPINNER (self->pv->spinner));
- gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
-
- /* More than one importer */
- if (self->pv->importers->next) {
- gtk_widget_show (self->pv->arrow);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), NULL);
-
- /* Only one importer */
- } else {
- gtk_widget_hide (self->pv->arrow);
- g_object_get (self->pv->importers->data, "label", &label, NULL);
- message = g_strdup_printf (_("Import to: %s"), label);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), message);
- g_free (message);
- g_free (label);
- }
-
- /* No importers, none compatible */
- } else if (self->pv->created) {
- gtk_widget_hide (self->pv->spinner);
- gtk_spinner_stop (GTK_SPINNER (self->pv->spinner));
- gtk_widget_hide (self->pv->arrow);
-
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Cannot import because there are no compatible importers"));
-
- /* No importers yet added */
- } else {
- gtk_widget_hide (self->pv->spinner);
- gtk_spinner_stop (GTK_SPINNER (self->pv->spinner));
- gtk_widget_hide (self->pv->arrow);
-
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("No data to import"));
- }
-}
-
-static void
-on_library_pkcs11_ready (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
- GList *queued, *l;
-
- self->pv->ready = TRUE;
-
- /* Process the parsed items that have been seen */
- queued = self->pv->queued;
- self->pv->queued = NULL;
- for (l = queued; l != NULL; l = g_list_next (l))
- gcr_import_button_add_parsed (self, l->data);
- g_assert (self->pv->queued == NULL);
- g_list_free_full (queued, gcr_parsed_unref);
-}
-
-static void
-gcr_import_button_constructed (GObject *obj)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
- GtkWidget *grid;
-
- G_OBJECT_CLASS (gcr_import_button_parent_class)->constructed (obj);
-
- self->pv->spinner = gtk_spinner_new ();
- self->pv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- grid = gtk_grid_new ();
-
- gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_HORIZONTAL);
- gtk_container_add (GTK_CONTAINER (grid), self->pv->spinner);
- gtk_container_add (GTK_CONTAINER (grid), self->pv->label);
- gtk_container_add (GTK_CONTAINER (grid), self->pv->arrow);
- gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
- gtk_widget_set_hexpand (grid, TRUE);
- gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
-
- gtk_widget_show (self->pv->label);
- gtk_widget_show (grid);
-
- gtk_container_add (GTK_CONTAINER (self), grid);
-
- update_import_button (self);
-
- gcr_pkcs11_initialize_async (NULL, on_library_pkcs11_ready, g_object_ref (self));
-}
-
-static void
-gcr_import_button_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- gtk_label_set_label (GTK_LABEL (self->pv->label), g_value_get_string (value));
- g_object_notify (obj, "label");
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_import_button_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_set_string (value, gtk_label_get_label (GTK_LABEL (self->pv->label)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_import_button_dispose (GObject *obj)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
-
- gck_list_unref_free (self->pv->importers);
- self->pv->importers = NULL;
- g_cancellable_cancel (self->pv->cancellable);
- g_clear_object (&self->pv->menu);
-
- g_list_free_full (self->pv->queued, gcr_parsed_unref);
- self->pv->queued = NULL;
-
- G_OBJECT_CLASS (gcr_import_button_parent_class)->dispose (obj);
-}
-
-static void
-gcr_import_button_finalize (GObject *obj)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (obj);
-
- g_object_unref (self->pv->cancellable);
-
- G_OBJECT_CLASS (gcr_import_button_parent_class)->finalize (obj);
-}
-
-static void
-on_import_complete (GObject *importer,
- GAsyncResult *result,
- gpointer user_data)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
- GError *error = NULL;
-
- g_return_if_fail (self->pv->imported == NULL);
-
- self->pv->importing = FALSE;
-
- gcr_importer_import_finish (GCR_IMPORTER (importer), result, &error);
- if (error == NULL) {
- g_object_get (importer, "label", &self->pv->imported, NULL);
- gck_list_unref_free (self->pv->importers);
- self->pv->importers = NULL;
- }
-
- g_signal_emit (self, signals[IMPORTED], 0, importer, error);
- g_clear_error (&error);
-
- update_import_button (self);
-}
-
-static void
-begin_import (GcrImportButton *self,
- GcrImporter *importer)
-{
- GTlsInteraction *interaction;
- GtkWindow *window;
-
- g_return_if_fail (self->pv->importing == FALSE);
-
- self->pv->importing = TRUE;
- g_free (self->pv->imported);
- self->pv->imported = NULL;
-
- /* TODO: Hack. Need to figure out how to pair these up... */
- if (g_strcmp0 (G_OBJECT_TYPE_NAME (importer), "GcrPkcs11Importer") == 0) {
- window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
- interaction = _gcr_pkcs11_import_interaction_new (window);
- gcr_importer_set_interaction (importer, interaction);
- g_object_unref (interaction);
- }
-
- gcr_importer_import_async (importer,
- self->pv->cancellable,
- on_import_complete,
- g_object_ref (self));
-}
-
-static void
-on_importer_menu_activated (GtkMenuItem *menu_item,
- gpointer user_data)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
- GcrImporter *importer;
-
- importer = g_object_get_qdata (G_OBJECT (menu_item), QUARK_IMPORTER);
- g_return_if_fail (GCR_IMPORTER (importer));
- g_return_if_fail (self->pv->importing == FALSE);
-
- begin_import (self, importer);
- update_import_button (self);
-}
-
-static void
-update_importer_menu (GcrImportButton *self)
-{
- GtkWidget *menu_item;
- GtkWidget *image;
- GList *children, *l;
- GIcon *icon;
- gchar *label;
-
- if (!self->pv->menu) {
- self->pv->menu = GTK_MENU (gtk_menu_new ());
- g_object_ref_sink (self->pv->menu);
- }
-
- children = gtk_container_get_children (GTK_CONTAINER (self->pv->menu));
- for (l = children; l != NULL; l = g_list_next (l))
- gtk_container_remove (GTK_CONTAINER (self->pv->menu), l->data);
- g_list_free (children);
-
- for (l = self->pv->importers; l != NULL; l = g_list_next (l)) {
- g_object_get (l->data, "label", &label, "icon", &icon, NULL);
- menu_item = gtk_image_menu_item_new_with_label (label);
- g_signal_connect (menu_item, "activate", G_CALLBACK (on_importer_menu_activated), self);
- g_object_set_qdata (G_OBJECT (menu_item), QUARK_IMPORTER, l->data);
- image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
- gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
- gtk_widget_show (image);
- gtk_widget_show (menu_item);
- gtk_container_add (GTK_CONTAINER (self->pv->menu), menu_item);
- g_object_unref (icon);
- g_free (label);
- }
-}
-
-static void
-on_menu_position (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (user_data);
- GtkWidget *widget = GTK_WIDGET (self);
- GtkAllocation allocation;
- GtkRequisition menu_req;
- GdkRectangle monitor;
- GdkWindow *window;
- GtkWidget *toplevel;
- GdkScreen *screen;
- gint monitor_num;
- gint sx = 0;
- gint sy = 0;
-
- g_return_if_fail (x != NULL);
- g_return_if_fail (y != NULL);
- g_return_if_fail (push_in != NULL);
-
- gtk_widget_get_allocation (widget, &allocation);
-
- if (!gtk_widget_get_has_window (widget)) {
- sx += allocation.x;
- sy += allocation.y;
- }
-
- window = gtk_widget_get_window (widget);
- gdk_window_get_root_coords (window, sx, sy, &sx, &sy);
-
- gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &menu_req);
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- *x = sx;
- else
- *x = sx + allocation.width - menu_req.width;
- *y = sy;
-
- screen = gtk_widget_get_screen (widget);
- monitor_num = gdk_screen_get_monitor_at_window (screen, window);
- if (monitor_num < 0)
- monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
- if (*x < monitor.x)
- *x = monitor.x;
- else if (*x + menu_req.width > monitor.x + monitor.width)
- *x = monitor.x + monitor.width - menu_req.width;
-
- if (monitor.y + monitor.height - *y - allocation.height >= menu_req.height)
- *y += allocation.height;
- else if (*y - monitor.y >= menu_req.height)
- *y -= menu_req.height;
- else if (monitor.y + monitor.height - *y - allocation.height > *y - monitor.y)
- *y += allocation.height;
- else
- *y -= menu_req.height;
-
- gtk_menu_set_monitor (menu, monitor_num);
-
- toplevel = gtk_widget_get_parent (GTK_WIDGET (menu));
- if (GTK_IS_WINDOW (toplevel) && gtk_widget_get_visible (toplevel))
- gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
-
- *push_in = FALSE;
-}
-
-static void
-gcr_import_button_clicked (GtkButton *button)
-{
- GcrImportButton *self = GCR_IMPORT_BUTTON (button);
-
- g_return_if_fail (self->pv->importing == FALSE);
- g_return_if_fail (self->pv->importers != NULL);
-
- /* More than one importer, show the menu */
- if (self->pv->importers->next) {
- update_importer_menu (self);
- gtk_menu_popup (self->pv->menu, NULL, NULL, on_menu_position,
- self, 1, gtk_get_current_event_time ());
-
- /* Only one importer, import on click */
- } else {
- begin_import (self, self->pv->importers->data);
- }
-
- update_import_button (self);
-}
-
-static void
-gcr_import_button_class_init (GcrImportButtonClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
-
- gobject_class->constructed = gcr_import_button_constructed;
- gobject_class->dispose = gcr_import_button_dispose;
- gobject_class->finalize = gcr_import_button_finalize;
- gobject_class->get_property = gcr_import_button_get_property;
- gobject_class->set_property = gcr_import_button_set_property;
-
- button_class->clicked = gcr_import_button_clicked;
-
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
-
- /**
- * GcrImportButton::imported:
- * @self: the import button
- * @importer: the importer that was imported to
- * @error: if import was successful %NULL, or an error
- *
- * Signal emitted when an import completes or fails.
- */
- signals[IMPORTED] = g_signal_new ("imported", GCR_TYPE_IMPORT_BUTTON, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrImportButtonClass, imported),
- NULL, NULL, _gcr_marshal_VOID__OBJECT_BOXED,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_ERROR);
-
- QUARK_IMPORTER = g_quark_from_static_string ("gcr-import-button-importer");
-
- g_type_class_add_private (klass, sizeof (GcrImportButtonPrivate));
-}
-
-/**
- * gcr_import_button_new:
- * @label: (allow-none): label to display on the button
- *
- * Create a new #GcrImportButton.
- *
- * Returns: (transfer full): a newly created #GcrImportButton
- */
-GcrImportButton *
-gcr_import_button_new (const gchar *label)
-{
- return g_object_new (GCR_TYPE_IMPORT_BUTTON,
- "label", label,
- NULL);
-}
-
-/**
- * gcr_import_button_add_parsed:
- * @self: an import button
- * @parsed: a parsed item
- *
- * Queue an item to import via the button
- */
-void
-gcr_import_button_add_parsed (GcrImportButton *self,
- GcrParsed *parsed)
-{
- GList *importers;
-
- g_return_if_fail (GCR_IS_IMPORT_BUTTON (self));
- g_return_if_fail (parsed != NULL);
-
- if (!self->pv->ready) {
- self->pv->queued = g_list_prepend (self->pv->queued, gcr_parsed_ref (parsed));
- update_import_button (self);
- return;
- }
-
- g_free (self->pv->imported);
- self->pv->imported = NULL;
-
- if (self->pv->created) {
- importers = gcr_importer_queue_and_filter_for_parsed (self->pv->importers, parsed);
- } else {
- importers = gcr_importer_create_for_parsed (parsed);
- self->pv->created = TRUE;
- }
-
- gck_list_unref_free (self->pv->importers);
- self->pv->importers = importers;
-
- update_import_button (self);
-}
diff --git a/gcr/gcr-import-button.h b/gcr/gcr-import-button.h
deleted file mode 100644
index 6c839fcb..00000000
--- a/gcr/gcr-import-button.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_IMPORT_BUTTON_H__
-#define __GCR_IMPORT_BUTTON_H__
-
-#include "gcr.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_IMPORT_BUTTON (gcr_import_button_get_type ())
-#define GCR_IMPORT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORT_BUTTON, GcrImportButton))
-#define GCR_IMPORT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_IMPORT_BUTTON, GcrImportButtonClass))
-#define GCR_IS_IMPORT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORT_BUTTON))
-#define GCR_IS_IMPORT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_IMPORT_BUTTON))
-#define GCR_IMPORT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_IMPORT_BUTTON, GcrImportButtonClass))
-
-typedef struct _GcrImportButton GcrImportButton;
-typedef struct _GcrImportButtonClass GcrImportButtonClass;
-typedef struct _GcrImportButtonPrivate GcrImportButtonPrivate;
-
-struct _GcrImportButton {
- GtkButton parent;
-
- /*< private >*/
- GcrImportButtonPrivate *pv;
-};
-
-struct _GcrImportButtonClass {
- GtkButtonClass parent_class;
-
- void (*imported) (GcrImportButton *self,
- GcrImporter *importer,
- GError *error);
-};
-
-GType gcr_import_button_get_type (void) G_GNUC_CONST;
-
-GcrImportButton * gcr_import_button_new (const gchar *label);
-
-void gcr_import_button_add_parsed (GcrImportButton *self,
- GcrParsed *parsed);
-
-G_END_DECLS
-
-#endif /* __GCR_IMPORT_BUTTON_H__ */
diff --git a/gcr/gcr-import-interaction.c b/gcr/gcr-import-interaction.c
deleted file mode 100644
index 19d0bc01..00000000
--- a/gcr/gcr-import-interaction.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-import-interaction.h"
-
-/**
- * SECTION:gcr-importer
- * @title: GcrImporter
- * @short_description: Import certificates and keys
- *
- * An interface which allows importing of certificates and keys. Each
- * #GcrImporter is registered with a set of PKCS\#11 attributes to match
- * stuff that it can import.
- *
- * An importer gets passed a #GcrParser and accesses the currently parsed
- * item. To create a set of importers that can import the currently parsed
- * item in a #GcrParser, use gcr_importer_create_for_parsed(). The list of
- * importers returned has the parsed item queued for import.
- *
- * To queue additional items with a importer use gcr_importer_queue_for_parsed().
- * In addition you can try and queue an additional item with a set of importers
- * using the gcr_importer_queue_and_filter_for_parsed().
- *
- * To start the import use gcr_importer_import() or the async variants.
- */
-
-/**
- * GcrImporter:
- *
- * Imports certificates and keys
- */
-
-/**
- * GcrImporterIface:
- * @parent: parent interface
- * @create_for_parsed: implementation of gcr_importer_create_for_parsed(), required
- * @queue_for_parsed: implementation of gcr_importer_queue_for_parsed(), required
- * @import_sync: optional implemantionon of gcr_importer_import()
- * @import_async: implementation of gcr_importer_import_async(), required
- * @import_finish: implementation of gcr_importer_import_finish()
- *
- * Interface implemented for a #GcrImporter.
- */
-
-typedef GcrImportInteractionIface GcrImportInteractionInterface;
-
-G_DEFINE_INTERFACE (GcrImportInteraction, gcr_import_interaction, G_TYPE_TLS_INTERACTION);
-
-static void
-gcr_import_interaction_default_init (GcrImportInteractionIface *iface)
-{
- static volatile gsize initialized = 0;
-
- if (g_once_init_enter (&initialized)) {
- g_once_init_leave (&initialized, 1);
- }
-}
-
-/**
- * gcr_import_interaction_supplement_prep:
- * @interaction: the interaction
- * @attributes: attributes to supplement
- *
- * Prepare for supplementing the given attributes before import. This means
- * prompting the user for things like labels and the like. The attributes
- * will contain attributes for values that the importer needs, either empty
- * or prefilled with suggested values.
- *
- * This method does not prompt the user, but rather just prepares the
- * interaction that these are the attributes that are needed.
- */
-void
-gcr_import_interaction_supplement_prep (GcrImportInteraction *interaction,
- GckAttributes *attributes)
-{
- GcrImportInteractionIface *iface;
-
- g_return_if_fail (GCR_IS_IMPORT_INTERACTION (interaction));
- g_return_if_fail (attributes != NULL);
-
- iface = GCR_IMPORT_INTERACTION_GET_INTERFACE (interaction);
- if (iface->supplement != NULL)
- (iface->supplement_prep) (interaction, attributes);
-}
-
-/**
- * gcr_import_interaction_supplement:
- * @interaction: the interaction
- * @attributes: supplemented attributes
- * @cancellable: optional cancellable object
- * @error: location to store error on failure
- *
- * Supplement attributes before import. This means prompting the user for
- * things like labels and the like. The needed attributes will have been passed
- * to gcr_import_interaction_supplement_prep().
- *
- * This method prompts the user and fills in the attributes. If the user or
- * cancellable cancels the operation the error should be set with %G_IO_ERROR_CANCELLED.
- *
- * Returns: %G_TLS_INTERACTION_HANDLED if successful or %G_TLS_INTERACTION_FAILED
- */
-GTlsInteractionResult
-gcr_import_interaction_supplement (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GError **error)
-{
- GcrImportInteractionIface *iface;
-
- g_return_val_if_fail (GCR_IS_IMPORT_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (attributes != NULL, G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_INTERACTION_UNHANDLED);
-
- iface = GCR_IMPORT_INTERACTION_GET_INTERFACE (interaction);
- g_return_val_if_fail (iface->supplement != NULL, G_TLS_INTERACTION_UNHANDLED);
-
- return (iface->supplement) (interaction, attributes, cancellable, error);
-}
-
-
-/**
- * gcr_import_interaction_supplement_async:
- * @interaction: the interaction
- * @attributes: supplemented attributes
- * @cancellable: optional cancellable object
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Asynchronously supplement attributes before import. This means prompting the
- * user for things like labels and the like. The needed attributes will have
- * been passed to gcr_import_interaction_supplement_prep().
- *
- * This method prompts the user and fills in the attributes.
- */
-void
-gcr_import_interaction_supplement_async (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrImportInteractionIface *iface;
-
- g_return_if_fail (GCR_IS_IMPORT_INTERACTION (interaction));
- g_return_if_fail (attributes != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- iface = GCR_IMPORT_INTERACTION_GET_INTERFACE (interaction);
- g_return_if_fail (iface->supplement != NULL);
-
- (iface->supplement_async) (interaction, attributes, cancellable, callback, user_data);
-}
-
-/**
- * gcr_import_interaction_supplement_finish:
- * @interaction: the interaction
- * @result: the asynchronous result
- * @error: location to place an error on failure
- *
- * Complete operation to asynchronously supplement attributes before import.
- *
- * If the user or cancellable cancels the operation the error should be set
- * with %G_IO_ERROR_CANCELLED.
- *
- * Returns: %G_TLS_INTERACTION_HANDLED if successful or %G_TLS_INTERACTION_FAILED
- */
-GTlsInteractionResult
-gcr_import_interaction_supplement_finish (GcrImportInteraction *interaction,
- GAsyncResult *result,
- GError **error)
-{
- GcrImportInteractionIface *iface;
-
- g_return_val_if_fail (GCR_IS_IMPORT_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_INTERACTION_UNHANDLED);
-
- iface = GCR_IMPORT_INTERACTION_GET_INTERFACE (interaction);
- g_return_val_if_fail (iface->supplement != NULL, G_TLS_INTERACTION_UNHANDLED);
-
- return (iface->supplement_finish) (interaction, result, error);
-}
diff --git a/gcr/gcr-import-interaction.h b/gcr/gcr-import-interaction.h
deleted file mode 100644
index 2793d139..00000000
--- a/gcr/gcr-import-interaction.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_IMPORT_INTERACTION_H__
-#define __GCR_IMPORT_INTERACTION_H__
-
-#include "gcr-importer.h"
-
-#include <glib-object.h>
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_IMPORT_INTERACTION (gcr_import_interaction_get_type ())
-#define GCR_IMPORT_INTERACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORT_INTERACTION, GcrImportInteraction))
-#define GCR_IS_IMPORT_INTERACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORT_INTERACTION))
-#define GCR_IMPORT_INTERACTION_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_IMPORT_INTERACTION, GcrImportInteractionIface))
-
-typedef struct _GcrImportInteraction GcrImportInteraction;
-typedef struct _GcrImportInteractionIface GcrImportInteractionIface;
-
-struct _GcrImportInteractionIface {
- GTypeInterface parent;
-
- void (*supplement_prep) (GcrImportInteraction *interaction,
- GckAttributes *attributes);
-
- GTlsInteractionResult (*supplement) (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GError **error);
-
- void (*supplement_async) (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- GTlsInteractionResult (*supplement_finish) (GcrImportInteraction *interaction,
- GAsyncResult *result,
- GError **error);
-
- /*< private >*/
- gpointer reserved[6];
-};
-
-GType gcr_import_interaction_get_type (void);
-
-void gcr_import_interaction_supplement_prep (GcrImportInteraction *interaction,
- GckAttributes *attributes);
-
-GTlsInteractionResult gcr_import_interaction_supplement (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_import_interaction_supplement_async (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-GTlsInteractionResult gcr_import_interaction_supplement_finish (GcrImportInteraction *interaction,
- GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_IMPORT_INTERACTION_H__ */
diff --git a/gcr/gcr-importer.c b/gcr/gcr-importer.c
deleted file mode 100644
index cb572851..00000000
--- a/gcr/gcr-importer.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-deprecated-base.h"
-#include "gcr-importer.h"
-#include "gcr-internal.h"
-#include "gcr-marshal.h"
-#include "gcr-gnupg-importer.h"
-#include "gcr-parser.h"
-#include "gcr-pkcs11-importer.h"
-
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-importer
- * @title: GcrImporter
- * @short_description: Import certificates and keys
- *
- * An interface which allows importing of certificates and keys. Each
- * #GcrImporter is registered with a set of PKCS\#11 attributes to match
- * stuff that it can import.
- *
- * An importer gets passed a #GcrParser and accesses the currently parsed
- * item. To create a set of importers that can import the currently parsed
- * item in a #GcrParser, use gcr_importer_create_for_parsed(). The list of
- * importers returned has the parsed item queued for import.
- *
- * To queue additional items with a importer use gcr_importer_queue_for_parsed().
- * In addition you can try and queue an additional item with a set of importers
- * using the gcr_importer_queue_and_filter_for_parsed().
- *
- * To start the import use gcr_importer_import() or the async variants.
- */
-
-/**
- * GcrImporter:
- *
- * Imports certificates and keys
- */
-
-/**
- * GcrImporterIface:
- * @parent: parent interface
- * @create_for_parsed: implementation of gcr_importer_create_for_parsed(), required
- * @queue_for_parsed: implementation of gcr_importer_queue_for_parsed(), required
- * @import_sync: optional implemantionon of gcr_importer_import()
- * @import_async: implementation of gcr_importer_import_async(), required
- * @import_finish: implementation of gcr_importer_import_finish()
- *
- * Interface implemented for a #GcrImporter.
- */
-
-typedef GcrImporterIface GcrImporterInterface;
-
-G_DEFINE_INTERFACE (GcrImporter, gcr_importer, G_TYPE_OBJECT);
-
-typedef struct _GcrRegistered {
- GckAttributes *attrs;
- GType importer_type;
-} GcrRegistered;
-
-static GArray *registered_importers = NULL;
-static gboolean registered_sorted = FALSE;
-
-static void
-gcr_importer_default_init (GcrImporterIface *iface)
-{
- static volatile gsize initialized = 0;
-
- if (g_once_init_enter (&initialized)) {
-
- /**
- * GcrImporter:label:
- *
- * The label for the importer.
- */
- g_object_interface_install_property (iface,
- g_param_spec_string ("label", "Label", "The label for the importer",
- "", G_PARAM_READABLE));
-
- /**
- * GcrImporter:icon:
- *
- * The icon for the importer.
- */
- g_object_interface_install_property (iface,
- g_param_spec_object ("icon", "Icon", "The icon for the importer",
- G_TYPE_ICON, G_PARAM_READABLE));
-
- /**
- * GcrImporter:interaction:
- *
- * The interaction for the importer.
- */
- g_object_interface_install_property (iface,
- g_param_spec_object ("interaction", "Interaction",
- "Interaction for prompts",
- G_TYPE_TLS_INTERACTION, G_PARAM_READWRITE));
-
- g_once_init_leave (&initialized, 1);
- }
-}
-
-/**
- * gcr_importer_register:
- * @importer_type: the GType of the importer being registered
- * @attrs: the attributes that this importer is compatible with
- *
- * Register an importer to handle parsed items that match the given attributes.
- */
-void
-gcr_importer_register (GType importer_type,
- GckAttributes *attrs)
-{
- GcrRegistered registered;
-
- if (!registered_importers)
- registered_importers = g_array_new (FALSE, FALSE, sizeof (GcrRegistered));
-
- registered.importer_type = importer_type;
- registered.attrs = gck_attributes_ref (attrs);
- g_array_append_val (registered_importers, registered);
- registered_sorted = FALSE;
-}
-
-static gint
-sort_registered_by_n_attrs (gconstpointer a, gconstpointer b)
-{
- const GcrRegistered *ra = a;
- const GcrRegistered *rb = b;
- gulong na, nb;
-
- g_assert (a);
- g_assert (b);
-
- na = gck_attributes_count (ra->attrs);
- nb = gck_attributes_count (rb->attrs);
-
- /* Note we're sorting in reverse order */
- if (na < nb)
- return 1;
- return (na == nb) ? 0 : -1;
-}
-
-static gboolean
-check_if_seen_or_add (GHashTable *seen,
- gpointer key)
-{
- if (g_hash_table_lookup (seen, key))
- return TRUE;
- g_hash_table_insert (seen, key, key);
- return FALSE;
-}
-
-/**
- * gcr_importer_create_for_parsed:
- * @parsed: a parser with a parsed item to import
- *
- * Create a set of importers which can import this parsed item.
- * The parsed item is represented by the state of the GcrParser at the
- * time of calling this method.
- *
- * Returns: (element-type Gcr.Importer) (transfer full): a list of importers
- * which can import the parsed item, which should be freed with
- * g_object_unref(), or %NULL if no types of importers can be created
- */
-GList *
-gcr_importer_create_for_parsed (GcrParsed *parsed)
-{
- GcrRegistered *registered;
- GcrImporterIface *iface;
- gpointer instance_class;
- GckAttributes *attrs;
- gboolean matched;
- gulong n_attrs;
- GList *results = NULL;
- GHashTable *seen;
- gulong j;
- gsize i;
-
- g_return_val_if_fail (parsed != NULL, NULL);
-
- gcr_importer_register_well_known ();
-
- if (!registered_importers)
- return NULL;
-
- if (!registered_sorted) {
- g_array_sort (registered_importers, sort_registered_by_n_attrs);
- registered_sorted = TRUE;
- }
-
- attrs = gcr_parsed_get_attributes (parsed);
- if (attrs != NULL)
- gck_attributes_ref (attrs);
- else
- attrs = gck_attributes_new ();
-
- seen = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- for (i = 0; i < registered_importers->len; ++i) {
- registered = &(g_array_index (registered_importers, GcrRegistered, i));
- n_attrs = gck_attributes_count (registered->attrs);
-
- matched = TRUE;
-
- for (j = 0; j < n_attrs; ++j) {
- if (!gck_attributes_contains (attrs, gck_attributes_at (registered->attrs, j))) {
- matched = FALSE;
- break;
- }
- }
-
- if (matched) {
- if (check_if_seen_or_add (seen, GUINT_TO_POINTER (registered->importer_type)))
- continue;
-
- instance_class = g_type_class_ref (registered->importer_type);
-
- iface = g_type_interface_peek (instance_class, GCR_TYPE_IMPORTER);
- g_return_val_if_fail (iface != NULL, NULL);
- g_return_val_if_fail (iface->create_for_parsed, NULL);
- results = g_list_concat (results, (iface->create_for_parsed) (parsed));
-
- g_type_class_unref (instance_class);
- }
- }
-
- g_hash_table_unref (seen);
- gck_attributes_unref (attrs);
- return results;
-}
-
-/**
- * gcr_importer_queue_for_parsed:
- * @importer: an importer to add additional items to
- * @parsed: a parsed item to import
- *
- * Queues an additional item to be imported. The parsed item is represented
- * by the state of the #GcrParser at the time of calling this method.
- *
- * If the parsed item is incompatible with the importer, then this will
- * fail and the item will not be queued.
- *
- * Returns: whether the item was queued or not
- */
-gboolean
-gcr_importer_queue_for_parsed (GcrImporter *importer,
- GcrParsed *parsed)
-{
- GcrImporterIface *iface;
-
- g_return_val_if_fail (GCR_IS_IMPORTER (importer), FALSE);
- g_return_val_if_fail (parsed != NULL, FALSE);
-
- iface = GCR_IMPORTER_GET_INTERFACE (importer);
- g_return_val_if_fail (iface != NULL, FALSE);
- g_return_val_if_fail (iface->queue_for_parsed != NULL, FALSE);
-
- return (iface->queue_for_parsed) (importer, parsed);
-}
-
-/**
- * gcr_importer_queue_and_filter_for_parsed:
- * @importers: (element-type Gcr.Importer): a set of importers
- * @parsed: a parsed item
- *
- * Queues an additional item to be imported in all compattible importers
- * in the set. The parsed item is represented by the state of the #GcrParser
- * at the time of calling this method.
- *
- * If the parsed item is incompatible with an importer, then that the item
- * will not be queued on that importer.
- *
- * Returns: (transfer full) (element-type Gcr.Importer): a new set of importers
- * that queued the item, which should be freed with gck_list_unref_free()
- */
-GList *
-gcr_importer_queue_and_filter_for_parsed (GList *importers,
- GcrParsed *parsed)
-{
- GList *results = NULL;
- GList *l;
-
- for (l = importers; l != NULL; l = g_list_next (l)) {
- if (gcr_importer_queue_for_parsed (l->data, parsed))
- results = g_list_prepend (results, g_object_ref (l->data));
- }
-
- return g_list_reverse (results);
-}
-
-typedef struct {
- gboolean complete;
- GCond *cond;
- GMutex *mutex;
- GError *error;
- GMainContext *context;
-} ImportClosure;
-
-static void
-on_import_async_complete (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- ImportClosure *closure = user_data;
- GError *error = NULL;
-
- if (!gcr_importer_import_finish (GCR_IMPORTER (source), result, &error)) {
- if (error == NULL) {
- g_warning ("%s::import_finished returned false, but did not set error",
- G_OBJECT_TYPE_NAME (source));
- }
- }
-
- g_mutex_lock (closure->mutex);
-
- closure->complete = TRUE;
- closure->error = error;
- g_cond_signal (closure->cond);
-
- g_mutex_unlock (closure->mutex);
-}
-
-/**
- * gcr_importer_import:
- * @importer: the importer
- * @cancellable: a #GCancellable, or %NULL
- * @error: the location to place an error on failure, or %NULL
- *
- * Import the queued items in the importer. This call will block
- * until the operation completes.
- *
- * Returns: whether the items were imported successfully or not
- */
-gboolean
-gcr_importer_import (GcrImporter *importer,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean result;
- ImportClosure *closure;
- GcrImporterIface *iface;
-
- g_return_val_if_fail (GCR_IS_IMPORTER (importer), FALSE);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- iface = GCR_IMPORTER_GET_INTERFACE (importer);
- if (iface->import_sync)
- return (iface->import_sync) (importer, cancellable, error);
-
- g_return_val_if_fail (iface->import_async != NULL, FALSE);
- g_return_val_if_fail (iface->import_finish != NULL, FALSE);
-
- closure = g_new0 (ImportClosure, 1);
- closure->cond = g_cond_new ();
- closure->mutex = g_mutex_new ();
- closure->context = g_main_context_get_thread_default ();
- g_mutex_lock (closure->mutex);
-
- (iface->import_async) (importer, cancellable, on_import_async_complete, closure);
-
- /*
- * Handle the case where we've been called from within the main context
- * or in the case where the main context is not running. This approximates
- * the behavior of a modal dialog.
- */
- if (g_main_context_acquire (closure->context)) {
- while (!closure->complete) {
- g_mutex_unlock (closure->mutex);
- g_main_context_iteration (closure->context, TRUE);
- g_mutex_lock (closure->mutex);
- }
-
- g_main_context_release (closure->context);
-
- /*
- * Handle the case where we're in a different thread than the main
- * context and a main loop is running.
- */
- } else {
- while (!closure->complete)
- g_cond_wait (closure->cond, closure->mutex);
- }
-
- g_mutex_unlock (closure->mutex);
-
- result = (closure->error == NULL);
- if (closure->error)
- g_propagate_error (error, closure->error);
-
- g_cond_free (closure->cond);
- g_mutex_free (closure->mutex);
- g_free (closure);
-
- return result;
-}
-
-/**
- * gcr_importer_import_async:
- * @importer: the importer
- * @cancellable: a #GCancellable, or %NULL
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Import the queued items in the importer. This function returns immediately
- * and completes asynchronously.
- */
-void
-gcr_importer_import_async (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrImporterIface *iface;
-
- g_return_if_fail (GCR_IS_IMPORTER (importer));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- iface = GCR_IMPORTER_GET_INTERFACE (importer);
- g_return_if_fail (iface != NULL);
- g_return_if_fail (iface->import_async != NULL);
-
- return (iface->import_async) (importer, cancellable, callback, user_data);
-}
-
-/**
- * gcr_importer_import_finish:
- * @importer: the importer
- * @result: an asynchronous result
- * @error: the location to place an error on failure, or %NULL
- *
- * Complete an asynchronous operation to import queued items.
- *
- * Returns: whether the import succeeded or failed
- */
-gboolean
-gcr_importer_import_finish (GcrImporter *importer,
- GAsyncResult *result,
- GError **error)
-{
- GcrImporterIface *iface;
-
- g_return_val_if_fail (GCR_IS_IMPORTER (importer), FALSE);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- iface = GCR_IMPORTER_GET_INTERFACE (importer);
- g_return_val_if_fail (iface != NULL, FALSE);
- g_return_val_if_fail (iface->import_finish != NULL, FALSE);
-
- return (iface->import_finish) (importer, result, error);
-}
-
-/**
- * gcr_importer_get_interaction:
- * @importer: the importer
- *
- * Get the interaction used to prompt the user when needed by this
- * importer.
- *
- * Returns: (transfer none) (allow-none): the interaction or %NULL
- */
-GTlsInteraction *
-gcr_importer_get_interaction (GcrImporter *importer)
-{
- GTlsInteraction *interaction = NULL;
-
- g_return_val_if_fail (GCR_IS_IMPORTER (importer), NULL);
-
- g_object_get (importer, "interaction", &interaction, NULL);
-
- if (interaction != NULL)
- g_object_unref (interaction);
-
- return interaction;
-}
-
-/**
- * gcr_importer_set_interaction:
- * @importer: the importer
- * @interaction: the interaction used by the importer
- *
- * Set the interaction used to prompt the user when needed by this
- * importer.
- */
-void
-gcr_importer_set_interaction (GcrImporter *importer,
- GTlsInteraction *interaction)
-{
- g_return_if_fail (GCR_IS_IMPORTER (importer));
- g_object_set (importer, "interaction", interaction, NULL);
-}
-
-/**
- * gcr_importer_register_well_known:
- *
- * Register built-in PKCS\#11 and GnuPG importers.
- */
-void
-gcr_importer_register_well_known (void)
-{
- g_type_class_unref (g_type_class_ref (GCR_TYPE_PKCS11_IMPORTER));
- g_type_class_unref (g_type_class_ref (GCR_TYPE_GNUPG_IMPORTER));
-}
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-/**
- * gcr_importer_get_parser:
- * @self: An importer
- *
- * Has no effect. Use gcr_importer_listen() instead.
- *
- * Returns: %NULL is always returned.
- * Deprecated: Since 3.0.0
- */
-GcrParser*
-gcr_importer_get_parser (GcrImporter *self)
-{
- g_warning ("gcr_importer_get_parser() is no longer supported "
- "Use gcr_importer_listen() instead.");
- return NULL;
-}
-
-/**
- * gcr_importer_set_parser:
- * @self: An importer
- * @parser: A parser
- *
- * Has no effect. Use gcr_importer_listen() instead.
- *
- * Deprecated: Since 3.0.0
- */
-void
-gcr_importer_set_parser (GcrImporter *self,
- GcrParser *parser)
-{
- g_warning ("gcr_importer_set_parser() is no longer supported "
- "Use gcr_importer_listen() instead.");
-}
-
-/*
- * gcr_importer_get_slot:
- * @self: The importer
- *
- * Returns %NULL.
- *
- * Deprecated: since 3.4.0
- */
-GckSlot *
-gcr_importer_get_slot (GcrImporter *self)
-{
- g_warning ("gcr_importer_get_slot() is no longer supported.");
- return NULL;
-}
-
-/**
- * gcr_importer_set_slot:
- * @self: The importer
- * @slot: The slot to import to
- *
- * Has no effect.
- *
- * Deprecated: since 3.4.0
- */
-void
-gcr_importer_set_slot (GcrImporter *self,
- GckSlot *slot)
-{
- g_warning ("gcr_importer_set_slot() is no longer supported.");
-}
-
-/**
- * gcr_importer_get_prompt_behavior:
- * @self: The importer
- *
- * Returns: zero
- *
- * Deprecated: since 3.4.0
- */
-GcrImporterPromptBehavior
-gcr_importer_get_prompt_behavior (GcrImporter *self)
-{
- g_warning ("gcr_importer_get_prompt_behavior() is no longer supported.");
- return 0;
-}
-
-/**
- * gcr_importer_set_prompt_behavior:
- * @self: The importer
- * @behavior: The prompt behavior flag
- *
- * Has no effect.
- *
- * Deprecated: since 3.4.0
- */
-void
-gcr_importer_set_prompt_behavior (GcrImporter *self,
- GcrImporterPromptBehavior behavior)
-{
- g_warning ("gcr_importer_set_prompt_behavior() is no longer supported.");
-}
-
-#endif /* GCR_DISABLE_DEPRECATED */
diff --git a/gcr/gcr-importer.h b/gcr/gcr-importer.h
deleted file mode 100644
index d9159408..00000000
--- a/gcr/gcr-importer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_IMPORTER_H__
-#define __GCR_IMPORTER_H__
-
-#include "gcr-parser.h"
-
-#include <glib-object.h>
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_IMPORTER (gcr_importer_get_type ())
-#define GCR_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORTER, GcrImporter))
-#define GCR_IS_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORTER))
-#define GCR_IMPORTER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_IMPORTER, GcrImporterIface))
-
-typedef struct _GcrImporter GcrImporter;
-typedef struct _GcrImporterIface GcrImporterIface;
-
-struct _GcrImporterIface {
- GTypeInterface parent;
-
- GList * (*create_for_parsed) (GcrParsed *parsed);
-
- gboolean (*queue_for_parsed) (GcrImporter *importer,
- GcrParsed *parsed);
-
- gboolean (*import_sync) (GcrImporter *importer,
- GCancellable *cancellable,
- GError **error);
-
- void (*import_async) (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
- gboolean (*import_finish) (GcrImporter *importer,
- GAsyncResult *result,
- GError **error);
-
- /*< private >*/
- gpointer reserved[14];
-};
-
-GType gcr_importer_get_type (void);
-
-GList * gcr_importer_create_for_parsed (GcrParsed *parsed);
-
-gboolean gcr_importer_queue_for_parsed (GcrImporter *importer,
- GcrParsed *parsed);
-
-GList * gcr_importer_queue_and_filter_for_parsed (GList *importers,
- GcrParsed *parsed);
-
-gboolean gcr_importer_import (GcrImporter *importer,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_importer_import_async (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_importer_import_finish (GcrImporter *importer,
- GAsyncResult *result,
- GError **error);
-
-GTlsInteraction * gcr_importer_get_interaction (GcrImporter *importer);
-
-void gcr_importer_set_interaction (GcrImporter *importer,
- GTlsInteraction *interaction);
-
-void gcr_importer_register (GType importer_type,
- GckAttributes *attrs);
-
-void gcr_importer_register_well_known (void);
-
-G_END_DECLS
-
-#endif /* __GCR_IMPORTER_H__ */
diff --git a/gcr/gcr-internal.h b/gcr/gcr-internal.h
deleted file mode 100644
index ef6153fc..00000000
--- a/gcr/gcr-internal.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_INTERNAL_H_
-#define GCR_INTERNAL_H_
-
-#include <glib.h>
-#include <gio/gio.h>
-
-/* Should only be used internally */
-#define GCR_SUCCESS 0
-
-void _gcr_initialize_library (void);
-
-void _gcr_set_pkcs11_config_dir (const gchar *dir);
-
-#endif /* GCR_INTERNAL_H_ */
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
deleted file mode 100644
index 91020692..00000000
--- a/gcr/gcr-key-renderer.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-key-renderer.h"
-#include "gcr-display-view.h"
-#include "gcr-fingerprint.h"
-#include "gcr-icons.h"
-#include "gcr-renderer.h"
-#include "gcr-viewer.h"
-
-#include "gck/gck.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-/**
- * GcrKeyRenderer:
- *
- * An implementation of #GcrRenderer which renders keys.
- */
-
-/**
- * GcrKeyRendererClass:
- * @parent_class: The parent class.
- *
- * The class for #GcrKeyRenderer.
- */
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ATTRIBUTES
-};
-
-struct _GcrKeyRendererPrivate {
- guint key_size;
- gchar *label;
- GckAttributes *attributes;
- GIcon *icon;
-};
-
-static void gcr_key_renderer_renderer_iface (GcrRendererIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrKeyRenderer, gcr_key_renderer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_key_renderer_renderer_iface));
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gchar*
-calculate_label (GcrKeyRenderer *self)
-{
- gchar *label;
-
- if (self->pv->label)
- return g_strdup (self->pv->label);
-
- if (self->pv->attributes) {
- if (gck_attributes_find_string (self->pv->attributes, CKA_LABEL, &label))
- return label;
- }
-
- return g_strdup (_("Key"));
-}
-
-static gint
-calculate_rsa_key_size (GckAttributes *attrs)
-{
- GckAttribute *attr;
- gulong bits;
-
- attr = gck_attributes_find (attrs, CKA_MODULUS);
-
- /* Calculate the bit length, and remove the complement */
- if (attr != NULL)
- return (attr->length / 2) * 2 * 8;
-
- if (gck_attributes_find_ulong (attrs, CKA_MODULUS_BITS, &bits))
- return (gint)bits;
-
- return -1;
-}
-
-static guint
-calculate_dsa_key_size (GckAttributes *attrs)
-{
- GckAttribute *attr;
- gulong bits;
-
- attr = gck_attributes_find (attrs, CKA_PRIME);
-
- /* Calculate the bit length, and remove the complement */
- if (attr != NULL)
- return (attr->length / 2) * 2 * 8;
-
- if (gck_attributes_find_ulong (attrs, CKA_PRIME_BITS, &bits))
- return (gint)bits;
-
- return -1;
-}
-
-static gint
-calculate_key_size (GckAttributes *attrs, gulong key_type)
-{
- if (key_type == CKK_RSA)
- return calculate_rsa_key_size (attrs);
- else if (key_type == CKK_DSA)
- return calculate_dsa_key_size (attrs);
- else
- return -1;
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gcr_key_renderer_init (GcrKeyRenderer *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_RENDERER, GcrKeyRendererPrivate));
- self->pv->icon = g_themed_icon_new (GCR_ICON_KEY);
-}
-
-static void
-gcr_key_renderer_dispose (GObject *obj)
-{
- G_OBJECT_CLASS (gcr_key_renderer_parent_class)->dispose (obj);
-}
-
-static void
-gcr_key_renderer_finalize (GObject *obj)
-{
- GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
-
- if (self->pv->attributes)
- gck_attributes_unref (self->pv->attributes);
- self->pv->attributes = NULL;
-
- g_free (self->pv->label);
- self->pv->label = NULL;
-
- if (self->pv->icon)
- g_object_unref (self->pv->icon);
- self->pv->icon = NULL;
-
- G_OBJECT_CLASS (gcr_key_renderer_parent_class)->finalize (obj);
-}
-
-static void
-gcr_key_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- case PROP_ATTRIBUTES:
- g_return_if_fail (!self->pv->attributes);
- self->pv->attributes = g_value_dup_boxed (value);
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_key_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, self->pv->attributes);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_key_renderer_class_init (GcrKeyRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- gcr_key_renderer_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrKeyRendererPrivate));
-
- gobject_class->dispose = gcr_key_renderer_dispose;
- gobject_class->finalize = gcr_key_renderer_finalize;
- gobject_class->set_property = gcr_key_renderer_set_property;
- gobject_class->get_property = gcr_key_renderer_get_property;
-
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
- g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
-
- /* Register this as a view which can be loaded */
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
- gcr_renderer_register (GCR_TYPE_KEY_RENDERER, registered);
- gck_attributes_unref (registered);
-}
-
-static void
-gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
-{
- GcrKeyRenderer *self;
- GcrDisplayView *view;
- const gchar *text = "";
- gpointer fingerprint;
- gsize n_fingerprint;
- gchar *display;
- gulong klass;
- gulong key_type;
- gint size;
-
- self = GCR_KEY_RENDERER (renderer);
-
- if (GCR_IS_DISPLAY_VIEW (viewer)) {
- view = GCR_DISPLAY_VIEW (viewer);
-
- } else {
- g_warning ("GcrKeyRenderer only works with internal specific "
- "GcrViewer returned by gcr_viewer_new().");
- return;
- }
-
- _gcr_display_view_begin (view, renderer);
-
- if (!self->pv->attributes) {
- _gcr_display_view_end (view, renderer);
- return;
- }
-
- if (!gck_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
- !gck_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
- g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
- _gcr_display_view_end (view, renderer);
- return;
- }
-
- _gcr_display_view_set_icon (view, renderer, self->pv->icon);
-
- display = calculate_label (self);
- _gcr_display_view_append_title (view, renderer, display);
- g_free (display);
-
- if (klass == CKO_PRIVATE_KEY) {
- if (key_type == CKK_RSA)
- text = _("Private RSA Key");
- else if (key_type == CKK_DSA)
- text = _("Private DSA Key");
- else
- text = _("Private Key");
- } else if (klass == CKO_PUBLIC_KEY) {
- if (key_type == CKK_RSA)
- text = _("Public DSA Key");
- else if (key_type == CKK_DSA)
- text = _("Public DSA Key");
- else
- text = _("Public Key");
- }
-
- _gcr_display_view_append_content (view, renderer, text, NULL);
-
- size = calculate_key_size (self->pv->attributes, key_type);
- if (size >= 0) {
- display = g_strdup_printf (ngettext ("%d bit", "%d bits", size), size);
- _gcr_display_view_append_content (view, renderer, _("Strength"), display);
- g_free (display);
- }
-
- _gcr_display_view_start_details (view, renderer);
-
-
- if (key_type == CKK_RSA)
- text = _("RSA");
- else if (key_type == CKK_DSA)
- text = _("DSA");
- else
- text = _("Unknown");
- _gcr_display_view_append_value (view, renderer, _("Algorithm"), text, FALSE);
-
- size = calculate_key_size (self->pv->attributes, key_type);
- if (size < 0)
- display = g_strdup (_("Unknown"));
- else
- display = g_strdup_printf ("%d", size);
- _gcr_display_view_append_value (view, renderer, _("Size"), display, FALSE);
- g_free (display);
-
- /* Fingerprints */
- _gcr_display_view_append_heading (view, renderer, _("Fingerprints"));
-
- fingerprint = gcr_fingerprint_from_attributes (self->pv->attributes,
- G_CHECKSUM_SHA1, &n_fingerprint);
- if (fingerprint) {
- _gcr_display_view_append_hex (view, renderer, _("SHA1"), fingerprint, n_fingerprint);
- g_free (fingerprint);
- }
- fingerprint = gcr_fingerprint_from_attributes (self->pv->attributes,
- G_CHECKSUM_SHA256, &n_fingerprint);
- if (fingerprint) {
- _gcr_display_view_append_hex (view, renderer, _("SHA256"), fingerprint, n_fingerprint);
- g_free (fingerprint);
- }
-
- _gcr_display_view_end (view, renderer);
-}
-
-static void
-gcr_key_renderer_renderer_iface (GcrRendererIface *iface)
-{
- iface->render_view = gcr_key_renderer_real_render;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_key_renderer_new:
- * @label: (allow-none): label describing the key
- * @attrs: (allow-none): key to display, or %NULL
- *
- * Create a new key renderer which renders a given key in the attributes.
- *
- * Returns: (transfer full): a newly allocated #GcrKeyRenderer, which should be
- * freed with g_object_unref()
- */
-GcrKeyRenderer*
-gcr_key_renderer_new (const gchar *label, GckAttributes *attrs)
-{
- return g_object_new (GCR_TYPE_KEY_RENDERER, "label", label, "attributes", attrs, NULL);
-}
-
-/**
- * gcr_key_renderer_set_attributes:
- * @self: The key renderer
- * @attrs: (allow-none): the attributes to display
- *
- * Get the attributes displayed in the renderer. The attributes should represent
- * either an RSA or DSA key in PKCS\#11 style.
- */
-void
-gcr_key_renderer_set_attributes (GcrKeyRenderer *self, GckAttributes *attrs)
-{
- g_return_if_fail (GCR_IS_KEY_RENDERER (self));
-
- if (self->pv->attributes)
- gck_attributes_unref (self->pv->attributes);
- self->pv->attributes = attrs;
- if (self->pv->attributes)
- gck_attributes_ref (self->pv->attributes);
-
- g_object_notify (G_OBJECT (self), "attributes");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
-}
-
-/**
- * gcr_key_renderer_get_attributes:
- * @self: The key renderer
- *
- * Get the attributes displayed in the renderer.
- *
- * Returns: (transfer none) (allow-none): the attributes, owned by the renderer
- */
-GckAttributes*
-gcr_key_renderer_get_attributes (GcrKeyRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_KEY_RENDERER (self), NULL);
- return self->pv->attributes;
-}
diff --git a/gcr/gcr-key-renderer.h b/gcr/gcr-key-renderer.h
deleted file mode 100644
index 1c796444..00000000
--- a/gcr/gcr-key-renderer.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_KEY_RENDERER_H__
-#define __GCR_KEY_RENDERER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_KEY_RENDERER (gcr_key_renderer_get_type ())
-#define GCR_KEY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_KEY_RENDERER, GcrKeyRenderer))
-#define GCR_KEY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_KEY_RENDERER, GcrKeyRendererClass))
-#define GCR_IS_KEY_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_KEY_RENDERER))
-#define GCR_IS_KEY_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_KEY_RENDERER))
-#define GCR_KEY_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_KEY_RENDERER, GcrKeyRendererClass))
-
-typedef struct _GcrKeyRenderer GcrKeyRenderer;
-typedef struct _GcrKeyRendererClass GcrKeyRendererClass;
-typedef struct _GcrKeyRendererPrivate GcrKeyRendererPrivate;
-
-struct _GcrKeyRenderer {
- GObject parent;
-
- /*< private >*/
- GcrKeyRendererPrivate *pv;
-};
-
-struct _GcrKeyRendererClass {
- GObjectClass parent_class;
-};
-
-GType gcr_key_renderer_get_type (void);
-
-GcrKeyRenderer* gcr_key_renderer_new (const gchar *label,
- GckAttributes *attrs);
-
-void gcr_key_renderer_set_attributes (GcrKeyRenderer *self,
- GckAttributes *attrs);
-
-GckAttributes* gcr_key_renderer_get_attributes (GcrKeyRenderer *self);
-
-G_END_DECLS
-
-#endif /* __GCR_KEY_RENDERER_H__ */
diff --git a/gcr/gcr-key-widget.c b/gcr/gcr-key-widget.c
deleted file mode 100644
index 65b57911..00000000
--- a/gcr/gcr-key-widget.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-key-renderer.h"
-#include "gcr-key-widget.h"
-#include "gcr-renderer.h"
-#include "gcr-viewer.h"
-
-#include "gck/gck.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-key-widget
- * @title: GcrKeyWidget
- * @short_description: Key widget and renderer
- *
- * A #GcrKeyWidget can be used to display a RSA or DSA key. The widget
- * is normally in a collapsed state showing only details, but can be expanded
- * by the user.
- *
- * Use gcr_key_widget_new() to create a new key widget. Only
- * one key can be displayed. A #GcrKeyWidget contains a
- * #GcrViewer internally and #GcrKeyRenderer is used to render the
- * key to the viewer. To show more than one key in a view,
- * create the viewer and add renderers to it.
- */
-
-/**
- * GcrKeyWidget:
- *
- * A widget that displays a key.
- */
-
-/**
- * GcrKeyWidgetClass:
- *
- * The class for #GcrKeyWidget
- */
-enum {
- PROP_0,
- PROP_ATTRIBUTES
-};
-
-struct _GcrKeyWidget {
- GtkAlignment parent;
-
- /*< private >*/
- GcrKeyWidgetPrivate *pv;
-};
-
-struct _GcrKeyWidgetClass {
- /*< private >*/
- GtkAlignmentClass parent_class;
-};
-
-struct _GcrKeyWidgetPrivate {
- GcrViewer *viewer;
- GcrKeyRenderer *renderer;
-};
-
-G_DEFINE_TYPE (GcrKeyWidget, gcr_key_widget, GTK_TYPE_ALIGNMENT);
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-gcr_key_widget_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GObject *obj = G_OBJECT_CLASS (gcr_key_widget_parent_class)->constructor (type, n_props, props);
- GcrKeyWidget *self = NULL;
-
- g_return_val_if_fail (obj, NULL);
-
- self = GCR_KEY_WIDGET (obj);
-
- self->pv->viewer = gcr_viewer_new_scrolled ();
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->viewer));
- gtk_widget_show (GTK_WIDGET (self->pv->viewer));
-
- gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (self->pv->renderer));
- return obj;
-}
-
-static void
-gcr_key_widget_init (GcrKeyWidget *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_KEY_WIDGET, GcrKeyWidgetPrivate));
- self->pv->renderer = gcr_key_renderer_new (NULL, NULL);
-}
-
-static void
-gcr_key_widget_finalize (GObject *obj)
-{
- GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
-
- g_assert (self->pv->renderer);
- g_object_unref (self->pv->renderer);
- self->pv->renderer = NULL;
-
- g_assert (self->pv->viewer);
- self->pv->viewer = NULL;
-
- G_OBJECT_CLASS (gcr_key_widget_parent_class)->finalize (obj);
-}
-
-static void
-gcr_key_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_ATTRIBUTES:
- gcr_key_widget_set_attributes (self, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_key_widget_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrKeyWidget *self = GCR_KEY_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, gcr_key_widget_get_attributes (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_key_widget_class_init (GcrKeyWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gcr_key_widget_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrKeyWidgetPrivate));
-
- gobject_class->constructor = gcr_key_widget_constructor;
- gobject_class->finalize = gcr_key_widget_finalize;
- gobject_class->set_property = gcr_key_widget_set_property;
- gobject_class->get_property = gcr_key_widget_get_property;
-
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the widget",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_key_widget_new:
- * @attrs: (allow-none): key to display, or %NULL
- *
- * Create a new key widget which displays a given key in the attributes.
- *
- * Returns: A newly allocated #GcrKeyWidget, which should be freed
- * with g_object_unref().
- */
-GcrKeyWidget*
-gcr_key_widget_new (GckAttributes *attrs)
-{
- return g_object_new (GCR_TYPE_KEY_WIDGET, "attributes", attrs, NULL);
-}
-
-/**
- * gcr_key_widget_set_attributes:
- * @self: The key widget
- * @attrs: (allow-none): the attributes to display
- *
- * Get the attributes displayed in the widget. The attributes should represent
- * either an RSA or DSA key in PKCS\#11 style.
- */
-void
-gcr_key_widget_set_attributes (GcrKeyWidget *self, GckAttributes *attrs)
-{
- g_return_if_fail (GCR_IS_KEY_WIDGET (self));
- gcr_key_renderer_set_attributes (self->pv->renderer, attrs);
-}
-
-/**
- * gcr_key_widget_get_attributes:
- * @self: The key widget
- *
- * Get the attributes displayed in the widget.
- *
- * Returns: (allow-none) (transfer none): The attributes, owned by the widget.
- */
-GckAttributes*
-gcr_key_widget_get_attributes (GcrKeyWidget *self)
-{
- g_return_val_if_fail (GCR_IS_KEY_WIDGET (self), NULL);
- return gcr_key_renderer_get_attributes (self->pv->renderer);
-}
diff --git a/gcr/gcr-key-widget.h b/gcr/gcr-key-widget.h
deleted file mode 100644
index 4901aad6..00000000
--- a/gcr/gcr-key-widget.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_KEY_WIDGET_H__
-#define __GCR_KEY_WIDGET_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_KEY_WIDGET (gcr_key_widget_get_type ())
-#define GCR_KEY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_KEY_WIDGET, GcrKeyWidget))
-#define GCR_KEY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_KEY_WIDGET, GcrKeyWidgetClass))
-#define GCR_IS_KEY_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_KEY_WIDGET))
-#define GCR_IS_KEY_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_KEY_WIDGET))
-#define GCR_KEY_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_KEY_WIDGET, GcrKeyWidgetClass))
-
-typedef struct _GcrKeyWidget GcrKeyWidget;
-typedef struct _GcrKeyWidgetClass GcrKeyWidgetClass;
-typedef struct _GcrKeyWidgetPrivate GcrKeyWidgetPrivate;
-
-/*
- * TODO: GcrKeyWidget and GcrKeyWidgetClass are hidden until
- * we can figure out what they should be derived from.
- */
-
-GType gcr_key_widget_get_type (void);
-
-GcrKeyWidget* gcr_key_widget_new (GckAttributes *attrs);
-
-void gcr_key_widget_set_attributes (GcrKeyWidget *self,
- GckAttributes *attrs);
-
-GckAttributes* gcr_key_widget_get_attributes (GcrKeyWidget *self);
-
-G_END_DECLS
-
-#endif /* __GCR_KEY_WIDGET_H__ */
diff --git a/gcr/gcr-library.c b/gcr/gcr-library.c
deleted file mode 100644
index 4910e6cd..00000000
--- a/gcr/gcr-library.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-base.h"
-#define DEBUG_FLAG GCR_DEBUG_LIBRARY
-#include "gcr-debug.h"
-#include "gcr-internal.h"
-#include "gcr-library.h"
-#include "gcr-types.h"
-
-#include "egg/egg-error.h"
-#include "egg/egg-libgcrypt.h"
-#include "egg/egg-secure-memory.h"
-
-#include <p11-kit/p11-kit.h>
-
-#include <gck/gck.h>
-
-#include <gcrypt.h>
-
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-library
- * @title: Library Settings
- * @short_description: functions for manipulating GCR library global settings.
- *
- * Manage or lookup various global aspesct and settings of the library.
- *
- * The GCR library maintains a global list of PKCS\#11 modules to use for
- * its various lookups and storage operations. Each module is represented by
- * a GckModule object. You can examine this list by using
- * gcr_pkcs11_get_modules().
- *
- * The list is configured automatically by looking for system installed
- * PKCS\#11 modules. It's not not normally necessary to modify this list. But
- * if you have special needs, you can use the gcr_pkcs11_set_modules() and
- * gcr_pkcs11_add_module() to do so.
- *
- * Trust assertions are stored and looked up in specific PKCS\#11 slots.
- * You can examine this list with gcr_pkcs11_get_trust_lookup_slots()
- */
-
-/**
- * SECTION:gcr-private
- * @title: Private declarations
- * @short_description: private declarations to supress warnings.
- *
- * This section is only here to supress warnings, and should not be displayed.
- */
-
-/**
- * GCR_DATA_ERROR:
- *
- * The #GError domain for data parsing errors.
- */
-
-G_LOCK_DEFINE_STATIC (modules);
-static GList *all_modules = NULL;
-static gboolean initialized_modules = FALSE;
-
-G_LOCK_DEFINE_STATIC (uris);
-static gboolean initialized_uris = FALSE;
-static gchar *trust_store_uri = NULL;
-static gchar **trust_lookup_uris = NULL;
-
-/* -----------------------------------------------------------------------------
- * ERRORS
- */
-
-GQuark
-gcr_data_error_get_domain (void)
-{
- static GQuark domain = 0;
- if (domain == 0)
- domain = g_quark_from_static_string ("gcr-parser-error");
- return domain;
-}
-
-GQuark
-gcr_error_get_domain (void)
-{
- static GQuark domain = 0;
- if (domain == 0)
- domain = g_quark_from_static_string ("gcr-error");
- return domain;
-}
-
-/* -----------------------------------------------------------------------------
- * INITIALIZATION
- */
-
-void
-_gcr_initialize_library (void)
-{
- static gint gcr_initialize = 0;
-
-#if GLIB_CHECK_VERSION (2,29,90)
- if (g_atomic_int_add (&gcr_initialize, 1) == 0)
-#else
- if (g_atomic_int_exchange_and_add (&gcr_initialize, 1) == 0)
-#endif
- return;
-
- /* Initialize the libgcrypt library if needed */
- egg_libgcrypt_initialize ();
-
- _gcr_debug ("initialized library");
-}
-
-static void
-initialize_uris (void)
-{
- GPtrArray *uris;
- GList *l;
- gchar *uri;
- gchar *debug;
-
- g_return_if_fail (initialized_modules);
-
- if (initialized_uris)
- return;
-
- G_LOCK (uris);
-
- if (!initialized_uris) {
- /* Ask for the global x-trust-store option */
- trust_store_uri = p11_kit_registered_option (NULL, "x-trust-store");
- for (l = all_modules; !trust_store_uri && l != NULL; l = g_list_next (l)) {
- trust_store_uri = p11_kit_registered_option (gck_module_get_functions (l->data),
- "x-trust-store");
- }
-
- uris = g_ptr_array_new ();
- uri = p11_kit_registered_option (NULL, "x-trust-lookup");
- if (uri != NULL)
- g_ptr_array_add (uris, uri);
- for (l = all_modules; l != NULL; l = g_list_next (l)) {
- uri = p11_kit_registered_option (gck_module_get_functions (l->data),
- "x-trust-lookup");
- if (uri != NULL)
- g_ptr_array_add (uris, uri);
- }
- g_ptr_array_add (uris, NULL);
-
- trust_lookup_uris = (gchar**)g_ptr_array_free (uris, FALSE);
-
- _gcr_debug ("trust store uri is: %s", trust_store_uri);
- debug = g_strjoinv (" ", trust_lookup_uris);
- _gcr_debug ("trust lookup uris are: %s", debug);
- g_free (debug);
-
- initialized_uris = TRUE;
- }
-
- G_UNLOCK (uris);
-}
-
-static void
-on_initialize_registered (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GList *results;
-
- results = gck_modules_initialize_registered_finish (result, &error);
- if (error != NULL) {
- _gcr_debug ("failed %s", error->message);
- g_simple_async_result_take_error (res, error);
-
- } else {
-
- G_LOCK (modules);
-
- if (!initialized_modules) {
- all_modules = g_list_concat(all_modules, results);
- results = NULL;
- initialized_modules = TRUE;
- }
-
- G_UNLOCK (modules);
- }
-
- gck_list_unref_free (results);
-
- _gcr_debug ("completed initialize of registered modules");
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-/**
- * gcr_pkcs11_initialize_async:
- * @cancellable: optional cancellable used to cancel the operation
- * @callback: callback which will be called when the operation completes
- * @user_data: data passed to the callback
- *
- * Asynchronously initialize the registered PKCS\#11 modules.
- */
-void
-gcr_pkcs11_initialize_async (GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (NULL, callback, user_data,
- gcr_pkcs11_initialize_async);
-
- if (initialized_modules) {
- _gcr_debug ("already initialized, no need to async");
- g_simple_async_result_complete_in_idle (res);
- } else {
- gck_modules_initialize_registered_async (cancellable,
- on_initialize_registered,
- g_object_ref (res));
- _gcr_debug ("starting initialize of registered modules");
- }
-
- g_object_unref (res);
-}
-
-/**
- * gcr_pkcs11_initialize_finish:
- * @result: the asynchronous result
- * @error: location to place an error on failure
- *
- * Complete the asynchronous operation to initialize the registered PKCS\#11
- * modules.
- *
- * Returns: whether the operation was successful or not.
- */
-gboolean
-gcr_pkcs11_initialize_finish (GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- gcr_pkcs11_initialize_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * gcr_pkcs11_initialize:
- * @cancellable: optional cancellable used to cancel the operation
- * @error: location to place an error on failure
- *
- * Asynchronously initialize the registered PKCS\#11 modules.
- *
- * Returns: whether the operation was successful or not.
- */
-
-gboolean
-gcr_pkcs11_initialize (GCancellable *cancellable,
- GError **error)
-{
- GList *results;
- GError *err = NULL;
-
- if (initialized_modules)
- return TRUE;
-
- results = gck_modules_initialize_registered (cancellable, &err);
- if (err == NULL) {
-
- _gcr_debug ("registered module initialize succeeded: %d modules",
- g_list_length (results));
-
- G_LOCK (modules);
-
- if (!initialized_modules) {
- all_modules = g_list_concat (all_modules, results);
- results = NULL;
- initialized_modules = TRUE;
- }
-
- G_UNLOCK (modules);
-
- } else {
- _gcr_debug ("registered module initialize failed: %s", err->message);
- g_propagate_error (error, err);
- }
-
- gck_list_unref_free (results);
- return (err == NULL);
-}
-
-/**
- * gcr_pkcs11_get_modules:
- *
- * List all the PKCS\#11 modules that are used by the GCR library.
- * Each module is a #GckModule object.
- *
- * When done with the list, free it with gck_list_unref_free().
- *
- * Returns: (transfer full) (element-type Gck.Module): a newly allocated list
- * of #GckModule objects
- */
-GList*
-gcr_pkcs11_get_modules (void)
-{
- g_return_val_if_fail (initialized_modules, NULL);
- if (!all_modules)
- _gcr_debug ("no modules loaded");
- return gck_list_ref_copy (all_modules);
-}
-
-/**
- * gcr_pkcs11_set_modules:
- * @modules: (element-type Gck.Module): a list of #GckModule
- *
- * Set the list of PKCS\#11 modules that are used by the GCR library.
- * Each module in the list is a #GckModule object.
- *
- * It is not normally necessary to call this function. The available
- * PKCS\#11 modules installed on the system are automatically loaded
- * by the GCR library.
- */
-void
-gcr_pkcs11_set_modules (GList *modules)
-{
- GList *l;
-
- for (l = modules; l; l = g_list_next (l))
- g_return_if_fail (GCK_IS_MODULE (l->data));
-
- modules = gck_list_ref_copy (modules);
- gck_list_unref_free (all_modules);
- all_modules = modules;
- initialized_modules = TRUE;
-}
-
-/**
- * gcr_pkcs11_add_module:
- * @module: a #GckModule
- *
- * Add a #GckModule to the list of PKCS\#11 modules that are used by the
- * GCR library.
- *
- * It is not normally necessary to call this function. The available
- * PKCS\#11 modules installed on the system are automatically loaded
- * by the GCR library.
- */
-void
-gcr_pkcs11_add_module (GckModule *module)
-{
- g_return_if_fail (GCK_IS_MODULE (module));
- all_modules = g_list_append (all_modules, g_object_ref (module));
-}
-
-/**
- * gcr_pkcs11_add_module_from_file:
- * @module_path: the full file path of the PKCS\#11 module
- * @unused: unused
- * @error: a #GError or NULL
- *
- * Initialize a PKCS\#11 module and add it to the modules that are
- * used by the GCR library. Note that is an error to initialize the same
- * PKCS\#11 module twice.
- *
- * It is not normally necessary to call this function. The available
- * PKCS\#11 modules installed on the system are automatically loaded
- * by the GCR library.
- *
- * Returns: whether the module was sucessfully added.
- */
-gboolean
-gcr_pkcs11_add_module_from_file (const gchar *module_path, gpointer unused,
- GError **error)
-{
- GckModule *module;
- GError *err = NULL;
-
- g_return_val_if_fail (module_path, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- module = gck_module_initialize (module_path, NULL, &err);
- if (module == NULL) {
- _gcr_debug ("initializing module failed: %s: %s",
- module_path, err->message);
- g_propagate_error (error, err);
- return FALSE;
- }
-
- gcr_pkcs11_add_module (module);
-
- _gcr_debug ("initialized and added module: %s", module_path);
- g_object_unref (module);
- return TRUE;
-}
-
-/**
- * gcr_pkcs11_get_trust_store_slot:
- *
- * Selects an appropriate PKCS\#11 slot to store trust assertions. The slot
- * to use is normally configured automatically by the system.
- *
- * When done with the #GckSlot, use g_object_unref() to release it.
- *
- * Returns: (transfer full): the #GckSlot to use for trust assertions.
- */
-GckSlot *
-gcr_pkcs11_get_trust_store_slot (void)
-{
- GckSlot *slot;
- GError *error = NULL;
-
- g_return_val_if_fail (initialized_modules, NULL);
-
- initialize_uris ();
- slot = gck_modules_token_for_uri (all_modules, trust_store_uri, &error);
- if (!slot) {
- if (error) {
- g_warning ("error finding slot to store trust assertions: %s: %s",
- trust_store_uri, egg_error_message (error));
- g_clear_error (&error);
- } else {
- _gcr_debug ("no trust store slot found");
- }
- }
-
- return slot;
-}
-
-/**
- * gcr_pkcs11_get_trust_lookup_slots:
- *
- * List all the PKCS\#11 slots that are used by the GCR library for lookup
- * of trust assertions. Each slot is a #GckSlot object.
- *
- * When done with the list, free it with gck_list_unref_free().
- *
- * Returns: (transfer full) (element-type Gck.Slot): a list of #GckSlot objects
- * to use for lookup of trust.
- */
-GList*
-gcr_pkcs11_get_trust_lookup_slots (void)
-{
- GList *results = NULL;
- GError *error = NULL;
- gchar **uri;
-
- g_return_val_if_fail (initialized_modules, NULL);
- initialize_uris ();
-
- for (uri = trust_lookup_uris; uri && *uri; ++uri) {
- results = g_list_concat (results, gck_modules_tokens_for_uri (all_modules, *uri, &error));
- if (error != NULL) {
- g_warning ("error finding slot for trust assertions: %s: %s",
- *uri, egg_error_message (error));
- g_clear_error (&error);
- }
- }
-
- if (results == NULL)
- _gcr_debug ("no trust lookup slots found");
-
- return results;
-}
-
-/**
- * gcr_pkcs11_get_trust_store_uri:
- *
- * Get the PKCS\#11 URI that is used to identify which slot to use for
- * storing trust storage.
- *
- * Returns: (allow-none): the uri which identifies trust storage slot
- */
-const gchar*
-gcr_pkcs11_get_trust_store_uri (void)
-{
- initialize_uris ();
- return trust_store_uri;
-}
-
-/**
- * gcr_pkcs11_set_trust_store_uri:
- * @pkcs11_uri: (allow-none): the uri which identifies trust storage slot
- *
- * Set the PKCS\#11 URI that is used to identify which slot to use for
- * storing trust assertions.
- *
- * It is not normally necessary to call this function. The relevant
- * PKCS\#11 slot is automatically configured by the GCR library.
- */
-void
-gcr_pkcs11_set_trust_store_uri (const gchar *pkcs11_uri)
-{
- G_LOCK (uris);
-
- g_free (trust_store_uri);
- trust_store_uri = g_strdup (pkcs11_uri);
- initialized_uris = TRUE;
-
- G_UNLOCK (uris);
-}
-
-
-/**
- * gcr_pkcs11_get_trust_lookup_uris:
- *
- * Get the PKCS\#11 URIs that are used to identify which slots to use for
- * lookup trust assertions.
- *
- * Returns: (allow-none) (transfer none): the uri which identifies trust storage slot
- */
-const gchar **
-gcr_pkcs11_get_trust_lookup_uris (void)
-{
- initialize_uris ();
- return (const gchar **)trust_lookup_uris;
-}
-
-/**
- * gcr_pkcs11_set_trust_lookup_uris:
- * @pkcs11_uris: (allow-none): the uris which identifies trust lookup slots
- *
- * Set the PKCS\#11 URIs that are used to identify which slots to use for
- * lookup of trust assertions.
- *
- * It is not normally necessary to call this function. The relevant
- * PKCS\#11 slots are automatically configured by the GCR library.
- */
-void
-gcr_pkcs11_set_trust_lookup_uris (const gchar **pkcs11_uris)
-{
- G_LOCK (uris);
-
- g_strfreev (trust_lookup_uris);
- trust_lookup_uris = g_strdupv ((gchar**)pkcs11_uris);
- initialized_uris = TRUE;
-
- G_UNLOCK (uris);
-}
diff --git a/gcr/gcr-library.h b/gcr/gcr-library.h
deleted file mode 100644
index 617a580b..00000000
--- a/gcr/gcr-library.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_LIBRARY_H_
-#define GCR_LIBRARY_H_
-
-#include "gcr-types.h"
-
-#include <glib.h>
-
-void gcr_pkcs11_initialize_async (GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_pkcs11_initialize_finish (GAsyncResult *result,
- GError **error);
-
-gboolean gcr_pkcs11_initialize (GCancellable *cancellable,
- GError **error);
-
-GList* gcr_pkcs11_get_modules (void);
-
-void gcr_pkcs11_set_modules (GList *modules);
-
-void gcr_pkcs11_add_module (GckModule *module);
-
-gboolean gcr_pkcs11_add_module_from_file (const gchar *module_path,
- gpointer unused,
- GError **error);
-
-GList* gcr_pkcs11_get_trust_lookup_slots (void);
-
-GckSlot* gcr_pkcs11_get_trust_store_slot (void);
-
-const gchar** gcr_pkcs11_get_trust_lookup_uris (void);
-
-void gcr_pkcs11_set_trust_lookup_uris (const gchar **pkcs11_uris);
-
-const gchar* gcr_pkcs11_get_trust_store_uri (void);
-
-void gcr_pkcs11_set_trust_store_uri (const gchar *pkcs11_uri);
-
-#endif /* GCR_LIBRARY_H_ */
diff --git a/gcr/gcr-list-selector-private.h b/gcr/gcr-list-selector-private.h
deleted file mode 100644
index 5f73e0b7..00000000
--- a/gcr/gcr-list-selector-private.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_LIST_SELECTOR_PRIVATE_H__
-#define __GCR_LIST_SELECTOR_PRIVATE_H__
-
-#include "gcr-types.h"
-#include "gcr-list-selector.h"
-#include "gcr-live-search.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-void _gcr_list_selector_set_live_search (GcrListSelector *self,
- GcrLiveSearch *search);
-
-G_END_DECLS
-
-#endif /* __GCR_LIST_SELECTOR_PRIVATE_H__ */
diff --git a/gcr/gcr-list-selector.c b/gcr/gcr-list-selector.c
deleted file mode 100644
index 87d354ea..00000000
--- a/gcr/gcr-list-selector.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2011 Collabora Ltd.
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-collection-model.h"
-#include "gcr-internal.h"
-#include "gcr-list-selector.h"
-#include "gcr-list-selector-private.h"
-#include "gcr-live-search.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <string.h>
-
-/**
- * SECTION:gcr-list-selector
- * @title: GcrListSelector
- * @short_description: A selector widget to one or more certificates from a list.
- *
- * The #GcrListSelector can be used to select one or more certificates or keys.
- * Live search is available for quick filtering.
- */
-
-/**
- * GcrListSelector:
- *
- * A list selector widget.
- */
-
-/**
- * GcrListSelectorClass:
- *
- * The class for #GcrListSelector.
- */
-
-enum {
- PROP_0,
- PROP_COLLECTION
-};
-
-struct _GcrListSelectorPrivate {
- GcrCollection *collection;
- GcrCollectionModel *model;
-
- GtkTreeModelFilter *filter;
- GtkWidget *search_widget;
-};
-
-G_DEFINE_TYPE (GcrListSelector, gcr_list_selector, GTK_TYPE_TREE_VIEW);
-
-static gboolean
-object_is_visible (GcrListSelector *self, GObject *object)
-{
- gchar *text;
- gboolean visible;
-
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), "search-text"))
- g_object_get (object, "search-text", &text, NULL);
- else
- g_object_get (object, "label", &text, NULL);
-
- visible = _gcr_live_search_match (GCR_LIVE_SEARCH (self->pv->search_widget), text);
- g_free (text);
-
- return visible;
-}
-
-static gboolean
-on_tree_filter_visible_func (GtkTreeModel *model, GtkTreeIter *iter,
- gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (user_data);
- GObject *object;
-
- if (self->pv->search_widget == NULL ||
- !gtk_widget_get_visible (self->pv->search_widget))
- return TRUE;
-
- object = gcr_collection_model_object_for_iter (self->pv->model, iter);
- if (object != NULL)
- return object_is_visible (self, object);
-
- return FALSE;
-}
-
-static gboolean
-on_tree_view_start_search (GtkTreeView *view, gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (view);
-
- if (self->pv->search_widget == NULL)
- return FALSE;
-
- if (gtk_widget_get_visible (self->pv->search_widget))
- gtk_widget_grab_focus (self->pv->search_widget);
- else
- gtk_widget_show (self->pv->search_widget);
-
- return TRUE;
-}
-
-static void
-on_search_widget_text_notify (GcrLiveSearch *search, GParamSpec *pspec,
- gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (user_data);
-#if 0
- GtkTreeViewColumn *focus_column;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
- gboolean set_cursor = FALSE;
-#endif
-
- gtk_tree_model_filter_refilter (self->pv->filter);
-
-#if 0
- /* Set cursor on the first object. */
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
- gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &path, &focus_column);
-
- if (path == NULL) {
- path = gtk_tree_path_new_from_string ("0");
- set_cursor = TRUE;
- }
-
- if (set_cursor) {
- /* FIXME: Workaround for GTK bug #621651, we have to make sure
- * the path is valid. */
- if (gtk_tree_model_get_iter (model, &iter, path)) {
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
- focus_column, FALSE);
- }
- }
-
- gtk_tree_path_free (path);
-#endif
-}
-
-static void
-on_search_widget_activate (GtkWidget *search, gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (user_data);
- GtkTreePath *path;
- GtkTreeViewColumn *focus_column;
-
- gtk_tree_view_get_cursor (GTK_TREE_VIEW (self), &path, &focus_column);
- if (path != NULL) {
- gtk_tree_view_row_activated (GTK_TREE_VIEW (self), path, focus_column);
- gtk_tree_path_free (path);
-
- gtk_widget_hide (search);
- }
-}
-
-static gboolean
-on_search_widget_key_navigation (GtkWidget *search, GdkEvent *event, gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (user_data);
- GdkEvent *new_event;
- gboolean ret = FALSE;
-
- new_event = gdk_event_copy (event);
- gtk_widget_grab_focus (GTK_WIDGET (self));
- ret = gtk_widget_event (GTK_WIDGET (self), new_event);
- gtk_widget_grab_focus (search);
-
- gdk_event_free (new_event);
-
- return ret;
-}
-
-static void
-on_check_column_toggled (GtkCellRendererToggle *cell, gchar *path, gpointer user_data)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (user_data);
- GtkTreeIter iter, model_iter;
-
- g_assert (path != NULL);
-
- if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (self->pv->filter), &iter, path)) {
- gtk_tree_model_filter_convert_iter_to_child_iter (self->pv->filter, &model_iter, &iter);
- gcr_collection_model_toggle_selected (self->pv->model, &model_iter);
- }
-}
-
-static void
-gcr_list_selector_constructed (GObject *object)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (object);
- GtkCellRenderer *cell;
- GtkTreeViewColumn *column;
- guint column_id;
-
- G_OBJECT_CLASS (gcr_list_selector_parent_class)->constructed (object);
-
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self), FALSE);
-
- self->pv->model = gcr_collection_model_new (self->pv->collection,
- "icon", G_TYPE_ICON,
- "markup", G_TYPE_STRING,
- NULL);
-
- self->pv->filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (
- GTK_TREE_MODEL (self->pv->model), NULL));
- gtk_tree_model_filter_set_visible_func (self->pv->filter,
- on_tree_filter_visible_func, self, NULL);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (self), GTK_TREE_MODEL (self->pv->filter));
-
- /* The check */
-
- cell = gtk_cell_renderer_toggle_new ();
- g_signal_connect (cell, "toggled", G_CALLBACK (on_check_column_toggled), self);
-
- column_id = gcr_collection_model_column_for_selected (self->pv->model);
- column = gtk_tree_view_column_new_with_attributes ("", cell, "active", column_id, NULL);
- gtk_tree_view_column_set_resizable (column, FALSE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
-
- column = gtk_tree_view_column_new ();
-
- /* The icon */
- cell = gtk_cell_renderer_pixbuf_new ();
- g_object_set (cell, "stock-size", GTK_ICON_SIZE_DND, NULL);
- gtk_tree_view_column_pack_start (column, cell, FALSE);
- gtk_tree_view_column_add_attribute (column, cell, "gicon", 0);
-
- /* The markup */
- cell = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, cell, TRUE);
- gtk_tree_view_column_add_attribute (column, cell, "markup", 1);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
-}
-
-static void
-gcr_list_selector_init (GcrListSelector *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_LIST_SELECTOR, GcrListSelectorPrivate);
-}
-
-static void
-gcr_list_selector_dispose (GObject *obj)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (obj);
-
- if (self->pv->filter)
- g_object_unref (self->pv->filter);
- self->pv->filter = NULL;
-
- if (self->pv->model)
- g_object_unref (self->pv->model);
- self->pv->model = NULL;
-
- if (self->pv->collection)
- g_object_unref (self->pv->collection);
- self->pv->collection = NULL;
-
- _gcr_list_selector_set_live_search (self, NULL);
-
- G_OBJECT_CLASS (gcr_list_selector_parent_class)->dispose (obj);
-}
-
-static void
-gcr_list_selector_finalize (GObject *obj)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (obj);
-
- g_assert (!self->pv->collection);
- g_assert (!self->pv->model);
-
- G_OBJECT_CLASS (gcr_list_selector_parent_class)->finalize (obj);
-}
-
-static void
-gcr_list_selector_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (obj);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_return_if_fail (!self->pv->collection);
- self->pv->collection = g_value_dup_object (value);
- g_return_if_fail (self->pv->collection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_list_selector_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrListSelector *self = GCR_LIST_SELECTOR (obj);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_value_set_object (value, gcr_list_selector_get_collection (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_list_selector_class_init (GcrListSelectorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructed = gcr_list_selector_constructed;
- gobject_class->dispose = gcr_list_selector_dispose;
- gobject_class->finalize = gcr_list_selector_finalize;
- gobject_class->set_property = gcr_list_selector_set_property;
- gobject_class->get_property = gcr_list_selector_get_property;
-
- g_type_class_add_private (gobject_class, sizeof (GcrListSelectorPrivate));
-
- /**
- * GcrListSelector:collection:
- *
- * The collection which contains the objects to display in the selector.
- */
- g_object_class_install_property (gobject_class, PROP_COLLECTION,
- g_param_spec_object ("collection", "Collection", "Collection to select from",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_list_selector_new:
- * @collection: The collection that contains the objects to display
- *
- * Create a new #GcrListSelector.
- *
- * Returns: (transfer full): a newly allocated selector, which should be
- * released with g_object_unref()
- */
-GcrListSelector *
-gcr_list_selector_new (GcrCollection *collection)
-{
- return g_object_new (GCR_TYPE_LIST_SELECTOR,
- "collection", collection,
- NULL);
-}
-
-/**
- * gcr_list_selector_get_collection:
- * @self: The selector
- *
- * Get the collection that this selector is displaying objects from.
- *
- * Returns: (transfer none): The collection, owned by the selector.
- */
-GcrCollection *
-gcr_list_selector_get_collection (GcrListSelector *self)
-{
- g_return_val_if_fail (GCR_IS_LIST_SELECTOR (self), NULL);
- return self->pv->collection;
-}
-
-/**
- * gcr_list_selector_get_selected:
- * @self: The selector
- *
- * Get a list of selected objects.
- *
- * Returns: (transfer container) (element-type GLib.Object): the list of
- * selected objects, to be released with g_list_free()
- */
-GList*
-gcr_list_selector_get_selected (GcrListSelector *self)
-{
- g_return_val_if_fail (GCR_IS_LIST_SELECTOR (self), NULL);
- return gcr_collection_model_get_selected_objects (self->pv->model);
-}
-
-/**
- * gcr_list_selector_set_selected:
- * @self: The selector
- * @selected: (element-type GLib.Object): the list of objects to select
- *
- * Select certain objects in the selector.
- */
-void
-gcr_list_selector_set_selected (GcrListSelector *self, GList *selected)
-{
- g_return_if_fail (GCR_IS_LIST_SELECTOR (self));
- gcr_collection_model_set_selected_objects (self->pv->model, selected);
-}
-
-
-void
-_gcr_list_selector_set_live_search (GcrListSelector *self, GcrLiveSearch *search)
-{
- g_return_if_fail (GCR_IS_LIST_SELECTOR (self));
-
- /* remove old handlers if old search was not null */
- if (self->pv->search_widget != NULL) {
- g_signal_handlers_disconnect_by_func (self, on_tree_view_start_search, NULL);
-
- g_signal_handlers_disconnect_by_func (self->pv->search_widget,
- on_search_widget_text_notify, self);
- g_signal_handlers_disconnect_by_func (self->pv->search_widget,
- on_search_widget_activate, self);
- g_signal_handlers_disconnect_by_func (self->pv->search_widget,
- on_search_widget_key_navigation, self);
- g_object_unref (self->pv->search_widget);
- self->pv->search_widget = NULL;
- }
-
- /* connect handlers if new search is not null */
- if (search != NULL) {
- self->pv->search_widget = g_object_ref (search);
-
- g_signal_connect (self, "start-interactive-search",
- G_CALLBACK (on_tree_view_start_search), NULL);
-
- g_signal_connect (self->pv->search_widget, "notify::text",
- G_CALLBACK (on_search_widget_text_notify), self);
- g_signal_connect (self->pv->search_widget, "activate",
- G_CALLBACK (on_search_widget_activate), self);
- g_signal_connect (self->pv->search_widget, "key-navigation",
- G_CALLBACK (on_search_widget_key_navigation), self);
- }
-}
diff --git a/gcr/gcr-list-selector.h b/gcr/gcr-list-selector.h
deleted file mode 100644
index e109167d..00000000
--- a/gcr/gcr-list-selector.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2011 Collabora Ltd.
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_LIST_SELECTOR_H__
-#define __GCR_LIST_SELECTOR_H__
-
-#include "gcr-types.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_LIST_SELECTOR (gcr_list_selector_get_type ())
-#define GCR_LIST_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_LIST_SELECTOR, GcrListSelector))
-#define GCR_LIST_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_LIST_SELECTOR, GcrListSelectorClass))
-#define GCR_IS_LIST_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_LIST_SELECTOR))
-#define GCR_IS_LIST_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_LIST_SELECTOR))
-#define GCR_LIST_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_LIST_SELECTOR, GcrListSelectorClass))
-
-typedef struct _GcrListSelector GcrListSelector;
-typedef struct _GcrListSelectorClass GcrListSelectorClass;
-typedef struct _GcrListSelectorPrivate GcrListSelectorPrivate;
-
-struct _GcrListSelector {
- GtkTreeView parent;
-
- /*< private >*/
- GcrListSelectorPrivate *pv;
-};
-
-struct _GcrListSelectorClass {
-
- /*< private >*/
- GtkTreeViewClass parent_class;
-};
-
-GType gcr_list_selector_get_type (void);
-
-GcrListSelector* gcr_list_selector_new (GcrCollection *collection);
-
-GcrCollection* gcr_list_selector_get_collection (GcrListSelector *self);
-
-GList* gcr_list_selector_get_selected (GcrListSelector *self);
-
-void gcr_list_selector_set_selected (GcrListSelector *self,
- GList *selected);
-
-G_END_DECLS
-
-#endif /* __GCR_LIST_SELECTOR_H__ */
diff --git a/gcr/gcr-live-search.c b/gcr/gcr-live-search.c
deleted file mode 100644
index ef1919cb..00000000
--- a/gcr/gcr-live-search.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * Copyright (C) 2011 Collabora Ltd.
- * Copyright (C) 2010 Collabora Ltd.
- * Copyright (C) 2007-2010 Nokia Corporation.
- *
- * This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Felix Kaser <felix.kaser@collabora.co.uk>
- * Xavier Claessens <xavier.claessens@collabora.co.uk>
- * Claudio Saavedra <csaavedra@igalia.com>
- * Stef Walter <stefw@collabora.co.uk>
- */
-
-/* Code borrowed from Empathy */
-
-#include "config.h"
-
-#include "gcr-live-search.h"
-#include "gcr-marshal.h"
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <string.h>
-
-G_DEFINE_TYPE (GcrLiveSearch, _gcr_live_search, GTK_TYPE_BOX)
-
-struct _GcrLiveSearchPrivate {
- GtkWidget *search_entry;
- GtkWidget *hook_widget;
- GPtrArray *stripped_words;
-};
-
-enum {
- PROP_0,
- PROP_HOOK_WIDGET,
- PROP_TEXT
-};
-
-enum {
- ACTIVATE,
- KEYNAV,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void on_hook_widget_destroy (GtkWidget *object, gpointer user_data);
-
-static gunichar
-stripped_char (gunichar ch)
-{
- gunichar retval = 0;
- GUnicodeType utype;
-#if GLIB_CHECK_VERSION (2,29,90)
- gunichar decomp[4];
-#else
- gunichar *decomp;
-#endif
- gsize dlen;
-
- utype = g_unichar_type (ch);
-
- switch (utype) {
- case G_UNICODE_CONTROL:
- case G_UNICODE_FORMAT:
- case G_UNICODE_UNASSIGNED:
- case G_UNICODE_NON_SPACING_MARK:
-#if GLIB_CHECK_VERSION (2,29,90)
- case G_UNICODE_SPACING_MARK:
-#else
- case G_UNICODE_COMBINING_MARK:
-#endif
- case G_UNICODE_ENCLOSING_MARK:
- /* Ignore those */
- break;
- case G_UNICODE_PRIVATE_USE:
- case G_UNICODE_SURROGATE:
- case G_UNICODE_LOWERCASE_LETTER:
- case G_UNICODE_MODIFIER_LETTER:
- case G_UNICODE_OTHER_LETTER:
- case G_UNICODE_TITLECASE_LETTER:
- case G_UNICODE_UPPERCASE_LETTER:
- case G_UNICODE_DECIMAL_NUMBER:
- case G_UNICODE_LETTER_NUMBER:
- case G_UNICODE_OTHER_NUMBER:
- case G_UNICODE_CONNECT_PUNCTUATION:
- case G_UNICODE_DASH_PUNCTUATION:
- case G_UNICODE_CLOSE_PUNCTUATION:
- case G_UNICODE_FINAL_PUNCTUATION:
- case G_UNICODE_INITIAL_PUNCTUATION:
- case G_UNICODE_OTHER_PUNCTUATION:
- case G_UNICODE_OPEN_PUNCTUATION:
- case G_UNICODE_CURRENCY_SYMBOL:
- case G_UNICODE_MODIFIER_SYMBOL:
- case G_UNICODE_MATH_SYMBOL:
- case G_UNICODE_OTHER_SYMBOL:
- case G_UNICODE_LINE_SEPARATOR:
- case G_UNICODE_PARAGRAPH_SEPARATOR:
- case G_UNICODE_SPACE_SEPARATOR:
- default:
- ch = g_unichar_tolower (ch);
-#if GLIB_CHECK_VERSION (2,29,90)
- dlen = g_unichar_fully_decompose (ch, FALSE, decomp, 4);
- if (dlen > 0) {
-#else
- decomp = g_unicode_canonical_decomposition (ch, &dlen);
- if (decomp != NULL) {
-#endif
- retval = decomp[0];
-#if !GLIB_CHECK_VERSION (2,29,90)
- g_free (decomp);
-#endif
- }
- }
-
- return retval;
-}
-
-static void
-append_word (GPtrArray **word_array, GString **word)
-{
- if (*word != NULL) {
- if (*word_array == NULL)
- *word_array = g_ptr_array_new_with_free_func (g_free);
- g_ptr_array_add (*word_array, g_string_free (*word, FALSE));
- *word = NULL;
- }
-}
-
-GPtrArray *
-_gcr_live_search_strip_utf8_string (const gchar *string)
-{
- GPtrArray *word_array = NULL;
- GString *word = NULL;
- const gchar *p;
-
- if (string == NULL || *string == '\0')
- return NULL;
-
- for (p = string; *p != '\0'; p = g_utf8_next_char (p)) {
- gunichar sc;
-
- /* Make the char lower-case, remove its accentuation marks, and ignore it
- * if it is just unicode marks */
- sc = stripped_char (g_utf8_get_char (p));
- if (sc == 0)
- continue;
-
- /* If it is not alpha-num, it is separator between words */
- if (!g_unichar_isalnum (sc)) {
- append_word (&word_array, &word);
- continue;
- }
-
- /* It is alpha-num, append this char to current word, or start new word */
- if (word == NULL)
- word = g_string_new (NULL);
- g_string_append_unichar (word, sc);
- }
-
- append_word (&word_array, &word);
-
- return word_array;
-}
-
-static gboolean
-live_search_match_prefix (const gchar *string, const gchar *prefix)
-{
- const gchar *p;
- const gchar *prefix_p;
- gboolean next_word = FALSE;
-
- if (prefix == NULL || prefix[0] == 0)
- return TRUE;
-
- if (string == NULL || *string == '\0')
- return FALSE;
-
- prefix_p = prefix;
- for (p = string; *p != '\0'; p = g_utf8_next_char (p)) {
- gunichar sc;
-
- /* Make the char lower-case, remove its accentuation marks, and ignore it
- * if it is just unicode marks */
- sc = stripped_char (g_utf8_get_char (p));
- if (sc == 0)
- continue;
-
- /* If we want to go to next word, ignore alpha-num chars */
- if (next_word && g_unichar_isalnum (sc))
- continue;
- next_word = FALSE;
-
- /* Ignore word separators */
- if (!g_unichar_isalnum (sc))
- continue;
-
- /* If this char does not match prefix_p, go to next word and start again
- * from the beginning of prefix */
- if (sc != g_utf8_get_char (prefix_p)) {
- next_word = TRUE;
- prefix_p = prefix;
- continue;
- }
-
- /* prefix_p match, verify to next char. If this was the last of prefix,
- * it means it completely machted and we are done. */
- prefix_p = g_utf8_next_char (prefix_p);
- if (*prefix_p == '\0')
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean
-_gcr_live_search_match_words (const gchar *string, GPtrArray *words)
-{
- guint i;
-
- if (words == NULL)
- return TRUE;
-
- for (i = 0; i < words->len; i++)
- if (!live_search_match_prefix (string, g_ptr_array_index (words, i)))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-fire_key_navigation_sig (GcrLiveSearch *self, GdkEventKey *event)
-{
- gboolean ret;
-
- g_signal_emit (self, signals[KEYNAV], 0, event, &ret);
- return ret;
-}
-
-static gboolean
-on_search_entry_key_pressed (GtkEntry *entry, GdkEventKey *event, gpointer user_data)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (user_data);
-
- /* if esc key pressed, hide the search */
- if (event->keyval == GDK_KEY_Escape) {
- gtk_widget_hide (GTK_WIDGET (self));
- return TRUE;
- }
-
- /* emit key navigation signal, so other widgets can respond to it properly */
- if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down
- || event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_Page_Down) {
- return fire_key_navigation_sig (self, event);
- }
-
- if (event->keyval == GDK_KEY_Home || event->keyval == GDK_KEY_End ||
- event->keyval == GDK_KEY_space) {
- /* If the live search is visible, the entry should catch the Home/End
- * and space events */
- if (!gtk_widget_get_visible (GTK_WIDGET (self))) {
- return fire_key_navigation_sig (self, event);
- }
- }
-
- return FALSE;
-}
-
-static void
-on_search_entry_text_changed (GtkEntry *entry, gpointer user_data)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (user_data);
- const gchar *text;
-
- text = gtk_entry_get_text (entry);
-
- if (text == NULL || *text == '\0')
- gtk_widget_hide (GTK_WIDGET (self));
- else
- gtk_widget_show (GTK_WIDGET (self));
-
- if (self->pv->stripped_words != NULL)
- g_ptr_array_unref (self->pv->stripped_words);
-
- self->pv->stripped_words = _gcr_live_search_strip_utf8_string (text);
-
- g_object_notify (G_OBJECT (self), "text");
-}
-
-static void
-on_search_entry_close_pressed (GtkEntry *entry, GtkEntryIconPosition icon_pos,
- GdkEvent *event, gpointer user_data)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (user_data);
- gtk_widget_hide (GTK_WIDGET (self));
-}
-
-static gboolean
-on_hook_widget_key_press_event (GtkWidget *widget, GdkEventKey *event,
- gpointer user_data)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (user_data);
- GdkEvent *new_event;
- gboolean ret;
-
- /* dont forward this event to the entry, else the event is consumed by the
- * entry and does not close the window */
- if (!gtk_widget_get_visible (GTK_WIDGET (self)) &&
- event->keyval == GDK_KEY_Escape)
- return FALSE;
-
- /* do not show the search if CTRL and/or ALT are pressed with a key
- * this is needed, because otherwise the CTRL + F accel would not work,
- * because the entry consumes it */
- if (event->state & (GDK_MOD1_MASK | GDK_CONTROL_MASK) ||
- event->keyval == GDK_KEY_Control_L ||
- event->keyval == GDK_KEY_Control_R)
- return FALSE;
-
- /* dont forward the up/down and Page Up/Down arrow keys to the entry,
- * they are needed for navigation in the treeview and are not needed in
- * the search entry */
- if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down ||
- event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_Page_Down)
- return FALSE;
-
- if (event->keyval == GDK_KEY_Home || event->keyval == GDK_KEY_End ||
- event->keyval == GDK_KEY_space) {
- /* Home/End and space keys have to be forwarded to the entry only if
- * the live search is visible (to move the cursor inside the entry). */
- if (!gtk_widget_get_visible (GTK_WIDGET (self)))
- return FALSE;
- }
-
- /* realize the widget if it is not realized yet */
- gtk_widget_realize (self->pv->search_entry);
- if (!gtk_widget_has_focus (self->pv->search_entry)) {
- gtk_widget_grab_focus (self->pv->search_entry);
- gtk_editable_set_position (GTK_EDITABLE (self->pv->search_entry), -1);
- }
-
- /* forward the event to the search entry */
- new_event = gdk_event_copy ((GdkEvent *) event);
- ret = gtk_widget_event (self->pv->search_entry, new_event);
- gdk_event_free (new_event);
-
- return ret;
-}
-
-static void
-on_search_entry_activate (GtkEntry *entry, GcrLiveSearch *self)
-{
- g_signal_emit (self, signals[ACTIVATE], 0);
-}
-
-static void
-live_search_release_hook_widget (GcrLiveSearch *self)
-{
- /* remove old handlers if old source was not null */
- if (self->pv->hook_widget != NULL) {
- g_signal_handlers_disconnect_by_func (self->pv->hook_widget,
- on_hook_widget_key_press_event, self);
- g_signal_handlers_disconnect_by_func (self->pv->hook_widget,
- on_hook_widget_destroy, self);
- g_object_unref (self->pv->hook_widget);
- self->pv->hook_widget = NULL;
- }
-}
-
-static void
-on_hook_widget_destroy (GtkWidget *object, gpointer user_data)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (user_data);
-
- /* unref the hook widget and hide search */
- gtk_widget_hide (GTK_WIDGET (self));
- live_search_release_hook_widget (self);
-}
-
-static void
-live_search_dispose (GObject *obj)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (obj);
-
- live_search_release_hook_widget (self);
-
- G_OBJECT_CLASS (_gcr_live_search_parent_class)->dispose (obj);
-}
-
-static void
-live_search_finalize (GObject *obj)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (obj);
-
- if (self->pv->stripped_words != NULL)
- g_ptr_array_unref (self->pv->stripped_words);
-
- G_OBJECT_CLASS (_gcr_live_search_parent_class)->finalize (obj);
-}
-
-static void
-live_search_get_property (GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (object);
-
- switch (param_id) {
- case PROP_HOOK_WIDGET:
- g_value_set_object (value, _gcr_live_search_get_hook_widget (self));
- break;
- case PROP_TEXT:
- g_value_set_string (value, _gcr_live_search_get_text (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-live_search_set_property (GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (object);
-
- switch (param_id) {
- case PROP_HOOK_WIDGET:
- _gcr_live_search_set_hook_widget (self, g_value_get_object (value));
- break;
- case PROP_TEXT:
- _gcr_live_search_set_text (self, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- };
-}
-
-static void
-live_search_unmap (GtkWidget *widget)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (widget);
-
- GTK_WIDGET_CLASS (_gcr_live_search_parent_class)->unmap (widget);
-
- /* unmap can happen if a parent gets hidden, in that case we want to hide
- * the live search as well, so when it gets mapped again, the live search
- * won't be shown. */
- gtk_widget_hide (widget);
-
- gtk_entry_set_text (GTK_ENTRY (self->pv->search_entry), "");
- gtk_widget_grab_focus (self->pv->hook_widget);
-}
-
-static void
-live_search_show (GtkWidget *widget)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (widget);
-
- if (!gtk_widget_has_focus (self->pv->search_entry))
- gtk_widget_grab_focus (self->pv->search_entry);
-
- GTK_WIDGET_CLASS (_gcr_live_search_parent_class)->show (widget);
-}
-
-static void
-live_search_grab_focus (GtkWidget *widget)
-{
- GcrLiveSearch *self = GCR_LIVE_SEARCH (widget);
-
- if (!gtk_widget_has_focus (self->pv->search_entry)) {
- gtk_widget_grab_focus (self->pv->search_entry);
- gtk_editable_set_position (GTK_EDITABLE (self->pv->search_entry), -1);
- }
-}
-
-static void
-_gcr_live_search_class_init (GcrLiveSearchClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
- GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
- GParamSpec *param_spec;
-
- object_class->finalize = live_search_finalize;
- object_class->dispose = live_search_dispose;
- object_class->get_property = live_search_get_property;
- object_class->set_property = live_search_set_property;
-
- widget_class->unmap = live_search_unmap;
- widget_class->show = live_search_show;
- widget_class->grab_focus = live_search_grab_focus;
-
- signals[ACTIVATE] = g_signal_new ("activate",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[KEYNAV] = g_signal_new ("key-navigation",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- 0,
- g_signal_accumulator_true_handled, NULL,
- _gcr_marshal_BOOLEAN__BOXED,
- G_TYPE_BOOLEAN, 1, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- param_spec = g_param_spec_object ("hook-widget", "Live Search Hook Widget",
- "The live search catches key-press-events on this widget",
- GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_HOOK_WIDGET, param_spec);
-
- param_spec = g_param_spec_string ("text", "Live Search Text",
- "The text of the live search entry",
- "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TEXT, param_spec);
-
- g_type_class_add_private (klass, sizeof (GcrLiveSearchPrivate));
-}
-
-static void
-_gcr_live_search_init (GcrLiveSearch *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE ((self), GCR_TYPE_LIVE_SEARCH,
- GcrLiveSearchPrivate);
-
- gtk_widget_set_no_show_all (GTK_WIDGET (self), TRUE);
-
- self->pv->search_entry = gtk_entry_new ();
- gtk_entry_set_icon_from_stock (GTK_ENTRY (self->pv->search_entry),
- GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLOSE);
- gtk_entry_set_icon_activatable (GTK_ENTRY (self->pv->search_entry),
- GTK_ENTRY_ICON_SECONDARY, TRUE);
- gtk_entry_set_icon_sensitive (GTK_ENTRY (self->pv->search_entry),
- GTK_ENTRY_ICON_SECONDARY, TRUE);
- gtk_widget_show (self->pv->search_entry);
-
- gtk_box_pack_start (GTK_BOX (self), self->pv->search_entry, TRUE, TRUE, 0);
-
- g_signal_connect (self->pv->search_entry, "icon_release",
- G_CALLBACK (on_search_entry_close_pressed), self);
- g_signal_connect (self->pv->search_entry, "changed",
- G_CALLBACK (on_search_entry_text_changed), self);
- g_signal_connect (self->pv->search_entry, "key-press-event",
- G_CALLBACK (on_search_entry_key_pressed), self);
- g_signal_connect (self->pv->search_entry, "activate",
- G_CALLBACK (on_search_entry_activate), self);
-
- self->pv->hook_widget = NULL;
-}
-
-/**
- * _gcr_live_search_new:
- * @hook: (allow-none): the widget to hook
- *
- * Returns: (transfer full) (type Gcr.LiveSearch): The new widget
- */
-GtkWidget *
-_gcr_live_search_new (GtkWidget *hook)
-{
- g_return_val_if_fail (hook == NULL || GTK_IS_WIDGET (hook), NULL);
-
- return g_object_new (GCR_TYPE_LIVE_SEARCH,
- "hook-widget", hook,
- NULL);
-}
-
-/* public methods */
-
-GtkWidget *
-_gcr_live_search_get_hook_widget (GcrLiveSearch *self)
-{
- g_return_val_if_fail (GCR_IS_LIVE_SEARCH (self), NULL);
-
- return self->pv->hook_widget;
-}
-
-void
-_gcr_live_search_set_hook_widget (GcrLiveSearch *self, GtkWidget *hook)
-{
- g_return_if_fail (GCR_IS_LIVE_SEARCH (self));
- g_return_if_fail (hook == NULL || GTK_IS_WIDGET (hook));
-
- /* release the actual widget */
- live_search_release_hook_widget (self);
-
- /* connect handlers if new source is not null */
- if (hook != NULL) {
- self->pv->hook_widget = g_object_ref (hook);
- g_signal_connect (self->pv->hook_widget, "key-press-event",
- G_CALLBACK (on_hook_widget_key_press_event),
- self);
- g_signal_connect (self->pv->hook_widget, "destroy",
- G_CALLBACK (on_hook_widget_destroy),
- self);
- }
-}
-
-const gchar *
-_gcr_live_search_get_text (GcrLiveSearch *self)
-{
- g_return_val_if_fail (GCR_IS_LIVE_SEARCH (self), NULL);
-
- return gtk_entry_get_text (GTK_ENTRY (self->pv->search_entry));
-}
-
-void
-_gcr_live_search_set_text (GcrLiveSearch *self, const gchar *text)
-{
- g_return_if_fail (GCR_IS_LIVE_SEARCH (self));
- g_return_if_fail (text != NULL);
-
- gtk_entry_set_text (GTK_ENTRY (self->pv->search_entry), text);
-}
-
-/**
- * _gcr_live_search_match:
- * @self: a #GcrLiveSearch
- * @string: a string where to search, must be valid UTF-8.
- *
- * Search if one of the words in @string string starts with the current text
- * of @self.
- *
- * Searching for "aba" in "Abasto" will match, searching in "Moraba" will not,
- * and searching in "A tool (abacus)" will do.
- *
- * The match is not case-sensitive, and regardless of the accentuation marks.
- *
- * Returns: %TRUE if a match is found, %FALSE otherwise.
- *
- **/
-gboolean
-_gcr_live_search_match (GcrLiveSearch *self, const gchar *string)
-{
- g_return_val_if_fail (GCR_IS_LIVE_SEARCH (self), FALSE);
-
- return _gcr_live_search_match_words (string, self->pv->stripped_words);
-}
-
-gboolean
-_gcr_live_search_match_string (const gchar *string, const gchar *prefix)
-{
- GPtrArray *words;
- gboolean match;
-
- words = _gcr_live_search_strip_utf8_string (prefix);
- match = _gcr_live_search_match_words (string, words);
- if (words != NULL)
- g_ptr_array_unref (words);
-
- return match;
-}
-
-GPtrArray *
-_gcr_live_search_get_words (GcrLiveSearch *self)
-{
- return self->pv->stripped_words;
-}
diff --git a/gcr/gcr-live-search.h b/gcr/gcr-live-search.h
deleted file mode 100644
index cf048fd9..00000000
--- a/gcr/gcr-live-search.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2011 Collabora Ltd.
- * Copyright (C) 2010 Collabora Ltd.
- * Copyright (C) 2007-2010 Nokia Corporation.
- *
- * This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Felix Kaser <felix.kaser@collabora.co.uk>
- * Xavier Claessens <xavier.claessens@collabora.co.uk>
- * Claudio Saavedra <csaavedra@igalia.com>
- * Stef Walter <stefw@collabora.co.uk>
- */
-
-/* Code borrowed from Empathy */
-
-#ifndef __GCR_LIVE_SEARCH_H__
-#define __GCR_LIVE_SEARCH_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_LIVE_SEARCH (_gcr_live_search_get_type ())
-#define GCR_LIVE_SEARCH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GCR_TYPE_LIVE_SEARCH, GcrLiveSearch))
-#define GCR_LIVE_SEARCH_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GCR_TYPE_LIVE_SEARCH, GcrLiveSearchClass))
-#define GCR_IS_LIVE_SEARCH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GCR_TYPE_LIVE_SEARCH))
-#define GCR_IS_LIVE_SEARCH_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GCR_TYPE_LIVE_SEARCH))
-#define GCR_LIVE_SEARCH_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GCR_TYPE_LIVE_SEARCH, GcrLiveSearchClass))
-
-typedef struct _GcrLiveSearch GcrLiveSearch;
-typedef struct _GcrLiveSearchClass GcrLiveSearchClass;
-typedef struct _GcrLiveSearchPrivate GcrLiveSearchPrivate;
-
-struct _GcrLiveSearch {
- /*< private >*/
- GtkBox parent;
- GcrLiveSearchPrivate *pv;
-};
-
-struct _GcrLiveSearchClass {
- GtkBoxClass parent_class;
-};
-
-GType _gcr_live_search_get_type (void) G_GNUC_CONST;
-
-GtkWidget * _gcr_live_search_new (GtkWidget *hook);
-
-GtkWidget * _gcr_live_search_get_hook_widget (GcrLiveSearch *self);
-void _gcr_live_search_set_hook_widget (GcrLiveSearch *self,
- GtkWidget *hook);
-
-const gchar * _gcr_live_search_get_text (GcrLiveSearch *self);
-void _gcr_live_search_set_text (GcrLiveSearch *self,
- const gchar *text);
-
-gboolean _gcr_live_search_match (GcrLiveSearch *self,
- const gchar *string);
-
-GPtrArray * _gcr_live_search_strip_utf8_string (const gchar *string);
-
-gboolean _gcr_live_search_match_words (const gchar *string,
- GPtrArray *words);
-
-GPtrArray * _gcr_live_search_get_words (GcrLiveSearch *self);
-
-/* Made public for unit tests */
-gboolean _gcr_live_search_match_string (const gchar *string,
- const gchar *prefix);
-
-G_END_DECLS
-
-#endif /* __GCR_LIVE_SEARCH_H__ */
diff --git a/gcr/gcr-marshal.list b/gcr/gcr-marshal.list
deleted file mode 100644
index 5e36589b..00000000
--- a/gcr/gcr-marshal.list
+++ /dev/null
@@ -1,7 +0,0 @@
-BOOLEAN:INT
-BOOLEAN:BOXED
-VOID:STRING,BOXED
-VOID:BOXED
-VOID:STRING
-VOID:OBJECT,BOXED
-VOID:OBJECT,OBJECT
diff --git a/gcr/gcr-memory-icon.c b/gcr/gcr-memory-icon.c
deleted file mode 100644
index 39713593..00000000
--- a/gcr/gcr-memory-icon.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-memory-icon.h"
-
-#include <string.h>
-
-struct _GcrMemoryIconPrivate {
- gpointer data;
- gsize n_data;
- goffset offset;
- gchar *image_type;
- GDestroyNotify destroy;
-};
-
-/* Forward declarations */
-static void _gcr_memory_icon_iface_icon (GIconIface *iface);
-static void _gcr_memory_icon_iface_loadable_icon (GLoadableIconIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrMemoryIcon, _gcr_memory_icon, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_ICON, _gcr_memory_icon_iface_icon);
- G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, _gcr_memory_icon_iface_loadable_icon);
-);
-
-
-static void
-_gcr_memory_icon_init (GcrMemoryIcon *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_MEMORY_ICON, GcrMemoryIconPrivate));
-}
-
-static void
-_gcr_memory_icon_finalize (GObject *obj)
-{
- GcrMemoryIcon *self = GCR_MEMORY_ICON (obj);
-
- if (self->pv->destroy)
- (self->pv->destroy) (self->pv->data);
- g_free (self->pv->image_type);
-
- G_OBJECT_CLASS (_gcr_memory_icon_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_memory_icon_class_init (GcrMemoryIconClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (GcrMemoryIconPrivate));
-
- gobject_class->finalize = _gcr_memory_icon_finalize;
-}
-
-static gboolean
-_gcr_memory_icon_equal (GIcon *icon1, GIcon *icon2)
-{
- GcrMemoryIcon *one = GCR_MEMORY_ICON (icon1);
- GcrMemoryIcon *two = GCR_MEMORY_ICON (icon2);
-
- if (icon1 == icon2)
- return TRUE;
- if (!g_str_equal (one->pv->image_type, two->pv->image_type))
- return FALSE;
- if ((one->pv->n_data - one->pv->offset) != (two->pv->n_data - two->pv->offset))
- return FALSE;
- return memcmp ((guchar*)one->pv->data + one->pv->offset,
- (guchar*)two->pv->data + two->pv->offset,
- one->pv->n_data - one->pv->offset) == 0;
-}
-
-static guint
-_gcr_memory_icon_hash (GIcon *icon)
-{
- GcrMemoryIcon *self = GCR_MEMORY_ICON (icon);
- const signed char *p, *end;
- guint32 hash;
-
- hash = g_str_hash (self->pv->image_type);
-
- /* Adapted from g_str_hash */
- p = self->pv->data;
- end = p + self->pv->n_data;
- p += self->pv->offset;
- while (p < end)
- hash = (hash << 5) + hash + *(p++);
-
- return hash;
-}
-
-static void
-_gcr_memory_icon_iface_icon (GIconIface *iface)
-{
- iface->equal = _gcr_memory_icon_equal;
- iface->hash = _gcr_memory_icon_hash;
-}
-
-static GInputStream *
-_gcr_memory_icon_load (GLoadableIcon *icon, int size, gchar **type,
- GCancellable *cancellable, GError **error)
-{
- GcrMemoryIcon *self = GCR_MEMORY_ICON (icon);
- GInputStream *is;
-
- if (type != NULL)
- *type = g_strdup (self->pv->image_type);
-
- is = g_memory_input_stream_new_from_data ((guchar*)self->pv->data + self->pv->offset,
- self->pv->n_data, NULL);
-
- /*
- * Hold a reference to this object from the stream, so that we can rely
- * on the data hanging around.
- */
- g_object_set_data_full (G_OBJECT (is), "back-reference", g_object_ref (self),
- g_object_unref);
-
- return is;
-}
-
-static void
-_gcr_memory_icon_load_async (GLoadableIcon *icon, int size, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data,
- _gcr_memory_icon_load_async);
-
- g_simple_async_result_complete_in_idle (res);
- g_object_unref (res);
-}
-
-static GInputStream*
-_gcr_memory_icon_finish (GLoadableIcon *icon, GAsyncResult *res, char **type,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (icon),
- _gcr_memory_icon_load_async), NULL);
- return _gcr_memory_icon_load (icon, 0, type, NULL, error);
-}
-
-
-static void
-_gcr_memory_icon_iface_loadable_icon (GLoadableIconIface *iface)
-{
- iface->load = _gcr_memory_icon_load;
- iface->load_async = _gcr_memory_icon_load_async;
- iface->load_finish = _gcr_memory_icon_finish;
-}
-
-/**
- * _gcr_memory_icon_new:
- * @image_type: MIME content-type of the image.
- * @data: Data for the image.
- * @n_data: Length of data.
- *
- * Create a new GIcon based on image data in memory. The data will be copied
- * by the new icon.
- *
- * Returns: (transfer full) (type Gcr.MemoryIcon): A newly allocated icon.
- */
-GIcon*
-_gcr_memory_icon_new (const gchar *image_type, gconstpointer data, gsize n_data)
-{
- g_return_val_if_fail (image_type != NULL, NULL);
- g_return_val_if_fail (data != NULL, NULL);
- g_return_val_if_fail (n_data != 0, NULL);
-
- return _gcr_memory_icon_new_full (image_type, g_memdup (data, n_data),
- n_data, 0, g_free);
-}
-
-/**
- * _gcr_memory_icon_new_full:
- * @image_type: MIME content-type of the image.
- * @data: Data for the image.
- * @n_data: Length of data.
- * @offset: Offset of the start of the image in @data.
- * @destroy: Callback to free or release @data when no longer needed.
- *
- * Create a new GIcon based on image data in memory. The data will be used
- * directly from the @data passed. Use @destroy to control the lifetime of
- * the data in memory.
- *
- * Returns: (transfer full): A newly allocated icon.
- */
-GIcon*
-_gcr_memory_icon_new_full (const gchar *image_type, gpointer data, gsize n_data,
- goffset offset, GDestroyNotify destroy)
-{
- GcrMemoryIcon *self;
-
- g_return_val_if_fail (image_type != NULL, NULL);
- g_return_val_if_fail (data != NULL, NULL);
- g_return_val_if_fail (offset < n_data, NULL);
-
- self = g_object_new (GCR_TYPE_MEMORY_ICON, NULL);
- self->pv->data = data;
- self->pv->n_data = n_data;
- self->pv->offset = offset;
- self->pv->destroy = destroy;
- self->pv->image_type = g_strdup (image_type);
-
- return G_ICON (self);
-}
diff --git a/gcr/gcr-memory-icon.h b/gcr/gcr-memory-icon.h
deleted file mode 100644
index 71da9e51..00000000
--- a/gcr/gcr-memory-icon.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_MEMORY_ICON_H
-#define GCR_MEMORY_ICON_H
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GCR_MEMORY_ICON_COLUMNS (_gcr_memory_icon_get_columns ())
-#define GCR_TYPE_MEMORY_ICON (_gcr_memory_icon_get_type ())
-#define GCR_MEMORY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_MEMORY_ICON, GcrMemoryIcon))
-#define GCR_MEMORY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_MEMORY_ICON, GcrMemoryIconClass))
-#define GCR_IS_MEMORY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_MEMORY_ICON))
-#define GCR_IS_MEMORY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_MEMORY_ICON))
-#define GCR_MEMORY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_MEMORY_ICON, GcrMemoryIconClass))
-
-typedef struct _GcrMemoryIcon GcrMemoryIcon;
-typedef struct _GcrMemoryIconClass GcrMemoryIconClass;
-typedef struct _GcrMemoryIconPrivate GcrMemoryIconPrivate;
-
-struct _GcrMemoryIcon {
- /*< private >*/
- GObject parent;
- GcrMemoryIconPrivate *pv;
-};
-
-struct _GcrMemoryIconClass {
- GObjectClass parent_class;
-};
-
-GType _gcr_memory_icon_get_type (void) G_GNUC_CONST;
-
-GIcon* _gcr_memory_icon_new (const gchar *image_type,
- gconstpointer data,
- gsize n_data);
-
-GIcon* _gcr_memory_icon_new_full (const gchar *image_type,
- gpointer data,
- gsize n_data,
- goffset offset,
- GDestroyNotify destroy);
-
-G_END_DECLS
-
-#endif /* __GCR_MEMORY_ICON_H__ */
diff --git a/gcr/gcr-memory.c b/gcr/gcr-memory.c
deleted file mode 100644
index 04d216d9..00000000
--- a/gcr/gcr-memory.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "egg/egg-secure-memory.h"
-
-#include <glib.h>
-
-/* -----------------------------------------------------------------------------
- * MEMORY
- */
-
-static gboolean do_warning = TRUE;
-#define WARNING "couldn't allocate secure memory to keep passwords " \
- "and or keys from being written to the disk"
-
-#define ABORTMSG "The GNOME_KEYRING_PARANOID environment variable was set. " \
- "Exiting..."
-
-static G_LOCK_DEFINE (memory_lock);
-
-/*
- * These are called from egg-secure-memory.c to provide appropriate
- * locking for memory between threads
- */
-
-void
-egg_memory_lock (void)
-{
- G_LOCK (memory_lock);
-}
-
-void
-egg_memory_unlock (void)
-{
- G_UNLOCK (memory_lock);
-}
-
-void*
-egg_memory_fallback (void *p, size_t sz)
-{
- const gchar *env;
-
- /* We were asked to free memory */
- if (!sz) {
- g_free (p);
- return NULL;
- }
-
- /* We were asked to allocate */
- if (!p) {
- if (do_warning) {
- g_message (WARNING);
- do_warning = FALSE;
- }
-
- env = g_getenv ("GNOME_KEYRING_PARANOID");
- if (env && *env)
- g_error (ABORTMSG);
-
- return g_malloc0 (sz);
- }
-
- /*
- * Reallocation is a bit of a gray area, as we can be asked
- * by external libraries (like libgcrypt) to reallocate a
- * non-secure block into secure memory. We cannot satisfy
- * this request (as we don't know the size of the original
- * block) so we just try our best here.
- */
-
- return g_realloc (p, sz);
-}
diff --git a/gcr/gcr-menu-button.c b/gcr/gcr-menu-button.c
deleted file mode 100644
index 044d6d3b..00000000
--- a/gcr/gcr-menu-button.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2011 Alexander Larsson <alexl@redhat.com>
- * Copyright (C) 2011 Collabora Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-menu-button.h"
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_MENU
-};
-
-struct _GcrMenuButtonPrivate {
- GtkMenu *menu;
- gboolean popup_in_progress;
- gchar *label;
-};
-
-G_DEFINE_TYPE (GcrMenuButton, _gcr_menu_button, GTK_TYPE_TOGGLE_BUTTON);
-
-static void
-_gcr_menu_button_init (GcrMenuButton *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_MENU_BUTTON,
- GcrMenuButtonPrivate));
-}
-
-static void
-_gcr_menu_button_constructed (GObject *obj)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (obj);
- GtkWidget *label_widget;
- GtkWidget *arrow;
- GtkWidget *grid;
-
- G_OBJECT_CLASS (_gcr_menu_button_parent_class)->constructed (obj);
-
- gtk_button_set_focus_on_click (GTK_BUTTON (self), FALSE);
-
- label_widget = gtk_label_new (self->pv->label);
- arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- grid = gtk_grid_new ();
-
- gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_HORIZONTAL);
- gtk_container_add (GTK_CONTAINER (grid), label_widget);
- gtk_container_add (GTK_CONTAINER (grid), arrow);
- gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
- gtk_widget_set_hexpand (grid, TRUE);
- gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
-
- gtk_container_add (GTK_CONTAINER (self), grid);
-}
-
-static void
-_gcr_menu_button_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (obj);
-
- switch (prop_id) {
- case PROP_MENU:
- g_value_set_object (value, _gcr_menu_button_get_menu (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_menu_button_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- self->pv->label = g_value_dup_string (value);
- break;
- case PROP_MENU:
- _gcr_menu_button_set_menu (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_menu_button_finalize (GObject *obj)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (obj);
-
- _gcr_menu_button_set_menu (self, NULL);
- g_free (self->pv->label);
-
- G_OBJECT_CLASS (_gcr_menu_button_parent_class)->finalize (obj);
-}
-
-
-static void
-on_menu_position (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (user_data);
- GtkWidget *widget = GTK_WIDGET (self);
- GtkAllocation allocation;
- GtkRequisition menu_req;
- GdkRectangle monitor;
- GdkWindow *window;
- GtkWidget *toplevel;
- GdkScreen *screen;
- gint monitor_num;
- gint sx = 0;
- gint sy = 0;
-
- g_return_if_fail (x != NULL);
- g_return_if_fail (y != NULL);
- g_return_if_fail (push_in != NULL);
-
- gtk_widget_get_allocation (widget, &allocation);
-
- if (!gtk_widget_get_has_window (widget)) {
- sx += allocation.x;
- sy += allocation.y;
- }
-
- window = gtk_widget_get_window (widget);
- gdk_window_get_root_coords (window, sx, sy, &sx, &sy);
-
- gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &menu_req);
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- *x = sx;
- else
- *x = sx + allocation.width - menu_req.width;
- *y = sy;
-
- screen = gtk_widget_get_screen (widget);
- monitor_num = gdk_screen_get_monitor_at_window (screen, window);
- if (monitor_num < 0)
- monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
- if (*x < monitor.x)
- *x = monitor.x;
- else if (*x + menu_req.width > monitor.x + monitor.width)
- *x = monitor.x + monitor.width - menu_req.width;
-
- if (monitor.y + monitor.height - *y - allocation.height >= menu_req.height)
- *y += allocation.height;
- else if (*y - monitor.y >= menu_req.height)
- *y -= menu_req.height;
- else if (monitor.y + monitor.height - *y - allocation.height > *y - monitor.y)
- *y += allocation.height;
- else
- *y -= menu_req.height;
-
- gtk_menu_set_monitor (menu, monitor_num);
-
- toplevel = gtk_widget_get_parent (GTK_WIDGET (menu));
- if (GTK_IS_WINDOW (toplevel) && gtk_widget_get_visible (toplevel))
- gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
-
- *push_in = FALSE;
-}
-
-static void
-_gcr_menu_button_toggled (GtkToggleButton *togglebutton)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (togglebutton);
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context (GTK_WIDGET (self));
- if (gtk_toggle_button_get_active (togglebutton)) {
- if (!self->pv->popup_in_progress)
- gtk_menu_popup (self->pv->menu, NULL, NULL,
- on_menu_position, self, 1,
- gtk_get_current_event_time ());
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_MENUBAR);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_MENUITEM);
- } else {
- gtk_style_context_remove_class (context, GTK_STYLE_CLASS_MENUBAR);
- gtk_style_context_remove_class (context, GTK_STYLE_CLASS_MENUITEM);
- gtk_menu_popdown (self->pv->menu);
- }
-
- gtk_widget_reset_style (GTK_WIDGET (self));
-}
-
-static gboolean
-_gcr_menu_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (widget);
- GtkWidget *ewidget;
-
- ewidget = gtk_get_event_widget ((GdkEvent *)event);
- if (ewidget != widget || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
- return FALSE;
-
- gtk_menu_popup (self->pv->menu, NULL, NULL, on_menu_position, self,
- 1, gtk_get_current_event_time ());
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
- self->pv->popup_in_progress = TRUE;
- return TRUE;
-}
-
-static gboolean
-_gcr_menu_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (widget);
- gboolean popup_in_progress_saved;
- GtkWidget *ewidget;
-
- popup_in_progress_saved = self->pv->popup_in_progress;
- self->pv->popup_in_progress = FALSE;
-
- ewidget = gtk_get_event_widget ((GdkEvent *)event);
-
- if (ewidget == widget && !popup_in_progress_saved &&
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
- gtk_menu_popdown (self->pv->menu);
- return TRUE;
- }
-
- if (ewidget != widget) {
- gtk_menu_popdown (self->pv->menu);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-_gcr_menu_button_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GTK_WIDGET_GET_CLASS (widget)->draw (widget, cr);
- return FALSE;
-}
-
-static void
-_gcr_menu_button_class_init (GcrMenuButtonClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkToggleButtonClass *toggle_class = GTK_TOGGLE_BUTTON_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- gobject_class->constructed = _gcr_menu_button_constructed;
- gobject_class->get_property = _gcr_menu_button_get_property;
- gobject_class->set_property = _gcr_menu_button_set_property;
- gobject_class->finalize = _gcr_menu_button_finalize;
-
- widget_class->button_press_event = _gcr_menu_button_press_event;
- widget_class->button_release_event = _gcr_menu_button_release_event;
- widget_class->draw = _gcr_menu_button_draw;
-
- toggle_class->toggled = _gcr_menu_button_toggled;
-
- g_type_class_add_private (klass, sizeof (GcrMenuButtonPrivate));
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Label for the button",
- "", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_MENU,
- g_param_spec_object ("menu", "Menu", "Menu for the button",
- GTK_TYPE_MENU, G_PARAM_READWRITE));
-
-}
-
-/**
- * _gcr_menu_button_new:
- * @label: (allow-none): the label
- *
- * Returns: (transfer full) (type Gcr.MenuButton): the new menu button
- */
-GtkWidget *
-_gcr_menu_button_new (const gchar *label)
-{
- return g_object_new (GCR_TYPE_MENU_BUTTON,
- "label", label,
- NULL);
-}
-
-static void
-on_menu_show (GtkWidget *menu,
- gpointer user_data)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (user_data);
- self->pv->popup_in_progress = TRUE;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), TRUE);
- self->pv->popup_in_progress = FALSE;
-}
-
-static void
-on_menu_hide (GtkWidget *menu,
- gpointer user_data)
-{
- GcrMenuButton *self = GCR_MENU_BUTTON (user_data);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), FALSE);
-}
-
-static void
-on_menu_detach (GtkWidget *attach_widget,
- GtkMenu *menu)
-{
-
-}
-
-GtkMenu *
-_gcr_menu_button_get_menu (GcrMenuButton *self)
-{
- g_return_val_if_fail (GCR_IS_MENU_BUTTON (self), NULL);
- return self->pv->menu;
-}
-
-void
-_gcr_menu_button_set_menu (GcrMenuButton *self,
- GtkMenu *menu)
-{
- g_return_if_fail (GCR_IS_MENU_BUTTON (self));
- g_return_if_fail (menu == NULL || GTK_IS_MENU (menu));
-
- if (menu == self->pv->menu)
- return;
-
- if (self->pv->menu != NULL) {
- g_signal_handlers_disconnect_by_func (self->pv->menu, on_menu_show, self);
- g_signal_handlers_disconnect_by_func (self->pv->menu, on_menu_hide, self);
- gtk_menu_detach (self->pv->menu);
- g_object_unref (self->pv->menu);
- }
-
- self->pv->menu = menu;
-
- if (self->pv->menu != NULL) {
- g_object_ref (self->pv->menu);
- g_signal_connect (self->pv->menu, "show", G_CALLBACK (on_menu_show), self);
- g_signal_connect (self->pv->menu, "hide", G_CALLBACK (on_menu_hide), self);
- gtk_menu_attach_to_widget (self->pv->menu, GTK_WIDGET (self), on_menu_detach);
- }
-
- g_object_notify (G_OBJECT (self), "menu");
-}
diff --git a/gcr/gcr-menu-button.h b/gcr/gcr-menu-button.h
deleted file mode 100644
index 02dbb9cf..00000000
--- a/gcr/gcr-menu-button.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_MENU_BUTTON_H
-#define GCR_MENU_BUTTON_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_MENU_BUTTON (_gcr_menu_button_get_type ())
-#define GCR_MENU_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_MENU_BUTTON, GcrMenuButton))
-#define GCR_MENU_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_MENU_BUTTON, GcrMenuButtonClass))
-#define GCR_IS_MENU_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_MENU_BUTTON))
-#define GCR_IS_MENU_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_MENU_BUTTON))
-#define GCR_MENU_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_MENU_BUTTON, GcrMenuButtonClass))
-
-typedef struct _GcrMenuButton GcrMenuButton;
-typedef struct _GcrMenuButtonClass GcrMenuButtonClass;
-typedef struct _GcrMenuButtonPrivate GcrMenuButtonPrivate;
-
-struct _GcrMenuButton {
- GtkToggleButton parent;
- GcrMenuButtonPrivate *pv;
-};
-
-struct _GcrMenuButtonClass {
- GtkToggleButtonClass parent;
-};
-
-GType _gcr_menu_button_get_type (void);
-
-GtkWidget * _gcr_menu_button_new (const gchar *label);
-
-GtkMenu * _gcr_menu_button_get_menu (GcrMenuButton *self);
-
-void _gcr_menu_button_set_menu (GcrMenuButton *self,
- GtkMenu *menu);
-G_END_DECLS
-
-#endif /* GCR_MENU_BUTTON_H */
diff --git a/gcr/gcr-mkoids b/gcr/gcr-mkoids
deleted file mode 100644
index 47d10953..00000000
--- a/gcr/gcr-mkoids
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-set -euf
-
-generate_header ()
-{
- echo "/* WARNING: file is autogenerated */"
- echo ""
- echo "#include <glib.h>"
- echo ""
- echo "#ifndef ${UPPER}_OIDS_"
- echo "#define ${UPPER}_OIDS_"
- echo ""
- echo "void _${LOWER}_oids_init (void);"
-
- while read name oid; do
- if [ -n "$name" ]; then
- echo "GQuark ${UPPER}_OID_${name};"
- fi
- done
-
- echo ""
- echo "#endif /* ${UPPER}_OIDS_ */"
-}
-
-generate_source ()
-{
- echo "/* WARNING: file is autogenerated */"
- echo ""
- echo "#include \"$HEADER\""
- echo ""
-
- echo "void"
- echo "_${LOWER}_oids_init (void)"
- echo "{"
- echo " static volatile gsize initialized = 0;"
- echo " if (g_once_init_enter (&initialized)) {"
-
- while read name oid; do
- if [ -n "$name" ]; then
- echo " ${UPPER}_OID_${name} = g_quark_from_static_string (\"${oid}\");"
- fi
- done
-
- echo " g_once_init_leave (&initialized, 1);"
- echo " }"
- echo "}"
-}
-
-UPPER="PREFIX"
-LOWER="prefix"
-
-while getopts 'c:h:p:' arg; do
- case $arg in
- p)
- UPPER=$(echo "$OPTARG" | tr '[:lower:]' '[:upper:]')
- LOWER=$(echo "$OPTARG" | tr '[:upper:]' '[:lower:]')
- ;;
- c)
- SOURCE="$OPTARG"
- ;;
- h)
- HEADER="$OPTARG"
- ;;
- *)
- echo "gcr-mkoids: invalid argument: $arg" >&2
- exit 2
- ;;
- esac
-done
-
-shift $(expr $OPTIND - 1)
-if [ $# -ne 1 ]; then
- echo "gcr-mkoids: specify input file on command line"
- exit 2
-fi
-
-INPUT="$1"
-
-if [ -n "$HEADER" ]; then
- generate_header < $INPUT > $HEADER
-fi
-if [ -n "$SOURCE" ]; then
- generate_source < $INPUT > $SOURCE
-fi
diff --git a/gcr/gcr-oids.list b/gcr/gcr-oids.list
deleted file mode 100644
index 552c6017..00000000
--- a/gcr/gcr-oids.list
+++ /dev/null
@@ -1,22 +0,0 @@
-BASIC_CONSTRAINTS 2.5.29.19
-EXTENDED_KEY_USAGE 2.5.29.37
-SUBJECT_KEY_IDENTIFIER 2.5.29.14
-KEY_USAGE 2.5.29.15
-SUBJECT_ALT_NAME 2.5.29.17
-
-PKIX1_RSA 1.2.840.113549.1.1.1
-PKIX1_DSA 1.2.840.10040.4.1
-
-PKCS7_DATA 1.2.840.113549.1.7.1
-PKCS7_SIGNED_DATA 1.2.840.113549.1.7.2
-PKCS7_ENCRYPTED_DATA 1.2.840.113549.1.7.6
-PKCS9_ATTRIBUTE_FRIENDLY 1.2.840.113549.1.9.20
-PKCS9_ATTRIBUTE_LOCAL_KEY_ID 1.2.840.113549.1.9.21
-PKCS12_BAG_PKCS8_KEY 1.2.840.113549.1.12.10.1.1
-PKCS12_BAG_PKCS8_ENCRYPTED_KEY 1.2.840.113549.1.12.10.1.2
-PKCS12_BAG_CERTIFICATE 1.2.840.113549.1.12.10.1.3
-PKCS12_BAG_CRL 1.2.840.113549.1.12.10.1.4
-
-
-ALT_NAME_XMPP_ADDR 1.3.6.1.5.5.7.8.5
-ALT_NAME_DNS_SRV 1.3.6.1.5.5.7.8.7
diff --git a/gcr/gcr-openpgp.c b/gcr/gcr-openpgp.c
deleted file mode 100644
index 7ae5c477..00000000
--- a/gcr/gcr-openpgp.c
+++ /dev/null
@@ -1,1304 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-openpgp.h"
-#include "gcr-internal.h"
-#include "gcr-record.h"
-#include "gcr-types.h"
-
-#include "egg/egg-hex.h"
-
-#include <gcrypt.h>
-
-#include <string.h>
-
-typedef enum {
- OPENPGP_PKT_RESERVED = 0,
- OPENPGP_PKT_PUBKEY_ENC = 1,
- OPENPGP_PKT_SIGNATURE = 2,
- OPENPGP_PKT_ONEPASS_SIG = 4,
- OPENPGP_PKT_SECRET_KEY = 5,
- OPENPGP_PKT_PUBLIC_KEY = 6,
- OPENPGP_PKT_SECRET_SUBKEY = 7,
- OPENPGP_PKT_COMPRESSED = 8,
- OPENPGP_PKT_MARKER = 10,
- OPENPGP_PKT_LITERAL = 11,
- OPENPGP_PKT_RING_TRUST = 12,
- OPENPGP_PKT_USER_ID = 13,
- OPENPGP_PKT_PUBLIC_SUBKEY = 14,
- OPENPGP_PKT_OLD_COMMENT = 16,
- OPENPGP_PKT_ATTRIBUTE = 17,
- OPENPGP_PKT_MDC = 19
-} OpenpgpPktType;
-
-typedef enum {
- OPENPGP_SIG_CREATION = 2,
- OPENPGP_SIG_EXPIRY = 3,
- OPENPGP_SIG_EXPORTABLE = 4,
- OPENPGP_SIG_TRUST = 5,
- OPENPGP_SIG_REGULAR_EXPRESSION = 6,
- OPENPGP_SIG_REVOCABLE = 7,
- OPENPGP_SIG_KEY_EXPIRY = 9,
- OPENPGP_SIG_SYMMETRIC_ALGOS = 11,
- OPENPGP_SIG_REVOCATION_KEY = 12,
- OPENPGP_SIG_ISSUER = 16,
- OPENPGP_SIG_NOTATION_DATA = 20,
- OPENPGP_SIG_HASH_ALGOS = 21,
- OPENPGP_SIG_COMPRESSION_ALGOS = 22,
- OPENPGP_SIG_KEYSERVER_PREFS = 23,
- OPENPGP_SIG_PREFERRED_KEYSERVER = 24,
- OPENPGP_SIG_PRIMARY_USERID = 25,
- OPENPGP_SIG_POLICY_URI = 26,
- OPENPGP_SIG_KEY_FLAGS = 27,
- OPENPGP_SIG_SIGNER_USERID = 28,
- OPENPGP_SIG_REVOCATION_REASON = 29,
- OPENPGP_SIG_FEATURES = 30,
- OPENPGP_SIG_TARGET = 31,
- OPENPGP_SIG_EMBEDDED_SIGNATURE = 32,
-} OpenpgpSigPacket;
-
-static gboolean
-read_byte (const guchar **at,
- const guchar *end,
- guint8 *result)
-{
- g_assert (at);
- if (*at == end)
- *at = NULL;
- if (*at == NULL)
- return FALSE;
- if (result)
- *result = *(*at);
- (*at)++;
- return TRUE;
-}
-
-static gboolean
-read_bytes (const guchar **at,
- const guchar *end,
- gpointer buffer,
- gsize length)
-{
- g_assert (at);
- if (*at + length > end)
- *at = NULL;
- if (*at == NULL)
- return FALSE;
- if (buffer != NULL)
- memcpy (buffer, *at, length);
- (*at) += length;
- return TRUE;
-}
-
-static gboolean
-read_uint32 (const guchar **at,
- const guchar *end,
- guint32 *value)
-{
- guchar buf[4];
- g_assert (at);
- if (!read_bytes (at, end, buf, 4))
- return FALSE;
- if (value)
- *value = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
- return TRUE;
-}
-
-static gboolean
-read_uint16 (const guchar **at,
- const guchar *end,
- guint16 *value)
-{
- guchar buf[2];
- g_assert (at);
- if (!read_bytes (at, end, buf, 2))
- return FALSE;
- if (value)
- *value = buf[0] << 8 | buf[1];
- return TRUE;
-}
-
-static gboolean
-read_mpi (const guchar **at,
- const guchar *end,
- guint16 *bits,
- guchar **value)
-{
- gsize bytes;
- guint16 b;
- g_assert (at);
- if (!bits)
- bits = &b;
- if (!read_uint16 (at, end, bits))
- return FALSE;
- bytes = (*bits + 7) / 8;
- if (bytes == 0)
- return FALSE;
- if (value)
- *value = g_malloc (bytes);
- if (!read_bytes (at, end, value ? *value : NULL, bytes)) {
- if (value)
- g_free (*value);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-read_new_length (const guchar **at,
- const guchar *end,
- gsize *pkt_len)
-{
- guint8 c, c1;
- guint32 val;
-
- if (!read_byte (at, end, &c))
- return FALSE;
- if (c < 192) {
- *pkt_len = c;
- } else if (c >= 192 && c <= 223) {
- if (!read_byte (at, end, &c1))
- return FALSE;
- *pkt_len = ((c - 192) << 8) + c1 + 192;
- } else if (c == 255) {
- if (!read_uint32 (at, end, &val))
- return FALSE;
- *pkt_len = val;
- } else {
- /* We don't support partial length */
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-read_old_length (const guchar **at,
- const guchar *end,
- guchar ctb,
- gsize *pkt_len)
-{
- gsize llen = ctb & 0x03;
- guint16 v16;
- guint32 v32;
- guint8 c;
-
- if (llen == 0) {
- if (!read_byte (at, end, &c))
- return FALSE;
- *pkt_len = c;
- } else if (llen == 1) {
- if (!read_uint16 (at, end, &v16))
- return FALSE;
- *pkt_len = v16;
- } else if (llen == 2) {
- if (!read_uint32 (at, end, &v32))
- return FALSE;
- *pkt_len = v32;
- } else {
- *pkt_len = end - *at;
- }
-
- return TRUE;
-}
-
-static GcrDataError
-read_openpgp_packet (const guchar **at,
- const guchar *end,
- guint8 *pkt_type,
- gsize *length)
-{
- gboolean new_ctb;
- guint8 ctb;
- gboolean ret;
-
- if (!read_byte (at, end, &ctb))
- return GCR_ERROR_UNRECOGNIZED;
- if (!(ctb & 0x80))
- return GCR_ERROR_UNRECOGNIZED;
-
- /* RFC2440 packet format. */
- if (ctb & 0x40) {
- *pkt_type = ctb & 0x3f;
- new_ctb = TRUE;
-
- /* the old RFC1991 packet format. */
- } else {
- *pkt_type = ctb & 0x3f;
- *pkt_type >>= 2;
- new_ctb = FALSE;
- }
-
- if (*pkt_type > 63)
- return GCR_ERROR_UNRECOGNIZED;
-
- if (new_ctb)
- ret = read_new_length (at, end, length);
- else
- ret = read_old_length (at, end, ctb, length);
- if (!ret)
- return GCR_ERROR_UNRECOGNIZED;
-
- if ((*at) + *length > end)
- return GCR_ERROR_FAILURE;
-
- return GCR_SUCCESS;
-}
-
-static gchar *
-hash_user_id_or_attribute (const guchar *beg,
- const guchar *end)
-{
- guint8 digest[20] = { 0, };
-
- g_assert (beg != NULL);
- g_assert (end > beg);
-
- gcry_md_hash_buffer (GCRY_MD_RMD160, digest, beg, end - beg);
- return egg_hex_encode_full (digest, sizeof (digest), TRUE, 0, 0);
-}
-
-static gboolean
-parse_v3_rsa_bits_and_keyid (const guchar **at,
- const guchar *end,
- guint16 *bits,
- gchar **keyid)
-{
- guchar *n;
- gsize bytes;
-
- g_assert (bits);
- g_assert (keyid);
-
- /* Read in the modulus */
- if (!read_mpi (at, end, bits, &n))
- return FALSE;
-
- /* Last 64-bits of modulus are keyid */
- bytes = (*bits + 7) / 8;
- if (bytes < 8) {
- g_free (n);
- return FALSE;
- }
-
- *keyid = egg_hex_encode_full (n + (bytes - 8), 8, TRUE, 0, 0);
- return TRUE;
-}
-
-static gchar *
-hash_v4_keyid (const guchar *data,
- const guchar *end,
- gchar **fingerprint)
-{
- gcry_md_hd_t mdh;
- gcry_error_t gcry;
- guchar header[3];
- guint8 *digest;
- gchar *keyid;
- gsize len;
-
- /*
- * Both primary and subkeys use the public key tag byte
- * 0x99 to construct the hash. So we skip over that here.
- */
-
- g_assert (data != NULL);
- g_assert (end > data);
-
- len = end - data;
- g_return_val_if_fail (len < G_MAXUSHORT, NULL);
-
- header[0] = 0x99;
- header[1] = len >> 8 & 0xff;
- header[2] = len & 0xff;
-
- gcry = gcry_md_open (&mdh, GCRY_MD_SHA1, 0);
- g_return_val_if_fail (gcry == 0, NULL);
-
- gcry_md_write (mdh, header, 3);
- gcry_md_write (mdh, data, len);
-
- digest = gcry_md_read (mdh, 0);
- keyid = egg_hex_encode_full (digest + 12, 8, TRUE, 0, 0);
- if (fingerprint)
- *fingerprint = egg_hex_encode_full (digest, 20, TRUE, 0, 0);
- gcry_md_close (mdh);
-
- return keyid;
-}
-
-static gboolean
-parse_v4_algo_bits (const guchar **at,
- const guchar *end,
- guint8 algo,
- guint16 *bits)
-{
- switch (algo) {
- case GCR_OPENPGP_ALGO_RSA:
- case GCR_OPENPGP_ALGO_RSA_E:
- case GCR_OPENPGP_ALGO_RSA_S:
- if (!read_mpi (at, end, bits, NULL) ||
- !read_mpi (at, end, NULL, NULL))
- return FALSE;
- return TRUE;
- case GCR_OPENPGP_ALGO_DSA:
- if (!read_mpi (at, end, bits, NULL) ||
- !read_mpi (at, end, NULL, NULL) ||
- !read_mpi (at, end, NULL, NULL) ||
- !read_mpi (at, end, NULL, NULL))
- return FALSE;
- return TRUE;
- case GCR_OPENPGP_ALGO_ELG_E:
- if (!read_mpi (at, end, bits, NULL) ||
- !read_mpi (at, end, NULL, NULL) ||
- !read_mpi (at, end, NULL, NULL))
- return FALSE;
- return TRUE;
- default: /* Unsupported key */
- return FALSE;
- }
-}
-
-static const gchar *
-default_caps_for_algo (guint8 algo)
-{
- switch (algo) {
- case GCR_OPENPGP_ALGO_RSA:
- return "cse";
- case GCR_OPENPGP_ALGO_RSA_E:
- return "e";
- case GCR_OPENPGP_ALGO_RSA_S:
- return "s";
- case GCR_OPENPGP_ALGO_ELG_E:
- return "e";
- case GCR_OPENPGP_ALGO_DSA:
- return "sca";
- default:
- return "";
- }
-}
-
-static gboolean
-parse_public_key_or_subkey (GQuark schema,
- guint n_columns,
- const guchar *beg,
- const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- gchar *keyid;
- GcrRecord *record;
- guint8 version;
- guint32 timestamp;
- guint16 ndays = 0;
- guint8 algo;
- guint16 bits;
- gulong expiry;
- gchar *fingerprint;
- const guchar *data;
-
- /* Start of actual key data in packet */
- data = *at;
-
- /* First byte is version */
- if (!read_byte (at, end, &version))
- return FALSE;
- if (version < 2 || version > 4)
- return FALSE;
-
- /* Next a 4 byte create date */
- if (!read_uint32 (at, end, &timestamp))
- return FALSE;
- /* If version 2 or 3, validity days comes next */
- if (version < 4) {
- if (!read_uint16 (at, end, &ndays))
- return FALSE;
- }
-
- /* Algorithm */
- if (!read_byte (at, end, &algo))
- return FALSE;
-
- /* For version 2 and 3, only RSA, keyid is low 64-bits of modulus */
- if (version < 4) {
- if (!parse_v3_rsa_bits_and_keyid (at, end, &bits, &keyid))
- return FALSE;
-
- /* For version 4 */
- } else {
- if (!parse_v4_algo_bits (at, end, algo, &bits))
- return FALSE;
- keyid = hash_v4_keyid (data, *at, &fingerprint);
- }
-
- record = _gcr_record_new (schema, n_columns, ':');
- _gcr_record_set_uint (record, GCR_RECORD_KEY_BITS, bits);
- _gcr_record_set_uint (record, GCR_RECORD_KEY_ALGO, algo);
- _gcr_record_take_raw (record, GCR_RECORD_KEY_KEYID, keyid);
- _gcr_record_set_ulong (record, GCR_RECORD_KEY_TIMESTAMP, timestamp);
- if (schema != GCR_RECORD_SCHEMA_SEC && schema != GCR_RECORD_SCHEMA_SSB)
- _gcr_record_set_raw (record, GCR_RECORD_PUB_CAPS, default_caps_for_algo (algo));
-
- if (ndays > 0) {
- expiry = (gulong)timestamp + ((gulong)ndays * 86400);
- _gcr_record_set_ulong (record, GCR_RECORD_KEY_EXPIRY, expiry);
- }
-
- g_ptr_array_add (records, record);
-
- if (fingerprint && (schema == GCR_RECORD_SCHEMA_PUB || schema == GCR_RECORD_SCHEMA_SEC)) {
- record = _gcr_record_new (GCR_RECORD_SCHEMA_FPR, GCR_RECORD_FPR_MAX, ':');
- _gcr_record_take_raw (record, GCR_RECORD_FPR_FINGERPRINT, fingerprint);
- g_ptr_array_add (records, record);
- fingerprint = NULL;
- }
-
- g_free (fingerprint);
- return TRUE;
-}
-
-static gboolean
-parse_secret_key_or_subkey (GQuark schema,
- const guchar *beg,
- const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- /*
- * Identical to a public key, with extra crap after it. The
- * extra crap is hard to parse and doesn't add anything to
- * the records, so just skip over it.
- *
- * Also don't print out trust, that doesn't make sense for
- * secret keys.
- */
-
- if (!parse_public_key_or_subkey (schema, GCR_RECORD_SEC_MAX,
- beg, at, end, flags, records))
- return FALSE;
-
- *at = end;
- return TRUE;
-}
-
-static gboolean
-parse_user_id (const guchar *beg,
- const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- gchar *string;
- GcrRecord *record;
- gchar *fingerprint;
-
- g_assert (at);
- if (!*at || !end || *at > end)
- return FALSE;
-
- string = g_strndup ((gchar *)*at, end - *at);
-
- fingerprint = hash_user_id_or_attribute (*at, end);
- record = _gcr_record_new (GCR_RECORD_SCHEMA_UID, GCR_RECORD_UID_MAX, ':');
- _gcr_record_take_raw (record, GCR_RECORD_UID_FINGERPRINT, fingerprint);
- _gcr_record_set_string (record, GCR_RECORD_UID_USERID, string);
- g_free (string);
-
- g_ptr_array_add (records, record);
-
- *at = end;
- return TRUE;
-}
-
-static gboolean
-parse_user_attribute_packet (const guchar *beg,
- const guchar **at,
- const guchar *end,
- guchar subpkt_type,
- GPtrArray *records)
-{
- GcrRecord *record;
- gchar *fingerprint;
-
- record = _gcr_record_new (GCR_RECORD_SCHEMA_XA1, GCR_RECORD_XA1_MAX, ':');
- _gcr_record_set_uint (record, GCR_RECORD_XA1_LENGTH, end - *at);
- _gcr_record_set_uint (record, GCR_RECORD_XA1_TYPE, subpkt_type);
- fingerprint = hash_user_id_or_attribute (*at, end);
- _gcr_record_take_raw (record, GCR_RECORD_XA1_FINGERPRINT, fingerprint);
- _gcr_record_set_base64 (record, GCR_RECORD_XA1_DATA, *at, end - *at);
-
- g_ptr_array_add (records, record);
-
- *at = end;
- return TRUE;
-}
-
-static gboolean
-parse_user_attribute (const guchar *beg,
- const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- gsize subpkt_len;
- guint count = 0;
- const guchar *start;
- const guchar *subpkt_beg;
- guint8 subpkt_type;
- gchar *fingerprint;
- gchar *string;
- GcrRecord *record;
-
- start = *at;
- while (*at != end) {
- subpkt_beg = *at;
-
- if (!read_new_length (at, end, &subpkt_len) ||
- !read_byte (at, end, &subpkt_type))
- return FALSE;
-
- count++;
-
- if (flags & GCR_OPENPGP_PARSE_ATTRIBUTES) {
- if (!parse_user_attribute_packet (subpkt_beg, at,
- *at + (subpkt_len - 1),
- subpkt_type, records))
- return FALSE;
-
- /* We already progressed one extra byte for the subpkt_type */
- } else {
- *at += (subpkt_len - 1);
- }
- }
-
- fingerprint = hash_user_id_or_attribute (start, end);
- string = g_strdup_printf ("%d %d", count, (guint)(*at - start));
- record = _gcr_record_new (GCR_RECORD_SCHEMA_UAT, GCR_RECORD_UAT_MAX, ':');
- _gcr_record_take_raw (record, GCR_RECORD_UAT_FINGERPRINT, fingerprint);
- _gcr_record_take_raw (record, GCR_RECORD_UAT_COUNT_SIZE, string);
-
- g_ptr_array_add (records, record);
- return TRUE;
-}
-
-static gboolean
-skip_signature_mpis (const guchar **at,
- const guchar *end,
- guint8 algo)
-{
- switch (algo) {
-
- /* RSA signature value */
- case GCR_OPENPGP_ALGO_RSA:
- return read_mpi (at, end, NULL, NULL);
-
- /* DSA values r and s */
- case GCR_OPENPGP_ALGO_DSA:
- return read_mpi (at, end, NULL, NULL) &&
- read_mpi (at, end, NULL, NULL);
- default:
- return FALSE;
- }
-}
-
-static gboolean
-parse_v3_signature (const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- guchar keyid[8];
- guint8 sig_type;
- guint8 sig_len;
- guint32 sig_time;
- guint8 key_algo;
- guint8 hash_algo;
- guint16 left_bits;
- GcrRecord *record;
- gchar *value;
-
- if (!read_byte (at, end, &sig_len) || sig_len != 5)
- return FALSE;
-
- if (!read_byte (at, end, &sig_type) ||
- !read_uint32 (at, end, &sig_time) ||
- !read_bytes (at, end, keyid, 8) ||
- !read_byte (at, end, &key_algo) ||
- !read_byte (at, end, &hash_algo) ||
- !read_uint16 (at, end, &left_bits) ||
- !skip_signature_mpis (at, end, key_algo))
- return FALSE;
-
- if (flags & GCR_OPENPGP_PARSE_SIGNATURES) {
- record = _gcr_record_new (GCR_RECORD_SCHEMA_SIG, GCR_RECORD_SIG_MAX, ':');
- _gcr_record_set_uint (record, GCR_RECORD_SIG_ALGO, key_algo);
- value = egg_hex_encode_full (keyid, sizeof (keyid), TRUE, 0, 0);
- _gcr_record_take_raw (record, GCR_RECORD_SIG_KEYID, value);
- _gcr_record_set_ulong (record, GCR_RECORD_SIG_TIMESTAMP, sig_time);
- value = g_strdup_printf ("%02xx", (guint)sig_type);
- _gcr_record_take_raw (record, GCR_RECORD_SIG_CLASS, value);
- g_ptr_array_add (records, record);
- }
-
- return TRUE;
-}
-
-typedef struct {
- gulong key_expiry;
- gboolean exportable;
- gboolean primary;
- guint8 key_flags;
- GcrRecord *revocation;
-} SigSubpacket;
-
-static gboolean
-parse_v4_signature_revocation (const guchar **at,
- const guchar *end,
- GcrRecord *revocation)
-{
- guchar fingerprint[20];
- gchar *value;
- guint8 klass;
- guint8 algo;
-
- if (!read_byte (at, end, &klass) ||
- !read_byte (at, end, &algo) ||
- !read_bytes (at, end, fingerprint, 20))
- return FALSE;
-
- _gcr_record_set_uint (revocation, GCR_RECORD_RVK_ALGO, algo);
- value = egg_hex_encode_full (fingerprint, 20, TRUE, 0, 0);
- _gcr_record_take_raw (revocation, GCR_RECORD_RVK_FINGERPRINT, value);
- value = g_strdup_printf ("%02X", (guint)klass);
- _gcr_record_take_raw (revocation, GCR_RECORD_RVK_CLASS, value);
-
- 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;
- }
-
-}
-
-static gboolean
-parse_v4_signature_subpackets (const guchar **at,
- const guchar *end,
- GcrRecord *record,
- SigSubpacket *subpkt)
-{
- gsize length;
- guint8 sub_type;
- const guchar *stop;
-
- while (*at != end) {
- if (!read_new_length (at, end, &length) ||
- !read_byte (at, end, &sub_type) ||
- length == 0)
- return FALSE;
-
- /* The length includes the sub_type */
- length--;
- stop = *at + length;
- if (stop > end)
- return FALSE;
-
- /* Actually parse the sub packets */
- if (!parse_v4_signature_subpacket (at, stop, sub_type, record, subpkt))
- return FALSE;
- if (*at != stop)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static GcrRecord *
-uid_or_uat_find_for_self_signature (GPtrArray *records,
- guint8 sig_type)
-{
- GcrRecord *record;
- GQuark schema;
-
- if (records->len == 0)
- return NULL;
-
- switch (sig_type) {
- /* Generic certification of a key or userid */
- case 0x10: case 0x11: case 0x12: case 0x13:
- record = records->pdata[records->len - 1];
- schema = _gcr_record_get_schema (record);
- if (schema == GCR_RECORD_SCHEMA_UID ||
- schema == GCR_RECORD_SCHEMA_UAT)
- return record;
- return NULL;
-
- default:
- return NULL;
- }
-
-}
-
-static GcrRecord *
-key_or_sub_find_for_self_signature (GPtrArray *records,
- guint8 sig_type,
- const gchar *keyid)
-{
- GcrRecord *record;
- const gchar *check;
- GQuark schema;
- gint i;
-
- if (records->len == 0)
- return NULL;
-
- switch (sig_type) {
- /* Generic certification of a key or userid */
- case 0x10: case 0x11: case 0x12: case 0x13:
- for (i = records->len - 1; i >= 0; i--) {
- record = records->pdata[i];
- schema = _gcr_record_get_schema (record);
- if (schema == GCR_RECORD_SCHEMA_PUB || schema == GCR_RECORD_SCHEMA_SEC) {
- check = _gcr_record_get_raw (record, GCR_RECORD_KEY_KEYID);
- return (check != NULL && g_str_equal (check, keyid)) ? record : NULL;
- }
- }
- return NULL;
-
- /* (Primary) Subkey Binding Signature */
- case 0x18: case 0x19:
- record = records->pdata[records->len - 1];
- schema = _gcr_record_get_schema (record);
- if (schema == GCR_RECORD_SCHEMA_SUB)
- return record;
- return NULL;
-
- default:
- return NULL;
- }
-}
-
-static void
-pub_or_sub_set_key_caps (GcrRecord *record,
- guint8 key_flags)
-{
- GString *string;
- GQuark schema;
-
- schema = _gcr_record_get_schema (record);
- if (schema == GCR_RECORD_SCHEMA_SEC || schema == GCR_RECORD_SCHEMA_SSB)
- return;
-
- string = g_string_sized_new (8);
- if (key_flags & 0x02)
- g_string_append_c (string, 's');
- if (key_flags & 0x01)
- g_string_append_c (string, 'c');
- if (key_flags & 0x04 || key_flags & 0x08)
- g_string_append_c (string, 'e');
- if (key_flags & 0x20)
- g_string_append_c (string, 'a');
-
- _gcr_record_take_raw (record, GCR_RECORD_PUB_CAPS,
- g_string_free (string, FALSE));
-}
-
-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, &timestamp))
- _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, &timestamp))
- _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_signature (const guchar *beg,
- const guchar **at,
- const guchar *end,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- guint8 version;
-
- if (!read_byte (at, end, &version))
- return FALSE;
-
- if (version == 3)
- return parse_v3_signature (at, end, flags, records);
- else if (version == 4)
- return parse_v4_signature (at, end, flags, records);
- else
- return FALSE;
-}
-
-static GcrDataFormat
-parse_openpgp_packet (const guchar *beg,
- const guchar *at,
- const guchar *end,
- guint8 pkt_type,
- GcrOpenpgpParseFlags flags,
- GPtrArray *records)
-{
- gboolean ret;
-
- switch (pkt_type) {
- case OPENPGP_PKT_PUBLIC_KEY:
- ret = parse_public_key_or_subkey (GCR_RECORD_SCHEMA_PUB, GCR_RECORD_PUB_MAX,
- beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_PUBLIC_SUBKEY:
- ret = parse_public_key_or_subkey (GCR_RECORD_SCHEMA_SUB, GCR_RECORD_PUB_MAX,
- beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_USER_ID:
- ret = parse_user_id (beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_ATTRIBUTE:
- ret = parse_user_attribute (beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_SIGNATURE:
- ret = parse_signature (beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_SECRET_KEY:
- ret = parse_secret_key_or_subkey (GCR_RECORD_SCHEMA_SEC,
- beg, &at, end, flags, records);
- break;
- case OPENPGP_PKT_SECRET_SUBKEY:
- ret = parse_secret_key_or_subkey (GCR_RECORD_SCHEMA_SSB,
- beg, &at, end, flags, records);
- break;
-
- /* Stuff we don't want to be meddling with right now */
- case OPENPGP_PKT_RING_TRUST:
- return GCR_SUCCESS;
-
- /* Ignore packets we don't understand */
- default:
- return GCR_SUCCESS;
- }
-
- /* Key packet had extra data */
- if (ret == TRUE && at != end)
- ret = FALSE;
-
- return ret ? GCR_SUCCESS : GCR_ERROR_FAILURE;
-}
-
-static void
-append_key_capabilities (GString *string,
- const gchar *caps)
-{
- guint i;
- gchar cap;
-
- for (i = 0; caps[i] != 0; i++) {
- cap = g_ascii_toupper (caps[i]);
- if (!strchr (string->str, cap))
- g_string_append_c (string, cap);
- }
-}
-
-static void
-normalize_capabilities (GPtrArray *records)
-{
- GString *string;
- GQuark schema;
- const gchar *caps;
- guint i;
-
- /* Gather the capabilities of all subkeys into the primary key */
- string = g_string_new (_gcr_record_get_raw (records->pdata[0], GCR_RECORD_PUB_CAPS));
- for (i = 0; i < records->len; i++) {
- schema = _gcr_record_get_schema (records->pdata[i]);
- if (schema == GCR_RECORD_SCHEMA_PUB || schema == GCR_RECORD_SCHEMA_SUB) {
- caps = _gcr_record_get_raw (records->pdata[i], GCR_RECORD_PUB_CAPS);
- append_key_capabilities (string, caps);
- }
- }
- _gcr_record_take_raw (records->pdata[0], GCR_RECORD_PUB_CAPS,
- g_string_free (string, FALSE));
-}
-
-static gboolean
-check_key_expiry (GcrRecord *record)
-{
- gulong expiry;
- time_t current;
-
- if (_gcr_record_get_ulong (record, GCR_RECORD_KEY_EXPIRY, &expiry)) {
- if (expiry == 0)
- return FALSE;
- current = time (NULL);
- if (current > expiry)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-normalize_key_records (GPtrArray *records)
-{
- GQuark schema;
- guchar trust = 0;
- const gchar *prev;
- gboolean force = FALSE;
- guint i;
-
- if (records->len == 0)
- return;
-
- schema = _gcr_record_get_schema (records->pdata[0]);
- if (schema == GCR_RECORD_SCHEMA_PUB) {
-
- if (check_key_expiry (records->pdata[0])) {
- trust = 'e';
- force = TRUE;
-
- /* Mark public keys as unknown trust */
- } else {
- normalize_capabilities (records);
- trust = 'o';
- force = FALSE;
- }
-
- /* Ownertrust unknown, new to system */
- _gcr_record_set_char (records->pdata[0], GCR_RECORD_KEY_OWNERTRUST, 'o');
-
- } else if (schema == GCR_RECORD_SCHEMA_SEC) {
-
- /* Trust doesn't make sense for secret keys */
- trust = 0;
- force = FALSE;
- }
-
-
- /* Setup default trust if necessary */
- if (trust != 0) {
- for (i = 0; i < records->len; i++) {
- if (!force) {
- prev = _gcr_record_get_raw (records->pdata[i], GCR_RECORD_TRUST);
- if (prev != NULL && prev[0])
- continue;
- }
- schema = _gcr_record_get_schema (records->pdata[i]);
- if (schema != GCR_RECORD_SCHEMA_SIG && schema != GCR_RECORD_SCHEMA_FPR)
- _gcr_record_set_char (records->pdata[i], GCR_RECORD_TRUST, trust);
- }
- }
-}
-
-typedef struct {
- GcrOpenpgpCallback callback;
- gpointer user_data;
- guint count;
- GPtrArray *records;
-} openpgp_parse_closure;
-
-static void
-openpgp_parse_free (gpointer data)
-{
- openpgp_parse_closure *closure = data;
- g_ptr_array_unref (closure->records);
- g_free (closure);
-}
-
-static void
-maybe_emit_openpgp_block (openpgp_parse_closure *closure,
- const guchar *block,
- const guchar *end)
-{
- gsize length;
- GPtrArray *records;
-
- if (block == NULL || block == end)
- return;
-
- g_assert (end != NULL);
- g_assert (end > block);
-
- length = end - block;
- closure->count++;
-
- records = closure->records;
- closure->records = g_ptr_array_new_with_free_func (_gcr_record_free);
-
- if (closure->callback)
- (closure->callback) (records, block, length, closure->user_data);
-
- g_ptr_array_unref (records);
-}
-
-guint
-_gcr_openpgp_parse (gconstpointer data,
- gsize n_data,
- GcrOpenpgpParseFlags flags,
- GcrOpenpgpCallback callback,
- gpointer user_data)
-{
- openpgp_parse_closure *closure;
- const guchar *at;
- const guchar *beg;
- const guchar *end;
- const guchar *block;
- guint8 pkt_type;
- GcrDataError res;
- gsize length;
- gboolean new_key;
- guint ret;
-
- g_return_val_if_fail (data != NULL, 0);
-
- /* For libgcrypt */
- _gcr_initialize_library ();
-
- at = data;
- end = at + n_data;
- block = NULL;
-
- closure = g_new0 (openpgp_parse_closure, 1);
- closure->callback = callback;
- closure->user_data = user_data;
- closure->records = g_ptr_array_new_with_free_func (_gcr_record_free);
-
- while (at != NULL && at != end) {
- beg = at;
- res = read_openpgp_packet (&at, end, &pkt_type, &length);
-
- if (res == GCR_SUCCESS) {
- new_key = (pkt_type == OPENPGP_PKT_PUBLIC_KEY ||
- pkt_type == OPENPGP_PKT_SECRET_KEY);
- if (flags & GCR_OPENPGP_PARSE_KEYS && new_key)
- normalize_key_records (closure->records);
- /* Start of a new set of packets, per key */
- if (!(flags & GCR_OPENPGP_PARSE_KEYS) || new_key) {
- maybe_emit_openpgp_block (closure, block, beg);
- block = beg;
- }
- if (!(flags & GCR_OPENPGP_PARSE_NO_RECORDS))
- parse_openpgp_packet (beg, at, at + length, pkt_type,
- flags, closure->records);
- }
-
- if (res != GCR_SUCCESS) {
- if (block != NULL && block != beg)
- maybe_emit_openpgp_block (closure, block, beg);
- block = NULL;
- break;
- }
-
- at += length;
- }
-
- if (flags & GCR_OPENPGP_PARSE_KEYS)
- normalize_key_records (closure->records);
- maybe_emit_openpgp_block (closure, block, at);
- ret = closure->count;
- openpgp_parse_free (closure);
- return ret;
-}
diff --git a/gcr/gcr-openpgp.h b/gcr/gcr-openpgp.h
deleted file mode 100644
index 31fd2956..00000000
--- a/gcr/gcr-openpgp.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_OPENPGP_H__
-#define __GCR_OPENPGP_H__
-
-#include <glib.h>
-
-#include <gck/gck.h>
-
-typedef enum {
- GCR_OPENPGP_ALGO_RSA = 1,
- GCR_OPENPGP_ALGO_RSA_E = 2,
- GCR_OPENPGP_ALGO_RSA_S = 3,
- GCR_OPENPGP_ALGO_ELG_E = 16,
- GCR_OPENPGP_ALGO_DSA = 17
-} GcrOpenpgpAlgo;
-
-typedef enum {
- GCR_OPENPGP_PARSE_NONE = 0,
- GCR_OPENPGP_PARSE_KEYS = 1 << 1,
- GCR_OPENPGP_PARSE_NO_RECORDS = 1 << 2,
- GCR_OPENPGP_PARSE_SIGNATURES = 1 << 3,
- GCR_OPENPGP_PARSE_ATTRIBUTES = 1 << 4,
-} GcrOpenpgpParseFlags;
-
-G_BEGIN_DECLS
-
-typedef void (*GcrOpenpgpCallback) (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
- gpointer user_data);
-
-guint _gcr_openpgp_parse (gconstpointer data,
- gsize n_data,
- GcrOpenpgpParseFlags flags,
- GcrOpenpgpCallback callback,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* __GCR_OPENPGP_H__ */
diff --git a/gcr/gcr-openssh.c b/gcr/gcr-openssh.c
deleted file mode 100644
index e285465c..00000000
--- a/gcr/gcr-openssh.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-openssh.h"
-#include "gcr-internal.h"
-#include "gcr-types.h"
-
-#include "egg/egg-buffer.h"
-#include "egg/egg-decimal.h"
-
-#include "pkcs11/pkcs11.h"
-
-#include <string.h>
-
-typedef struct {
- GcrOpensshPubCallback callback;
- gpointer user_data;
-} OpensshPubClosure;
-
-static void
-skip_spaces (const gchar ** line,
- gsize *n_line)
-{
- while (*n_line > 0 && (*line)[0] == ' ') {
- (*line)++;
- (*n_line)--;
- }
-}
-
-static gboolean
-next_word (const gchar **line,
- gsize *n_line,
- const gchar **word,
- gsize *n_word)
-{
- const gchar *beg;
- const gchar *end;
- const gchar *at;
- gboolean quotes;
-
- skip_spaces (line, n_line);
-
- if (!*n_line) {
- *word = NULL;
- *n_word = 0;
- return FALSE;
- }
-
- beg = at = *line;
- end = beg + *n_line;
- quotes = FALSE;
-
- do {
- switch (*at) {
- case '"':
- quotes = !quotes;
- at++;
- break;
- case ' ':
- if (!quotes)
- end = at;
- else
- at++;
- break;
- default:
- at++;
- break;
- }
- } while (at < end);
-
- *word = beg;
- *n_word = end - beg;
- (*line) += *n_word;
- (*n_line) -= *n_word;
- return TRUE;
-}
-
-static gboolean
-match_word (const gchar *word,
- gsize n_word,
- const gchar *matches)
-{
- gsize len = strlen (matches);
- if (len != n_word)
- return FALSE;
- return memcmp (word, matches, n_word) == 0;
-}
-
-static gulong
-keytype_to_algo (const gchar *algo,
- gsize length)
-{
- if (!algo)
- return G_MAXULONG;
- else if (match_word (algo, length, "ssh-rsa"))
- return CKK_RSA;
- else if (match_word (algo, length, "ssh-dss"))
- return CKK_DSA;
- return G_MAXULONG;
-}
-
-static gboolean
-read_decimal_mpi (const gchar *decimal,
- gsize n_decimal,
- GckAttributes *attrs,
- gulong attribute_type)
-{
- gpointer data;
- gsize n_data;
-
- data = egg_decimal_decode (decimal, n_decimal, &n_data);
- if (data == NULL)
- return FALSE;
-
- gck_attributes_add_data (attrs, attribute_type, data, n_data);
- return TRUE;
-}
-
-static gint
-atoin (const char *p, gint digits)
-{
- gint ret = 0, base = 1;
- while(--digits >= 0) {
- if (p[digits] < '0' || p[digits] > '9')
- return -1;
- ret += (p[digits] - '0') * base;
- base *= 10;
- }
- return ret;
-}
-
-static GcrDataError
-parse_v1_public_line (const gchar *line,
- gsize length,
- GcrOpensshPubCallback callback,
- gpointer user_data)
-{
- const gchar *word_bits, *word_exponent, *word_modulus, *word_options, *outer;
- gsize len_bits, len_exponent, len_modulus, len_options, n_outer;
- GckAttributes *attrs;
- gchar *label, *options;
- gint bits;
-
- g_assert (line);
-
- outer = line;
- n_outer = length;
- options = NULL;
- label = NULL;
-
- /* Eat space at the front */
- skip_spaces (&line, &length);
-
- /* Blank line or comment */
- if (length == 0 || line[0] == '#')
- return GCR_ERROR_UNRECOGNIZED;
-
- /*
- * If the line starts with a digit, then no options:
- *
- * 2048 35 25213680043....93533757 Label
- *
- * If the line doesn't start with a digit, then have options:
- *
- * option,option 2048 35 25213680043....93533757 Label
- */
- if (g_ascii_isdigit (line[0])) {
- word_options = NULL;
- len_options = 0;
- } else {
- if (!next_word (&line, &length, &word_options, &len_options))
- return GCR_ERROR_UNRECOGNIZED;
- }
-
- if (!next_word (&line, &length, &word_bits, &len_bits) ||
- !next_word (&line, &length, &word_exponent, &len_exponent) ||
- !next_word (&line, &length, &word_modulus, &len_modulus))
- return GCR_ERROR_UNRECOGNIZED;
-
- bits = atoin (word_bits, len_bits);
- if (bits <= 0)
- return GCR_ERROR_UNRECOGNIZED;
-
- attrs = gck_attributes_new ();
-
- if (!read_decimal_mpi (word_exponent, len_exponent, attrs, CKA_PUBLIC_EXPONENT) ||
- !read_decimal_mpi (word_modulus, len_modulus, attrs, CKA_MODULUS)) {
- gck_attributes_unref (attrs);
- return GCR_ERROR_UNRECOGNIZED;
- }
-
- gck_attributes_add_ulong (attrs, CKA_KEY_TYPE, CKK_RSA);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
-
- skip_spaces (&line, &length);
- if (length > 0) {
- label = g_strndup (line, length);
- g_strstrip (label);
- gck_attributes_add_string (attrs, CKA_LABEL, label);
- }
-
- if (word_options)
- options = g_strndup (word_options, len_options);
-
- if (callback != NULL)
- (callback) (attrs, label, options, outer, n_outer, user_data);
-
- gck_attributes_unref (attrs);
- g_free (options);
- g_free (label);
- return GCR_SUCCESS;
-}
-
-static gboolean
-read_buffer_mpi (EggBuffer *buffer,
- gsize *offset,
- GckAttributes *attrs,
- gulong attribute_type)
-{
- const guchar *data;
- gsize len;
-
- if (!egg_buffer_get_byte_array (buffer, *offset, offset, &data, &len))
- return FALSE;
-
- gck_attributes_add_data (attrs, attribute_type, data, len);
- return TRUE;
-}
-
-static GckAttributes *
-read_v2_public_dsa (EggBuffer *buffer,
- gsize *offset)
-{
- GckAttributes *attrs;
-
- attrs = gck_attributes_new ();
-
- if (!read_buffer_mpi (buffer, offset, attrs, CKA_PRIME) ||
- !read_buffer_mpi (buffer, offset, attrs, CKA_SUBPRIME) ||
- !read_buffer_mpi (buffer, offset, attrs, CKA_BASE) ||
- !read_buffer_mpi (buffer, offset, attrs, CKA_VALUE)) {
- gck_attributes_unref (attrs);
- return NULL;
- }
-
- gck_attributes_add_ulong (attrs, CKA_KEY_TYPE, CKK_DSA);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
-
- return attrs;
-}
-
-static GckAttributes *
-read_v2_public_rsa (EggBuffer *buffer,
- gsize *offset)
-{
- GckAttributes *attrs;
-
- attrs = gck_attributes_new ();
-
- if (!read_buffer_mpi (buffer, offset, attrs, CKA_PUBLIC_EXPONENT) ||
- !read_buffer_mpi (buffer, offset, attrs, CKA_MODULUS)) {
- gck_attributes_unref (attrs);
- return NULL;
- }
-
- gck_attributes_add_ulong (attrs, CKA_KEY_TYPE, CKK_RSA);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
-
- return attrs;
-}
-
-static GckAttributes *
-read_v2_public_key (gulong algo,
- gconstpointer data,
- gsize n_data)
-{
- GckAttributes *attrs;
- EggBuffer buffer;
- gsize offset;
- gchar *stype;
- int alg;
-
- egg_buffer_init_static (&buffer, data, n_data);
- offset = 0;
-
- /* The string algorithm */
- if (!egg_buffer_get_string (&buffer, offset, &offset,
- &stype, (EggBufferAllocator)g_realloc))
- return NULL;
-
- alg = keytype_to_algo (stype, stype ? strlen (stype) : 0);
- g_free (stype);
-
- if (alg != algo) {
- g_message ("invalid or mis-matched algorithm in ssh public key: %s", stype);
- egg_buffer_uninit (&buffer);
- return NULL;
- }
-
- switch (algo) {
- case CKK_RSA:
- attrs = read_v2_public_rsa (&buffer, &offset);
- break;
- case CKK_DSA:
- attrs = read_v2_public_dsa (&buffer, &offset);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- egg_buffer_uninit (&buffer);
- return attrs;
-}
-
-static GckAttributes *
-decode_v2_public_key (gulong algo,
- const gchar *data,
- gsize n_data)
-{
- GckAttributes *attrs;
- gpointer decoded;
- gsize n_decoded;
- guint save;
- gint state;
-
- /* Decode the base64 key */
- save = state = 0;
- decoded = g_malloc (n_data * 3 / 4);
- n_decoded = g_base64_decode_step ((gchar*)data, n_data, decoded, &state, &save);
-
- if (!n_decoded) {
- g_free (decoded);
- return NULL;
- }
-
- /* Parse the actual key */
- attrs = read_v2_public_key (algo, decoded, n_decoded);
-
- g_free (decoded);
-
- return attrs;
-}
-
-static GcrDataError
-parse_v2_public_line (const gchar *line,
- gsize length,
- GcrOpensshPubCallback callback,
- gpointer user_data)
-{
- const gchar *word_options, *word_algo, *word_key;
- gsize len_options, len_algo, len_key;
- GckAttributes *attrs;
- gchar *options;
- gchar *label = NULL;
- const gchar *outer = line;
- gsize n_outer = length;
- gulong algo;
-
- g_assert (line);
-
- /* Eat space at the front */
- skip_spaces (&line, &length);
-
- /* Blank line or comment */
- if (length == 0 || line[0] == '#')
- return GCR_ERROR_UNRECOGNIZED;
-
- if (!next_word (&line, &length, &word_algo, &len_algo))
- return GCR_ERROR_UNRECOGNIZED;
-
- /*
- * If the first word is not the algorithm, then we have options:
- *
- * option,option ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAI...EAz8Ji= Label here
- *
- * If the first word is the algorithm, then we have no options:
- *
- * ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAI...EAz8Ji= Label here
- */
- algo = keytype_to_algo (word_algo, len_algo);
- if (algo == G_MAXULONG) {
- word_options = word_algo;
- len_options = len_algo;
- if (!next_word (&line, &length, &word_algo, &len_algo))
- return GCR_ERROR_UNRECOGNIZED;
- algo = keytype_to_algo (word_algo, len_algo);
- if (algo == G_MAXULONG)
- return GCR_ERROR_UNRECOGNIZED;
- } else {
- word_options = NULL;
- len_options = 0;
- }
-
- /* Must have at least two words */
- if (!next_word (&line, &length, &word_key, &len_key))
- return GCR_ERROR_FAILURE;
-
- attrs = decode_v2_public_key (algo, word_key, len_key);
- if (attrs == NULL)
- return GCR_ERROR_FAILURE;
-
- if (word_options)
- options = g_strndup (word_options, len_options);
- else
- options = NULL;
-
- /* The remainder of the line is the label */
- skip_spaces (&line, &length);
- if (length > 0) {
- label = g_strndup (line, length);
- g_strstrip (label);
- gck_attributes_add_string (attrs, CKA_LABEL, label);
- }
-
- if (callback != NULL)
- (callback) (attrs, label, options, outer, n_outer, user_data);
-
- gck_attributes_unref (attrs);
- g_free (options);
- g_free (label);
- return GCR_SUCCESS;
-}
-
-guint
-_gcr_openssh_pub_parse (gconstpointer data,
- gsize n_data,
- GcrOpensshPubCallback callback,
- gpointer user_data)
-{
- const gchar *line;
- const gchar *end;
- gsize length;
- gboolean last;
- GcrDataError res;
- guint num_parsed;
-
- g_return_val_if_fail (data, FALSE);
-
- line = data;
- length = n_data;
- last = FALSE;
- num_parsed = 0;
-
- for (;;) {
- end = memchr (line, '\n', length);
- if (end == NULL) {
- end = line + length;
- last = TRUE;
- }
-
- if (line != end) {
- res = parse_v2_public_line (line, end - line, callback, user_data);
- if (res == GCR_ERROR_UNRECOGNIZED)
- res = parse_v1_public_line (line, end - line, callback, user_data);
- if (res == GCR_SUCCESS)
- num_parsed++;
- }
-
- if (last)
- break;
-
- end++;
- length -= (end - line);
- line = end;
- }
-
- return num_parsed;
-}
diff --git a/gcr/gcr-openssh.h b/gcr/gcr-openssh.h
deleted file mode 100644
index 2fdac2a1..00000000
--- a/gcr/gcr-openssh.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_OPENSSH_H__
-#define __GCR_OPENSSH_H__
-
-#include <glib.h>
-
-#include <gck/gck.h>
-
-G_BEGIN_DECLS
-
-typedef void (*GcrOpensshPubCallback) (GckAttributes *attrs,
- const gchar *label,
- const gchar *options,
- const gchar *outer,
- gsize n_outer,
- gpointer user_data);
-
-guint _gcr_openssh_pub_parse (gconstpointer data,
- gsize n_data,
- GcrOpensshPubCallback callback,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* __GCR_OPENSSH_H__ */
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
deleted file mode 100644
index ffcdd091..00000000
--- a/gcr/gcr-parser.c
+++ /dev/null
@@ -1,2934 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gck/gck.h"
-
-#include "gcr-internal.h"
-#include "gcr-marshal.h"
-#include "gcr-oids.h"
-#include "gcr-openpgp.h"
-#include "gcr-openssh.h"
-#include "gcr-parser.h"
-#include "gcr-record.h"
-#include "gcr-types.h"
-
-#include "egg/egg-armor.h"
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-dn.h"
-#include "egg/egg-openssl.h"
-#include "egg/egg-secure-memory.h"
-#include "egg/egg-symkey.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <stdlib.h>
-#include <gcrypt.h>
-
-/**
- * SECTION:gcr-parser
- * @title: GcrParser
- * @short_description: Parser for certificate and key files
- *
- * A #GcrParser can parse various certificate and key files such as OpenSSL
- * PEM files, DER encoded certifictes, PKCS\#8 keys and so on. Each various
- * format is identified by a value in the #GcrDataFormat enumeration.
- *
- * In order to parse data, a new parser is created with gcr_parser_new() and
- * then the GcrParser::authenticate and GcrParser::parsed signals should be
- * connected to. Data is then fed to the parser via gcr_parser_parse_data()
- * or gcr_parser_parse_stream().
- *
- * During the GcrParsed::parsed signal the attributes that make up the currently
- * parsed item can be retrieved using the gcr_parser_get_parsed_attributes()
- * function.
- */
-
-/**
- * GcrParser:
- *
- * A parser for parsing various types of files or data.
- */
-
-/**
- * GcrParsed:
- *
- * A parsed item parsed by a #GcrParser.
- */
-
-/**
- * GcrParserClass:
- * @parent_class: The parent class
- * @authenticate: The default handler for the authenticate signal.
- * @parsed: The default handler for the parsed signal.
- *
- * The class for #GcrParser
- */
-
-/**
- * GCR_DATA_ERROR:
- *
- * A domain for data errors with codes from #GcrDataError
- */
-
-/**
- * GcrDataError
- * @GCR_ERROR_FAILURE: Failed to parse or serialize the data
- * @GCR_ERROR_UNRECOGNIZED: The data was unrecognized or unsupported
- * @GCR_ERROR_CANCELLED: The operation was cancelled
- * @GCR_ERROR_LOCKED: The data was encrypted or locked and could not be unlocked.
- *
- * Values responding to error codes for parsing and serializing data.
- */
-
-enum {
- PROP_0,
- PROP_PARSED_LABEL,
- PROP_PARSED_ATTRIBUTES,
- PROP_PARSED_DESCRIPTION
-};
-
-enum {
- AUTHENTICATE,
- PARSED,
- LAST_SIGNAL
-};
-
-#define SUCCESS 0
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-struct _GcrParsed {
- gint refs;
- GckAttributes *attrs;
- const gchar *description;
- gchar *label;
- gpointer data;
- gsize n_data;
- gboolean sensitive;
- GDestroyNotify destroy_func;
- GcrDataFormat format;
- struct _GcrParsed *next;
-};
-
-struct _GcrParserPrivate {
- GTree *specific_formats;
- gboolean normal_formats;
- GPtrArray *passwords;
- GcrParsed *parsed;
-};
-
-G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
-
-typedef struct {
- gint ask_state;
- gint seen;
-} PasswordState;
-
-#define PASSWORD_STATE_INIT { 0, 0 }
-
-typedef struct _ParserFormat {
- gint format_id;
- gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
-} ParserFormat;
-
-/* Forward declarations */
-static const ParserFormat parser_normal[];
-static const ParserFormat parser_formats[];
-static ParserFormat* parser_format_lookup (gint format_id);
-
-EGG_SECURE_DECLARE (parser);
-
-/* -----------------------------------------------------------------------------
- * QUARK DEFINITIONS
- */
-
-/*
- * PEM STRINGS
- * The xxxxx in: ----- BEGIN xxxxx ------
- */
-
-static GQuark PEM_CERTIFICATE;
-static GQuark PEM_RSA_PRIVATE_KEY;
-static GQuark PEM_DSA_PRIVATE_KEY;
-static GQuark PEM_ANY_PRIVATE_KEY;
-static GQuark PEM_ENCRYPTED_PRIVATE_KEY;
-static GQuark PEM_PRIVATE_KEY;
-static GQuark PEM_PKCS7;
-static GQuark PEM_PKCS12;
-
-static GQuark ARMOR_PGP_PUBLIC_KEY_BLOCK;
-static GQuark ARMOR_PGP_PRIVATE_KEY_BLOCK;
-
-static void
-init_quarks (void)
-{
- static volatile gsize quarks_inited = 0;
-
- _gcr_oids_init ();
-
- if (g_once_init_enter (&quarks_inited)) {
-
- #define QUARK(name, value) \
- name = g_quark_from_static_string(value)
-
- QUARK (PEM_CERTIFICATE, "CERTIFICATE");
- QUARK (PEM_PRIVATE_KEY, "PRIVATE KEY");
- QUARK (PEM_RSA_PRIVATE_KEY, "RSA PRIVATE KEY");
- QUARK (PEM_DSA_PRIVATE_KEY, "DSA PRIVATE KEY");
- QUARK (PEM_ANY_PRIVATE_KEY, "ANY PRIVATE KEY");
- QUARK (PEM_ENCRYPTED_PRIVATE_KEY, "ENCRYPTED PRIVATE KEY");
- QUARK (PEM_PKCS7, "PKCS7");
- QUARK (PEM_PKCS12, "PKCS12");
- QUARK (ARMOR_PGP_PRIVATE_KEY_BLOCK, "PGP PRIVATE KEY BLOCK");
- QUARK (ARMOR_PGP_PUBLIC_KEY_BLOCK, "PGP PUBLIC KEY BLOCK");
-
- #undef QUARK
-
- g_once_init_leave (&quarks_inited, 1);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-parsed_attribute (GcrParsed *parsed,
- CK_ATTRIBUTE_TYPE type,
- gconstpointer data,
- gsize n_data)
-{
- g_assert (parsed != NULL);
- g_assert (parsed->attrs != NULL);
- gck_attributes_add_data (parsed->attrs, type, data, n_data);
-}
-
-static gboolean
-parsed_asn1_number (GcrParsed *parsed,
- GNode *asn,
- const gchar *part,
- CK_ATTRIBUTE_TYPE type)
-{
- const guchar *value;
- gsize n_value;
-
- g_assert (asn);
- g_assert (parsed);
-
- value = egg_asn1x_get_integer_as_usg (egg_asn1x_node (asn, part, NULL), &n_value);
- if (value == NULL)
- return FALSE;
-
- parsed_attribute (parsed, type, value, n_value);
- return TRUE;
-}
-
-static gboolean
-parsed_asn1_element (GcrParsed *parsed,
- GNode *asn,
- const gchar *part,
- CK_ATTRIBUTE_TYPE type)
-{
- const guchar *value;
- gsize n_value;
-
- g_assert (asn);
- g_assert (parsed);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, part, NULL), &n_value);
- if (value == NULL)
- return FALSE;
-
- parsed_attribute (parsed, type, value, n_value);
- return TRUE;
-}
-
-static void
-parsed_ulong_attribute (GcrParsed *parsed,
- CK_ATTRIBUTE_TYPE type,
- gulong value)
-{
- g_assert (parsed != NULL);
- g_assert (parsed->attrs != NULL);
- gck_attributes_add_ulong (parsed->attrs, type, value);
-}
-
-static void
-parsed_boolean_attribute (GcrParsed *parsed,
- CK_ATTRIBUTE_TYPE type,
- gboolean value)
-{
- g_assert (parsed != NULL);
- g_assert (parsed->attrs != NULL);
- gck_attributes_add_boolean (parsed->attrs, type, value);
-}
-
-
-static void
-parsing_block (GcrParsed *parsed,
- gint format,
- gconstpointer data,
- gsize n_data)
-{
- g_assert (parsed != NULL);
- g_assert (data != NULL);
- g_assert (n_data != 0);
- g_assert (format);
- g_assert (parsed->data == NULL);
- g_assert (parsed->destroy_func == NULL);
-
- parsed->format = format;
- parsed->data = (gpointer)data;
- parsed->n_data = n_data;
-}
-
-static void
-parsed_description (GcrParsed *parsed,
- CK_OBJECT_CLASS klass)
-{
- g_assert (parsed != NULL);
- switch (klass) {
- case CKO_PRIVATE_KEY:
- parsed->description = _("Private Key");
- break;
- case CKO_CERTIFICATE:
- parsed->description = _("Certificate");
- break;
- case CKO_PUBLIC_KEY:
- parsed->description = _("Public Key");
- break;
- case CKO_GCR_GNUPG_RECORDS:
- parsed->description = _("PGP Key");
- break;
- default:
- parsed->description = NULL;
- break;
- }
-}
-
-static void
-parsing_object (GcrParsed *parsed,
- CK_OBJECT_CLASS klass)
-{
- g_assert (parsed != NULL);
- g_assert (parsed->attrs == NULL);
-
- if (parsed->sensitive)
- parsed->attrs = gck_attributes_new_full ((GckAllocator)egg_secure_realloc);
- else
- parsed->attrs = gck_attributes_new ();
- gck_attributes_add_ulong (parsed->attrs, CKA_CLASS, klass);
- parsed_description (parsed, klass);
-}
-
-static void
-parsed_attributes (GcrParsed *parsed,
- GckAttributes *attrs)
-{
- gulong klass;
-
- g_assert (parsed != NULL);
- g_assert (attrs != NULL);
- g_assert (parsed->attrs == NULL);
-
- parsed->attrs = gck_attributes_ref (attrs);
- if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
- parsed_description (parsed, klass);
-}
-
-static void
-parsed_label (GcrParsed *parsed,
- const gchar *label)
-{
- g_assert (parsed != NULL);
- g_assert (parsed->label == NULL);
- parsed->label = g_strdup (label);
-}
-
-static GcrParsed *
-push_parsed (GcrParser *self,
- gboolean sensitive)
-{
- GcrParsed *parsed = g_new0 (GcrParsed, 1);
- parsed->refs = 0;
- parsed->sensitive = sensitive;
- parsed->next = self->pv->parsed;
- self->pv->parsed = parsed;
- return parsed;
-}
-
-static void
-pop_parsed (GcrParser *self,
- GcrParsed *parsed)
-{
- g_assert (parsed == self->pv->parsed);
-
- self->pv->parsed = parsed->next;
-
- gck_attributes_unref (parsed->attrs);
- g_free (parsed->label);
- g_free (parsed);
-}
-
-static gint
-enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
-{
- gboolean result;
-
- /*
- * Next passes we look through all the passwords that the parser
- * has seen so far. This is because different parts of a encrypted
- * container (such as PKCS#12) often use the same password even
- * if with different algorithms.
- *
- * If we didn't do this and the user chooses enters a password,
- * but doesn't save it, they would get prompted for the same thing
- * over and over, dumb.
- */
-
- /* Look in our list of passwords */
- if (state->seen < self->pv->passwords->len) {
- g_assert (state->seen >= 0);
- *password = g_ptr_array_index (self->pv->passwords, state->seen);
- ++state->seen;
- return SUCCESS;
- }
-
- /* Fire off all the parsed property signals so anyone watching can update their state */
- g_object_notify (G_OBJECT (self), "parsed-description");
- g_object_notify (G_OBJECT (self), "parsed-attributes");
- g_object_notify (G_OBJECT (self), "parsed-label");
-
- g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
- ++state->ask_state;
-
- if (!result)
- return GCR_ERROR_CANCELLED;
-
- /* Return any passwords added */
- if (state->seen < self->pv->passwords->len) {
- g_assert (state->seen >= 0);
- *password = g_ptr_array_index (self->pv->passwords, state->seen);
- ++state->seen;
- return SUCCESS;
- }
-
- return GCR_ERROR_LOCKED;
-}
-
-static void
-parsed_fire (GcrParser *self,
- GcrParsed *parsed)
-{
- g_assert (GCR_IS_PARSER (self));
- g_assert (parsed != NULL);
- g_assert (parsed == self->pv->parsed);
-
- g_object_notify (G_OBJECT (self), "parsed-description");
- g_object_notify (G_OBJECT (self), "parsed-attributes");
- g_object_notify (G_OBJECT (self), "parsed-label");
-
- g_signal_emit (self, signals[PARSED], 0);
-}
-
-/* -----------------------------------------------------------------------------
- * RSA PRIVATE KEY
- */
-
-static gint
-parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
-{
- gint res = GCR_ERROR_UNRECOGNIZED;
- GNode *asn = NULL;
- gulong version;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, TRUE);
-
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
- parsing_object (parsed, CKO_PRIVATE_KEY);
- parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_RSA);
- parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
- res = GCR_ERROR_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) {
- res = GCR_ERROR_UNRECOGNIZED;
- g_message ("unsupported version of RSA key: %lu", version);
- goto done;
- }
-
- if (!parsed_asn1_number (parsed, asn, "modulus", CKA_MODULUS) ||
- !parsed_asn1_number (parsed, asn, "publicExponent", CKA_PUBLIC_EXPONENT) ||
- !parsed_asn1_number (parsed, asn, "privateExponent", CKA_PRIVATE_EXPONENT) ||
- !parsed_asn1_number (parsed, asn, "prime1", CKA_PRIME_1) ||
- !parsed_asn1_number (parsed, asn, "prime2", CKA_PRIME_2) ||
- !parsed_asn1_number (parsed, asn, "coefficient", CKA_COEFFICIENT))
- goto done;
-
- parsed_fire (self, parsed);
- res = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn);
- if (res == GCR_ERROR_FAILURE)
- g_message ("invalid RSA key");
-
- pop_parsed (self, parsed);
- return res;
-}
-
-/* -----------------------------------------------------------------------------
- * DSA PRIVATE KEY
- */
-
-static gint
-parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
-{
- gint ret = GCR_ERROR_UNRECOGNIZED;
- GNode *asn = NULL;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, TRUE);
-
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
- parsing_object (parsed, CKO_PRIVATE_KEY);
- parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
- parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
- ret = GCR_ERROR_FAILURE;
-
- if (!parsed_asn1_number (parsed, asn, "p", CKA_PRIME) ||
- !parsed_asn1_number (parsed, asn, "q", CKA_SUBPRIME) ||
- !parsed_asn1_number (parsed, asn, "g", CKA_BASE) ||
- !parsed_asn1_number (parsed, asn, "priv", CKA_VALUE))
- goto done;
-
- parsed_fire (self, parsed);
- ret = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn);
- if (ret == GCR_ERROR_FAILURE)
- g_message ("invalid DSA key");
-
- pop_parsed (self, parsed);
- return ret;
-}
-
-static gint
-parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
- const guchar *params, gsize n_params)
-{
- gint ret = GCR_ERROR_UNRECOGNIZED;
- GNode *asn_params = NULL;
- GNode *asn_key = NULL;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, TRUE);
-
- asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
- asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
- if (!asn_params || !asn_key)
- goto done;
-
- parsing_object (parsed, CKO_PRIVATE_KEY);
- parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
- parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
- ret = GCR_ERROR_FAILURE;
-
- if (!parsed_asn1_number (parsed, asn_params, "p", CKA_PRIME) ||
- !parsed_asn1_number (parsed, asn_params, "q", CKA_SUBPRIME) ||
- !parsed_asn1_number (parsed, asn_params, "g", CKA_BASE) ||
- !parsed_asn1_number (parsed, asn_key, NULL, CKA_VALUE))
- goto done;
-
- parsed_fire (self, parsed);
- ret = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn_key);
- egg_asn1x_destroy (asn_params);
- if (ret == GCR_ERROR_FAILURE)
- g_message ("invalid DSA key");
-
- pop_parsed (self, parsed);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * PRIVATE KEY
- */
-
-static gint
-parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
-{
- gint res;
-
- res = parse_der_private_key_rsa (self, data, n_data);
- if (res == GCR_ERROR_UNRECOGNIZED)
- res = parse_der_private_key_dsa (self, data, n_data);
-
- return res;
-}
-
-/* -----------------------------------------------------------------------------
- * PKCS8
- */
-
-static gint
-parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
-{
- gint ret;
- CK_KEY_TYPE key_type;
- GQuark key_algo;
- const guchar *keydata;
- gsize n_keydata;
- const guchar *params;
- gsize n_params;
- GNode *asn = NULL;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, TRUE);
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PKCS8_PLAIN, data, n_data);
- ret = GCR_ERROR_FAILURE;
- key_type = GCK_INVALID;
-
- key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
- if (!key_algo)
- goto done;
- else if (key_algo == GCR_OID_PKIX1_RSA)
- key_type = CKK_RSA;
- else if (key_algo == GCR_OID_PKIX1_DSA)
- key_type = CKK_DSA;
-
- if (key_type == GCK_INVALID) {
- ret = GCR_ERROR_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 = SUCCESS;
-
-done:
- if (ret == SUCCESS) {
- switch (key_type) {
- case CKK_RSA:
- ret = parse_der_private_key_rsa (self, keydata, n_keydata);
- break;
- case CKK_DSA:
- /* Try the normal sane format */
- ret = parse_der_private_key_dsa (self, keydata, n_keydata);
-
- /* Otherwise try the two part format that everyone seems to like */
- if (ret == GCR_ERROR_UNRECOGNIZED && params && n_params)
- ret = parse_der_private_key_dsa_parts (self, keydata, n_keydata,
- params, n_params);
- break;
- default:
- g_message ("invalid or unsupported key type in PKCS#8 key");
- ret = GCR_ERROR_UNRECOGNIZED;
- break;
- };
-
- } else if (ret == GCR_ERROR_FAILURE) {
- g_message ("invalid PKCS#8 key");
- }
-
- egg_asn1x_destroy (asn);
- pop_parsed (self, parsed);
- return ret;
-}
-
-static gint
-parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
-{
- PasswordState pstate = PASSWORD_STATE_INIT;
- GNode *asn = NULL;
- gcry_cipher_hd_t cih = NULL;
- gcry_error_t gcry;
- gint ret, r;
- GQuark scheme;
- guchar *crypted = NULL;
- const guchar *params;
- gsize n_crypted, n_params;
- const gchar *password;
- GcrParsed *parsed;
- gint l;
-
- parsed = push_parsed (self, FALSE);
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data, n_data);
- ret = GCR_ERROR_FAILURE;
-
- /* Figure out the type of encryption */
- scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
- if (!scheme)
- goto done;
-
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
-
- /* Loop to try different passwords */
- for (;;) {
-
- g_assert (cih == NULL);
-
- r = enum_next_password (self, &pstate, &password);
- if (r != SUCCESS) {
- ret = r;
- break;
- }
-
- /* Parse the encryption stuff into a cipher. */
- if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
- break;
-
- crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
- if (!crypted)
- break;
-
- gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
- gcry_cipher_close (cih);
- cih = NULL;
-
- if (gcry != 0) {
- g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
- break;
- }
-
- /* Unpad the DER data */
- l = egg_asn1x_element_length (crypted, n_crypted);
- if (l > 0)
- n_crypted = l;
-
- /* Try to parse the resulting key */
- r = parse_der_pkcs8_plain (self, crypted, n_crypted);
- egg_secure_free (crypted);
- crypted = NULL;
-
- if (r != GCR_ERROR_UNRECOGNIZED) {
- ret = r;
- break;
- }
-
- /* We assume unrecognized data, is a bad encryption key */
- }
-
-done:
- if (cih)
- gcry_cipher_close (cih);
- egg_asn1x_destroy (asn);
- egg_secure_free (crypted);
-
- pop_parsed (self, parsed);
- return ret;
-}
-
-static gint
-parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
-{
- gint ret;
-
- ret = parse_der_pkcs8_plain (self, data, n_data);
- if (ret == GCR_ERROR_UNRECOGNIZED)
- ret = parse_der_pkcs8_encrypted (self, data, n_data);
-
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * CERTIFICATE
- */
-
-static gint
-parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
-{
- gchar *name = NULL;
- GcrParsed *parsed;
- GNode *node;
- GNode *asn;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- if (asn == NULL)
- return GCR_ERROR_UNRECOGNIZED;
-
- parsed = push_parsed (self, FALSE);
-
- parsing_block (parsed, GCR_FORMAT_DER_CERTIFICATE_X509, data, n_data);
- parsing_object (parsed, CKO_CERTIFICATE);
- parsed_ulong_attribute (parsed, CKA_CERTIFICATE_TYPE, CKC_X_509);
-
- node = egg_asn1x_node (asn, "tbsCertificate", NULL);
- g_return_val_if_fail (node != NULL, GCR_ERROR_FAILURE);
-
- if (gcr_parser_get_parsed_label (self) == NULL)
- name = egg_dn_read_part (egg_asn1x_node (node, "subject", "rdnSequence", NULL), "CN");
-
- if (name != NULL) {
- parsed_label (parsed, name);
- g_free (name);
- }
-
- parsed_attribute (parsed, CKA_VALUE, data, n_data);
- parsed_asn1_element (parsed, node, "subject", CKA_SUBJECT);
- parsed_asn1_element (parsed, node, "issuer", CKA_ISSUER);
- parsed_asn1_number (parsed, node, "serialNumber", CKA_SERIAL_NUMBER);
- parsed_fire (self, parsed);
-
- egg_asn1x_destroy (asn);
-
- pop_parsed (self, parsed);
- return SUCCESS;
-}
-
-/* -----------------------------------------------------------------------------
- * PKCS7
- */
-
-static gint
-handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *node;
- gint ret;
- const guchar *certificate;
- gsize n_certificate;
- int i;
-
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data, n_data);
- if (!asn)
- goto done;
-
- ret = GCR_ERROR_FAILURE;
-
- for (i = 0; TRUE; ++i) {
-
- node = egg_asn1x_node (asn, "certificates", i + 1, NULL);
-
- /* No more certificates? */
- if (node == NULL)
- break;
-
- certificate = egg_asn1x_get_raw_element (node, &n_certificate);
-
- ret = parse_der_certificate (self, certificate, n_certificate);
- if (ret != SUCCESS)
- goto done;
- }
-
- /* TODO: Parse out all the CRLs */
-
- ret = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn);
- return ret;
-}
-
-static gint
-parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *node;
- gint ret;
- const guchar* content = NULL;
- gsize n_content;
- GQuark oid;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, FALSE);
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PKCS7, data, n_data);
- ret = GCR_ERROR_FAILURE;
-
- node = egg_asn1x_node (asn, "contentType", NULL);
- if (!node)
- goto done;
-
- oid = egg_asn1x_get_oid_as_quark (node);
- g_return_val_if_fail (oid, GCR_ERROR_FAILURE);
-
- /* Outer most one must just be plain data */
- if (oid != GCR_OID_PKCS7_SIGNED_DATA) {
- g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
- goto done;
- }
-
- content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL), &n_content);
- if (!content)
- goto done;
-
- ret = handle_pkcs7_signed_data (self, content, n_content);
-
-done:
- egg_asn1x_destroy (asn);
- pop_parsed (self, parsed);
- return ret;
-}
-
-/* -----------------------------------------------------------------------------
- * PKCS12
- */
-
-static GNode *
-decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
- const gchar *identifier,
- gconstpointer data,
- gsize n_data)
-{
- GNode *asn;
-
- /*
- * Because PKCS#12 files, the bags specifically, are notorious for
- * being crappily constructed and are often break rules such as DER
- * sorting order etc.. we parse the DER in a non-strict fashion.
- *
- * The rules in DER are designed for X.509 certificates, so there is
- * only one way to represent a given certificate (although they fail
- * at that as well). But with PKCS#12 we don't have such high
- * requirements, and we can slack off on our validation.
- */
-
- asn = egg_asn1x_create (defs, identifier);
- g_return_val_if_fail (asn != NULL, NULL);
-
- /* Passing FALSE as the strictness argument */
- if (!egg_asn1x_decode_no_validate (asn, data, n_data) ||
- !egg_asn1x_validate (asn, FALSE)) {
- egg_asn1x_destroy (asn);
- asn = NULL;
- }
-
- return asn;
-}
-
-static gint
-handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *asn_content = NULL;
- guchar *certificate = NULL;
- const guchar *element;
- gsize n_certificate, n_element;
- gint ret;
-
- ret = GCR_ERROR_UNRECOGNIZED;
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
- "pkcs-12-CertBag",
- data, n_data);
- if (!asn)
- goto done;
-
- ret = GCR_ERROR_FAILURE;
-
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL), &n_element);
- if (!element)
- goto done;
-
- asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
- if (!asn_content)
- goto done;
-
- certificate = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_certificate);
- if (!certificate)
- goto done;
-
- ret = parse_der_certificate (self, certificate, n_certificate);
-
-done:
- egg_asn1x_destroy (asn_content);
- egg_asn1x_destroy (asn);
- g_free (certificate);
- return ret;
-}
-
-static gchar *
-parse_pkcs12_bag_friendly_name (GNode *asn)
-{
- guint count, i;
- GQuark oid;
- GNode *node;
- gconstpointer element;
- gsize n_element;
- GNode *asn_str;
- gchar *result;
-
- if (asn == NULL)
- return NULL;
-
- count = egg_asn1x_count (asn);
- for (i = 1; i <= count; i++) {
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "type", NULL));
- if (oid == GCR_OID_PKCS9_ATTRIBUTE_FRIENDLY) {
- node = egg_asn1x_node (asn, i, "values", 1, NULL);
- if (node != NULL) {
- element = egg_asn1x_get_raw_element (node, &n_element);
- asn_str = egg_asn1x_create_and_decode (pkix_asn1_tab, "BMPString",
- element, n_element);
- if (asn_str) {
- result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
- egg_asn1x_destroy (asn_str);
- return result;
- }
- }
- }
- }
-
- return NULL;
-}
-
-static gint
-handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- gint ret, r;
- guint count = 0;
- GQuark oid;
- const guchar *element;
- gchar *friendly;
- gsize n_element;
- guint i;
- GcrParsed *parsed;
-
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
- "pkcs-12-SafeContents",
- data, n_data);
- if (!asn)
- goto done;
-
- ret = GCR_ERROR_FAILURE;
-
- /* Get the number of elements in this bag */
- count = egg_asn1x_count (asn);
-
- /*
- * Now inside each bag are multiple elements. Who comes up
- * with this stuff?
- */
- for (i = 1; i <= count; i++) {
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "bagId", NULL));
- if (!oid)
- goto done;
-
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, i, "bagValue", NULL), &n_element);
- if (!element)
- goto done;
-
- parsed = push_parsed (self, FALSE);
-
- friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
- if (friendly != NULL)
- parsed_label (parsed, friendly);
-
- /* A normal unencrypted key */
- if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
- r = parse_der_pkcs8_plain (self, element, n_element);
-
- /* A properly encrypted key */
- } else if (oid == GCR_OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
- r = parse_der_pkcs8_encrypted (self, element, n_element);
-
- /* A certificate */
- } else if (oid == GCR_OID_PKCS12_BAG_CERTIFICATE) {
- r = handle_pkcs12_cert_bag (self, element, n_element);
-
- /* TODO: GCR_OID_PKCS12_BAG_CRL */
- } else {
- r = GCR_ERROR_UNRECOGNIZED;
- }
-
- pop_parsed (self, parsed);
-
- if (r == GCR_ERROR_FAILURE ||
- r == GCR_ERROR_CANCELLED ||
- r == GCR_ERROR_LOCKED) {
- ret = r;
- goto done;
- }
- }
-
- ret = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn);
- return ret;
-}
-
-static gint
-handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
-{
- PasswordState pstate = PASSWORD_STATE_INIT;
- GNode *asn = NULL;
- gcry_cipher_hd_t cih = NULL;
- gcry_error_t gcry;
- guchar *crypted = NULL;
- const guchar *params;
- gsize n_params, n_crypted;
- const gchar *password;
- GQuark scheme;
- gint ret, r;
- gint l;
-
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
- "pkcs-7-EncryptedData",
- data, n_data);
- if (!asn)
- goto done;
-
- ret = GCR_ERROR_FAILURE;
-
- /* Check the encryption schema OID */
- scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "algorithm", NULL));
- if (!scheme)
- goto done;
-
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL), &n_params);
- if (!params)
- goto done;
-
- /* Loop to try different passwords */
- for (;;) {
-
- g_assert (cih == NULL);
-
- r = enum_next_password (self, &pstate, &password);
- if (r != SUCCESS) {
- ret = r;
- goto done;
- }
-
- /* Parse the encryption stuff into a cipher. */
- if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih)) {
- ret = GCR_ERROR_FAILURE;
- goto done;
- }
-
- crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedContentInfo", "encryptedContent", NULL),
- egg_secure_realloc, &n_crypted);
- if (!crypted)
- goto done;
-
- gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
- gcry_cipher_close (cih);
- cih = NULL;
-
- if (gcry != 0) {
- g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
- goto done;
- }
-
- /* Unpad the DER data */
- l = egg_asn1x_element_length (crypted, n_crypted);
- if (l > 0)
- n_crypted = l;
-
- /* Try to parse the resulting key */
- r = handle_pkcs12_bag (self, crypted, n_crypted);
- egg_secure_free (crypted);
- crypted = NULL;
-
- if (r != GCR_ERROR_UNRECOGNIZED) {
- ret = r;
- break;
- }
-
- /* We assume unrecognized data is a bad encryption key */
- }
-
-done:
- if (cih)
- gcry_cipher_close (cih);
- egg_asn1x_destroy (asn);
- egg_secure_free (crypted);
- return ret;
-}
-
-static gint
-handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *asn_content = NULL;
- gint ret, r;
- const guchar *bag;
- guchar *content = NULL;
- gsize n_bag, n_content;
- GQuark oid;
- guint i;
- GNode *node;
-
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
- "pkcs-12-AuthenticatedSafe",
- data, n_data);
- if (!asn)
- goto done;
-
- ret = GCR_ERROR_FAILURE;
-
- /*
- * Inside each PKCS12 safe there are multiple bags.
- */
- for (i = 0; TRUE; ++i) {
- node = egg_asn1x_node (asn, i + 1, "contentType", NULL);
-
- /* All done? no more bags */
- if (!node)
- break;
-
- oid = egg_asn1x_get_oid_as_quark (node);
-
- node = egg_asn1x_node (asn, i + 1, "content", NULL);
- if (!node)
- goto done;
-
- bag = egg_asn1x_get_raw_element (node, &n_bag);
- g_return_val_if_fail (bag, ret);
-
- /* A non encrypted bag, just parse */
- if (oid == GCR_OID_PKCS7_DATA) {
-
- egg_asn1x_destroy (asn_content);
- asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
- "pkcs-7-Data",
- bag, n_bag);
- if (!asn_content)
- goto done;
-
- g_free (content);
- content = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_content);
- if (!content)
- goto done;
-
- r = handle_pkcs12_bag (self, content, n_content);
-
- /* Encrypted data first needs decryption */
- } else if (oid == GCR_OID_PKCS7_ENCRYPTED_DATA) {
- r = handle_pkcs12_encrypted_bag (self, bag, n_bag);
-
- /* Hmmmm, not sure what this is */
- } else {
- g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
- r = GCR_ERROR_UNRECOGNIZED;
- }
-
- if (r == GCR_ERROR_FAILURE ||
- r == GCR_ERROR_CANCELLED ||
- r == GCR_ERROR_LOCKED) {
- ret = r;
- goto done;
- }
- }
-
- ret = SUCCESS;
-
-done:
- egg_asn1x_destroy (asn);
- egg_asn1x_destroy (asn_content);
- g_free (content);
- return ret;
-}
-
-static gint
-verify_pkcs12_safe (GcrParser *self,
- GNode *asn,
- gconstpointer content,
- gsize n_content)
-{
- PasswordState pstate = PASSWORD_STATE_INIT;
- const gchar *password;
- gcry_md_hd_t mdh = NULL;
- const guchar *mac_digest;
- gsize mac_len;
- guchar *digest = NULL;
- gsize n_digest;
- GQuark algorithm;
- GNode *mac_data;
- gconstpointer params;
- gsize n_params;
- int ret, r;
-
- ret = GCR_ERROR_FAILURE;
-
- /*
- * The MAC is optional (and outside the encryption no less). I wonder
- * what the designers (ha) of PKCS#12 were trying to achieve
- */
-
- mac_data = egg_asn1x_node (asn, "macData", NULL);
- if (mac_data == NULL)
- return SUCCESS;
-
- algorithm = egg_asn1x_get_oid_as_quark (egg_asn1x_node (mac_data, "mac",
- "digestAlgorithm", "algorithm", NULL));
- if (!algorithm)
- goto done;
-
- params = egg_asn1x_get_raw_element (mac_data, &n_params);
- if (!params)
- goto done;
-
- digest = egg_asn1x_get_string_as_raw (egg_asn1x_node (mac_data, "mac", "digest", NULL), NULL, &n_digest);
- if (!digest)
- goto done;
-
- /* Loop to try different passwords */
- for (;;) {
- g_assert (mdh == NULL);
-
- r = enum_next_password (self, &pstate, &password);
- if (r != SUCCESS) {
- ret = r;
- goto done;
- }
-
- /* Parse the encryption stuff into a cipher. */
- if (!egg_symkey_read_mac (algorithm, password, -1, params, n_params,
- &mdh, &mac_len)) {
- ret = GCR_ERROR_FAILURE;
- goto done;
- }
-
- /* If not the right length, then that's really broken */
- if (mac_len != n_digest) {
- r = GCR_ERROR_FAILURE;
-
- } else {
- gcry_md_write (mdh, content, n_content);
- mac_digest = gcry_md_read (mdh, 0);
- g_return_val_if_fail (mac_digest, GCR_ERROR_FAILURE);
- r = memcmp (mac_digest, digest, n_digest) == 0 ? SUCCESS : GCR_ERROR_LOCKED;
- }
-
- gcry_md_close (mdh);
- mdh = NULL;
-
- if (r != GCR_ERROR_LOCKED) {
- ret = r;
- break;
- }
- }
-
-done:
- if (mdh)
- gcry_md_close (mdh);
- g_free (digest);
- return ret;
-
-}
-
-static gint
-parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
-{
- GNode *asn = NULL;
- GNode *asn_content = NULL;
- gint ret;
- const guchar* element = NULL;
- guchar *content = NULL;
- gsize n_element, n_content;
- GQuark oid;
- GcrParsed *parsed;
-
- parsed = push_parsed (self, FALSE);
- ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX",
- data, n_data);
- if (!asn)
- goto done;
-
- parsing_block (parsed, GCR_FORMAT_DER_PKCS12, data, n_data);
-
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
- if (!oid)
- goto done;
-
- /* Outer most one must just be plain data */
- if (oid != GCR_OID_PKCS7_DATA) {
- g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
- goto done;
- }
-
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL), &n_element);
- if (!element)
- goto done;
-
- asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-7-Data",
- element, n_element);
- if (!asn_content)
- goto done;
-
- content = egg_asn1x_get_string_as_raw (asn_content, g_realloc, &n_content);
- if (!content)
- goto done;
-
- ret = verify_pkcs12_safe (self, asn, content, n_content);
- if (ret == SUCCESS)
- ret = handle_pkcs12_safe (self, content, n_content);
-
-done:
- g_free (content);
- egg_asn1x_destroy (asn_content);
- egg_asn1x_destroy (asn);
- pop_parsed (self, parsed);
- return ret;
-}
-
-
-/* -----------------------------------------------------------------------------
- * OPENPGP
- */
-
-static void
-on_openpgp_packet (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
- gpointer user_data)
-{
- GcrParser *self = GCR_PARSER (user_data);
- GcrParsed *parsed;
- gchar *string;
-
- /*
- * If it's an openpgp packet that doesn't contain a key, then
- * just ignore it here.
- */
- if (records->len == 0)
- return;
-
- parsed = push_parsed (self, FALSE);
-
- /* All we can do is the packet bounds */
- parsing_block (parsed, GCR_FORMAT_OPENPGP_PACKET, outer, n_outer);
- parsing_object (parsed, CKO_GCR_GNUPG_RECORDS);
- string = _gcr_records_format (records);
- parsed_attribute (parsed, CKA_VALUE, string, strlen (string));
- parsed_fire (self, parsed);
- pop_parsed (self, parsed);
-
- g_free (string);
-}
-
-static gint
-parse_openpgp_packets (GcrParser *self,
- const guchar *data,
- gsize n_data)
-{
- gint num_parsed;
-
- num_parsed = _gcr_openpgp_parse (data, n_data,
- GCR_OPENPGP_PARSE_KEYS |
- GCR_OPENPGP_PARSE_ATTRIBUTES |
- GCR_OPENPGP_PARSE_SIGNATURES,
- on_openpgp_packet, self);
-
- if (num_parsed == 0)
- return GCR_ERROR_UNRECOGNIZED;
- return SUCCESS;
-}
-
-/* -----------------------------------------------------------------------------
- * ARMOR PARSING
- */
-
-static gboolean
-formats_for_armor_type (GQuark armor_type,
- gint *inner_format,
- gint *outer_format)
-{
- gint dummy;
- if (!inner_format)
- inner_format = &dummy;
- if (!outer_format)
- outer_format = &dummy;
-
- if (armor_type == PEM_RSA_PRIVATE_KEY) {
- *inner_format = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
- *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_RSA;
- } else if (armor_type == PEM_DSA_PRIVATE_KEY) {
- *inner_format = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
- *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_DSA;
- } else if (armor_type == PEM_ANY_PRIVATE_KEY) {
- *inner_format = GCR_FORMAT_DER_PRIVATE_KEY;
- *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY;
- } else if (armor_type == PEM_PRIVATE_KEY) {
- *inner_format = GCR_FORMAT_DER_PKCS8_PLAIN;
- *outer_format = GCR_FORMAT_PEM_PKCS8_PLAIN;
- } else if (armor_type == PEM_ENCRYPTED_PRIVATE_KEY) {
- *inner_format = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
- *outer_format = GCR_FORMAT_PEM_PKCS8_ENCRYPTED;
- } else if (armor_type == PEM_CERTIFICATE) {
- *inner_format = GCR_FORMAT_DER_CERTIFICATE_X509;
- *outer_format = GCR_FORMAT_PEM_CERTIFICATE_X509;
- } else if (armor_type == PEM_PKCS7) {
- *inner_format = GCR_FORMAT_DER_PKCS7;
- *outer_format = GCR_FORMAT_PEM_PKCS7;
- } else if (armor_type == PEM_PKCS12) {
- *inner_format = GCR_FORMAT_DER_PKCS12;
- *outer_format = GCR_FORMAT_PEM_PKCS12;
- } else if (armor_type == ARMOR_PGP_PRIVATE_KEY_BLOCK) {
- *inner_format = GCR_FORMAT_OPENPGP_PACKET;
- *outer_format = GCR_FORMAT_OPENPGP_ARMOR;
- } else if (armor_type == ARMOR_PGP_PUBLIC_KEY_BLOCK) {
- *inner_format = GCR_FORMAT_OPENPGP_PACKET;
- *outer_format = GCR_FORMAT_OPENPGP_ARMOR;
- } else {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gint
-handle_plain_pem (GcrParser *self,
- gint format_id,
- gint want_format,
- const guchar *data,
- gsize n_data)
-{
- ParserFormat *format;
-
- if (want_format != 0 && want_format != format_id)
- return GCR_ERROR_UNRECOGNIZED;
-
- format = parser_format_lookup (format_id);
- if (format == NULL)
- return GCR_ERROR_UNRECOGNIZED;
-
- return (format->function) (self, data, n_data);
-}
-
-static gint
-handle_encrypted_pem (GcrParser *self,
- gint format_id,
- gint want_format,
- GHashTable *headers,
- const guchar *data,
- gsize n_data)
-{
- PasswordState pstate = PASSWORD_STATE_INIT;
- const gchar *password;
- guchar *decrypted;
- gsize n_decrypted;
- const gchar *val;
- gboolean ret;
- gint res;
- gint l;
-
- g_assert (GCR_IS_PARSER (self));
- g_assert (headers);
-
- val = g_hash_table_lookup (headers, "DEK-Info");
- if (!val) {
- g_message ("missing encryption header");
- return GCR_ERROR_FAILURE;
- }
-
- res = GCR_ERROR_FAILURE;
- for (;;) {
-
- res = enum_next_password (self, &pstate, &password);
- if (res != SUCCESS)
- break;
-
- decrypted = NULL;
- n_decrypted = 0;
-
- /* Decrypt, this will result in garble if invalid password */
- ret = egg_openssl_decrypt_block (val, password, -1, data, n_data,
- &decrypted, &n_decrypted);
- if (!ret) {
- res = GCR_ERROR_FAILURE;
- break;
- }
-
- g_assert (decrypted);
-
- /* Unpad the DER data */
- l = egg_asn1x_element_length (decrypted, n_decrypted);
- if (l > 0)
- n_decrypted = l;
-
- /* Try to parse */
- res = handle_plain_pem (self, format_id, want_format,
- decrypted, n_decrypted);
- egg_secure_free (decrypted);
-
- /* Unrecognized is a bad password */
- if (res != GCR_ERROR_UNRECOGNIZED)
- break;
- }
-
- return res;
-}
-
-typedef struct {
- GcrParser *parser;
- gint result;
- gint want_format;
-} HandlePemArgs;
-
-static void
-handle_pem_data (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
- GHashTable *headers,
- gpointer user_data)
-{
- HandlePemArgs *args = (HandlePemArgs*)user_data;
- gint res = GCR_ERROR_FAILURE;
- gboolean encrypted = FALSE;
- const gchar *val;
- gint inner_format;
- gint outer_format;
- GcrParsed *parsed;
-
- /* Something already failed to parse */
- if (args->result == GCR_ERROR_FAILURE)
- return;
-
- if (!formats_for_armor_type (type, &inner_format, &outer_format))
- return;
-
- parsed = push_parsed (args->parser, FALSE);
-
- /* Fill in information necessary for prompting */
- parsing_block (parsed, outer_format, outer, n_outer);
-
- /* See if it's encrypted PEM all openssl like*/
- if (headers) {
- val = g_hash_table_lookup (headers, "Proc-Type");
- if (val && strcmp (val, "4,ENCRYPTED") == 0)
- encrypted = TRUE;
- }
-
- if (encrypted)
- res = handle_encrypted_pem (args->parser, inner_format,
- args->want_format, headers,
- data, n_data);
- else
- res = handle_plain_pem (args->parser, inner_format,
- args->want_format, data, n_data);
-
- pop_parsed (args->parser, parsed);
-
- if (res != GCR_ERROR_UNRECOGNIZED) {
- if (args->result == GCR_ERROR_UNRECOGNIZED)
- args->result = res;
- else if (res > args->result)
- args->result = res;
- }
-}
-
-static gint
-handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
-{
- HandlePemArgs ctx = { self, GCR_ERROR_UNRECOGNIZED, subformat };
- guint found;
-
- if (n_data == 0)
- return GCR_ERROR_UNRECOGNIZED;
-
- found = egg_armor_parse (data, n_data, handle_pem_data, &ctx);
-
- if (found == 0)
- return GCR_ERROR_UNRECOGNIZED;
-
- return ctx.result;
-}
-
-
-static gint
-parse_pem (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, 0, data, n_data);
-}
-
-static gint
-parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
-}
-
-static gint
-parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
-}
-
-static gint
-parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_CERTIFICATE_X509, data, n_data);
-}
-
-static gint
-parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_PLAIN, data, n_data);
-}
-
-static gint
-parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data, n_data);
-}
-
-static gint
-parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS7, data, n_data);
-}
-
-static gint
-parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS12, data, n_data);
-}
-
-static gint
-parse_openpgp_armor (GcrParser *self,
- const guchar *data,
- gsize n_data)
-{
- return handle_pem_format (self, GCR_FORMAT_OPENPGP_PACKET, data, n_data);
-}
-
-/* -----------------------------------------------------------------------------
- * OPENSSH
- */
-
-static void
-on_openssh_public_key_parsed (GckAttributes *attrs,
- const gchar *label,
- const gchar *options,
- const gchar *outer,
- gsize n_outer,
- gpointer user_data)
-{
- GcrParser *self = GCR_PARSER (user_data);
- GcrParsed *parsed;
-
- parsed = push_parsed (self, FALSE);
- parsing_block (parsed, GCR_FORMAT_OPENSSH_PUBLIC, outer, n_outer);
- parsed_attributes (parsed, attrs);
- parsed_label (parsed, label);
- parsed_fire (self, parsed);
- pop_parsed (self, parsed);
-}
-
-static gint
-parse_openssh_public (GcrParser *self,
- const guchar *data,
- gsize n_data)
-{
- guint num_parsed;
-
- num_parsed = _gcr_openssh_pub_parse (data, n_data,
- on_openssh_public_key_parsed, self);
-
- if (num_parsed == 0)
- return GCR_ERROR_UNRECOGNIZED;
- return SUCCESS;
-}
-
-/* -----------------------------------------------------------------------------
- * FORMATS
- */
-
-/**
- * GcrDataFormat:
- * @GCR_FORMAT_ALL: Represents all the formats, when enabling or disabling
- * @GCR_FORMAT_INVALID: Not a valid format
- * @GCR_FORMAT_DER_PRIVATE_KEY: DER encoded private key
- * @GCR_FORMAT_DER_PRIVATE_KEY_RSA: DER encoded RSA private key
- * @GCR_FORMAT_DER_PRIVATE_KEY_DSA: DER encoded DSA private key
- * @GCR_FORMAT_DER_CERTIFICATE_X509: DER encoded X.509 certificate
- * @GCR_FORMAT_DER_PKCS7: DER encoded PKCS\#7 container file which can contain certificates
- * @GCR_FORMAT_DER_PKCS8: DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS8_PLAIN: Unencrypted DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS8_ENCRYPTED: Encrypted DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS12: DER encoded PKCS\#12 file which can contain certificates and/or keys
- * @GCR_FORMAT_OPENSSH_PUBLIC: OpenSSH v1 or v2 public key
- * @GCR_FORMAT_OPENPGP_PACKET: OpenPGP key packet(s)
- * @GCR_FORMAT_OPENPGP_ARMOR: OpenPGP public or private key armor encoded data
- * @GCR_FORMAT_PEM: An OpenSSL style PEM file with unspecified contents
- * @GCR_FORMAT_PEM_PRIVATE_KEY: An OpenSSL style PEM file with a private key
- * @GCR_FORMAT_PEM_PRIVATE_KEY_RSA: An OpenSSL style PEM file with a private RSA key
- * @GCR_FORMAT_PEM_PRIVATE_KEY_DSA: An OpenSSL style PEM file with a private DSA key
- * @GCR_FORMAT_PEM_CERTIFICATE_X509: An OpenSSL style PEM file with an X.509 certificate
- * @GCR_FORMAT_PEM_PKCS7: An OpenSSL style PEM file containing PKCS\#7
- * @GCR_FORMAT_PEM_PKCS8_PLAIN: Unencrypted OpenSSL style PEM file containing PKCS\#8
- * @GCR_FORMAT_PEM_PKCS8_ENCRYPTED: Encrypted OpenSSL style PEM file containing PKCS\#8
- * @GCR_FORMAT_PEM_PKCS12: An OpenSSL style PEM file containing PKCS\#12
- *
- * The various format identifiers.
- */
-
-/* In order of parsing when no formats specified */
-static const ParserFormat parser_normal[] = {
- { GCR_FORMAT_PEM, parse_pem },
- { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
- { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
- { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
- { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
- { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
- { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
- { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
- { GCR_FORMAT_OPENSSH_PUBLIC, parse_openssh_public },
- { GCR_FORMAT_OPENPGP_PACKET, parse_openpgp_packets },
- { GCR_FORMAT_OPENPGP_ARMOR, parse_openpgp_armor },
-};
-
-/* Must be in format_id numeric order */
-static const ParserFormat parser_formats[] = {
- { GCR_FORMAT_DER_PRIVATE_KEY, parse_der_private_key },
- { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
- { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
- { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
- { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
- { GCR_FORMAT_DER_PKCS8, parse_der_pkcs8 },
- { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
- { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
- { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
- { GCR_FORMAT_OPENSSH_PUBLIC, parse_openssh_public },
- { GCR_FORMAT_OPENPGP_PACKET, parse_openpgp_packets },
- { GCR_FORMAT_OPENPGP_ARMOR, parse_openpgp_armor },
- { GCR_FORMAT_PEM, parse_pem },
- { GCR_FORMAT_PEM_PRIVATE_KEY_RSA, parse_pem_private_key_rsa },
- { GCR_FORMAT_PEM_PRIVATE_KEY_DSA, parse_pem_private_key_dsa },
- { GCR_FORMAT_PEM_CERTIFICATE_X509, parse_pem_certificate },
- { GCR_FORMAT_PEM_PKCS7, parse_pem_pkcs7 },
- { GCR_FORMAT_PEM_PKCS8_PLAIN, parse_pem_pkcs8_plain },
- { GCR_FORMAT_PEM_PKCS8_ENCRYPTED, parse_pem_pkcs8_encrypted },
- { GCR_FORMAT_PEM_PKCS12, parse_pem_pkcs12 },
-};
-
-static int
-compar_id_to_parser_format (const void *a, const void *b)
-{
- const gint *format_id = a;
- const ParserFormat *format = b;
-
- g_assert (format_id);
- g_assert (format);
-
- if (format->format_id == *format_id)
- return 0;
- return (*format_id < format->format_id) ? -1 : 1;
-}
-
-static ParserFormat*
-parser_format_lookup (gint format_id)
-{
- return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
- sizeof (parser_formats[0]), compar_id_to_parser_format);
-}
-
-static gint
-compare_pointers (gconstpointer a, gconstpointer b)
-{
- if (a == b)
- return 0;
- return a < b ? -1 : 1;
-}
-
-typedef struct _ForeachArgs {
- GcrParser *parser;
- const guchar *data;
- gsize n_data;
- gint result;
-} ForeachArgs;
-
-static gboolean
-parser_format_foreach (gpointer key, gpointer value, gpointer data)
-{
- ForeachArgs *args = data;
- ParserFormat *format = key;
- gint result;
-
- g_assert (format);
- g_assert (format->function);
- g_assert (GCR_IS_PARSER (args->parser));
-
- result = (format->function) (args->parser, args->data, args->n_data);
- if (result != GCR_ERROR_UNRECOGNIZED) {
- args->result = result;
- return TRUE;
- }
-
- /* Keep going */
- return FALSE;
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-
-static GObject*
-gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GcrParser *self = GCR_PARSER (G_OBJECT_CLASS (gcr_parser_parent_class)->constructor(type, n_props, props));
- g_return_val_if_fail (self, NULL);
-
- /* Always try to parse with NULL and empty passwords first */
- gcr_parser_add_password (self, NULL);
- gcr_parser_add_password (self, "");
-
- return G_OBJECT (self);
-}
-
-static void
-gcr_parser_init (GcrParser *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PARSER, GcrParserPrivate);
- self->pv->passwords = g_ptr_array_new ();
- self->pv->normal_formats = TRUE;
-}
-
-static void
-gcr_parser_dispose (GObject *obj)
-{
- GcrParser *self = GCR_PARSER (obj);
- gsize i;
-
- g_assert (!self->pv->parsed);
-
- for (i = 0; i < self->pv->passwords->len; ++i)
- egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
- g_ptr_array_set_size (self->pv->passwords, 0);
-
- G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
-}
-
-static void
-gcr_parser_finalize (GObject *obj)
-{
- GcrParser *self = GCR_PARSER (obj);
-
- g_assert (!self->pv->parsed);
-
- g_ptr_array_free (self->pv->passwords, TRUE);
- self->pv->passwords = NULL;
-
- G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
-}
-
-static void
-gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrParser *self = GCR_PARSER (obj);
-
- switch (prop_id) {
- case PROP_PARSED_ATTRIBUTES:
- g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
- break;
- case PROP_PARSED_LABEL:
- g_value_set_string (value, gcr_parser_get_parsed_label (self));
- break;
- case PROP_PARSED_DESCRIPTION:
- g_value_set_string (value, gcr_parser_get_parsed_description (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_parser_class_init (GcrParserClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gint i;
-
- gobject_class->constructor = gcr_parser_constructor;
- gobject_class->dispose = gcr_parser_dispose;
- gobject_class->finalize = gcr_parser_finalize;
- gobject_class->set_property = gcr_parser_set_property;
- gobject_class->get_property = gcr_parser_get_property;
-
- /**
- * GcrParser:parsed-attributes:
- *
- * Get the attributes that make up the currently parsed item. This is
- * generally only valid during a #GcrParser::parsed signal.
- */
- g_type_class_add_private (gobject_class, sizeof (GcrParserPrivate));
-
- g_object_class_install_property (gobject_class, PROP_PARSED_ATTRIBUTES,
- g_param_spec_boxed ("parsed-attributes", "Parsed Attributes", "Parsed PKCS#11 attributes",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READABLE));
-
- /**
- * GcrParser:parsed-label:
- *
- * The label of the currently parsed item. This is generally
- * only valid during a #GcrParser::parsed signal.
- */
- g_object_class_install_property (gobject_class, PROP_PARSED_LABEL,
- g_param_spec_string ("parsed-label", "Parsed Label", "Parsed item label",
- "", G_PARAM_READABLE));
-
- /**
- * GcrParser:parsed-description:
- *
- * The description of the type of the currently parsed item. This is generally
- * only valid during a #GcrParser::parsed signal.
- */
- g_object_class_install_property (gobject_class, PROP_PARSED_DESCRIPTION,
- g_param_spec_string ("parsed-description", "Parsed Description", "Parsed item description",
- "", G_PARAM_READABLE));
-
- /**
- * GcrParser::authenticate:
- * @count: The number of times this item has been authenticated.
- *
- * This signal is emitted when an item needs to be unlocked or decrypted before
- * it can be parsed. The @count argument specifies the number of times
- * the signal has been emitted for a given item. This can be used to
- * display a message saying the previous password was incorrect.
- *
- * Typically the gcr_parser_add_password() function is called in
- * response to this signal.
- *
- * If %FALSE is returned, then the authentication was not handled. If
- * no handlers return %TRUE then the item is not parsed and an error
- * with the code %GCR_ERROR_CANCELLED will be raised.
- *
- * Returns: Whether the authentication was handled.
- */
- signals[AUTHENTICATE] = g_signal_new ("authenticate", GCR_TYPE_PARSER,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrParserClass, authenticate),
- g_signal_accumulator_true_handled, NULL, _gcr_marshal_BOOLEAN__INT,
- G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
-
- /**
- * GcrParser::parsed:
- *
- * This signal is emitted when an item is sucessfully parsed. To access
- * the information about the item use the gcr_parser_get_parsed_label(),
- * gcr_parser_get_parsed_attributes() and gcr_parser_get_parsed_description()
- * functions.
- */
- signals[PARSED] = g_signal_new ("parsed", GCR_TYPE_PARSER,
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrParserClass, parsed),
- NULL, NULL, g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- init_quarks ();
- _gcr_initialize_library ();
-
- /* Check that the format tables are in order */
- for (i = 1; i < G_N_ELEMENTS (parser_formats); ++i)
- g_assert (parser_formats[i].format_id >= parser_formats[i - 1].format_id);
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_parser_new:
- *
- * Create a new #GcrParser
- *
- * Returns: (transfer full): a newly allocated #GcrParser
- */
-GcrParser *
-gcr_parser_new (void)
-{
- return g_object_new (GCR_TYPE_PARSER, NULL);
-}
-
-/**
- * gcr_parser_add_password:
- * @self: The parser
- * @password: (allow-none): a password to try
- *
- * Add a password to the set of passwords to try when parsing locked or encrypted
- * items. This is usually called from the GcrParser::authenticate signal.
- */
-void
-gcr_parser_add_password (GcrParser *self, const gchar *password)
-{
- g_return_if_fail (GCR_IS_PARSER (self));
- g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
-}
-
-/**
- * gcr_parser_parse_data:
- * @self: The parser
- * @data: (array length=n_data): the data to parse
- * @n_data: The length of the data
- * @error: A location to raise an error on failure.
- *
- * Parse the data. The GcrParser::parsed and GcrParser::authenticate signals
- * may fire during the parsing.
- *
- * Returns: Whether the data was parsed successfully or not.
- */
-gboolean
-gcr_parser_parse_data (GcrParser *self,
- const guchar *data,
- gsize n_data,
- GError **error)
-{
- ForeachArgs args = { self, data, n_data, GCR_ERROR_UNRECOGNIZED };
- const gchar *message = NULL;
- gint i;
-
- g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
- g_return_val_if_fail (data || !n_data, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- if (data && n_data) {
- /* Just the specific formats requested */
- if (self->pv->specific_formats) {
- g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
-
- /* All the 'normal' formats */
- } else if (self->pv->normal_formats) {
- for (i = 0; i < G_N_ELEMENTS (parser_normal); ++i) {
- if (parser_format_foreach ((gpointer)(parser_normal + i),
- (gpointer)(parser_normal + i), &args))
- break;
- }
- }
- }
-
- switch (args.result) {
- case SUCCESS:
- return TRUE;
- case GCR_ERROR_CANCELLED:
- message = _("The operation was cancelled");
- break;
- case GCR_ERROR_UNRECOGNIZED:
- message = _("Unrecognized or unsupported data.");
- break;
- case GCR_ERROR_FAILURE:
- message = _("Could not parse invalid or corrupted data.");
- break;
- case GCR_ERROR_LOCKED:
- message = _("The data is locked");
- break;
- default:
- g_assert_not_reached ();
- break;
- };
-
- g_set_error_literal (error, GCR_DATA_ERROR, args.result, message);
- return FALSE;
-}
-
-/**
- * gcr_parser_format_enable:
- * @self: The parser
- * @format: The format identifier
- *
- * Enable parsing of the given format. Use %GCR_FORMAT_ALL to enable all the formats.
- */
-void
-gcr_parser_format_enable (GcrParser *self,
- GcrDataFormat format)
-{
- const ParserFormat *form;
- guint i;
-
- g_return_if_fail (GCR_IS_PARSER (self));
-
- if (!self->pv->specific_formats)
- self->pv->specific_formats = g_tree_new (compare_pointers);
-
- if (format != -1) {
- form = parser_format_lookup (format);
- g_return_if_fail (form);
- g_tree_insert (self->pv->specific_formats,
- (gpointer)form, (gpointer)form);
- } else {
- for (i = 0; i < G_N_ELEMENTS (parser_formats); i++) {
- form = &parser_formats[i];
- g_tree_insert (self->pv->specific_formats, (gpointer)form,
- (gpointer)form);
- }
- }
-}
-
-/**
- * gcr_parser_format_disable:
- * @self: The parser
- * @format: The format identifier
- *
- * Disable parsing of the given format. Use %GCR_FORMAT_ALL to disable all the formats.
- */
-void
-gcr_parser_format_disable (GcrParser *self,
- GcrDataFormat format)
-{
- ParserFormat *form;
-
- g_return_if_fail (GCR_IS_PARSER (self));
-
- if (format == -1) {
- if (self->pv->specific_formats)
- g_tree_destroy (self->pv->specific_formats);
- self->pv->specific_formats = NULL;
- self->pv->normal_formats = FALSE;
- }
-
- if (!self->pv->specific_formats)
- return;
-
- form = parser_format_lookup (format);
- g_return_if_fail (form);
-
- g_tree_remove (self->pv->specific_formats, form);
-}
-
-/**
- * gcr_parser_format_supported:
- * @self: The parser
- * @format: The format identifier
- *
- * Check whether the given format is supported by the parser.
- *
- * Returns: Whether the format is supported.
- */
-gboolean
-gcr_parser_format_supported (GcrParser *self,
- GcrDataFormat format)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
- g_return_val_if_fail (format != GCR_FORMAT_ALL, FALSE);
- g_return_val_if_fail (format != GCR_FORMAT_INVALID, FALSE);
- return parser_format_lookup (format) ? TRUE : FALSE;
-}
-
-/**
- * gcr_parser_get_parsed:
- * @self: a parser
- *
- * Get the currently parsed item
- *
- * Returns: (transfer none): the currently parsed item
- */
-GcrParsed *
-gcr_parser_get_parsed (GcrParser *self)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- return self->pv->parsed;
-}
-
-GType
-gcr_parsed_get_type (void)
-{
- static volatile gsize initialized = 0;
- static GType type = 0;
- if (g_once_init_enter (&initialized)) {
- type = g_boxed_type_register_static ("GcrParsed",
- (GBoxedCopyFunc)gcr_parsed_ref,
- (GBoxedFreeFunc)gcr_parsed_unref);
- g_once_init_leave (&initialized, 1);
- }
- return type;
-}
-
-/**
- * gcr_parsed_ref:
- * @parsed: a parsed item
- *
- * Add a reference to a parsed item. An item may not be shared across threads
- * until it has been referenced at least once.
- *
- * Returns: (transfer full): the parsed item
- */
-GcrParsed *
-gcr_parsed_ref (GcrParsed *parsed)
-{
- GcrParsed *copy;
-
- g_return_val_if_fail (parsed != NULL, NULL);
-
- /* Already had a reference */
-#if GLIB_CHECK_VERSION (2,29,90)
- if (g_atomic_int_add (&parsed->refs, 1) >= 1)
-#else
- if (g_atomic_int_exchange_and_add (&parsed->refs, 1) >= 1)
-#endif
- return parsed;
-
- /* If this is the first reference, flatten the stack of parsed */
- copy = g_new0 (GcrParsed, 1);
- copy->refs = 1;
- copy->label = g_strdup (gcr_parsed_get_label (parsed));
- copy->attrs = gcr_parsed_get_attributes (parsed);
- if (copy->attrs)
- gck_attributes_ref (copy->attrs);
- copy->description = gcr_parsed_get_description (parsed);
- copy->next = NULL;
-
- /* Find the block of data to copy */
- while (parsed != NULL) {
- if (parsed->data != NULL) {
- if (parsed->sensitive) {
- copy->data = egg_secure_alloc (parsed->n_data);
- memcpy (copy->data, parsed->data, parsed->n_data);
- copy->destroy_func = egg_secure_free;
- } else {
- copy->data = g_memdup (parsed->data, parsed->n_data);
- copy->destroy_func = g_free;
- }
- copy->n_data = parsed->n_data;
- break;
- }
- parsed = parsed->next;
- }
-
- return copy;
-}
-
-/**
- * gcr_parsed_unref:
- * @parsed: a parsed item
- *
- * Unreferences a parsed item which was referenced with gcr_parsed_ref()
- */
-void
-gcr_parsed_unref (gpointer parsed)
-{
- GcrParsed *par = parsed;
-
- g_return_if_fail (parsed != NULL);
-
- if (g_atomic_int_dec_and_test (&par->refs)) {
- if (par->attrs)
- gck_attributes_unref (par->attrs);
- g_free (par->label);
- if (par->destroy_func)
- (par->destroy_func) (par->data);
- g_free (par);
- }
-}
-
-/**
- * gcr_parser_get_parsed_description:
- * @self: The parser
- *
- * Get a description for the type of the currently parsed item. This is generally
- * only valid during the GcrParser::parsed signal.
- *
- * Returns: (allow-none): the description for the current item; this is owned by
- * the parser and should not be freed
- */
-const gchar*
-gcr_parser_get_parsed_description (GcrParser *self)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- g_return_val_if_fail (self->pv->parsed != NULL, NULL);
-
- return gcr_parsed_get_description (self->pv->parsed);
-}
-
-/**
- * gcr_parsed_get_description:
- * @parsed: a parsed item
- *
- * Get the descirption for a parsed item.
- *
- * Returns: (allow-none): the description
- */
-const gchar*
-gcr_parsed_get_description (GcrParsed *parsed)
-{
- while (parsed != NULL) {
- if (parsed->description != NULL)
- return parsed->description;
- parsed = parsed->next;
- }
-
- return NULL;
-}
-
-/**
- * gcr_parser_get_parsed_attributes:
- * @self: The parser
- *
- * Get the attributes which make up the currently parsed item. This is generally
- * only valid during the GcrParser::parsed signal.
- *
- * Returns: (transfer none) (allow-none): the attributes for the current item,
- * which are owned by the parser and should not be freed
- */
-GckAttributes *
-gcr_parser_get_parsed_attributes (GcrParser *self)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- g_return_val_if_fail (self->pv->parsed != NULL, NULL);
-
- return gcr_parsed_get_attributes (self->pv->parsed);
-}
-
-/**
- * gcr_parsed_get_attributes:
- * @parsed: a parsed item
- *
- * Get the attributes which make up the parsed item.
- *
- * Returns: (transfer none) (allow-none): the attributes for the item; these
- * are owned by the parsed item and should not be freed
- */
-GckAttributes *
-gcr_parsed_get_attributes (GcrParsed *parsed)
-{
- while (parsed != NULL) {
- if (parsed->attrs != NULL)
- return parsed->attrs;
- parsed = parsed->next;
- }
-
- return NULL;
-}
-
-/**
- * gcr_parser_get_parsed_label:
- * @self: The parser
- *
- * Get the label of the currently parsed item. This is generally only valid
- * during the GcrParser::parsed signal.
- *
- * Returns: (allow-none): the label of the currently parsed item. The value is
- * owned by the parser and should not be freed.
- */
-const gchar*
-gcr_parser_get_parsed_label (GcrParser *self)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- g_return_val_if_fail (self->pv->parsed != NULL, NULL);
-
- return gcr_parsed_get_label (self->pv->parsed);
-}
-
-/**
- * gcr_parsed_get_label:
- * @parsed: a parsed item
- *
- * Get the label for the parsed item.
- *
- * Returns: (allow-none): the label for the item
- */
-const gchar*
-gcr_parsed_get_label (GcrParsed *parsed)
-{
- while (parsed != NULL) {
- if (parsed->label != NULL)
- return parsed->label;
- parsed = parsed->next;
- }
-
- return NULL;
-}
-
-/**
- * gcr_parser_get_parsed_block:
- * @self: a parser
- * @n_block: a location to place the size of the block
- *
- * Get the raw data block that represents this parsed object. This is only
- * valid during the GcrParser::parsed signal.
- *
- * Returns: (transfer none) (array length=n_block) (allow-none): the raw data
- * block of the currently parsed item; the value is owned by the parser
- * and should not be freed
- */
-const guchar *
-gcr_parser_get_parsed_block (GcrParser *self,
- gsize *n_block)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- g_return_val_if_fail (n_block != NULL, NULL);
- g_return_val_if_fail (self->pv->parsed != NULL, NULL);
-
- return gcr_parsed_get_data (self->pv->parsed, n_block);
-}
-
-/**
- * gcr_parsed_get_data:
- * @parsed: a parsed item
- * @n_data: location to store size of returned data
- *
- * Get the raw data block for the parsed item.
- *
- * Returns: (transfer full) (array length=n_data) (allow-none): the raw data of
- * the parsed item, or %NULL
- */
-const guchar *
-gcr_parsed_get_data (GcrParsed *parsed,
- gsize *n_data)
-{
- g_return_val_if_fail (n_data != NULL, NULL);
-
- while (parsed != NULL) {
- if (parsed->data != NULL) {
- *n_data = parsed->n_data;
- return parsed->data;
- }
- parsed = parsed->next;
- }
-
- *n_data = 0;
- return NULL;
-}
-
-/**
- * gcr_parser_get_parsed_format:
- * @self: a parser
- *
- * Get the format of the raw data block that represents this parsed object.
- * This corresponds with the data returned from gcr_parser_get_parsed_block().
- *
- * This is only valid during the GcrParser::parsed signal.
- *
- * Returns: the data format of the currently parsed item
- */
-GcrDataFormat
-gcr_parser_get_parsed_format (GcrParser *self)
-{
- g_return_val_if_fail (GCR_IS_PARSER (self), 0);
- g_return_val_if_fail (self->pv->parsed != NULL, 0);
-
- return gcr_parsed_get_format (self->pv->parsed);
-}
-
-/**
- * gcr_parsed_get_format:
- * @parsed: a parsed item
- *
- * Get the format of the parsed item.
- *
- * Returns: the data format of the item
- */
-GcrDataFormat
-gcr_parsed_get_format (GcrParsed *parsed)
-{
- while (parsed != NULL) {
- if (parsed->data != NULL)
- return parsed->format;
- parsed = parsed->next;
- }
-
- return 0;
-}
-/* ---------------------------------------------------------------------------------
- * STREAM PARSING
- */
-
-#define GCR_TYPE_PARSING (gcr_parsing_get_type ())
-#define GCR_PARSING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSING, GcrParsing))
-#define GCR_IS_PARSING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSING))
-
-typedef struct _GcrParsing {
- GObjectClass parent;
-
- GcrParser *parser;
- gboolean async;
- GCancellable *cancel;
-
- /* Failure information */
- GError *error;
- gboolean complete;
-
- /* Operation state */
- GInputStream *input;
- GByteArray *buffer;
-
- /* Async callback stuff */
- GAsyncReadyCallback callback;
- gpointer user_data;
-
-} GcrParsing;
-
-typedef struct _GcrParsingClass {
- GObjectClass parent_class;
-} GcrParsingClass;
-
-/* State forward declarations */
-static void state_cancelled (GcrParsing *self, gboolean async);
-static void state_failure (GcrParsing *self, gboolean async);
-static void state_complete (GcrParsing *self, gboolean async);
-static void state_parse_buffer (GcrParsing *self, gboolean async);
-static void state_read_buffer (GcrParsing *self, gboolean async);
-
-/* Other forward declarations */
-static GType gcr_parsing_get_type (void) G_GNUC_CONST;
-static void gcr_parsing_async_result_init (GAsyncResultIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrParsing, gcr_parsing, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gcr_parsing_async_result_init));
-
-#define BLOCK 4096
-
-static void
-next_state (GcrParsing *self, void (*state) (GcrParsing*, gboolean))
-{
- g_assert (GCR_IS_PARSING (self));
- g_assert (state);
-
- if (self->cancel && g_cancellable_is_cancelled (self->cancel))
- state = state_cancelled;
-
- (state) (self, self->async);
-}
-
-static void
-state_complete (GcrParsing *self, gboolean async)
-{
- g_assert (GCR_IS_PARSING (self));
- g_assert (!self->complete);
- self->complete = TRUE;
- if (async && self->callback != NULL)
- (self->callback) (G_OBJECT (self->parser), G_ASYNC_RESULT (self), self->user_data);
-}
-
-static void
-state_failure (GcrParsing *self, gboolean async)
-{
- g_assert (GCR_IS_PARSING (self));
- g_assert (self->error);
- next_state (self, state_complete);
-}
-
-static void
-state_cancelled (GcrParsing *self, gboolean async)
-{
- g_assert (GCR_IS_PARSING (self));
- if (self->cancel && g_cancellable_is_cancelled (self->cancel))
- g_cancellable_cancel (self->cancel);
- if (self->error)
- g_error_free (self->error);
- self->error = g_error_new_literal (GCR_DATA_ERROR, GCR_ERROR_CANCELLED, _("The operation was cancelled"));
- next_state (self, state_failure);
-}
-
-static void
-state_parse_buffer (GcrParsing *self, gboolean async)
-{
- GError *error = NULL;
- gboolean ret;
-
- g_assert (GCR_IS_PARSING (self));
- g_assert (self->buffer);
-
- ret = gcr_parser_parse_data (self->parser, self->buffer->data, self->buffer->len, &error);
-
- if (ret == TRUE) {
- next_state (self, state_complete);
- } else {
- g_propagate_error (&self->error, error);
- next_state (self, state_failure);
- }
-}
-
-static void
-complete_read_buffer (GcrParsing *self, gssize count, GError *error)
-{
- g_assert (GCR_IS_PARSING (self));
- g_assert (self->buffer);
-
- /* A failure */
- if (count == -1) {
- g_propagate_error (&self->error, error);
- next_state (self, state_failure);
- } else {
-
- g_return_if_fail (count >= 0 && count <= BLOCK);
- g_byte_array_set_size (self->buffer, self->buffer->len - (BLOCK - count));
-
- /* Finished reading */
- if (count == 0)
- next_state (self, state_parse_buffer);
-
- /* Read the next block */
- else
- next_state (self, state_read_buffer);
- }
-
-}
-
-static void
-on_read_buffer (GObject *obj, GAsyncResult *res, gpointer user_data)
-{
- GError *error = NULL;
- gssize count;
-
- count = g_input_stream_read_finish (G_INPUT_STREAM (obj), res, &error);
- complete_read_buffer (user_data, count, error);
-}
-
-static void
-state_read_buffer (GcrParsing *self, gboolean async)
-{
- GError *error = NULL;
- gssize count;
- gsize at;
-
- g_assert (GCR_IS_PARSING (self));
- g_assert (G_IS_INPUT_STREAM (self->input));
-
- if (!self->buffer)
- self->buffer = g_byte_array_sized_new (BLOCK);
-
- at = self->buffer->len;
- g_byte_array_set_size (self->buffer, at + BLOCK);
-
- if (async) {
- g_input_stream_read_async (self->input, self->buffer->data + at,
- BLOCK, G_PRIORITY_DEFAULT, self->cancel,
- on_read_buffer, self);
- } else {
- count = g_input_stream_read (self->input, self->buffer->data + at,
- BLOCK, self->cancel, &error);
- complete_read_buffer (self, count, error);
- }
-}
-
-static void
-gcr_parsing_init (GcrParsing *self)
-{
-
-}
-
-static void
-gcr_parsing_finalize (GObject *obj)
-{
- GcrParsing *self = GCR_PARSING (obj);
-
- g_object_unref (self->parser);
- self->parser = NULL;
-
- g_object_unref (self->input);
- self->input = NULL;
-
- if (self->cancel)
- g_object_unref (self->cancel);
- self->cancel = NULL;
-
- g_clear_error (&self->error);
-
- if (self->buffer)
- g_byte_array_free (self->buffer, TRUE);
- self->buffer = NULL;
-
- G_OBJECT_CLASS (gcr_parsing_parent_class)->finalize (obj);
-}
-
-static void
-gcr_parsing_class_init (GcrParsingClass *klass)
-{
- G_OBJECT_CLASS (klass)->finalize = gcr_parsing_finalize;
-}
-
-static gpointer
-gcr_parsing_real_get_user_data (GAsyncResult *base)
-{
- g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
- return GCR_PARSING (base)->user_data;
-}
-
-static GObject*
-gcr_parsing_real_get_source_object (GAsyncResult *base)
-{
- g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
- return G_OBJECT (GCR_PARSING (base)->parser);
-}
-
-static void
-gcr_parsing_async_result_init (GAsyncResultIface *iface)
-{
- iface->get_source_object = gcr_parsing_real_get_source_object;
- iface->get_user_data = gcr_parsing_real_get_user_data;
-}
-
-static GcrParsing*
-gcr_parsing_new (GcrParser *parser, GInputStream *input, GCancellable *cancel)
-{
- GcrParsing *self;
-
- g_assert (GCR_IS_PARSER (parser));
- g_assert (G_IS_INPUT_STREAM (input));
-
- self = g_object_new (GCR_TYPE_PARSING, NULL);
- self->parser = g_object_ref (parser);
- self->input = g_object_ref (input);
- if (cancel)
- self->cancel = g_object_ref (cancel);
-
- return self;
-}
-
-/**
- * gcr_parser_parse_stream:
- * @self: The parser
- * @input: The input stream
- * @cancellable: An optional cancellation object
- * @error: A location to raise an error on failure
- *
- * Parse items from the data in a #GInputStream. This function may block while
- * reading from the input stream. Use gcr_parser_parse_stream_async() for
- * a non-blocking variant.
- *
- * The GcrParser::parsed and GcrParser::authenticate signals
- * may fire during the parsing.
- *
- * Returns: Whether the parsing completed successfully or not.
- */
-gboolean
-gcr_parser_parse_stream (GcrParser *self, GInputStream *input, GCancellable *cancellable,
- GError **error)
-{
- GcrParsing *parsing;
-
- g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
- g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- parsing = gcr_parsing_new (self, input, cancellable);
- parsing->async = FALSE;
-
- next_state (parsing, state_read_buffer);
- g_assert (parsing->complete);
-
- return gcr_parser_parse_stream_finish (self, G_ASYNC_RESULT (parsing), error);
-}
-
-/**
- * gcr_parser_parse_stream_async:
- * @self: The parser
- * @input: The input stream
- * @cancellable: An optional cancellation object
- * @callback: Called when the operation result is ready.
- * @user_data: Data to pass to callback
- *
- * Parse items from the data in a #GInputStream. This function completes
- * asyncronously and doesn't block.
- *
- * The GcrParser::parsed and GcrParser::authenticate signals
- * may fire during the parsing.
- */
-void
-gcr_parser_parse_stream_async (GcrParser *self, GInputStream *input, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GcrParsing *parsing;
-
- g_return_if_fail (GCR_IS_PARSER (self));
- g_return_if_fail (G_IS_INPUT_STREAM (input));
-
- parsing = gcr_parsing_new (self, input, cancellable);
- parsing->async = TRUE;
- parsing->callback = callback;
- parsing->user_data = user_data;
-
- next_state (parsing, state_read_buffer);
-}
-
-/**
- * gcr_parser_parse_stream_finish:
- * @self: The parser
- * @result:The operation result
- * @error: A location to raise an error on failure
- *
- * Complete an operation to parse a stream.
- *
- * Returns: Whether the parsing completed successfully or not.
- */
-gboolean
-gcr_parser_parse_stream_finish (GcrParser *self, GAsyncResult *result, GError **error)
-{
- GcrParsing *parsing;
-
- g_return_val_if_fail (GCR_IS_PARSING (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- parsing = GCR_PARSING (result);
- g_return_val_if_fail (parsing->complete, FALSE);
-
- if (parsing->error) {
- g_propagate_error (error, parsing->error);
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/gcr/gcr-parser.h b/gcr/gcr-parser.h
deleted file mode 100644
index 99a7e872..00000000
--- a/gcr/gcr-parser.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_PARSER_H__
-#define __GCR_PARSER_H__
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_PARSER (gcr_parser_get_type ())
-#define GCR_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSER, GcrParser))
-#define GCR_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PARSER, GcrParserClass))
-#define GCR_IS_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSER))
-#define GCR_IS_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PARSER))
-#define GCR_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PARSER, GcrParserClass))
-
-typedef struct _GcrParser GcrParser;
-typedef struct _GcrParserClass GcrParserClass;
-typedef struct _GcrParserPrivate GcrParserPrivate;
-typedef struct _GcrParsed GcrParsed;
-
-struct _GcrParser {
- GObject parent;
-
- /*< private >*/
- GcrParserPrivate *pv;
-};
-
-struct _GcrParserClass {
- GObjectClass parent_class;
-
- /* signals --------------------------------------------------------- */
-
- /* A callback for each password needed */
- gboolean (*authenticate) (GcrParser *self, gint count);
-
- void (*parsed) (GcrParser *self);
-};
-
-GType gcr_parser_get_type (void);
-
-GcrParser* gcr_parser_new (void);
-
-void gcr_parser_format_enable (GcrParser *self,
- GcrDataFormat format);
-
-void gcr_parser_format_disable (GcrParser *self,
- GcrDataFormat format);
-
-gboolean gcr_parser_format_supported (GcrParser *self,
- GcrDataFormat format);
-
-gboolean gcr_parser_parse_data (GcrParser *self,
- const guchar *data,
- gsize n_data,
- GError **error);
-
-gboolean gcr_parser_parse_stream (GcrParser *self,
- GInputStream *input,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_parser_parse_stream_async (GcrParser *self,
- GInputStream *input,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_parser_parse_stream_finish (GcrParser *self,
- GAsyncResult *result,
- GError **error);
-
-void gcr_parser_add_password (GcrParser *self,
- const gchar *password);
-
-GcrParsed * gcr_parser_get_parsed (GcrParser *self);
-
-const gchar* gcr_parser_get_parsed_label (GcrParser *self);
-
-const gchar* gcr_parser_get_parsed_description (GcrParser *self);
-
-GckAttributes* gcr_parser_get_parsed_attributes (GcrParser *self);
-
-const guchar * gcr_parser_get_parsed_block (GcrParser *self,
- gsize *n_block);
-
-GcrDataFormat gcr_parser_get_parsed_format (GcrParser *self);
-
-#define GCR_TYPE_PARSED (gcr_parsed_get_type ())
-
-GType gcr_parsed_get_type (void) G_GNUC_CONST;
-
-GcrParsed * gcr_parsed_ref (GcrParsed *parsed);
-
-void gcr_parsed_unref (gpointer parsed);
-
-const gchar* gcr_parsed_get_label (GcrParsed *parsed);
-
-const gchar* gcr_parsed_get_description (GcrParsed *parsed);
-
-GckAttributes* gcr_parsed_get_attributes (GcrParsed *parsed);
-
-const guchar * gcr_parsed_get_data (GcrParsed *parsed,
- gsize *n_data);
-
-GcrDataFormat gcr_parsed_get_format (GcrParsed *parsed);
-
-G_END_DECLS
-
-#endif /* __GCR_PARSER_H__ */
diff --git a/gcr/gcr-pkcs11-certificate.c b/gcr/gcr-pkcs11-certificate.c
deleted file mode 100644
index 25c22079..00000000
--- a/gcr/gcr-pkcs11-certificate.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-pkcs11-certificate.h"
-
-#include <gck/gck.h>
-#include <string.h>
-
-#include "gcr-certificate.h"
-#include "gcr-internal.h"
-#include "gcr-library.h"
-
-#include "pkcs11/pkcs11.h"
-
-/**
- * SECTION:gcr-pkcs11-certificate
- * @title: GcrPkcs11Certificate
- * @short_description: A certificate loaded from PKCS\#11 storage
- *
- * A #GcrPkcs11Certificate is a certificate loaded from a PKCS\#11 storage.
- * It is also a valid #GckObject and can be used as such.
- *
- * Use gcr_pkcs11_certificate_lookup_issuer() to lookup the issuer of a given
- * certificate in the PKCS\#11 store.
- *
- * Various common PKCS\#11 certificate attributes are automatically loaded and
- * are available via gcr_pkcs11_certificate_get_attributes().
- */
-
-/**
- * GcrPkcs11Certificate:
- *
- * A certificate loaded from PKCS\#11 storage.
- */
-
-/**
- * GcrPkcs11CertificateClass:
- *
- * The class for #GcrPkcs11Certificate.
- */
-
-enum {
- PROP_0,
- PROP_ATTRIBUTES
-};
-
-struct _GcrPkcs11CertificatePrivate {
- GckAttributes *attrs;
-};
-
-static void gcr_certificate_iface (GcrCertificateIface *iface);
-G_DEFINE_TYPE_WITH_CODE (GcrPkcs11Certificate, gcr_pkcs11_certificate, GCK_TYPE_OBJECT,
- GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface);
-);
-
-typedef struct {
- GckAttributes *search;
- GcrCertificate *result;
-} lookup_issuer_closure;
-
-static void
-lookup_issuer_free (gpointer data)
-{
- lookup_issuer_closure *closure = data;
- gck_attributes_unref (closure->search);
- g_clear_object (&closure->result);
- g_free (closure);
-}
-
-static GckAttributes *
-prepare_lookup_certificate_issuer (GcrCertificate *cert)
-{
- GckAttributes *search;
- gpointer data;
- gsize n_data;
-
- search = gck_attributes_new ();
- gck_attributes_add_ulong (search, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (search, CKA_CERTIFICATE_TYPE, CKC_X_509);
-
- data = gcr_certificate_get_issuer_raw (cert, &n_data);
- gck_attributes_add_data (search, CKA_SUBJECT, data, n_data);
- g_free (data);
-
- return search;
-}
-
-static GcrCertificate*
-perform_lookup_certificate (GckAttributes *search,
- GCancellable *cancellable,
- GError **error)
-{
- GcrCertificate *cert;
- GckObject *object;
- GckAttributes *attrs;
- GckModule *module;
- GckSession *session;
- GckEnumerator *en;
- GList *modules;
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return NULL;
-
- modules = gcr_pkcs11_get_modules ();
- en = gck_modules_enumerate_objects (modules, search, 0);
- gck_list_unref_free (modules);
-
- object = gck_enumerator_next (en, cancellable, error);
- g_object_unref (en);
-
- if (object == NULL)
- return NULL;
-
- /*
- * Only the CKA_VALUE, CKA_CLASS and CKA_CERTIFICATE_TYPE
- * is strictly necessary here, but we get more attrs.
- */
- attrs = gck_object_get (object, cancellable, error,
- CKA_VALUE, CKA_LABEL,
- CKA_ID, CKA_CLASS,
- CKA_CERTIFICATE_TYPE,
- CKA_ISSUER,
- CKA_SERIAL_NUMBER,
- GCK_INVALID);
-
- if (attrs == NULL) {
- g_object_unref (object);
- return NULL;
- }
-
- module = gck_object_get_module (object);
- session = gck_object_get_session (object);
-
- cert = g_object_new (GCR_TYPE_PKCS11_CERTIFICATE,
- "module", module,
- "handle", gck_object_get_handle (object),
- "session", session,
- "attributes", attrs,
- NULL);
-
- g_object_unref (module);
- g_object_unref (session);
- g_object_unref (object);
-
- gck_attributes_unref (attrs);
-
- return cert;
-}
-
-static void
-thread_lookup_certificate (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
-{
- lookup_issuer_closure *closure;
- GError *error = NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- closure->result = perform_lookup_certificate (closure->search, cancel, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (res, error);
- g_clear_error (&error);
- }
-}
-
-/* ----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-gcr_pkcs11_certificate_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- gpointer obj = G_OBJECT_CLASS (gcr_pkcs11_certificate_parent_class)->constructor (type, n_props, props);
- GckAttributes *attrs;
- GckAttribute *attr;
- gulong value;
-
- attrs = gcr_pkcs11_certificate_get_attributes (obj);
- g_return_val_if_fail (attrs, NULL);
-
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &value) ||
- value != CKO_CERTIFICATE) {
- g_warning ("attributes don't contain a certificate with: %s",
- "CKA_CLASS == CKO_CERTIFICATE");
- return NULL;
- }
-
- if (!gck_attributes_find_ulong (attrs, CKA_CERTIFICATE_TYPE, &value) ||
- value != CKC_X_509) {
- g_warning ("attributes don't contain a certificate with: %s",
- "CKA_CERTIFICATE_TYPE == CKC_X_509");
- return NULL;
- }
-
- attr = gck_attributes_find (attrs, CKA_VALUE);
- if (!attr || !attr->value || attr->length == 0 || attr->length == G_MAXULONG) {
- g_warning ("attributes don't contain a valid: CKA_VALUE");
- return NULL;
- }
-
- return obj;
-}
-
-static void
-gcr_pkcs11_certificate_init (GcrPkcs11Certificate *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PKCS11_CERTIFICATE, GcrPkcs11CertificatePrivate);
-}
-
-static void
-gcr_pkcs11_certificate_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
-
- switch (prop_id) {
- case PROP_ATTRIBUTES:
- g_return_if_fail (self->pv->attrs == NULL);
- self->pv->attrs = g_value_dup_boxed (value);
- g_return_if_fail (self->pv->attrs != NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_pkcs11_certificate_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
-
- switch (prop_id) {
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, gcr_pkcs11_certificate_get_attributes (self));
- break;
- default:
- gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
- break;
- }
-}
-
-static void
-gcr_pkcs11_certificate_finalize (GObject *obj)
-{
- GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
-
- gck_attributes_unref (self->pv->attrs);
-
- G_OBJECT_CLASS (gcr_pkcs11_certificate_parent_class)->finalize (obj);
-}
-
-static void
-gcr_pkcs11_certificate_class_init (GcrPkcs11CertificateClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructor = gcr_pkcs11_certificate_constructor;
- gobject_class->get_property = gcr_pkcs11_certificate_get_property;
- gobject_class->set_property = gcr_pkcs11_certificate_set_property;
- gobject_class->finalize = gcr_pkcs11_certificate_finalize;
-
- /**
- * GcrPkcs11Certificate:attributes:
- *
- * Automatically loaded attributes for this certificate.
- */
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the renderer",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (gobject_class, sizeof (GcrPkcs11CertificatePrivate));
-
- gcr_certificate_mixin_class_init (gobject_class);
- _gcr_initialize_library ();
-}
-
-static const guchar *
-gcr_pkcs11_certificate_get_der_data (GcrCertificate *cert,
- gsize *n_data)
-{
- GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (cert);
- GckAttribute *attr;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data, NULL);
- g_return_val_if_fail (self->pv->attrs, NULL);
-
- attr = gck_attributes_find (self->pv->attrs, CKA_VALUE);
- g_return_val_if_fail (attr && attr->length != 0 && attr->length != G_MAXULONG, NULL);
- *n_data = attr->length;
- return attr->value;
-}
-
-static void
-gcr_certificate_iface (GcrCertificateIface *iface)
-{
- iface->get_der_data = gcr_pkcs11_certificate_get_der_data;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_pkcs11_certificate_get_attributes:
- * @self: A #GcrPkcs11Certificate
- *
- * Access the automatically loaded attributes for this certificate.
- *
- * Returns: (transfer none): the certificate attributes
- */
-GckAttributes *
-gcr_pkcs11_certificate_get_attributes (GcrPkcs11Certificate *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_CERTIFICATE (self), NULL);
- return self->pv->attrs;
-}
-
-/**
- * gcr_pkcs11_certificate_lookup_issuer:
- * @certificate: a #GcrCertificate
- * @cancellable: a #GCancellable
- * @error: a #GError, or NULL
- *
- * Lookup a the issuer of a @certificate in the PKCS\#11 storage. The
- * lookup is done using the issuer DN of the certificate. No certificate chain
- * verification is done. Use a crypto library to make trust decisions.
- *
- * This call may block, see gcr_pkcs11_certificate_lookup_issuer() for the
- * non-blocking version.
- *
- * Will return %NULL if no issuer certificate is found. Use @error to determine
- * if an error occurred.
- *
- * Returns: (transfer full): a new #GcrPkcs11Certificate, or %NULL
- */
-GcrCertificate *
-gcr_pkcs11_certificate_lookup_issuer (GcrCertificate *certificate, GCancellable *cancellable,
- GError **error)
-{
- GckAttributes *search;
- GcrCertificate *issuer;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), NULL);
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return NULL;
-
- search = prepare_lookup_certificate_issuer (certificate);
- g_return_val_if_fail (search, FALSE);
-
- issuer = perform_lookup_certificate (search, cancellable, error);
- gck_attributes_unref (search);
-
- return issuer;
-}
-
-/**
- * gcr_pkcs11_certificate_lookup_issuer_async:
- * @certificate: a #GcrCertificate
- * @cancellable: a #GCancellable
- * @callback: a #GAsyncReadyCallback to call when the operation completes
- * @user_data: the data to pass to callback function
- *
- * Lookup a the issuer of a @certificate in the PKCS\#11 storage. The
- * lookup is done using the issuer DN of the certificate. No certificate chain
- * verification is done. Use a crypto library to make trust decisions.
- *
- * When the operation is finished, callback will be called. You can then call
- * gcr_pkcs11_certificate_lookup_issuer_finish() to get the result of the
- * operation.
- */
-void
-gcr_pkcs11_certificate_lookup_issuer_async (GcrCertificate *certificate, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *async;
- lookup_issuer_closure *closure;
-
- g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
-
- async = g_simple_async_result_new (G_OBJECT (certificate), callback, user_data,
- gcr_pkcs11_certificate_lookup_issuer_async);
- closure = g_new0 (lookup_issuer_closure, 1);
- closure->search = prepare_lookup_certificate_issuer (certificate);
- g_return_if_fail (closure->search);
- g_simple_async_result_set_op_res_gpointer (async, closure, lookup_issuer_free);
-
- g_simple_async_result_run_in_thread (async, thread_lookup_certificate,
- G_PRIORITY_DEFAULT, cancellable);
-
- g_object_unref (async);
-}
-
-/**
- * gcr_pkcs11_certificate_lookup_issuer_finish:
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_pkcs11_certificate_lookup_issuer_async().
- *
- * Will return %NULL if no issuer certificate is found. Use @error to determine
- * if an error occurred.
- *
- * Returns: (transfer full): a new #GcrPkcs11Certificate, or %NULL
- */
-GcrCertificate *
-gcr_pkcs11_certificate_lookup_issuer_finish (GAsyncResult *result, GError **error)
-{
- lookup_issuer_closure *closure;
- GObject *source;
-
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
-
- source = g_async_result_get_source_object (result);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, source,
- gcr_pkcs11_certificate_lookup_issuer_async), NULL);
- g_object_unref (source);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- if (closure->result != NULL)
- g_object_ref (closure->result);
- return closure->result;
-}
diff --git a/gcr/gcr-pkcs11-certificate.h b/gcr/gcr-pkcs11-certificate.h
deleted file mode 100644
index 04c15b36..00000000
--- a/gcr/gcr-pkcs11-certificate.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_PKCS11_CERTIFICATE_H__
-#define __GCR_PKCS11_CERTIFICATE_H__
-
-#include "gcr-types.h"
-#include "gcr-certificate.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_PKCS11_CERTIFICATE (gcr_pkcs11_certificate_get_type ())
-#define GCR_PKCS11_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PKCS11_CERTIFICATE, GcrPkcs11Certificate))
-#define GCR_PKCS11_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PKCS11_CERTIFICATE, GcrPkcs11CertificateClass))
-#define GCR_IS_PKCS11_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PKCS11_CERTIFICATE))
-#define GCR_IS_PKCS11_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PKCS11_CERTIFICATE))
-#define GCR_PKCS11_CERTIFICATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PKCS11_CERTIFICATE, GcrPkcs11CertificateClass))
-
-typedef struct _GcrPkcs11Certificate GcrPkcs11Certificate;
-typedef struct _GcrPkcs11CertificateClass GcrPkcs11CertificateClass;
-typedef struct _GcrPkcs11CertificatePrivate GcrPkcs11CertificatePrivate;
-
-struct _GcrPkcs11Certificate {
- GckObject parent;
-
- /*< private >*/
- GcrPkcs11CertificatePrivate *pv;
-};
-
-struct _GcrPkcs11CertificateClass {
- /*< private >*/
- GckObjectClass parent_class;
-};
-
-GType gcr_pkcs11_certificate_get_type (void);
-
-GckAttributes* gcr_pkcs11_certificate_get_attributes (GcrPkcs11Certificate *self);
-
-GcrCertificate* gcr_pkcs11_certificate_lookup_issuer (GcrCertificate *certificate,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_pkcs11_certificate_lookup_issuer_async (GcrCertificate *certificate,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-GcrCertificate* gcr_pkcs11_certificate_lookup_issuer_finish (GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_PKCS11_CERTIFICATE_H__ */
diff --git a/gcr/gcr-pkcs11-import-dialog.c b/gcr/gcr-pkcs11-import-dialog.c
deleted file mode 100644
index e33d624a..00000000
--- a/gcr/gcr-pkcs11-import-dialog.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-dialog-util.h"
-#include "gcr-pkcs11-import-dialog.h"
-
-#include "egg/egg-entry-buffer.h"
-#include "egg/egg-secure-memory.h"
-
-#include <gtk/gtk.h>
-
-#include <glib/gi18n-lib.h>
-
-EGG_SECURE_DECLARE (import_dialog);
-
-#define GCR_PKCS11_IMPORT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PKCS11_IMPORT_DIALOG, GcrPkcs11ImportDialogClass))
-#define GCR_IS_PKCS11_IMPORT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PKCS11_IMPORT_DIALOG))
-#define GCR_PKCS11_IMPORT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PKCS11_IMPORT_DIALOG, GcrPkcs11ImportDialogClass))
-
-enum {
- PROP_0,
- PROP_IMPORTER
-};
-
-struct _GcrPkcs11ImportDialog {
- GtkDialog parent;
- GtkBuilder *builder;
- GtkWidget *password_area;
- GtkLabel *token_label;
- GtkImage *token_image;
- GtkEntry *password_entry;
- GtkEntry *label_entry;
- gboolean label_changed;
-};
-
-typedef struct _GcrPkcs11ImportDialogClass GcrPkcs11ImportDialogClass;
-
-struct _GcrPkcs11ImportDialogClass {
- GtkDialogClass parent;
-};
-
-G_DEFINE_TYPE (GcrPkcs11ImportDialog, _gcr_pkcs11_import_dialog, GTK_TYPE_DIALOG);
-
-static void
-on_label_changed (GtkEditable *editable,
- gpointer user_data)
-{
- GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (user_data);
- self->label_changed = TRUE;
-}
-
-static void
-_gcr_pkcs11_import_dialog_constructed (GObject *obj)
-{
- GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (obj);
- GError *error = NULL;
- GtkEntryBuffer *buffer;
- GtkWidget *widget;
- GtkBox *contents;
-
- G_OBJECT_CLASS (_gcr_pkcs11_import_dialog_parent_class)->constructed (obj);
-
- if (!gtk_builder_add_from_file (self->builder, UIDIR "gcr-pkcs11-import-dialog.ui", &error)) {
- g_warning ("couldn't load ui builder file: %s", error->message);
- return;
- }
-
- /* Fill in the dialog from builder */
- widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "pkcs11-import-dialog"));
- contents = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self)));
- gtk_box_pack_start (contents, widget, TRUE, TRUE, 0);
-
- /* The password area */
- self->password_area = GTK_WIDGET (gtk_builder_get_object (self->builder, "unlock-area"));
- gtk_widget_hide (self->password_area);
-
- /* Add a secure entry */
- buffer = egg_entry_buffer_new ();
- self->password_entry = GTK_ENTRY (gtk_builder_get_object (self->builder, "password-entry"));
- gtk_entry_set_buffer (self->password_entry, buffer);
- gtk_entry_set_activates_default (self->password_entry, TRUE);
- g_object_unref (buffer);
-
- self->token_label = GTK_LABEL (gtk_builder_get_object (self->builder, "token-description"));
- self->token_image = GTK_IMAGE (gtk_builder_get_object (self->builder, "token-image"));
-
- /* Setup the label */
- self->label_entry = GTK_ENTRY (gtk_builder_get_object (self->builder, "label-entry"));
- g_signal_connect (self->label_entry, "changed", G_CALLBACK (on_label_changed), self);
- gtk_entry_set_activates_default (self->label_entry, TRUE);
-
- /* Add our various buttons */
- gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_OK, GTK_RESPONSE_OK);
- gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
-
- gtk_window_set_modal (GTK_WINDOW (self), TRUE);
-}
-
-static void
-_gcr_pkcs11_import_dialog_init (GcrPkcs11ImportDialog *self)
-{
- self->builder = gtk_builder_new ();
-}
-
-static void
-_gcr_pkcs11_import_dialog_finalize (GObject *obj)
-{
- GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (obj);
-
- g_object_unref (self->builder);
-
- G_OBJECT_CLASS (_gcr_pkcs11_import_dialog_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_pkcs11_import_dialog_class_init (GcrPkcs11ImportDialogClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructed = _gcr_pkcs11_import_dialog_constructed;
- gobject_class->finalize = _gcr_pkcs11_import_dialog_finalize;
-}
-
-GcrPkcs11ImportDialog *
-_gcr_pkcs11_import_dialog_new (GtkWindow *parent)
-{
- GcrPkcs11ImportDialog *dialog;
-
- g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
-
- dialog = g_object_new (GCR_TYPE_PKCS11_IMPORT_DIALOG,
- "transient-for", parent,
- NULL);
-
- return g_object_ref_sink (dialog);
-}
-
-void
-_gcr_pkcs11_import_dialog_get_supplements (GcrPkcs11ImportDialog *self,
- GckAttributes *attributes)
-{
- const gchar *label;
-
- g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
- g_return_if_fail (attributes != NULL);
-
- label = gtk_entry_get_text (self->label_entry);
- if (self->label_changed && label != NULL && label[0])
- gck_attributes_set_string (attributes, CKA_LABEL, label);
-}
-
-void
-_gcr_pkcs11_import_dialog_set_supplements (GcrPkcs11ImportDialog *self,
- GckAttributes *attributes)
-{
- gchar *label;
-
- g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
- g_return_if_fail (attributes != NULL);
-
- if (!gck_attributes_find_string (attributes, CKA_LABEL, &label))
- label = NULL;
-
- if (label == NULL)
- gtk_entry_set_placeholder_text (self->label_entry, _("Automatically chosen"));
- gtk_entry_set_text (self->label_entry, label == NULL ? "" : label);
- g_free (label);
-
- self->label_changed = FALSE;
-}
-
-gboolean
-_gcr_pkcs11_import_dialog_run (GcrPkcs11ImportDialog *self)
-{
- gboolean ret = FALSE;
-
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), FALSE);
-
- if (gtk_dialog_run (GTK_DIALOG (self)) == GTK_RESPONSE_OK) {
- ret = TRUE;
- }
-
- gtk_widget_hide (GTK_WIDGET (self));
-
- return ret;
-}
-
-void
-_gcr_pkcs11_import_dialog_run_async (GcrPkcs11ImportDialog *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
-
- _gcr_dialog_util_run_async (GTK_DIALOG (self), cancellable, callback, user_data);
-}
-
-gboolean
-_gcr_pkcs11_import_dialog_run_finish (GcrPkcs11ImportDialog *self,
- GAsyncResult *result)
-{
- gint response;
-
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), FALSE);
-
- response = _gcr_dialog_util_run_finish (GTK_DIALOG (self), result);
-
- gtk_widget_hide (GTK_WIDGET (self));
-
- return (response == GTK_RESPONSE_OK) ? TRUE : FALSE;
-}
-
-GTlsInteractionResult
-_gcr_pkcs11_import_dialog_run_ask_password (GcrPkcs11ImportDialog *self,
- GTlsPassword *password,
- GCancellable *cancellable,
- GError **error)
-{
- GckTokenInfo *token_info;
- const gchar *value;
- GckSlot *slot;
- GIcon *icon;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_INTERACTION_UNHANDLED);
-
- if (GCK_IS_PASSWORD (password)) {
- slot = gck_password_get_token (GCK_PASSWORD (password));
- token_info = gck_slot_get_token_info (slot);
- icon = gcr_icon_for_token (token_info);
- gtk_image_set_from_gicon (self->token_image, icon, GTK_ICON_SIZE_BUTTON);
- gck_token_info_free (token_info);
- g_object_unref (icon);
- }
-
- gtk_label_set_text (self->token_label, g_tls_password_get_description (password));
-
- gtk_widget_show (self->password_area);
-
- ret = _gcr_pkcs11_import_dialog_run (self);
-
- gtk_widget_hide (self->password_area);
-
- if (!ret) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("The user cancelled the operation"));
- return G_TLS_INTERACTION_FAILED;
- }
-
- value = gtk_entry_get_text (self->password_entry);
- g_tls_password_set_value_full (password, egg_secure_strdup (value),
- -1, egg_secure_free);
- return G_TLS_INTERACTION_HANDLED;
-}
diff --git a/gcr/gcr-pkcs11-import-dialog.h b/gcr/gcr-pkcs11-import-dialog.h
deleted file mode 100644
index 38a1dd4c..00000000
--- a/gcr/gcr-pkcs11-import-dialog.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_PKCS11_IMPORT_DIALOG_H__
-#define __GCR_PKCS11_IMPORT_DIALOG_H__
-
-#include "gcr.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_PKCS11_IMPORT_DIALOG (_gcr_pkcs11_import_dialog_get_type ())
-#define GCR_PKCS11_IMPORT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PKCS11_IMPORT_DIALOG, GcrPkcs11ImportDialog))
-#define GCR_IS_PKCS11_IMPORT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PKCS11_IMPORT_DIALOG))
-
-typedef struct _GcrPkcs11ImportDialog GcrPkcs11ImportDialog;
-
-GType _gcr_pkcs11_import_dialog_get_type (void) G_GNUC_CONST;
-
-GcrPkcs11ImportDialog * _gcr_pkcs11_import_dialog_new (GtkWindow *parent);
-
-void _gcr_pkcs11_import_dialog_get_supplements (GcrPkcs11ImportDialog *self,
- GckAttributes *attributes);
-
-void _gcr_pkcs11_import_dialog_set_supplements (GcrPkcs11ImportDialog *self,
- GckAttributes *attributes);
-
-gboolean _gcr_pkcs11_import_dialog_run (GcrPkcs11ImportDialog *self);
-
-void _gcr_pkcs11_import_dialog_run_async (GcrPkcs11ImportDialog *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean _gcr_pkcs11_import_dialog_run_finish (GcrPkcs11ImportDialog *self,
- GAsyncResult *result);
-
-GTlsInteractionResult _gcr_pkcs11_import_dialog_run_ask_password (GcrPkcs11ImportDialog *self,
- GTlsPassword *password,
- GCancellable *cancellable,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_PKCS11_IMPORT_DIALOG_H__ */
diff --git a/gcr/gcr-pkcs11-import-dialog.ui b/gcr/gcr-pkcs11-import-dialog.ui
deleted file mode 100644
index a565cf1f..00000000
--- a/gcr/gcr-pkcs11-import-dialog.ui
+++ /dev/null
@@ -1,251 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <!-- interface-requires gtk+ 2.12 -->
- <object class="GtkVBox" id="pkcs11-import-dialog">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkFrame" id="unlock-area">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkBox" id="box1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="password-description">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">In order to import, please enter the password.</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</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="GtkEntry" id="password-entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="visibility">False</property>
- <property name="width_chars">20</property>
- <property name="invisible_char_set">True</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>
- <object class="GtkLabel" id="password-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Password:</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="GtkLabel" id="token-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Token:</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="GtkBox" id="box2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="token-image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-missing-image</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="token-description">
- <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="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </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>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Unlock&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="settings-area">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkGrid" id="grid1">
- <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="label-label">
- <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="GtkEntry" id="label-entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <property name="width_chars">20</property>
- <property name="invisible_char_set">True</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>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_bottom">6</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">&lt;b&gt;Import settings&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <object class="GtkSizeGroup" id="entry-size-group">
- <property name="mode">GTK_SIZE_GROUP_HORIZONTAL</property>
- <widgets>
- <widget name="password-label"/>
- <widget name="token-label"/>
- <widget name="label-label"/>
- </widgets>
- </object>
-</interface>
diff --git a/gcr/gcr-pkcs11-import-interaction.c b/gcr/gcr-pkcs11-import-interaction.c
deleted file mode 100644
index e9a18335..00000000
--- a/gcr/gcr-pkcs11-import-interaction.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-dialog-util.h"
-#include "gcr-import-interaction.h"
-#include "gcr-pkcs11-import-interaction.h"
-
-#include <glib/gi18n-lib.h>
-
-#define GCR_PKCS11_IMPORT_INTERACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PKCS11_IMPORT_INTERACTION, GcrPkcs11ImportInteractionClass))
-#define GCR_IS_PKCS11_IMPORT_INTERACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PKCS11_IMPORT_INTERACTION))
-#define GCR_PKCS11_IMPORT_INTERACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PKCS11_IMPORT_INTERACTION, GcrPkcs11ImportInteractionClass))
-
-enum {
- PROP_0,
- PROP_PARENT_WINDOW
-};
-
-typedef struct _GcrPkcs11ImportInteractionClass GcrPkcs11ImportInteractionClass;
-
-struct _GcrPkcs11ImportInteraction {
- GTlsInteraction parent;
- gboolean supplemented;
- GtkWindow *parent_window;
- GcrPkcs11ImportDialog *dialog;
-};
-
-struct _GcrPkcs11ImportInteractionClass {
- GTlsInteractionClass parent_class;
-};
-
-static void _gcr_pkcs11_import_interaction_iface_init (GcrImportInteractionIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE(GcrPkcs11ImportInteraction, _gcr_pkcs11_import_interaction, G_TYPE_TLS_INTERACTION,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_IMPORT_INTERACTION, _gcr_pkcs11_import_interaction_iface_init));
-
-static void
-_gcr_pkcs11_import_interaction_init (GcrPkcs11ImportInteraction *self)
-{
- self->dialog = _gcr_pkcs11_import_dialog_new (self->parent_window);
-}
-
-static void
-_gcr_pkcs11_import_interaction_dispose (GObject *obj)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (obj);
-
- g_clear_object (&self->dialog);
-
- G_OBJECT_CLASS (_gcr_pkcs11_import_interaction_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_pkcs11_import_interaction_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (obj);
-
- switch (prop_id) {
- case PROP_PARENT_WINDOW:
- gtk_window_set_transient_for (GTK_WINDOW (self->dialog),
- g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_pkcs11_import_interaction_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (obj);
-
- switch (prop_id) {
- case PROP_PARENT_WINDOW:
- g_value_set_object (value, gtk_window_get_transient_for (GTK_WINDOW (self->dialog)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static GTlsInteractionResult
-_gcr_pkcs11_import_interaction_ask_password (GTlsInteraction *interaction,
- GTlsPassword *password,
- GCancellable *cancellable,
- GError **error)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (interaction);
-
- g_return_val_if_fail (self->dialog != NULL, G_TLS_INTERACTION_UNHANDLED);
-
- self->supplemented = TRUE;
- return _gcr_pkcs11_import_dialog_run_ask_password (self->dialog, password, cancellable, error);
-}
-
-static void
-_gcr_pkcs11_import_interaction_supplement_prep (GcrImportInteraction *interaction,
- GckAttributes *attributes)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (interaction);
-
- self->supplemented = FALSE;
- _gcr_pkcs11_import_dialog_set_supplements (self->dialog, attributes);
-}
-
-static GTlsInteractionResult
-_gcr_pkcs11_import_interaction_supplement (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GError **error)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (interaction);
-
- g_return_val_if_fail (self->dialog != NULL, G_TLS_INTERACTION_UNHANDLED);
-
- if (self->supplemented)
- return G_TLS_INTERACTION_HANDLED;
-
- self->supplemented = TRUE;
- if (_gcr_pkcs11_import_dialog_run (self->dialog)) {
- _gcr_pkcs11_import_dialog_get_supplements (self->dialog, attributes);
- return G_TLS_INTERACTION_HANDLED;
-
- } else {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, _("The user cancelled the operation"));
- return G_TLS_INTERACTION_FAILED;
- }
-}
-
-static void
-on_dialog_run_async (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GckAttributes *attributes = g_simple_async_result_get_op_res_gpointer (res);
-
- if (_gcr_pkcs11_import_dialog_run_finish (GCR_PKCS11_IMPORT_DIALOG (source), result)) {
- _gcr_pkcs11_import_dialog_get_supplements (GCR_PKCS11_IMPORT_DIALOG (source), attributes);
-
- } else {
- g_simple_async_result_set_error (res, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("The user cancelled the operation"));
- }
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-_gcr_pkcs11_import_interaction_supplement_async (GcrImportInteraction *interaction,
- GckAttributes *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (interaction);
- GSimpleAsyncResult *res;
-
- g_return_if_fail (self->dialog != NULL);
-
- res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
- _gcr_pkcs11_import_interaction_supplement_async);
-
- /* If dialog was already shown, then short circuit */
- if (self->supplemented) {
- g_simple_async_result_complete_in_idle (res);
-
- } else {
- self->supplemented = TRUE;
- g_simple_async_result_set_op_res_gpointer (res, gck_attributes_ref (attributes),
- (GDestroyNotify)gck_attributes_unref);
- _gcr_pkcs11_import_dialog_run_async (self->dialog, cancellable,
- on_dialog_run_async, g_object_ref (res));
- }
-
- g_object_unref (res);
-}
-
-static GTlsInteractionResult
-_gcr_pkcs11_import_interaction_supplement_finish (GcrImportInteraction *interaction,
- GAsyncResult *result,
- GError **error)
-{
- GcrPkcs11ImportInteraction *self = GCR_PKCS11_IMPORT_INTERACTION (interaction);
-
- g_return_val_if_fail (self->dialog != NULL, G_TLS_INTERACTION_UNHANDLED);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
- _gcr_pkcs11_import_interaction_supplement_async), G_TLS_INTERACTION_UNHANDLED);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return G_TLS_INTERACTION_FAILED;
-
- return G_TLS_INTERACTION_HANDLED;
-
-}
-
-static void
-_gcr_pkcs11_import_interaction_iface_init (GcrImportInteractionIface *iface)
-{
- iface->supplement_prep = _gcr_pkcs11_import_interaction_supplement_prep;
- iface->supplement = _gcr_pkcs11_import_interaction_supplement;
- iface->supplement_async = _gcr_pkcs11_import_interaction_supplement_async;
- iface->supplement_finish = _gcr_pkcs11_import_interaction_supplement_finish;
-}
-
-static void
-_gcr_pkcs11_import_interaction_class_init (GcrPkcs11ImportInteractionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
-
- gobject_class->dispose = _gcr_pkcs11_import_interaction_dispose;
- gobject_class->set_property = _gcr_pkcs11_import_interaction_set_property;
- gobject_class->get_property = _gcr_pkcs11_import_interaction_get_property;
-
- interaction_class->ask_password = _gcr_pkcs11_import_interaction_ask_password;
-
- g_object_class_install_property (gobject_class, PROP_PARENT_WINDOW,
- g_param_spec_object ("parent-window", "Parent Window", "Prompt Parent Window",
- GTK_TYPE_WINDOW, G_PARAM_READWRITE));
-}
-
-GTlsInteraction *
-_gcr_pkcs11_import_interaction_new (GtkWindow *parent_window)
-{
- g_return_val_if_fail (parent_window == NULL || GTK_IS_WINDOW (parent_window), NULL);
- return g_object_new (GCR_TYPE_PKCS11_IMPORT_INTERACTION,
- "parent-window", parent_window,
- NULL);
-}
diff --git a/gcr/gcr-pkcs11-import-interaction.h b/gcr/gcr-pkcs11-import-interaction.h
deleted file mode 100644
index 97027ba9..00000000
--- a/gcr/gcr-pkcs11-import-interaction.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_PKCS11_IMPORT_INTERACTION_H__
-#define __GCR_PKCS11_IMPORT_INTERACTION_H__
-
-#include "gcr.h"
-
-#include "gcr-pkcs11-import-dialog.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_PKCS11_IMPORT_INTERACTION (_gcr_pkcs11_import_interaction_get_type ())
-#define GCR_PKCS11_IMPORT_INTERACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PKCS11_IMPORT_INTERACTION, GcrPkcs11ImportInteraction))
-#define GCR_IS_PKCS11_IMPORT_INTERACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PKCS11_IMPORT_INTERACTION))
-
-typedef struct _GcrPkcs11ImportInteraction GcrPkcs11ImportInteraction;
-
-GType _gcr_pkcs11_import_interaction_get_type (void) G_GNUC_CONST;
-
-GTlsInteraction * _gcr_pkcs11_import_interaction_new (GtkWindow *parent_window);
-
-G_END_DECLS
-
-#endif /* __GCR_PKCS11_IMPORT_INTERACTION_H__ */
diff --git a/gcr/gcr-pkcs11-importer.c b/gcr/gcr-pkcs11-importer.c
deleted file mode 100644
index 5cc60b62..00000000
--- a/gcr/gcr-pkcs11-importer.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#define DEBUG_FLAG GCR_DEBUG_IMPORT
-#include "gcr-debug.h"
-#include "gcr-fingerprint.h"
-#include "gcr-icons.h"
-#include "gcr-internal.h"
-#include "gcr-library.h"
-#include "gcr-import-interaction.h"
-#include "gcr-internal.h"
-#include "gcr-parser.h"
-#include "gcr-pkcs11-importer.h"
-
-#include "egg/egg-hex.h"
-
-#include <gck/gck.h>
-
-#include <gcrypt.h>
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ICON,
- PROP_INTERACTION,
- PROP_SLOT,
- PROP_IMPORTED,
- PROP_QUEUED
-};
-
-typedef struct _GcrPkcs11ImporterClass GcrPkcs11ImporterClass;
-
-struct _GcrPkcs11Importer {
- GObject parent;
- GckSlot *slot;
- GList *objects;
- GckSession *session;
- GQueue *queue;
- GTlsInteraction *interaction;
- gboolean any_private;
-};
-
-struct _GcrPkcs11ImporterClass {
- GObjectClass parent_class;
-};
-
-typedef struct {
- GcrPkcs11Importer *importer;
- GCancellable *cancellable;
- gboolean prompted;
- gboolean async;
- GckAttributes *supplement;
-} GcrImporterData;
-
-/* State forward declarations */
-static void state_cancelled (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_complete (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_create_object (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_supplement (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_open_session (GSimpleAsyncResult *res,
- gboolean async);
-
-static void _gcr_pkcs11_importer_init_iface (GcrImporterIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrPkcs11Importer, _gcr_pkcs11_importer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_IMPORTER, _gcr_pkcs11_importer_init_iface);
-);
-
-#define BLOCK 4096
-
-static void
-gcr_importer_data_free (gpointer data)
-{
- GcrImporterData *state = data;
-
- g_clear_object (&state->cancellable);
- g_clear_object (&state->importer);
- g_free (state);
-}
-
-static void
-next_state (GSimpleAsyncResult *res,
- void (*state) (GSimpleAsyncResult *, gboolean))
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
-
- g_assert (state);
-
- if (g_cancellable_is_cancelled (data->cancellable))
- state = state_cancelled;
-
- (state) (res, data->async);
-}
-
-/* ---------------------------------------------------------------------------------
- * COMPLETE
- */
-
-static void
-state_complete (GSimpleAsyncResult *res,
- gboolean async)
-{
- g_simple_async_result_complete (res);
-}
-
-static void
-state_cancelled (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
-
- if (data->cancellable && !g_cancellable_is_cancelled (data->cancellable))
- g_cancellable_cancel (data->cancellable);
-
- g_cancellable_set_error_if_cancelled (data->cancellable, &error);
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-}
-
-/* ---------------------------------------------------------------------------------
- * CREATE OBJECTS
- */
-
-static void
-complete_create_object (GSimpleAsyncResult *res,
- GckObject *object,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
-
- if (object == NULL) {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-
- } else {
- self->objects = g_list_append (self->objects, object);
- next_state (res, state_create_object);
- }
-}
-
-static void
-on_create_object (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GckObject *object;
-
- object = gck_session_create_object_finish (GCK_SESSION (source), result, &error);
- complete_create_object (res, object, error);
- g_object_unref (res);
-}
-
-static void
-state_create_object (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GckAttributes *attrs;
- GckObject *object;
- GError *error = NULL;
-
- /* No more objects */
- if (g_queue_is_empty (self->queue)) {
- next_state (res, state_complete);
-
- } else {
-
- /* Pop first one off the list */
- attrs = g_queue_pop_head (self->queue);
- g_assert (attrs != NULL);
-
- if (async) {
- gck_session_create_object_async (self->session, attrs,
- data->cancellable, on_create_object,
- g_object_ref (res));
- } else {
- object = gck_session_create_object (self->session, attrs,
- data->cancellable, &error);
- complete_create_object (res, object, error);
- }
-
- gck_attributes_unref (attrs);
- }
-}
-
-/* ---------------------------------------------------------------------------------
- * SUPPLEMENTING and FIXING UP
- */
-
-typedef struct {
- GckAttributes *certificate;
- GckAttributes *private_key;
-} CertificateKeyPair;
-
-static void
-supplement_with_attributes (GckAttributes *attrs,
- GckAttributes *supplements)
-{
- GckAttribute *supplement;
- gint i;
-
- for (i = 0; i < gck_attributes_count (supplements); i++) {
- supplement = gck_attributes_at (supplements, i);
- if (!gck_attribute_is_invalid (supplement) && supplement->length != 0)
- gck_attributes_add (attrs, supplement);
- }
-}
-
-static void
-supplement_id_for_data (GckAttributes *attrs,
- guchar *nonce,
- gsize n_once,
- gpointer data,
- gsize n_data)
-{
- gcry_md_hd_t mdh;
- gcry_error_t gcry;
-
- if (gck_attributes_find (attrs, CKA_ID) != NULL)
- return;
-
- gcry = gcry_md_open (&mdh, GCRY_MD_SHA1, 0);
- g_return_if_fail (gcry == 0);
-
- gcry_md_write (mdh, nonce, n_once);
- gcry_md_write (mdh, data, n_data);
-
- gck_attributes_add_data (attrs, CKA_ID,
- gcry_md_read (mdh, 0),
- gcry_md_get_algo_dlen (GCRY_MD_SHA1));
-
- gcry_md_close (mdh);
-}
-
-static void
-supplement_attributes (GcrPkcs11Importer *self,
- GckAttributes *supplements)
-{
- GHashTable *pairs;
- GHashTable *paired;
- CertificateKeyPair *pair;
- gboolean supplemented = FALSE;
- GckAttributes *attrs;
- gulong klass;
- guchar *finger;
- gchar *fingerprint;
- guchar nonce[20];
- GHashTableIter iter;
- gsize n_finger;
- GQueue *queue;
- GList *l;
-
- /* A table of certificate/key pairs by fingerprint */
- pairs = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
-
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attrs = l->data;
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
- g_return_if_reached ();
-
- /* Make a string fingerprint for this guy */
- finger = gcr_fingerprint_from_attributes (attrs, G_CHECKSUM_SHA1,
- &n_finger);
- if (finger) {
- fingerprint = egg_hex_encode (finger, n_finger);
- g_free (finger);
-
- pair = g_hash_table_lookup (pairs, fingerprint);
- if (pair == NULL) {
- pair = g_new0 (CertificateKeyPair, 1);
- g_hash_table_insert (pairs, fingerprint, pair);
- } else {
- g_free (fingerprint);
- }
- } else {
- pair = NULL;
- }
-
- fingerprint = NULL;
-
- gck_attributes_set_boolean (attrs, CKA_TOKEN, CK_TRUE);
-
- switch (klass) {
- case CKO_CERTIFICATE:
- gck_attributes_set_boolean (attrs, CKA_PRIVATE, FALSE);
- if (pair != NULL && pair->certificate == NULL)
- pair->certificate = attrs;
- break;
- case CKO_PRIVATE_KEY:
- gck_attributes_set_boolean (attrs, CKA_PRIVATE, TRUE);
- gck_attributes_add_boolean (attrs, CKA_DECRYPT, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SIGN, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SIGN_RECOVER, TRUE);
- gck_attributes_add_boolean (attrs, CKA_UNWRAP, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SENSITIVE, TRUE);
- if (pair != NULL && pair->private_key == NULL)
- pair->private_key = attrs;
- break;
- }
- }
-
- /* For generation of CKA_ID's */
- gcry_create_nonce (nonce, sizeof (nonce));
-
- /* A table for marking which attributes are in the pairs table */
- paired = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- /* Now move everything in pairs to the front */
- queue = g_queue_new ();
- g_hash_table_iter_init (&iter, pairs);
- while (g_hash_table_iter_next (&iter, (gpointer *)&fingerprint, (gpointer *)&pair)) {
- if (pair->certificate != NULL && pair->private_key != NULL) {
- /*
- * Generate a CKA_ID based on the fingerprint and nonce,
- * and do the same CKA_ID for both private key and certificate.
- */
-
- supplement_with_attributes (pair->private_key, supplements);
- supplement_id_for_data (pair->private_key, nonce, sizeof (nonce),
- fingerprint, strlen (fingerprint));
- g_queue_push_tail (queue, pair->private_key);
- g_hash_table_insert (paired, pair->private_key, "present");
-
- supplement_with_attributes (pair->private_key, supplements);
- supplement_id_for_data (pair->certificate, nonce, sizeof (nonce),
- fingerprint, strlen (fingerprint));
- g_queue_push_tail (queue, pair->certificate);
- g_hash_table_insert (paired, pair->certificate, "present");
-
- /* Used the suplements for the pairs, don't use for unpaired stuff */
- supplemented = TRUE;
- }
- }
-
- /* Go through the old queue, and look for anything not paired */
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attrs = l->data;
- if (!g_hash_table_lookup (paired, attrs)) {
- if (!supplemented)
- supplement_with_attributes (attrs, supplements);
-
- /*
- * Generate a CKA_ID based on the location of attrs in,
- * memory, since this together with the nonce should
- * be unique.
- */
- supplement_id_for_data (attrs, nonce, sizeof (nonce),
- &attrs, sizeof (gpointer));
-
- g_queue_push_tail (queue, l->data);
- }
- }
-
- /* And swap the new queue into place */
- g_queue_free (self->queue);
- self->queue = queue;
-
- g_hash_table_destroy (paired);
- g_hash_table_destroy (pairs);
-}
-
-static void
-complete_supplement (GSimpleAsyncResult *res,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
-
- if (error == NULL) {
- supplement_attributes (data->importer, data->supplement);
- next_state (res, state_create_object);
- } else {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
- }
-}
-
-static void
-on_supplement_done (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GError *error = NULL;
-
- gcr_import_interaction_supplement_finish (GCR_IMPORT_INTERACTION (self->interaction),
- result, &error);
- complete_supplement (res, error);
- g_object_unref (res);
-}
-
-static void
-state_supplement (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GError *error = NULL;
-
- if (self->interaction == NULL || !GCR_IS_IMPORT_INTERACTION (self->interaction)) {
- complete_supplement (res, NULL);
-
- } else if (async) {
- gcr_import_interaction_supplement_async (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement, data->cancellable,
- on_supplement_done, g_object_ref (res));
-
- } else {
- gcr_import_interaction_supplement (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement, data->cancellable, &error);
- complete_supplement (res, error);
- }
-}
-
-static void
-supplement_prep (GSimpleAsyncResult *res)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GckAttribute *the_label = NULL;
- GckAttribute *attr;
- gboolean first = TRUE;
- GList *l;
-
- if (data->supplement)
- gck_attributes_unref (data->supplement);
- data->supplement = gck_attributes_new ();
-
- /* Do we have a consistent label across all objects? */
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attr = gck_attributes_find (l->data, CKA_LABEL);
- if (first)
- the_label = attr;
- else if (!gck_attribute_equal (the_label, attr))
- the_label = NULL;
- first = FALSE;
- }
-
- /* If consistent label, set that in supplement data */
- if (the_label != NULL)
- gck_attributes_add (data->supplement, the_label);
- else
- gck_attributes_add_empty (data->supplement, CKA_LABEL);
-
- if (GCR_IS_IMPORT_INTERACTION (self->interaction))
- gcr_import_interaction_supplement_prep (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement);
-}
-
-/* ---------------------------------------------------------------------------------
- * OPEN SESSION
- */
-
-static void
-complete_open_session (GSimpleAsyncResult *res,
- GckSession *session,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
-
- if (!session) {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-
- } else {
- g_clear_object (&self->session);
- self->session = session;
- next_state (res, state_supplement);
- }
-}
-
-static void
-on_open_session (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GckSession *session;
-
- session = gck_slot_open_session_finish (GCK_SLOT (source), result, &error);
- complete_open_session (res, session, error);
- g_object_unref (res);
-}
-
-static void
-state_open_session (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- guint options = GCK_SESSION_READ_WRITE | GCK_SESSION_LOGIN_USER;
- GckSession *session;
- GError *error = NULL;
-
- if (async) {
- gck_slot_open_session_async (self->slot, options,
- data->cancellable, on_open_session,
- g_object_ref (res));
- } else {
- session = gck_slot_open_session_full (self->slot, options, 0,
- NULL, NULL, data->cancellable, &error);
- complete_open_session (res, session, error);
- }
-}
-
-static void
-_gcr_pkcs11_importer_init (GcrPkcs11Importer *self)
-{
- self->queue = g_queue_new ();
-}
-
-static void
-_gcr_pkcs11_importer_dispose (GObject *obj)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- gck_list_unref_free (self->objects);
- self->objects = NULL;
- g_clear_object (&self->session);
- g_clear_object (&self->interaction);
-
- while (!g_queue_is_empty (self->queue))
- gck_attributes_unref (g_queue_pop_head (self->queue));
-
- G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_pkcs11_importer_finalize (GObject *obj)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- g_clear_object (&self->slot);
-
- G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_pkcs11_importer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_SLOT:
- self->slot = g_value_dup_object (value);
- g_return_if_fail (self->slot);
- break;
- case PROP_INTERACTION:
- g_clear_object (&self->interaction);
- self->interaction = g_value_dup_object (value);
- g_object_notify (G_OBJECT (self), "interaction");
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static gchar *
-calculate_label (GcrPkcs11Importer *self)
-{
- GckTokenInfo *info;
- gchar *result;
-
- info = gck_slot_get_token_info (self->slot);
- result = g_strdup (info->label);
- gck_token_info_free (info);
-
- return result;
-}
-
-static GIcon *
-calculate_icon (GcrPkcs11Importer *self,
- GckTokenInfo *token_info)
-{
- GckTokenInfo *info = NULL;
- GIcon *result;
-
- if (token_info == NULL)
- info = token_info = gck_slot_get_token_info (self->slot);
- result = gcr_icon_for_token (token_info);
- gck_token_info_free (info);
-
- return result;
-}
-
-static void
-_gcr_pkcs11_importer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ICON:
- g_value_take_object (value, calculate_icon (self, NULL));
- break;
- case PROP_SLOT:
- g_value_set_object (value, _gcr_pkcs11_importer_get_slot (self));
- break;
- case PROP_IMPORTED:
- g_value_take_boxed (value, _gcr_pkcs11_importer_get_imported (self));
- break;
- case PROP_QUEUED:
- g_value_set_pointer (value, _gcr_pkcs11_importer_get_queued (self));
- break;
- case PROP_INTERACTION:
- g_value_set_object (value, self->interaction);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- gobject_class->dispose = _gcr_pkcs11_importer_dispose;
- gobject_class->finalize = _gcr_pkcs11_importer_finalize;
- gobject_class->set_property = _gcr_pkcs11_importer_set_property;
- gobject_class->get_property = _gcr_pkcs11_importer_get_property;
-
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
-
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
-
- g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
-
- g_object_class_install_property (gobject_class, PROP_SLOT,
- g_param_spec_object ("slot", "Slot", "PKCS#11 slot to import data into",
- GCK_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_IMPORTED,
- g_param_spec_boxed ("imported", "Imported", "Imported objects",
- GCK_TYPE_LIST, G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class, PROP_QUEUED,
- g_param_spec_pointer ("queued", "Queued", "Queued attributes",
- G_PARAM_READABLE));
-
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (registered, CKA_CERTIFICATE_TYPE, CKC_X_509);
- gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
- gck_attributes_unref (registered);
-
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
- gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
- gck_attributes_unref (registered);
-
- _gcr_initialize_library ();
-}
-
-static GList *
-list_all_slots (void)
-{
- GList *modules;
- GList *results;
-
- modules = gcr_pkcs11_get_modules ();
- results = gck_modules_get_slots (modules, TRUE);
- gck_list_unref_free (modules);
-
- return results;
-}
-
-static const char *token_blacklist[] = {
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SECRET:MAIN",
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:USER:DEFAULT",
- NULL
-};
-
-static gboolean
-is_slot_importable (GckSlot *slot,
- GckTokenInfo *token)
-{
- GError *error = NULL;
- GckUriData *uri;
- gboolean match;
- guint i;
-
- if (token->flags & CKF_WRITE_PROTECTED) {
- _gcr_debug ("token is not importable: %s: write protected", token->label);
- return FALSE;
- }
- if (!(token->flags & CKF_TOKEN_INITIALIZED)) {
- _gcr_debug ("token is not importable: %s: not initialized", token->label);
- return FALSE;
- }
- if ((token->flags & CKF_LOGIN_REQUIRED) &&
- !(token->flags & CKF_USER_PIN_INITIALIZED)) {
- _gcr_debug ("token is not importable: %s: user pin not initialized", token->label);
- return FALSE;
- }
-
- for (i = 0; token_blacklist[i] != NULL; i++) {
- uri = gck_uri_parse (token_blacklist[i], GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, &error);
- if (uri == NULL) {
- g_warning ("couldn't parse pkcs11 blacklist uri: %s", error->message);
- g_clear_error (&error);
- continue;
- }
-
- match = gck_slot_match (slot, uri);
- gck_uri_data_free (uri);
-
- if (match) {
- _gcr_debug ("token is not importable: %s: on the black list", token->label);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static GList *
-_gcr_pkcs11_importer_create_for_parsed (GcrParsed *parsed)
-{
- GcrImporter *self;
- GList *slots, *l;
- GList *results = NULL;
- GckTokenInfo *token_info;
- gboolean importable;
-
- slots = list_all_slots ();
- for (l = slots; l != NULL; l = g_list_next (l)) {
- token_info = gck_slot_get_token_info (l->data);
- importable = is_slot_importable (l->data, token_info);
-
- if (importable) {
- _gcr_debug ("creating importer for token: %s", token_info->label);
- self = _gcr_pkcs11_importer_new (l->data);
- if (!gcr_importer_queue_for_parsed (self, parsed))
- g_assert_not_reached ();
- results = g_list_prepend (results, self);
- }
-
- gck_token_info_free (token_info);
- }
- gck_list_unref_free (slots);
-
- return g_list_reverse (results);
-}
-
-static gboolean
-_gcr_pkcs11_importer_queue_for_parsed (GcrImporter *importer,
- GcrParsed *parsed)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer);
- GckAttributes *attrs;
- const gchar *label;
-
- attrs = gcr_parsed_get_attributes (parsed);
- label = gcr_parsed_get_label (parsed);
- _gcr_pkcs11_importer_queue (self, label, attrs);
-
- return TRUE;
-}
-
-static void
-_gcr_pkcs11_importer_import_async (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer);
- GSimpleAsyncResult *res;
- GcrImporterData *data;
-
- res = g_simple_async_result_new (G_OBJECT (importer), callback, user_data,
- _gcr_pkcs11_importer_import_async);
- data = g_new0 (GcrImporterData, 1);
- data->async = TRUE;
- data->importer = g_object_ref (importer);
- data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- g_simple_async_result_set_op_res_gpointer (res, data, gcr_importer_data_free);
-
- supplement_prep (res);
- gck_slot_set_interaction (self->slot, self->interaction);
-
- next_state (res, state_open_session);
- g_object_unref (res);
-}
-
-static gboolean
-_gcr_pkcs11_importer_import_finish (GcrImporter *importer,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (importer),
- _gcr_pkcs11_importer_import_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-_gcr_pkcs11_importer_init_iface (GcrImporterIface *iface)
-{
- iface->create_for_parsed = _gcr_pkcs11_importer_create_for_parsed;
- iface->queue_for_parsed = _gcr_pkcs11_importer_queue_for_parsed;
- iface->import_async = _gcr_pkcs11_importer_import_async;
- iface->import_finish = _gcr_pkcs11_importer_import_finish;
-}
-
-/**
- * _gcr_pkcs11_importer_new:
- *
- * Returns: (transfer full) (type Gcr.Pkcs11Importer): the new importer
- */
-GcrImporter *
-_gcr_pkcs11_importer_new (GckSlot *slot)
-{
- g_return_val_if_fail (GCK_IS_SLOT (slot), NULL);
-
- return g_object_new (GCR_TYPE_PKCS11_IMPORTER,
- "slot", slot,
- NULL);
-}
-
-GckSlot *
-_gcr_pkcs11_importer_get_slot (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return self->slot;
-}
-
-GList *
-_gcr_pkcs11_importer_get_imported (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return g_list_copy (self->objects);
-}
-
-GList *
-_gcr_pkcs11_importer_get_queued (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return g_list_copy (self->queue->head);
-}
-
-void
-_gcr_pkcs11_importer_queue (GcrPkcs11Importer *self,
- const gchar *label,
- GckAttributes *attrs)
-{
- g_return_if_fail (GCR_IS_PKCS11_IMPORTER (self));
- g_return_if_fail (attrs != NULL);
-
- if (label != NULL && !gck_attributes_find (attrs, CKA_LABEL))
- gck_attributes_add_string (attrs, CKA_LABEL, label);
-
- g_queue_push_tail (self->queue, gck_attributes_ref (attrs));
-}
diff --git a/gcr/gcr-pkcs11-importer.h b/gcr/gcr-pkcs11-importer.h
deleted file mode 100644
index 5f66f7b3..00000000
--- a/gcr/gcr-pkcs11-importer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> can be included directly."
-#endif
-
-#ifndef __GCR_PKCS11_IMPORTER_H__
-#define __GCR_PKCS11_IMPORTER_H__
-
-#include "gcr-importer.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_PKCS11_IMPORTER (_gcr_pkcs11_importer_get_type ())
-#define GCR_PKCS11_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PKCS11_IMPORTER, GcrPkcs11Importer))
-#define GCR_PKCS11_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PKCS11_IMPORTER, GcrPkcs11ImporterClass))
-#define GCR_IS_PKCS11_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PKCS11_IMPORTER))
-#define GCR_IS_PKCS11_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PKCS11_IMPORTER))
-#define GCR_PKCS11_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PKCS11_IMPORTER, GcrPkcs11ImporterClass))
-
-typedef struct _GcrPkcs11Importer GcrPkcs11Importer;
-
-
-GType _gcr_pkcs11_importer_get_type (void);
-
-GcrImporter * _gcr_pkcs11_importer_new (GckSlot *slot);
-
-void _gcr_pkcs11_importer_queue (GcrPkcs11Importer *self,
- const gchar *label,
- GckAttributes *attrs);
-
-GckSlot * _gcr_pkcs11_importer_get_slot (GcrPkcs11Importer *self);
-
-GList * _gcr_pkcs11_importer_get_queued (GcrPkcs11Importer *self);
-
-GList * _gcr_pkcs11_importer_get_imported (GcrPkcs11Importer *self);
-
-G_END_DECLS
-
-#endif /* __GCR_PKCS11_IMPORTER_H__ */
diff --git a/gcr/gcr-record.c b/gcr/gcr-record.c
deleted file mode 100644
index 7b065eb0..00000000
--- a/gcr/gcr-record.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-record.h"
-#define DEBUG_FLAG GCR_DEBUG_PARSE
-#include "gcr-debug.h"
-
-#include "egg/egg-timegm.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#define MAX_COLUMNS 32
-
-typedef struct {
- gpointer next;
- gsize n_value;
- gchar value[1];
- /* Hangs off the end */
-} GcrRecordBlock;
-
-struct _GcrRecord {
- GcrRecordBlock *block;
- const gchar *columns[MAX_COLUMNS];
- guint n_columns;
- gchar delimiter;
-};
-
-G_DEFINE_BOXED_TYPE (GcrRecord, _gcr_record, _gcr_record_copy, _gcr_record_free);
-
-static GcrRecordBlock *
-record_block_new (const gchar *value,
- gsize length)
-{
- GcrRecordBlock *block;
-
- block = g_malloc (sizeof (GcrRecordBlock) + length);
- block->next = NULL;
- block->n_value = length;
-
- if (value != NULL) {
- memcpy (block->value, value, length);
- block->value[length] = 0;
- } else {
- block->value[0] = 0;
- }
-
- return block;
-}
-
-static GcrRecordBlock *
-record_block_take (gchar *value,
- gsize length)
-{
- GcrRecordBlock *block;
-
- g_assert (value);
-
- block = g_realloc (value, sizeof (GcrRecordBlock) + length);
- memmove (((gchar*)block) + G_STRUCT_OFFSET (GcrRecordBlock, value),
- block, length);
- block->next = NULL;
- block->n_value = length;
- block->value[length] = 0;
-
- return block;
-}
-
-static GcrRecord *
-record_flatten (GcrRecord *record)
-{
- GcrRecord *result;
- GcrRecordBlock *block;
- gsize total;
- gsize at;
- gsize len;
- guint i;
-
- /* Calculate the length of what we need */
- total = 0;
- for (i = 0; i < record->n_columns; i++)
- total += strlen (record->columns[i]) + 1;
-
- /* Allocate a new GcrRecordData which will hold all that */
- result = g_slice_new0 (GcrRecord);
- result->block = block = record_block_new (NULL, total);
-
- at = 0;
- for (i = 0; i < record->n_columns; i++) {
- len = strlen (record->columns[i]);
- result->columns[i] = block->value + at;
- memcpy ((gchar *)result->columns[i], record->columns[i], len + 1);
- at += len + 1;
- }
-
- result->n_columns = record->n_columns;
- result->delimiter = record->delimiter;
- g_assert (at == total);
-
- return result;
-}
-
-static void
-print_record_to_string (GcrRecord *record,
- GString *string)
-{
- guint i;
-
- for (i = 0; i < record->n_columns; i++) {
- g_string_append (string, record->columns[i]);
- g_string_append_c (string, record->delimiter);
- }
-}
-
-gchar *
-_gcr_record_format (GcrRecord *record)
-{
- GString *string;
-
- g_return_val_if_fail (record, NULL);
-
- string = g_string_new ("");
- print_record_to_string (record, string);
- return g_string_free (string, FALSE);
-}
-
-GcrRecord *
-_gcr_record_new (GQuark schema,
- guint n_columns,
- gchar delimiter)
-{
- GcrRecord *result;
- guint i;
-
- result = g_slice_new0 (GcrRecord);
- result->block = NULL;
- result->delimiter = delimiter;
-
- for (i = 0; i < n_columns; i++)
- result->columns[i] = "";
- result->columns[0] = g_quark_to_string (schema);
- result->n_columns = n_columns;
-
- return result;
-}
-
-GcrRecord *
-_gcr_record_copy (GcrRecord *record)
-{
- return record_flatten (record);
-}
-
-static GcrRecord *
-take_and_parse_internal (GcrRecordBlock *block,
- gchar delimiter,
- gboolean allow_empty)
-{
- GcrRecord *result;
- gchar *at, *beg, *end;
-
- g_assert (block);
-
- result = g_slice_new0 (GcrRecord);
- result->block = block;
- result->delimiter = delimiter;
-
- _gcr_debug ("parsing line %s", block->value);
-
- at = block->value;
- for (;;) {
- if (result->n_columns >= MAX_COLUMNS) {
- _gcr_debug ("too many record (%d) in gnupg line", MAX_COLUMNS);
- _gcr_record_free (result);
- return NULL;
- }
-
- beg = at;
- result->columns[result->n_columns] = beg;
-
- at = strchr (beg, delimiter);
- if (at == NULL) {
- end = (block->value + block->n_value) - 1;
- } else {
- at[0] = '\0';
- end = at;
- at++;
- }
-
- if (allow_empty || end > beg)
- result->n_columns++;
-
- if (at == NULL)
- break;
- }
-
- return result;
-}
-
-GcrRecord*
-_gcr_record_parse_colons (const gchar *line, gssize n_line)
-{
- g_return_val_if_fail (line, NULL);
- if (n_line < 0)
- n_line = strlen (line);
- return take_and_parse_internal (record_block_new (line, n_line), ':', TRUE);
-}
-
-GcrRecord*
-_gcr_record_parse_spaces (const gchar *line, gssize n_line)
-{
- g_return_val_if_fail (line, NULL);
- if (n_line < 0)
- n_line = strlen (line);
- return take_and_parse_internal (record_block_new (line, n_line), ' ', FALSE);
-}
-
-guint
-_gcr_record_get_count (GcrRecord *record)
-{
- g_return_val_if_fail (record, 0);
- return record->n_columns;
-}
-
-static void
-record_take_column (GcrRecord *record,
- guint column,
- GcrRecordBlock *block)
-{
- g_assert (block->next == NULL);
- block->next = record->block;
- record->block = block;
-
- g_assert (column < record->n_columns);
- record->columns[column] = block->value;
-}
-
-static const char HEXC_LOWER[] = "0123456789abcdef";
-
-/* Will return NULL if unescaping failed or not needed */
-static gchar *
-c_colons_unescape (const gchar *source,
- gsize *length)
-{
- const gchar *p = source, *octal, *hex;
- gchar *dest = NULL;
- gchar *q = dest;
- gchar *pos;
-
- while (*p) {
- if (*p == '\\') {
- if (dest == NULL) {
- dest = g_malloc (strlen (source) + 1);
- memcpy (dest, source, (p - source));
- q = dest + (p - source);
- }
-
- p++;
- switch (*p) {
- case '\0': /* invalid trailing backslash */
- g_free (dest);
- return NULL;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
- *q = 0;
- octal = p;
- while ((p < octal + 3) && (*p >= '0') && (*p <= '7')) {
- *q = (*q * 8) + (*p - '0');
- p++;
- }
- q++;
- p--;
- break;
- case 'x':
- *q = 0;
- hex = p;
- while (p < hex + 2) {
- pos = strchr (HEXC_LOWER, g_ascii_tolower (*p));
- if (pos == 0) { /* invalid bad hex character */
- g_free (dest);
- return NULL;
- }
- *q = (*q * 16) + (pos - HEXC_LOWER);
- p++;
- }
- q++;
- p--;
- break;
- case 'b':
- *q++ = '\b';
- break;
- case 'f':
- *q++ = '\f';
- break;
- case 'n':
- *q++ = '\n';
- break;
- case 'r':
- *q++ = '\r';
- break;
- case 't':
- *q++ = '\t';
- break;
- default: /* Also handles \" and \\ */
- *q++ = *p;
- break;
- }
- } else if (q != NULL) {
- *q++ = *p;
- }
- p++;
- }
-
- if (q != NULL) {
- *q = 0;
- if (length)
- *length = q - dest;
- }
-
- return dest;
-}
-
-/* Will return NULL if no escaping needed */
-static gchar *
-c_colons_escape (const gchar *source,
- const gchar extra,
- gsize *length)
-{
- const guchar *p;
- gchar *dest = NULL;
- gchar *q = NULL;
- gchar escape;
- gsize off;
-
- g_return_val_if_fail (source != NULL, NULL);
-
- p = (guchar *) source;
-
- while (*p) {
- escape = 0;
- switch (*p) {
- case '\b':
- escape = 'b';
- break;
- case '\f':
- escape = 'f';
- break;
- case '\n':
- escape = 'n';
- break;
- case '\r':
- escape = 'r';
- break;
- case '\t':
- escape = 't';
- break;
- case '\\':
- escape = '\\';
- break;
- case '"':
- escape = '"';
- break;
- }
-
- if (escape != 0 || *p < ' ' || *p >= 0x127 || *p == extra) {
- if (dest == NULL) {
- /* Each source byte needs maximally four destination chars (\xff) */
- dest = g_malloc (strlen (source) * 4 + 1);
- off = (gchar *)p - source;
- memcpy (dest, source, off);
- q = dest + off;
- }
-
- if (escape) {
- *q++ = '\\';
- *q++ = escape;
- } else {
- *q++ = '\\';
- *q++ = 'x';
- *q++ = HEXC_LOWER[*p >> 4 & 0xf];
- *q++ = HEXC_LOWER[*p & 0xf];
- }
- } else if (q != NULL) {
- *q++ = *p;
- }
- p++;
- }
-
- if (q != NULL) {
- *q = 0;
- if (length)
- *length = q - dest;
- }
-
- return dest;
-}
-
-gchar*
-_gcr_record_get_string (GcrRecord *record, guint column)
-{
- const gchar *value;
- gchar *text = NULL;
-
- g_return_val_if_fail (record, NULL);
-
- value = _gcr_record_get_raw (record, column);
- if (!value)
- return NULL;
-
- text = c_colons_unescape (value, NULL);
- if (text != NULL)
- value = text;
-
- /* If it's not UTF-8, we guess that it's latin1 */
- if (!g_utf8_validate (value, -1, NULL)) {
- gchar *conv = g_convert (value, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
- g_free (text);
- value = text = conv;
- }
-
- /*
- * latin1 to utf-8 conversion can't really fail, just produce
- * garbage... so there's no need to check here.
- */
-
- return (text == value) ? text : g_strdup (value);
-}
-
-void
-_gcr_record_set_string (GcrRecord *record,
- guint column,
- const gchar *string)
-{
- GcrRecordBlock *block;
- gchar *escaped;
-
- g_return_if_fail (record != NULL);
- g_return_if_fail (string != NULL);
- g_return_if_fail (column < record->n_columns);
-
- escaped = c_colons_escape (string, record->delimiter, NULL);
- if (escaped != NULL)
- block = record_block_take (escaped, strlen (escaped));
- else
- block = record_block_new (string, strlen (string));
-
- record_take_column (record, column, block);
-}
-
-gchar
-_gcr_record_get_char (GcrRecord *record,
- guint column)
-{
- const gchar *value;
-
- g_return_val_if_fail (record, 0);
-
- value = _gcr_record_get_raw (record, column);
- if (!value)
- return 0;
-
- if (value[0] != 0 && value[1] == 0)
- return value[0];
-
- return 0;
-}
-
-void
-_gcr_record_set_char (GcrRecord *record,
- guint column,
- gchar value)
-{
- g_return_if_fail (record != NULL);
- g_return_if_fail (column < record->n_columns);
- g_return_if_fail (value != 0);
-
- record_take_column (record, column, record_block_new (&value, 1));
-}
-
-gboolean
-_gcr_record_get_uint (GcrRecord *record, guint column, guint *value)
-{
- const gchar *raw;
- gint64 result;
- gchar *end = NULL;
-
- g_return_val_if_fail (record, FALSE);
-
- raw = _gcr_record_get_raw (record, column);
- if (raw == NULL)
- return FALSE;
-
- result = g_ascii_strtoll (raw, &end, 10);
- if (!end || end[0]) {
- _gcr_debug ("invalid unsigned integer value: %s", raw);
- return FALSE;
- }
-
- if (result < 0 || result > G_MAXUINT32) {
- _gcr_debug ("unsigned integer value is out of range: %s", raw);
- return FALSE;
- }
-
- if (value)
- *value = (guint)result;
- return TRUE;
-}
-
-void
-_gcr_record_set_uint (GcrRecord *record,
- guint column,
- guint value)
-{
- gchar *escaped;
-
- g_return_if_fail (record != NULL);
- g_return_if_fail (column < record->n_columns);
-
- escaped = g_strdup_printf ("%u", value);
- record_take_column (record, column,
- record_block_take (escaped, strlen (escaped)));
-}
-
-gboolean
-_gcr_record_get_ulong (GcrRecord *record,
- guint column,
- gulong *value)
-{
- const gchar *raw;
- gint64 result;
- gchar *end = NULL;
-
- g_return_val_if_fail (record, FALSE);
-
- raw = _gcr_record_get_raw (record, column);
- if (raw == NULL)
- return FALSE;
-
- result = g_ascii_strtoull (raw, &end, 10);
- if (!end || end[0]) {
- _gcr_debug ("invalid unsigned long value: %s", raw);
- return FALSE;
- }
-
- if (result < 0 || result > G_MAXULONG) {
- _gcr_debug ("unsigned long value is out of range: %s", raw);
- return FALSE;
- }
-
- if (value)
- *value = (guint)result;
- return TRUE;
-
-}
-
-void
-_gcr_record_set_ulong (GcrRecord *record,
- guint column,
- gulong value)
-{
- gchar *escaped;
-
- g_return_if_fail (record != NULL);
- g_return_if_fail (column < record->n_columns);
-
- escaped = g_strdup_printf ("%lu", value);
- record_take_column (record, column,
- record_block_take (escaped, strlen (escaped)));
-}
-
-GDateTime *
-_gcr_record_get_date (GcrRecord *record,
- guint column)
-{
- const gchar *raw;
- gulong result;
- gchar *end = NULL;
- struct tm tm;
-
- g_return_val_if_fail (record, NULL);
-
- raw = _gcr_record_get_raw (record, column);
- if (raw == NULL)
- return NULL;
-
- /* Try to parse as a number */
- result = strtoul (raw, &end, 10);
- if (end != NULL && end[0] == '\0')
- return g_date_time_new_from_unix_utc (result);
-
- /* Try to parse as a date */
- memset (&tm, 0, sizeof (tm));
- end = strptime (raw, "%Y-%m-%d", &tm);
- if (!end || end[0]) {
- _gcr_debug ("invalid date value: %s", raw);
- return NULL;
- }
-
- return g_date_time_new_utc (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 0, 0, 0);
-}
-
-/**
- * _gcr_record_get_base64:
- * @record: The record
- * @column: The column to decode.
- * @n_data: Location to return size of returned data.
- *
- * Decode a column of a record as base64 data.
- *
- * Returns: (transfer full): The decoded value, or %NULL if not found.
- */
-gpointer
-_gcr_record_get_base64 (GcrRecord *record, guint column, gsize *n_data)
-{
- const gchar *raw;
-
- g_return_val_if_fail (record, NULL);
-
- raw = _gcr_record_get_raw (record, column);
- if (raw == NULL)
- return NULL;
-
- return g_base64_decode (raw, n_data);
-}
-
-void
-_gcr_record_set_base64 (GcrRecord *record,
- guint column,
- gconstpointer data,
- gsize n_data)
-{
- GcrRecordBlock *block;
- gint state, save;
- gsize estimate;
- gsize length;
-
- g_return_if_fail (record != NULL);
- g_return_if_fail (column < record->n_columns);
-
- estimate = n_data * 4 / 3 + n_data * 4 / (3 * 65) + 7;
- block = record_block_new (NULL, estimate);
-
- /* The actual base64 data, without line breaks */
- state = save = 0;
- length = g_base64_encode_step ((guchar *)data, n_data, FALSE,
- block->value, &state, &save);
- length += g_base64_encode_close (TRUE, block->value + length,
- &state, &save);
- block->value[length] = 0;
- g_assert (length < estimate);
-
- g_strchomp (block->value);
- record_take_column (record, column, block);
-}
-
-const gchar*
-_gcr_record_get_raw (GcrRecord *record, guint column)
-{
- g_return_val_if_fail (record, NULL);
-
- if (column >= record->n_columns) {
- _gcr_debug ("only %d columns exist, tried to access %d",
- record->n_columns, column);
- return NULL;
- }
-
- return record->columns[column];
-}
-
-void
-_gcr_record_set_raw (GcrRecord *record,
- guint column,
- const gchar *value)
-{
- g_return_if_fail (record != NULL);
- g_return_if_fail (value != NULL);
- g_return_if_fail (column < record->n_columns);
-
- record_take_column (record, column,
- record_block_new (value, strlen (value)));
-}
-
-void
-_gcr_record_take_raw (GcrRecord *record,
- guint column,
- gchar *value)
-{
- g_return_if_fail (record != NULL);
- g_return_if_fail (value != NULL);
- g_return_if_fail (column < record->n_columns);
-
- record_take_column (record, column,
- record_block_take (value, strlen (value)));
-}
-
-void
-_gcr_record_free (gpointer record)
-{
- GcrRecordBlock *block, *next;
- GcrRecord *rec = record;
-
- if (!record)
- return;
-
- for (block = rec->block; block != NULL; block = next) {
- next = block->next;
- g_free (block);
- }
-
- g_slice_free (GcrRecord, record);
-}
-
-GQuark
-_gcr_record_get_schema (GcrRecord *record)
-{
- const gchar *value;
-
- value = _gcr_record_get_raw (record, GCR_RECORD_SCHEMA);
- if (value != NULL)
- return g_quark_try_string (value);
- return 0;
-}
-
-GcrRecord *
-_gcr_records_find (GPtrArray *records,
- GQuark schema)
-{
- guint i;
-
- g_return_val_if_fail (records, NULL);
- g_return_val_if_fail (schema, NULL);
-
- for (i = 0; i < records->len; i++) {
- if (schema == _gcr_record_get_schema (records->pdata[i]))
- return records->pdata[i];
- }
-
- return NULL;
-}
-
-gchar *
-_gcr_records_format (GPtrArray *records)
-{
- GString *string;
- guint i;
-
- g_return_val_if_fail (records, NULL);
-
- string = g_string_new ("");
- for (i = 0; i < records->len; i++) {
- print_record_to_string (records->pdata[i], string);
- g_string_append_c (string, '\n');
- }
- return g_string_free (string, FALSE);
-}
-
-GPtrArray *
-_gcr_records_parse_colons (gconstpointer data,
- gssize n_data)
-{
- GPtrArray *result = NULL;
- GcrRecordBlock *block;
- GcrRecord *record;
- gchar **lines;
- guint i;
-
- lines = g_strsplit (data, "\n", n_data);
- result = g_ptr_array_new_with_free_func (_gcr_record_free);
-
- for (i = 0; lines[i] != NULL; i++) {
- block = record_block_take (lines[i], strlen (lines[i]));
- record = take_and_parse_internal (block, ':', TRUE);
- if (record == NULL) {
- g_ptr_array_unref (result);
- result = NULL;
- break;
- }
- g_ptr_array_add (result, record);
- }
-
- /* Free any not done */
- for (; lines[i] != NULL; i++)
- g_free (lines[i]);
-
- /* Individual lines already freed */
- g_free (lines);
-
- return result;
-}
diff --git a/gcr/gcr-record.h b/gcr/gcr-record.h
deleted file mode 100644
index 37201cef..00000000
--- a/gcr/gcr-record.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCR_RECORD_H
-#define GCR_RECORD_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-/*
- * Gnupg's official format for listing keys is in the '--with-colons' format.
- * This is documented in doc/DETAILS in the gnupg distribution. Looks like:
- *
- * pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC:
- * fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:
- * uid:f::::::::Werner Koch <wk@g10code.com>:
- * uid:f::::::::Werner Koch <wk@gnupg.org>:
- * sub:f:1536:16:06AD222CADF6A6E1:919537416:1036177416:::::e:
- * fpr:::::::::CF8BCC4B18DE08FCD8A1615906AD222CADF6A6E1:
- * sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc:
- * fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4:
- *
- * Each row is colon delimeted, and has a certain 'schema'. The first item
- * in the row tells us the schema. Then the various columns are numbered,
- * (schema is zero).
- */
-
-G_BEGIN_DECLS
-
-#define GCR_RECORD_SCHEMA_ATTRIBUTE (g_quark_from_static_string ("ATTRIBUTE"))
-#define GCR_RECORD_SCHEMA_IMPORT_OK (g_quark_from_static_string ("IMPORT_OK"))
-#define GCR_RECORD_SCHEMA_FPR (g_quark_from_static_string ("fpr"))
-#define GCR_RECORD_SCHEMA_PUB (g_quark_from_static_string ("pub"))
-#define GCR_RECORD_SCHEMA_SUB (g_quark_from_static_string ("sub"))
-#define GCR_RECORD_SCHEMA_SEC (g_quark_from_static_string ("sec"))
-#define GCR_RECORD_SCHEMA_SSB (g_quark_from_static_string ("ssb"))
-#define GCR_RECORD_SCHEMA_UID (g_quark_from_static_string ("uid"))
-#define GCR_RECORD_SCHEMA_UAT (g_quark_from_static_string ("uat"))
-#define GCR_RECORD_SCHEMA_XA1 (g_quark_from_static_string ("xa1"))
-#define GCR_RECORD_SCHEMA_SIG (g_quark_from_static_string ("sig"))
-#define GCR_RECORD_SCHEMA_RVK (g_quark_from_static_string ("rvk"))
-
-/* Common columns for schemas */
-typedef enum {
- GCR_RECORD_SCHEMA = 0,
- GCR_RECORD_TRUST = 1,
-} GcrRecordColumns;
-
-/*
- * Columns for ATTRIBUTE status message. eg:
- * [GNUPG:] ATTRIBUTE FBAFC70D60AE13D560764062B547B5580EEB5A80 10604 1 1 1 1227936754 0 1
- */
-typedef enum {
- GCR_RECORD_ATTRIBUTE_KEY_FINGERPRINT = 1,
- GCR_RECORD_ATTRIBUTE_LENGTH = 2,
- GCR_RECORD_ATTRIBUTE_TYPE = 3,
- GCR_RECORD_ATTRIBUTE_TIMESTAMP = 6,
- GCR_RECORD_ATTRIBUTE_EXPIRY = 7,
- GCR_RECORD_ATTRIBUTE_FLAGS = 8
-} GcrRecordAttributeColumns;
-
-/*
- * Columns for IMPORT_OK and IMPORT_PROBLEM status message. eg:
- * [GNUPG:] IMPORT_OK 1 6BD9050FD8FC941B43412DCC68B7AB8957548DCD
- * [GNUPG:] IMPORT_PROBLEM 1
- */
-typedef enum {
- GCR_RECORD_IMPORT_REASON = 1,
- GCR_RECORD_IMPORT_FINGERPRINT
-} GcrRecordImportColumns;
-
-/*
- * Columns for fpr schema, add them as they're used. eg:
- * fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:
- */
-typedef enum {
- GCR_RECORD_FPR_FINGERPRINT = 9,
- GCR_RECORD_FPR_MAX = 10
-} GcrRecordFprColumns;
-
-/*
- * Columns for pub, sec, sub, and ssb schemas. eg:
- * pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC:
- */
-typedef enum {
- GCR_RECORD_KEY_BITS = 2,
- GCR_RECORD_KEY_ALGO = 3,
- GCR_RECORD_KEY_KEYID = 4,
- GCR_RECORD_KEY_TIMESTAMP = 5,
- GCR_RECORD_KEY_EXPIRY = 6,
- GCR_RECORD_KEY_OWNERTRUST = 8,
-} GcrRecordKeyColumns;
-
-typedef enum {
- GCR_RECORD_PUB_CAPS = 11,
- GCR_RECORD_PUB_MAX = 12
-} GcrRecordPubColumns;
-
-typedef enum {
- GCR_RECORD_SEC_MAX = 15
-} GcrRecordSecColumns;
-
-/*
- * Columns for uid schema, add them as they're used. eg:
- * uid:u::::1024442705::7A5C6648DAA1F5D12BD80BBED538439ABAFEE203::Test <test@example.com>:
- */
-typedef enum {
- GCR_RECORD_UID_TIMESTAMP = 5,
- GCR_RECORD_UID_EXPIRY = 6,
- GCR_RECORD_UID_FINGERPRINT = 7,
- GCR_RECORD_UID_USERID = 9,
- GCR_RECORD_UID_MAX = 10,
-} GcrRecordUidColumns;
-
-/*
- * Columns for sig schema. eg:
- * sig:::17:FAD3A86D2505A4D5:1291829838::::Stef Walter <stefw@servingtfi.com>:10x:
- */
-typedef enum {
- GCR_RECORD_SIG_STATUS = 1,
- GCR_RECORD_SIG_ALGO = 3,
- GCR_RECORD_SIG_KEYID = 4,
- GCR_RECORD_SIG_TIMESTAMP = 5,
- GCR_RECORD_SIG_EXPIRY = 6,
- GCR_RECORD_SIG_USERID = 9,
- GCR_RECORD_SIG_CLASS = 10,
- GCR_RECORD_SIG_MAX = 11,
-} GcrRecordSigColumns;
-
-/*
- * Columns for rvk schema. eg:
- * rvk:::17::::::3FC732041D23E9EA66DDB5009C9DBC21DF74DC61:80:
- */
-typedef enum {
- GCR_RECORD_RVK_ALGO = 3,
- GCR_RECORD_RVK_FINGERPRINT = 9,
- GCR_RECORD_RVK_CLASS = 10,
- GCR_RECORD_RVK_MAX = 11,
-} GcrRecordRvkColumns;
-
-/*
- * Columns for uat schema, add them as they're used. eg:
- * uat:u::::1024442705::7A5C6648DAA1F5D12BD80BBED538439ABAFEE203::1 3233:
- */
-typedef enum {
- GCR_RECORD_UAT_TRUST = 1,
- GCR_RECORD_UAT_FINGERPRINT = 7,
- GCR_RECORD_UAT_COUNT_SIZE = 9,
- GCR_RECORD_UAT_MAX = 10,
-} GcrRecordUatColumns;
-
-/*
- * Columns for xa1 schema. This is a schema that we've invented ourselves
- * for representing the actual data of openpgp attribute packets. eg:
- * xa1:e:10838:1:::1998-02-02:0:ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013::...
- */
-typedef enum {
- GCR_RECORD_XA1_TRUST = 1,
- GCR_RECORD_XA1_LENGTH = 2,
- GCR_RECORD_XA1_TYPE = 3,
- GCR_RECORD_XA1_TIMESTAMP = 5,
- GCR_RECORD_XA1_EXPIRY = 6,
- GCR_RECORD_XA1_FINGERPRINT = 7,
- GCR_RECORD_XA1_DATA = 9,
- GCR_RECORD_XA1_MAX = 11,
-} GcrRecordXa1Columns;
-
-typedef struct _GcrRecord GcrRecord;
-
-#define GCR_TYPE_RECORD (_gcr_record_get_type ())
-
-GType _gcr_record_get_type (void) G_GNUC_CONST;
-
-GcrRecord * _gcr_record_new (GQuark schema,
- guint n_columns,
- gchar delimiter);
-
-GcrRecord* _gcr_record_copy (GcrRecord *record);
-
-GcrRecord* _gcr_record_parse_colons (const gchar *line,
- gssize n_line);
-
-GcrRecord* _gcr_record_parse_spaces (const gchar *line,
- gssize n_line);
-
-gchar * _gcr_record_format (GcrRecord *record);
-
-void _gcr_record_free (gpointer record);
-
-guint _gcr_record_get_count (GcrRecord *record);
-
-gchar _gcr_record_get_char (GcrRecord *record,
- guint column);
-
-void _gcr_record_set_char (GcrRecord *record,
- guint column,
- gchar value);
-
-gchar* _gcr_record_get_string (GcrRecord *record,
- guint column);
-
-void _gcr_record_set_string (GcrRecord *record,
- guint column,
- const gchar *value);
-
-gboolean _gcr_record_get_uint (GcrRecord *record,
- guint column,
- guint *value);
-
-void _gcr_record_set_uint (GcrRecord *record,
- guint column,
- guint value);
-
-gboolean _gcr_record_get_ulong (GcrRecord *record,
- guint column,
- gulong *value);
-
-void _gcr_record_set_ulong (GcrRecord *record,
- guint column,
- gulong value);
-
-GDateTime * _gcr_record_get_date (GcrRecord *record,
- guint column);
-
-gpointer _gcr_record_get_base64 (GcrRecord *record,
- guint column,
- gsize *n_data);
-
-void _gcr_record_set_base64 (GcrRecord *record,
- guint column,
- gconstpointer data,
- gsize n_data);
-
-const gchar* _gcr_record_get_raw (GcrRecord *record,
- guint column);
-
-void _gcr_record_set_raw (GcrRecord *record,
- guint column,
- const gchar *value);
-
-void _gcr_record_take_raw (GcrRecord *record,
- guint column,
- gchar *value);
-
-GQuark _gcr_record_get_schema (GcrRecord *record);
-
-GPtrArray * _gcr_records_parse_colons (gconstpointer data,
- gssize n_data);
-
-gchar * _gcr_records_format (GPtrArray *records);
-
-GcrRecord * _gcr_records_find (GPtrArray *records,
- GQuark schema);
-
-G_END_DECLS
-
-#endif /* GCR_RECORD_H */
diff --git a/gcr/gcr-renderer.c b/gcr/gcr-renderer.c
deleted file mode 100644
index c98376b5..00000000
--- a/gcr/gcr-renderer.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-deprecated.h"
-#include "gcr-renderer.h"
-
-#include "gcr-certificate-renderer.h"
-#include "gcr-gnupg-renderer.h"
-#include "gcr-key-renderer.h"
-
-#include "gck/gck.h"
-
-#include <gtk/gtk.h>
-
-/**
- * SECTION:gcr-renderer
- * @title: GcrRenderer
- * @short_description: An interface implemented by renderers.
- *
- * A #GcrRenderer is an interface that's implemented by renderers which wish
- * to render data to a #GcrViewer.
- *
- * The interaction between #GcrRenderer and #GcrViewer is not stable yet, and
- * so new renderers cannot be implemented outside the Gcr library at this time.
- *
- * To lookup a renderer for a given set of attributes, use the gcr_renderer_create()
- * function. This will create and initialize a renderer that's capable of viewing
- * the data in those attributes.
- */
-
-/**
- * GcrRenderer:
- *
- * A renderer.
- */
-
-/**
- * GcrRendererIface:
- * @parent: the parent interface type
- * @data_changed: signal emitted when data being rendered changes
- * @render_view: method invoked to render the data into a viewer
- * @populate_popup: method invoked to populate a popup menu with additional
- * renderer options
- *
- * The interface for #GcrRenderer
- */
-
-enum {
- DATA_CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-typedef struct _GcrRegistered {
- GckAttributes *attrs;
- GType renderer_type;
-} GcrRegistered;
-
-static GArray *registered_renderers = NULL;
-static gboolean registered_sorted = FALSE;
-
-static void
-gcr_renderer_default_init (GcrRendererIface *iface)
-{
- static gboolean initialized = FALSE;
- if (!initialized) {
-
- /**
- * GcrRenderer:label:
- *
- * The label to display.
- */
- g_object_interface_install_property (iface,
- g_param_spec_string ("label", "Label", "The label for the renderer",
- "", G_PARAM_READWRITE));
-
- /**
- * GcrRenderer:attributes:
- *
- * The attributes to display.
- */
- g_object_interface_install_property (iface,
- g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the renderer",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-
- /**
- * GcrRenderer::data-changed:
- *
- * A signal that is emitted by the renderer when it's data
- * changed and should be rerendered.
- */
- signals[DATA_CHANGED] = g_signal_new ("data-changed", GCR_TYPE_RENDERER, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrRendererIface, data_changed),
- NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- initialized = TRUE;
- }
-}
-
-typedef GcrRendererIface GcrRendererInterface;
-
-G_DEFINE_INTERFACE (GcrRenderer, gcr_renderer, G_TYPE_OBJECT);
-
-/**
- * gcr_renderer_render_view:
- * @self: The renderer
- * @viewer: The viewer to render to.
- *
- * Render the contents of the renderer to the given viewer.
- */
-void
-gcr_renderer_render_view (GcrRenderer *self, GcrViewer *viewer)
-{
- g_return_if_fail (GCR_IS_RENDERER (self));
- g_return_if_fail (GCR_RENDERER_GET_INTERFACE (self)->render_view);
- GCR_RENDERER_GET_INTERFACE (self)->render_view (self, viewer);
-}
-
-/**
- * gcr_renderer_render:
- * @self: the renderer
- * @viewer: the viewer to render to
- *
- * Render a renderer to the viewer.
- *
- * Deprecated: 3.2: Use gcr_renderer_render_view() instead
- */
-void
-gcr_renderer_render (GcrRenderer *self,
- GcrViewer *viewer)
-{
- gcr_renderer_render_view (self, viewer);
-}
-
-/**
- * gcr_renderer_popuplate_popup:
- * @self: The renderer
- * @viewer: The viewer that is displaying a popup
- * @menu: The popup menu being displayed
- *
- * Called by #GcrViewer when about to display a popup menu for the content
- * displayed by the renderer. The renderer can add a menu item if desired.
- */
-void
-gcr_renderer_popuplate_popup (GcrRenderer *self, GcrViewer *viewer,
- GtkMenu *menu)
-{
- g_return_if_fail (GCR_IS_RENDERER (self));
- if (GCR_RENDERER_GET_INTERFACE (self)->populate_popup)
- GCR_RENDERER_GET_INTERFACE (self)->populate_popup (self, viewer, menu);
-}
-
-/**
- * gcr_renderer_emit_data_changed:
- * @self: The renderer
- *
- * Emit the GcrRenderer::data-changed signal on the renderer. This is used by
- * renderer implementations.
- */
-void
-gcr_renderer_emit_data_changed (GcrRenderer *self)
-{
- g_return_if_fail (GCR_IS_RENDERER (self));
- g_signal_emit (self, signals[DATA_CHANGED], 0);
-}
-
-static gint
-sort_registered_by_n_attrs (gconstpointer a, gconstpointer b)
-{
- const GcrRegistered *ra = a;
- const GcrRegistered *rb = b;
- gulong na, nb;
-
- g_assert (a);
- g_assert (b);
-
- na = gck_attributes_count (ra->attrs);
- nb = gck_attributes_count (rb->attrs);
-
- /* Note we're sorting in reverse order */
- if (na < nb)
- return 1;
- return (na == nb) ? 0 : -1;
-}
-
-/**
- * gcr_renderer_create:
- * @label: (allow-none): The label for the renderer
- * @attrs: The attributes to render
- *
- * Create and initialize a renderer for the given attributes and label. These
- * renderers should have been preregistered via gcr_renderer_register().
- *
- * Returns: (transfer full) (allow-none): a new renderer, or %NULL if no renderer
- * matched the attributes; the render should be released with g_object_unref()
- */
-GcrRenderer *
-gcr_renderer_create (const gchar *label, GckAttributes *attrs)
-{
- GcrRegistered *registered;
- gboolean matched;
- gulong n_attrs;
- gulong j;
- gsize i;
-
- g_return_val_if_fail (attrs, NULL);
-
- gcr_renderer_register_well_known ();
-
- if (!registered_renderers)
- return NULL;
-
- if (!registered_sorted) {
- g_array_sort (registered_renderers, sort_registered_by_n_attrs);
- registered_sorted = TRUE;
- }
-
- for (i = 0; i < registered_renderers->len; ++i) {
- registered = &(g_array_index (registered_renderers, GcrRegistered, i));
- n_attrs = gck_attributes_count (registered->attrs);
-
- matched = TRUE;
-
- for (j = 0; j < n_attrs; ++j) {
- if (!gck_attributes_contains (attrs, gck_attributes_at (registered->attrs, j))) {
- matched = FALSE;
- break;
- }
- }
-
- if (matched)
- return g_object_new (registered->renderer_type, "label", label,
- "attributes", attrs, NULL);
- }
-
- return NULL;
-}
-
-/**
- * gcr_renderer_register:
- * @renderer_type: The renderer class type
- * @attrs: The attributes to match
- *
- * Register a renderer to be created when matching attributes are passed to
- * gcr_renderer_create().
- */
-void
-gcr_renderer_register (GType renderer_type, GckAttributes *attrs)
-{
- GcrRegistered registered;
-
- if (!registered_renderers)
- registered_renderers = g_array_new (FALSE, FALSE, sizeof (GcrRegistered));
-
- registered.renderer_type = renderer_type;
- registered.attrs = gck_attributes_ref (attrs);
- g_array_append_val (registered_renderers, registered);
- registered_sorted = FALSE;
-}
-
-/**
- * gcr_renderer_register_well_known:
- *
- * Register all the well known renderers for certificates and keys known to the
- * Gcr library.
- */
-void
-gcr_renderer_register_well_known (void)
-{
- g_type_class_unref (g_type_class_ref (GCR_TYPE_CERTIFICATE_RENDERER));
- g_type_class_unref (g_type_class_ref (GCR_TYPE_KEY_RENDERER));
- g_type_class_unref (g_type_class_ref (GCR_TYPE_GNUPG_RENDERER));
-}
diff --git a/gcr/gcr-renderer.h b/gcr/gcr-renderer.h
deleted file mode 100644
index 4223ce66..00000000
--- a/gcr/gcr-renderer.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_RENDERER_H__
-#define __GCR_RENDERER_H__
-
-#include <glib-object.h>
-
-#include "gcr-column.h"
-#include "gcr-types.h"
-#include "gcr-viewer.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_RENDERER (gcr_renderer_get_type())
-#define GCR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_RENDERER, GcrRenderer))
-#define GCR_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_RENDERER))
-#define GCR_RENDERER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_RENDERER, GcrRendererIface))
-
-typedef struct _GcrRenderer GcrRenderer;
-typedef struct _GcrRendererIface GcrRendererIface;
-
-struct _GcrRendererIface {
- GTypeInterface parent;
-
- /* signals */
- void (*data_changed) (GcrRenderer *self);
-
- /* virtual */
- void (*render_view) (GcrRenderer *self, GcrViewer *viewer);
-
- void (*populate_popup) (GcrRenderer *self, GcrViewer *viewer, GtkMenu *menu);
-
- /*< private >*/
- gpointer dummy1;
-
- gpointer dummy2;
- gpointer dummy3;
- gpointer dummy4;
- gpointer dummy5;
- gpointer dummy6;
- gpointer dummy7;
-
-};
-
-GType gcr_renderer_get_type (void) G_GNUC_CONST;
-
-void gcr_renderer_render_view (GcrRenderer *self,
- GcrViewer *viewer);
-
-void gcr_renderer_popuplate_popup (GcrRenderer *self,
- GcrViewer *viewer,
- GtkMenu *menu);
-
-void gcr_renderer_emit_data_changed (GcrRenderer *self);
-
-GcrRenderer* gcr_renderer_create (const gchar *label,
- GckAttributes *attrs);
-
-void gcr_renderer_register (GType renderer_type,
- GckAttributes *attrs);
-
-void gcr_renderer_register_well_known (void);
-
-G_END_DECLS
-
-#endif /* __GCR_RENDERER_H__ */
diff --git a/gcr/gcr-secret-exchange.c b/gcr/gcr-secret-exchange.c
deleted file mode 100644
index 92899ad4..00000000
--- a/gcr/gcr-secret-exchange.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-secret-exchange.h"
-
-#include "egg/egg-dh.h"
-#include "egg/egg-hkdf.h"
-#include "egg/egg-libgcrypt.h"
-#include "egg/egg-padding.h"
-#include "egg/egg-secure-memory.h"
-
-#include <string.h>
-#include <gcrypt.h>
-
-EGG_SECURE_DECLARE (secret_exchange);
-
-/**
- * SECTION:gcr-secret-exchange
- * @title: GcrSecretExchange
- * @short_description: Exchange secrets between processes in an unexposed way.
- *
- * Allows exchange of secrets between two processes on the same system without
- * exposing those secrets to things like loggers, non-pageable memory etc.
- *
- * This does not protect against active attacks like MITM attacks.
- *
- * Each side creates a #GcrSecretExchange object, and one of the sides calls
- * gcr_secret_exchange_begin(). This creates a string, which should be passed
- * to the other side. Each side passes the strings it receives into
- * gcr_secret_exchange_receive().
- *
- * In order to send a reply (either with or without a secret) use
- * gcr_secret_exchange_send(). A side must have had gcr_secret_exchange_receive()
- * successfully called before it can use gcr_secret_exchange_send().
- *
- * The #GcrSecretExchange objects can be used for multiple iterations of the
- * conversation, or for just one request/reply. The only limitation being that
- * the initial request cannot contain a secret.
- *
- * Caveat: Information about the approximate length (rounded up to the nearest
- * 16 bytes) may be leaked. If this is considered inacceptable, do not use
- * #GcrSecretExchange.
- */
-
-/**
- * GcrSecretExchange:
- *
- * An object representing one side of a secret exchange.
- */
-
-/**
- * GcrSecretExchangeClass:
- *
- * The class for #GcrSecretExchange
- */
-
-/**
- * GCR_SECRET_EXCHANGE_PROTOCOL_1:
- *
- * The current secret exchange protocol. Key agreement is done using DH with the
- * 1536 bit IKE parameter group. Keys are derived using SHA256 with HKDF. The
- * transport encryption is done with 128 bit AES.
- */
-
-#define SECRET_EXCHANGE_PROTOCOL_1_PREFIX "[" GCR_SECRET_EXCHANGE_PROTOCOL_1 "]\n"
-
-enum {
- PROP_0,
- PROP_PROTOCOL
-};
-
-typedef struct _GcrSecretExchangeDefault GcrSecretExchangeDefault;
-
-struct _GcrSecretExchangePrivate {
- GcrSecretExchangeDefault *default_exchange;
- GDestroyNotify destroy_exchange;
- gboolean explicit_protocol;
- gboolean generated;
- guchar *publi;
- gsize n_publi;
- gboolean derived;
- gchar *secret;
- gsize n_secret;
-};
-
-G_DEFINE_TYPE (GcrSecretExchange, gcr_secret_exchange, G_TYPE_OBJECT);
-
-static void
-key_file_set_base64 (GKeyFile *key_file, const gchar *section,
- const gchar *field, gconstpointer data, gsize n_data)
-{
- gchar *value;
-
- value = g_base64_encode (data, n_data);
- g_key_file_set_value (key_file, section, field, value);
- g_free (value);
-}
-
-static gpointer
-key_file_get_base64 (GKeyFile *key_file, const gchar *section,
- const gchar *field, gsize *n_result)
-{
- gpointer result = NULL;
- gchar *data;
-
- g_return_val_if_fail (key_file, NULL);
- g_return_val_if_fail (section, NULL);
- g_return_val_if_fail (field, NULL);
- g_return_val_if_fail (n_result, NULL);
-
- data = g_key_file_get_value (key_file, section, field, NULL);
- if (data != NULL)
- result = g_base64_decode (data, n_result);
- g_free (data);
- return result;
-}
-
-static void
-gcr_secret_exchange_init (GcrSecretExchange *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_SECRET_EXCHANGE,
- GcrSecretExchangePrivate);
-}
-
-
-static void
-gcr_secret_exchange_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrSecretExchange *self = GCR_SECRET_EXCHANGE (obj);
- const gchar *protocol;
-
- switch (prop_id) {
- case PROP_PROTOCOL:
- protocol = g_value_get_string (value);
- if (protocol != NULL) {
- if (g_str_equal (protocol, GCR_SECRET_EXCHANGE_PROTOCOL_1))
- self->pv->explicit_protocol = TRUE;
- else
- g_warning ("the GcrSecretExchange protocol %s is unsupported defaulting to %s",
- protocol, GCR_SECRET_EXCHANGE_PROTOCOL_1);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_secret_exchange_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrSecretExchange *self = GCR_SECRET_EXCHANGE (obj);
-
- switch (prop_id) {
- case PROP_PROTOCOL:
- g_value_set_string (value, gcr_secret_exchange_get_protocol (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-clear_secret_exchange (GcrSecretExchange *self)
-{
- g_free (self->pv->publi);
- self->pv->publi = NULL;
- self->pv->n_publi = 0;
- self->pv->derived = FALSE;
- self->pv->generated = TRUE;
- egg_secure_free (self->pv->secret);
- self->pv->secret = NULL;
- self->pv->n_secret = 0;
-}
-
-static void
-gcr_secret_exchange_finalize (GObject *obj)
-{
- GcrSecretExchange *self = GCR_SECRET_EXCHANGE (obj);
-
- if (self->pv->destroy_exchange)
- (self->pv->destroy_exchange) (self->pv->default_exchange);
-
- clear_secret_exchange (self);
-
- G_OBJECT_CLASS (gcr_secret_exchange_parent_class)->finalize (obj);
-}
-
-/**
- * gcr_secret_exchange_new:
- * @protocol: (allow-none): the exchange protocol to use
- *
- * Create a new secret exchange object.
- *
- * Specify a protocol of %NULL to allow any protocol. This is especially
- * relevant on the side of the exchange that does not call
- * gcr_secret_exchange_begin(), that is the originator. Currently the only
- * protocol supported is %GCR_SECRET_EXCHANGE_PROTOCOL_1.
- *
- * Returns: (transfer full): A new #GcrSecretExchange object
- */
-GcrSecretExchange *
-gcr_secret_exchange_new (const gchar *protocol)
-{
- return g_object_new (GCR_TYPE_SECRET_EXCHANGE,
- "protocol", protocol,
- NULL);
-}
-
-/**
- * gcr_secret_exchange_get_protocol:
- * @self: a #GcrSecretExchange object
- * Get the secret exchange protocol.
- *
- * Will return %NULL if no protocol was specified, and either
- * gcr_secret_exchange_begin() or gcr_secret_exchange_receive() have not been
- * called successfully.
- *
- * Returns: the protocol or %NULL
- */
-const gchar *
-gcr_secret_exchange_get_protocol (GcrSecretExchange *self)
-{
- g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
- if (self->pv->explicit_protocol || self->pv->generated)
- return GCR_SECRET_EXCHANGE_PROTOCOL_1;
- return NULL;
-}
-
-/**
- * gcr_secret_exchange_begin:
- * @self: a #GcrSecretExchange object
- *
- * Begin the secret exchange. The resulting string should be sent to the other
- * side of the exchange. The other side should use gcr_secret_exchange_receive()
- * to process the string.
- *
- * Returns: (transfer full): A newly allocated string to be sent to the other
- * side of the secret exchange
- */
-gchar *
-gcr_secret_exchange_begin (GcrSecretExchange *self)
-{
- GcrSecretExchangeClass *klass;
- GKeyFile *output;
- gchar *result;
-
- g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
-
- klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
- g_return_val_if_fail (klass->generate_exchange_key, NULL);
-
- clear_secret_exchange (self);
-
- output = g_key_file_new ();
-
- if (!(klass->generate_exchange_key) (self, GCR_SECRET_EXCHANGE_PROTOCOL_1,
- &self->pv->publi, &self->pv->n_publi))
- g_return_val_if_reached (NULL);
- self->pv->generated = TRUE;
-
- key_file_set_base64 (output, GCR_SECRET_EXCHANGE_PROTOCOL_1, "public",
- self->pv->publi, self->pv->n_publi);
-
- result = g_key_file_to_data (output, NULL, NULL);
- g_return_val_if_fail (result != NULL, NULL);
-
- g_strchomp (result);
-
- if (g_str_has_prefix (result, SECRET_EXCHANGE_PROTOCOL_1_PREFIX))
- g_warning ("the prepared data does not have the correct protocol prefix");
-
- g_key_file_free (output);
-
- return result;
-}
-
-static gboolean
-derive_key (GcrSecretExchange *self,
- GKeyFile *input)
-{
- GcrSecretExchangeClass *klass;
- gboolean ret;
- guchar *peer;
- gsize n_peer;
-
- klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
- g_return_val_if_fail (klass->derive_transport_key, FALSE);
-
- peer = key_file_get_base64 (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "public", &n_peer);
- if (peer == NULL) {
- g_message ("secret-exchange: invalid or missing 'public' argument");
- return FALSE;
- }
-
- ret = (klass->derive_transport_key) (self, peer, n_peer);
- self->pv->derived = ret;
-
- g_free (peer);
- return ret;
-}
-
-static gboolean
-perform_decrypt (GcrSecretExchange *self,
- GKeyFile *input,
- guchar **secret,
- gsize *n_secret)
-{
- GcrSecretExchangeClass *klass;
- gpointer iv, value;
- guchar *result;
- gsize n_result, n_iv, n_value;
- gboolean ret;
-
- klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
- g_return_val_if_fail (klass->decrypt_transport_data, FALSE);
-
- iv = key_file_get_base64 (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "iv", &n_iv);
-
- value = key_file_get_base64 (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "secret", &n_value);
- if (value == NULL) {
- g_message ("secret-exchange: invalid or missing value");
- g_free (iv);
- return FALSE;
- }
-
- ret = (klass->decrypt_transport_data) (self, egg_secure_realloc, value, n_value,
- iv, n_iv, &result, &n_result);
-
- g_free (value);
- g_free (iv);
-
- if (!ret)
- return FALSE;
-
- /* Reallocate a null terminator */
- if (result) {
- result = egg_secure_realloc (result, n_result + 1);
- result[n_result] = 0;
- }
-
- *secret = result;
- *n_secret = n_result;
-
- return TRUE;
-}
-
-/**
- * gcr_secret_exchange_receive:
- * @self: a #GcrSecretExchange object
- * @exchange: the string received
- *
- * Receive a string from the other side of secret exchange. This string will
- * have been created by gcr_secret_exchange_begin() or gcr_secret_exchange_send()
- *
- * Returns: whether the string was successfully parsed and received
- */
-gboolean
-gcr_secret_exchange_receive (GcrSecretExchange *self,
- const gchar *exchange)
-{
- GcrSecretExchangeClass *klass;
- GKeyFile *input;
- gchar *secret;
- gsize n_secret;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), FALSE);
- g_return_val_if_fail (exchange != NULL, FALSE);
-
- klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
- g_return_val_if_fail (klass->generate_exchange_key, FALSE);
- g_return_val_if_fail (klass->derive_transport_key, FALSE);
-
- /* Parse the input */
- input = g_key_file_new ();
- if (!g_key_file_load_from_data (input, exchange, strlen (exchange),
- G_KEY_FILE_NONE, NULL)) {
- g_key_file_free (input);
- g_message ("couldn't parse secret exchange data");
- return FALSE;
- }
-
- if (!self->pv->generated) {
- if (!(klass->generate_exchange_key) (self, GCR_SECRET_EXCHANGE_PROTOCOL_1,
- &self->pv->publi, &self->pv->n_publi))
- g_return_val_if_reached (FALSE);
- self->pv->generated = TRUE;
- }
-
- if (!self->pv->derived) {
- if (!derive_key (self, input))
- return FALSE;
- }
-
- ret = TRUE;
-
- if (g_key_file_has_key (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "secret", NULL)) {
-
- /* Remember that this can return a NULL secret */
- if (!perform_decrypt (self, input, (guchar **)&secret, &n_secret)) {
- ret = FALSE;
- } else {
- egg_secure_free (self->pv->secret);
- self->pv->secret = secret;
- self->pv->n_secret = n_secret;
- }
- }
-
- return ret;
-}
-
-/**
- * gcr_secret_exchange_get_secret:
- * @self: a #GcrSecretExchange object
- * @secret_len: (allow-none): optionally, a location to store the length of returned secret
- *
- * Returns the last secret received. If no secret has yet been received this
- * will return %NULL. The string is owned by the #GcrSecretExchange object
- * and will be valid until the next time that gcr_secret_exchange_receive()
- * is called on this object, or the object is destroyed.
- *
- * Depending on the secret passed into the other side of the secret exchange,
- * the resurt may be a binary string. It does however have a null terminator,
- * so if you're certain that it is does not contain arbitrary binary data,
- * it can be used as a string.
- *
- * Returns: (transfer none) (array length=secret_len): the last secret received
- */
-const gchar *
-gcr_secret_exchange_get_secret (GcrSecretExchange *self,
- gsize *secret_len)
-{
- g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
-
- if (secret_len)
- *secret_len = self->pv->n_secret;
- return self->pv->secret;
-}
-
-static gboolean
-perform_encrypt (GcrSecretExchange *self,
- GKeyFile *output,
- const gchar *secret,
- gsize n_secret)
-{
- GcrSecretExchangeClass *klass;
- guchar *result, *iv;
- gsize n_result, n_iv;
-
- klass = GCR_SECRET_EXCHANGE_GET_CLASS (self);
- g_return_val_if_fail (klass->encrypt_transport_data, FALSE);
-
- if (!(klass->encrypt_transport_data) (self, g_realloc, (const guchar *)secret,
- n_secret, &iv, &n_iv, &result, &n_result))
- return FALSE;
-
- key_file_set_base64 (output, GCR_SECRET_EXCHANGE_PROTOCOL_1, "secret", result, n_result);
- key_file_set_base64 (output, GCR_SECRET_EXCHANGE_PROTOCOL_1, "iv", iv, n_iv);
-
- g_free (result);
- g_free (iv);
-
- return TRUE;
-}
-
-/**
- * gcr_secret_exchange_send:
- * @self: a #GcrSecretExchange object
- * @secret: (allow-none): optionally, a secret to send to the other side
- * @secret_len: length of @secret, or -1 if null terminated
- *
- * Send a reply to the other side of the secret exchange, optionally sending a
- * secret.
- *
- * gcr_secret_exchange_receive() must have been successfully called at least
- * once on this object. In other words this object must have received data
- * from the other side of the secret exchange, before we can send a secret.
- *
- * Returns: (transfer full): a newly allocated string to be sent to the other
- * side of the secret exchange
- */
-gchar *
-gcr_secret_exchange_send (GcrSecretExchange *self,
- const gchar *secret,
- gssize secret_len)
-{
- GKeyFile *output;
- gchar *result;
-
- g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
-
- if (!self->pv->derived) {
- g_warning ("gcr_secret_exchange_receive() must be called "
- "before calling this function");
- return NULL;
- }
-
- output = g_key_file_new ();
- key_file_set_base64 (output, GCR_SECRET_EXCHANGE_PROTOCOL_1, "public", self->pv->publi,
- self->pv->n_publi);
-
- if (secret != NULL) {
- if (secret_len < 0)
- secret_len = strlen (secret);
- if (!perform_encrypt (self, output, secret, secret_len)) {
- g_key_file_free (output);
- return NULL;
- }
- }
-
- result = g_key_file_to_data (output, NULL, NULL);
- g_return_val_if_fail (result != NULL, NULL);
-
- g_strchomp (result);
-
- if (g_str_has_prefix (result, SECRET_EXCHANGE_PROTOCOL_1_PREFIX))
- g_warning ("the prepared data does not have the correct protocol prefix");
-
- g_key_file_free (output);
- return result;
-}
-
-/*
- * This is the only set we support so far. It includes:
- * - DH with the 1536 ike modp group for key exchange
- * - HKDF SHA256 for hashing of the key to appropriate size
- * - AES 128 CBC for encryption
- * - PKCS#7 style padding
- */
-
-#define EXCHANGE_1_IKE_NAME "ietf-ike-grp-modp-1536"
-#define EXCHANGE_1_KEY_LENGTH 16
-#define EXCHANGE_1_IV_LENGTH 16
-#define EXCHANGE_1_HASH_ALGO "sha256"
-#define EXCHANGE_1_CIPHER_ALGO GCRY_CIPHER_AES128
-#define EXCHANGE_1_CIPHER_MODE GCRY_CIPHER_MODE_CBC
-
-struct _GcrSecretExchangeDefault {
- gcry_mpi_t prime;
- gcry_mpi_t base;
- gcry_mpi_t pub;
- gcry_mpi_t priv;
- gpointer key;
-};
-
-static guchar *
-mpi_to_data (gcry_mpi_t mpi,
- gsize *n_data)
-{
- gcry_error_t gcry;
- guchar *data;
-
- /* Get the size */
- gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, n_data, mpi);
- g_return_val_if_fail (gcry == 0, NULL);
-
- data = g_malloc0 (*n_data);
-
- /* Write into buffer */
- gcry = gcry_mpi_print (GCRYMPI_FMT_USG, data, *n_data, n_data, mpi);
- g_return_val_if_fail (gcry == 0, NULL);
-
- return data;
-}
-
-static gcry_mpi_t
-mpi_from_data (const guchar *data,
- gsize n_data)
-{
- gcry_mpi_t mpi;
- gcry_error_t gcry;
-
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
- return (gcry == 0) ? mpi : NULL;
-}
-
-static void
-gcr_secret_exchange_default_free (gpointer to_free)
-{
- GcrSecretExchangeDefault *data = to_free;
- gcry_mpi_release (data->prime);
- gcry_mpi_release (data->base);
- gcry_mpi_release (data->pub);
- gcry_mpi_release (data->priv);
- if (data->key) {
- egg_secure_clear (data->key, EXCHANGE_1_KEY_LENGTH);
- egg_secure_free (data->key);
- }
- g_free (data);
-}
-
-static gboolean
-gcr_secret_exchange_default_generate_exchange_key (GcrSecretExchange *exchange,
- const gchar *scheme,
- guchar **public_key,
- gsize *n_public_key)
-{
- GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
-
- if (data == NULL) {
- data = g_new0 (GcrSecretExchangeDefault, 1);
- if (!egg_dh_default_params (EXCHANGE_1_IKE_NAME, &data->prime, &data->base))
- g_return_val_if_reached (FALSE);
-
- exchange->pv->default_exchange = data;
- exchange->pv->destroy_exchange = gcr_secret_exchange_default_free;
- }
-
- gcry_mpi_release (data->priv);
- data->priv = NULL;
- gcry_mpi_release (data->pub);
- data->pub = NULL;
- egg_secure_free (data->key);
- data->key = NULL;
-
- if (!egg_dh_gen_pair (data->prime, data->base, 0,
- &data->pub, &data->priv))
- g_return_val_if_reached (FALSE);
-
- *public_key = mpi_to_data (data->pub, n_public_key);
- return *public_key != NULL;
-}
-
-static gboolean
-gcr_secret_exchange_default_derive_transport_key (GcrSecretExchange *exchange,
- const guchar *peer,
- gsize n_peer)
-{
- GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
- gpointer ikm;
- gsize n_ikm;
- gcry_mpi_t mpi;
-
- g_return_val_if_fail (data != NULL, FALSE);
- g_return_val_if_fail (data->priv != NULL, FALSE);
-
- mpi = mpi_from_data (peer, n_peer);
- if (mpi == NULL)
- return FALSE;
-
- /* Build up a key we can use */
- ikm = egg_dh_gen_secret (mpi, data->priv, data->prime, &n_ikm);
- g_return_val_if_fail (ikm != NULL, FALSE);
-
- if (data->key == NULL)
- data->key = egg_secure_alloc (EXCHANGE_1_KEY_LENGTH);
-
- if (!egg_hkdf_perform (EXCHANGE_1_HASH_ALGO, ikm, n_ikm, NULL, 0,
- NULL, 0, data->key, EXCHANGE_1_KEY_LENGTH))
- g_return_val_if_reached (FALSE);
-
- egg_secure_free (ikm);
- gcry_mpi_release (mpi);
-
- return TRUE;
-}
-
-static gboolean
-gcr_secret_exchange_default_encrypt_transport_data (GcrSecretExchange *exchange,
- GckAllocator allocator,
- const guchar *plain_text,
- gsize n_plain_text,
- guchar **iv,
- gsize *n_iv,
- guchar **cipher_text,
- gsize *n_cipher_text)
-{
- GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
- gcry_cipher_hd_t cih;
- gcry_error_t gcry;
- guchar *padded;
- gsize n_result;
- guchar *result;
- gsize pos;
-
- g_return_val_if_fail (data != NULL, FALSE);
- g_return_val_if_fail (data->key != NULL, FALSE);
-
- gcry = gcry_cipher_open (&cih, EXCHANGE_1_CIPHER_ALGO, EXCHANGE_1_CIPHER_MODE, 0);
- if (gcry != 0) {
- g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gcry));
- g_free (iv);
- return FALSE;
- }
-
- *iv = (allocator) (NULL, EXCHANGE_1_IV_LENGTH);
- g_return_val_if_fail (*iv != NULL, FALSE);
- gcry_create_nonce (*iv, EXCHANGE_1_IV_LENGTH);
- *n_iv = EXCHANGE_1_IV_LENGTH;
-
- /* 16 = 128 bits */
- gcry = gcry_cipher_setkey (cih, data->key, EXCHANGE_1_KEY_LENGTH);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* 16 = 128 bits */
- gcry = gcry_cipher_setiv (cih, *iv, EXCHANGE_1_IV_LENGTH);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* Pad the text properly */
- if (!egg_padding_pkcs7_pad (egg_secure_realloc, 16, plain_text, n_plain_text,
- (gpointer*)&padded, &n_result))
- g_return_val_if_reached (FALSE);
- result = (allocator) (NULL, n_result);
- g_return_val_if_fail (result != NULL, FALSE);
-
- for (pos = 0; pos < n_result; pos += 16) {
- gcry = gcry_cipher_encrypt (cih, result + pos, 16, padded + pos, 16);
- g_return_val_if_fail (gcry == 0, FALSE);
- }
-
- gcry_cipher_close (cih);
-
- egg_secure_clear (padded, n_result);
- egg_secure_free (padded);
-
- *cipher_text = result;
- *n_cipher_text = n_result;
- return TRUE;
-}
-
-static gboolean
-gcr_secret_exchange_default_decrypt_transport_data (GcrSecretExchange *exchange,
- GckAllocator allocator,
- const guchar *cipher_text,
- gsize n_cipher_text,
- const guchar *iv,
- gsize n_iv,
- guchar **plain_text,
- gsize *n_plain_text)
-{
- GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
- guchar* padded;
- guchar* result;
- gsize n_result;
- gsize pos;
- gcry_cipher_hd_t cih;
- gcry_error_t gcry;
-
- g_return_val_if_fail (data != NULL, FALSE);
- g_return_val_if_fail (data->key != NULL, FALSE);
-
- if (iv == NULL || n_iv != EXCHANGE_1_IV_LENGTH) {
- g_message ("secret-exchange: invalid or missing iv");
- return FALSE;
- }
-
- if (n_cipher_text % 16 != 0) {
- g_message ("secret-message: invalid length for cipher text");
- return FALSE;
- }
-
- gcry = gcry_cipher_open (&cih, EXCHANGE_1_CIPHER_ALGO, EXCHANGE_1_CIPHER_MODE, 0);
- if (gcry != 0) {
- g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gcry));
- return FALSE;
- }
-
- /* 16 = 128 bits */
- gcry = gcry_cipher_setkey (cih, data->key, EXCHANGE_1_KEY_LENGTH);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* 16 = 128 bits */
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* Allocate memory for the result */
- padded = (allocator) (NULL, n_cipher_text);
- g_return_val_if_fail (padded != NULL, FALSE);
-
- for (pos = 0; pos < n_cipher_text; pos += 16) {
- gcry = gcry_cipher_decrypt (cih, padded + pos, 16, (guchar *)cipher_text + pos, 16);
- g_return_val_if_fail (gcry == 0, FALSE);
- }
-
- gcry_cipher_close (cih);
-
- if (!egg_padding_pkcs7_unpad (allocator, 16, padded, n_cipher_text,
- (gpointer*)&result, &n_result))
- result = NULL;
-
- /* Free the padded text */
- (allocator) (padded, 0);
-
- *plain_text = result;
- *n_plain_text = n_result;
- return TRUE;
-}
-
-static void
-gcr_secret_exchange_class_init (GcrSecretExchangeClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->get_property = gcr_secret_exchange_get_property;
- gobject_class->set_property = gcr_secret_exchange_set_property;
- gobject_class->finalize = gcr_secret_exchange_finalize;
-
- klass->generate_exchange_key = gcr_secret_exchange_default_generate_exchange_key;
- klass->derive_transport_key = gcr_secret_exchange_default_derive_transport_key;
- klass->decrypt_transport_data = gcr_secret_exchange_default_decrypt_transport_data;
- klass->encrypt_transport_data = gcr_secret_exchange_default_encrypt_transport_data;
-
- g_type_class_add_private (gobject_class, sizeof (GcrSecretExchangePrivate));
-
- egg_libgcrypt_initialize ();
-
- /**
- * GcrSecretExchange:protocol:
- *
- * The protocol being used for the exchange.
- *
- * Will be %NULL if no protocol was specified when creating this object,
- * and either gcr_secret_exchange_begin() or gcr_secret_exchange_receive()
- * have not been called successfully.
- */
- g_object_class_install_property (gobject_class, PROP_PROTOCOL,
- g_param_spec_string ("protocol", "Protocol", "Exchange protocol",
- GCR_SECRET_EXCHANGE_PROTOCOL_1,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
diff --git a/gcr/gcr-secret-exchange.h b/gcr/gcr-secret-exchange.h
deleted file mode 100644
index 5608f632..00000000
--- a/gcr/gcr-secret-exchange.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_SECRET_EXCHANGE_H__
-#define __GCR_SECRET_EXCHANGE_H__
-
-#include "gcr-base.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_SECRET_EXCHANGE_PROTOCOL_1 "sx-aes-1"
-
-#define GCR_TYPE_SECRET_EXCHANGE (gcr_secret_exchange_get_type ())
-#define GCR_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchange))
-#define GCR_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchangeClass))
-#define GCR_IS_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_SECRET_EXCHANGE))
-#define GCR_IS_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_SECRET_EXCHANGE))
-#define GCR_SECRET_EXCHANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchangeClass))
-
-typedef struct _GcrSecretExchange GcrSecretExchange;
-typedef struct _GcrSecretExchangeClass GcrSecretExchangeClass;
-typedef struct _GcrSecretExchangePrivate GcrSecretExchangePrivate;
-
-struct _GcrSecretExchange {
- /*< private >*/
- GObject parent;
- GcrSecretExchangePrivate *pv;
-};
-
-struct _GcrSecretExchangeClass {
- /*< private >*/
- GObjectClass parent_class;
-
- /* virtual methods, not used publicly */
- gboolean (*generate_exchange_key) (GcrSecretExchange *exchange,
- const gchar *scheme,
- guchar **public_key,
- gsize *n_public_key);
-
- gboolean (*derive_transport_key) (GcrSecretExchange *exchange,
- const guchar *peer,
- gsize n_peer);
-
- gboolean (*encrypt_transport_data) (GcrSecretExchange *exchange,
- GckAllocator allocator,
- const guchar *plain_text,
- gsize n_plain_text,
- guchar **parameter,
- gsize *n_parameter,
- guchar **cipher_text,
- gsize *n_cipher_text);
-
- gboolean (*decrypt_transport_data) (GcrSecretExchange *exchange,
- GckAllocator allocator,
- const guchar *cipher_text,
- gsize n_cipher_text,
- const guchar *parameter,
- gsize n_parameter,
- guchar **plain_text,
- gsize *n_plain_text);
-
- gpointer dummy[6];
-};
-
-/* Caller side functions */
-
-GType gcr_secret_exchange_get_type (void);
-
-GcrSecretExchange * gcr_secret_exchange_new (const gchar *protocol);
-
-const gchar * gcr_secret_exchange_get_protocol (GcrSecretExchange *self);
-
-gchar * gcr_secret_exchange_begin (GcrSecretExchange *self);
-
-gboolean gcr_secret_exchange_receive (GcrSecretExchange *self,
- const gchar *exchange);
-
-gchar * gcr_secret_exchange_send (GcrSecretExchange *self,
- const gchar *secret,
- gssize secret_len);
-
-const gchar * gcr_secret_exchange_get_secret (GcrSecretExchange *self,
- gsize *secret_len);
-
-G_END_DECLS
-
-#endif /* __GCR_SECRET_EXCHANGE_H__ */
diff --git a/gcr/gcr-simple-certificate.c b/gcr/gcr-simple-certificate.c
deleted file mode 100644
index 03e3e763..00000000
--- a/gcr/gcr-simple-certificate.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-certificate.h"
-#include "gcr-comparable.h"
-#include "gcr-internal.h"
-#include "gcr-simple-certificate.h"
-
-#include <string.h>
-
-/**
- * SECTION:gcr-simple-certificate
- * @title: GcrSimpleCertificate
- * @short_description: A certificate loaded from a memory buffer
- *
- * An implementation of #GcrCertificate which loads a certificate from DER
- * data already located in memory.
- *
- * To create a #GcrSimpleCertificate object use the
- * gcr_simple_certificate_new() or gcr_simple_certificate_new_static()
- * functions.
- */
-
-/**
- * GcrSimpleCertificate:
- *
- * A #GcrCertificate which represents a certificate already in memory.
- */
-
-/**
- * GcrSimpleCertificateClass:
- * @parent_class: The parent class
- *
- * The class for #GcrSimpleCertificate.
- */
-
-struct _GcrSimpleCertificatePrivate {
- const guchar *data;
- gsize n_data;
- guchar *owned;
-};
-
-/* Forward declarations */
-static void gcr_simple_certificate_iface_init (GcrCertificateIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrSimpleCertificate, gcr_simple_certificate, G_TYPE_OBJECT,
- GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_simple_certificate_iface_init);
-);
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gcr_simple_certificate_init (GcrSimpleCertificate *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_SIMPLE_CERTIFICATE, GcrSimpleCertificatePrivate);
-}
-
-static void
-gcr_simple_certificate_real_finalize (GObject *obj)
-{
- GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (obj);
-
- g_free (self->pv->owned);
- self->pv->owned = NULL;
- self->pv->data = NULL;
- self->pv->n_data = 0;
-
- G_OBJECT_CLASS (gcr_simple_certificate_parent_class)->finalize (obj);
-}
-
-static void
-gcr_simple_certificate_class_init (GcrSimpleCertificateClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gcr_simple_certificate_real_finalize;
- gobject_class->get_property = gcr_certificate_mixin_get_property;
-
- g_type_class_add_private (gobject_class, sizeof (GcrSimpleCertificatePrivate));
-
- gcr_certificate_mixin_class_init (gobject_class);
- _gcr_initialize_library ();
-}
-
-static const guchar *
-gcr_simple_certificate_get_der_data (GcrCertificate *cert,
- gsize *n_data)
-{
- GcrSimpleCertificate *self = GCR_SIMPLE_CERTIFICATE (cert);
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data, NULL);
- g_return_val_if_fail (self->pv->data, NULL);
-
- /* This is called when we're not a base class */
- *n_data = self->pv->n_data;
- return self->pv->data;
-}
-
-static void
-gcr_simple_certificate_iface_init (GcrCertificateIface *iface)
-{
- iface->get_der_data = gcr_simple_certificate_get_der_data;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_simple_certificate_new:
- * @data: (array length=n_data): the raw DER certificate data
- * @n_data: The length of @data
- *
- * Create a new #GcrSimpleCertificate for the raw DER data. The @data memory is
- * copied so you can dispose of it after this function returns.
- *
- * Returns: (transfer full) (type Gcr.SimpleCertificate): a new #GcrSimpleCertificate
- */
-GcrCertificate *
-gcr_simple_certificate_new (const guchar *data,
- gsize n_data)
-{
- GcrSimpleCertificate *cert;
-
- g_return_val_if_fail (data, NULL);
- g_return_val_if_fail (n_data, NULL);
-
- cert = g_object_new (GCR_TYPE_SIMPLE_CERTIFICATE, NULL);
-
- cert->pv->data = cert->pv->owned = g_memdup (data, n_data);
- cert->pv->n_data = n_data;
- return GCR_CERTIFICATE (cert);
-}
-
-/**
- * gcr_simple_certificate_new_static: (skip)
- * @data: (array length=n_data): The raw DER certificate data
- * @n_data: The length of @data
- *
- * Create a new #GcrSimpleCertificate for the raw DER data. The @data memory is
- * not copied and must persist until the #GcrSimpleCertificate object is
- * destroyed.
- *
- * Returns: (transfer full) (type Gcr.SimpleCertificate): a new #GcrSimpleCertificate
- */
-GcrCertificate *
-gcr_simple_certificate_new_static (const guchar *data,
- gsize n_data)
-{
- GcrSimpleCertificate *cert;
-
- g_return_val_if_fail (data, NULL);
- g_return_val_if_fail (n_data, NULL);
-
- cert = g_object_new (GCR_TYPE_SIMPLE_CERTIFICATE, NULL);
-
- cert->pv->owned = NULL;
- cert->pv->data = data;
- cert->pv->n_data = n_data;
- return GCR_CERTIFICATE (cert);
-}
diff --git a/gcr/gcr-simple-certificate.h b/gcr/gcr-simple-certificate.h
deleted file mode 100644
index d95aaae8..00000000
--- a/gcr/gcr-simple-certificate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_SIMPLE_CERTIFICATE_H__
-#define __GCR_SIMPLE_CERTIFICATE_H__
-
-#include "gcr-base.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_SIMPLE_CERTIFICATE (gcr_simple_certificate_get_type ())
-#define GCR_SIMPLE_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_SIMPLE_CERTIFICATE, GcrSimpleCertificate))
-#define GCR_SIMPLE_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_SIMPLE_CERTIFICATE, GcrSimpleCertificateClass))
-#define GCR_IS_SIMPLE_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_SIMPLE_CERTIFICATE))
-#define GCR_IS_SIMPLE_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_SIMPLE_CERTIFICATE))
-#define GCR_SIMPLE_CERTIFICATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_SIMPLE_CERTIFICATE, GcrSimpleCertificateClass))
-
-typedef struct _GcrSimpleCertificate GcrSimpleCertificate;
-typedef struct _GcrSimpleCertificateClass GcrSimpleCertificateClass;
-typedef struct _GcrSimpleCertificatePrivate GcrSimpleCertificatePrivate;
-
-struct _GcrSimpleCertificate {
- GObject parent;
-
- /*< private >*/
- GcrSimpleCertificatePrivate *pv;
-};
-
-struct _GcrSimpleCertificateClass {
- GObjectClass parent_class;
-};
-
-GType gcr_simple_certificate_get_type (void);
-
-GcrCertificate * gcr_simple_certificate_new (const guchar *data,
- gsize n_data);
-
-GcrCertificate * gcr_simple_certificate_new_static (const guchar *data,
- gsize n_data);
-
-G_END_DECLS
-
-#endif /* __GCR_SIMPLE_CERTIFICATE_H__ */
diff --git a/gcr/gcr-simple-collection.c b/gcr/gcr-simple-collection.c
deleted file mode 100644
index f843a7c3..00000000
--- a/gcr/gcr-simple-collection.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection.h"
-#include "gcr-deprecated-base.h"
-#include "gcr-internal.h"
-#include "gcr-simple-collection.h"
-
-#include <string.h>
-
-/**
- * SECTION:gcr-simple-collection
- * @title: GcrSimpleCollection
- * @short_description: A simple implementation of GcrCollection
- *
- * A simple implementation of #GcrCollection, which you can add and remove
- * objects from. Use gcr_simple_collection_add() to do this
- * gcr_simple_collection_remove().
- */
-
-/**
- * GcrSimpleCollection:
- *
- * A simple implementation of #GcrCollection.
- */
-
-/**
- * GcrSimpleCollectionClass:
- * @parent_class: The parent class
- *
- * The class for #GcrSimpleCollection.
- */
-
-struct _GcrSimpleCollectionPrivate {
- GHashTable *items;
-};
-
-static void gcr_collection_iface (GcrCollectionIface *iface);
-G_DEFINE_TYPE_WITH_CODE (GcrSimpleCollection, gcr_simple_collection, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, gcr_collection_iface));
-
-#define UNUSED_VALUE GUINT_TO_POINTER (1)
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gcr_simple_collection_init (GcrSimpleCollection *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_SIMPLE_COLLECTION, GcrSimpleCollectionPrivate);
- self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
-}
-
-static void
-gcr_simple_collection_dispose (GObject *obj)
-{
- GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (obj);
-
- g_hash_table_remove_all (self->pv->items);
-
- G_OBJECT_CLASS (gcr_simple_collection_parent_class)->dispose (obj);
-}
-
-static void
-gcr_simple_collection_finalize (GObject *obj)
-{
- GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (obj);
-
- g_assert (self->pv->items);
- g_assert (g_hash_table_size (self->pv->items) == 0);
- g_hash_table_destroy (self->pv->items);
- self->pv->items = NULL;
-
- G_OBJECT_CLASS (gcr_simple_collection_parent_class)->finalize (obj);
-}
-
-static void
-gcr_simple_collection_class_init (GcrSimpleCollectionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose = gcr_simple_collection_dispose;
- gobject_class->finalize = gcr_simple_collection_finalize;
- g_type_class_add_private (gobject_class, sizeof (GcrSimpleCollectionPrivate));
-}
-
-static guint
-gcr_simple_collection_real_get_length (GcrCollection *coll)
-{
- GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (coll);
- return g_hash_table_size (self->pv->items);
-}
-
-static GList*
-gcr_simple_collection_real_get_objects (GcrCollection *coll)
-{
- GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (coll);
- return g_hash_table_get_keys (self->pv->items);
-}
-
-static gboolean
-gcr_simple_collection_real_contains (GcrCollection *collection,
- GObject *object)
-{
- GcrSimpleCollection *self = GCR_SIMPLE_COLLECTION (collection);
- return g_hash_table_lookup (self->pv->items, object) ? TRUE : FALSE;
-}
-
-static void
-gcr_collection_iface (GcrCollectionIface *iface)
-{
- iface->get_length = gcr_simple_collection_real_get_length;
- iface->get_objects = gcr_simple_collection_real_get_objects;
- iface->contains = gcr_simple_collection_real_contains;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_simple_collection_new:
- *
- * Create a new #GcrSimpleCollection.
- *
- * Returns: (transfer full) (type Gcr.SimpleCollection): a newly allocated
- * collection, which should be freed with g_object_unref()
- */
-GcrCollection *
-gcr_simple_collection_new (void)
-{
- return g_object_new (GCR_TYPE_SIMPLE_COLLECTION, NULL);
-}
-
-/**
- * gcr_simple_collection_add:
- * @self: The collection
- * @object: The object to add
- *
- * Add an object to this collection
- */
-void
-gcr_simple_collection_add (GcrSimpleCollection *self, GObject *object)
-{
- g_return_if_fail (GCR_IS_SIMPLE_COLLECTION (self));
- g_return_if_fail (G_IS_OBJECT (object));
- g_return_if_fail (!g_hash_table_lookup (self->pv->items, object));
- g_hash_table_insert (self->pv->items, g_object_ref (object), UNUSED_VALUE);
- gcr_collection_emit_added (GCR_COLLECTION (self), object);
-}
-
-/**
- * gcr_simple_collection_remove:
- * @self: The collection
- * @object: The object to remove from the collection
- *
- * Remove an object from the collection.
- */
-void
-gcr_simple_collection_remove (GcrSimpleCollection *self, GObject *object)
-{
- g_return_if_fail (GCR_IS_SIMPLE_COLLECTION (self));
- g_return_if_fail (G_IS_OBJECT (object));
- g_return_if_fail (g_hash_table_lookup (self->pv->items, object));
- g_object_ref (object);
- g_hash_table_remove (self->pv->items, object);
- gcr_collection_emit_removed (GCR_COLLECTION (self), object);
- g_object_unref (object);
-}
-
-/**
- * gcr_simple_collection_contains:
- * @self: The collection
- * @object: The object to check
- *
- * Check if the collection contains a certain object.
- *
- * Deprecated: use gcr_collection_contains() instead
- *
- * Returns: %TRUE if the collection contains the object.
- */
-gboolean
-gcr_simple_collection_contains (GcrSimpleCollection *self, GObject *object)
-{
- g_return_val_if_fail (GCR_IS_SIMPLE_COLLECTION (self), FALSE);
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- return gcr_collection_contains (GCR_COLLECTION (self), object);
-}
diff --git a/gcr/gcr-simple-collection.h b/gcr/gcr-simple-collection.h
deleted file mode 100644
index e78c48c9..00000000
--- a/gcr/gcr-simple-collection.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_SIMPLE_COLLECTION_H__
-#define __GCR_SIMPLE_COLLECTION_H__
-
-#include "gcr-base.h"
-#include "gcr-collection.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_SIMPLE_COLLECTION (gcr_simple_collection_get_type ())
-#define GCR_SIMPLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrSimpleCollection))
-#define GCR_SIMPLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION, GcrSimpleCollectionClass))
-#define GCR_IS_SIMPLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
-#define GCR_IS_SIMPLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION))
-#define GCR_SIMPLE_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION, GcrSimpleCollectionClass))
-
-typedef struct _GcrSimpleCollection GcrSimpleCollection;
-typedef struct _GcrSimpleCollectionClass GcrSimpleCollectionClass;
-typedef struct _GcrSimpleCollectionPrivate GcrSimpleCollectionPrivate;
-
-struct _GcrSimpleCollection {
- GObject parent;
-
- /*< private >*/
- GcrSimpleCollectionPrivate *pv;
-};
-
-struct _GcrSimpleCollectionClass {
- GObjectClass parent_class;
-};
-
-GType gcr_simple_collection_get_type (void);
-
-GcrCollection* gcr_simple_collection_new (void);
-
-void gcr_simple_collection_add (GcrSimpleCollection *self,
- GObject *object);
-
-void gcr_simple_collection_remove (GcrSimpleCollection *self,
- GObject *object);
-
-G_END_DECLS
-
-#endif /* __GCR_SIMPLE_COLLECTION_H__ */
diff --git a/gcr/gcr-single-collection.c b/gcr/gcr-single-collection.c
deleted file mode 100644
index 942d47de..00000000
--- a/gcr/gcr-single-collection.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection.h"
-#include "gcr-single-collection.h"
-
-#include <string.h>
-
-/**
- * GcrSingleCollection:
- *
- * A single implementation of #GcrCollection.
- */
-
-struct _GcrSingleCollection {
- GObject parent;
- GObject *object;
-};
-
-/**
- * GcrSingleCollectionClass:
- * @parent_class: The parent class
- *
- * The class for #GcrSingleCollection.
- */
-
-struct _GcrSingleCollectionClass {
- GObjectClass parent_class;
-};
-
-static void _gcr_single_collection_iface (GcrCollectionIface *iface);
-G_DEFINE_TYPE_WITH_CODE (GcrSingleCollection, _gcr_single_collection, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, _gcr_single_collection_iface));
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-_gcr_single_collection_init (GcrSingleCollection *self)
-{
-
-}
-
-static void
-_gcr_single_collection_dispose (GObject *obj)
-{
- GcrSingleCollection *self = GCR_SINGLE_COLLECTION (obj);
-
- _gcr_single_collection_set_object (self, NULL);
-
- G_OBJECT_CLASS (_gcr_single_collection_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_single_collection_class_init (GcrSingleCollectionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose = _gcr_single_collection_dispose;
-}
-
-static guint
-_gcr_single_collection_real_get_length (GcrCollection *coll)
-{
- GcrSingleCollection *self = GCR_SINGLE_COLLECTION (coll);
- return self->object == NULL ? 0 : 1;
-}
-
-static GList*
-_gcr_single_collection_real_get_objects (GcrCollection *coll)
-{
- GcrSingleCollection *self = GCR_SINGLE_COLLECTION (coll);
- return self->object == NULL ? NULL : g_list_append (NULL, self->object);
-}
-
-static gboolean
-_gcr_single_collection_real_contains (GcrCollection *collection,
- GObject *object)
-{
- GcrSingleCollection *self = GCR_SINGLE_COLLECTION (collection);
- return self->object == object;
-}
-
-static void
-_gcr_single_collection_iface (GcrCollectionIface *iface)
-{
- iface->get_length = _gcr_single_collection_real_get_length;
- iface->get_objects = _gcr_single_collection_real_get_objects;
- iface->contains = _gcr_single_collection_real_contains;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-GcrCollection *
-_gcr_single_collection_new (GObject *object)
-{
- GcrSingleCollection *self;
-
- self = g_object_new (GCR_TYPE_SINGLE_COLLECTION, NULL);
- _gcr_single_collection_set_object (self, object);
-
- return GCR_COLLECTION (self);
-}
-
-GObject *
-_gcr_single_collection_get_object (GcrSingleCollection *self)
-{
- g_return_val_if_fail (GCR_IS_SINGLE_COLLECTION (self), NULL);
- return self->object;
-}
-
-void
-_gcr_single_collection_set_object (GcrSingleCollection *self,
- GObject *object)
-{
- GObject *obj;
-
- g_return_if_fail (GCR_IS_SINGLE_COLLECTION (self));
- g_return_if_fail (object == NULL || G_IS_OBJECT (object));
-
- if (object == self->object)
- return;
-
- if (self->object) {
- obj = self->object;
- self->object = NULL;
- gcr_collection_emit_removed (GCR_COLLECTION (self), obj);
- g_object_unref (obj);
- }
-
- if (object) {
- self->object = g_object_ref (object);
- gcr_collection_emit_added (GCR_COLLECTION (self), self->object);
- }
-}
diff --git a/gcr/gcr-single-collection.h b/gcr/gcr-single-collection.h
deleted file mode 100644
index 9bd598ff..00000000
--- a/gcr/gcr-single-collection.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_SINGLE_COLLECTION_H__
-#define __GCR_SINGLE_COLLECTION_H__
-
-#include "gcr-base.h"
-#include "gcr-collection.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_SINGLE_COLLECTION (_gcr_single_collection_get_type ())
-#define GCR_SINGLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrSingleCollection))
-#define GCR_SINGLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION, GcrSingleCollectionClass))
-#define GCR_IS_SINGLE_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
-#define GCR_IS_SINGLE_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION))
-#define GCR_SINGLE_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION, GcrSingleCollectionClass))
-
-typedef struct _GcrSingleCollection GcrSingleCollection;
-typedef struct _GcrSingleCollectionClass GcrSingleCollectionClass;
-
-GType _gcr_single_collection_get_type (void);
-
-GcrCollection * _gcr_single_collection_new (GObject *object);
-
-GObject * _gcr_single_collection_get_object (GcrSingleCollection *self);
-
-void _gcr_single_collection_set_object (GcrSingleCollection *self,
- GObject *object);
-
-G_END_DECLS
-
-#endif /* __GCR_SINGLE_COLLECTION_H__ */
diff --git a/gcr/gcr-tree-selector.c b/gcr/gcr-tree-selector.c
deleted file mode 100644
index fb5261fe..00000000
--- a/gcr/gcr-tree-selector.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-collection-model.h"
-#include "gcr-internal.h"
-#include "gcr-tree-selector.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <string.h>
-
-/**
- * SECTION:gcr-tree-selector
- * @title: GcrTreeSelector
- * @short_description: A selector widget to select certificates or keys.
- *
- * The #GcrTreeSelector can be used to select certificates or keys. It allows
- * the user to select multiple objects from a tree.
- */
-
-/**
- * GcrTreeSelector:
- *
- * A tree selector widget.
- */
-
-/**
- * GcrTreeSelectorClass:
- *
- * The class for #GcrTreeSelector.
- */
-
-enum {
- PROP_0,
- PROP_COLLECTION,
- PROP_COLUMNS
-};
-
-struct _GcrTreeSelectorPrivate {
- GcrCollection *collection;
- const GcrColumn *columns;
- GcrCollectionModel *model;
-};
-
-G_DEFINE_TYPE (GcrTreeSelector, gcr_tree_selector, GTK_TYPE_TREE_VIEW);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static void
-on_check_column_toggled (GtkCellRendererToggle *cell, gchar *path, GcrCollectionModel *model)
-{
- GtkTreeIter iter;
-
- g_assert (path != NULL);
-
- if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
- gcr_collection_model_toggle_selected (model, &iter);
-}
-
-static void
-add_string_column (GcrTreeSelector *self, const GcrColumn *column, gint column_id)
-{
- GtkCellRenderer *cell;
- GtkTreeViewColumn *col;
- const gchar *label;
-
- g_assert (column->column_type == G_TYPE_STRING);
- g_assert (!(column->flags & GCR_COLUMN_HIDDEN));
-
- cell = gtk_cell_renderer_text_new ();
- g_object_set (G_OBJECT (cell), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- label = column->label ? g_dpgettext2 (NULL, "column", column->label) : "";
- col = gtk_tree_view_column_new_with_attributes (label, cell, "text", column_id, NULL);
- gtk_tree_view_column_set_resizable (col, TRUE);
- if (column->flags & GCR_COLUMN_SORTABLE)
- gtk_tree_view_column_set_sort_column_id (col, column_id);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
-}
-
-static void
-add_icon_column (GcrTreeSelector *self, const GcrColumn *column, gint column_id)
-{
- GtkCellRenderer *cell;
- GtkTreeViewColumn *col;
- const gchar *label;
-
- g_assert (column->column_type == G_TYPE_ICON);
- g_assert (!(column->flags & GCR_COLUMN_HIDDEN));
-
- cell = gtk_cell_renderer_pixbuf_new ();
- g_object_set (cell, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
- label = column->label ? g_dpgettext2 (NULL, "column", column->label) : "";
- col = gtk_tree_view_column_new_with_attributes (label, cell, "gicon", column_id, NULL);
- gtk_tree_view_column_set_resizable (col, TRUE);
- if (column->flags & GCR_COLUMN_SORTABLE)
- gtk_tree_view_column_set_sort_column_id (col, column_id);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
-}
-
-static void
-add_check_column (GcrTreeSelector *self, guint column_id)
-{
- GtkCellRenderer *cell;
- GtkTreeViewColumn *col;
-
- cell = gtk_cell_renderer_toggle_new ();
- g_signal_connect (cell, "toggled", G_CALLBACK (on_check_column_toggled), self->pv->model);
-
- col = gtk_tree_view_column_new_with_attributes ("", cell, "active", column_id, NULL);
- gtk_tree_view_column_set_resizable (col, FALSE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self), col);
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-static GObject*
-gcr_tree_selector_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GcrTreeSelector *self = GCR_TREE_SELECTOR (G_OBJECT_CLASS (gcr_tree_selector_parent_class)->constructor(type, n_props, props));
- const GcrColumn *column;
- guint i;
-
- g_return_val_if_fail (self, NULL);
- g_return_val_if_fail (self->pv->columns, NULL);
-
- self->pv->model = gcr_collection_model_new_full (self->pv->collection,
- self->pv->columns);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (self), GTK_TREE_MODEL (self->pv->model));
-
- /* First add the check mark column */
- add_check_column (self, gcr_collection_model_column_for_selected (self->pv->model));
-
- for (column = self->pv->columns, i = 0; column->property_name; ++column, ++i) {
- if (column->flags & GCR_COLUMN_HIDDEN)
- continue;
-
- if (column->column_type == G_TYPE_STRING)
- add_string_column (self, column, i);
- else if (column->column_type == G_TYPE_ICON)
- add_icon_column (self, column, i);
- else
- g_warning ("skipping unsupported column '%s' of type: %s",
- column->property_name, g_type_name (column->column_type));
- }
-
- return G_OBJECT (self);
-}
-
-static void
-gcr_tree_selector_init (GcrTreeSelector *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_TREE_SELECTOR, GcrTreeSelectorPrivate);
-}
-
-static void
-gcr_tree_selector_dispose (GObject *obj)
-{
- GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
-
- if (self->pv->model)
- g_object_unref (self->pv->model);
- self->pv->model = NULL;
-
- if (self->pv->collection)
- g_object_unref (self->pv->collection);
- self->pv->collection = NULL;
-
- G_OBJECT_CLASS (gcr_tree_selector_parent_class)->dispose (obj);
-}
-
-static void
-gcr_tree_selector_finalize (GObject *obj)
-{
- GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
-
- g_assert (!self->pv->collection);
- g_assert (!self->pv->model);
-
- G_OBJECT_CLASS (gcr_tree_selector_parent_class)->finalize (obj);
-}
-
-static void
-gcr_tree_selector_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
- switch (prop_id) {
- case PROP_COLLECTION:
- g_return_if_fail (!self->pv->collection);
- self->pv->collection = g_value_dup_object (value);
- g_return_if_fail (self->pv->collection);
- break;
- case PROP_COLUMNS:
- g_return_if_fail (!self->pv->columns);
- self->pv->columns = g_value_get_pointer (value);
- g_return_if_fail (self->pv->columns);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_tree_selector_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrTreeSelector *self = GCR_TREE_SELECTOR (obj);
-
- switch (prop_id) {
- case PROP_COLLECTION:
- g_value_set_object (value, gcr_tree_selector_get_collection (self));
- break;
- case PROP_COLUMNS:
- g_value_set_pointer (value, (gpointer)gcr_tree_selector_get_columns (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_tree_selector_class_init (GcrTreeSelectorClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructor = gcr_tree_selector_constructor;
- gobject_class->dispose = gcr_tree_selector_dispose;
- gobject_class->finalize = gcr_tree_selector_finalize;
- gobject_class->set_property = gcr_tree_selector_set_property;
- gobject_class->get_property = gcr_tree_selector_get_property;
-
- g_type_class_add_private (gobject_class, sizeof (GcrTreeSelectorPrivate));
-
- /**
- * GcrTreeSelector:collection:
- *
- * The collection which contains the objects to display in the selector.
- */
- g_object_class_install_property (gobject_class, PROP_COLLECTION,
- g_param_spec_object ("collection", "Collection", "Collection to select from",
- GCR_TYPE_COLLECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /**
- * GcrTreeSelector:columns:
- *
- * The columns to use to display the objects.
- */
- g_object_class_install_property (gobject_class, PROP_COLUMNS,
- g_param_spec_pointer ("columns", "Columns", "Columns to display in selector",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_tree_selector_new: (skip)
- * @collection: The collection that contains the objects to display
- * @columns: The columns to use to display the objects
- *
- * Create a new #GcrTreeSelector.
- *
- * Returns: (transfer full): a newly allocated selector, which should be
- * released with g_object_unref()
- */
-GcrTreeSelector *
-gcr_tree_selector_new (GcrCollection *collection, const GcrColumn *columns)
-{
- return g_object_new (GCR_TYPE_TREE_SELECTOR,
- "collection", collection,
- "columns", columns,
- NULL);
-}
-
-/**
- * gcr_tree_selector_get_collection:
- * @self: The selector
- *
- * Get the collection that this selector is displaying objects from.
- *
- * Returns: (transfer none): the collection, owned by the selector
- */
-GcrCollection *
-gcr_tree_selector_get_collection (GcrTreeSelector *self)
-{
- g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
- return self->pv->collection;
-}
-
-/**
- * gcr_tree_selector_get_columns: (skip)
- * @self: The selector
- *
- * Get the columns displayed in a selector in multiple mode.
- *
- * Returns: (transfer none): The columns, owned by the selector.
- */
-const GcrColumn *
-gcr_tree_selector_get_columns (GcrTreeSelector *self)
-{
- g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
- return self->pv->columns;
-}
-
-/**
- * gcr_tree_selector_get_selected:
- * @self: The selector
- *
- * Get a list of selected objects.
- *
- * Returns: (transfer container) (element-type GLib.Object): the list of selected
- * objects, to be released with g_list_free()
- */
-GList*
-gcr_tree_selector_get_selected (GcrTreeSelector *self)
-{
- g_return_val_if_fail (GCR_IS_TREE_SELECTOR (self), NULL);
- return gcr_collection_model_get_selected_objects (self->pv->model);
-}
-
-/**
- * gcr_tree_selector_set_selected:
- * @self: The selector
- * @selected: (element-type GLib.Object): The list of objects to select.
- *
- * Select certain objects in the selector.
- */
-void
-gcr_tree_selector_set_selected (GcrTreeSelector *self, GList *selected)
-{
- g_return_if_fail (GCR_IS_TREE_SELECTOR (self));
- gcr_collection_model_set_selected_objects (self->pv->model, selected);
-}
diff --git a/gcr/gcr-tree-selector.h b/gcr/gcr-tree-selector.h
deleted file mode 100644
index 7792153c..00000000
--- a/gcr/gcr-tree-selector.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_TREE_SELECTOR_H__
-#define __GCR_TREE_SELECTOR_H__
-
-#include "gcr-types.h"
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_TREE_SELECTOR (gcr_tree_selector_get_type ())
-#define GCR_TREE_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_TREE_SELECTOR, GcrTreeSelector))
-#define GCR_TREE_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_TREE_SELECTOR, GcrTreeSelectorClass))
-#define GCR_IS_TREE_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_TREE_SELECTOR))
-#define GCR_IS_TREE_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_TREE_SELECTOR))
-#define GCR_TREE_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_TREE_SELECTOR, GcrTreeSelectorClass))
-
-typedef struct _GcrTreeSelector GcrTreeSelector;
-typedef struct _GcrTreeSelectorClass GcrTreeSelectorClass;
-typedef struct _GcrTreeSelectorPrivate GcrTreeSelectorPrivate;
-
-struct _GcrTreeSelector {
- GtkTreeView parent;
-
- /*< private >*/
- GcrTreeSelectorPrivate *pv;
-};
-
-struct _GcrTreeSelectorClass {
- /*< private >*/
- GtkTreeViewClass parent_class;
-};
-
-GType gcr_tree_selector_get_type (void);
-
-GcrTreeSelector* gcr_tree_selector_new (GcrCollection *collection,
- const GcrColumn *columns);
-
-GcrCollection* gcr_tree_selector_get_collection (GcrTreeSelector *self);
-
-const GcrColumn* gcr_tree_selector_get_columns (GcrTreeSelector *self);
-
-GList* gcr_tree_selector_get_selected (GcrTreeSelector *self);
-
-void gcr_tree_selector_set_selected (GcrTreeSelector *self,
- GList *selected);
-
-G_END_DECLS
-
-#endif /* __GCR_TREE_SELECTOR_H__ */
diff --git a/gcr/gcr-trust.c b/gcr/gcr-trust.c
deleted file mode 100644
index 48006e64..00000000
--- a/gcr/gcr-trust.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-base.h"
-#define DEBUG_FLAG GCR_DEBUG_TRUST
-#include "gcr-debug.h"
-#include "gcr-types.h"
-#include "gcr-internal.h"
-#include "gcr-library.h"
-#include "gcr-trust.h"
-
-#include <gck/gck.h>
-
-#include "pkcs11/pkcs11n.h"
-#include "pkcs11/pkcs11i.h"
-#include "pkcs11/pkcs11x.h"
-
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-trust
- * @title: Trust Storage and Lookups
- * @short_description: Store and lookup bits of information used for
- * verifying certificates.
- *
- * These functions provide access to stored information about which
- * certificates the system and user trusts as certificate authority trust
- * anchors, or overrides to the normal verification of certificates.
- *
- * Trust anchors are used to verify the certificate authority in a certificate
- * chain. Trust anchors are always valid for a given purpose. The most common
- * purpose is the #GCR_PURPOSE_SERVER_AUTH and is used for a client application
- * to verify that the certificate at the server side of a TLS connection is
- * authorized to act as such. To check if a certificate is a trust anchor use
- * gcr_trust_is_certificate_anchored().
- *
- * Pinned certificates are used when a user overrides the default trust
- * decision for a given certificate. They're often used with self-signed
- * certificates. Pinned certificates are always only valid for a single peer
- * such as the remote host with which TLS is being performed. To lookup
- * pinned certificates use gcr_trust_is_certificate_pinned().
- *
- * After the user has requested to override the trust decision
- * about a given certificate then a pinned certificates can be added by using
- * the gcr_trust_add_pinned_certificate() function.
- *
- * These functions do not constitute a viable method for verifying certificates
- * used in TLS or other locations. Instead they support such verification
- * by providing some of the needed data for a trust decision.
- *
- * The storage is provided by pluggable PKCS\#11 modules.
- */
-
-/**
- * GCR_PURPOSE_SERVER_AUTH:
- *
- * The purpose used to verify the server certificate in a TLS connection. This
- * is the most common purpose in use.
- */
-
-/**
- * GCR_PURPOSE_CLIENT_AUTH:
- *
- * The purpose used to verify the client certificate in a TLS connection.
- */
-
-/**
- * GCR_PURPOSE_CODE_SIGNING:
- *
- * The purpose used to verify certificate used for the signature on signed code.
- */
-
-/**
- * GCR_PURPOSE_EMAIL:
- *
- * The purpose used to verify certificates that are used in email communication
- * such as S/MIME.
- */
-
-/* ----------------------------------------------------------------------------------
- * HELPERS
- */
-
-typedef struct {
- GckAttributes *attrs;
- gboolean found;
-} trust_closure;
-
-static void
-trust_closure_free (gpointer data)
-{
- trust_closure *closure = data;
- gck_attributes_unref (closure->attrs);
- g_free (closure);
-}
-
-static GckAttributes*
-prepare_trust_attrs (GcrCertificate *certificate, CK_X_ASSERTION_TYPE type)
-{
- GckAttributes *attrs;
- gconstpointer data;
- gsize n_data;
-
- attrs = gck_attributes_new ();
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION);
- gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, type);
-
- data = gcr_certificate_get_der_data (certificate, &n_data);
- g_return_val_if_fail (data, NULL);
- gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, data, n_data);
-
- return attrs;
-}
-
-/* ----------------------------------------------------------------------------------
- * GET PINNED CERTIFICATE
- */
-
-static GckAttributes *
-prepare_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
-{
- GckAttributes *attrs;
-
- attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
- g_return_val_if_fail (attrs, NULL);
-
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
- gck_attributes_add_string (attrs, CKA_X_PEER, peer);
-
- return attrs;
-}
-
-static gboolean
-perform_is_certificate_pinned (GckAttributes *search,
- GCancellable *cancellable,
- GError **error)
-{
- GckEnumerator *en;
- GList *slots;
- GckObject *object;
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return FALSE;
-
- slots = gcr_pkcs11_get_trust_lookup_slots ();
- _gcr_debug ("searching for pinned certificate in %d slots",
- g_list_length (slots));
- en = gck_slots_enumerate_objects (slots, search, 0);
- gck_list_unref_free (slots);
-
- object = gck_enumerator_next (en, cancellable, error);
- g_object_unref (en);
-
- if (object)
- g_object_unref (object);
-
- _gcr_debug ("%s certificate anchor", object ? "found" : "did not find");
- return (object != NULL);
-}
-
-/**
- * gcr_trust_is_certificate_pinned:
- * @certificate: a #GcrCertificate to check
- * @purpose: the purpose string
- * @peer: the peer for this pinned
- * @cancellable: a #GCancellable
- * @error: a #GError, or NULL
- *
- * Check if @certificate is pinned for @purpose to communicate with @peer.
- * A pinned certificate overrides all other certificate verification.
- *
- * This call may block, see gcr_trust_is_certificate_pinned_async() for the
- * non-blocking version.
- *
- * In the case of an error, %FALSE is also returned. Check @error to detect
- * if an error occurred.
- *
- * Returns: %TRUE if the certificate is pinned for the host and purpose
- */
-gboolean
-gcr_trust_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose,
- const gchar *peer, GCancellable *cancellable, GError **error)
-{
- GckAttributes *search;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
- g_return_val_if_fail (purpose, FALSE);
- g_return_val_if_fail (peer, FALSE);
-
- search = prepare_is_certificate_pinned (certificate, purpose, peer);
- g_return_val_if_fail (search, FALSE);
-
- ret = perform_is_certificate_pinned (search, cancellable, error);
- gck_attributes_unref (search);
-
- return ret;
-}
-
-static void
-thread_is_certificate_pinned (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
-{
- GError *error = NULL;
- trust_closure *closure;
-
- closure = g_simple_async_result_get_op_res_gpointer (result);
- closure->found = perform_is_certificate_pinned (closure->attrs, cancel, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- g_clear_error (&error);
- }
-}
-
-/**
- * gcr_trust_is_certificate_pinned_async:
- * @certificate: a #GcrCertificate to check
- * @purpose: the purpose string
- * @peer: the peer for this pinned
- * @cancellable: a #GCancellable
- * @callback: a #GAsyncReadyCallback to call when the operation completes
- * @user_data: the data to pass to callback function
- *
- * Check if @certificate is pinned for @purpose to communicate with @peer. A
- * pinned certificate overrides all other certificate verification.
- *
- * When the operation is finished, callback will be called. You can then call
- * gcr_trust_is_certificate_pinned_finish() to get the result of the
- * operation.
- */
-void
-gcr_trust_is_certificate_pinned_async (GcrCertificate *certificate, const gchar *purpose,
- const gchar *peer, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *async;
- trust_closure *closure;
-
- g_return_if_fail (GCR_CERTIFICATE (certificate));
- g_return_if_fail (purpose);
- g_return_if_fail (peer);
-
- async = g_simple_async_result_new (NULL, callback, user_data,
- gcr_trust_is_certificate_pinned_async);
- closure = g_new0 (trust_closure, 1);
- closure->attrs = prepare_is_certificate_pinned (certificate, purpose, peer);
- g_return_if_fail (closure->attrs);
- g_simple_async_result_set_op_res_gpointer (async, closure, trust_closure_free);
-
- g_simple_async_result_run_in_thread (async, thread_is_certificate_pinned,
- G_PRIORITY_DEFAULT, cancellable);
-
- g_object_unref (async);
-}
-
-/**
- * gcr_trust_is_certificate_pinned_finish:
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_trust_is_certificate_pinned_async().
- *
- * In the case of an error, %FALSE is also returned. Check @error to detect
- * if an error occurred.
- *
- * Returns: %TRUE if the certificate is pinned.
- */
-gboolean
-gcr_trust_is_certificate_pinned_finish (GAsyncResult *result, GError **error)
-{
- trust_closure *closure;
-
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- gcr_trust_is_certificate_pinned_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- return closure->found;
-}
-
-/* ----------------------------------------------------------------------------------
- * ADD PINNED CERTIFICATE
- */
-
-static GckAttributes *
-prepare_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer)
-{
- GckAttributes *attrs;
-
- attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
- g_return_val_if_fail (attrs, NULL);
-
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
- gck_attributes_add_string (attrs, CKA_X_PEER, peer);
- gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
-
- return attrs;
-}
-
-static gboolean
-perform_add_pinned_certificate (GckAttributes *search,
- GCancellable *cancellable,
- GError **error)
-{
- GckAttributes *attrs;
- gboolean ret = FALSE;
- GError *lerr = NULL;
- GckObject *object;
- GckSession *session;
- GckSlot *slot;
- GckEnumerator *en;
- GList *slots;
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return FALSE;
-
- slots = gcr_pkcs11_get_trust_lookup_slots ();
- en = gck_slots_enumerate_objects (slots, search, CKF_RW_SESSION);
- gck_list_unref_free (slots);
-
- /* We need an error below */
- if (error && !*error)
- *error = lerr;
-
- object = gck_enumerator_next (en, cancellable, error);
- g_object_unref (en);
-
- if (*error)
- return FALSE;
-
- /* It already exists */
- if (object) {
- g_object_unref (object);
- return TRUE;
- }
-
- attrs = gck_attributes_new ();
- gck_attributes_add_all (attrs, search);
-
- /* TODO: Add relevant label */
-
- /* Find an appropriate token */
- slot = gcr_pkcs11_get_trust_store_slot ();
- if (slot == NULL) {
- g_set_error (error, GCK_ERROR, CKR_FUNCTION_FAILED,
- /* Translators: A pinned certificate is an exception which
- trusts a given certificate explicitly for a purpose and
- communication with a certain peer. */
- _("Couldn't find a place to store the pinned certificate"));
- ret = FALSE;
- } else {
- session = gck_slot_open_session (slot, CKF_RW_SESSION, NULL, error);
- if (session != NULL) {
- object = gck_session_create_object (session, attrs, cancellable, error);
- if (object != NULL) {
- g_object_unref (object);
- ret = TRUE;
- }
-
- g_object_unref (session);
- }
-
- g_object_unref (slot);
- }
-
- gck_attributes_unref (attrs);
-
- /* Our own local error pointer */
- g_clear_error (&lerr);
-
- return ret;
-}
-
-/**
- * gcr_trust_add_pinned_certificate:
- * @certificate: a #GcrCertificate
- * @purpose: the purpose string
- * @peer: the peer for this pinned certificate
- * @cancellable: a #GCancellable
- * @error: a #GError, or NULL
- *
- * Add a pinned @certificate for connections to @peer for @purpose. A pinned
- * certificate overrides all other certificate verification and should be
- * used with care.
- *
- * If the same pinned certificate already exists, then this operation
- * does not add another, and succeeds without error.
- *
- * This call may block, see gcr_trust_add_pinned_certificate_async() for the
- * non-blocking version.
- *
- * Returns: %TRUE if the pinned certificate is recorded successfully
- */
-gboolean
-gcr_trust_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
- GCancellable *cancellable, GError **error)
-{
- GckAttributes *search;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
- g_return_val_if_fail (purpose, FALSE);
- g_return_val_if_fail (peer, FALSE);
-
- search = prepare_add_pinned_certificate (certificate, purpose, peer);
- g_return_val_if_fail (search, FALSE);
-
- ret = perform_add_pinned_certificate (search, cancellable, error);
- gck_attributes_unref (search);
-
- return ret;
-}
-
-static void
-thread_add_pinned_certificate (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
-{
- GError *error = NULL;
- trust_closure *closure;
-
- closure = g_simple_async_result_get_op_res_gpointer (result);
- perform_add_pinned_certificate (closure->attrs, cancel, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- g_clear_error (&error);
- }
-}
-
-/**
- * gcr_trust_add_pinned_certificate_async:
- * @certificate: a #GcrCertificate
- * @purpose: the purpose string
- * @peer: the peer for this pinned certificate
- * @cancellable: a #GCancellable
- * @callback: a #GAsyncReadyCallback to call when the operation completes
- * @user_data: the data to pass to callback function
- *
- * Add a pinned certificate for communication with @peer for @purpose. A pinned
- * certificate overrides all other certificate verification and should be used
- * with care.
- *
- * If the same pinned certificate already exists, then this operation
- * does not add another, and succeeds without error.
- *
- * When the operation is finished, callback will be called. You can then call
- * gcr_trust_add_pinned_certificate_finish() to get the result of the
- * operation.
- */
-void
-gcr_trust_add_pinned_certificate_async (GcrCertificate *certificate, const gchar *purpose,
- const gchar *peer, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *async;
- trust_closure *closure;
-
- g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
- g_return_if_fail (purpose);
- g_return_if_fail (peer);
-
- async = g_simple_async_result_new (NULL, callback, user_data,
- gcr_trust_add_pinned_certificate_async);
- closure = g_new0 (trust_closure, 1);
- closure->attrs = prepare_add_pinned_certificate (certificate, purpose, peer);
- g_return_if_fail (closure->attrs);
- g_simple_async_result_set_op_res_gpointer (async, closure, trust_closure_free);
-
- g_simple_async_result_run_in_thread (async, thread_add_pinned_certificate,
- G_PRIORITY_DEFAULT, cancellable);
-
- g_object_unref (async);
-}
-
-/**
- * gcr_trust_add_pinned_certificate_finish:
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_trust_add_pinned_certificate_async().
- *
- * Returns: %TRUE if the pinned certificate is recorded successfully
- */
-gboolean
-gcr_trust_add_pinned_certificate_finish (GAsyncResult *result, GError **error)
-{
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- gcr_trust_add_pinned_certificate_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-/* -----------------------------------------------------------------------
- * REMOVE PINNED CERTIFICATE
- */
-
-static GckAttributes *
-prepare_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose,
- const gchar *peer)
-{
- GckAttributes *attrs;
-
- attrs = prepare_trust_attrs (certificate, CKT_X_PINNED_CERTIFICATE);
- g_return_val_if_fail (attrs, NULL);
-
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
- gck_attributes_add_string (attrs, CKA_X_PEER, peer);
-
- return attrs;
-}
-
-static gboolean
-perform_remove_pinned_certificate (GckAttributes *attrs,
- GCancellable *cancellable,
- GError **error)
-{
- GList *objects, *l;
- GError *lerr = NULL;
- GckEnumerator *en;
- GList *slots;
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return FALSE;
-
- slots = gcr_pkcs11_get_trust_lookup_slots ();
- en = gck_slots_enumerate_objects (slots, attrs, CKF_RW_SESSION);
- gck_list_unref_free (slots);
-
- /* We need an error below */
- if (error && !*error)
- *error = lerr;
-
- objects = gck_enumerator_next_n (en, -1, cancellable, error);
- g_object_unref (en);
-
- if (*error)
- return FALSE;
-
- for (l = objects; l; l = g_list_next (l)) {
- if (!gck_object_destroy (l->data, cancellable, error)) {
-
- /* In case there's a race condition */
- if (g_error_matches (*error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) {
- g_clear_error (error);
- continue;
- }
-
- gck_list_unref_free (objects);
- return FALSE;
- }
- }
-
- gck_list_unref_free (objects);
- return TRUE;
-}
-
-/**
- * gcr_trust_remove_pinned_certificate:
- * @certificate: a #GcrCertificate
- * @purpose: the purpose string
- * @peer: the peer for this pinned certificate
- * @cancellable: a #GCancellable
- * @error: a #GError, or NULL
- *
- * Remove a pinned certificate for communication with @peer for @purpose.
- *
- * If the same pinned certificate does not exist, or was already removed,
- * then this operation succeeds without error.
- *
- * This call may block, see gcr_trust_remove_pinned_certificate_async() for the
- * non-blocking version.
- *
- * Returns: %TRUE if the pinned certificate no longer exists
- */
-gboolean
-gcr_trust_remove_pinned_certificate (GcrCertificate *certificate, const gchar *purpose, const gchar *peer,
- GCancellable *cancellable, GError **error)
-{
- GckAttributes *search;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
- g_return_val_if_fail (purpose, FALSE);
- g_return_val_if_fail (peer, FALSE);
-
- search = prepare_remove_pinned_certificate (certificate, purpose, peer);
- g_return_val_if_fail (search, FALSE);
-
- ret = perform_remove_pinned_certificate (search, cancellable, error);
- gck_attributes_unref (search);
-
- return ret;
-}
-
-static void
-thread_remove_pinned_certificate (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
-{
- GError *error = NULL;
- trust_closure *closure;
-
- closure = g_simple_async_result_get_op_res_gpointer (result);
- perform_remove_pinned_certificate (closure->attrs, cancel, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- g_clear_error (&error);
- }
-}
-
-/**
- * gcr_trust_remove_pinned_certificate_async:
- * @certificate: a #GcrCertificate
- * @purpose: the purpose string
- * @peer: the peer for this pinned certificate
- * @cancellable: a #GCancellable
- * @callback: a #GAsyncReadyCallback to call when the operation completes
- * @user_data: the data to pass to callback function
- *
- * Remove a pinned certificate for communication with @peer for @purpose.
- *
- * If the same pinned certificate does not exist, or was already removed,
- * then this operation succeeds without error.
- *
- * When the operation is finished, callback will be called. You can then call
- * gcr_trust_remove_pinned_certificate_finish() to get the result of the
- * operation.
- */
-void
-gcr_trust_remove_pinned_certificate_async (GcrCertificate *certificate, const gchar *purpose,
- const gchar *peer, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GSimpleAsyncResult *async;
- trust_closure *closure;
-
- g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
- g_return_if_fail (purpose);
- g_return_if_fail (peer);
-
- async = g_simple_async_result_new (NULL, callback, user_data,
- gcr_trust_remove_pinned_certificate_async);
- closure = g_new0 (trust_closure, 1);
- closure->attrs = prepare_remove_pinned_certificate (certificate, purpose, peer);
- g_return_if_fail (closure->attrs);
- g_simple_async_result_set_op_res_gpointer (async, closure, trust_closure_free);
-
- g_simple_async_result_run_in_thread (async, thread_remove_pinned_certificate,
- G_PRIORITY_DEFAULT, cancellable);
-
- g_object_unref (async);
-}
-
-/**
- * gcr_trust_remove_pinned_certificate_finish:
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_trust_remove_pinned_certificate_async().
- *
- * Returns: %TRUE if the pinned certificate no longer exists
- */
-gboolean
-gcr_trust_remove_pinned_certificate_finish (GAsyncResult *result, GError **error)
-{
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- gcr_trust_remove_pinned_certificate_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-/* ----------------------------------------------------------------------------------
- * CERTIFICATE ROOT
- */
-
-static GckAttributes *
-prepare_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose)
-{
- GckAttributes *attrs;
-
- attrs = prepare_trust_attrs (certificate, CKT_X_ANCHORED_CERTIFICATE);
- g_return_val_if_fail (attrs, NULL);
-
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
-
- return attrs;
-}
-
-static gboolean
-perform_is_certificate_anchored (GckAttributes *attrs,
- GCancellable *cancellable,
- GError **error)
-{
- GckEnumerator *en;
- GList *slots;
- GckObject *object;
-
- if (!gcr_pkcs11_initialize (cancellable, error))
- return FALSE;
-
- slots = gcr_pkcs11_get_trust_lookup_slots ();
- _gcr_debug ("searching for certificate anchor in %d slots",
- g_list_length (slots));
- en = gck_slots_enumerate_objects (slots, attrs, 0);
- gck_list_unref_free (slots);
-
- object = gck_enumerator_next (en, cancellable, error);
- g_object_unref (en);
-
- if (object != NULL)
- g_object_unref (object);
-
- _gcr_debug ("%s certificate anchor", object ? "found" : "did not find");
- return (object != NULL);
-}
-
-/**
- * gcr_trust_is_certificate_anchored:
- * @certificate: a #GcrCertificate to check
- * @purpose: the purpose string
- * @cancellable: a #GCancellable
- * @error: a #GError, or NULL
- *
- * Check if the @certificate is a trust anchor for the given @purpose. A trust
- * anchor is used to verify the signatures on other certificates when verifying
- * a certificate chain. Also known as a trusted certificate authority.
- *
- * This call may block, see gcr_trust_is_certificate_anchored_async() for the
- * non-blocking version.
- *
- * In the case of an error, %FALSE is also returned. Check @error to detect
- * if an error occurred.
- *
- * Returns: %TRUE if the certificate is a trust anchor
- */
-gboolean
-gcr_trust_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpose,
- GCancellable *cancellable, GError **error)
-{
- GckAttributes *search;
- gboolean ret;
-
- g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), FALSE);
- g_return_val_if_fail (purpose, FALSE);
-
- search = prepare_is_certificate_anchored (certificate, purpose);
- g_return_val_if_fail (search, FALSE);
-
- ret = perform_is_certificate_anchored (search, cancellable, error);
- gck_attributes_unref (search);
-
- return ret;
-}
-
-static void
-thread_is_certificate_anchored (GSimpleAsyncResult *result, GObject *object, GCancellable *cancel)
-{
- GError *error = NULL;
- trust_closure *closure;
-
- closure = g_simple_async_result_get_op_res_gpointer (result);
- closure->found = perform_is_certificate_anchored (closure->attrs, cancel, &error);
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- g_clear_error (&error);
- }
-}
-
-/**
- * gcr_trust_is_certificate_anchored_async:
- * @certificate: a #GcrCertificate to check
- * @purpose: the purpose string
- * @cancellable: a #GCancellable
- * @callback: a #GAsyncReadyCallback to call when the operation completes
- * @user_data: the data to pass to callback function
- *
- * Check if the @certificate is a trust anchor for the given @purpose. A trust
- * anchor is used to verify the signatures on other certificates when verifying
- * a certificate chain. Also known as a trusted certificate authority.
- *
- * When the operation is finished, callback will be called. You can then call
- * gcr_trust_is_certificate_anchored_finish() to get the result of the operation.
- */
-void
-gcr_trust_is_certificate_anchored_async (GcrCertificate *certificate, const gchar *purpose,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *async;
- trust_closure *closure;
-
- g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
- g_return_if_fail (purpose);
-
- async = g_simple_async_result_new (NULL, callback, user_data,
- gcr_trust_is_certificate_anchored_async);
- closure = g_new0 (trust_closure, 1);
- closure->attrs = prepare_is_certificate_anchored (certificate, purpose);
- g_return_if_fail (closure->attrs);
- g_simple_async_result_set_op_res_gpointer (async, closure, trust_closure_free);
-
- g_simple_async_result_run_in_thread (async, thread_is_certificate_anchored,
- G_PRIORITY_DEFAULT, cancellable);
-
- g_object_unref (async);
-}
-
-/**
- * gcr_trust_is_certificate_anchored_finish:
- * @result: the #GAsyncResult passed to the callback
- * @error: a #GError, or NULL
- *
- * Finishes an asynchronous operation started by
- * gcr_trust_is_certificate_anchored_async().
- *
- * In the case of an error, %FALSE is also returned. Check @error to detect
- * if an error occurred.
- *
- * Returns: %TRUE if the certificate is a trust anchor
- */
-gboolean
-gcr_trust_is_certificate_anchored_finish (GAsyncResult *result, GError **error)
-{
- trust_closure *closure;
-
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- gcr_trust_is_certificate_anchored_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- return closure->found;
-}
diff --git a/gcr/gcr-trust.h b/gcr/gcr-trust.h
deleted file mode 100644
index 79db47fd..00000000
--- a/gcr/gcr-trust.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_TRUST_H__
-#define __GCR_TRUST_H__
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_PURPOSE_SERVER_AUTH "1.3.6.1.5.5.7.3.1"
-#define GCR_PURPOSE_CLIENT_AUTH "1.3.6.1.5.5.7.3.2"
-#define GCR_PURPOSE_CODE_SIGNING "1.3.6.1.5.5.7.3.3"
-#define GCR_PURPOSE_EMAIL "1.3.6.1.5.5.7.3.4"
-
-gboolean gcr_trust_is_certificate_pinned (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_trust_is_certificate_pinned_async (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_trust_is_certificate_pinned_finish (GAsyncResult *result,
- GError **error);
-
-gboolean gcr_trust_add_pinned_certificate (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_trust_add_pinned_certificate_async (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_trust_add_pinned_certificate_finish (GAsyncResult *result,
- GError **error);
-
-gboolean gcr_trust_remove_pinned_certificate (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_trust_remove_pinned_certificate_async (GcrCertificate *certificate,
- const gchar *purpose,
- const gchar *peer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_trust_remove_pinned_certificate_finish (GAsyncResult *result,
- GError **error);
-
-gboolean gcr_trust_is_certificate_anchored (GcrCertificate *certificate,
- const gchar *purpose,
- GCancellable *cancellable,
- GError **error);
-
-void gcr_trust_is_certificate_anchored_async (GcrCertificate *certificate,
- const gchar *purpose,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean gcr_trust_is_certificate_anchored_finish (GAsyncResult *result,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GCR_TOKEN_MANAGER_H__ */
diff --git a/gcr/gcr-types.h b/gcr/gcr-types.h
deleted file mode 100644
index cffed10d..00000000
--- a/gcr/gcr-types.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef GCRTYPES_H_
-#define GCRTYPES_H_
-
-#include <glib.h>
-
-#ifndef GCK_API_SUBJECT_TO_CHANGE
-
-/**
- * GCK_API_SUBJECT_TO_CHANGE: (skip)
- *
- * skip for gir introspection
- */
-#define GCK_API_SUBJECT_TO_CHANGE 1
-
-/**
- * __GCR_DEFINED_GCK_SUBJECT_TO_CHANGE__: (skip)
- *
- * skip for gir introspection
- */
-#define __GCR_DEFINED_GCK_SUBJECT_TO_CHANGE__ 1
-
-#endif
-
-#include <gck/gck.h>
-
-#ifdef __GCR_DEFINED_GCK_SUBJECT_TO_CHANGE__
-#undef GCK_API_SUBJECT_TO_CHANGE
-#endif
-
-G_BEGIN_DECLS
-
-#define GCR_DATA_ERROR (gcr_data_error_get_domain ())
-
-GQuark gcr_data_error_get_domain (void) G_GNUC_CONST;
-
-typedef enum {
- GCR_ERROR_FAILURE = -1,
- GCR_ERROR_UNRECOGNIZED = 1,
- GCR_ERROR_CANCELLED = 2,
- GCR_ERROR_LOCKED = 3
-} GcrDataError;
-
-typedef enum {
- GCR_FORMAT_ALL = -1,
- GCR_FORMAT_INVALID = 0,
-
- GCR_FORMAT_DER_PRIVATE_KEY = 100,
- GCR_FORMAT_DER_PRIVATE_KEY_RSA,
- GCR_FORMAT_DER_PRIVATE_KEY_DSA,
-
- GCR_FORMAT_DER_CERTIFICATE_X509 = 200,
-
- GCR_FORMAT_DER_PKCS7 = 300,
-
- GCR_FORMAT_DER_PKCS8 = 400,
- GCR_FORMAT_DER_PKCS8_PLAIN,
- GCR_FORMAT_DER_PKCS8_ENCRYPTED,
-
- GCR_FORMAT_DER_PKCS12 = 500,
-
- GCR_FORMAT_OPENSSH_PUBLIC = 600,
-
- GCR_FORMAT_OPENPGP_PACKET = 700,
- GCR_FORMAT_OPENPGP_ARMOR,
-
- GCR_FORMAT_PEM = 1000,
- GCR_FORMAT_PEM_PRIVATE_KEY_RSA,
- GCR_FORMAT_PEM_PRIVATE_KEY_DSA,
- GCR_FORMAT_PEM_CERTIFICATE_X509,
- GCR_FORMAT_PEM_PKCS7,
- GCR_FORMAT_PEM_PKCS8_PLAIN,
- GCR_FORMAT_PEM_PKCS8_ENCRYPTED,
- GCR_FORMAT_PEM_PKCS12,
- GCR_FORMAT_PEM_PRIVATE_KEY
-} GcrDataFormat;
-
-/*
- * Special PKCS#11 style attributes that we use internally in GCR.
- * These are used by GcrParser the most
- */
-
-enum {
- /* An object class representing GcrRecord/gnupg-colons style data */
- CKO_GCR_GNUPG_RECORDS = (CKO_VENDOR_DEFINED | 0x47435200UL /* GCR0 */)
-};
-
-G_END_DECLS
-
-#endif /* GCRTYPES_H_ */
diff --git a/gcr/gcr-union-collection.c b/gcr/gcr-union-collection.c
deleted file mode 100644
index 459fbcc0..00000000
--- a/gcr/gcr-union-collection.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-collection.h"
-#include "gcr-internal.h"
-#include "gcr-union-collection.h"
-
-#include <string.h>
-
-/**
- * SECTION:gcr-union-collection
- * @title: GcrUnionCollection
- * @short_description: A GcrCollection which combines other collections
- *
- * An implementation of #GcrCollection, which combines the objects in
- * other #GcrCollections. Use gcr_union_collection_add() to add and
- * gcr_union_collection_remove() to remove them.
- */
-
-/**
- * GcrUnionCollection:
- *
- * A union implementation of #GcrCollection.
- */
-
-/**
- * GcrUnionCollectionClass:
- * @parent_class: The parent class
- *
- * The class for #GcrUnionCollection.
- */
-
-struct _GcrUnionCollectionPrivate {
- GHashTable *items;
- GHashTable *collections;
-};
-
-static void gcr_collection_iface (GcrCollectionIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrUnionCollection, gcr_union_collection, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, gcr_collection_iface));
-
-static void
-on_collection_added (GcrCollection *collection,
- GObject *object,
- gpointer user_data)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (user_data);
- gint *count;
-
- g_object_ref (object);
-
- count = g_hash_table_lookup (self->pv->items, object);
- if (count == NULL) {
- count = g_new0 (gint, 1);
- *count = 1;
- g_hash_table_insert (self->pv->items, object, count);
- gcr_collection_emit_added (GCR_COLLECTION (self), object);
- } else {
- g_assert (*count > 0);
- (*count)++;
- }
-
- g_object_unref (object);
-}
-
-static void
-on_collection_removed (GcrCollection *collection,
- GObject *object,
- gpointer user_data)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (user_data);
- gint *count;
-
- g_object_ref (object);
-
- count = g_hash_table_lookup (self->pv->items, object);
- if (count != NULL) {
- g_assert (*count > 0);
- (*count)--;
-
- if (*count == 0) {
- g_hash_table_remove (self->pv->items, object);
- gcr_collection_emit_removed (GCR_COLLECTION (self), object);
- }
- } else {
- g_warning ("Object of type %s that exists in an underlying "
- "collection of a GcrUnionCollection appeared without "
- "emitting 'added' signal.", G_OBJECT_TYPE_NAME (object));
- }
-
- g_object_unref (object);
-
-}
-
-static void
-connect_to_collection (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- g_signal_connect (collection, "added", G_CALLBACK (on_collection_added), self);
- g_signal_connect (collection, "removed", G_CALLBACK (on_collection_removed), self);
-}
-
-static void
-disconnect_from_collection (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- g_signal_handlers_disconnect_by_func (collection, on_collection_added, self);
- g_signal_handlers_disconnect_by_func (collection, on_collection_removed, self);
-}
-
-static void
-gcr_union_collection_init (GcrUnionCollection *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_UNION_COLLECTION, GcrUnionCollectionPrivate);
- self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, g_free);
- self->pv->collections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- g_object_unref, NULL);
-}
-
-static void
-gcr_union_collection_dispose (GObject *obj)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (obj);
- GHashTableIter iter;
- GcrCollection *collection;
-
- g_hash_table_iter_init (&iter, self->pv->collections);
- while (g_hash_table_iter_next (&iter, (gpointer *)&collection, NULL))
- disconnect_from_collection (self, collection);
- g_hash_table_remove_all (self->pv->collections);
- g_hash_table_remove_all (self->pv->items);
-
- G_OBJECT_CLASS (gcr_union_collection_parent_class)->dispose (obj);
-}
-
-static void
-gcr_union_collection_finalize (GObject *obj)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (obj);
-
- g_assert (g_hash_table_size (self->pv->items) == 0);
- g_hash_table_destroy (self->pv->items);
-
- g_assert (g_hash_table_size (self->pv->collections) == 0);
- g_hash_table_destroy (self->pv->collections);
-
- G_OBJECT_CLASS (gcr_union_collection_parent_class)->finalize (obj);
-}
-
-static void
-gcr_union_collection_class_init (GcrUnionCollectionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->dispose = gcr_union_collection_dispose;
- gobject_class->finalize = gcr_union_collection_finalize;
- g_type_class_add_private (gobject_class, sizeof (GcrUnionCollectionPrivate));
-}
-
-static guint
-gcr_union_collection_real_get_length (GcrCollection *coll)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (coll);
- return g_hash_table_size (self->pv->items);
-}
-
-static GList*
-gcr_union_collection_real_get_objects (GcrCollection *coll)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (coll);
- return g_hash_table_get_keys (self->pv->items);
-}
-
-static gboolean
-gcr_union_collection_real_contains (GcrCollection *collection,
- GObject *object)
-{
- GcrUnionCollection *self = GCR_UNION_COLLECTION (collection);
- return g_hash_table_lookup (self->pv->items, object) ? TRUE : FALSE;
-}
-
-static void
-gcr_collection_iface (GcrCollectionIface *iface)
-{
- iface->get_length = gcr_union_collection_real_get_length;
- iface->get_objects = gcr_union_collection_real_get_objects;
- iface->contains = gcr_union_collection_real_contains;
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_union_collection_new:
- *
- * Create a new #GcrUnionCollection.
- *
- * Returns: (transfer full) (type Gcr.UnionCollection): a newly allocated
- * collection, which should be freed with g_object_unref()
- */
-GcrCollection *
-gcr_union_collection_new (void)
-{
- return g_object_new (GCR_TYPE_UNION_COLLECTION, NULL);
-}
-
-/**
- * gcr_union_collection_add:
- * @self: The union collection
- * @collection: The collection whose objects to add
- *
- * Add objects from this collection to the union
- */
-void
-gcr_union_collection_add (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- g_return_if_fail (GCR_IS_UNION_COLLECTION (self));
- g_return_if_fail (GCR_IS_COLLECTION (collection));
- gcr_union_collection_take (self, g_object_ref (collection));
-}
-
-/**
- * gcr_union_collection_take:
- * @self: The union collection
- * @collection: The collection whose objects to add
- *
- * Add objects from this collection to the union. Do not add an additional
- * reference to the collection.
- */
-void
-gcr_union_collection_take (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- GList *objects, *l;
-
- g_return_if_fail (GCR_IS_UNION_COLLECTION (self));
- g_return_if_fail (GCR_IS_COLLECTION (collection));
- g_return_if_fail (!g_hash_table_lookup (self->pv->collections, collection));
-
- g_object_ref (collection);
-
- g_hash_table_insert (self->pv->collections, collection, collection);
- connect_to_collection (self, collection);
-
- objects = gcr_collection_get_objects (collection);
- for (l = objects; l != NULL; l = g_list_next (l))
- on_collection_added (collection, l->data, self);
- g_list_free (objects);
-
- g_object_unref (collection);
-}
-
-/**
- * gcr_union_collection_remove:
- * @self: The collection
- * @collection: The collection whose objects to remove
- *
- * Remove an object from the collection.
- */
-void
-gcr_union_collection_remove (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- GList *objects, *l;
-
- g_return_if_fail (GCR_IS_UNION_COLLECTION (self));
- g_return_if_fail (GCR_IS_COLLECTION (collection));
- g_return_if_fail (g_hash_table_lookup (self->pv->collections, collection));
-
- g_object_ref (collection);
-
- g_hash_table_remove (self->pv->collections, collection);
- disconnect_from_collection (self, collection);
-
- objects = gcr_collection_get_objects (collection);
- for (l = objects; l != NULL; l = g_list_next (l))
- on_collection_removed (collection, l->data, self);
- g_list_free (objects);
-
- g_object_unref (collection);
-}
-
-/**
- * gcr_union_collection_have:
- * @self: the union collection
- * @collection: the collection to check
- *
- * Check whether the collection is present in the union.
- *
- * Returns: whether present or not
- */
-gboolean
-gcr_union_collection_have (GcrUnionCollection *self,
- GcrCollection *collection)
-{
- g_return_val_if_fail (GCR_IS_UNION_COLLECTION (self), FALSE);
- g_return_val_if_fail (GCR_IS_COLLECTION (collection), FALSE);
- return g_hash_table_lookup (self->pv->collections, collection) != NULL;
-}
-
-/**
- * gcr_union_collection_size:
- * @self: the union collection
- *
- * Return the number of collections in this union. This does not reflect
- * the number of objects in the combined collection.
- *
- * Returns: number of collections inlcuded
- */
-guint
-gcr_union_collection_size (GcrUnionCollection *self)
-{
- g_return_val_if_fail (GCR_IS_UNION_COLLECTION (self), FALSE);
- return g_hash_table_size (self->pv->collections);
-}
diff --git a/gcr/gcr-union-collection.h b/gcr/gcr-union-collection.h
deleted file mode 100644
index 4628799b..00000000
--- a/gcr/gcr-union-collection.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef __GCR_UNION_COLLECTION_H__
-#define __GCR_UNION_COLLECTION_H__
-
-#include "gcr-base.h"
-#include "gcr-collection.h"
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_UNION_COLLECTION (gcr_union_collection_get_type ())
-#define GCR_UNION_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrUnionCollection))
-#define GCR_UNION_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION, GcrUnionCollectionClass))
-#define GCR_IS_UNION_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
-#define GCR_IS_UNION_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION))
-#define GCR_UNION_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION, GcrUnionCollectionClass))
-
-typedef struct _GcrUnionCollection GcrUnionCollection;
-typedef struct _GcrUnionCollectionClass GcrUnionCollectionClass;
-typedef struct _GcrUnionCollectionPrivate GcrUnionCollectionPrivate;
-
-struct _GcrUnionCollection {
- GObject parent;
-
- /*< private >*/
- GcrUnionCollectionPrivate *pv;
-};
-
-struct _GcrUnionCollectionClass {
- GObjectClass parent_class;
-};
-
-GType gcr_union_collection_get_type (void);
-
-GcrCollection* gcr_union_collection_new (void);
-
-void gcr_union_collection_add (GcrUnionCollection *self,
- GcrCollection *collection);
-
-void gcr_union_collection_take (GcrUnionCollection *self,
- GcrCollection *collection);
-
-void gcr_union_collection_remove (GcrUnionCollection *self,
- GcrCollection *collection);
-
-gboolean gcr_union_collection_have (GcrUnionCollection *self,
- GcrCollection *collection);
-
-guint gcr_union_collection_size (GcrUnionCollection *self);
-
-G_END_DECLS
-
-#endif /* __GCR_UNION_COLLECTION_H__ */
diff --git a/gcr/gcr-unlock-options-widget.c b/gcr/gcr-unlock-options-widget.c
deleted file mode 100644
index 5721cafa..00000000
--- a/gcr/gcr-unlock-options-widget.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-unlock-options-widget.h"
-
-#include <glib/gi18n-lib.h>
-
-/**
- * SECTION:gcr-unlock-options-widget
- * @title: GcrUnlockOptionsWidget
- * @short_description: A widget for unlock options
- *
- * This widget displays a set of unlock options for the user to select. The user
- * can choose between keeping caching the unlock indefinitely, or for a given
- * amount of time.
- *
- * Each option has a different name, for example #GCR_UNLOCK_OPTION_ALWAYS. These
- * names are used together with the various functions like
- * gcr_unlock_options_widget_get_choice().
- */
-
-/**
- * GCR_UNLOCK_OPTION_ALWAYS:
- *
- * Option name for caching unlock indefinitely.
- */
-
-/**
- * GCR_UNLOCK_OPTION_IDLE:
- *
- * Option name for caching unlock for a certain amount of idle time.
- */
-
-/**
- * GCR_UNLOCK_OPTION_SESSION:
- *
- * Option name for caching unlock for the current session.
- */
-
-/**
- * GCR_UNLOCK_OPTION_TIMEOUT:
- *
- * Option name for caching unlock for a certain amount of time.
- */
-
-/**
- * GcrUnlockOptionsWidget:
- *
- * An unlock options widget.
- */
-
-/**
- * GcrUnlockOptionsWidgetClass:
- *
- * Class for #GcrUnlockOptionsWidget.
- */
-
-enum {
- PROP_0,
- PROP_CHOICE,
- PROP_TTL
-};
-
-struct _GcrUnlockOptionsWidget {
- GtkAlignment parent;
-
- /*< private >*/
- GcrUnlockOptionsWidgetPrivate *pv;
-};
-
-struct _GcrUnlockOptionsWidgetClass {
- GtkAlignmentClass parent_class;
-};
-
-struct _GcrUnlockOptionsWidgetPrivate {
- GtkBuilder *builder;
- gchar *choice;
-};
-
-G_DEFINE_TYPE (GcrUnlockOptionsWidget, gcr_unlock_options_widget, GTK_TYPE_ALIGNMENT);
-
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static GtkToggleButton*
-builder_get_toggle_button (GtkBuilder *builder, const gchar *name)
-{
- GObject *object = gtk_builder_get_object (builder, name);
- g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (object), NULL);
- return GTK_TOGGLE_BUTTON (object);
-}
-
-static GtkSpinButton*
-builder_get_spin_button (GtkBuilder *builder, const gchar *name)
-{
- GObject *object = gtk_builder_get_object (builder, name);
- g_return_val_if_fail (GTK_IS_SPIN_BUTTON (object), NULL);
- return GTK_SPIN_BUTTON (object);
-}
-
-static const gchar*
-widget_name_for_option (const gchar *option)
-{
- g_return_val_if_fail (option, NULL);
- if (g_str_equal (option, GCR_UNLOCK_OPTION_ALWAYS))
- return "lock_always_choice";
- else if (g_str_equal (option, GCR_UNLOCK_OPTION_SESSION))
- return "lock_session_choice";
- else if (g_str_equal (option, GCR_UNLOCK_OPTION_TIMEOUT))
- return "lock_timeout_choice";
- else if (g_str_equal (option, GCR_UNLOCK_OPTION_IDLE))
- return "lock_idle_choice";
- else
- return NULL;
-}
-
-static GtkToggleButton*
-widget_button_for_option (GcrUnlockOptionsWidget *self, const gchar *option)
-{
- const gchar *name = widget_name_for_option (option);
- g_return_val_if_fail (name, NULL);
- return builder_get_toggle_button (self->pv->builder, name);
-}
-
-static const gchar*
-widget_button_to_option (GcrUnlockOptionsWidget *self, GtkToggleButton *button)
-{
- const gchar *option;
- g_return_val_if_fail (button, NULL);
- option = g_object_get_data (G_OBJECT (button), "unlock-choice");
- g_return_val_if_fail (option, NULL);
- return option;
-}
-
-static void
-on_choice_toggled (GtkToggleButton *button, GcrUnlockOptionsWidget *self)
-{
- GtkWidget *spin;
- GtkToggleButton *after, *idle;
-
- spin = GTK_WIDGET (gtk_builder_get_object (self->pv->builder, "lock_minutes_spin"));
- after = builder_get_toggle_button (self->pv->builder, "lock_timeout_choice");
- idle = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
- gtk_widget_set_sensitive (spin, gtk_toggle_button_get_active (after) ||
- gtk_toggle_button_get_active (idle));
-
- if (gtk_toggle_button_get_active (button)) {
- g_free (self->pv->choice);
- self->pv->choice = g_strdup (widget_button_to_option (self, button));
- }
-}
-
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
-
-
-static GObject*
-gcr_unlock_options_widget_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GObject *obj = G_OBJECT_CLASS (gcr_unlock_options_widget_parent_class)->constructor (type, n_props, props);
- GcrUnlockOptionsWidget *self = NULL;
- GtkToggleButton *button;
- GtkWidget *widget;
-
- if (obj) {
- self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-
- if (!gtk_builder_add_from_file (self->pv->builder, UIDIR "gcr-unlock-options-widget.ui", NULL))
- g_return_val_if_reached (obj);
-
- widget = GTK_WIDGET (gtk_builder_get_object (self->pv->builder, "unlock-options-widget"));
- g_return_val_if_fail (GTK_IS_WIDGET (widget), obj);
- gtk_container_add (GTK_CONTAINER (self), widget);
- gtk_widget_show (widget);
-
- button = builder_get_toggle_button (self->pv->builder, "lock_always_choice");
- g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
- g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_ALWAYS);
-
- button = builder_get_toggle_button (self->pv->builder, "lock_session_choice");
- g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
- g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_SESSION);
- on_choice_toggled (button, self);
-
- button = builder_get_toggle_button (self->pv->builder, "lock_timeout_choice");
- g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
- g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_TIMEOUT);
-
- button = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
- g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
- g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_IDLE);
- }
-
- return obj;
-}
-
-static void
-gcr_unlock_options_widget_init (GcrUnlockOptionsWidget *self)
-{
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_UNLOCK_OPTIONS_WIDGET, GcrUnlockOptionsWidgetPrivate));
- self->pv->builder = gtk_builder_new ();
-}
-
-static void
-gcr_unlock_options_widget_dispose (GObject *obj)
-{
- GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-
- if (self->pv->builder)
- g_object_unref (self->pv->builder);
- self->pv->builder = NULL;
-
- G_OBJECT_CLASS (gcr_unlock_options_widget_parent_class)->dispose (obj);
-}
-
-static void
-gcr_unlock_options_widget_finalize (GObject *obj)
-{
- GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-
- g_assert (!self->pv->builder);
- g_free (self->pv->choice);
- self->pv->choice = NULL;
-
- G_OBJECT_CLASS (gcr_unlock_options_widget_parent_class)->finalize (obj);
-}
-
-static void
-gcr_unlock_options_widget_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_CHOICE:
- gcr_unlock_options_widget_set_choice (self, g_value_get_string (value));
- break;
- case PROP_TTL:
- gcr_unlock_options_widget_set_ttl (self, g_value_get_uint (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_unlock_options_widget_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_CHOICE:
- g_value_set_string (value, gcr_unlock_options_widget_get_choice (self));
- break;
- case PROP_TTL:
- g_value_set_uint (value, gcr_unlock_options_widget_get_ttl (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_unlock_options_widget_class_init (GcrUnlockOptionsWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gcr_unlock_options_widget_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GcrUnlockOptionsWidgetPrivate));
-
- gobject_class->constructor = gcr_unlock_options_widget_constructor;
- gobject_class->dispose = gcr_unlock_options_widget_dispose;
- gobject_class->finalize = gcr_unlock_options_widget_finalize;
- gobject_class->set_property = gcr_unlock_options_widget_set_property;
- gobject_class->get_property = gcr_unlock_options_widget_get_property;
-
- g_object_class_install_property (gobject_class, PROP_CHOICE,
- g_param_spec_string ("choice", "Choice", "Unlock Option Choice",
- NULL, G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_TTL,
- g_param_spec_uint ("ttl", "TTL", "Unlock Option Timeout in Seconds",
- 0, G_MAXUINT, 0, G_PARAM_READWRITE));
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_unlock_options_widget_new:
- *
- * Create a new #GcrUnlockOptionsWidget.
- *
- * Returns: (transfer full) (type Gcr.UnlockOptionsWidget): a new #GcrUnlockOptionsWidget
- */
-GtkWidget *
-gcr_unlock_options_widget_new (void)
-{
- return g_object_new (GCR_TYPE_UNLOCK_OPTIONS_WIDGET, NULL);
-}
-
-/**
- * gcr_unlock_options_widget_get_choice:
- * @self: The unlock options widget
- *
- * Get the currently selected option, like %GCR_UNLOCK_OPTION_ALWAYS.
- *
- * Returns: The currently selected option name.
- */
-const gchar*
-gcr_unlock_options_widget_get_choice (GcrUnlockOptionsWidget *self)
-{
- g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), NULL);
- return self->pv->choice;
-}
-
-/**
- * gcr_unlock_options_widget_set_choice:
- * @self: The unlock options widget
- * @option: The option name
- *
- * Set the currently selected option. Use an option name like
- * %GCR_UNLOCK_OPTION_ALWAYS.
- */
-void
-gcr_unlock_options_widget_set_choice (GcrUnlockOptionsWidget *self, const gchar *option)
-{
- GtkToggleButton *button;
-
- g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
- g_return_if_fail (option);
-
- button = widget_button_for_option (self, option);
- gtk_toggle_button_set_active (button, TRUE);
-}
-
-/**
- * gcr_unlock_options_widget_get_ttl:
- * @self: The unlock options widget
- *
- * Get the timeout setting set for unlock options that have a timeout.
- * This will also return a valid value if the currently selected option
- * does not have a timeout.
- *
- * Returns: The unlock timeout in seconds.
- */
-guint
-gcr_unlock_options_widget_get_ttl (GcrUnlockOptionsWidget *self)
-{
- GtkSpinButton *spin;
- gint amount;
-
- g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), 0);
-
- spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
- amount = gtk_spin_button_get_value_as_int (spin);
- return amount * 60;
-}
-
-/**
- * gcr_unlock_options_widget_set_ttl:
- * @self: The unlock options widget
- * @ttl: The timeout to set, in seconds
- *
- * Set the current setting for the timeout. This can be set even when the
- * currently selected option does not have a timeout.
- */
-void
-gcr_unlock_options_widget_set_ttl (GcrUnlockOptionsWidget *self, guint ttl)
-{
- GtkSpinButton *spin;
- guint amount;
-
- g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
-
- amount = ttl / 60;
- if (!amount || ttl % 60)
- amount += 1;
-
- spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
- gtk_spin_button_set_value (spin, amount);
-}
-
-/**
- * gcr_unlock_options_widget_get_label:
- * @self: The unlock options widget
- * @option: The option name
- *
- * Get the label for one of the options. Use an option name like
- * %GCR_UNLOCK_OPTION_ALWAYS.
- *
- * Returns: The current label for the option.
- */
-const gchar*
-gcr_unlock_options_widget_get_label (GcrUnlockOptionsWidget *self, const gchar *option)
-{
- GtkToggleButton *button;
- const gchar *name;
-
- g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), NULL);
- g_return_val_if_fail (option, NULL);
-
- name = widget_name_for_option (option);
- g_return_val_if_fail (name, NULL);
-
- button = builder_get_toggle_button (self->pv->builder, name);
- g_return_val_if_fail (button, NULL);
-
- return gtk_button_get_label (GTK_BUTTON (button));
-}
-
-/**
- * gcr_unlock_options_widget_set_label:
- * @self: The unlock options widget
- * @option: The option name
- * @text: The new label
- *
- * Set the label for one of the options. Use an option name like
- * %GCR_UNLOCK_OPTION_ALWAYS.
- */
-void
-gcr_unlock_options_widget_set_label (GcrUnlockOptionsWidget *self, const gchar *option,
- const gchar *text)
-{
- GtkToggleButton *button;
- const gchar *name;
-
- g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
- g_return_if_fail (option);
- g_return_if_fail (text);
-
- name = widget_name_for_option (option);
- g_return_if_fail (name);
-
- button = builder_get_toggle_button (self->pv->builder, name);
- g_return_if_fail (button);
-
- gtk_button_set_label (GTK_BUTTON (button), text);
-}
-
-/**
- * gcr_unlock_options_widget_get_sensitive:
- * @self: The unlock options widget
- * @option: The option name
- *
- * Get the sensitivity state for one of the options. Use an option name like
- * %GCR_UNLOCK_OPTION_ALWAYS.
- *
- * Returns: Whether the option is sensitive or not.
- */
-gboolean
-gcr_unlock_options_widget_get_sensitive (GcrUnlockOptionsWidget *self, const gchar *option)
-{
- GtkToggleButton *button;
- GtkStateType state;
-
- g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), FALSE);
- g_return_val_if_fail (option, FALSE);
-
- button = widget_button_for_option (self, option);
- state = gtk_widget_get_state (GTK_WIDGET (button));
- return (state & GTK_STATE_INSENSITIVE) != GTK_STATE_INSENSITIVE;
-}
-
-/**
- * gcr_unlock_options_widget_set_sensitive:
- * @self: The unlock options widget
- * @option: The option name
- * @sensitive: The sensitivity state.
- * @reason: A user displayable string which contains the reason for the sensitivity.
- *
- * Set the sensitivity state for one of the options. Use an option name like
- * %GCR_UNLOCK_OPTION_ALWAYS. The reason will be displayed as a tooltip.
- */
-void
-gcr_unlock_options_widget_set_sensitive (GcrUnlockOptionsWidget *self, const gchar *option,
- gboolean sensitive, const gchar *reason)
-{
- GtkToggleButton *button;
-
- g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
- g_return_if_fail (option);
-
- button = widget_button_for_option (self, option);
- gtk_widget_set_sensitive (GTK_WIDGET (button), sensitive);
-
- if (!sensitive && reason)
- gtk_widget_set_tooltip_text (GTK_WIDGET (button), reason);
- else if (sensitive)
- gtk_widget_set_has_tooltip (GTK_WIDGET (button), FALSE);
-}
diff --git a/gcr/gcr-unlock-options-widget.h b/gcr/gcr-unlock-options-widget.h
deleted file mode 100644
index ca274f5c..00000000
--- a/gcr/gcr-unlock-options-widget.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_UNLOCK_OPTIONS_WIDGET_H__
-#define __GCR_UNLOCK_OPTIONS_WIDGET_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-types.h"
-#include "gcr-unlock-options.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_UNLOCK_OPTIONS_WIDGET (gcr_unlock_options_widget_get_type ())
-#define GCR_UNLOCK_OPTIONS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_UNLOCK_OPTIONS_WIDGET, GcrUnlockOptionsWidget))
-#define GCR_UNLOCK_OPTIONS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_UNLOCK_OPTIONS_WIDGET, GcrUnlockOptionsWidgetClass))
-#define GCR_IS_UNLOCK_OPTIONS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_UNLOCK_OPTIONS_WIDGET))
-#define GCR_IS_UNLOCK_OPTIONS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_UNLOCK_OPTIONS_WIDGET))
-#define GCR_UNLOCK_OPTIONS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_UNLOCK_OPTIONS_WIDGET, GcrUnlockOptionsWidgetClass))
-
-typedef struct _GcrUnlockOptionsWidget GcrUnlockOptionsWidget;
-typedef struct _GcrUnlockOptionsWidgetClass GcrUnlockOptionsWidgetClass;
-typedef struct _GcrUnlockOptionsWidgetPrivate GcrUnlockOptionsWidgetPrivate;
-
-/*
- * TODO: GcrUnlockOptionsWidget and GcrUnlockOptionsWidgetClass are hidden until
- * we can figure out what they should be derived from.
- */
-
-GType gcr_unlock_options_widget_get_type (void);
-
-GtkWidget* gcr_unlock_options_widget_new (void);
-
-const gchar* gcr_unlock_options_widget_get_choice (GcrUnlockOptionsWidget *self);
-
-void gcr_unlock_options_widget_set_choice (GcrUnlockOptionsWidget *self,
- const gchar *option);
-
-guint gcr_unlock_options_widget_get_ttl (GcrUnlockOptionsWidget *self);
-
-void gcr_unlock_options_widget_set_ttl (GcrUnlockOptionsWidget *self,
- guint ttl);
-
-const gchar* gcr_unlock_options_widget_get_label (GcrUnlockOptionsWidget *self,
- const gchar *option);
-
-void gcr_unlock_options_widget_set_label (GcrUnlockOptionsWidget *self,
- const gchar *option,
- const gchar *text);
-
-gboolean gcr_unlock_options_widget_get_sensitive (GcrUnlockOptionsWidget *self,
- const gchar *option);
-
-void gcr_unlock_options_widget_set_sensitive (GcrUnlockOptionsWidget *self,
- const gchar *option,
- gboolean sensitive,
- const gchar *reason);
-
-G_END_DECLS
-
-#endif /* __GCR_UNLOCK_OPTIONS_WIDGET_H__ */
diff --git a/gcr/gcr-unlock-options-widget.ui b/gcr/gcr-unlock-options-widget.ui
deleted file mode 100644
index ef59144d..00000000
--- a/gcr/gcr-unlock-options-widget.ui
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy project-wide -->
- <object class="GtkAdjustment" id="spin_adjustment">
- <property name="lower">1</property>
- <property name="upper">999</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkVBox" id="unlock-options-widget">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkRadioButton" id="lock_always_choice">
- <property name="label" translatable="yes">Automatically unlock this keyring whenever I'm logged in</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">lock_session_choice</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkRadioButton" id="lock_session_choice">
- <property name="label" translatable="yes">Lock this keyring when I log out</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkRadioButton" id="lock_timeout_choice">
- <property name="label" translatable="yes">Lock this keyring after</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">lock_session_choice</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkRadioButton" id="lock_idle_choice">
- <property name="label" translatable="yes">Lock this keyring if idle for</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">lock_session_choice</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="lock_minutes_spin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">•</property>
- <property name="adjustment">spin_adjustment</property>
- <property name="climb_rate">1</property>
- <property name="numeric">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes" comments="Translators: The 'minutes' from 'Lock this keyring if idle for x minutes'.">minutes</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
-</interface>
diff --git a/gcr/gcr-unlock-options.h b/gcr/gcr-unlock-options.h
deleted file mode 100644
index e4ec6705..00000000
--- a/gcr/gcr-unlock-options.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_UNLOCK_OPTIONS_H__
-#define __GCR_UNLOCK_OPTIONS_H__
-
-G_BEGIN_DECLS
-
-#define GCR_UNLOCK_OPTION_ALWAYS "always"
-#define GCR_UNLOCK_OPTION_SESSION "session"
-#define GCR_UNLOCK_OPTION_TIMEOUT "timeout"
-#define GCR_UNLOCK_OPTION_IDLE "idle"
-
-G_END_DECLS
-
-#endif /* __GCR_UNLOCK_OPTIONS_H__ */
diff --git a/gcr/gcr-unlock-renderer.c b/gcr/gcr-unlock-renderer.c
deleted file mode 100644
index 4615057f..00000000
--- a/gcr/gcr-unlock-renderer.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-display-view.h"
-#include "gcr-icons.h"
-#include "gcr-parser.h"
-#include "gcr-unlock-renderer.h"
-
-#include "egg/egg-entry-buffer.h"
-
-#include <gdk/gdk.h>
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ATTRIBUTES
-};
-
-struct _GcrUnlockRendererPrivate {
- GtkEntry *entry;
- GtkLabel *warning;
-
- gpointer locked_data;
- gsize n_locked_data;
- gchar *label;
- gboolean unlocked;
- GList *renderers;
- guint unlock_tries;
-
- /* block widget destroys during render */
- gint no_destroy;
-};
-
-enum {
- UNLOCK_CLICKED,
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static void gcr_renderer_iface_init (GcrRendererIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrUnlockRenderer, _gcr_unlock_renderer, GTK_TYPE_ALIGNMENT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
-);
-
-static gchar*
-calculate_label (GcrUnlockRenderer *self)
-{
- if (self->pv->label)
- return g_strdup_printf (_("Unlock: %s"), self->pv->label);
-
- return g_strdup (_("Unlock"));
-}
-
-void
-_gcr_unlock_renderer_show_warning (GcrUnlockRenderer *self,
- const gchar *message)
-{
- gchar *text;
-
- g_return_if_fail (GCR_UNLOCK_RENDERER (self));
- g_return_if_fail (message != NULL);
-
- text = g_strdup_printf ("<i>%s</i>", message);
- gtk_label_set_markup (self->pv->warning, text);
- g_free (text);
-
- gtk_widget_show (GTK_WIDGET (self->pv->warning));
-}
-
-static void
-on_unlock_button_clicked (GtkButton *button,
- gpointer user_data)
-{
- GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (user_data);
- g_signal_emit (self, signals[UNLOCK_CLICKED], 0);
-}
-
-static void
-on_entry_activated (GtkEntry *entry,
- gpointer user_data)
-{
- GtkButton *button = GTK_BUTTON (user_data);
- gtk_button_clicked (button);
-}
-
-static void
-_gcr_unlock_renderer_init (GcrUnlockRenderer *self)
-{
- GtkWidget *box, *vbox;
- GtkWidget *button;
- GtkEntryBuffer *buffer;
-
- self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_UNLOCK_RENDERER,
- GcrUnlockRendererPrivate));
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-
- buffer = egg_entry_buffer_new ();
- self->pv->entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
- gtk_entry_set_visibility (self->pv->entry, FALSE);
- gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (self->pv->entry), TRUE, FALSE, 0);
- gtk_widget_show (GTK_WIDGET (self->pv->entry));
- g_object_unref (buffer);
-#if GTK_CHECK_VERSION (3,1,1)
- gtk_entry_set_placeholder_text (self->pv->entry, _("Password"));
-#endif
-
- button = gtk_button_new_with_label (_("Unlock"));
- gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
- g_signal_connect (button, "clicked", G_CALLBACK (on_unlock_button_clicked), self);
- g_signal_connect (self->pv->entry, "activate", G_CALLBACK (on_entry_activated), button);
- gtk_widget_show (button);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
- gtk_widget_show (box);
-
- self->pv->warning = GTK_LABEL (gtk_label_new (""));
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (self->pv->warning), FALSE, FALSE, 0);
- gtk_widget_hide (GTK_WIDGET (self->pv->warning));
-
- gtk_container_add (GTK_CONTAINER (self), vbox);
- gtk_widget_show (vbox);
-}
-
-static void
-_gcr_unlock_renderer_finalize (GObject *obj)
-{
- GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (obj);
-
- g_free (self->pv->locked_data);
- g_free (self->pv->label);
- g_list_free_full (self->pv->renderers, g_object_unref);
-
- G_OBJECT_CLASS (_gcr_unlock_renderer_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_unlock_renderer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_free (self->pv->label);
- self->pv->label = g_value_dup_string (value);
- g_object_notify (obj, "label");
- gcr_renderer_emit_data_changed (GCR_RENDERER (self));
- break;
- case PROP_ATTRIBUTES:
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_unlock_renderer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ATTRIBUTES:
- g_value_set_boxed (value, NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_unlock_renderer_class_init (GcrUnlockRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (GcrUnlockRendererPrivate));
-
- gobject_class->finalize = _gcr_unlock_renderer_finalize;
- gobject_class->set_property = _gcr_unlock_renderer_set_property;
- gobject_class->get_property = _gcr_unlock_renderer_get_property;
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "Label", "Unlock Label",
- "", G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
- g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
- GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
-
- signals[UNLOCK_CLICKED] = g_signal_new ("unlock-clicked", GCR_TYPE_UNLOCK_RENDERER, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrUnlockRendererClass, unlock_clicked),
- NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void
-gcr_unlock_renderer_render (GcrRenderer *renderer,
- GcrViewer *viewer)
-{
- GcrUnlockRenderer *self = GCR_UNLOCK_RENDERER (renderer);
- GcrDisplayView *view;
- gchar *display;
- GList *renderers;
- GIcon *icon;
- GList *l;
-
- if (GCR_IS_DISPLAY_VIEW (viewer)) {
- view = GCR_DISPLAY_VIEW (viewer);
-
- } else {
- g_warning ("GcrUnlockRenderer only works with internal specific "
- "GcrViewer returned by gcr_viewer_new().");
- return;
- }
-
- /*
- * If we were successfully unlocked, then this will contain a list of
- * renderers to add to the viewer.
- */
- if (self->pv->unlocked) {
-
- /* We used prepend above, so list is backwards */
- renderers = g_list_reverse (self->pv->renderers);
- self->pv->renderers = NULL;
-
- for (l = renderers; l != NULL; l = g_list_next (l))
- gcr_viewer_insert_renderer (viewer, l->data, renderer);
- g_list_free_full (renderers, g_object_unref);
-
- /* And finally remove ourselves from the viewer */
- gcr_viewer_remove_renderer (viewer, GCR_RENDERER (self));
- /*
- * Not yet unlocked, display the unlock dialog.
- */
- } else {
-
- _gcr_display_view_begin (view, renderer);
-
- icon = g_themed_icon_new ("emblem-readonly");
- _gcr_display_view_set_icon (view, renderer, icon);
- g_object_unref (icon);
-
- display = calculate_label (self);
- _gcr_display_view_append_title (view, renderer, display);
- g_free (display);
-
- if (self->pv->label)
- display = g_strdup_printf (_("The contents of '%s' are locked. In order to view the contents, enter the correct password."),
- self->pv->label);
- else
- display = g_strdup (_("The contents are locked. In order to view the contents, enter the correct password."));
- _gcr_display_view_append_content (view, renderer, display, NULL);
- g_free (display);
-
- _gcr_display_view_add_widget_area (view, renderer, GTK_WIDGET (self));
- gtk_widget_show (GTK_WIDGET (self));
-
- _gcr_display_view_end (view, renderer);
- }
-}
-
-static void
-gcr_renderer_iface_init (GcrRendererIface *iface)
-{
- iface->render_view = gcr_unlock_renderer_render;
-}
-
-GcrUnlockRenderer*
-_gcr_unlock_renderer_new (const gchar *label,
- gconstpointer locked_data,
- gsize n_locked_data)
-{
- GcrUnlockRenderer *renderer;
-
- renderer = g_object_new (GCR_TYPE_UNLOCK_RENDERER,
- "label", label,
- NULL);
- g_object_ref_sink (renderer);
-
- renderer->pv->locked_data = g_memdup (locked_data, n_locked_data);
- renderer->pv->n_locked_data = n_locked_data;
-
- return renderer;
-}
-
-GcrUnlockRenderer *
-_gcr_unlock_renderer_new_for_parsed (GcrParser *parser)
-{
- gconstpointer block;
- gsize n_block;
-
- g_return_val_if_fail (GCR_IS_PARSER (parser), NULL);
-
- block = gcr_parser_get_parsed_block (parser, &n_block);
- return _gcr_unlock_renderer_new (gcr_parser_get_parsed_label (parser),
- block, n_block);
-}
-
-const gchar *
-_gcr_unlock_renderer_get_password (GcrUnlockRenderer *self)
-{
- g_return_val_if_fail (GCR_IS_UNLOCK_RENDERER (self), NULL);
- return gtk_entry_get_text (self->pv->entry);
-}
-
-gconstpointer
-_gcr_unlock_renderer_get_locked_data (GcrUnlockRenderer *self,
- gsize *n_data)
-{
- g_return_val_if_fail (GCR_IS_UNLOCK_RENDERER (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
- *n_data = self->pv->n_locked_data;
- return self->pv->locked_data;
-}
diff --git a/gcr/gcr-unlock-renderer.h b/gcr/gcr-unlock-renderer.h
deleted file mode 100644
index bc695b13..00000000
--- a/gcr/gcr-unlock-renderer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
-#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
-#endif
-
-#ifndef __GCR_UNLOCK_RENDERER_H__
-#define __GCR_UNLOCK_RENDERER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-renderer.h"
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_UNLOCK_RENDERER (_gcr_unlock_renderer_get_type ())
-#define GCR_UNLOCK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRenderer))
-#define GCR_UNLOCK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRendererClass))
-#define GCR_IS_UNLOCK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_UNLOCK_RENDERER))
-#define GCR_IS_UNLOCK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_UNLOCK_RENDERER))
-#define GCR_UNLOCK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_UNLOCK_RENDERER, GcrUnlockRendererClass))
-
-typedef struct _GcrUnlockRenderer GcrUnlockRenderer;
-typedef struct _GcrUnlockRendererClass GcrUnlockRendererClass;
-typedef struct _GcrUnlockRendererPrivate GcrUnlockRendererPrivate;
-
-struct _GcrUnlockRenderer {
- /*< private >*/
- GtkAlignment parent;
- GcrUnlockRendererPrivate *pv;
-};
-
-struct _GcrUnlockRendererClass {
- GtkAlignmentClass parent_class;
-
- /* signals */
- void (*unlock_clicked) (GcrUnlockRenderer *unlock);
-};
-
-GType _gcr_unlock_renderer_get_type (void);
-
-GcrUnlockRenderer * _gcr_unlock_renderer_new (const gchar *label,
- gconstpointer locked_data,
- gsize n_locked_data);
-
-GcrUnlockRenderer * _gcr_unlock_renderer_new_for_parsed (GcrParser *parser);
-
-const gchar * _gcr_unlock_renderer_get_password (GcrUnlockRenderer *self);
-
-void _gcr_unlock_renderer_show_warning (GcrUnlockRenderer *self,
- const gchar *message);
-
-gconstpointer _gcr_unlock_renderer_get_locked_data (GcrUnlockRenderer *self,
- gsize *n_data);
-
-G_END_DECLS
-
-#endif /* __GCR_UNLOCK_RENDERER_H__ */
diff --git a/gcr/gcr-util.c b/gcr/gcr-util.c
deleted file mode 100644
index 418b73cb..00000000
--- a/gcr/gcr-util.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr-util.h"
-
-#include <string.h>
-
-/**
- * _gcr_util_parse_lines:
- * @string: The string to parse lines from, will be modified
- * @last_line: Whether or not we should run for last line or not
- * @callback: Call for each line
- * @user_data: Data for callback
- *
- * Calls callback for each line. If last_line, also sends the remainder
- * data that comes after the last line break. \n and \r\n are line separators.
- * Neither are included in data passed to callback.
- */
-void
-_gcr_util_parse_lines (GString *string, gboolean last_line,
- GcrLineCallback callback, gpointer user_data)
-{
- gchar *ptr;
- gchar *prev;
-
- g_return_if_fail (string);
- g_return_if_fail (callback);
-
- /* Print all stderr lines as messages */
- while ((ptr = strchr (string->str, '\n')) != NULL) {
- *ptr = '\0';
- prev = ptr - 1;
- if (*prev == '\r')
- *prev = '\0';
-
- (callback) (string->str, user_data);
- g_string_erase (string, 0, ptr - string->str + 1);
- }
-
- if (last_line && string->len) {
- (callback) (string->str, user_data);
- g_string_erase (string, 0, string->len);
- }
-}
diff --git a/gcr/gcr-util.h b/gcr/gcr-util.h
deleted file mode 100644
index a104a8ec..00000000
--- a/gcr/gcr-util.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_UTIL_H
-#define GCR_UTIL_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef void (*GcrLineCallback) (const gchar *line,
- gpointer user_data);
-
-void _gcr_util_parse_lines (GString *string,
- gboolean last_line,
- GcrLineCallback callback,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* __GCR_TOKEN_MANAGER_H__ */
diff --git a/gcr/gcr-viewer-tool.c b/gcr/gcr-viewer-tool.c
deleted file mode 100644
index e3510f45..00000000
--- a/gcr/gcr-viewer-tool.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gcr-viewer-tool.c: Command line utility
-
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr-viewer-window.h"
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
-
-static gchar **remaining_args = NULL;
-
-static gboolean
-print_version_and_exit (const gchar *option_name, const gchar *value,
- gpointer data, GError **error)
-{
- g_print("%s -- %s\n", _("GCR Certificate and Key Viewer"), VERSION);
- exit (0);
- return TRUE;
-}
-
-static const GOptionEntry options[] = {
- { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- print_version_and_exit, N_("Show the application's version"), NULL},
- { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY,
- &remaining_args, NULL, N_("[file...]") },
- { NULL }
-};
-
-static gboolean
-on_idle_load_files (gpointer user_data)
-{
- GcrViewerWindow *window = GCR_VIEWER_WINDOW (user_data);
- GFile *file;
- gint i;
-
- if (remaining_args) {
- for (i = 0; remaining_args[i] != NULL; ++i) {
- file = g_file_new_for_commandline_arg (remaining_args[i]);
- gcr_viewer_window_load (window, file);
- g_object_unref (file);
- }
-
- g_strfreev (remaining_args);
- remaining_args = NULL;
- }
-
- return FALSE; /* Don't run this again */
-}
-
-static void
-on_window_destroy (GtkWidget *widget,
- gpointer unused)
-{
- gtk_widget_hide (widget);
- gtk_main_quit ();
-}
-
-int
-main (int argc, char *argv[])
-{
- GOptionContext *context;
- GError *error = NULL;
- GtkWindow *window;
-
- g_type_init ();
- g_thread_init (NULL);
-
-#ifdef HAVE_LOCALE_H
- /* internationalisation */
- setlocale (LC_ALL, "");
-#endif
-
-#ifdef HAVE_GETTEXT
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- textdomain (GETTEXT_PACKAGE);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#endif
-
- context = g_option_context_new (N_("- View certificate and key files"));
- g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
- g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
-
- if (! g_option_context_parse (context, &argc, &argv, &error)) {
- g_critical ("Failed to parse arguments: %s", error->message);
- g_error_free (error);
- g_option_context_free (context);
- return 1;
- }
-
- g_option_context_free (context);
- g_set_application_name (_("Certificate Viewer"));
-
- gtk_init (&argc, &argv);
-
- window = gcr_viewer_window_new ();
- gtk_widget_show (GTK_WIDGET (window));
-
- g_idle_add (on_idle_load_files, window);
- g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), NULL);
- gtk_main ();
-
- return 0;
-}
diff --git a/gcr/gcr-viewer-widget.c b/gcr/gcr-viewer-widget.c
deleted file mode 100644
index 6e065994..00000000
--- a/gcr/gcr-viewer-widget.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gcr-viewer-widget: Widget for viewer
-
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr-display-scrolled.h"
-#include "gcr-failure-renderer.h"
-#include "gcr-importer.h"
-#include "gcr-marshal.h"
-#include "gcr-parser.h"
-#include "gcr-renderer.h"
-#include "gcr-unlock-renderer.h"
-#include "gcr-viewer-widget.h"
-#include "gcr-viewer.h"
-
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-
-#include <locale.h>
-#include <string.h>
-
-/**
- * SECTION:gcr-viewer-widget
- * @title: GcrViewerWidget
- * @short_description: A widget which shows certificates or keys
- *
- * A viewer widget which can display certificates and keys that are
- * located in files.
- */
-
-enum {
- PROP_0,
- PROP_PARSER
-};
-
-/**
- * GcrViewerWidget:
- *
- * A viewer widget object.
- */
-
-/**
- * GcrViewerWidgetClass:
- *
- * Class for #GcrViewerWidget
- */
-
-/*
- * Not yet figured out how to expose these without locking down our
- * implementation, the parent class we derive from.
- */
-
-struct _GcrViewerWidget {
- /*< private >*/
- GcrDisplayScrolled parent;
- GcrViewerWidgetPrivate *pv;
-};
-
-struct _GcrViewerWidgetClass {
- GcrDisplayScrolledClass parent_class;
-
- void (*added) (GcrViewerWidget *widget,
- GcrRenderer *renderer,
- GcrParsed *parsed);
-};
-
-struct _GcrViewerWidgetPrivate {
- GQueue *files_to_load;
- GcrParser *parser;
- GCancellable *cancellable;
- GList *unlocks;
- gboolean loading;
- gchar *display_name;
-};
-
-enum {
- ADDED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0, };
-
-static void viewer_load_next_file (GcrViewerWidget *self);
-static void viewer_stop_loading_files (GcrViewerWidget *self);
-
-G_DEFINE_TYPE (GcrViewerWidget, gcr_viewer_widget, GCR_TYPE_DISPLAY_SCROLLED);
-
-static const gchar *
-get_parsed_label_or_display_name (GcrViewerWidget *self,
- GcrParser *parser)
-{
- const gchar *label;
-
- label = gcr_parser_get_parsed_label (parser);
- if (label == NULL)
- label = self->pv->display_name;
-
- return label;
-}
-
-static void
-on_parser_parsed (GcrParser *parser,
- gpointer user_data)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
- GckAttributes *attrs;
- GcrRenderer *renderer;
- const gchar *label;
- gboolean actual = TRUE;
-
- label = get_parsed_label_or_display_name (self, parser);
- attrs = gcr_parser_get_parsed_attributes (parser);
-
- renderer = gcr_renderer_create (label, attrs);
-
- if (renderer == NULL) {
- renderer = gcr_failure_renderer_new_unsupported (label);
- actual = FALSE;
- }
-
- /* And show the data */
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
-
- /* Let callers know we're rendering data */
- if (actual == TRUE)
- g_signal_emit (self, signals[ADDED], 0, renderer,
- gcr_parser_get_parsed (parser));
-
- g_object_unref (renderer);
-}
-
-static gboolean
-on_parser_authenticate_for_unlock (GcrParser *parser,
- guint count,
- gpointer user_data)
-{
- GcrUnlockRenderer *unlock = GCR_UNLOCK_RENDERER (user_data);
- const gchar *password;
-
- if (count == 0) {
- password = _gcr_unlock_renderer_get_password (unlock);
- gcr_parser_add_password (parser, password);
- }
-
- return TRUE;
-}
-
-static void
-on_unlock_renderer_clicked (GcrUnlockRenderer *unlock,
- gpointer user_data)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
- GError *error = NULL;
- gconstpointer data;
- gsize n_data;
- gulong sig;
-
- /* Override our main authenticate signal handler */
- sig = g_signal_connect (self->pv->parser, "authenticate",
- G_CALLBACK (on_parser_authenticate_for_unlock), unlock);
-
- data = _gcr_unlock_renderer_get_locked_data (unlock, &n_data);
- if (gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
-
- /* Done with this unlock renderer */
- gcr_viewer_remove_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
- self->pv->unlocks = g_list_remove (self->pv->unlocks, unlock);
- g_object_unref (unlock);
-
- } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)){
- _gcr_unlock_renderer_show_warning (unlock, _("The password was incorrect"));
- g_error_free (error);
-
- } else {
- _gcr_unlock_renderer_show_warning (unlock, error->message);
- g_error_free (error);
- }
-
- g_signal_handler_disconnect (self->pv->parser, sig);
-}
-
-static gboolean
-on_parser_authenticate_for_data (GcrParser *parser,
- guint count,
- gpointer user_data)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
- GcrUnlockRenderer *unlock;
-
- unlock = _gcr_unlock_renderer_new_for_parsed (parser);
- if (unlock != NULL) {
- g_object_set (unlock, "label", get_parsed_label_or_display_name (self, parser), NULL);
- gcr_viewer_add_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
- g_signal_connect (unlock, "unlock-clicked", G_CALLBACK (on_unlock_renderer_clicked), self);
- self->pv->unlocks = g_list_prepend (self->pv->unlocks, unlock);
- }
-
- return TRUE;
-}
-
-static void
-gcr_viewer_widget_init (GcrViewerWidget *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_VIEWER_WIDGET,
- GcrViewerWidgetPrivate);
-
- self->pv->files_to_load = g_queue_new ();
- self->pv->parser = gcr_parser_new ();
- self->pv->cancellable = g_cancellable_new ();
- self->pv->unlocks = NULL;
-
- g_signal_connect (self->pv->parser, "parsed", G_CALLBACK (on_parser_parsed), self);
- g_signal_connect_after (self->pv->parser, "authenticate", G_CALLBACK (on_parser_authenticate_for_data), self);
-}
-
-static void
-gcr_viewer_widget_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (obj);
-
- switch (prop_id) {
- case PROP_PARSER:
- g_value_set_object (value, gcr_viewer_widget_get_parser (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gcr_viewer_widget_dispose (GObject *obj)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (obj);
- GList *l;
-
- g_signal_handlers_disconnect_by_func (self->pv->parser, on_parser_parsed, self);
-
- for (l = self->pv->unlocks; l != NULL; l = g_list_next (l)) {
- g_signal_handlers_disconnect_by_func (l->data, on_unlock_renderer_clicked, self);
- g_object_unref (l->data);
- }
- g_list_free (self->pv->unlocks);
- self->pv->unlocks = NULL;
-
- while (!g_queue_is_empty (self->pv->files_to_load))
- g_object_unref (g_queue_pop_head (self->pv->files_to_load));
-
- g_cancellable_cancel (self->pv->cancellable);
-
- G_OBJECT_CLASS (gcr_viewer_widget_parent_class)->dispose (obj);
-}
-
-static void
-gcr_viewer_widget_finalize (GObject *obj)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (obj);
-
- g_assert (g_queue_is_empty (self->pv->files_to_load));
- g_queue_free (self->pv->files_to_load);
-
- g_free (self->pv->display_name);
- g_object_unref (self->pv->cancellable);
- g_object_unref (self->pv->parser);
-
- G_OBJECT_CLASS (gcr_viewer_widget_parent_class)->finalize (obj);
-}
-
-static void
-gcr_viewer_widget_class_init (GcrViewerWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->dispose = gcr_viewer_widget_dispose;
- gobject_class->finalize = gcr_viewer_widget_finalize;
- gobject_class->get_property = gcr_viewer_widget_get_property;
-
- /**
- * GcrViewerWidget:parser:
- *
- * The parser used to parse loaded data into viewable items.
- */
- g_object_class_install_property (gobject_class, PROP_PARSER,
- g_param_spec_object ("parser", "Parser", "Parser used to parse viewable items",
- GCR_TYPE_PARSER, G_PARAM_READABLE));
-
- g_type_class_add_private (klass, sizeof (GcrViewerWidget));
-
- /**
- * GcrViewerWidget::added:
- * @self: the viewer widget
- * @renderer: (type Gcr.Renderer): the renderer that was added
- * @parsed: (type Gcr.Parsed): the parsed item that was added
- *
- * This signal is emitted when an item is added to the viewer widget.
- */
- signals[ADDED] = g_signal_new ("added", GCR_TYPE_VIEWER_WIDGET, G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcrViewerWidgetClass, added),
- NULL, NULL, _gcr_marshal_VOID__OBJECT_BOXED,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, GCR_TYPE_PARSED);
-}
-
-static void
-on_parser_parse_stream_returned (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
- GError *error = NULL;
- GcrRenderer *renderer;
-
- gcr_parser_parse_stream_finish (self->pv->parser, result, &error);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
- g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_CANCELLED)) {
- viewer_stop_loading_files (self);
-
- } else if (g_error_matches (error, GCR_DATA_ERROR, GCR_ERROR_LOCKED)) {
- /* Just skip this one, an unlock renderer was added */
-
- } else if (error) {
- renderer = gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
- g_object_unref (renderer);
- g_error_free (error);
- }
-
- viewer_load_next_file (self);
-}
-
-static void
-update_display_name (GcrViewerWidget *self,
- GFile *file)
-{
- gchar *basename;
-
- basename = g_file_get_basename (file);
-
- g_free (self->pv->display_name);
- self->pv->display_name = g_filename_display_name (basename);
-
- g_free (basename);
-}
-
-static void
-on_file_read_returned (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GcrViewerWidget *self = GCR_VIEWER_WIDGET (user_data);
- GFile *file = G_FILE (source);
- GError *error = NULL;
- GFileInputStream *fis;
- GcrRenderer *renderer;
-
- fis = g_file_read_finish (file, result, &error);
- update_display_name (self, file);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- viewer_stop_loading_files (self);
-
- } else if (error) {
- renderer = gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
- g_object_unref (renderer);
- g_error_free (error);
-
- viewer_load_next_file (self);
-
- } else {
- gcr_parser_parse_stream_async (self->pv->parser, G_INPUT_STREAM (fis),
- self->pv->cancellable, on_parser_parse_stream_returned,
- self);
- g_object_unref (fis);
- }
-}
-
-static void
-viewer_stop_loading_files (GcrViewerWidget *self)
-{
- self->pv->loading = FALSE;
-}
-
-static void
-viewer_load_next_file (GcrViewerWidget *self)
-{
- GFile* file;
-
- file = g_queue_pop_head (self->pv->files_to_load);
- if (file == NULL) {
- viewer_stop_loading_files (self);
- return;
- }
-
- g_file_read_async (file, G_PRIORITY_DEFAULT, self->pv->cancellable,
- on_file_read_returned, self);
-
- g_object_unref (file);
-}
-
-/**
- * gcr_viewer_widget_new:
- *
- * Create a new viewer widget.
- *
- * Returns: (transfer full): A new #GcrViewerWidget object
- */
-GcrViewerWidget *
-gcr_viewer_widget_new (void)
-{
- return g_object_new (GCR_TYPE_VIEWER_WIDGET, NULL);
-}
-
-/**
- * gcr_viewer_widget_load_file:
- * @self: a viewer widget
- * @file: a file to load
- *
- * Display contents of a file in the viewer widget. Multiple files can
- * be loaded.
- */
-void
-gcr_viewer_widget_load_file (GcrViewerWidget *self,
- GFile *file)
-{
- g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
- g_return_if_fail (G_IS_FILE (file));
-
- g_queue_push_tail (self->pv->files_to_load, g_object_ref (file));
-
- if (!self->pv->loading)
- viewer_load_next_file (self);
-}
-
-/**
- * gcr_viewer_widget_load_data:
- * @self: a viewer widget
- * @display_name: (allow-none): label for the loaded data
- * @data: (array length=n_data): data to load
- * @n_data: length of data to load
- *
- * Parse and load some data to be displayed into the viewer widgets. The data
- * may contain multiple parseable items if the format can contain multiple
- * items.
- */
-void
-gcr_viewer_widget_load_data (GcrViewerWidget *self,
- const gchar *display_name,
- const guchar *data,
- gsize n_data)
-{
- GError *error = NULL;
- GcrRenderer *renderer;
-
- g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
-
- g_free (self->pv->display_name);
- self->pv->display_name = g_strdup (display_name);
-
- if (!gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
- renderer = gcr_failure_renderer_new (display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
- g_object_unref (renderer);
- g_error_free (error);
- }
-}
-
-/**
- * gcr_viewer_widget_get_parser:
- * @self: a viewer widget
- *
- * Get the parser used to parse loaded data into viewable items.
- *
- * Returns: (transfer none): the parser
- */
-GcrParser *
-gcr_viewer_widget_get_parser (GcrViewerWidget *self)
-{
- g_return_val_if_fail (GCR_IS_VIEWER_WIDGET (self), NULL);
- return self->pv->parser;
-}
diff --git a/gcr/gcr-viewer-widget.h b/gcr/gcr-viewer-widget.h
deleted file mode 100644
index 3e1e17e7..00000000
--- a/gcr/gcr-viewer-widget.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gcr-viewer-widget.h: Widget for viewer
-
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#ifndef GCR_VIEWER_WIDGET_H
-#define GCR_VIEWER_WIDGET_H
-
-#include <gtk/gtk.h>
-
-#define GCR_TYPE_VIEWER_WIDGET (gcr_viewer_widget_get_type ())
-#define GCR_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidget))
-#define GCR_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
-#define GCR_IS_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER_WIDGET))
-#define GCR_IS_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_VIEWER_WIDGET))
-#define GCR_VIEWER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
-
-typedef struct _GcrViewerWidget GcrViewerWidget;
-typedef struct _GcrViewerWidgetClass GcrViewerWidgetClass;
-typedef struct _GcrViewerWidgetPrivate GcrViewerWidgetPrivate;
-
-
-GType gcr_viewer_widget_get_type (void);
-
-GcrViewerWidget * gcr_viewer_widget_new (void);
-
-void gcr_viewer_widget_load_file (GcrViewerWidget *self,
- GFile *file);
-
-void gcr_viewer_widget_load_data (GcrViewerWidget *self,
- const gchar *display_name,
- const guchar *data,
- gsize n_data);
-
-GcrParser * gcr_viewer_widget_get_parser (GcrViewerWidget *self);
-
-#endif /* GCR_VIEWER_WIDGET_H */
diff --git a/gcr/gcr-viewer-window.c b/gcr/gcr-viewer-window.c
deleted file mode 100644
index c604d18d..00000000
--- a/gcr/gcr-viewer-window.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gcr-viewer-window.c: Window for viewer
-
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr-viewer-window.h"
-
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-
-#include <locale.h>
-#include <string.h>
-
-struct _GcrViewerWindowPrivate {
- GcrViewerWidget *viewer;
- GcrImportButton *import;
-};
-
-G_DEFINE_TYPE (GcrViewerWindow, gcr_viewer_window, GTK_TYPE_WINDOW);
-
-static void
-on_viewer_renderer_added (GcrViewerWidget *viewer,
- GcrRenderer *renderer,
- GcrParsed *parsed,
- gpointer user_data)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- gcr_import_button_add_parsed (self->pv->import, parsed);
-}
-
-static void
-gcr_viewer_window_init (GcrViewerWindow *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_VIEWER_WINDOW,
- GcrViewerWindowPrivate);
-}
-
-static void
-on_import_button_imported (GcrImportButton *button,
- GcrImporter *importer,
- GError *error,
- gpointer user_data)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- GcrRenderer *renderer;
-
- if (error == NULL) {
- g_object_set (button, "label", _("Imported"), NULL);
-
- } else {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- renderer = gcr_failure_renderer_new (_("Import failed"), error);
- gcr_viewer_add_renderer (GCR_VIEWER (self->pv->viewer), renderer);
- g_object_unref (renderer);
- }
- }
-}
-
-static void
-on_close_clicked (GtkButton *button,
- gpointer user_data)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- gtk_widget_destroy (GTK_WIDGET (self));
-}
-
-static void
-gcr_viewer_window_constructed (GObject *obj)
-{
- GcrViewerWindow *self = GCR_VIEWER_WINDOW (obj);
- GtkWidget *bbox;
- GtkWidget *box;
- GtkWidget *button;
- GtkWidget *align;
-
- G_OBJECT_CLASS (gcr_viewer_window_parent_class)->constructed (obj);
-
- bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_set_spacing (GTK_BOX (bbox), 12);
- gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
- gtk_widget_show (bbox);
-
- self->pv->import = gcr_import_button_new (_("Import"));
- g_signal_connect_object (self->pv->import, "imported",
- G_CALLBACK (on_import_button_imported),
- self, 0);
- gtk_widget_show (GTK_WIDGET (self->pv->import));
-
- button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
- g_signal_connect_object (button, "clicked",
- G_CALLBACK (on_close_clicked),
- self, 0);
- gtk_widget_show (button);
-
- gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (bbox), GTK_WIDGET (self->pv->import), FALSE, TRUE, 0);
-
- align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 0, 12);
- gtk_widget_show (align);
- gtk_container_add (GTK_CONTAINER (align), bbox);
-
- self->pv->viewer = gcr_viewer_widget_new ();
- g_signal_connect_object (self->pv->viewer, "added",
- G_CALLBACK (on_viewer_renderer_added),
- self, 0);
- gtk_widget_show (GTK_WIDGET (self->pv->viewer));
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_widget_show (box);
-
- gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (self->pv->viewer), TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (box), align, FALSE, FALSE, 6);
-
- gtk_container_add (GTK_CONTAINER (self), box);
-
- gtk_window_set_default_size (GTK_WINDOW (self), 250, 400);
-}
-
-static void
-gcr_viewer_window_class_init (GcrViewerWindowClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->constructed = gcr_viewer_window_constructed;
-
- g_type_class_add_private (klass, sizeof (GcrViewerWindow));
-}
-
-/**
- * gcr_viewer_window_new:
- *
- * Create a new viewer window.
- *
- * Returns: (transfer full) (type Gcr.ViewerWindow): a new viewer window
- */
-GtkWindow *
-gcr_viewer_window_new (void)
-{
- return g_object_new (GCR_TYPE_VIEWER_WINDOW, NULL);
-}
-
-/**
- * gcr_viewer_window_load:
- * @self: a viewer window
- * @file: file to load
- *
- * Load a file into a viewer window. It may not appear immediately.
- */
-void
-gcr_viewer_window_load (GcrViewerWindow *self,
- GFile *file)
-{
- g_return_if_fail (GCR_IS_VIEWER_WINDOW (self));
- g_return_if_fail (G_IS_FILE (file));
-
- return gcr_viewer_widget_load_file (self->pv->viewer, file);
-}
diff --git a/gcr/gcr-viewer-window.h b/gcr/gcr-viewer-window.h
deleted file mode 100644
index 4ec24203..00000000
--- a/gcr/gcr-viewer-window.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gcr-viewer-window.h: Window for viewer
-
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#ifndef GCR_VIEWER_WINDOW_H
-#define GCR_VIEWER_WINDOW_H
-
-#include <gtk/gtk.h>
-
-#ifndef GCR_DISABLE_DEPRECATED
-
-#include "gcr/gcr.h"
-
-#define GCR_TYPE_VIEWER_WINDOW (gcr_viewer_window_get_type ())
-#define GCR_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER_WINDOW, GcrViewerWindow))
-#define GCR_VIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WINDOW, GcrViewerWindowClass))
-#define GCR_IS_VIEWER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER_WINDOW))
-#define GCR_IS_VIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_VIEWER_WINDOW))
-#define GCR_VIEWER_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_VIEWER_WINDOW, GcrViewerWindowClass))
-
-typedef struct _GcrViewerWindow GcrViewerWindow;
-typedef struct _GcrViewerWindowClass GcrViewerWindowClass;
-typedef struct _GcrViewerWindowPrivate GcrViewerWindowPrivate;
-
-struct _GcrViewerWindow {
- /*< private >*/
- GtkWindow parent;
- GcrViewerWindowPrivate *pv;
-};
-
-struct _GcrViewerWindowClass {
- /*< private >*/
- GtkWindowClass parent_class;
-};
-
-GType gcr_viewer_window_get_type (void);
-
-GtkWindow * gcr_viewer_window_new (void);
-
-void gcr_viewer_window_load (GcrViewerWindow *self,
- GFile *file);
-
-#endif /* GCR_DISABLE_DEPRECATED */
-
-#endif /* GCR_VIEWER_WINDOW_H */
diff --git a/gcr/gcr-viewer.c b/gcr/gcr-viewer.c
deleted file mode 100644
index 9cc2ceca..00000000
--- a/gcr/gcr-viewer.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2008 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gcr-display-scrolled.h"
-#include "gcr-display-view.h"
-#include "gcr-renderer.h"
-#include "gcr-viewer.h"
-
-/**
- * SECTION:gcr-viewer
- * @title: GcrViewer
- * @short_description: A viewer which can hold renderers
- *
- * A #GcrViewer is an abstract interface that represents a widget that can hold
- * various renderers and display their contents.
- *
- * The interaction between #GcrRenderer and #GcrViewer is not stable yet, and
- * so viewers cannot be implemented outside the Gcr library at this time.
- *
- * Use the gcr_viewer_new() and gcr_viewer_new_scrolled() to get default
- * implementations of viewers.
- */
-
-/**
- * GcrViewer:
- *
- * An abstract viewer which displays renderers contents.
- */
-
-/**
- * GcrViewerIface:
- * @parent: The parent interface
- * @add_renderer: Virtual method to add a renderer
- * @insert_renderer: Virtual method to insert a renderer
- * @remove_renderer: Virtual method to remove a renderer
- * @count_renderers: Virtual method to count renderers
- * @get_renderer: Virtual method to get a renderer
- *
- * The interface for #GcrViewer
- */
-
-typedef GcrViewerIface GcrViewerInterface;
-
-G_DEFINE_INTERFACE (GcrViewer, gcr_viewer, GTK_TYPE_WIDGET);
-
-static void
-gcr_viewer_default_init (GcrViewerIface *iface)
-{
-
-}
-
-/* -----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gcr_viewer_new:
- *
- * Get an implementation of #GcrViewer that supports a view
- * of multiple renderers.
- *
- * Returns: (transfer full): a newly allocated #GcrViewer, which should be
- * released with g_object_unref()
- */
-GcrViewer *
-gcr_viewer_new (void)
-{
- return GCR_VIEWER (_gcr_display_view_new ());
-}
-
-/**
- * gcr_viewer_new_scrolled:
- *
- * Get an implementation of #GcrViewer that supports a scrolled view
- * of multiple renderers.
- *
- * Returns: (transfer full): a newly allocated #GcrViewer, which should be
- * released with g_object_unref()
- */
-GcrViewer*
-gcr_viewer_new_scrolled (void)
-{
- return GCR_VIEWER (_gcr_display_scrolled_new ());
-}
-
-/**
- * gcr_viewer_add_renderer:
- * @viewer: The viewer
- * @renderer: The renderer to add
- *
- * Add a renderer to this viewer.
- */
-void
-gcr_viewer_add_renderer (GcrViewer *viewer,
- GcrRenderer *renderer)
-{
- g_return_if_fail (GCR_IS_VIEWER (viewer));
- g_return_if_fail (GCR_IS_RENDERER (renderer));
- g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->add_renderer);
- GCR_VIEWER_GET_INTERFACE (viewer)->add_renderer (viewer, renderer);
-}
-
-/**
- * gcr_viewer_insert_renderer:
- * @viewer: the viewer
- * @renderer: the renderer to insert
- * @before: (allow-none): the renderer to insert before
- *
- * Insert a renderer at a specific point in the viewer
- */
-void
-gcr_viewer_insert_renderer (GcrViewer *viewer,
- GcrRenderer *renderer,
- GcrRenderer *before)
-{
- g_return_if_fail (GCR_IS_VIEWER (viewer));
- g_return_if_fail (GCR_IS_RENDERER (renderer));
- g_return_if_fail (!before || GCR_IS_RENDERER (before));
- g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->insert_renderer);
- GCR_VIEWER_GET_INTERFACE (viewer)->insert_renderer (viewer, renderer, before);
-}
-
-/**
- * gcr_viewer_remove_renderer:
- * @viewer: The viewer
- * @renderer: The renderer to remove
- *
- * Remove a renderer from this viewer.
- */
-void
-gcr_viewer_remove_renderer (GcrViewer *viewer,
- GcrRenderer *renderer)
-{
- g_return_if_fail (GCR_IS_VIEWER (viewer));
- g_return_if_fail (GCR_IS_RENDERER (renderer));
- g_return_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->remove_renderer);
- GCR_VIEWER_GET_INTERFACE (viewer)->remove_renderer (viewer, renderer);
-}
-
-/**
- * gcr_viewer_count_renderers:
- * @viewer: The viewer
- *
- * Get the number of renderers present in the viewer.
- *
- * Returns: The number of renderers.
- */
-guint
-gcr_viewer_count_renderers (GcrViewer *viewer)
-{
- g_return_val_if_fail (GCR_IS_VIEWER (viewer), 0);
- g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->count_renderers, 0);
- return GCR_VIEWER_GET_INTERFACE (viewer)->count_renderers (viewer);
-}
-
-/**
- * gcr_viewer_get_renderer:
- * @viewer: The viewer
- * @index_: The index of the renderer to get
- *
- * Get a pointer to the renderer at the given index. It is an error to request
- * an index that is out of bounds.
- *
- * Returns: (transfer none): the render, owned by the viewer
- */
-GcrRenderer*
-gcr_viewer_get_renderer (GcrViewer *viewer,
- guint index_)
-{
- g_return_val_if_fail (GCR_IS_VIEWER (viewer), NULL);
- g_return_val_if_fail (GCR_VIEWER_GET_INTERFACE (viewer)->get_renderer, NULL);
- return GCR_VIEWER_GET_INTERFACE (viewer)->get_renderer (viewer, index_);
-}
diff --git a/gcr/gcr-viewer.desktop.in.in b/gcr/gcr-viewer.desktop.in.in
deleted file mode 100644
index 6cd913a1..00000000
--- a/gcr/gcr-viewer.desktop.in.in
+++ /dev/null
@@ -1,10 +0,0 @@
-[Desktop Entry]
-Name=View file
-MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;
-Exec=gcr-viewer
-Type=Application
-Terminal=false
-NoDisplay=true
-X-GNOME-Bugzilla-Bugzilla=GNOME
-X-GNOME-Bugzilla-Product=gnome-keyring
-X-GNOME-Bugzilla-Component=gcr \ No newline at end of file
diff --git a/gcr/gcr-viewer.h b/gcr/gcr-viewer.h
deleted file mode 100644
index b806cdae..00000000
--- a/gcr/gcr-viewer.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2010 Stefan Walter
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef __GCR_VIEWER_H__
-#define __GCR_VIEWER_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gcr-types.h"
-
-G_BEGIN_DECLS
-
-#define GCR_TYPE_VIEWER (gcr_viewer_get_type())
-#define GCR_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER, GcrViewer))
-#define GCR_IS_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER))
-#define GCR_VIEWER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GCR_TYPE_VIEWER, GcrViewerIface))
-
-typedef struct _GcrRenderer GcrRenderer;
-typedef struct _GcrViewer GcrViewer;
-typedef struct _GcrViewerIface GcrViewerIface;
-
-struct _GcrViewerIface {
- GTypeInterface parent;
-
- void (*add_renderer) (GcrViewer *viewer,
- GcrRenderer *renderer);
-
- void (*insert_renderer) (GcrViewer *viewer,
- GcrRenderer *renderer,
- GcrRenderer *before);
-
- void (*remove_renderer) (GcrViewer *viewer,
- GcrRenderer *renderer);
-
- guint (*count_renderers) (GcrViewer *viewer);
-
- GcrRenderer* (*get_renderer) (GcrViewer *viewer,
- guint index_);
-
- /*< private >*/
- gpointer dummy1;
- gpointer dummy2;
- gpointer dummy3;
- gpointer dummy4;
-};
-
-GType gcr_viewer_get_type (void);
-
-GcrViewer* gcr_viewer_new (void);
-
-GcrViewer* gcr_viewer_new_scrolled (void);
-
-void gcr_viewer_add_renderer (GcrViewer *viewer,
- GcrRenderer *renderer);
-
-void gcr_viewer_insert_renderer (GcrViewer *viewer,
- GcrRenderer *renderer,
- GcrRenderer *before);
-
-void gcr_viewer_remove_renderer (GcrViewer *viewer,
- GcrRenderer *renderer);
-
-guint gcr_viewer_count_renderers (GcrViewer *viewer);
-
-GcrRenderer* gcr_viewer_get_renderer (GcrViewer *viewer,
- guint index_);
-
-G_END_DECLS
-
-#endif /* __GCR_VIEWER_H__ */
diff --git a/gcr/gcr.h b/gcr/gcr.h
deleted file mode 100644
index ec150a94..00000000
--- a/gcr/gcr.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#ifndef GCR_API_SUBJECT_TO_CHANGE
-#error "This API has not yet reached stability."
-#endif
-
-#ifndef __GCR_H__
-#define __GCR_H__
-
-#include <glib.h>
-
-#include "gcr-base.h"
-
-#define __GCR_INSIDE_HEADER__
-
-#include "gcr-certificate-renderer.h"
-#include "gcr-certificate-widget.h"
-#include "gcr-collection-model.h"
-#include "gcr-column.h"
-#include "gcr-combo-selector.h"
-#include "gcr-deprecated.h"
-#include "gcr-key-renderer.h"
-#include "gcr-key-widget.h"
-#include "gcr-enum-types.h"
-#include "gcr-failure-renderer.h"
-#include "gcr-key-renderer.h"
-#include "gcr-key-widget.h"
-#include "gcr-import-button.h"
-#include "gcr-list-selector.h"
-#include "gcr-renderer.h"
-#include "gcr-tree-selector.h"
-#include "gcr-union-collection.h"
-#include "gcr-unlock-options-widget.h"
-#include "gcr-viewer.h"
-#include "gcr-viewer-widget.h"
-
-#undef __GCR_INSIDE_HEADER__
-
-#endif /* __GCR_H__ */
diff --git a/gcr/gcr.pc.in b/gcr/gcr.pc.in
deleted file mode 100644
index 47f89358..00000000
--- a/gcr/gcr.pc.in
+++ /dev/null
@@ -1,16 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-sysconfdir=@sysconfdir@
-pkcs11dir=@P11_MODULE_PATH@
-pkcs11standalonedir=@pkcs11standalonedir@
-
-Name: gcr-@GCR_MAJOR@
-Description: GObject and GUI library for high level crypto parsing and display
-Version: @VERSION@
-Requires: glib-2.0 gtk+-3.0 gcr-base-@GCR_MAJOR@ gck-@GCK_MAJOR@ p11-kit-1
-Libs: -L${libdir} -lgcr-@GCR_MAJOR@
-Cflags: -I${includedir}/gcr-@GCR_MAJOR@
diff --git a/gcr/gcr.symbols b/gcr/gcr.symbols
deleted file mode 100644
index 4cb927e1..00000000
--- a/gcr/gcr.symbols
+++ /dev/null
@@ -1,103 +0,0 @@
-/* This file lists all exported symbols. It is used to guarantee that we
- * only consciously change our ABI.
- */
-
-gcr_certificate_basics_widget_get_certificate
-gcr_certificate_basics_widget_get_type
-gcr_certificate_basics_widget_new
-gcr_certificate_basics_widget_set_certificate
-gcr_certificate_details_widget_get_certificate
-gcr_certificate_details_widget_get_type
-gcr_certificate_details_widget_new
-gcr_certificate_details_widget_set_certificate
-gcr_certificate_renderer_get_attributes
-gcr_certificate_renderer_get_certificate
-gcr_certificate_renderer_get_type
-gcr_certificate_renderer_new
-gcr_certificate_renderer_new_for_attributes
-gcr_certificate_renderer_set_attributes
-gcr_certificate_renderer_set_certificate
-gcr_certificate_widget_get_attributes
-gcr_certificate_widget_get_certificate
-gcr_certificate_widget_get_type
-gcr_certificate_widget_new
-gcr_certificate_widget_set_attributes
-gcr_certificate_widget_set_certificate
-gcr_collection_model_change_selected
-gcr_collection_model_column_for_selected
-gcr_collection_model_get_collection
-gcr_collection_model_get_selected_objects
-gcr_collection_model_get_type
-gcr_collection_model_is_selected
-gcr_collection_model_iter_for_object
-gcr_collection_model_new
-gcr_collection_model_new_full
-gcr_collection_model_object_for_iter
-gcr_collection_model_set_columns
-gcr_collection_model_set_selected_objects
-gcr_collection_model_toggle_selected
-gcr_column_flags_get_type
-gcr_combo_selector_get_collection
-gcr_combo_selector_get_selected
-gcr_combo_selector_get_type
-gcr_combo_selector_new
-gcr_combo_selector_set_selected
-gcr_failure_renderer_get_type
-gcr_failure_renderer_new
-gcr_failure_renderer_new_unsupported
-gcr_import_button_add_parsed
-gcr_import_button_get_type
-gcr_import_button_new
-gcr_key_renderer_get_attributes
-gcr_key_renderer_get_type
-gcr_key_renderer_new
-gcr_key_renderer_set_attributes
-gcr_key_widget_get_attributes
-gcr_key_widget_get_type
-gcr_key_widget_new
-gcr_key_widget_set_attributes
-gcr_list_selector_get_collection
-gcr_list_selector_get_selected
-gcr_list_selector_get_type
-gcr_list_selector_new
-gcr_list_selector_set_selected
-gcr_renderer_create
-gcr_renderer_emit_data_changed
-gcr_renderer_get_type
-gcr_renderer_popuplate_popup
-gcr_renderer_register
-gcr_renderer_register_well_known
-gcr_renderer_render
-gcr_renderer_render_view
-gcr_tree_selector_get_collection
-gcr_tree_selector_get_columns
-gcr_tree_selector_get_selected
-gcr_tree_selector_get_type
-gcr_tree_selector_new
-gcr_tree_selector_set_selected
-gcr_unlock_options_widget_get_choice
-gcr_unlock_options_widget_get_label
-gcr_unlock_options_widget_get_sensitive
-gcr_unlock_options_widget_get_ttl
-gcr_unlock_options_widget_get_type
-gcr_unlock_options_widget_new
-gcr_unlock_options_widget_set_choice
-gcr_unlock_options_widget_set_label
-gcr_unlock_options_widget_set_sensitive
-gcr_unlock_options_widget_set_ttl
-gcr_viewer_add_renderer
-gcr_viewer_insert_renderer
-gcr_viewer_count_renderers
-gcr_viewer_get_renderer
-gcr_viewer_get_type
-gcr_viewer_new
-gcr_viewer_new_scrolled
-gcr_viewer_remove_renderer
-gcr_viewer_window_get_type
-gcr_viewer_window_load
-gcr_viewer_window_new
-gcr_viewer_widget_get_parser
-gcr_viewer_widget_get_type
-gcr_viewer_widget_load_data
-gcr_viewer_widget_load_file
-gcr_viewer_widget_new
diff --git a/gcr/icons/16x16/Makefile.am b/gcr/icons/16x16/Makefile.am
deleted file mode 100644
index ab9cd709..00000000
--- a/gcr/icons/16x16/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/16x16/apps
-icon_DATA = \
- gcr-key.png \
- gcr-key-pair.png \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/16x16/gcr-key-pair.png b/gcr/icons/16x16/gcr-key-pair.png
deleted file mode 100644
index 01df7686..00000000
--- a/gcr/icons/16x16/gcr-key-pair.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/16x16/gcr-key.png b/gcr/icons/16x16/gcr-key.png
deleted file mode 100644
index fd056b71..00000000
--- a/gcr/icons/16x16/gcr-key.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/16x16/gcr-smart-card.png b/gcr/icons/16x16/gcr-smart-card.png
deleted file mode 100644
index 2860eb44..00000000
--- a/gcr/icons/16x16/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/22x22/Makefile.am b/gcr/icons/22x22/Makefile.am
deleted file mode 100644
index a4d1ba84..00000000
--- a/gcr/icons/22x22/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/22x22/apps
-icon_DATA = \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/22x22/gcr-smart-card.png b/gcr/icons/22x22/gcr-smart-card.png
deleted file mode 100644
index 65cbcf89..00000000
--- a/gcr/icons/22x22/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/24x24/Makefile.am b/gcr/icons/24x24/Makefile.am
deleted file mode 100644
index 87c90ad1..00000000
--- a/gcr/icons/24x24/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/24x24/apps
-icon_DATA = \
- gcr-key.png \
- gcr-key-pair.png \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/24x24/gcr-key-pair.png b/gcr/icons/24x24/gcr-key-pair.png
deleted file mode 100644
index 8ebe2f78..00000000
--- a/gcr/icons/24x24/gcr-key-pair.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/24x24/gcr-key.png b/gcr/icons/24x24/gcr-key.png
deleted file mode 100644
index 441737c0..00000000
--- a/gcr/icons/24x24/gcr-key.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/24x24/gcr-smart-card.png b/gcr/icons/24x24/gcr-smart-card.png
deleted file mode 100644
index 833a811e..00000000
--- a/gcr/icons/24x24/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/256x256/Makefile.am b/gcr/icons/256x256/Makefile.am
deleted file mode 100644
index ee3525ed..00000000
--- a/gcr/icons/256x256/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/256x256/apps
-icon_DATA = \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/256x256/gcr-smart-card.png b/gcr/icons/256x256/gcr-smart-card.png
deleted file mode 100644
index 156933e1..00000000
--- a/gcr/icons/256x256/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/32x32/Makefile.am b/gcr/icons/32x32/Makefile.am
deleted file mode 100644
index d19b370b..00000000
--- a/gcr/icons/32x32/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/32x32/apps
-icon_DATA = \
- gcr-key.png \
- gcr-key-pair.png \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/32x32/gcr-key-pair.png b/gcr/icons/32x32/gcr-key-pair.png
deleted file mode 100644
index e8c5dc2c..00000000
--- a/gcr/icons/32x32/gcr-key-pair.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/32x32/gcr-key.png b/gcr/icons/32x32/gcr-key.png
deleted file mode 100644
index 29806e8e..00000000
--- a/gcr/icons/32x32/gcr-key.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/32x32/gcr-smart-card.png b/gcr/icons/32x32/gcr-smart-card.png
deleted file mode 100644
index b4eaa92d..00000000
--- a/gcr/icons/32x32/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/48x48/Makefile.am b/gcr/icons/48x48/Makefile.am
deleted file mode 100644
index bbfbc075..00000000
--- a/gcr/icons/48x48/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-NULL =
-
-icondir = $(datadir)/icons/hicolor/48x48/apps
-icon_DATA = \
- gcr-key.png \
- gcr-key-pair.png \
- gcr-smart-card.png \
- $(NULL)
-
-EXTRA_DIST = \
- $(icon_DATA)
diff --git a/gcr/icons/48x48/gcr-key-pair.png b/gcr/icons/48x48/gcr-key-pair.png
deleted file mode 100644
index 7b623d2f..00000000
--- a/gcr/icons/48x48/gcr-key-pair.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/48x48/gcr-key.png b/gcr/icons/48x48/gcr-key.png
deleted file mode 100644
index c4ca3557..00000000
--- a/gcr/icons/48x48/gcr-key.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/48x48/gcr-smart-card.png b/gcr/icons/48x48/gcr-smart-card.png
deleted file mode 100644
index 18f139b1..00000000
--- a/gcr/icons/48x48/gcr-smart-card.png
+++ /dev/null
Binary files differ
diff --git a/gcr/icons/Makefile.am b/gcr/icons/Makefile.am
deleted file mode 100644
index cdc16c52..00000000
--- a/gcr/icons/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-
-SUBDIRS = 16x16 22x22 24x24 32x32 48x48 256x256
-
-EXTRA_DIST = \
- src \
- render-icons.py
-
-gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
-
-install-data-hook:
- @-if test -z "$(DESTDIR)"; then \
- echo "Updating Gtk icon cache."; \
- $(gtk_update_icon_cache); \
- else \
- echo "*** Icon cache not updated. After install, run this:"; \
- echo "*** $(gtk_update_icon_cache)"; \
- fi
-
-render:
- python render-icons.py
diff --git a/gcr/icons/key-and-keypair.svg b/gcr/icons/key-and-keypair.svg
deleted file mode 100644
index 9fc45b12..00000000
--- a/gcr/icons/key-and-keypair.svg
+++ /dev/null
@@ -1,3921 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- inkscape:export-ydpi="90.000000"
- inkscape:export-xdpi="90.000000"
- inkscape:export-filename="/home/lapo/firewall.png"
- width="400"
- height="300"
- id="svg11300"
- sodipodi:version="0.32"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="seahorse.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- version="1.0"
- style="display:inline;enable-background:new">
- <title
- id="title4872">Firewall</title>
- <sodipodi:namedview
- stroke="#ef2929"
- fill="#f57900"
- id="base"
- pagecolor="#474747"
- bordercolor="#666666"
- borderopacity="0.25490196"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:zoom="4"
- inkscape:cx="344.14948"
- inkscape:cy="153.42666"
- inkscape:current-layer="layer4"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:showpageshadow="false"
- inkscape:window-width="1343"
- inkscape:window-height="967"
- inkscape:window-x="1615"
- inkscape:window-y="52"
- width="400px"
- height="300px"
- inkscape:snap-nodes="false"
- inkscape:snap-bbox="true"
- gridtolerance="10000"
- inkscape:object-nodes="true"
- inkscape:snap-grids="true"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-maximized="0"
- inkscape:snap-global="true">
- <inkscape:grid
- spacingy="1px"
- spacingx="1px"
- id="grid5883"
- type="xygrid"
- enabled="true"
- visible="true"
- empspacing="4"
- snapvisiblegridlinesonly="true" />
- <inkscape:grid
- type="xygrid"
- id="grid11592"
- empspacing="2"
- visible="true"
- enabled="false"
- spacingx="0.5px"
- spacingy="0.5px"
- color="#ff0000"
- opacity="0.1254902"
- empcolor="#ff0000"
- empopacity="0.25098039"
- snapvisiblegridlinesonly="true" />
- <sodipodi:guide
- orientation="-0.70710678,0.70710678"
- position="309.8125,173.625"
- id="guide9630" />
- <sodipodi:guide
- orientation="1,0"
- position="299.99005,217.08178"
- id="guide5162" />
- <sodipodi:guide
- orientation="0,1"
- position="301,232"
- id="guide5182" />
- <sodipodi:guide
- orientation="0,1"
- position="305,165"
- id="guide5184" />
- <sodipodi:guide
- orientation="0,1"
- position="303,114"
- id="guide5186" />
- <sodipodi:guide
- orientation="0,1"
- position="306,81"
- id="guide5188" />
- </sodipodi:namedview>
- <defs
- id="defs3">
- <linearGradient
- inkscape:collect="always"
- id="linearGradient8002">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop8004" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop8006" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient7994">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop7996" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop7998" />
- </linearGradient>
- <linearGradient
- id="linearGradient7419"
- inkscape:collect="always">
- <stop
- id="stop7421"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop7423"
- offset="1"
- style="stop-color:#e0d684;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6249">
- <stop
- style="stop-color:#c49f00;stop-opacity:0.627451"
- offset="0"
- id="stop6251" />
- <stop
- style="stop-color:#fceca6;stop-opacity:1"
- offset="1"
- id="stop6253" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6156">
- <stop
- style="stop-color:#c4a000;stop-opacity:1;"
- offset="0"
- id="stop6158" />
- <stop
- style="stop-color:#ffe365;stop-opacity:1"
- offset="1"
- id="stop6160" />
- </linearGradient>
- <linearGradient
- id="linearGradient6107">
- <stop
- id="stop6109"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113" />
- <stop
- id="stop6111"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784" />
- </linearGradient>
- <linearGradient
- id="linearGradient17752">
- <stop
- style="stop-color:#d3d7cf;stop-opacity:1"
- offset="0"
- id="stop17754" />
- <stop
- style="stop-color:#f6f6f5;stop-opacity:1"
- offset="0.28330287"
- id="stop17756" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.33564273"
- id="stop17758" />
- <stop
- id="stop17760"
- offset="0.6530382"
- style="stop-color:#ffffff;stop-opacity:1" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="1"
- id="stop17762" />
- </linearGradient>
- <linearGradient
- id="linearGradient17498">
- <stop
- id="stop17500"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512" />
- <stop
- id="stop17514"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient14960">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop14962" />
- <stop
- style="stop-color:#d7d9d5;stop-opacity:1"
- offset="1"
- id="stop14964" />
- </linearGradient>
- <linearGradient
- id="linearGradient13770">
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0"
- id="stop13772" />
- <stop
- id="stop13780"
- offset="0.19258282"
- style="stop-color:#f2f2f1;stop-opacity:1" />
- <stop
- id="stop13774"
- offset="0.23801444"
- style="stop-color:#edeeec;stop-opacity:1" />
- <stop
- id="stop13776"
- offset="0.27069226"
- style="stop-color:#dcdeda;stop-opacity:1;" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="1"
- id="stop13778" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4262">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop4264" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop4266" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4203">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop4205" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop4207" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient12494">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop12496" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop12498" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient11491">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop11493" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop11495" />
- </linearGradient>
- <pattern
- inkscape:stockid="Sand (bitmap)"
- id="sand_bitmap"
- height="256"
- width="256"
- patternUnits="userSpaceOnUse">
- <!-- Seamless texture provided by FreeSeamlessTextures.com -->
- <!-- License: creative commons attribution -->
- <image
- xlink:href="data:image/jpeg;base64,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 /p1//9k= "
- y="0"
- x="0"
- id="image9"
- height="260"
- width="260" />
- </pattern>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3916">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3918" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3920" />
- </linearGradient>
- <linearGradient
- id="linearGradient3894">
- <stop
- style="stop-color:#b7beb0;stop-opacity:1"
- offset="0"
- id="stop3896" />
- <stop
- id="stop3898"
- offset="0.15504535"
- style="stop-color:#f9f9f9;stop-opacity:1" />
- <stop
- style="stop-color:#f9f9f8;stop-opacity:1"
- offset="0.2005571"
- id="stop3900" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.37639078"
- id="stop3906" />
- <stop
- id="stop3908"
- offset="0.50482041"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.66817862"
- id="stop3910" />
- <stop
- style="stop-color:#eeeeec;stop-opacity:1"
- offset="1"
- id="stop3912" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3859">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3861" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3863" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3831">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop3833" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop3835" />
- </linearGradient>
- <linearGradient
- id="linearGradient6219">
- <stop
- id="stop6221"
- offset="0"
- style="stop-color:#b7beb0;stop-opacity:1" />
- <stop
- style="stop-color:#f9f9f9;stop-opacity:1"
- offset="0.05144871"
- id="stop6227" />
- <stop
- id="stop6229"
- offset="0.09541478"
- style="stop-color:#e7e7e4;stop-opacity:1" />
- <stop
- style="stop-color:#fafafa;stop-opacity:1"
- offset="0.12829006"
- id="stop6231" />
- <stop
- id="stop6417"
- offset="0.16864988"
- style="stop-color:#ffffff;stop-opacity:1" />
- <stop
- id="stop6233"
- offset="0.3383725"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.46680215"
- id="stop6235" />
- <stop
- id="stop6832"
- offset="0.66817862"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop6223"
- offset="1"
- style="stop-color:#eeeeec;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- gradientTransform="matrix(1,0,0,1.0793362,-124.58426,148.9484)"
- y2="-18.526932"
- x2="142.09839"
- y1="-138.38556"
- x1="142.09839"
- gradientUnits="userSpaceOnUse"
- id="linearGradient9527"
- xlink:href="#linearGradient6219"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3894"
- id="linearGradient9572"
- gradientUnits="userSpaceOnUse"
- x1="77"
- y1="106"
- x2="119.61018"
- y2="266.47308"
- gradientTransform="translate(-10,-7)" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3813">
- <path
- id="path3815"
- d="m 85.46875,105.625 -1.78125,2.46875 -8.46875,15.1875 -6.375,1.0625 -2.46875,3.53125 -6.03125,0.71875 -0.6875,2.125 -4.59375,2.125 -1.78125,9.1875 4.25,6.71875 4.9375,1.0625 2.84375,4.25 -0.34375,8.84375 4.9375,3.15625 -3.1875,10.625 3.90625,3.1875 -0.71875,-1.78125 2.8125,-11.3125 1.4375,2.46875 -1.4375,9.90625 1.4375,0.71875 -11.6875,73.53125 8.84375,7.40625 2.46875,0 0,-1.75 0.8125,-0.78125 -0.625,2.53125 9.1875,-8.28125 -1.3125,-1.1875 0.09375,-0.0625 -2.0625,-2.5625 1.53125,-4.15625 5.28125,-4.25 -1.09375,-0.90625 0.21875,-0.15625 -2.09375,-2.3125 1.375,-4.5625 L 89.6875,229 88.90625,228 89,227.9375 l -2.09375,-2.84375 0.3125,-4.40625 4.125,-4.1875 -0.96875,-1.25 0.03125,-0.0312 -2.3125,-4.0938 L 94.25,204 l -0.6875,-1.46875 0.03125,-0.0312 -0.375,-0.75 -1.03125,-2.25 4.9375,-6.5625 2.84375,-10.96875 6,0.1875 1.9375,-10.78125 5.125,-3.875 2.46875,-9.90625 5.3125,-4.78125 4.59375,-0.71875 1.78125,-3.6875 3.71875,-1.0625 2.09375,-8.65625 -1.40625,-4.25 -0.21875,0 0.0312,-0.1875 -4.9375,-1.40625 L 125.75,130 l -6,-1.40625 0.34375,-3.53125 -7.0625,-3.1875 -4.9375,-13.4375 -4.25,-2.46875 -18.375,-0.34375 z m 15.90625,8.125 3.875,8.84375 -4.9375,2.8125 -13.78125,-0.34375 -1.0625,-3.53125 5.65625,-7.4375 10.25,-0.34375 z"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3837"
- x1="80.78125"
- y1="243.79688"
- x2="80"
- y2="246.60938"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3841"
- gradientUnits="userSpaceOnUse"
- x1="80.78125"
- y1="243.79688"
- x2="80"
- y2="246.60938"
- gradientTransform="translate(3.875,-12.21875)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3845"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,167.5,463.5)"
- x1="80.78125"
- y1="243.79688"
- x2="80"
- y2="246.60938" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3849"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,168.5,453.625)"
- x1="80.78125"
- y1="243.79688"
- x2="80"
- y2="246.60938" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3853"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,172.59375,442.1875)"
- x1="80.78125"
- y1="243.79688"
- x2="80"
- y2="246.60938" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3831"
- id="linearGradient3857"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,180.5625,423.65625)"
- x1="80.78125"
- y1="243.79688"
- x2="79.28125"
- y2="244.35938" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3859"
- id="linearGradient3865"
- x1="107.53125"
- y1="157.21875"
- x2="53.28125"
- y2="142.03125"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3916"
- id="linearGradient3922"
- x1="60.34375"
- y1="128.59375"
- x2="65.822327"
- y2="134.79822"
- gradientUnits="userSpaceOnUse" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6088">
- <path
- sodipodi:nodetypes="cccccccscccccccccccc"
- inkscape:connector-curvature="0"
- id="path6090"
- d="m 102.125,114.75 3.375,7.75 -4.75,3 L 67,99 95.75,46.5 161,54 l 15.75,54.5 c 0,0 -9.20083,-8.2747 -22.75,-8.5 -3.89033,-0.06469 -13.75,1.75 -13.75,1.75 l -10,13.5 13.5,-1 -6,10.75 -5.75,0.25 -12.125,2.75 0.25,-2.5 -0.75,-0.625 -6.625,-3.125 -1.75,-5.25 -5,-1.375 z"
- style="opacity:0.45614038;color:#000000;fill:#75507b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6230">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path6232"
- d="m 100.57289,62.541562 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222194 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242505 86.891873,77.175486 90.047996,70.775374 94.878999,65.820152 100.57289,62.541562 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814335 15.017289,35.518325 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899695 -1.77117,-30.814334 -15.01728,-35.518318 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:#c9c9c9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient11491"
- id="radialGradient11497"
- cx="89.221237"
- cy="158.54852"
- fx="89.221237"
- fy="158.54852"
- r="27.316811"
- gradientTransform="matrix(7.792316,-0.25732976,0.04413985,1.3366185,-614.65762,-38.072453)"
- gradientUnits="userSpaceOnUse" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath11525">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path11527"
- d="m 100.57289,62.541565 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222191 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242508 86.891873,77.175489 90.047996,70.775377 94.878999,65.820155 100.57289,62.541565 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814332 15.017289,35.518322 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899692 -1.77117,-30.814331 -15.01728,-35.518315 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0.99999982px;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3263-6"
- id="linearGradient565-7"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,0.8160225)"
- x1="-868.11768"
- y1="1159.4119"
- x2="-243.19453"
- y2="1326.8596" />
- <linearGradient
- id="linearGradient3263-6"
- inkscape:collect="always">
- <stop
- id="stop3265-8"
- offset="0"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- id="stop3267-41"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- y2="1326.8596"
- x2="-243.19453"
- y1="1159.4119"
- x1="-868.11768"
- gradientTransform="matrix(0.08620296,0.08620294,-0.08620296,0.08620294,74.48657,-3.091602)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient12312"
- xlink:href="#linearGradient3263-6"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3263-6-9"
- id="linearGradient565-7-7"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,0.8160225)"
- x1="-868.11768"
- y1="1159.4119"
- x2="-243.19453"
- y2="1326.8596" />
- <linearGradient
- id="linearGradient3263-6-9"
- inkscape:collect="always">
- <stop
- id="stop3265-8-4"
- offset="0"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- id="stop3267-41-9"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- y2="1326.8596"
- x2="-243.19453"
- y1="1159.4119"
- x1="-868.11768"
- gradientTransform="matrix(0.08620296,0.08620294,-0.08620296,0.08620294,84.986565,-15.091602)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient12312-5"
- xlink:href="#linearGradient3263-6-9"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3263-6-1"
- id="linearGradient565-7-75"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,0.8160225)"
- x1="-1726.1508"
- y1="5055.0815"
- x2="476.7652"
- y2="5321.1538" />
- <linearGradient
- id="linearGradient3263-6-1"
- inkscape:collect="always">
- <stop
- id="stop3265-8-1"
- offset="0"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- id="stop3267-41-3"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- y2="1326.8596"
- x2="-243.19453"
- y1="1159.4119"
- x1="-868.11768"
- gradientTransform="matrix(0.08620296,0.08620294,-0.08620296,0.08620294,227.41356,-13.853323)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient12312-7"
- xlink:href="#linearGradient3263-6-1"
- inkscape:collect="always" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath12461">
- <path
- sodipodi:nodetypes="ssscccccccccccccccccccss"
- inkscape:connector-curvature="0"
- id="path12463"
- d="m -52.298199,90.961216 c -14.221332,0 -25.747088,11.549034 -25.747088,25.770364 0,14.22134 11.525756,25.74709 25.747088,25.74709 3.878336,0 7.549624,-0.88545 10.848231,-2.42106 l 37.8989687,37.92225 4.51621619,0 -0.51214823,-1.2571 2.25810814,0 0.7449428,1.2571 5.8431458,-1.58301 -0.6518251,-0.65182 -1.1872527,-7.2632 -5.4939537,-5.51723 -5.2611591,0.25608 0,-6.00611 -3.7479939,-3.74799 -4.2601419,0.74494 -0.232795,-5.75003 -16.08611,-15.15493 1.583003,-1.583 0.488869,-2.00204 -2.909933,-3.30568 c 1.215993,-2.99138 1.908916,-6.25621 1.908916,-9.68426 0,-14.22133 -11.525756,-25.770364 -25.747088,-25.770364 z"
- style="fill:none;stroke:#000000;stroke-width:1.48988581;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494"
- id="linearGradient12500"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3263-6-1"
- id="linearGradient12502"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,0.8160225)"
- x1="-1726.1508"
- y1="5055.0815"
- x2="476.7652"
- y2="5321.1538" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494"
- id="linearGradient12504"
- gradientUnits="userSpaceOnUse"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3894-6"
- id="linearGradient9572-3"
- gradientUnits="userSpaceOnUse"
- x1="77"
- y1="106"
- x2="119.61018"
- y2="266.47308"
- gradientTransform="translate(-10,-7)" />
- <linearGradient
- id="linearGradient3894-6">
- <stop
- style="stop-color:#b7beb0;stop-opacity:1"
- offset="0"
- id="stop3896-3" />
- <stop
- id="stop3898-2"
- offset="0.15504535"
- style="stop-color:#f9f9f9;stop-opacity:1" />
- <stop
- style="stop-color:#f9f9f8;stop-opacity:1"
- offset="0.2005571"
- id="stop3900-3" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.37639078"
- id="stop3906-1" />
- <stop
- id="stop3908-2"
- offset="0.50482041"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.66817862"
- id="stop3910-7" />
- <stop
- style="stop-color:#eeeeec;stop-opacity:1"
- offset="1"
- id="stop3912-4" />
- </linearGradient>
- <linearGradient
- id="linearGradient3263-6-1-8">
- <stop
- id="stop3265-8-1-3"
- offset="0"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#cbcdc8;stop-opacity:1;"
- offset="0.25"
- id="stop13768" />
- <stop
- style="stop-color:#dcdeda;stop-opacity:1;"
- offset="0.5"
- id="stop13766" />
- <stop
- id="stop3267-41-3-7"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:1" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6088-5">
- <path
- sodipodi:nodetypes="cccccccscccccccccccc"
- inkscape:connector-curvature="0"
- id="path6090-7"
- d="m 102.125,114.75 3.375,7.75 -4.75,3 L 67,99 95.75,46.5 161,54 l 15.75,54.5 c 0,0 -9.20083,-8.2747 -22.75,-8.5 -3.89033,-0.06469 -13.75,1.75 -13.75,1.75 l -9.125,14.875 c 4.47535,-3.19478 8.82199,-2.60624 12.625,-2.375 l -6,10.75 -5.75,0.25 -12.125,2.75 0.25,-2.5 -0.75,-0.625 -6.625,-3.125 -1.75,-5.25 -5,-1.375 z"
- style="opacity:0.45614038;color:#000000;fill:#75507b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6230-2">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path6232-2"
- d="m 100.57289,62.541562 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222194 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242505 86.891873,77.175486 90.047996,70.775374 94.878999,65.820152 100.57289,62.541562 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814335 15.017289,35.518325 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899695 -1.77117,-30.814334 -15.01728,-35.518318 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:#c9c9c9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath11525-4">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path11527-1"
- d="m 100.57289,62.541565 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222191 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242508 86.891873,77.175489 90.047996,70.775377 94.878999,65.820155 100.57289,62.541565 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814332 15.017289,35.518322 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899692 -1.77117,-30.814331 -15.01728,-35.518315 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0.99999982px;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3859-9"
- id="linearGradient3865-1"
- x1="107.53125"
- y1="157.21875"
- x2="53.28125"
- y2="142.03125"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3859-9">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3861-3" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3863-9" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3813-9">
- <path
- id="path3815-1"
- d="m 85.46875,105.625 -1.78125,2.46875 -8.46875,15.1875 -6.375,1.0625 -2.46875,3.53125 -6.03125,0.71875 -0.6875,2.125 -4.59375,2.125 -1.78125,9.1875 4.25,6.71875 4.9375,1.0625 2.84375,4.25 -0.34375,8.84375 4.9375,3.15625 -3.1875,10.625 3.90625,3.1875 -0.71875,-1.78125 2.8125,-11.3125 1.4375,2.46875 -1.4375,9.90625 1.4375,0.71875 -11.6875,73.53125 8.84375,7.40625 2.46875,0 0,-1.75 0.8125,-0.78125 -0.625,2.53125 9.1875,-8.28125 -1.3125,-1.1875 0.09375,-0.0625 -2.0625,-2.5625 1.53125,-4.15625 5.28125,-4.25 -1.09375,-0.90625 0.21875,-0.15625 -2.09375,-2.3125 1.375,-4.5625 L 89.6875,229 88.90625,228 89,227.9375 l -2.09375,-2.84375 0.3125,-4.40625 4.125,-4.1875 -0.96875,-1.25 0.03125,-0.0312 -2.3125,-4.0938 L 94.25,204 l -0.6875,-1.46875 0.03125,-0.0312 -0.375,-0.75 -1.03125,-2.25 4.9375,-6.5625 2.84375,-10.96875 6,0.1875 1.9375,-10.78125 5.125,-3.875 2.46875,-9.90625 5.3125,-4.78125 4.59375,-0.71875 1.78125,-3.6875 3.71875,-1.0625 2.09375,-8.65625 -1.40625,-4.25 -0.21875,0 0.0312,-0.1875 -4.9375,-1.40625 L 125.75,130 l -6,-1.40625 0.34375,-3.53125 -7.0625,-3.1875 -4.9375,-13.4375 -4.25,-2.46875 -18.375,-0.34375 z m 15.90625,8.125 3.875,8.84375 -4.9375,2.8125 -13.78125,-0.34375 -1.0625,-3.53125 5.65625,-7.4375 10.25,-0.34375 z"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- id="linearGradient3894-9">
- <stop
- style="stop-color:#d3d7cf;stop-opacity:1"
- offset="0"
- id="stop3896-5" />
- <stop
- style="stop-color:#eeeeec;stop-opacity:1"
- offset="0.28330287"
- id="stop3900-6" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.33564273"
- id="stop3906-0" />
- <stop
- id="stop4160"
- offset="0.42023158"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop3908-9"
- offset="0.53767145"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.62985241"
- id="stop3910-3" />
- <stop
- id="stop4162"
- offset="0.77754474"
- style="stop-color:#ffffff;stop-opacity:1" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="1"
- id="stop3912-0" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494-4"
- id="linearGradient12500-6"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient12494-4">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop12496-8" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop12498-9" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath12461-5">
- <path
- sodipodi:nodetypes="ssscccccccccccccccccccss"
- inkscape:connector-curvature="0"
- id="path12463-1"
- d="m -52.298199,90.961216 c -14.221332,0 -25.747088,11.549034 -25.747088,25.770364 0,14.22134 11.525756,25.74709 25.747088,25.74709 3.878336,0 7.549624,-0.88545 10.848231,-2.42106 l 37.8989687,37.92225 4.51621619,0 -0.51214823,-1.2571 2.25810814,0 0.7449428,1.2571 5.8431458,-1.58301 -0.6518251,-0.65182 -1.1872527,-7.2632 -5.4939537,-5.51723 -5.2611591,0.25608 0,-6.00611 -3.7479939,-3.74799 -4.2601419,0.74494 -0.232795,-5.75003 -16.08611,-15.15493 1.583003,-1.583 0.488869,-2.00204 -2.909933,-3.30568 c 1.215993,-2.99138 1.908916,-6.25621 1.908916,-9.68426 0,-14.22133 -11.525756,-25.770364 -25.747088,-25.770364 z"
- style="fill:none;stroke:#000000;stroke-width:1.48988581;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4203"
- id="linearGradient4209"
- x1="130.10339"
- y1="146.05803"
- x2="125.68246"
- y2="147.24261"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4262"
- id="linearGradient4268"
- x1="112.8125"
- y1="153.96875"
- x2="120.875"
- y2="154.03125"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4262-2"
- id="linearGradient4268-9"
- x1="112.8125"
- y1="153.96875"
- x2="120.875"
- y2="154.03125"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4262-2">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop4264-1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop4266-5" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient13585-4">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop13587-7" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop13589-9" />
- </linearGradient>
- <linearGradient
- gradientTransform="translate(-182.43355,-157.87154)"
- y2="170.51106"
- x2="192.86339"
- y1="168.56653"
- x1="194.63113"
- gradientUnits="userSpaceOnUse"
- id="linearGradient13608"
- xlink:href="#linearGradient13585-4"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient13585-2">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop13587-8" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop13589-4" />
- </linearGradient>
- <linearGradient
- gradientTransform="translate(-182.43355,-157.87154)"
- y2="170.51106"
- x2="192.86339"
- y1="168.56653"
- x1="194.63113"
- gradientUnits="userSpaceOnUse"
- id="linearGradient13608-9"
- xlink:href="#linearGradient13585-2"
- inkscape:collect="always" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath13687">
- <path
- d="m 180,135.625 a 28.375,28.375 0 1 1 -56.75,0 28.375,28.375 0 1 1 56.75,0 z"
- sodipodi:ry="28.375"
- sodipodi:rx="28.375"
- sodipodi:cy="135.625"
- sodipodi:cx="151.625"
- id="path13689"
- style="color:#000000;fill:none;stroke:#f9f9f8;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath13687-5">
- <path
- d="m 180,135.625 a 28.375,28.375 0 1 1 -56.75,0 28.375,28.375 0 1 1 56.75,0 z"
- sodipodi:ry="28.375"
- sodipodi:rx="28.375"
- sodipodi:cy="135.625"
- sodipodi:cx="151.625"
- id="path13689-5"
- style="color:#000000;fill:none;stroke:#f9f9f8;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494-4-8"
- id="linearGradient12500-6-3"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient12494-4-8">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop12496-8-9" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop12498-9-5" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath12461-5-4">
- <path
- sodipodi:nodetypes="ssscccccccccccccccccccss"
- inkscape:connector-curvature="0"
- id="path12463-1-5"
- d="m -52.298199,90.961216 c -14.221332,0 -25.747088,11.549034 -25.747088,25.770364 0,14.22134 11.525756,25.74709 25.747088,25.74709 3.878336,0 7.549624,-0.88545 10.848231,-2.42106 l 37.8989687,37.92225 4.51621619,0 -0.51214823,-1.2571 2.25810814,0 0.7449428,1.2571 5.8431458,-1.58301 -0.6518251,-0.65182 -1.1872527,-7.2632 -5.4939537,-5.51723 -5.2611591,0.25608 0,-6.00611 -3.7479939,-3.74799 -4.2601419,0.74494 -0.232795,-5.75003 -16.08611,-15.15493 1.583003,-1.583 0.488869,-2.00204 -2.909933,-3.30568 c 1.215993,-2.99138 1.908916,-6.25621 1.908916,-9.68426 0,-14.22133 -11.525756,-25.770364 -25.747088,-25.770364 z"
- style="fill:none;stroke:#000000;stroke-width:1.48988581;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494-4-8"
- id="linearGradient12504-5-4"
- gradientUnits="userSpaceOnUse"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494-4-8"
- id="linearGradient13987"
- gradientUnits="userSpaceOnUse"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6088-5-0">
- <path
- sodipodi:nodetypes="cccccccscccccccccccc"
- inkscape:connector-curvature="0"
- id="path6090-7-6"
- d="m 102.125,114.75 3.375,7.75 -4.75,3 L 67,99 95.75,46.5 161,54 l 15.75,54.5 c 0,0 -9.20083,-8.2747 -22.75,-8.5 -3.89033,-0.06469 -13.75,1.75 -13.75,1.75 l -9.125,14.875 c 4.47535,-3.19478 8.82199,-2.60624 12.625,-2.375 l -6,10.75 -5.75,0.25 -12.125,2.75 0.25,-2.5 -0.75,-0.625 -6.625,-3.125 -1.75,-5.25 -5,-1.375 z"
- style="opacity:0.45614038;color:#000000;fill:#75507b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6230-2-1">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path6232-2-0"
- d="m 100.57289,62.541562 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222194 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242505 86.891873,77.175486 90.047996,70.775374 94.878999,65.820152 100.57289,62.541562 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814335 15.017289,35.518325 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899695 -1.77117,-30.814334 -15.01728,-35.518318 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:#c9c9c9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath11525-4-2">
- <path
- sodipodi:nodetypes="ssssssssssss"
- clip-path="none"
- inkscape:connector-curvature="0"
- id="path11527-1-6"
- d="m 100.57289,62.541565 c 9.48984,-5.464319 21.33605,-6.200507 31.7778,-0.907186 16.70676,8.469299 23.42235,29.155172 15.00603,46.222191 -8.41633,17.06699 -28.75204,24.0104 -45.45881,15.54111 C 85.191127,114.92838 78.475532,94.242508 86.891873,77.175489 90.047996,70.775377 94.878999,65.820155 100.57289,62.541565 z m 6.9728,5.220359 c -5.96406,3.340783 -10.900661,9.170026 -13.378439,16.619864 -4.955579,14.899702 1.771155,30.814332 15.017289,35.518322 13.24609,4.70395 27.99598,-3.61355 32.95155,-18.51325 4.95556,-14.899692 -1.77117,-30.814331 -15.01728,-35.518315 -6.62305,-2.351969 -13.60904,-1.447398 -19.57312,1.893379 z"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0.99999982px;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- </clipPath>
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
- id="filter11544-7-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.58922844"
- id="feGaussianBlur11546-0-0" />
- </filter>
- <linearGradient
- id="linearGradient3894-9-9">
- <stop
- style="stop-color:#d3d7cf;stop-opacity:1"
- offset="0"
- id="stop3896-5-6" />
- <stop
- style="stop-color:#eeeeec;stop-opacity:1"
- offset="0.28330287"
- id="stop3900-6-6" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.33564273"
- id="stop3906-0-9" />
- <stop
- id="stop4160-0"
- offset="0.42023158"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop3908-9-6"
- offset="0.53767145"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.62985241"
- id="stop3910-3-0" />
- <stop
- id="stop4162-8"
- offset="0.77754474"
- style="stop-color:#ffffff;stop-opacity:1" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="1"
- id="stop3912-0-5" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3859-9-6"
- id="linearGradient3865-1-5"
- x1="107.53125"
- y1="157.21875"
- x2="53.28125"
- y2="142.03125"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3859-9-6">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3861-3-7" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop3863-9-3" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3813-9-8">
- <path
- id="path3815-1-3"
- d="m 85.46875,105.625 -1.78125,2.46875 -8.46875,15.1875 -6.375,1.0625 -2.46875,3.53125 -6.03125,0.71875 -0.6875,2.125 -4.59375,2.125 -1.78125,9.1875 4.25,6.71875 4.9375,1.0625 2.84375,4.25 -0.34375,8.84375 4.9375,3.15625 -3.1875,10.625 3.90625,3.1875 -0.71875,-1.78125 2.8125,-11.3125 1.4375,2.46875 -1.4375,9.90625 1.4375,0.71875 -11.6875,73.53125 8.84375,7.40625 2.46875,0 0,-1.75 0.8125,-0.78125 -0.625,2.53125 9.1875,-8.28125 -1.3125,-1.1875 0.09375,-0.0625 -2.0625,-2.5625 1.53125,-4.15625 5.28125,-4.25 -1.09375,-0.90625 0.21875,-0.15625 -2.09375,-2.3125 1.375,-4.5625 L 89.6875,229 88.90625,228 89,227.9375 l -2.09375,-2.84375 0.3125,-4.40625 4.125,-4.1875 -0.96875,-1.25 0.03125,-0.0312 -2.3125,-4.0938 L 94.25,204 l -0.6875,-1.46875 0.03125,-0.0312 -0.375,-0.75 -1.03125,-2.25 4.9375,-6.5625 2.84375,-10.96875 6,0.1875 1.9375,-10.78125 5.125,-3.875 2.46875,-9.90625 5.3125,-4.78125 4.59375,-0.71875 1.78125,-3.6875 3.71875,-1.0625 2.09375,-8.65625 -1.40625,-4.25 -0.21875,0 0.0312,-0.1875 -4.9375,-1.40625 L 125.75,130 l -6,-1.40625 0.34375,-3.53125 -7.0625,-3.1875 -4.9375,-13.4375 -4.25,-2.46875 -18.375,-0.34375 z m 15.90625,8.125 3.875,8.84375 -4.9375,2.8125 -13.78125,-0.34375 -1.0625,-3.53125 5.65625,-7.4375 10.25,-0.34375 z"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
- id="filter3825-6-1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.50626347"
- id="feGaussianBlur3827-5-5" />
- </filter>
- <linearGradient
- id="linearGradient3263-6-1-8-3">
- <stop
- id="stop3265-8-1-3-1"
- offset="0"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#cbcdc8;stop-opacity:1;"
- offset="0.25"
- id="stop13768-5" />
- <stop
- style="stop-color:#dcdeda;stop-opacity:1;"
- offset="0.5"
- id="stop13766-1" />
- <stop
- id="stop3267-41-3-7-6"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- id="linearGradient13770-9">
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0"
- id="stop13772-1" />
- <stop
- id="stop13780-9"
- offset="0.17445399"
- style="stop-color:#f2f2f1;stop-opacity:1" />
- <stop
- id="stop13774-5"
- offset="0.23801444"
- style="stop-color:#edeeec;stop-opacity:1" />
- <stop
- id="stop13776-7"
- offset="0.27069226"
- style="stop-color:#dcdeda;stop-opacity:1;" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="1"
- id="stop13778-9" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath13687-5-1">
- <path
- d="m 180,135.625 a 28.375,28.375 0 1 1 -56.75,0 28.375,28.375 0 1 1 56.75,0 z"
- sodipodi:ry="28.375"
- sodipodi:rx="28.375"
- sodipodi:cy="135.625"
- sodipodi:cx="151.625"
- id="path13689-5-4"
- style="color:#000000;fill:none;stroke:#f9f9f8;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient12494-4-8-1"
- id="linearGradient13987-9"
- gradientUnits="userSpaceOnUse"
- x1="-19.567272"
- y1="146.57585"
- x2="23.103989"
- y2="188.40904" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient12494-4-8-1">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop12496-8-9-1" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop12498-9-5-0" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath12461-5-4-5">
- <path
- sodipodi:nodetypes="ssscccccccccccccccccccss"
- inkscape:connector-curvature="0"
- id="path12463-1-5-7"
- d="m -52.298199,90.961216 c -14.221332,0 -25.747088,11.549034 -25.747088,25.770364 0,14.22134 11.525756,25.74709 25.747088,25.74709 3.878336,0 7.549624,-0.88545 10.848231,-2.42106 l 37.8989687,37.92225 4.51621619,0 -0.51214823,-1.2571 2.25810814,0 0.7449428,1.2571 5.8431458,-1.58301 -0.6518251,-0.65182 -1.1872527,-7.2632 -5.4939537,-5.51723 -5.2611591,0.25608 0,-6.00611 -3.7479939,-3.74799 -4.2601419,0.74494 -0.232795,-5.75003 -16.08611,-15.15493 1.583003,-1.583 0.488869,-2.00204 -2.909933,-3.30568 c 1.215993,-2.99138 1.908916,-6.25621 1.908916,-9.68426 0,-14.22133 -11.525756,-25.770364 -25.747088,-25.770364 z"
- style="fill:none;stroke:#000000;stroke-width:1.48988581;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </clipPath>
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
- id="filter12480-2-4-0">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.56367413"
- id="feGaussianBlur12482-5-6-5" />
- </filter>
- <linearGradient
- y2="188.40904"
- x2="23.103989"
- y1="146.57585"
- x1="-19.567272"
- gradientUnits="userSpaceOnUse"
- id="linearGradient14313"
- xlink:href="#linearGradient12494-4-8-1"
- inkscape:collect="always" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath14890">
- <path
- style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 179.63667,158.14666 0,-65.569995 -75.57667,0 0,65.569995 75.57667,0 z m -37.7225,-22.58083 c -5.74468,0 -10.40167,-4.65699 -10.40167,-10.40167 0,-5.74468 4.65699,-10.40166 10.40167,-10.40166 5.74468,0 10.40166,4.65698 10.40166,10.40166 0,5.74468 -4.65698,10.40167 -10.40166,10.40167 z"
- id="path14892"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient14960"
- id="linearGradient14966"
- x1="-2.0341735"
- y1="213.94829"
- x2="-1.2096813"
- y2="198.59221"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient14960"
- id="linearGradient14992"
- gradientUnits="userSpaceOnUse"
- x1="-2.0341735"
- y1="213.94829"
- x2="-1.2096813"
- y2="198.59221" />
- <filter
- color-interpolation-filters="sRGB"
- inkscape:collect="always"
- id="filter14931-9">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.5341601"
- id="feGaussianBlur14933-8" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient14960-7"
- id="linearGradient14992-4"
- gradientUnits="userSpaceOnUse"
- x1="-2.0341735"
- y1="213.94829"
- x2="-1.2096813"
- y2="198.59221" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient14960-7">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop14962-1" />
- <stop
- style="stop-color:#d7d9d5;stop-opacity:1"
- offset="1"
- id="stop14964-8" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath14890-4">
- <path
- style="color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 179.63667,158.14666 0,-65.569995 -75.57667,0 0,65.569995 75.57667,0 z m -37.7225,-22.58083 c -5.74468,0 -10.40167,-4.65699 -10.40167,-10.40167 0,-5.74468 4.65699,-10.40166 10.40167,-10.40166 5.74468,0 10.40166,4.65698 10.40166,10.40166 0,5.74468 -4.65698,10.40167 -10.40166,10.40167 z"
- id="path14892-4"
- inkscape:connector-curvature="0" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient14915-2"
- id="radialGradient14996-4"
- gradientUnits="userSpaceOnUse"
- cx="152.45"
- cy="113.6"
- fx="152.45"
- fy="113.6"
- r="25.799999" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient14915-2">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop14917-6" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop14919-7" />
- </linearGradient>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient14915-1"
- id="radialGradient14921-5"
- cx="152.45"
- cy="113.6"
- fx="152.45"
- fy="113.6"
- r="25.799999"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient14915-1">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop14917-60" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop14919-5" />
- </linearGradient>
- <linearGradient
- id="linearGradient6762"
- inkscape:collect="always">
- <stop
- id="stop6764"
- offset="0"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- id="stop6766"
- offset="1"
- style="stop-color:#000000;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6833"
- inkscape:collect="always">
- <stop
- id="stop6835"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6837"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6753"
- inkscape:collect="always">
- <stop
- id="stop6755"
- offset="0"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop6757"
- offset="1"
- style="stop-color:#eeeeec;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- id="linearGradient6837"
- inkscape:collect="always">
- <stop
- id="stop6839"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6841"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient7582"
- inkscape:collect="always">
- <stop
- id="stop7584"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop7586"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6958"
- inkscape:collect="always">
- <stop
- id="stop6960"
- offset="0"
- style="stop-color:#000000;stop-opacity:1" />
- <stop
- id="stop6962"
- offset="1"
- style="stop-color:#888a85;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient2816"
- inkscape:collect="always">
- <stop
- id="stop2818"
- offset="0"
- style="stop-color:white;stop-opacity:1;" />
- <stop
- id="stop2820"
- offset="1"
- style="stop-color:white;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4542"
- inkscape:collect="always">
- <stop
- id="stop4544"
- offset="0"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop4546"
- offset="1"
- style="stop-color:#888a85;stop-opacity:0" />
- </linearGradient>
- <linearGradient
- id="linearGradient6762-2"
- inkscape:collect="always">
- <stop
- id="stop6764-9"
- offset="0"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- id="stop6766-9"
- offset="1"
- style="stop-color:#000000;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6833-5"
- inkscape:collect="always">
- <stop
- id="stop6835-7"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6837-6"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6742-8"
- inkscape:collect="always">
- <stop
- id="stop6744-9"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6746-2"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- gradientUnits="userSpaceOnUse"
- id="linearGradient6127-5"
- inkscape:collect="always"
- x1="14.4375"
- x2="8"
- xlink:href="#linearGradient6753-1"
- y1="13.8125"
- y2="7.5" />
- <linearGradient
- id="linearGradient6753-1"
- inkscape:collect="always">
- <stop
- id="stop6755-2"
- offset="0"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop6757-6"
- offset="1"
- style="stop-color:#eeeeec;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7419"
- id="linearGradient17359"
- gradientUnits="userSpaceOnUse"
- x1="-2.0341735"
- y1="213.94829"
- x2="-1.2096813"
- y2="198.59221" />
- <filter
- inkscape:collect="always"
- id="filter17409">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.60698113"
- id="feGaussianBlur17411" />
- </filter>
- <linearGradient
- id="linearGradient3894-9-9-0">
- <stop
- style="stop-color:#d3d7cf;stop-opacity:1"
- offset="0"
- id="stop3896-5-6-3" />
- <stop
- style="stop-color:#eeeeec;stop-opacity:1"
- offset="0.28330287"
- id="stop3900-6-6-4" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="0.33564273"
- id="stop3906-0-9-9" />
- <stop
- id="stop4160-0-3"
- offset="0.42023158"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop3908-9-6-9"
- offset="0.53767145"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- style="stop-color:#888a85;stop-opacity:1"
- offset="0.62985241"
- id="stop3910-3-0-5" />
- <stop
- id="stop4162-8-4"
- offset="0.77754474"
- style="stop-color:#ffffff;stop-opacity:1" />
- <stop
- style="stop-color:#babdb6;stop-opacity:1"
- offset="1"
- id="stop3912-0-5-9" />
- </linearGradient>
- <linearGradient
- y2="253.83969"
- x2="116.61353"
- y1="106"
- x1="77"
- gradientTransform="translate(-63.28125,-112.625)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17468"
- xlink:href="#linearGradient3894-9-9-0"
- inkscape:collect="always" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath17624">
- <path
- style="color:#000000;fill:none;stroke:#888a85;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- d="m 314.04481,64.503538 c 3.04979,0.261024 2.71652,1.730288 3.6651,2.741745 l 1.31603,2.778302 -7.16509,2.558962 -15.13443,-9.358492 7.53066,-12.941037 19.375,-3.582547 2.04717,6.287735 0,12.575473 -2.48585,-4.31368 c -2.2239,-1.975914 -5.25311,-0.529264 -8.10614,0.168632 z"
- id="path17626"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccccc" />
- </clipPath>
- <linearGradient
- id="linearGradient17498-1">
- <stop
- id="stop17500-1"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-9"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-7"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-8" />
- <stop
- id="stop17514-2"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- id="linearGradient4542-7"
- inkscape:collect="always">
- <stop
- id="stop4544-6"
- offset="0"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop4546-6"
- offset="1"
- style="stop-color:#888a85;stop-opacity:0" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath17624-3">
- <path
- style="color:#000000;fill:none;stroke:#888a85;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- d="m 314.04481,64.503538 c 3.04979,0.261024 2.71652,1.730288 3.6651,2.741745 l 1.31603,2.778302 -7.16509,2.558962 -15.13443,-9.358492 7.53066,-12.941037 19.375,-3.582547 2.04717,6.287735 0,12.575473 -2.19859,-5.175466 c -2.2239,-1.975914 -5.10948,-1.103789 -7.96251,-0.405893 z"
- id="path17626-6"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccccc" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4542-7"
- id="linearGradient17750"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)"
- x1="33.120464"
- y1="20.5"
- x2="22.328388"
- y2="20.5" />
- <linearGradient
- id="linearGradient17498-7">
- <stop
- id="stop17500-8"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-3"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-9"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-4" />
- <stop
- id="stop17514-4"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780-3">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782-6" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784-1" />
- </linearGradient>
- <linearGradient
- y2="51.558521"
- x2="19.272995"
- y1="25.183172"
- x1="28.897871"
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,49.646976,-20.299048)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17810"
- xlink:href="#linearGradient17498-7"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,35.129488,-15.017404)"
- y2="21.948019"
- x2="21.54595"
- y1="35.318134"
- x1="12.744178"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17812"
- xlink:href="#linearGradient17780-3"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient17498-3">
- <stop
- id="stop17500-3"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-4"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-4"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-2" />
- <stop
- id="stop17514-1"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780-6">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782-8" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784-3" />
- </linearGradient>
- <linearGradient
- y2="51.558521"
- x2="19.272995"
- y1="25.183172"
- x1="28.897871"
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,49.646976,-20.299048)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17810-0"
- xlink:href="#linearGradient17498-3"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,35.129488,-15.017404)"
- y2="21.948019"
- x2="21.54595"
- y1="35.318134"
- x1="12.744178"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17812-7"
- xlink:href="#linearGradient17780-6"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-5"
- id="linearGradient17518-1"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="28.897871"
- y1="25.183172"
- x2="19.272995"
- y2="51.558521" />
- <linearGradient
- id="linearGradient17498-5">
- <stop
- id="stop17500-6"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-2"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-8"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-6" />
- <stop
- id="stop17514-9"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-7"
- id="linearGradient17786-1"
- x1="12.744178"
- y1="35.318134"
- x2="21.54595"
- y2="21.948019"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780-7">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782-4" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784-7" />
- </linearGradient>
- <linearGradient
- y2="51.558521"
- x2="19.272995"
- y1="25.183172"
- x1="28.897871"
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,49.646976,-20.299048)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17810-7"
- xlink:href="#linearGradient17498-5"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,35.129488,-15.017404)"
- y2="21.948019"
- x2="21.54595"
- y1="35.318134"
- x1="12.744178"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17812-9"
- xlink:href="#linearGradient17780-7"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient17498-6">
- <stop
- id="stop17500-5"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-8"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-6"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-3" />
- <stop
- id="stop17514-5"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780-5">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782-68" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784-4" />
- </linearGradient>
- <linearGradient
- y2="51.558521"
- x2="19.272995"
- y1="25.183172"
- x1="28.897871"
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,49.646976,-20.299048)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17810-09"
- xlink:href="#linearGradient17498-6"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-1.222459,-0.32755691,-0.32755691,1.222459,35.129488,-15.017404)"
- y2="21.948019"
- x2="21.54595"
- y1="35.318134"
- x1="12.744178"
- gradientUnits="userSpaceOnUse"
- id="linearGradient17812-1"
- xlink:href="#linearGradient17780-5"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient5376-1-5-2">
- <stop
- style="stop-color:#fce94f;stop-opacity:1;"
- offset="0"
- id="stop5378-1-7-2" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="1"
- id="stop5380-0-9-0" />
- </linearGradient>
- <linearGradient
- y2="1326.8596"
- x2="-243.19453"
- y1="1159.4119"
- x1="-868.11768"
- gradientTransform="matrix(0.08620296,0.08620294,-0.08620296,0.08620294,227.41356,-13.853324)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6089"
- xlink:href="#linearGradient5376-1-5-2"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient6107-8">
- <stop
- id="stop6109-3"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115-8" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113-7" />
- <stop
- id="stop6111-3"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- y2="1684.3187"
- x2="3503.502"
- y1="921.10638"
- x1="1382.548"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,45.03819,-90.402987)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6134"
- xlink:href="#linearGradient6107-8"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient6107-8-2">
- <stop
- id="stop6109-3-0"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115-8-6" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113-7-3" />
- <stop
- id="stop6111-3-6"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6156-0">
- <stop
- style="stop-color:#c4a000;stop-opacity:1;"
- offset="0"
- id="stop6158-5" />
- <stop
- style="stop-color:#ffe365;stop-opacity:1"
- offset="1"
- id="stop6160-7" />
- </linearGradient>
- <linearGradient
- y2="1684.3187"
- x2="3503.502"
- y1="921.10638"
- x1="1382.548"
- gradientTransform="matrix(0,0.06759483,0.06759483,0,-134.30354,128.13852)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6185"
- xlink:href="#linearGradient6107-8-2"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-0.89490214,0.89490212,0.89490212,0.89490214,0.34336141,-23.651613)"
- y2="21.641434"
- x2="5.5136962"
- y1="46.923531"
- x1="16.843721"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6187"
- xlink:href="#linearGradient6156-0"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient6107-8-7">
- <stop
- id="stop6109-3-6"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115-8-3" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113-7-9" />
- <stop
- id="stop6111-3-1"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6156-4">
- <stop
- style="stop-color:#c4a000;stop-opacity:1;"
- offset="0"
- id="stop6158-1" />
- <stop
- style="stop-color:#ffe365;stop-opacity:1"
- offset="1"
- id="stop6160-1" />
- </linearGradient>
- <linearGradient
- y2="1684.3187"
- x2="3503.502"
- y1="921.10638"
- x1="1382.548"
- gradientTransform="matrix(0,0.06759483,0.06759483,0,-134.30354,128.13852)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6185-8"
- xlink:href="#linearGradient6107-8-7"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-0.89490214,0.89490212,0.89490212,0.89490214,0.34336141,-23.651613)"
- y2="21.641434"
- x2="5.5136962"
- y1="46.923531"
- x1="16.843721"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6187-6"
- xlink:href="#linearGradient6156-4"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6249-2">
- <stop
- style="stop-color:#c49f00;stop-opacity:0.627451"
- offset="0"
- id="stop6251-7" />
- <stop
- style="stop-color:#fceca6;stop-opacity:1"
- offset="1"
- id="stop6253-0" />
- </linearGradient>
- <linearGradient
- gradientTransform="matrix(-1.34294e-8,1,1,1.34294e-8,-8.4999999,-9.0000001)"
- y2="7.5"
- x2="8"
- y1="13.8125"
- x1="14.4375"
- gradientUnits="userSpaceOnUse"
- id="linearGradient6270"
- xlink:href="#linearGradient6249-2"
- inkscape:collect="always" />
- <linearGradient
- id="linearGradient6107-8-7-1">
- <stop
- id="stop6109-3-6-5"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115-8-3-1" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113-7-9-4" />
- <stop
- id="stop6111-3-1-8"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient6156-4-3">
- <stop
- style="stop-color:#c4a000;stop-opacity:1;"
- offset="0"
- id="stop6158-1-7" />
- <stop
- style="stop-color:#ffe365;stop-opacity:1"
- offset="1"
- id="stop6160-1-4" />
- </linearGradient>
- <linearGradient
- y2="1684.3187"
- x2="3503.502"
- y1="921.10638"
- x1="1382.548"
- gradientTransform="matrix(0.0377666,0.03776661,0.0377666,-0.03776661,9.578274,160.03315)"
- gradientUnits="userSpaceOnUse"
- id="linearGradient7446"
- xlink:href="#linearGradient6107-8-7-1"
- inkscape:collect="always" />
- <linearGradient
- gradientTransform="matrix(-1.34294e-8,1,1,1.34294e-8,7.3861713e-8,-0.00503904)"
- y2="11.641434"
- x2="-1.2363037"
- y1="14.923531"
- x1="13.593721"
- gradientUnits="userSpaceOnUse"
- id="linearGradient7448"
- xlink:href="#linearGradient6156-4-3"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8002-5"
- id="linearGradient8008-1"
- x1="14.679631"
- y1="16.403772"
- x2="-6.3245316"
- y2="46.160282"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient8002-5">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop8004-2" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop8006-6" />
- </linearGradient>
- <linearGradient
- y2="46.160282"
- x2="-6.3245316"
- y1="16.403772"
- x1="14.679631"
- gradientUnits="userSpaceOnUse"
- id="linearGradient8025"
- xlink:href="#linearGradient8002-5"
- inkscape:collect="always" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7419"
- id="linearGradient8053"
- gradientUnits="userSpaceOnUse"
- x1="-2.0341735"
- y1="213.94829"
- x2="-1.2096813"
- y2="198.59221" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8"
- id="linearGradient3907"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156"
- id="linearGradient3909"
- gradientUnits="userSpaceOnUse"
- x1="12.892972"
- y1="33.490982"
- x2="5.5136962"
- y2="21.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6958"
- id="linearGradient3911"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)"
- x1="17"
- y1="45.248375"
- x2="17"
- y2="30.759407" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2816"
- id="linearGradient3913"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)"
- x1="15.406166"
- y1="37.34367"
- x2="16.864777"
- y2="24.249567" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249-2"
- id="linearGradient3915"
- gradientUnits="userSpaceOnUse"
- x1="44.46957"
- y1="-15.295949"
- x2="31.692965"
- y2="-15.121348" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7994"
- id="linearGradient3917"
- gradientUnits="userSpaceOnUse"
- x1="6.7611751"
- y1="30.90625"
- x2="19.926325"
- y2="30.90625" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498"
- id="linearGradient3987"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="28.897871"
- y1="25.183172"
- x2="19.272995"
- y2="51.558521" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780"
- id="linearGradient3989"
- gradientUnits="userSpaceOnUse"
- x1="17.291615"
- y1="31.321718"
- x2="23.125856"
- y2="14.906891" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4542"
- id="linearGradient3991"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)"
- x1="33.120464"
- y1="20.5"
- x2="22.328388"
- y2="20.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8002"
- id="linearGradient3993"
- gradientUnits="userSpaceOnUse"
- x1="14.679631"
- y1="16.403772"
- x2="-6.3245316"
- y2="46.160282" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-7"
- id="linearGradient4085"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-4"
- id="linearGradient4087"
- gradientUnits="userSpaceOnUse"
- x1="13.593721"
- y1="14.923531"
- x2="-1.2363037"
- y2="11.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762-2"
- id="linearGradient4089"
- gradientUnits="userSpaceOnUse"
- x1="6.5"
- y1="9"
- x2="7.5"
- y2="5.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833-5"
- id="linearGradient4091"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="5.9061942"
- y2="5.2978506" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6742-8"
- id="linearGradient4093"
- gradientUnits="userSpaceOnUse"
- x1="9.9340439"
- y1="4.53125"
- x2="10.562407"
- y2="22.717516" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249"
- id="linearGradient4095"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-6"
- id="linearGradient4097"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="6.6240072"
- y1="10.33393"
- x2="10.96449"
- y2="28.577551" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-5"
- id="linearGradient4099"
- gradientUnits="userSpaceOnUse"
- x1="0.36980912"
- y1="9.6855135"
- x2="-3.3759925"
- y2="3.3339295" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762"
- id="linearGradient4101"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="6.4375"
- y1="6.7797499"
- x2="8.4537582"
- y2="8.7975082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6837"
- id="linearGradient4103"
- gradientUnits="userSpaceOnUse"
- x1="-7.96875"
- y1="11.5"
- x2="0.96875"
- y2="11.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833"
- id="linearGradient4105"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="6.1381931"
- y2="6.2651649" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753"
- id="linearGradient4107"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7582"
- id="radialGradient4113"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,0.6206897,0,0.7823276)"
- cx="11.15625"
- cy="2.0625"
- fx="11.15625"
- fy="2.0625"
- r="0.90625" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-2"
- id="linearGradient4907"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-0"
- id="linearGradient4909"
- gradientUnits="userSpaceOnUse"
- x1="16.843721"
- y1="46.923531"
- x2="5.5136962"
- y2="21.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6958"
- id="linearGradient4911"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)"
- x1="17"
- y1="45.248375"
- x2="17"
- y2="30.759407" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2816"
- id="linearGradient4913"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)"
- x1="15.406166"
- y1="37.34367"
- x2="16.864777"
- y2="24.249567" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249-2"
- id="linearGradient4915"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- <linearGradient
- id="linearGradient6107-8-7-3">
- <stop
- id="stop6109-3-6-54"
- offset="0"
- style="stop-color:#e0d684;stop-opacity:1" />
- <stop
- style="stop-color:#f7f5e3;stop-opacity:1"
- offset="0.25"
- id="stop6115-8-3-3" />
- <stop
- style="stop-color:#e5e3ae;stop-opacity:1;"
- offset="0.5"
- id="stop6113-7-9-6" />
- <stop
- id="stop6111-3-1-4"
- offset="1"
- style="stop-color:#ebf0d8;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- id="linearGradient17498-6-8">
- <stop
- id="stop17500-5-7"
- offset="0"
- style="stop-color:#d3d7cf;stop-opacity:1" />
- <stop
- id="stop17502-8-4"
- offset="0.28330287"
- style="stop-color:#eeeeec;stop-opacity:1" />
- <stop
- id="stop17504-6-9"
- offset="0.33564273"
- style="stop-color:#babdb6;stop-opacity:1" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="0.6530382"
- id="stop17512-3-3" />
- <stop
- id="stop17514-5-1"
- offset="1"
- style="stop-color:#babdb6;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient17780-5-8">
- <stop
- style="stop-color:#888a85;stop-opacity:1;"
- offset="0"
- id="stop17782-68-7" />
- <stop
- style="stop-color:#e2e2e1;stop-opacity:1"
- offset="1"
- id="stop17784-4-9" />
- </linearGradient>
- <linearGradient
- id="linearGradient6762-8"
- inkscape:collect="always">
- <stop
- id="stop6764-8"
- offset="0"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- id="stop6766-4"
- offset="1"
- style="stop-color:#000000;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6837-0"
- inkscape:collect="always">
- <stop
- id="stop6839-8"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6841-6"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient6833-2"
- inkscape:collect="always">
- <stop
- id="stop6835-3"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- id="stop6837-8"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753-0"
- id="linearGradient4107-5"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <linearGradient
- id="linearGradient6753-0"
- inkscape:collect="always">
- <stop
- id="stop6755-5"
- offset="0"
- style="stop-color:#888a85;stop-opacity:1" />
- <stop
- id="stop6757-9"
- offset="1"
- style="stop-color:#eeeeec;stop-opacity:1" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498"
- id="linearGradient5212"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="28.897871"
- y1="25.183172"
- x2="19.272995"
- y2="51.558521" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780"
- id="linearGradient5214"
- gradientUnits="userSpaceOnUse"
- x1="17.291615"
- y1="31.321718"
- x2="23.125856"
- y2="14.906891" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4542"
- id="linearGradient5216"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)"
- x1="33.120464"
- y1="20.5"
- x2="22.328388"
- y2="20.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8002"
- id="linearGradient5218"
- gradientUnits="userSpaceOnUse"
- x1="14.679631"
- y1="16.403772"
- x2="-6.3245316"
- y2="46.160282" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8"
- id="linearGradient5220"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156"
- id="linearGradient5222"
- gradientUnits="userSpaceOnUse"
- x1="12.892972"
- y1="33.490982"
- x2="5.5136962"
- y2="21.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6958"
- id="linearGradient5224"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)"
- x1="17"
- y1="45.248375"
- x2="17"
- y2="30.759407" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2816"
- id="linearGradient5226"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)"
- x1="15.406166"
- y1="37.34367"
- x2="16.864777"
- y2="24.249567" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249-2"
- id="linearGradient5228"
- gradientUnits="userSpaceOnUse"
- x1="44.46957"
- y1="-15.295949"
- x2="31.692965"
- y2="-15.121348" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7994"
- id="linearGradient5230"
- gradientUnits="userSpaceOnUse"
- x1="6.7611751"
- y1="30.90625"
- x2="19.926325"
- y2="30.90625" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7582"
- id="radialGradient5256"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,0.6206897,0,0.7823276)"
- cx="11.15625"
- cy="2.0625"
- fx="11.15625"
- fy="2.0625"
- r="0.90625" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-5"
- id="linearGradient5258"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="28.897871"
- y1="25.183172"
- x2="19.272995"
- y2="51.558521" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-7"
- id="linearGradient5260"
- gradientUnits="userSpaceOnUse"
- x1="12.744178"
- y1="35.318134"
- x2="21.54595"
- y2="21.948019" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4542-7"
- id="linearGradient5262"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.727273,0,0,0.999999,12.27273,-34.84375)"
- x1="33.120464"
- y1="20.5"
- x2="22.328388"
- y2="20.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8002-5"
- id="linearGradient5264"
- gradientUnits="userSpaceOnUse"
- x1="14.679631"
- y1="16.403772"
- x2="-6.3245316"
- y2="46.160282" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-2"
- id="linearGradient5266"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-0"
- id="linearGradient5268"
- gradientUnits="userSpaceOnUse"
- x1="16.843721"
- y1="46.923531"
- x2="5.5136962"
- y2="21.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6958"
- id="linearGradient5270"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.625,-0.676136,0,37.10227,15.875)"
- x1="17"
- y1="45.248375"
- x2="17"
- y2="30.759407" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2816"
- id="linearGradient5272"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,0.673693,-0.676136,0,37.10227,14.81577)"
- x1="15.406166"
- y1="37.34367"
- x2="16.864777"
- y2="24.249567" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249-2"
- id="linearGradient5274"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-6"
- id="linearGradient5304"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="6.6240072"
- y1="10.33393"
- x2="10.96449"
- y2="28.577551" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-5"
- id="linearGradient5306"
- gradientUnits="userSpaceOnUse"
- x1="0.36980912"
- y1="9.6855135"
- x2="-3.3759925"
- y2="3.3339295" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762"
- id="linearGradient5308"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="6.4375"
- y1="6.7797499"
- x2="8.4537582"
- y2="8.7975082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6837"
- id="linearGradient5310"
- gradientUnits="userSpaceOnUse"
- x1="-7.96875"
- y1="11.5"
- x2="0.96875"
- y2="11.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833"
- id="linearGradient5312"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="6.1381931"
- y2="6.2651649" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753"
- id="linearGradient5314"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-7"
- id="linearGradient5316"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-4"
- id="linearGradient5318"
- gradientUnits="userSpaceOnUse"
- x1="13.593721"
- y1="14.923531"
- x2="-1.2363037"
- y2="11.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762-2"
- id="linearGradient5320"
- gradientUnits="userSpaceOnUse"
- x1="6.5"
- y1="9"
- x2="7.5"
- y2="5.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833-5"
- id="linearGradient5322"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="5.9061942"
- y2="5.2978506" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6742-8"
- id="linearGradient5324"
- gradientUnits="userSpaceOnUse"
- x1="9.9340439"
- y1="4.53125"
- x2="10.562407"
- y2="22.717516" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249"
- id="linearGradient5326"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-6-8"
- id="linearGradient5356"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="6.6240072"
- y1="10.33393"
- x2="10.96449"
- y2="28.577551" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-5-8"
- id="linearGradient5358"
- gradientUnits="userSpaceOnUse"
- x1="0.36980912"
- y1="9.6855135"
- x2="-3.3759925"
- y2="3.3339295" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762-8"
- id="linearGradient5360"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="6.4375"
- y1="6.7797499"
- x2="8.4537582"
- y2="8.7975082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6837-0"
- id="linearGradient5362"
- gradientUnits="userSpaceOnUse"
- x1="-7.96875"
- y1="11.5"
- x2="0.96875"
- y2="11.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833-2"
- id="linearGradient5364"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="6.1381931"
- y2="6.2651649" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753-0"
- id="linearGradient5366"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-6"
- id="linearGradient5432"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="6.6240072"
- y1="10.33393"
- x2="10.96449"
- y2="28.577551" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-5"
- id="linearGradient5434"
- gradientUnits="userSpaceOnUse"
- x1="0.36980912"
- y1="9.6855135"
- x2="-3.3759925"
- y2="3.3339295" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762"
- id="linearGradient5436"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="6.4375"
- y1="6.7797499"
- x2="8.4537582"
- y2="8.7975082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6837"
- id="linearGradient5438"
- gradientUnits="userSpaceOnUse"
- x1="-7.96875"
- y1="11.5"
- x2="0.96875"
- y2="11.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833"
- id="linearGradient5440"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="6.1381931"
- y2="6.2651649" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753"
- id="linearGradient5442"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-7"
- id="linearGradient5444"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-4"
- id="linearGradient5446"
- gradientUnits="userSpaceOnUse"
- x1="13.593721"
- y1="14.923531"
- x2="-1.2363037"
- y2="11.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762-2"
- id="linearGradient5448"
- gradientUnits="userSpaceOnUse"
- x1="6.5"
- y1="9"
- x2="7.5"
- y2="5.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833-5"
- id="linearGradient5450"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="5.9061942"
- y2="5.2978506" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6742-8"
- id="linearGradient5452"
- gradientUnits="userSpaceOnUse"
- x1="9.9340439"
- y1="4.53125"
- x2="10.562407"
- y2="22.717516" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249"
- id="linearGradient5454"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17498-6"
- id="linearGradient5484"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-10,-7.0000003)"
- x1="6.6240072"
- y1="10.33393"
- x2="10.96449"
- y2="28.577551" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient17780-5"
- id="linearGradient5486"
- gradientUnits="userSpaceOnUse"
- x1="0.36980912"
- y1="9.6855135"
- x2="-3.3759925"
- y2="3.3339295" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762"
- id="linearGradient5488"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="6.4375"
- y1="6.7797499"
- x2="8.4537582"
- y2="8.7975082" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6837"
- id="linearGradient5490"
- gradientUnits="userSpaceOnUse"
- x1="-7.96875"
- y1="11.5"
- x2="0.96875"
- y2="11.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833"
- id="linearGradient5492"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="6.1381931"
- y2="6.2651649" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6753"
- id="linearGradient5494"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,-3.506058,-0.3596506)"
- x1="9.2127371"
- y1="9.4198446"
- x2="17.65192"
- y2="17.15192" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6107-8-7"
- id="linearGradient5496"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.03776661,0.0377666,-0.03776661,0.0377666,160.03819,9.5782761)"
- x1="1382.548"
- y1="921.10638"
- x2="3503.502"
- y2="1684.3187" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6156-4"
- id="linearGradient5498"
- gradientUnits="userSpaceOnUse"
- x1="13.593721"
- y1="14.923531"
- x2="-1.2363037"
- y2="11.641434" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6762-2"
- id="linearGradient5500"
- gradientUnits="userSpaceOnUse"
- x1="6.5"
- y1="9"
- x2="7.5"
- y2="5.5" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6833-5"
- id="linearGradient5502"
- gradientUnits="userSpaceOnUse"
- x1="8.7232523"
- y1="6.2651649"
- x2="5.9061942"
- y2="5.2978506" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6742-8"
- id="linearGradient5504"
- gradientUnits="userSpaceOnUse"
- x1="9.9340439"
- y1="4.53125"
- x2="10.562407"
- y2="22.717516" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6249"
- id="linearGradient5506"
- gradientUnits="userSpaceOnUse"
- x1="14.4375"
- y1="13.8125"
- x2="8"
- y2="7.5" />
- </defs>
- <metadata
- id="metadata4">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:creator>
- <cc:Agent>
- <dc:title>Lapo Calamandrei</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:source />
- <cc:license
- rdf:resource="" />
- <dc:title>Firewall</dc:title>
- <dc:subject>
- <rdf:Bag />
- </dc:subject>
- <dc:date />
- <dc:rights>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:rights>
- <dc:publisher>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:publisher>
- <dc:identifier />
- <dc:relation />
- <dc:language />
- <dc:coverage />
- <dc:description />
- <dc:contributor>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:contributor>
- </cc:Work>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- style="display:inline"
- inkscape:groupmode="layer"
- inkscape:label="artwork"
- id="layer1">
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="baseplate"
- style="display:none"
- sodipodi:insensitive="true">
- <rect
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect6284"
- width="48"
- height="48"
- x="296.0625"
- y="51.99633"
- inkscape:label="48x48" />
- <rect
- inkscape:label="32x32"
- y="127.99634"
- x="303"
- height="32"
- width="32"
- id="rect6592"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- inkscape:label="24x24"
- y="178"
- x="302"
- height="24"
- width="24"
- id="rect5028"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- inkscape:label="16x16"
- y="221"
- x="303"
- height="16"
- width="16"
- id="rect6833"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect6749"
- width="22"
- height="22"
- x="303"
- y="179.05884"
- inkscape:label="22x22" />
- <text
- id="context"
- inkscape:label="context"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
- x="31.87059"
- xml:space="preserve"
- y="18.860306"><tspan
- id="tspan2716"
- sodipodi:role="line"
- x="31.87059"
- y="18.860306"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans">apps</tspan></text>
- <text
- id="icon-name"
- inkscape:label="icon-name"
- sodipodi:linespacing="125%"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
- x="199.87057"
- xml:space="preserve"
- y="18.860306"><tspan
- id="tspan3023"
- sodipodi:role="line"
- x="199.87057"
- y="18.860306"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold">seahorse</tspan></text>
- <rect
- inkscape:label="256x256"
- y="32"
- x="20"
- height="256"
- width="256"
- id="rect6282"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="smallsizes"
- style="display:inline">
- <g
- id="g6154"
- style="fill:#ffffff"
- transform="matrix(1.25,0,0,1.25,-78,-47.25)" />
- <g
- transform="matrix(0.01764125,1.4827579,1.4547795,2.9762967e-4,279.22187,67.025361)"
- id="g7413">
- <path
- style="color:#000000;fill:url(#linearGradient3987);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3989);stroke-width:0.68087411px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- sodipodi:nodetypes="sccccccccccccccccccccccscsssc"
- id="path7415"
- d="M 13.4375,16.5 C 9.5186406,16.51383 9.104267,20.317626 9.104267,20.317626 L 4.5779358,22.440454 5.5274999,28.161436 10.537742,29.545854 10.34375,31.5 l 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.5,2 2.5,0 1,-1.5 0,-14 4.843587,-3.351692 0.285612,-4.53777 -3.879353,-1.635941 C 17.697518,18.950089 16.72173,16.488411 13.4375,16.5 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- inkscape:connector-curvature="0" />
- <rect
- y="-14.84375"
- x="29"
- width="16.311773"
- transform="matrix(0,1,-1,0,0,0)"
- style="opacity:0.61538463;fill:url(#linearGradient3991);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="rect7423"
- height="0.98128641" />
- <path
- d="m 13.4375,17.28125 c -1.703381,0.006 -2.476193,0.776336 -2.96875,1.5625 -0.4925567,0.786164 -0.59375,1.5625 -0.59375,1.5625 a 0.79285854,0.79285854 0 0 1 -0.4375,0.625 l -4,1.875 0.78125,4.625 4.53125,1.25 a 0.79285854,0.79285854 0 0 1 0.5625,0.8125 l -0.15625,1.59375 1.25,1.25 a 0.79285854,0.79285854 0 0 1 0,1.125 l -1.28125,1.28125 0,0.15625 1.5625,0.78125 A 0.79285854,0.79285854 0 0 1 13.125,36.5 l 0,1 a 0.79285854,0.79285854 0 0 1 -0.4375,0.71875 L 11.125,39 l 0,0.15625 1.28125,1.28125 a 0.79285854,0.79285854 0 0 1 0,1.125 l -1.28125,1.28125 0,0.25 2.03125,1.625 1.75,0 0.65625,-0.96875 0,-13.75 a 0.79285854,0.79285854 0 0 1 0.34375,-0.65625 l 4.53125,-3.125 0.21875,-3.59375 -3.375,-1.4375 A 0.79285854,0.79285854 0 0 1 16.8125,20.40625 c 0.03854,-0.565438 -0.159384,-1.378013 -0.65625,-2 -0.496866,-0.621987 -1.274512,-1.130096 -2.71875,-1.125 z m -0.09375,0.4375 c 1.532943,0 2.78125,1.248307 2.78125,2.78125 0,1.532943 -1.248307,2.78125 -2.78125,2.78125 -1.532943,0 -2.78125,-1.248307 -2.78125,-2.78125 0,-1.532943 1.248307,-2.78125 2.78125,-2.78125 z"
- inkscape:href="#path7415"
- id="path17516"
- style="color:#000000;fill:none;stroke:url(#linearGradient3993);stroke-width:0.68087411px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- xlink:href="#path7415"
- inkscape:original="M 13.4375 16.5 C 9.5186406 16.51383 9.09375 20.3125 9.09375 20.3125 L 4.5625 22.4375 L 5.53125 28.15625 L 10.53125 29.53125 L 10.34375 31.5 L 11.84375 33 L 10.34375 34.5 L 10.34375 35.5 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.84375 41 L 10.34375 42.5 L 10.34375 43.5 L 12.84375 45.5 L 15.34375 45.5 L 16.34375 44 L 16.34375 30 L 21.1875 26.65625 L 21.46875 22.125 L 17.59375 20.46875 C 17.697672 18.944242 16.72173 16.488411 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- inkscape:radius="-0.79277927"
- sodipodi:type="inkscape:offset" />
- </g>
- <path
- transform="matrix(0.5532396,-0.54421924,0.87679765,0.89133046,297.34092,149.00568)"
- style="fill:url(#radialGradient4113);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc"
- sodipodi:ry="0.5625"
- sodipodi:rx="0.90625"
- sodipodi:cy="2.0625"
- sodipodi:cx="11.15625"
- id="path177"
- d="m 12.0625,2.0625 a 0.90625,0.5625 0 1 1 -1.8125,0 0.90625,0.5625 0 1 1 1.8125,0 z"
- inkscape:export-filename="/data/projects/seahorse/32x32.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
- transform="matrix(0.00416675,0.99999132,0.99999132,-0.00416675,301.00511,199.0963)"
- id="g6769"
- inkscape:export-filename="/data/projects/seahorse/24x24.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- style="color:#000000;fill:url(#linearGradient4097);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4099);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- sodipodi:nodetypes="csccccccccccccccccssssc"
- id="path6081"
- d="M -0.5017742,6.4584078 C -0.37175202,4.4522829 -0.8448083,2.5 -3.5060582,2.5 -6.2660581,2.5 -6.6064795,4.8828745 -6.625,6.3689418 l -1.8916614,1.1881832 -0.01828,2.1039435 3.0401445,2.3848735 -0.0052,2.529476 L -4.5,16 l -1,1.5 0,1 2,2 0.9999989,0 L -1.5,19.5 -1.51732,12.045942 1.4161394,9.5495158 1.4878836,7.4939418 z M -2.7989514,5.3726214 c 0.1810001,0.1810001 0.3093592,0.4311066 0.3093592,0.7071068 2e-7,0.5520005 -0.4644656,1.016466 -1.016466,1.016466 -0.552,10e-8 -1.016466,-0.4644656 -1.016466,-1.016466 0,-0.5520004 0.4644656,-1.016466 1.016466,-1.016466 0.2760002,0 0.5261067,0.1283591 0.7071068,0.3093592 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.06334845;fill:url(#linearGradient4101);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path6083"
- d="m 0.71269221,8.9174565 -8.43750041,0 c 0.6214183,1.7412405 2.2649102,3.0000005 4.2187502,3.0000005 1.9538399,0 3.5973328,-1.258759 4.21875021,-3.0000005 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.52036252;fill:none;stroke:url(#linearGradient4103);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.0199475"
- inkscape:original="M -3.5 2.5 C -6.2599999 2.5 -8.5 4.7399998 -8.5 7.5 C -8.4999997 9.5446378 -7.2593482 11.256644 -5.5 12.03125 L -5.5 14.5625 L -4.5 16 L -5.5 17.5 L -5.5 18.5 C -5.5 18.5 -3.5 20.5 -3.5 20.5 L -2.5 20.5 L -1.5 19.5 L -1.53125 12.03125 C 0.22809828 11.256644 1.4999997 9.5446378 1.5 7.5 C 1.5000001 6.12 0.93625013 4.8737501 0.03125 3.96875 C -0.87375013 3.0637498 -2.1200001 2.5 -3.5 2.5 z "
- id="path6765"
- d="m -3.5,3.53125 c -2.2081443,0 -3.96875,1.7606055 -3.96875,3.96875 2e-7,1.6320467 0.9610544,2.971218 2.375,3.59375 a 1.0200495,1.0200495 0 0 1 0.625,0.9375 l 0,2.21875 0.8125,1.15625 a 1.0200495,1.0200495 0 0 1 0,1.15625 l -0.8125,1.21875 0,0.3125 1.375,1.375 0.1875,0 0.375,-0.375 -0.03125,-7.0625 a 1.0200495,1.0200495 0 0 1 0.625,-0.9375 C -0.51947782,10.469423 0.46874976,9.1216542 0.46875,7.5 0.46875008,6.3977756 0.03620106,5.411201 -0.6875,4.6875 -1.411201,3.9637989 -2.3977756,3.53125 -3.5,3.53125 z" />
- <path
- transform="matrix(0,1.3333333,-1.3333333,0,4.493942,-3.3285949)"
- style="fill:none;stroke:url(#linearGradient4105);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="arc"
- sodipodi:ry="1.5"
- sodipodi:rx="1.5"
- sodipodi:cy="6"
- sodipodi:cx="7"
- id="path6085"
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z" />
- <path
- style="fill:none;stroke:url(#linearGradient4107);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:nodetypes="cc"
- id="path6091"
- d="m -3.1525046,18.37868 0,-5.656855"
- inkscape:connector-curvature="0" />
- </g>
- <g
- style="display:inline;enable-background:new"
- id="g7413-2"
- transform="matrix(0.04996045,0.90113171,0.90113171,-0.04996045,286.95195,137.30619)"
- inkscape:export-filename="/data/projects/seahorse/32x32.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- inkscape:connector-curvature="0"
- d="M 13.4375,16.5 C 9.5186406,16.51383 9.104267,20.317626 9.104267,20.317626 L 6.1982808,21.790068 6.2456938,25.750941 10.34375,30 l 0,1.5 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.440937,1.274442 3.754218,0.995104 L 17.061728,43.68543 16.34375,30 l 4.843587,-3.351692 0.285612,-4.53777 -3.879353,-1.635941 C 17.697518,18.950089 16.72173,16.488411 13.4375,16.5 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- id="path7415-5"
- sodipodi:nodetypes="sccccccccccccccccccccccscsssc"
- style="color:#000000;fill:url(#linearGradient17518-1);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient17786-1);stroke-width:1.10801411px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- <rect
- height="0.98128641"
- id="rect7423-4"
- style="opacity:0.61538463;fill:url(#linearGradient17750);fill-opacity:1;fill-rule:evenodd;stroke:none"
- transform="matrix(0,1,-1,0,0,0)"
- width="16.311773"
- x="29"
- y="-14.84375" />
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="-0.96211886"
- inkscape:original="M 13.4375 16.5 C 9.5186406 16.51383 9.09375 20.3125 9.09375 20.3125 L 6.1875 21.78125 L 6.25 25.75 L 10.34375 30 L 10.34375 31.5 L 11.84375 33 L 10.34375 34.5 L 10.34375 35.5 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.84375 41 L 10.34375 42.5 L 10.34375 43.5 L 12.78125 44.78125 L 16.53125 45.78125 L 17.0625 43.6875 L 16.34375 30 L 21.1875 26.65625 L 21.46875 22.125 L 17.59375 20.46875 C 17.697672 18.944242 16.72173 16.488411 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- xlink:href="#path7415-5"
- style="color:#000000;fill:none;stroke:url(#linearGradient8008-1);stroke-width:1.10801411px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="path17516-2"
- inkscape:href="#path7415-5"
- d="m 13.4375,17.46875 c -1.648688,0.0058 -2.342056,0.71788 -2.8125,1.46875 -0.470444,0.75087 -0.5625,1.46875 -0.5625,1.46875 a 0.96221508,0.96221508 0 0 1 -0.53125,0.75 l -2.375,1.1875 0.0625,3.03125 3.8125,3.96875 A 0.96221508,0.96221508 0 0 1 11.3125,30 l 0,1.09375 1.21875,1.21875 a 0.96221508,0.96221508 0 0 1 0,1.375 l -1.21875,1.1875 0,0.03125 1.46875,0.71875 A 0.96221508,0.96221508 0 0 1 13.3125,36.5 l 0,1 a 0.96221508,0.96221508 0 0 1 -0.53125,0.875 l -1.46875,0.71875 0,0.03125 1.21875,1.1875 a 0.96221508,0.96221508 0 0 1 0,1.375 l -1.21875,1.21875 0,0.03125 1.71875,0.90625 0.03125,0 2.78125,0.75 0.25,-1 L 15.375,30.0625 a 0.96221508,0.96221508 0 0 1 0.4375,-0.84375 l 4.4375,-3.0625 0.21875,-3.4375 -3.25,-1.375 A 0.96221508,0.96221508 0 0 1 16.625,20.40625 C 16.660679,19.882852 16.497217,19.083307 16.03125,18.5 15.565283,17.916693 14.83947,17.463803 13.4375,17.46875 z m -0.09375,0.0625 c 1.624567,0 2.96875,1.344183 2.96875,2.96875 0,1.624567 -1.344183,2.96875 -2.96875,2.96875 -1.624567,0 -2.96875,-1.344183 -2.96875,-2.96875 0,-1.624567 1.344183,-2.96875 2.96875,-2.96875 z" />
- </g>
- <g
- transform="matrix(-0.03314179,-1.4601652,1.4591995,-1.244622e-4,279.83218,118.08326)"
- id="g6765">
- <path
- style="color:#000000;fill:url(#linearGradient3907);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3909);stroke-width:0.68507993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="csccccccccccccccccsccsssc"
- id="path6767"
- d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.39524,1.39524 -1.5,1.5 0,1 2.10476,1.10476 0,1 -2,1 0,1 1.3254,1.3254 -1.1508,1.1508 0.374619,1.468424 1.846021,1.880776 2.22064,0 1.38412,-1.3254 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.3;fill:url(#linearGradient3911);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path6769"
- d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.6;fill:url(#linearGradient3913);fill-opacity:1;fill-rule:evenodd;stroke:none"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-0.10364762"
- inkscape:original="M 13.40625 17.53125 C 13.179953 17.535742 12.940048 17.565361 12.71875 17.59375 C 11.746507 17.718472 10.844502 18.056009 10.0625 18.5625 C 10.273788 19.382459 10.603512 20.028723 11 20.59375 C 10.998818 20.562191 11 20.531846 11 20.5 C 11 19.119998 12.119999 18 13.5 18 C 14.880001 18 16 19.119998 16 20.5 C 16 21.880003 14.880001 23 13.5 23 C 13.338115 23 13.184591 22.966937 13.03125 22.9375 C 14.159156 24.243071 15.219875 25.922289 15.46875 29.3125 C 17.839227 28.416828 19.53125 26.324417 19.53125 23.5625 C 19.444481 20.923505 17.958879 18.870351 15.46875 17.84375 C 14.777284 17.614671 14.085142 17.517773 13.40625 17.53125 z M 15.46875 31.96875 C 15.356466 34.978468 14.778907 38.970391 13.4375 44.46875 L 14.78125 44.46875 L 15.46875 43.125 L 15.46875 31.96875 z "
- id="path6832"
- d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z" />
- <rect
- y="-14.84375"
- x="29"
- width="16.311773"
- transform="matrix(0,1,-1,0,0,0)"
- style="color:#000000;fill:url(#linearGradient3915);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.79014987px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect6776"
- height="0.98128641" />
- <path
- d="m 13.4375,17.3125 c -3.4801559,-1e-6 -6.28125,2.787977 -6.28125,6.25 2e-7,2.508186 1.4242699,4.687474 3.53125,5.6875 A 0.81679083,0.81679083 0 0 1 11.15625,30 l 0,1.1875 1.15625,1.15625 a 0.81679083,0.81679083 0 0 1 0,1.125 l -1.25,1.25 0,0.1875 1.65625,0.875 A 0.81679083,0.81679083 0 0 1 13.15625,36.5 l 0,1 a 0.81679083,0.81679083 0 0 1 -0.4375,0.71875 L 11.15625,39 l 0,0.1875 1.0625,1.0625 A 0.81679083,0.81679083 0 0 1 12.25,41.375 L 11.4375,42.21875 11.625,43 l 1.46875,1.5 1.53125,0 0.90625,-0.84375 0,-13.65625 A 0.81679083,0.81679083 0 0 1 16,29.25 c 2.076228,-1.002425 3.53125,-3.264837 3.53125,-5.75 0,-3.488167 -2.60491,-6.1875 -6.09375,-6.1875 z m -0.09375,0.375 c 1.545891,0 2.8125,1.266609 2.8125,2.8125 0,1.545891 -1.266609,2.8125 -2.8125,2.8125 -1.545891,0 -2.8125,-1.266609 -2.8125,-2.8125 0,-1.545891 1.266609,-2.8125 2.8125,-2.8125 z"
- inkscape:href="#path6767"
- id="path6313"
- style="color:#000000;fill:none;stroke:url(#linearGradient3917);stroke-width:0.68507993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- xlink:href="#path6767"
- inkscape:original="M 13.4375 16.5 C 9.5186162 16.499999 6.34375 19.657775 6.34375 23.5625 C 6.3437502 26.380698 7.9483759 28.863095 10.34375 30 L 10.34375 31.5 L 11.75 32.90625 L 10.25 34.40625 L 10.25 35.40625 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.65625 40.8125 L 10.53125 41.96875 L 10.90625 43.4375 L 12.75 45.3125 L 14.96875 45.3125 L 16.34375 44 L 16.34375 30 C 18.716179 28.854566 20.34375 26.301484 20.34375 23.5 C 20.34375 19.595276 17.356384 16.5 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- inkscape:radius="-0.81670916"
- sodipodi:type="inkscape:offset" />
- </g>
- <g
- transform="matrix(9.4955145e-4,-0.89007416,0.89007416,9.4955145e-4,288.00153,167.01742)"
- id="g193"
- inkscape:export-filename="/data/projects/seahorse/32x32.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- style="color:#000000;fill:url(#linearGradient4907);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4909);stroke-width:1.1235013;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="csccccccccccccccccsccsssc"
- id="path195"
- d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.5,2 2.5,0 1,-1.5 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.3;fill:url(#linearGradient4911);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path197"
- d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z"
- inkscape:connector-curvature="0" />
- <path
- xlink:href="#path1884"
- style="fill:none;stroke:#ffffff;stroke-width:1.12350094;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.1191492"
- inkscape:original="M 13.4375 16.5 C 9.5186162 16.499999 6.34375 19.657775 6.34375 23.5625 C 6.3437502 26.380698 7.9483759 28.863095 10.34375 30 L 10.34375 31.5 L 11.84375 33 L 10.34375 34.5 L 10.34375 35.5 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.84375 41 L 10.34375 42.5 L 10.34375 43.5 L 12.84375 45.5 L 15.34375 45.5 L 16.34375 44 L 16.34375 30 C 18.716179 28.854566 20.34375 26.301484 20.34375 23.5 C 20.34375 19.595276 17.356384 16.5 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- inkscape:href="#path1884"
- id="path199"
- d="m 14.3125,17.78125 c 1.186974,0.442749 2.15625,1.386496 2.15625,2.71875 0,1.70953 -1.41547,3.125 -3.125,3.125 -1.70953,0 -3.125,-1.41547 -3.125,-3.125 0,-1.246778 0.868438,-2.127736 1.9375,-2.625 -2.6767585,0.591658 -4.6875,2.839731 -4.6875,5.6875 2e-7,2.393384 1.3435667,4.488163 3.34375,5.4375 a 1.1192611,1.1192611 0 0 1 0.65625,1 l 0,1.0625 1.15625,1.15625 a 1.1192611,1.1192611 0 0 1 0,1.5625 l -1.0625,1.0625 1.28125,0.65625 a 1.1192611,1.1192611 0 0 1 0.625,1 l 0,1 a 1.1192611,1.1192611 0 0 1 -0.625,1 l -1.28125,0.65625 1.0625,1.0625 a 1.1192611,1.1192611 0 0 1 0,1.5625 l -1.15625,1.15625 0,0.03125 1.75,1.40625 1.53125,0 0.46875,-0.71875 0,-13.65625 a 1.1192611,1.1192611 0 0 1 0.625,-1 c 1.966541,-0.949467 3.375,-3.131976 3.375,-5.5 0,-3.019151 -2.052931,-5.297441 -4.90625,-5.71875 z" />
- <path
- style="opacity:0.6;fill:url(#linearGradient4913);fill-opacity:1;fill-rule:evenodd;stroke:none"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-0.10364762"
- inkscape:original="M 13.40625 17.53125 C 13.179953 17.535742 12.940048 17.565361 12.71875 17.59375 C 11.746507 17.718472 10.844502 18.056009 10.0625 18.5625 C 10.273788 19.382459 10.603512 20.028723 11 20.59375 C 10.998818 20.562191 11 20.531846 11 20.5 C 11 19.119998 12.119999 18 13.5 18 C 14.880001 18 16 19.119998 16 20.5 C 16 21.880003 14.880001 23 13.5 23 C 13.338115 23 13.184591 22.966937 13.03125 22.9375 C 14.159156 24.243071 15.219875 25.922289 15.46875 29.3125 C 17.839227 28.416828 19.53125 26.324417 19.53125 23.5625 C 19.444481 20.923505 17.958879 18.870351 15.46875 17.84375 C 14.777284 17.614671 14.085142 17.517773 13.40625 17.53125 z M 15.46875 31.96875 C 15.356466 34.978468 14.778907 38.970391 13.4375 44.46875 L 14.78125 44.46875 L 15.46875 43.125 L 15.46875 31.96875 z "
- id="path201"
- d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z" />
- <rect
- y="-14.84375"
- x="29"
- width="16.311773"
- transform="matrix(0,1,-1,0,0,0)"
- style="opacity:0.61538463;color:#000000;fill:none;stroke:url(#linearGradient4915);stroke-width:1.1235013px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect203"
- height="0.98128641" />
- </g>
- <g
- transform="matrix(0.7179987,-0.69604444,0.69604444,0.7179987,300.63641,201.31637)"
- id="g6111"
- style="display:inline;enable-background:new"
- inkscape:export-filename="/data/projects/seahorse/24x24.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- style="color:#000000;fill:url(#linearGradient4085);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4087);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path7124"
- d="m 5.5,0.5 c -1.2798634,3e-8 -2.5554427,0.49294272 -3.53125,1.46875 -1.95161458,1.9516146 -1.95161484,5.1108852 0,7.0625 1.4457774,1.445777 3.5519739,1.790068 5.34375,1.09375 L 8,11 l 1.5,-0.5 0,2 2,0 0,1.5 0.5,0.5 c 0,0 3,0 3,0 l 0.5,-0.5 0,-1.5 -5.375,-5.1875 C 10.821318,5.5207238 10.477027,3.4145274 9.03125,1.96875 8.0554428,0.9929426 6.7798634,0.49999997 5.5,0.5 z m -1,3 c 0.2559728,0 0.5235884,0.086088 0.71875,0.28125 0.3903234,0.3903232 0.3903232,1.0471768 0,1.4375 -0.3903229,0.390323 -1.0471768,0.3903232 -1.4375,0 -0.3903232,-0.3903233 -0.3903232,-1.0471768 0,-1.4375 C 3.9764116,3.5860884 4.2440272,3.5 4.5,3.5 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.13574662;fill:url(#linearGradient4089);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path6142"
- d="M 9.543012,3.5767984 3.5767984,9.543012 C 5.2474506,10.334846 7.2996521,10.062799 8.6812256,8.6812256 10.062799,7.2996522 10.334847,5.2474503 9.543012,3.5767984 z"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(0.942809,0.942809,-0.942809,0.942809,3.5574935,-7.7562147)"
- style="fill:none;stroke:url(#linearGradient4091);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="arc"
- sodipodi:ry="1.5"
- sodipodi:rx="1.5"
- sodipodi:cy="6"
- sodipodi:cx="7"
- id="path7134"
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z" />
- <path
- style="opacity:0.42986426;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.0313957"
- inkscape:original="M 5.5 0.5 C 4.2201366 0.50000003 2.9445573 0.99294272 1.96875 1.96875 C 0.017135421 3.9203646 0.017135161 7.0796352 1.96875 9.03125 C 3.4145274 10.477027 5.5207239 10.821318 7.3125 10.125 L 8 11 L 9.5 10.5 L 9.5 12.5 L 11.5 12.5 L 11.5 14 L 12 14.5 C 12 14.5 15 14.5 15 14.5 L 15.5 14 L 15.5 12.5 L 10.125 7.3125 C 10.821318 5.5207238 10.477027 3.4145274 9.03125 1.96875 C 8.0554428 0.9929426 6.7798634 0.49999997 5.5 0.5 z "
- id="path6161"
- d="m 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625 1.1495193,1.149519 2.8195738,1.3996406 4.25,0.84375 A 1.0314988,1.0314988 0 0 1 8.125,9.5 L 8.375,9.8125 9.1875,9.53125 A 1.0314988,1.0314988 0 0 1 10.53125,10.5 l 0,0.96875 0.96875,0 A 1.0314988,1.0314988 0 0 1 12.53125,12.5 l 0,0.96875 1.9375,0 0,-0.53125 -5.0625,-4.875 a 1.0314988,1.0314988 0 0 1 -0.25,-1.125 C 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 z" />
- <path
- style="fill:none;stroke:url(#linearGradient4093);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992"
- sodipodi:nodetypes="cccsscsc"
- id="path6750"
- d="m 14.46875,13.46875 0,-0.53125 -5.0625,-4.875 C 9.1016694,7.7733588 9.0027957,7.3284268 9.15625,6.9375 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient4095);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:nodetypes="cc"
- id="path6773"
- d="M 13.5,13 9.5,9"
- inkscape:connector-curvature="0" />
- </g>
- <rect
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect4939"
- width="31.875473"
- height="31.876154"
- x="300.05255"
- y="135.0625"
- ry="0"
- inkscape:export-filename="/data/projects/seahorse/32x32.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect4941"
- width="23.874947"
- height="23.874947"
- x="300.05255"
- y="186.0625"
- inkscape:export-filename="/data/projects/seahorse/24x24.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect4943"
- width="15.876632"
- height="15.876632"
- x="300.0625"
- y="219.0625"
- inkscape:export-filename="/data/projects/seahorse/16x16.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect4939-4"
- width="47.81321"
- height="47.814232"
- x="300.0625"
- y="68.0625"
- ry="0" />
- <g
- id="g5198"
- transform="matrix(-0.03314179,-1.4601652,1.4591995,-1.244622e-4,231.83218,113.33326)">
- <path
- inkscape:connector-curvature="0"
- d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.39524,1.39524 -1.5,1.5 0,1 2.10476,1.10476 0,1 -2,1 0,1 1.3254,1.3254 -1.1508,1.1508 0.374619,1.468424 1.846021,1.880776 2.22064,0 1.38412,-1.3254 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- id="path5200"
- sodipodi:nodetypes="csccccccccccccccccsccsssc"
- style="color:#000000;fill:url(#linearGradient5220);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5222);stroke-width:0.68507993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z"
- id="path5202"
- style="opacity:0.3;fill:url(#linearGradient5224);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <path
- d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z"
- id="path5204"
- inkscape:original="M 13.40625 17.53125 C 13.179953 17.535742 12.940048 17.565361 12.71875 17.59375 C 11.746507 17.718472 10.844502 18.056009 10.0625 18.5625 C 10.273788 19.382459 10.603512 20.028723 11 20.59375 C 10.998818 20.562191 11 20.531846 11 20.5 C 11 19.119998 12.119999 18 13.5 18 C 14.880001 18 16 19.119998 16 20.5 C 16 21.880003 14.880001 23 13.5 23 C 13.338115 23 13.184591 22.966937 13.03125 22.9375 C 14.159156 24.243071 15.219875 25.922289 15.46875 29.3125 C 17.839227 28.416828 19.53125 26.324417 19.53125 23.5625 C 19.444481 20.923505 17.958879 18.870351 15.46875 17.84375 C 14.777284 17.614671 14.085142 17.517773 13.40625 17.53125 z M 15.46875 31.96875 C 15.356466 34.978468 14.778907 38.970391 13.4375 44.46875 L 14.78125 44.46875 L 15.46875 43.125 L 15.46875 31.96875 z "
- inkscape:radius="-0.10364762"
- sodipodi:type="inkscape:offset"
- style="opacity:0.6;fill:url(#linearGradient5226);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <rect
- height="0.98128641"
- id="rect5206"
- style="color:#000000;fill:url(#linearGradient5228);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.79014987px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(0,1,-1,0,0,0)"
- width="16.311773"
- x="29"
- y="-14.84375" />
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="-0.81670916"
- inkscape:original="M 13.4375 16.5 C 9.5186162 16.499999 6.34375 19.657775 6.34375 23.5625 C 6.3437502 26.380698 7.9483759 28.863095 10.34375 30 L 10.34375 31.5 L 11.75 32.90625 L 10.25 34.40625 L 10.25 35.40625 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.65625 40.8125 L 10.53125 41.96875 L 10.90625 43.4375 L 12.75 45.3125 L 14.96875 45.3125 L 16.34375 44 L 16.34375 30 C 18.716179 28.854566 20.34375 26.301484 20.34375 23.5 C 20.34375 19.595276 17.356384 16.5 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- xlink:href="#path6767"
- style="color:#000000;fill:none;stroke:url(#linearGradient5230);stroke-width:0.68507993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path5208"
- inkscape:href="#path6767"
- d="m 13.4375,17.3125 c -3.4801559,-1e-6 -6.28125,2.787977 -6.28125,6.25 2e-7,2.508186 1.4242699,4.687474 3.53125,5.6875 A 0.81679083,0.81679083 0 0 1 11.15625,30 l 0,1.1875 1.15625,1.15625 a 0.81679083,0.81679083 0 0 1 0,1.125 l -1.25,1.25 0,0.1875 1.65625,0.875 A 0.81679083,0.81679083 0 0 1 13.15625,36.5 l 0,1 a 0.81679083,0.81679083 0 0 1 -0.4375,0.71875 L 11.15625,39 l 0,0.1875 1.0625,1.0625 A 0.81679083,0.81679083 0 0 1 12.25,41.375 L 11.4375,42.21875 11.625,43 l 1.46875,1.5 1.53125,0 0.90625,-0.84375 0,-13.65625 A 0.81679083,0.81679083 0 0 1 16,29.25 c 2.076228,-1.002425 3.53125,-3.264837 3.53125,-5.75 0,-3.488167 -2.60491,-6.1875 -6.09375,-6.1875 z m -0.09375,0.375 c 1.545891,0 2.8125,1.266609 2.8125,2.8125 0,1.545891 -1.266609,2.8125 -2.8125,2.8125 -1.545891,0 -2.8125,-1.266609 -2.8125,-2.8125 0,-1.545891 1.266609,-2.8125 2.8125,-2.8125 z" />
- </g>
- <rect
- ry="0"
- y="68.0625"
- x="252.0625"
- height="47.814232"
- width="47.81321"
- id="rect5210"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/32x32.png"
- d="m 12.0625,2.0625 a 0.90625,0.5625 0 1 1 -1.8125,0 0.90625,0.5625 0 1 1 1.8125,0 z"
- id="path5232"
- sodipodi:cx="11.15625"
- sodipodi:cy="2.0625"
- sodipodi:rx="0.90625"
- sodipodi:ry="0.5625"
- sodipodi:type="arc"
- style="fill:url(#radialGradient5256);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(0.5532396,-0.54421924,0.87679765,0.89133046,265.34092,149.00568)" />
- <g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/32x32.png"
- id="g5242"
- transform="matrix(9.4955145e-4,-0.89007416,0.89007416,9.4955145e-4,256.00153,164.01742)">
- <path
- inkscape:connector-curvature="0"
- d="m 13.4375,16.5 c -3.9188838,-1e-6 -7.09375,3.157775 -7.09375,7.0625 2e-7,2.818198 1.6046259,5.300595 4,6.4375 l 0,1.5 1.5,1.5 -1.5,1.5 0,1 2,1 0,1 -2,1 0,1 1.5,1.5 -1.5,1.5 0,1 2.5,2 2.5,0 1,-1.5 0,-14 c 2.372429,-1.145434 4,-3.698516 4,-6.5 0,-3.904724 -2.987366,-7 -6.90625,-7 z m -0.09375,2 c 1.104,0 2,0.896 2,2 0,1.104 -0.896,2 -2,2 -1.104,0 -2,-0.896 -2,-2 0,-1.104 0.896,-2 2,-2 z"
- id="path5244"
- sodipodi:nodetypes="csccccccccccccccccsccsssc"
- style="color:#000000;fill:url(#linearGradient5266);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5268);stroke-width:1.1235013;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- d="M 18.846598,24 8.028422,24 c 0,2.76 2.423271,5 5.409088,5 2.985817,0 5.409088,-2.24 5.409088,-5 z"
- id="path5246"
- style="opacity:0.3;fill:url(#linearGradient5270);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <path
- d="m 14.3125,17.78125 c 1.186974,0.442749 2.15625,1.386496 2.15625,2.71875 0,1.70953 -1.41547,3.125 -3.125,3.125 -1.70953,0 -3.125,-1.41547 -3.125,-3.125 0,-1.246778 0.868438,-2.127736 1.9375,-2.625 -2.6767585,0.591658 -4.6875,2.839731 -4.6875,5.6875 2e-7,2.393384 1.3435667,4.488163 3.34375,5.4375 a 1.1192611,1.1192611 0 0 1 0.65625,1 l 0,1.0625 1.15625,1.15625 a 1.1192611,1.1192611 0 0 1 0,1.5625 l -1.0625,1.0625 1.28125,0.65625 a 1.1192611,1.1192611 0 0 1 0.625,1 l 0,1 a 1.1192611,1.1192611 0 0 1 -0.625,1 l -1.28125,0.65625 1.0625,1.0625 a 1.1192611,1.1192611 0 0 1 0,1.5625 l -1.15625,1.15625 0,0.03125 1.75,1.40625 1.53125,0 0.46875,-0.71875 0,-13.65625 a 1.1192611,1.1192611 0 0 1 0.625,-1 c 1.966541,-0.949467 3.375,-3.131976 3.375,-5.5 0,-3.019151 -2.052931,-5.297441 -4.90625,-5.71875 z"
- id="path5248"
- inkscape:href="#path1884"
- inkscape:original="M 13.4375 16.5 C 9.5186162 16.499999 6.34375 19.657775 6.34375 23.5625 C 6.3437502 26.380698 7.9483759 28.863095 10.34375 30 L 10.34375 31.5 L 11.84375 33 L 10.34375 34.5 L 10.34375 35.5 L 12.34375 36.5 L 12.34375 37.5 L 10.34375 38.5 L 10.34375 39.5 L 11.84375 41 L 10.34375 42.5 L 10.34375 43.5 L 12.84375 45.5 L 15.34375 45.5 L 16.34375 44 L 16.34375 30 C 18.716179 28.854566 20.34375 26.301484 20.34375 23.5 C 20.34375 19.595276 17.356384 16.5 13.4375 16.5 z M 13.34375 18.5 C 14.44775 18.5 15.34375 19.396 15.34375 20.5 C 15.34375 21.604 14.44775 22.5 13.34375 22.5 C 12.23975 22.5 11.34375 21.604 11.34375 20.5 C 11.34375 19.396 12.23975 18.5 13.34375 18.5 z "
- inkscape:radius="-1.1191492"
- sodipodi:type="inkscape:offset"
- style="fill:none;stroke:#ffffff;stroke-width:1.12350094;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- xlink:href="#path1884" />
- <path
- d="m 13.40625,17.625 c -0.218712,0.0043 -0.466555,0.03416 -0.6875,0.0625 -0.93254,0.119629 -1.775868,0.460272 -2.53125,0.9375 0.173643,0.634817 0.42464,1.158079 0.71875,1.625 0.125954,-1.319354 1.241853,-2.34375 2.59375,-2.34375 1.436081,0 2.59375,1.157668 2.59375,2.59375 0,1.436083 -1.157669,2.59375 -2.59375,2.59375 -0.07717,0 -0.14697,-0.02119 -0.21875,-0.03125 1.059311,1.270254 2.021943,2.944267 2.28125,6.09375 2.266237,-0.909044 3.875,-2.925566 3.875,-5.59375 -0.08555,-2.601924 -1.541462,-4.611423 -4,-5.625 -0.680148,-0.225329 -1.363612,-0.325754 -2.03125,-0.3125 z M 15.375,34.6875 c -0.279435,2.585586 -0.854558,5.742004 -1.8125,9.6875 l 1.15625,0 0.65625,-1.3125 0,-8.375 z"
- id="path5250"
- inkscape:original="M 13.40625 17.53125 C 13.179953 17.535742 12.940048 17.565361 12.71875 17.59375 C 11.746507 17.718472 10.844502 18.056009 10.0625 18.5625 C 10.273788 19.382459 10.603512 20.028723 11 20.59375 C 10.998818 20.562191 11 20.531846 11 20.5 C 11 19.119998 12.119999 18 13.5 18 C 14.880001 18 16 19.119998 16 20.5 C 16 21.880003 14.880001 23 13.5 23 C 13.338115 23 13.184591 22.966937 13.03125 22.9375 C 14.159156 24.243071 15.219875 25.922289 15.46875 29.3125 C 17.839227 28.416828 19.53125 26.324417 19.53125 23.5625 C 19.444481 20.923505 17.958879 18.870351 15.46875 17.84375 C 14.777284 17.614671 14.085142 17.517773 13.40625 17.53125 z M 15.46875 31.96875 C 15.356466 34.978468 14.778907 38.970391 13.4375 44.46875 L 14.78125 44.46875 L 15.46875 43.125 L 15.46875 31.96875 z "
- inkscape:radius="-0.10364762"
- sodipodi:type="inkscape:offset"
- style="opacity:0.6;fill:url(#linearGradient5272);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <rect
- height="0.98128641"
- id="rect5252"
- style="opacity:0.61538463;color:#000000;fill:none;stroke:url(#linearGradient5274);stroke-width:1.1235013px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(0,1,-1,0,0,0)"
- width="16.311773"
- x="29"
- y="-14.84375" />
- </g>
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/32x32.png"
- ry="0"
- y="135.0625"
- x="268.05255"
- height="31.876154"
- width="31.875473"
- id="rect5254"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/24x24.png"
- style="display:inline;enable-background:new"
- id="g5288"
- transform="matrix(0.7179987,-0.69604444,0.69604444,0.7179987,276.63641,199.31637)">
- <path
- inkscape:connector-curvature="0"
- d="m 5.5,0.5 c -1.2798634,3e-8 -2.5554427,0.49294272 -3.53125,1.46875 -1.95161458,1.9516146 -1.95161484,5.1108852 0,7.0625 1.4457774,1.445777 3.5519739,1.790068 5.34375,1.09375 L 8,11 l 1.5,-0.5 0,2 2,0 0,1.5 0.5,0.5 c 0,0 3,0 3,0 l 0.5,-0.5 0,-1.5 -5.375,-5.1875 C 10.821318,5.5207238 10.477027,3.4145274 9.03125,1.96875 8.0554428,0.9929426 6.7798634,0.49999997 5.5,0.5 z m -1,3 c 0.2559728,0 0.5235884,0.086088 0.71875,0.28125 0.3903234,0.3903232 0.3903232,1.0471768 0,1.4375 -0.3903229,0.390323 -1.0471768,0.3903232 -1.4375,0 -0.3903232,-0.3903233 -0.3903232,-1.0471768 0,-1.4375 C 3.9764116,3.5860884 4.2440272,3.5 4.5,3.5 z"
- id="path5290"
- style="color:#000000;fill:url(#linearGradient5316);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5318);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- d="M 9.543012,3.5767984 3.5767984,9.543012 C 5.2474506,10.334846 7.2996521,10.062799 8.6812256,8.6812256 10.062799,7.2996522 10.334847,5.2474503 9.543012,3.5767984 z"
- id="path5292"
- style="opacity:0.13574662;fill:url(#linearGradient5320);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <path
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z"
- id="path5294"
- sodipodi:cx="7"
- sodipodi:cy="6"
- sodipodi:rx="1.5"
- sodipodi:ry="1.5"
- sodipodi:type="arc"
- style="fill:none;stroke:url(#linearGradient5322);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- transform="matrix(0.942809,0.942809,-0.942809,0.942809,3.5574935,-7.7562147)" />
- <path
- d="m 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625 1.1495193,1.149519 2.8195738,1.3996406 4.25,0.84375 A 1.0314988,1.0314988 0 0 1 8.125,9.5 L 8.375,9.8125 9.1875,9.53125 A 1.0314988,1.0314988 0 0 1 10.53125,10.5 l 0,0.96875 0.96875,0 A 1.0314988,1.0314988 0 0 1 12.53125,12.5 l 0,0.96875 1.9375,0 0,-0.53125 -5.0625,-4.875 a 1.0314988,1.0314988 0 0 1 -0.25,-1.125 C 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 z"
- id="path5296"
- inkscape:original="M 5.5 0.5 C 4.2201366 0.50000003 2.9445573 0.99294272 1.96875 1.96875 C 0.017135421 3.9203646 0.017135161 7.0796352 1.96875 9.03125 C 3.4145274 10.477027 5.5207239 10.821318 7.3125 10.125 L 8 11 L 9.5 10.5 L 9.5 12.5 L 11.5 12.5 L 11.5 14 L 12 14.5 C 12 14.5 15 14.5 15 14.5 L 15.5 14 L 15.5 12.5 L 10.125 7.3125 C 10.821318 5.5207238 10.477027 3.4145274 9.03125 1.96875 C 8.0554428 0.9929426 6.7798634 0.49999997 5.5 0.5 z "
- inkscape:radius="-1.0313957"
- sodipodi:type="inkscape:offset"
- style="opacity:0.42986426;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992" />
- <path
- inkscape:connector-curvature="0"
- d="m 14.46875,13.46875 0,-0.53125 -5.0625,-4.875 C 9.1016694,7.7733588 9.0027957,7.3284268 9.15625,6.9375 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625"
- id="path5298"
- sodipodi:nodetypes="cccsscsc"
- style="fill:none;stroke:url(#linearGradient5324);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" />
- <path
- inkscape:connector-curvature="0"
- d="M 13.5,13 9.5,9"
- id="path5300"
- sodipodi:nodetypes="cc"
- style="fill:none;stroke:url(#linearGradient5326);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
- </g>
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/24x24.png"
- y="186.0625"
- x="276.05255"
- height="23.874947"
- width="23.874947"
- id="rect5302"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/seahorse/16x16.png"
- id="g5406"
- transform="matrix(0.00307324,0.73755651,0.73755651,-0.00307324,299.50757,227.71465)">
- <path
- inkscape:connector-curvature="0"
- d="M -0.5017742,6.4584078 C -0.37175202,4.4522829 -0.8448083,2.5 -3.5060582,2.5 -6.2660581,2.5 -6.6064795,4.8828745 -6.625,6.3689418 l -1.8916614,1.1881832 -0.01828,2.1039435 3.0401445,2.3848735 -0.0052,2.529476 L -4.5,16 l -1,1.5 0,1 2,2 0.9999989,0 L -1.5,19.5 -1.51732,12.045942 1.4161394,9.5495158 1.4878836,7.4939418 z M -2.7989514,5.3726214 c 0.1810001,0.1810001 0.3093592,0.4311066 0.3093592,0.7071068 2e-7,0.5520005 -0.4644656,1.016466 -1.016466,1.016466 -0.552,10e-8 -1.016466,-0.4644656 -1.016466,-1.016466 0,-0.5520004 0.4644656,-1.016466 1.016466,-1.016466 0.2760002,0 0.5261067,0.1283591 0.7071068,0.3093592 z"
- id="path5408"
- sodipodi:nodetypes="csccccccccccccccccssssc"
- style="color:#000000;fill:url(#linearGradient5432);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5434);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- d="m 0.71269221,8.9174565 -8.43750041,0 c 0.6214183,1.7412405 2.2649102,3.0000005 4.2187502,3.0000005 1.9538399,0 3.5973328,-1.258759 4.21875021,-3.0000005 z"
- id="path5410"
- style="opacity:0.06334845;fill:url(#linearGradient5436);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <path
- d="m -3.5,3.53125 c -2.2081443,0 -3.96875,1.7606055 -3.96875,3.96875 2e-7,1.6320467 0.9610544,2.971218 2.375,3.59375 a 1.0200495,1.0200495 0 0 1 0.625,0.9375 l 0,2.21875 0.8125,1.15625 a 1.0200495,1.0200495 0 0 1 0,1.15625 l -0.8125,1.21875 0,0.3125 1.375,1.375 0.1875,0 0.375,-0.375 -0.03125,-7.0625 a 1.0200495,1.0200495 0 0 1 0.625,-0.9375 C -0.51947782,10.469423 0.46874976,9.1216542 0.46875,7.5 0.46875008,6.3977756 0.03620106,5.411201 -0.6875,4.6875 -1.411201,3.9637989 -2.3977756,3.53125 -3.5,3.53125 z"
- id="path5412"
- inkscape:original="M -3.5 2.5 C -6.2599999 2.5 -8.5 4.7399998 -8.5 7.5 C -8.4999997 9.5446378 -7.2593482 11.256644 -5.5 12.03125 L -5.5 14.5625 L -4.5 16 L -5.5 17.5 L -5.5 18.5 C -5.5 18.5 -3.5 20.5 -3.5 20.5 L -2.5 20.5 L -1.5 19.5 L -1.53125 12.03125 C 0.22809828 11.256644 1.4999997 9.5446378 1.5 7.5 C 1.5000001 6.12 0.93625013 4.8737501 0.03125 3.96875 C -0.87375013 3.0637498 -2.1200001 2.5 -3.5 2.5 z "
- inkscape:radius="-1.0199475"
- sodipodi:type="inkscape:offset"
- style="opacity:0.52036252;fill:none;stroke:url(#linearGradient5438);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992" />
- <path
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z"
- id="path5414"
- sodipodi:cx="7"
- sodipodi:cy="6"
- sodipodi:rx="1.5"
- sodipodi:ry="1.5"
- sodipodi:type="arc"
- style="fill:none;stroke:url(#linearGradient5440);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- transform="matrix(0,1.3333333,-1.3333333,0,4.493942,-3.3285949)" />
- <path
- inkscape:connector-curvature="0"
- d="m -3.1525046,18.37868 0,-5.656855"
- id="path5416"
- sodipodi:nodetypes="cc"
- style="fill:none;stroke:url(#linearGradient5442);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
- </g>
- <g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/seahorse/16x16.png"
- style="display:inline;enable-background:new"
- id="g5418"
- transform="matrix(0.52956921,-0.51337657,0.51337657,0.52956921,299.23562,229.35209)">
- <path
- inkscape:connector-curvature="0"
- d="m 5.5,0.5 c -1.2798634,3e-8 -2.5554427,0.49294272 -3.53125,1.46875 -1.95161458,1.9516146 -1.95161484,5.1108852 0,7.0625 1.4457774,1.445777 3.5519739,1.790068 5.34375,1.09375 L 8,11 l 1.5,-0.5 0,2 2,0 0,1.5 0.5,0.5 c 0,0 3,0 3,0 l 0.5,-0.5 0,-1.5 -5.375,-5.1875 C 10.821318,5.5207238 10.477027,3.4145274 9.03125,1.96875 8.0554428,0.9929426 6.7798634,0.49999997 5.5,0.5 z m -1,3 c 0.2559728,0 0.5235884,0.086088 0.71875,0.28125 0.3903234,0.3903232 0.3903232,1.0471768 0,1.4375 -0.3903229,0.390323 -1.0471768,0.3903232 -1.4375,0 -0.3903232,-0.3903233 -0.3903232,-1.0471768 0,-1.4375 C 3.9764116,3.5860884 4.2440272,3.5 4.5,3.5 z"
- id="path5420"
- style="color:#000000;fill:url(#linearGradient5444);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5446);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- d="M 9.543012,3.5767984 3.5767984,9.543012 C 5.2474506,10.334846 7.2996521,10.062799 8.6812256,8.6812256 10.062799,7.2996522 10.334847,5.2474503 9.543012,3.5767984 z"
- id="path5422"
- style="opacity:0.13574662;fill:url(#linearGradient5448);fill-opacity:1;fill-rule:evenodd;stroke:none" />
- <path
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z"
- id="path5424"
- sodipodi:cx="7"
- sodipodi:cy="6"
- sodipodi:rx="1.5"
- sodipodi:ry="1.5"
- sodipodi:type="arc"
- style="fill:none;stroke:url(#linearGradient5450);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- transform="matrix(0.942809,0.942809,-0.942809,0.942809,3.5574935,-7.7562147)" />
- <path
- d="m 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625 1.1495193,1.149519 2.8195738,1.3996406 4.25,0.84375 A 1.0314988,1.0314988 0 0 1 8.125,9.5 L 8.375,9.8125 9.1875,9.53125 A 1.0314988,1.0314988 0 0 1 10.53125,10.5 l 0,0.96875 0.96875,0 A 1.0314988,1.0314988 0 0 1 12.53125,12.5 l 0,0.96875 1.9375,0 0,-0.53125 -5.0625,-4.875 a 1.0314988,1.0314988 0 0 1 -0.25,-1.125 C 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 z"
- id="path5426"
- inkscape:original="M 5.5 0.5 C 4.2201366 0.50000003 2.9445573 0.99294272 1.96875 1.96875 C 0.017135421 3.9203646 0.017135161 7.0796352 1.96875 9.03125 C 3.4145274 10.477027 5.5207239 10.821318 7.3125 10.125 L 8 11 L 9.5 10.5 L 9.5 12.5 L 11.5 12.5 L 11.5 14 L 12 14.5 C 12 14.5 15 14.5 15 14.5 L 15.5 14 L 15.5 12.5 L 10.125 7.3125 C 10.821318 5.5207238 10.477027 3.4145274 9.03125 1.96875 C 8.0554428 0.9929426 6.7798634 0.49999997 5.5 0.5 z "
- inkscape:radius="-1.0313957"
- sodipodi:type="inkscape:offset"
- style="opacity:0.42986426;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992" />
- <path
- inkscape:connector-curvature="0"
- d="m 14.46875,13.46875 0,-0.53125 -5.0625,-4.875 C 9.1016694,7.7733588 9.0027957,7.3284268 9.15625,6.9375 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625"
- id="path5428"
- sodipodi:nodetypes="cccsscsc"
- style="fill:none;stroke:url(#linearGradient5452);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992" />
- <path
- inkscape:connector-curvature="0"
- d="M 13.5,13 9.5,9"
- id="path5430"
- sodipodi:nodetypes="cc"
- style="fill:none;stroke:url(#linearGradient5454);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
- </g>
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/16.png"
- y="219.0625"
- x="284.0625"
- height="15.876632"
- width="15.876632"
- id="rect5456"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- transform="matrix(0.52956921,-0.51337657,0.51337657,0.52956921,283.23562,227.35209)"
- id="g5470"
- style="display:inline;enable-background:new"
- inkscape:export-filename="/data/projects/gnome-keyring/gcr/icons/16.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- style="color:#000000;fill:url(#linearGradient5496);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5498);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path5472"
- d="m 5.5,0.5 c -1.2798634,3e-8 -2.5554427,0.49294272 -3.53125,1.46875 -1.95161458,1.9516146 -1.95161484,5.1108852 0,7.0625 1.4457774,1.445777 3.5519739,1.790068 5.34375,1.09375 L 8,11 l 1.5,-0.5 0,2 2,0 0,1.5 0.5,0.5 c 0,0 3,0 3,0 l 0.5,-0.5 0,-1.5 -5.375,-5.1875 C 10.821318,5.5207238 10.477027,3.4145274 9.03125,1.96875 8.0554428,0.9929426 6.7798634,0.49999997 5.5,0.5 z m -1,3 c 0.2559728,0 0.5235884,0.086088 0.71875,0.28125 0.3903234,0.3903232 0.3903232,1.0471768 0,1.4375 -0.3903229,0.390323 -1.0471768,0.3903232 -1.4375,0 -0.3903232,-0.3903233 -0.3903232,-1.0471768 0,-1.4375 C 3.9764116,3.5860884 4.2440272,3.5 4.5,3.5 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.13574662;fill:url(#linearGradient5500);fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="path5474"
- d="M 9.543012,3.5767984 3.5767984,9.543012 C 5.2474506,10.334846 7.2996521,10.062799 8.6812256,8.6812256 10.062799,7.2996522 10.334847,5.2474503 9.543012,3.5767984 z"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(0.942809,0.942809,-0.942809,0.942809,3.5574935,-7.7562147)"
- style="fill:none;stroke:url(#linearGradient5502);stroke-width:0.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="arc"
- sodipodi:ry="1.5"
- sodipodi:rx="1.5"
- sodipodi:cy="6"
- sodipodi:cx="7"
- id="path5476"
- d="M 8.5,6 C 8.5,6.8284271 7.8284271,7.5 7,7.5 6.1715729,7.5 5.5,6.8284271 5.5,6 5.5,5.1715729 6.1715729,4.5 7,4.5 7.8284271,4.5 8.5,5.1715729 8.5,6 z" />
- <path
- style="opacity:0.42986426;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.69999992"
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.0313957"
- inkscape:original="M 5.5 0.5 C 4.2201366 0.50000003 2.9445573 0.99294272 1.96875 1.96875 C 0.017135421 3.9203646 0.017135161 7.0796352 1.96875 9.03125 C 3.4145274 10.477027 5.5207239 10.821318 7.3125 10.125 L 8 11 L 9.5 10.5 L 9.5 12.5 L 11.5 12.5 L 11.5 14 L 12 14.5 C 12 14.5 15 14.5 15 14.5 L 15.5 14 L 15.5 12.5 L 10.125 7.3125 C 10.821318 5.5207238 10.477027 3.4145274 9.03125 1.96875 C 8.0554428 0.9929426 6.7798634 0.49999997 5.5 0.5 z "
- id="path5478"
- d="m 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625 1.1495193,1.149519 2.8195738,1.3996406 4.25,0.84375 A 1.0314988,1.0314988 0 0 1 8.125,9.5 L 8.375,9.8125 9.1875,9.53125 A 1.0314988,1.0314988 0 0 1 10.53125,10.5 l 0,0.96875 0.96875,0 A 1.0314988,1.0314988 0 0 1 12.53125,12.5 l 0,0.96875 1.9375,0 0,-0.53125 -5.0625,-4.875 a 1.0314988,1.0314988 0 0 1 -0.25,-1.125 C 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 z" />
- <path
- style="fill:none;stroke:url(#linearGradient5504);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.69999992"
- sodipodi:nodetypes="cccsscsc"
- id="path5480"
- d="m 14.46875,13.46875 0,-0.53125 -5.0625,-4.875 C 9.1016694,7.7733588 9.0027957,7.3284268 9.15625,6.9375 9.7121406,5.5070736 9.462019,3.8370193 8.3125,2.6875 7.5316707,1.9066705 6.5150336,1.53125 5.5,1.53125 c -1.0150336,0 -2.0316705,0.3754205 -2.8125,1.15625 -1.558081,1.558081 -1.5580812,4.0669188 0,5.625"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient5506);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:nodetypes="cc"
- id="path5482"
- d="M 13.5,13 9.5,9"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="hires"
- style="display:inline">
- <g
- id="g8198"
- transform="matrix(5.0928038,0,0,2.2388776,20.301687,129.4805)"
- style="opacity:0.4" />
- <g
- id="g8230"
- inkscape:label="base"
- style="display:inline"
- transform="matrix(4.8890868,0,0,4.8890868,322.06038,251.81989)" />
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="-1.0153296"
- inkscape:original="M 711.96875 227 C 709.68001 227.00001 707.67461 227.86289 706.5 229.1875 L 706.5 231.625 C 706.5 232.11623 706.8838 232.5 707.375 232.5 L 716.625 232.5 C 717.11622 232.50001 717.5 232.11622 717.5 231.625 L 717.5 229.25 C 716.33242 227.89578 714.28785 227 711.96875 227 z "
- style="opacity:0.35;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path5171-2"
- d="m 711.96875,228 c -1.90789,1e-5 -3.49694,0.75848 -4.46875,1.71875 l 0,1.78125 9,0 0,-1.75 c -0.96562,-0.98703 -2.59089,-1.75 -4.53125,-1.75 z"
- transform="translate(-7.8685593e-7,2.029528e-6)" />
- </g>
- </g>
-</svg>
diff --git a/gcr/icons/render-icons.py b/gcr/icons/render-icons.py
deleted file mode 100755
index d5948569..00000000
--- a/gcr/icons/render-icons.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/env python
-
-# Copied from gnome-icon-theme and adjusted lightly.
-#
-# GNOME icon theme is distributed under the terms of either
-# GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
-
-import os
-import sys
-import xml.sax
-import subprocess
-
-INKSCAPE = '/usr/bin/inkscape'
-OPTIPNG = '/usr/bin/optipng'
-SRC = 'src'
-OUT = '.'
-
-inkscape_process = None
-
-def optimize_png(png_file):
- if os.path.exists(OPTIPNG):
- process = subprocess.Popen([OPTIPNG, '-quiet', '-o7', png_file])
- process.wait()
-
-def wait_for_prompt(process, command=None):
- if command is not None:
- process.stdin.write(command+'\n')
-
- # This is kinda ugly ...
- # Wait for just a '>', or '\n>' if some other char appearead first
- output = process.stdout.read(1)
- if output == '>':
- return
-
- output += process.stdout.read(1)
- while output != "\n>":
- output += process.stdout.read(1)
- output = output[1:]
-
-def start_inkscape():
- process = subprocess.Popen([INKSCAPE, '--shell'], bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
- wait_for_prompt(process)
- return process
-
-def inkscape_render_rect(icon_file, rect, output_file):
- global inkscape_process
- if inkscape_process is None:
- inkscape_process = start_inkscape()
- wait_for_prompt(inkscape_process, '%s -i %s -e %s' % (icon_file, rect, output_file))
- optimize_png(output_file)
-
-class ContentHandler(xml.sax.ContentHandler):
- ROOT = 0
- SVG = 1
- LAYER = 2
- OTHER = 3
- TEXT = 4
- def __init__(self, path, force=False, filter=None):
- self.stack = [self.ROOT]
- self.inside = [self.ROOT]
- self.path = path
- self.rects = []
- self.state = self.ROOT
- self.chars = ""
- self.force = force
- self.filter = filter
-
- def endDocument(self):
- pass
-
- def startElement(self, name, attrs):
- if self.inside[-1] == self.ROOT:
- if name == "svg":
- self.stack.append(self.SVG)
- self.inside.append(self.SVG)
- return
- elif self.inside[-1] == self.SVG:
- if (name == "g" and attrs.has_key('inkscape:groupmode') and attrs.has_key('inkscape:label')
- and attrs['inkscape:groupmode'] == 'layer' and attrs['inkscape:label'].startswith('baseplate')):
- self.stack.append(self.LAYER)
- self.inside.append(self.LAYER)
- self.context = None
- self.icon_name = None
- self.rects = []
- return
- elif self.inside[-1] == self.LAYER:
- if name == "text" and attrs.has_key('inkscape:label') and attrs['inkscape:label'] == 'context':
- self.stack.append(self.TEXT)
- self.inside.append(self.TEXT)
- self.text='context'
- self.chars = ""
- return
- elif name == "text" and attrs.has_key('inkscape:label') and attrs['inkscape:label'] == 'icon-name':
- self.stack.append(self.TEXT)
- self.inside.append(self.TEXT)
- self.text='icon-name'
- self.chars = ""
- return
- elif name == "rect":
- self.rects.append(attrs)
-
- self.stack.append(self.OTHER)
-
-
- def endElement(self, name):
- stacked = self.stack.pop()
- if self.inside[-1] == stacked:
- self.inside.pop()
-
- if stacked == self.TEXT and self.text is not None:
- assert self.text in ['context', 'icon-name']
- if self.text == 'context':
- self.context = self.chars
- elif self.text == 'icon-name':
- self.icon_name = self.chars
- self.text = None
- elif stacked == self.LAYER:
- assert self.icon_name
- assert self.context
-
- if self.filter is not None and not self.icon_name in self.filter:
- return
-
- print '%s %s' % (self.context, self.icon_name)
- for rect in self.rects:
- width = rect['width']
- height = rect['height']
- id = rect['id']
-
- # dir = os.path.join(OUT, "%sx%s" % (width, height), self.context)
- dir = os.path.join(OUT, "%sx%s" % (width, height))
- outfile = os.path.join(dir, self.icon_name+'.png')
- if not os.path.exists(dir):
- os.makedirs(dir)
- # Do a time based check!
- if self.force or not os.path.exists(outfile):
- inkscape_render_rect(self.path, id, outfile)
- sys.stdout.write('.')
- else:
- stat_in = os.stat(self.path)
- stat_out = os.stat(outfile)
- if stat_in.st_mtime > stat_out.st_mtime:
- inkscape_render_rect(self.path, id, outfile)
- sys.stdout.write('.')
- else:
- sys.stdout.write('-')
- sys.stdout.flush()
- sys.stdout.write('\n')
- sys.stdout.flush()
-
- def characters(self, chars):
- self.chars += chars.strip()
-
-if len(sys.argv) == 1:
- if not os.path.exists(OUT):
- os.mkdir(OUT)
- print 'Rendering from SVGs in %s' % SRC
- for file in os.listdir(SRC):
- if file[-4:] == '.svg':
- file = os.path.join(SRC, file)
- handler = ContentHandler(file)
- xml.sax.parse(open(file), handler)
-else:
- file = os.path.join(SRC, sys.argv[1] + '.svg')
- if len(sys.argv) > 2:
- icons = sys.argv[2:]
- else:
- icons = None
- if os.path.exists(os.path.join(file)):
- handler = ContentHandler(file, True, filter=icons)
- xml.sax.parse(open(file), handler)
- else:
- print "Error: No such file %s" % file
- sys.exit(1)
diff --git a/gcr/icons/src/gcr-smart-card.svg b/gcr/icons/src/gcr-smart-card.svg
deleted file mode 100644
index 51a37611..00000000
--- a/gcr/icons/src/gcr-smart-card.svg
+++ /dev/null
@@ -1,1165 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- inkscape:export-ydpi="90.000000"
- inkscape:export-xdpi="90.000000"
- inkscape:export-filename="/home/lapo/firewall.png"
- width="400"
- height="300"
- id="svg11300"
- sodipodi:version="0.32"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="gcr-smart-card.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- version="1.0"
- style="display:inline;enable-background:new">
- <title
- id="title4872">Firewall</title>
- <sodipodi:namedview
- stroke="#ef2929"
- fill="#f57900"
- id="base"
- pagecolor="#474747"
- bordercolor="#666666"
- borderopacity="0.25490196"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:zoom="31.059262"
- inkscape:cx="310.4148"
- inkscape:cy="75.246655"
- inkscape:current-layer="layer4"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:showpageshadow="false"
- inkscape:window-width="1278"
- inkscape:window-height="866"
- inkscape:window-x="1345"
- inkscape:window-y="34"
- width="400px"
- height="300px"
- inkscape:snap-nodes="false"
- inkscape:snap-bbox="false"
- gridtolerance="10000"
- inkscape:object-nodes="true"
- inkscape:snap-grids="true"
- showguides="false"
- inkscape:guide-bbox="true"
- inkscape:window-maximized="0">
- <inkscape:grid
- spacingy="1px"
- spacingx="1px"
- id="grid5883"
- type="xygrid"
- enabled="true"
- visible="true"
- empspacing="4"
- snapvisiblegridlinesonly="true" />
- <inkscape:grid
- type="xygrid"
- id="grid11592"
- empspacing="2"
- visible="true"
- enabled="false"
- spacingx="0.5px"
- spacingy="0.5px"
- color="#ff0000"
- opacity="0.1254902"
- empcolor="#ff0000"
- empopacity="0.25098039"
- snapvisiblegridlinesonly="true" />
- <sodipodi:guide
- orientation="-0.70710678,0.70710678"
- position="309.8125,173.625"
- id="guide9630" />
- <sodipodi:guide
- orientation="1,0"
- position="155.01758,221.5"
- id="guide4407" />
- <sodipodi:guide
- orientation="1,0"
- position="244.125,212.625"
- id="guide4409" />
- <sodipodi:guide
- orientation="1,0"
- position="184.875,211.625"
- id="guide4411" />
- <sodipodi:guide
- orientation="1,0"
- position="213.875,214.25"
- id="guide4413" />
- </sodipodi:namedview>
- <defs
- id="defs3">
- <linearGradient
- id="linearGradient6048">
- <stop
- style="stop-color:#edd400;stop-opacity:1;"
- offset="0"
- id="stop6050" />
- <stop
- id="stop6052"
- offset="0.25"
- style="stop-color:#c7b201;stop-opacity:1;" />
- <stop
- id="stop6054"
- offset="0.5"
- style="stop-color:#af9c05;stop-opacity:1;" />
- <stop
- style="stop-color:#ffeb3e;stop-opacity:1;"
- offset="1"
- id="stop6056" />
- </linearGradient>
- <linearGradient
- id="linearGradient5987">
- <stop
- style="stop-color:#c4a000;stop-opacity:1;"
- offset="0"
- id="stop5989" />
- <stop
- style="stop-color:#997e00;stop-opacity:1;"
- offset="1"
- id="stop5991" />
- </linearGradient>
- <linearGradient
- id="linearGradient5540">
- <stop
- id="stop5542"
- offset="0"
- style="stop-color:#fc8817;stop-opacity:1;" />
- <stop
- id="stop5544"
- offset="1"
- style="stop-color:#fc8817;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient5532">
- <stop
- style="stop-color:#719fcf;stop-opacity:1;"
- offset="0"
- id="stop5534" />
- <stop
- style="stop-color:#3466a4;stop-opacity:1;"
- offset="1"
- id="stop5536" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath9887">
- <path
- d="m 32.1875,0 c -4.917465,0.322114 -6.796581,5.25981 -6.46875,9.125 l 0,211.8125 c 0.365597,5.50865 5.236892,11.01932 12.5,10.46875 l 167.0625,0 c 4.68699,-0.22612 9.31856,-4.12416 9.25,-11.84375 l 0,-193.71875 c 0,-3.758448 -1.21492,-6.263069 -3.96875,-8.96875 L 196.15625,2 C 194.64949,0.576511 193.73508,0 189.5625,0 L 32.1875,0 z"
- inkscape:href="#path9521"
- id="path9889"
- style="fill:none;stroke:#343a3b;stroke-width:0.38129407;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible"
- xlink:href="#path9521"
- inkscape:original="M 66.4375 95.9375 C 61.520035 96.259614 59.609669 101.19731 59.9375 105.0625 L 59.9375 316.875 C 60.303097 322.38365 65.174392 327.89432 72.4375 327.34375 L 239.53125 327.34375 C 244.21824 327.11763 248.84981 323.21959 248.78125 315.5 L 248.78125 121.78125 C 248.78125 118.0228 247.56633 115.51818 244.8125 112.8125 L 230.375 97.9375 C 228.86824 96.514011 227.95383 95.9375 223.78125 95.9375 L 66.4375 95.9375 z "
- inkscape:radius="0"
- sodipodi:type="inkscape:offset" />
- </clipPath>
- <linearGradient
- id="linearGradient9941">
- <stop
- id="stop9943"
- offset="0"
- style="stop-color:#edd400;stop-opacity:1;" />
- <stop
- style="stop-color:#bda901;stop-opacity:1;"
- offset="0.25"
- id="stop9959" />
- <stop
- style="stop-color:#a08f05;stop-opacity:1"
- offset="0.5"
- id="stop9945" />
- <stop
- id="stop9947"
- offset="1"
- style="stop-color:#ffeb3e;stop-opacity:1;" />
- </linearGradient>
- <pattern
- inkscape:stockid="Sand (bitmap)"
- id="sand_bitmap"
- height="256"
- width="256"
- patternUnits="userSpaceOnUse"
- patternTransform="matrix(0.1089357,0,0,0.1089357,304.12642,53.923124)">
- <!-- Seamless texture provided by FreeSeamlessTextures.com -->
- <!-- License: creative commons attribution -->
- <image
- xlink:href="data:image/jpeg;base64,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 /p1//9k= "
- y="0"
- x="0"
- id="image9"
- height="260"
- width="260" />
- </pattern>
- <linearGradient
- id="linearGradient9326">
- <stop
- id="stop9328"
- offset="0"
- style="stop-color:#555753;stop-opacity:1;" />
- <stop
- style="stop-color:#555652;stop-opacity:1"
- offset="0.52639353"
- id="stop9342" />
- <stop
- style="stop-color:#5e605b;stop-opacity:1"
- offset="0.62553692"
- id="stop9332" />
- <stop
- id="stop9330"
- offset="1"
- style="stop-color:#3e3f3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient9326-5">
- <stop
- id="stop9328-9"
- offset="0"
- style="stop-color:#555753;stop-opacity:1;" />
- <stop
- style="stop-color:#555652;stop-opacity:1"
- offset="0.52639353"
- id="stop9342-8" />
- <stop
- style="stop-color:#5e605b;stop-opacity:1"
- offset="0.62553692"
- id="stop9332-4" />
- <stop
- id="stop9330-8"
- offset="1"
- style="stop-color:#3e3f3c;stop-opacity:1;" />
- </linearGradient>
- <pattern
- inkscape:stockid="Sand (bitmap)"
- id="sand_bitmap-1"
- height="256"
- width="256"
- patternUnits="userSpaceOnUse"
- patternTransform="matrix(0.1089357,0,0,0.1089357,304.12642,53.923124)">
- <!-- Seamless texture provided by FreeSeamlessTextures.com -->
- <!-- License: creative commons attribution -->
- <image
- xlink:href="data:image/jpeg;base64,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 /p1//9k= "
- y="0"
- x="0"
- id="image9-0"
- height="260"
- width="260" />
- </pattern>
- <linearGradient
- id="linearGradient9941-4">
- <stop
- id="stop9943-7"
- offset="0"
- style="stop-color:#edd400;stop-opacity:1;" />
- <stop
- style="stop-color:#bda901;stop-opacity:1;"
- offset="0.25"
- id="stop9959-6" />
- <stop
- style="stop-color:#a08f05;stop-opacity:1"
- offset="0.5"
- id="stop9945-3" />
- <stop
- id="stop9947-1"
- offset="1"
- style="stop-color:#ffeb3e;stop-opacity:1;" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath9887-5">
- <path
- d="m 62.15625,35.96875 c -4.917465,0.322114 -6.827831,5.25981 -6.5,9.125 l 0,211.8125 c 0.365597,5.50865 5.236892,11.01932 12.5,10.46875 l 167.09375,0 c 4.68699,-0.22612 9.31856,-4.12416 9.25,-11.84375 l 0,-193.71875 c 0,-3.758448 -1.21492,-6.263069 -3.96875,-8.96875 L 226.125,37.96875 c -1.50676,-1.423489 -2.45242,-2 -6.625,-2 l -157.34375,0 z"
- inkscape:href="#path9521-4"
- id="path9889-3"
- style="fill:none;stroke:#343a3b;stroke-width:0.38129407;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible"
- xlink:href="#path9521-4"
- inkscape:original="M 62.15625 35.96875 C 57.238785 36.290864 55.328419 41.22856 55.65625 45.09375 L 55.65625 256.90625 C 56.021847 262.4149 60.893142 267.92557 68.15625 267.375 L 235.25 267.375 C 239.93699 267.14888 244.56856 263.25084 244.5 255.53125 L 244.5 61.8125 C 244.5 58.054052 243.28508 55.549431 240.53125 52.84375 L 226.125 37.96875 C 224.61824 36.545261 223.67258 35.96875 219.5 35.96875 L 62.15625 35.96875 z "
- inkscape:radius="0"
- sodipodi:type="inkscape:offset" />
- </clipPath>
- <linearGradient
- id="linearGradient9326-2">
- <stop
- id="stop9328-5"
- offset="0"
- style="stop-color:#555753;stop-opacity:1;" />
- <stop
- style="stop-color:#555652;stop-opacity:1"
- offset="0.52639353"
- id="stop9342-4" />
- <stop
- style="stop-color:#5e605b;stop-opacity:1"
- offset="0.62553692"
- id="stop9332-49" />
- <stop
- id="stop9330-9"
- offset="1"
- style="stop-color:#3e3f3c;stop-opacity:1;" />
- </linearGradient>
- <pattern
- inkscape:stockid="Sand (bitmap)"
- id="sand_bitmap-3"
- height="256"
- width="256"
- patternUnits="userSpaceOnUse"
- patternTransform="matrix(0.1089357,0,0,0.1089357,304.12642,53.923124)">
- <!-- Seamless texture provided by FreeSeamlessTextures.com -->
- <!-- License: creative commons attribution -->
- <image
- xlink:href="data:image/jpeg;base64,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 /p1//9k= "
- y="0"
- x="0"
- id="image9-6"
- height="260"
- width="260" />
- </pattern>
- <linearGradient
- id="linearGradient9903-5">
- <stop
- style="stop-color:#bdc5c7;stop-opacity:1"
- offset="0"
- id="stop9905-0" />
- <stop
- style="stop-color:#2e3436;stop-opacity:1"
- offset="1"
- id="stop9907-2" />
- </linearGradient>
- <linearGradient
- id="linearGradient9941-43">
- <stop
- id="stop9943-5"
- offset="0"
- style="stop-color:#edd400;stop-opacity:1;" />
- <stop
- style="stop-color:#bda901;stop-opacity:1;"
- offset="0.25"
- id="stop9959-1" />
- <stop
- style="stop-color:#a08f05;stop-opacity:1"
- offset="0.5"
- id="stop9945-7" />
- <stop
- id="stop9947-4"
- offset="1"
- style="stop-color:#ffeb3e;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient9677-1">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop9679-4" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop9681-69" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath9887-8">
- <path
- d="m 62.15625,35.96875 c -4.917465,0.322114 -6.827831,5.25981 -6.5,9.125 l 0,211.8125 c 0.365597,5.50865 5.236892,11.01932 12.5,10.46875 l 167.09375,0 c 4.68699,-0.22612 9.31856,-4.12416 9.25,-11.84375 l 0,-193.71875 c 0,-3.758448 -1.21492,-6.263069 -3.96875,-8.96875 L 226.125,37.96875 c -1.50676,-1.423489 -2.45242,-2 -6.625,-2 l -157.34375,0 z"
- inkscape:href="#path9521"
- id="path9889-6"
- style="fill:none;stroke:#343a3b;stroke-width:0.38129407;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible"
- xlink:href="#path9521"
- inkscape:original="M 44.84375 57.3125 C 39.3351 57.678097 33.82443 62.549392 34.375 69.8125 L 34.375 236.875 C 34.60112 241.56199 38.49916 246.19356 46.21875 246.125 L 239.9375 246.125 C 243.69595 246.125 246.20057 244.91008 248.90625 242.15625 L 263.78125 227.75 C 265.20474 226.24324 265.78125 225.29758 265.78125 221.125 L 265.78125 63.78125 C 265.45913 58.863785 260.52144 56.984669 256.65625 57.3125 L 44.84375 57.3125 z "
- inkscape:radius="0"
- sodipodi:type="inkscape:offset" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9903-5"
- id="radialGradient3610"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.02241743,-4.5362601,2.141228,0.00322394,2.865653,1366.4873)"
- cx="319.47476"
- cy="74.762054"
- fx="319.47476"
- fy="74.762054"
- r="14.737162" />
- <linearGradient
- id="linearGradient9326-8">
- <stop
- id="stop9328-2"
- offset="0"
- style="stop-color:#555753;stop-opacity:1;" />
- <stop
- style="stop-color:#555652;stop-opacity:1"
- offset="0.52639353"
- id="stop9342-5" />
- <stop
- style="stop-color:#5e605b;stop-opacity:1"
- offset="0.62553692"
- id="stop9332-3" />
- <stop
- id="stop9330-1"
- offset="1"
- style="stop-color:#3e3f3c;stop-opacity:1;" />
- </linearGradient>
- <pattern
- inkscape:stockid="Sand (bitmap)"
- id="sand_bitmap-2"
- height="256"
- width="256"
- patternUnits="userSpaceOnUse"
- patternTransform="matrix(0.1089357,0,0,0.1089357,304.12642,53.923124)">
- <!-- Seamless texture provided by FreeSeamlessTextures.com -->
- <!-- License: creative commons attribution -->
- <image
- xlink:href="data:image/jpeg;base64,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 /p1//9k= "
- y="0"
- x="0"
- id="image9-1"
- height="260"
- width="260" />
- </pattern>
- <linearGradient
- id="linearGradient9941-2">
- <stop
- id="stop9943-9"
- offset="0"
- style="stop-color:#edd400;stop-opacity:1;" />
- <stop
- style="stop-color:#bda901;stop-opacity:1;"
- offset="0.25"
- id="stop9959-2" />
- <stop
- style="stop-color:#a08f05;stop-opacity:1"
- offset="0.5"
- id="stop9945-6" />
- <stop
- id="stop9947-46"
- offset="1"
- style="stop-color:#ffeb3e;stop-opacity:1;" />
- </linearGradient>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath9887-4">
- <path
- d="m 62.15625,35.96875 c -4.917465,0.322114 -6.827831,5.25981 -6.5,9.125 l 0,211.8125 c 0.365597,5.50865 5.236892,11.01932 12.5,10.46875 l 167.09375,0 c 4.68699,-0.22612 9.31856,-4.12416 9.25,-11.84375 l 0,-193.71875 c 0,-3.758448 -1.21492,-6.263069 -3.96875,-8.96875 L 226.125,37.96875 c -1.50676,-1.423489 -2.45242,-2 -6.625,-2 l -157.34375,0 z"
- inkscape:href="#path9521"
- id="path9889-0"
- style="fill:none;stroke:#343a3b;stroke-width:0.38129407;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible"
- xlink:href="#path9521"
- inkscape:original="M 62.15625 35.96875 C 57.238785 36.290864 55.328419 41.22856 55.65625 45.09375 L 55.65625 256.90625 C 56.021847 262.4149 60.893142 267.92557 68.15625 267.375 L 235.25 267.375 C 239.93699 267.14888 244.56856 263.25084 244.5 255.53125 L 244.5 61.8125 C 244.5 58.054052 243.28508 55.549431 240.53125 52.84375 L 226.125 37.96875 C 224.61824 36.545261 223.67258 35.96875 219.5 35.96875 L 62.15625 35.96875 z "
- inkscape:radius="0"
- sodipodi:type="inkscape:offset" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5532"
- id="linearGradient5538"
- x1="151.9079"
- y1="188.73213"
- x2="151.07002"
- y2="49.432087"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(3,40)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9941-43"
- id="linearGradient5640"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-1.9049813,3.5398921,0,97.3544,-37.747404)"
- x1="29.374996"
- y1="21.741114"
- x2="20.004526"
- y2="6.7253776" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9677-1"
- id="radialGradient5642"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.6935297,-1.6353265,6.1727401,1.8717188,-790.31279,320.79789)"
- cx="319.82288"
- cy="64.117065"
- fx="319.82288"
- fy="64.117065"
- r="13.808043" />
- <filter
- inkscape:collect="always"
- id="filter5758">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="4.6408213"
- id="feGaussianBlur5760" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5532"
- id="linearGradient5840"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.18585006,0,0,0.18717507,293.02852,53.343152)"
- x1="151.9079"
- y1="188.73213"
- x2="151.07002"
- y2="49.432087" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9903-5"
- id="radialGradient5842"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.00589609,-1.2059869,0.56317324,8.5710016e-4,35.496775,74.218944)"
- cx="319.47476"
- cy="74.762054"
- fx="319.47476"
- fy="74.762054"
- r="14.737162" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9941-43"
- id="linearGradient5844"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.50644856,0.93104166,0,60.348652,-299.10369)"
- x1="29.374996"
- y1="21.741114"
- x2="20.004526"
- y2="6.7253776" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9677-1"
- id="radialGradient5846"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.4615968,-0.44981091,1.6824726,0.51483267,-182.87988,-200.0395)"
- cx="319.82288"
- cy="64.117065"
- fx="319.82288"
- fy="64.117065"
- r="13.808043" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5532"
- id="linearGradient5866"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.12671561,0,0,0.12478236,300.6104,129.22895)"
- x1="151.9079"
- y1="188.73213"
- x2="151.07002"
- y2="49.432087" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9903-5"
- id="radialGradient5868"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.00461699,-0.8988884,0.44099713,6.3884392e-4,113.24551,-25.407226)"
- cx="319.47476"
- cy="74.762054"
- fx="319.47476"
- fy="74.762054"
- r="14.737162" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9941-43"
- id="linearGradient5870"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.37748401,0.72905934,0,132.70595,-303.66517)"
- x1="29.374996"
- y1="21.741114"
- x2="20.004526"
- y2="6.7253776" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5532"
- id="linearGradient5926"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.09292503,0,0,0.09705373,300.51424,178.5113)"
- x1="151.9079"
- y1="188.73213"
- x2="151.07002"
- y2="49.432087" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5532"
- id="linearGradient5965"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.06758181,0,0,0.08318892,301.19216,219.15252)"
- x1="151.9079"
- y1="188.73213"
- x2="151.07002"
- y2="49.432087" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5987"
- id="linearGradient5993"
- x1="223.94716"
- y1="-310.04846"
- x2="233.99281"
- y2="-310.04846"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.99495343,0,0,0.98976252,1.1855286,-3.1256575)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5987"
- id="linearGradient5999"
- gradientUnits="userSpaceOnUse"
- x1="223.94716"
- y1="-310.04846"
- x2="233.99281"
- y2="-310.04846"
- gradientTransform="translate(-38.940119,0)" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9677-1"
- id="radialGradient6007"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.42866379,-0.45005125,1.5624352,0.51510774,-164.07876,-199.45791)"
- cx="319.82288"
- cy="64.117065"
- fx="319.82288"
- fy="64.117065"
- r="13.808043" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9941-43"
- id="linearGradient6009"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.50649125,0.86346939,0,61.811175,-298.60338)"
- x1="29.374996"
- y1="21.741114"
- x2="20.004526"
- y2="6.7253776" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9903-5"
- id="radialGradient6011"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.00553762,-1.2219079,0.52893295,8.6841528e-4,38.317881,79.803805)"
- cx="319.47476"
- cy="74.762054"
- fx="319.47476"
- fy="74.762054"
- r="14.737162" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9903-5"
- id="radialGradient6021"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.00468607,-1.0692464,0.44759605,7.5991801e-4,112.80492,28.04045)"
- cx="319.47476"
- cy="74.762054"
- fx="319.47476"
- fy="74.762054"
- r="14.737162" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6048"
- id="linearGradient6023"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.44321172,0.73068902,0,132.68554,-303.08965)"
- x1="29.374996"
- y1="21.741114"
- x2="20.004526"
- y2="6.7253776" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient9677-1"
- id="radialGradient6025"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.36274586,-0.3938231,1.3221712,0.4507516,-58.572255,-216.17961)"
- cx="319.82288"
- cy="64.117065"
- fx="319.82288"
- fy="64.117065"
- r="13.808043" />
- </defs>
- <metadata
- id="metadata4">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:creator>
- <cc:Agent>
- <dc:title>Lapo Calamandrei</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:source />
- <cc:license
- rdf:resource="" />
- <dc:title>Firewall</dc:title>
- <dc:subject>
- <rdf:Bag />
- </dc:subject>
- <dc:date />
- <dc:rights>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:rights>
- <dc:publisher>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:publisher>
- <dc:identifier />
- <dc:relation />
- <dc:language />
- <dc:coverage />
- <dc:description />
- <dc:contributor>
- <cc:Agent>
- <dc:title />
- </cc:Agent>
- </dc:contributor>
- </cc:Work>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- style="display:inline"
- inkscape:groupmode="layer"
- inkscape:label="artwork"
- id="layer1">
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="baseplate"
- style="display:none">
- <rect
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect6284"
- width="48"
- height="48"
- x="296.0625"
- y="51.99633"
- inkscape:label="48x48" />
- <rect
- inkscape:label="32x32"
- y="127.99634"
- x="303"
- height="32"
- width="32"
- id="rect6592"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- inkscape:label="24x24"
- y="178"
- x="302"
- height="24"
- width="24"
- id="rect5028"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- inkscape:label="16x16"
- y="221"
- x="303"
- height="16"
- width="16"
- id="rect6833"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect6749"
- width="22"
- height="22"
- x="303"
- y="179.05884"
- inkscape:label="22x22" />
- <text
- id="context"
- inkscape:label="context"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
- x="31.87059"
- xml:space="preserve"
- y="18.860306"><tspan
- sodipodi:role="line"
- x="31.87059"
- y="18.860306"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
- id="tspan6058">devices</tspan></text>
- <text
- id="icon-name"
- inkscape:label="icon-name"
- sodipodi:linespacing="125%"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
- x="302.87057"
- xml:space="preserve"
- y="18.860306"><tspan
- sodipodi:role="line"
- x="302.87057"
- y="18.860306"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans Bold"
- id="tspan6062">gcr-smart-card</tspan></text>
- <rect
- inkscape:label="256x256"
- y="32"
- x="20"
- height="256"
- width="256"
- id="rect6282"
- style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="smallsizes"
- style="display:inline">
- <g
- id="g6154"
- style="fill:#ffffff"
- transform="matrix(1.25,0,0,1.25,-78,-47.25)" />
- <rect
- ry="4.75"
- rx="5.1779518"
- y="94.979431"
- x="301.29306"
- height="137.04115"
- width="234.22455"
- id="rect5804"
- style="opacity:0.9;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5758);enable-background:accumulate"
- transform="matrix(0.18598708,0,0,0.18713623,242.2418,45.859499)" />
- <rect
- ry="1.4764122"
- rx="1.4764122"
- y="62"
- x="298"
- height="27"
- width="44"
- id="rect5806"
- style="color:#000000;fill:url(#linearGradient5840);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="sscsscsss"
- inkscape:connector-curvature="0"
- id="path5808"
- d="M 298.41236,62 C 298.18248,62 298,62.181715 298,62.410634 l 0,11.815805 c 1.52647,-0.617796 9.57138,-5.313111 20.58744,-4.326436 8.69319,0.778613 9.46199,4.841397 21.61795,6.084632 0.63834,0.06527 1.23556,-0.09702 1.79461,-0.121446 l 0,-13.452555 C 342,62.181715 341.81752,62 341.58765,62 z"
- style="color:#000000;fill:#ffffff;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- ry="2.1703689"
- rx="2.2517214"
- y="-319"
- x="67.03595"
- height="17"
- width="13.928329"
- id="rect5810"
- style="fill:url(#radialGradient6011);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.57194108;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- style="fill:url(#linearGradient6009);fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect5812"
- width="13"
- height="16"
- x="67.5"
- y="-318.50003"
- rx="1.6989782"
- ry="1.6375958" />
- <rect
- ry="1.3708601"
- rx="1.4222498"
- y="-318.358"
- x="66.713745"
- height="15.981206"
- width="12.965498"
- id="rect5814"
- style="opacity:0.44943824;fill:none;stroke:url(#radialGradient6007);stroke-width:1.00000608;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- transform="matrix(0.00182552,0.99999833,-0.99999665,-0.00258966,0,0)" />
- <path
- sodipodi:nodetypes="ccccccccccccccc"
- inkscape:connector-curvature="0"
- d="m 312.98117,76.998772 4.77911,0 m -4.77911,-3.015818 4.81883,0 m -14.6,3.015818 4.7455,0 m -4.69808,-3.015818 4.69808,0 m -4.74235,-2.999064 4.74235,0 m 0,-2.783875 0,11.590736 m 5.03567,0.0093 0,-8.816161 4.77898,0"
- style="fill:none;stroke:#534917;stroke-width:0.40000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- id="path5816" />
- <g
- transform="scale(0.99692491,1.0030846)"
- style="font-size:3.35809374px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- id="text5818">
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 322.99971,84.505959 c -0.32371,0.232981 -1.54949,0.04907 -0.57167,0.557469 1.30174,0.111492 0.90098,-1.166102 0.16184,-1.291557 0.7756,0.107934 0.81615,-0.650871 0.0161,-0.415116 -1.167,0.423486 -0.30987,0.983754 0.39371,1.149204 z"
- id="path3148"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 324.52575,83.720165 c 0.58322,0.03859 0.10268,1.927499 0.68071,0.994317 -0.3454,-0.72254 0.65411,-1.459071 0.67298,-0.433284 -0.1754,1.210945 0.81092,0.431071 0.38687,-0.3259 -0.30544,-1.052506 -1.70368,-0.501021 -2.4567,-0.441665 0.0358,0.422654 -0.24246,1.331187 0.16648,1.501906 0.58935,-0.152916 -0.24835,-1.362377 0.54972,-1.295373"
- id="path3150"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 327.4337,83.337343 c -0.70375,-0.234044 -0.80517,0.751699 -0.003,0.36018 0.96307,0.47219 -1.53569,0.210894 -0.53946,1.184024 1.15222,0.871793 1.96139,-1.044388 0.78064,-1.523536 -0.0776,-0.02067 -0.15937,-0.0125 -0.23867,-0.02067 z m 0.34254,1.232423 c -1.23331,0.556156 -0.29753,-0.917646 0,0 z"
- id="path3152"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 328.92638,83.454876 c -0.71121,-0.25821 -0.25734,2.460253 0.0886,1.181193 -0.23749,-0.835217 0.28101,-0.801149 0.77477,-1.147657 -0.21432,-0.248059 -0.60833,-0.147961 -0.8634,-0.03354 z"
- id="path3154"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 331.15846,84.959302 c -0.13091,-0.370672 -1.13688,-0.707435 -0.41974,-1.235716 1.0052,-0.210009 -0.3378,-0.211313 -0.25368,-0.824831 -0.82724,0.270344 -0.32313,1.166161 -0.20457,1.867126 0.16445,0.336794 0.58411,0.319444 0.87799,0.193421 z"
- id="path3156"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 332.36092,84.213805 c -0.34598,1.156552 2.30829,0.778865 0.87676,0.398324 -1.11605,-0.394633 0.0921,-1.041939 0.53419,-1.056156 -0.28714,-0.59917 -1.58123,-0.02864 -1.41095,0.657832 z"
- id="path3158"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 334.87136,83.337343 c -0.70375,-0.234044 -0.80517,0.7517 -0.003,0.36018 0.96308,0.472187 -1.53573,0.210908 -0.53944,1.184035 1.15222,0.871768 1.96152,-1.044324 0.78072,-1.523548 -0.0776,-0.02067 -0.15935,-0.01249 -0.23866,-0.02067 m 0.34252,1.23242 c -0.79103,0.509837 -0.62218,-0.701893 0.0231,-0.122198 l -0.0231,0.122198 -1e-5,0 z"
- id="path3160"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 336.36403,83.454876 c -0.71123,-0.258235 -0.25735,2.460259 0.0886,1.181193 -0.23749,-0.835217 0.28101,-0.801149 0.77477,-1.147658 -0.21432,-0.248055 -0.60832,-0.147962 -0.86339,-0.03354 z"
- id="path3162"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 337.43085,84.207089 c -0.19412,0.926634 1.81011,1.235668 1.60519,0.181973 0,-0.575565 0,-1.151129 0,-1.726694 -0.6641,-0.140942 -0.24181,1.169719 -1.07378,0.721555 -0.32992,0.120291 -0.56299,0.471056 -0.53139,0.823167 m 0.90333,0.460059 c -1.26081,-0.05566 0.4577,-1.896907 0.30375,-0.395608 0.045,0.197727 -0.0297,0.498815 -0.30375,0.395608 z"
- id="path3164"
- inkscape:connector-curvature="0" />
- </g>
- <rect
- style="color:#000000;fill:url(#linearGradient5866);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5850"
- width="29.999918"
- height="17.999855"
- x="304.00003"
- y="135.00011"
- rx="0.98426384"
- ry="0.98426384" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 304.28119,135.00013 c -0.15674,0 -0.28115,0.12252 -0.28115,0.27686 l 0,7.96657 c 1.04078,-0.41652 6.52593,-3.58226 14.03685,-2.91701 5.92717,0.52497 6.45133,3.26422 14.73948,4.10245 0.43522,0.0441 0.84241,-0.0654 1.22358,-0.082 l 0,-9.07012 c 0,-0.15435 -0.12441,-0.27686 -0.28115,-0.27686 z"
- id="path5852"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sscsscsss" />
- <rect
- ry="1.7391665"
- rx="1.7391665"
- y="183"
- x="303"
- height="14"
- width="22"
- id="rect5912"
- style="color:#000000;fill:url(#linearGradient5926);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="sscsscsss"
- inkscape:connector-curvature="0"
- id="path5914"
- d="m 303.21305,182.94658 c -0.11472,0 -0.20579,0.0955 -0.20579,0.21585 l 0,6.21093 c 0.76181,-0.32475 4.77672,-2.79283 10.27441,-2.27419 4.33843,0.40929 4.72211,2.54486 10.78869,3.19837 0.31857,0.0342 0.61662,-0.051 0.89562,-0.0639 l 0,-7.07126 c 0,-0.12034 -0.091,-0.21585 -0.20579,-0.21585 z"
- style="color:#000000;fill:#ffffff;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="color:#000000;fill:url(#linearGradient5965);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5951"
- width="15.999992"
- height="12"
- x="303"
- y="223"
- rx="1.1520458"
- ry="1.1520458" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 303.13151,222.99567 c -0.0836,0 -0.14994,0.0743 -0.14994,0.16804 l 0,4.83532 c 0.55508,-0.25282 3.4805,-2.17427 7.48634,-1.77049 3.16115,0.31863 3.44071,1.98122 7.86106,2.48999 0.23212,0.0267 0.4493,-0.0398 0.65259,-0.0497 l 0,-5.50511 c 0,-0.0938 -0.0663,-0.16804 -0.14995,-0.16804 z"
- id="path5953"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sscsscsss" />
- <g
- id="g6001">
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- style="fill:#edd400;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5993);stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect5957"
- width="9"
- height="11"
- x="224.5"
- y="-315.5"
- rx="0.77868956"
- ry="0.75055641" />
- <path
- sodipodi:nodetypes="ccccccccccc"
- inkscape:connector-curvature="0"
- d="m 305.4,227.52877 3.11391,0 m -3.11391,2.99452 3.11391,0 m 0,-5.12329 0,7.2 m 3.00306,0 0,-5.07126 3.08303,0 m -3.08303,2.99453 3.08303,0"
- style="fill:none;stroke:#997e00;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- id="path5959" />
- </g>
- <use
- x="0"
- y="0"
- xlink:href="#g6001"
- id="use6005"
- transform="translate(1,-39)"
- width="400"
- height="300" />
- <rect
- style="fill:url(#radialGradient6021);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.57194108;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect6013"
- width="11.786495"
- height="14.87607"
- x="137.10687"
- y="-320.93796"
- rx="2.2517214"
- ry="2.1703689"
- transform="matrix(0,1,-1,0,0,0)" />
- <rect
- ry="1.6375959"
- rx="1.6989781"
- y="-320.50052"
- x="137.49954"
- height="14.001008"
- width="11.000917"
- id="rect6015"
- style="fill:url(#linearGradient6023);fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- transform="matrix(0,1,-1,0,0,0)" />
- <rect
- transform="matrix(0.00188775,0.99999822,-0.99999686,-0.00250432,0,0)"
- style="opacity:0.44943824;fill:none;stroke:url(#radialGradient6025);stroke-width:1.00000584;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect6017"
- width="10.971724"
- height="13.984559"
- x="136.73004"
- y="-320.22476"
- rx="1.4222493"
- ry="1.3708594" />
- <path
- id="path6019"
- style="fill:none;stroke:#534917;stroke-width:0.40000004;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- d="m 315.67112,145.03765 4.18202,0 m -12.74115,0 4.15261,0 m -4.14987,-4.08993 4.14987,0 m 0,-2.85579 0,9.80836 m 4.40652,0.008 0,-6.96046 4.18192,0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccccc" />
- <g
- transform="scale(0.99692489,1.0030846)"
- style="font-size:3.35809374px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- id="text5818-1">
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 324.73265,150.20183 c -0.1498,0.47294 -1.22187,-0.24989 -0.92803,0.39893 0.44803,0.21962 1.36154,0.19425 1.34952,-0.46486 -0.17549,-0.36152 -1.51481,-0.69478 -0.48028,-0.74481 0.77118,0.0816 0.18308,-0.57638 -0.27856,-0.35109 -0.764,-0.0395 -0.81521,1.01459 -0.0215,0.98616 0.12766,0.0373 0.2619,0.0795 0.35874,0.17574"
- id="path3194"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 326.25869,149.41603 c 0.71846,0.0386 -0.14498,1.60083 0.68772,1.20383 0.0179,-0.41554 -0.12296,-1.60217 0.61952,-1.07011 0.0999,0.36387 0.0235,0.75779 0.0461,1.13566 0.71789,0.15007 0.31762,-0.83289 0.37072,-1.2446 -0.21322,-0.68735 -0.99215,-0.22592 -1.47668,-0.33668 -0.39956,-0.045 -1.20695,-0.18263 -0.99616,0.501 0,0.36015 0,0.72031 0,1.08047 0.50746,0.18919 0.39911,-0.29755 0.40297,-0.60366 0.0437,-0.24774 -0.15038,-0.67967 0.25649,-0.65789 l 0.0894,-0.008"
- id="path3196"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 329.16664,149.03321 c -0.32716,-0.17538 -0.99565,0.36781 -0.46833,0.39802 0.30912,-0.2484 1.20575,0.25077 0.50658,0.30317 -0.65596,-0.19946 -1.1852,0.74136 -0.40594,0.95373 0.35502,0.006 0.923,0.0745 1.13792,-0.16201 -0.11738,-0.48714 0.21614,-1.29662 -0.46842,-1.46339 -0.0987,-0.0238 -0.20056,-0.0318 -0.30182,-0.0295 m 0.34253,1.23242 c -0.26325,0.40537 -1.05186,-0.22392 -0.32028,-0.23605 0.18832,-0.0694 0.38958,0.007 0.32028,0.23605 z"
- id="path3198"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 330.65932,149.15075 c -0.50816,-0.27071 -0.26674,0.61692 -0.31559,0.93657 0.0344,0.27813 -0.15175,0.76409 0.32991,0.60519 0.15485,-0.16454 0.0353,-0.49128 0.0731,-0.72395 -0.11713,-0.47484 0.15253,-0.66492 0.64507,-0.56399 0.51608,-0.4521 -0.53351,-0.42473 -0.73236,-0.25382"
- id="path3200"
- inkscape:connector-curvature="0" />
- <path
- style="line-height:125%;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- d="m 332.8914,150.65517 c 0.15406,-0.45772 -0.90016,-0.23396 -0.57789,-0.85702 -0.0342,-0.26324 -0.023,-0.48106 0.30169,-0.38543 0.5643,0.0893 0.15789,-0.63836 -0.27811,-0.35519 0.15554,-0.33148 -0.27666,-0.72568 -0.4369,-0.31336 0.22561,0.36229 -0.64372,0.41043 -0.0911,0.66216 0.22765,0.45317 -0.1117,1.46905 0.77408,1.30723 0.10405,-0.0111 0.20641,-0.0336 0.30793,-0.0583"
- id="path3202"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="hires"
- style="display:inline">
- <g
- inkscape:groupmode="layer"
- id="layer7"
- inkscape:label="card"
- style="display:inline">
- <rect
- style="opacity:0.9;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5758);enable-background:accumulate"
- id="rect5716"
- width="234.22455"
- height="137.04115"
- x="31.293058"
- y="94.979431"
- rx="5.1461554"
- ry="4.75" />
- <rect
- style="color:#000000;fill:url(#linearGradient5538);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect5530"
- width="236.75"
- height="144.25"
- x="29.75"
- y="86.25"
- rx="7.8895049"
- ry="7.8895049" />
- <path
- style="color:#000000;fill:#ffffff;fill-opacity:0.1254902;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 31.96875,86.25 c -1.236888,0 -2.21875,0.981862 -2.21875,2.21875 l 0,63.84375 c 8.213435,-3.3381 51.500517,-28.70807 110.77449,-23.37684 46.77528,4.20707 50.91189,26.15933 116.31926,32.87684 3.4347,0.35275 6.64817,-0.52413 9.65625,-0.65625 l 0,-72.6875 c 0,-1.236888 -0.98186,-2.21875 -2.21875,-2.21875 z"
- id="rect5546"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sscsscsss" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer6"
- inkscape:label="chip"
- style="display:inline"
- sodipodi:insensitive="true">
- <rect
- style="fill:url(#radialGradient3610);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.57194108;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect9523"
- width="56.384705"
- height="63.111481"
- x="119.12219"
- y="-114.04798"
- rx="8.1474466"
- ry="8.1474466"
- transform="matrix(0,1,-1,0,0,0)" />
- <rect
- ry="6.1474447"
- rx="6.1474452"
- y="-112.58131"
- x="120.67642"
- height="60.178139"
- width="53.294991"
- id="rect9525"
- style="fill:url(#linearGradient5640);fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- transform="matrix(0,1,-1,0,0,0)" />
- <rect
- transform="matrix(0.001679,0.99999859,-0.99999604,-0.00281563,0,0)"
- style="opacity:0.44943824;fill:none;stroke:url(#radialGradient5642);stroke-width:1.00000632;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.8;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect9527"
- width="51.223022"
- height="58.07003"
- x="121.48322"
- y="-111.24284"
- rx="5.1461554"
- ry="5.1461334" />
- <path
- id="path4425"
- style="fill:none;stroke:#282e2f;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- d="m 93.01004,159.80439 19.08411,0 m -19.1169,-12.22749 19.10314,0 m -59.17981,12.22749 18.80887,0 m -18.812733,-12.22749 18.812733,0 m -18.81815,-12.22749 18.90251,0 m -0.0844,-14.18495 0,52.24742 m 21.23733,0.0613 0,-38.10229 19.12426,-0.0214"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccccccccc" />
- <text
- xml:space="preserve"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
- x="152.5"
- y="210.5"
- id="text5551"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- x="152.5"
- y="210.5"
- id="tspan5555"
- style="font-size:18px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold">smart card</tspan></text>
- </g>
- </g>
- </g>
-</svg>
diff --git a/gcr/tests/.gitignore b/gcr/tests/.gitignore
deleted file mode 100644
index f30fd7b9..00000000
--- a/gcr/tests/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/ui-test-certificate
-/ui-test-details
-/ui-test-key
-/ui-test-unlock-options
-/test-ui-selector
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
deleted file mode 100644
index 5872ff9f..00000000
--- a/gcr/tests/Makefile.am
+++ /dev/null
@@ -1,68 +0,0 @@
-
-INCLUDES = \
- -I$(top_builddir) \
- -I$(top_srcdir) \
- -DSRCDIR="\"@abs_srcdir@\"" \
- -DGCR_API_SUBJECT_TO_CHANGE \
- -DGCK_API_SUBJECT_TO_CHANGE \
- -DGCR_COMPILATION \
- $(GLIB_CFLAGS) \
- $(GTK_CFLAGS) \
- $(LIBGCRYPT_CFLAGS)
-
-LDADD = \
- $(top_builddir)/gcr/libgcr-testable.la \
- $(top_builddir)/egg/libegg.la \
- $(top_builddir)/egg/libegg-entry-buffer.la \
- $(top_builddir)/gck/libgck-testable.la \
- $(GTK_LIBS) \
- $(GLIB_LIBS) \
- $(LIBGCRYPT_LIBS)
-
-TEST_PROGS = \
- test-util \
- test-secret-exchange \
- test-simple-certificate \
- test-certificate \
- test-certificate-chain \
- test-fingerprint \
- test-pkcs11-certificate \
- test-openpgp \
- test-openssh \
- test-trust \
- test-parser \
- test-record \
- test-memory-icon \
- test-gnupg-key \
- test-gnupg-collection \
- test-gnupg-process
-
-check_PROGRAMS = $(TEST_PROGS)
-
-test: $(TEST_PROGS)
- chmod -f 700 $(srcdir)/files/gnupg-homedir
- gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
-
-check-local: test
-
-all-local: $(check_PROGRAMS)
-
-EXTRA_DIST = \
- files
-
-# ------------------------------------------------------------------
-
-noinst_PROGRAMS = \
- frob-certificate \
- frob-combo-selector \
- frob-gnupg-selector \
- frob-key \
- frob-tree-selector \
- frob-openpgp \
- frob-parser \
- frob-unlock \
- frob-unlock-options
-
-frob_unlock_SOURCES = \
- frob-unlock.c \
- ../gcr-viewer-window.c
diff --git a/gcr/tests/files/RSA_Root_Certificate_1.pem b/gcr/tests/files/RSA_Root_Certificate_1.pem
deleted file mode 100644
index f6cdfcd0..00000000
--- a/gcr/tests/files/RSA_Root_Certificate_1.pem
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD
-ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
-Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRp
-b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv
-bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy
-NjAwMjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x
-NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24g
-QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x
-IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2f
-NUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChM
-MFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqYJJgpp0lZpd34
-t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs3x/b
-e0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0Wu
-PIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
-PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
------END CERTIFICATE-----
diff --git a/gcr/tests/files/RSA_Security_1024_v3.pem b/gcr/tests/files/RSA_Security_1024_v3.pem
deleted file mode 100644
index 94e0ad13..00000000
--- a/gcr/tests/files/RSA_Security_1024_v3.pem
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUF
-ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg
-U2VjdXJpdHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAx
-NDlaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT
-QSBTZWN1cml0eSAxMDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDV3f5mCc8kPD6ugU5OisRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dY
-rIMKo1W1exeQFYRMiu4mmdxY78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYt
-bzZUaMjShFbuklNhCbM/OZuoyZu9zp9+1BlqFikYvtc6adwlWzMaUQIDAQAB
-o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSME
-GDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAdBgNVHQ4EFgQUxMAcpAeU/c1N
-AdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEAPy1q4yZDlX2Jl2X7deRy
-HUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdNT1+nr6JGFLkM88y9
-am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgDmMrzVcydro7B
-qkWY+o8aoI2II/EVQQ2lRj6RP4vr93E=
------END CERTIFICATE-----
diff --git a/gcr/tests/files/RSA_Security_2048_v3.pem b/gcr/tests/files/RSA_Security_2048_v3.pem
deleted file mode 100644
index 86c907eb..00000000
--- a/gcr/tests/files/RSA_Security_2048_v3.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUF
-ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg
-U2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5
-MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT
-QSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37
-RqtBaB4Y6lXIL5F4iSj7Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E
-0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J
-6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iHKrtjEAMq
-s6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzD
-uvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2Mw
-YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAW
-gBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NRMKSq6UWuNST6
-/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmYv/3V
-EhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5g
-EydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
-f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJq
-aHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEk
-llgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
-pKnXwiJPZ9d37CAFYd4=
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Personal_Basic_CA.pem b/gcr/tests/files/Thawte_Personal_Basic_CA.pem
deleted file mode 100644
index 22c2a8db..00000000
--- a/gcr/tests/files/Thawte_Personal_Basic_CA.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBl
-cnNvbmFsIEJhc2ljIENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNp
-Y0B0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVow
-gcsxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNV
-BAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAm
-BgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xITAfBgNV
-BAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBDQTEoMCYGCSqGSIb3DQEJARYZ
-cGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOB
-jQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53dXLdjUmbllegeNTK
-P1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdKwPQIcOk8RHtQ
-fmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7G1sY0b8j
-kyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOB
-gQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
-c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95
-B21P9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Personal_Freemail_CA.pem b/gcr/tests/files/Thawte_Personal_Freemail_CA.pem
deleted file mode 100644
index 565a4be1..00000000
--- a/gcr/tests/files/Thawte_Personal_Freemail_CA.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBl
-cnNvbmFsIEZyZWVtYWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1m
-cmVlbWFpbEB0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIz
-NTk1OVowgdExCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUx
-EjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRp
-bmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x
-JDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBDQTErMCkGCSqG
-SIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhhd3RlLmNvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfYDFG26nKRsIRefS0N
-j3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5ErHzmj+hND3Ef
-QDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVquzgkCGqY
-x7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
-hkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
-MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgC
-neSa/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr
-5PjRzneigQ==
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Personal_Premium_CA.pem b/gcr/tests/files/Thawte_Personal_Premium_CA.pem
deleted file mode 100644
index 688c3ae1..00000000
--- a/gcr/tests/files/Thawte_Personal_Premium_CA.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBl
-cnNvbmFsIFByZW1pdW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXBy
-ZW1pdW1AdGhhd3RlLmNvbTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5
-NTlaMIHPMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIw
-EAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5n
-MSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMSMw
-IQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJlbWl1bSBDQTEqMCgGCSqGSIb3
-DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0VsBd/eJxZRNkERbGw7
-7f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWIEt12TfIa/G8j
-Hnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYDZicRFTuq
-W/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
-b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVx
-eTBhKXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1
-KzGJ
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Premium_Server_CA.pem b/gcr/tests/files/Thawte_Premium_Server_CA.pem
deleted file mode 100644
index aa37cfc9..00000000
--- a/gcr/tests/files/Thawte_Premium_Server_CA.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy
-dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3Rl
-IFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl
-cnZlckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1
-OVowgc4xCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQ
-BgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENvbnN1bHRpbmcg
-Y2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x
-ITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3
-DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhI
-NTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQug2SBhRz1JPL
-lyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/qgeN
-9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
-AQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
-hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZ
-a4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcU
-Qg==
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Server_CA.pem b/gcr/tests/files/Thawte_Server_CA.pem
deleted file mode 100644
index ac4e25bf..00000000
--- a/gcr/tests/files/Thawte_Server_CA.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy
-dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3Rl
-IFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
-ZS5jb20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkG
-A1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2Fw
-ZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE
-CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQ
-VGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRz
-QHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I
-/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC
-6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCXL+eQbcAoQpnX
-TEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzARMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWD
-TSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
-QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdni
-TCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
diff --git a/gcr/tests/files/Thawte_Time_Stamping_CA.pem b/gcr/tests/files/Thawte_Time_Stamping_CA.pem
deleted file mode 100644
index fecbd15e..00000000
--- a/gcr/tests/files/Thawte_Time_Stamping_CA.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmls
-bGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmlj
-YXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcw
-MTAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTAT
-BgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
-BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24x
-HzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcN
-AQEBBQADgY0AMIGJAoGBANYrWHhhRYZT6jR7UZztsOYuGA7+4F+oJ9O0yeB8
-WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQaWt9MevPZQx08EHp5JduQ/vBR
-5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL8vg7ij5FrHGSALSQQZj7
-X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
-AQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC9RAIDb/LogWK
-0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQpgCed/r8
-zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZCayJ
-SdM=
------END CERTIFICATE-----
diff --git a/gcr/tests/files/ca-certificates.crt b/gcr/tests/files/ca-certificates.crt
deleted file mode 100644
index c30335f8..00000000
--- a/gcr/tests/files/ca-certificates.crt
+++ /dev/null
@@ -1,2560 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEuDCCA6CgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCQlIx
-EzARBgNVBAoTCklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25h
-bCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxETAPBgNVBAcTCEJy
-YXNpbGlhMQswCQYDVQQIEwJERjExMC8GA1UEAxMoQXV0b3JpZGFkZSBDZXJ0aWZp
-Y2Fkb3JhIFJhaXogQnJhc2lsZWlyYTAeFw0wMTExMzAxMjU4MDBaFw0xMTExMzAy
-MzU5MDBaMIG0MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE9MDsG
-A1UECxM0SW5zdGl0dXRvIE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3Jt
-YWNhbyAtIElUSTERMA8GA1UEBxMIQnJhc2lsaWExCzAJBgNVBAgTAkRGMTEwLwYD
-VQQDEyhBdXRvcmlkYWRlIENlcnRpZmljYWRvcmEgUmFpeiBCcmFzaWxlaXJhMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPMudwX/hvm+Uh2b/lQAcHVA
-isamaLkWdkwP9/S/tOKIgRrL6Oy+ZIGlOUdd6uYtk9Ma/3pUpgcfNAj0vYm5gsyj
-Qo9emsc+x6m4VWwk9iqMZSCK5EQkAq/Ut4n7KuLE1+gdftwdIgxfUsPt4CyNrY50
-QV57KM2UT8x5rrmzEjr7TICGpSUAl2gVqe6xaii+bmYR1QrmWaBSAG59LrkrjrYt
-bRhFboUDe1DK+6T8s5L6k8c8okpbHpa9veMztDVC9sPJ60MWXh6anVKo1UcLcbUR
-yEeNvZneVRKAAU6ouwdjDvwlsaKydFKwed0ToQ47bmUKgcm+wV3eTRk36UOnTwID
-AQABo4HSMIHPME4GA1UdIARHMEUwQwYFYEwBAQAwOjA4BggrBgEFBQcCARYsaHR0
-cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0RQQ2FjcmFpei5wZGYwPQYDVR0f
-BDYwNDAyoDCgLoYsaHR0cDovL2FjcmFpei5pY3BicmFzaWwuZ292LmJyL0xDUmFj
-cmFpei5jcmwwHQYDVR0OBBYEFIr68VeEERM1kEL6V0lUaQ2kxPA3MA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAZA5c1
-U/hgIh6OcgLAfiJgFWpvmDZWqlV30/bHFpj8iBobJSm5uDpt7TirYh1Uxe3fQaGl
-YjJe+9zd+izPRbBqXPVQA34EXcwk4qpWuf1hHriWfdrx8AcqSqr6CuQFwSr75Fos
-SzlwDADa70mT7wZjAmQhnZx2xJ6wfWlT9VQfS//JYeIc7Fue2JNLd00UOSMMaiK/
-t79enKNHEA2fupH3vEigf5Eh4bVAN5VohrTm6MY53x7XQZZr1ME7a55lFEnSeT0u
-mlOAjR2mAbvSM5X5oSZNrmetdzyTj2flCM8CC7MLab0kkdngRIlUBGHF1/S5nmPb
-K+9A46sd33oqK8n8
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
-IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
-IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
-Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
-BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
-MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
-ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
-8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
-zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
-fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
-w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
-G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
-epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
-laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
-QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
-fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
-YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
-ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
-gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
-MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
-IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
-dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
-czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
-dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
-aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
-AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
-b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
-ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
-nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
-18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
-gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
-Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
-sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
-SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
-CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
-GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
-zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
-omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEF
-BQAwgYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2Fz
-aGluZ3RvbjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFC
-QS5FQ09NIFJvb3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3Ry
-dXN0LmNvbTAeFw05OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQsw
-CQYDVQQGEwJVUzELMAkGA1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24x
-FzAVBgNVBAoTDkFCQS5FQ09NLCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBS
-b290IENBMSQwIgYJKoZIhvcNAQkBFhVhZG1pbkBkaWdzaWd0cnVzdC5jb20w
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx0xHgeVVDBwhMywVC
-AOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM0KLMsFWWU4RmBQDaREmA2FQK
-pSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFGPR7wuSw0X4x8TAgpnUBV
-6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGULOR4SCQaJRk665Wc
-OQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZsiSrK2jMTecJV
-jO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU+/94Qby9
-cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYBAf8C
-AQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k
-qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvT
-ZOirvRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHeg
-TYjHInYZw8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm
-/lowdiT/QHI8eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgx
-fexgeqMiKL0ZJGA/O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJ
-TzFxiNmIf1Q=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMC
-VVMxHTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNB
-bWVyaWNhIE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIg
-Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAw
-MFoXDTM3MTEyMDE1MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRB
-T0wgVGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUg
-SW5jLjE3MDUGA1UEAxMuQU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U0pPlLYnKhHw/EEMbjIt8hFj4JHxI
-zyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItITuLCxFlpMGK2MKKMCxGZYTVt
-fu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAfRC+iYkGzuxgh28pxPIzs
-trkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqFzQ6axOAAsNUl6twr
-5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqhBC4aMqiaILGc
-LCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEAAaNjMGEw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jYPXy+
-XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/
-BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNM
-eUWn9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7
-CegCgTXTCt8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77Bf
-WgDrvq2g+EQFZ7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oT
-LW4jYYehY0KswsuXn2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCz
-vhGbRWeDhhmH05i9CBoWH1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmw
-X7A5KGgOc90lmt4S
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMC
-VVMxHTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNB
-bWVyaWNhIE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIg
-Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAw
-MFoXDTM3MDkyODIzNDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRB
-T0wgVGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUg
-SW5jLjE3MDUGA1UEAxMuQU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
-ggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ7ouZzU9AhqS2TcnZsdw8TQ2FTBVs
-RotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilbm2BPJoPRYxJWSXakFsKlnUWs
-i4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOYxFSMFkpBd4aVdQxHAWZg
-/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZYYCLqJV+FNwSbKTQ
-2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbqJS5Gr42whTg0
-ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fxI2rSAG2X
-+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETzkxml
-J85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh
-EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNo
-Kk/SBtc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJ
-Kg71ZDIMgtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1Ex
-MVCgyhwn2RAurda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMB
-Af8wHQYDVR0OBBYEFE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaA
-FE9pbQN+nZ8HGEO8txBO1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
-9w0BAQUFAAOCAgEAO/Ouyuguh4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0
-cnAxa8cZmIDJgt43d15Ui47y6mdPyXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRF
-ASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q7C+qPBR7V8F+GBRn7iTGvboVsNIY
-vbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKTRuidDV29rs4prWPVVRaAMCf/
-drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/ClTluUI8JPu3B5wwn3la
-5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyBM5kYJRF3p+v9WAks
-mWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQmy8YJPamTQr5
-O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xOAU++CrYD
-062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT9Y41
-xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H
-hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOL
-Z8/5fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4
-dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h
-bCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzEL
-MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1B
-ZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1
-c3QgRXh0ZXJuYWwgQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBALf3GjPm8gAELTngTlvtH7xsD821+iO2zt6bETOXpClMfZOfvUq8
-k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfwTz/oMp50
-ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504
-B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDez
-eWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5
-aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0WicCAwEAAaOB
-3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0PBAQD
-AgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6
-xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdv
-cmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJ
-KoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
-j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5R
-xNKWt9x+Tu5w/Rw56wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjT
-K3rMUUKhemPR5ruhxSvCNr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1
-n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHx
-REzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49O
-hgQ=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU
-UCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3Qw
-HhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU
-UCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3Qw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwze
-xODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY654eyNAbFvAWlA3yCyykQruGI
-gb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWroulpOj0O
-M3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1Lc
-sRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5
-mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG
-9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0OBBYEFJWxtPCU
-tr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
-MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQsw
-CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
-ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAx
-IENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0
-MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
-iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9
-tTEv2dB8Xfjea4MYeDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL
-/bscVjby/rK25Xa71SJlpz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlV
-g3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6
-tkD9xOQ14R0WHNC8K47Wcdk=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU
-UCBOZXR3b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAe
-Fw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNF
-MRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
-IE5ldHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+
-A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c
-+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1id9NEHif2
-P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKX
-C1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8R
-s3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9
-BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQWBBSBPjfYkrAf
-d59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zCB
-jgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkG
-A1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
-cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENB
-IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmu
-G7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
-+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbj
-PGsye/Kf8Lb93/AoGEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bY
-GozH7ZxOmuASu7VqTITh4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6
-NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9HEufOX1362Kqx
-My3ZdvJOOjMMK7MtkAY=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJT
-RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRU
-UCBOZXR3b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9v
-dDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYT
-AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3Qg
-VFRQIE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBS
-b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoek
-n0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKk
-IhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3KP0q6p6z
-sLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1t
-UvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R
-+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvES
-a0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0GA1UdDgQWBBQ5
-lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
-AwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkw
-ZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
-ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVh
-bGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2Vh
-lRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
-GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx9
-5dr6h+sNNVJn0J6XdgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKF
-Yqa0p9m9N5xotS1WfbC3P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVA
-wRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQw
-dOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV
-UzEcMBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1l
-cmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4X
-DTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMx
-HDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJp
-Y2EgT25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCa
-xlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CGv2BlnEtUiMJIxUo5vxTjWVXl
-GbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44zDyL9Hy7n
-BzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145Lcx
-VR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiE
-mf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCu
-JKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
-HQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Zo/Z5
-9m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUA
-A4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
-Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOM
-IOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTI
-dGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
-Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j
-8uB9Gr784N/Xx6dssPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV
-UzEcMBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1l
-cmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4X
-DTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMx
-HDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJp
-Y2EgT25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw
-DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssN
-t79Hc9PwVU3dxgz6sWYFas14tNwC206B89enfHG8dWOgXeMHDEjsJcQDIPT/
-DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8f3SkWq7x
-uhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE
-18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxr
-kJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMD
-bi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8BPeraunzgWGcX
-uVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn6KVu
-Y8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9
-W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
-o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48
-ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124Hhn
-AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op
-aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNee
-MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypL
-M7PmG2tZTiLMubekJcmnxPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qf
-tIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjR
-Ywu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R
-+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr
-+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVM
-nNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMADjMSW7yV5TKQqLPGbIOt
-d+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh1NolNscI
-WC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZ
-ZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y
-3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz
-2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
-RY8mkaKO/qk=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQG
-EwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0
-MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUx
-MjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNV
-BAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZ
-QmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+h
-Xe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gR
-QKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP
-wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1
-pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNT
-Px8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkC
-AwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1BE3wMBIGA1Ud
-EwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUA
-A4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkT
-I7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/
-oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67
-G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
-RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYT
-AlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNl
-cnR1bSBDQTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJ
-BgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNV
-BAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AM6xwS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYV
-M42sLQnFdvkrOYCJ5JdLkKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/Ox
-LjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE
-7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/KUz/iDsaW
-VhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu
-/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYD
-VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESS
-bLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQaTOs9qmdvLdTN
-/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvgGrZg
-FCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqT
-E5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
-O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYV
-IZQs6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJH
-QjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxm
-b3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFB
-IENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIz
-MTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
-Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENB
-IExpbWl0ZWQxITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5AnfRu4ep2hxxNRUSO
-vkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhGC1Pqy0wk
-wLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfH
-dr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf04
-9vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULi
-mAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cmez6KJcfA3Z3m
-NWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEKIz6W
-8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
-Af8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
-QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwu
-Y29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG
-9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
-7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHC
-v8S5dIa2LX1rzNLzRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdV
-CYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAV
-GI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C12yxow+ev+to
-51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJH
-QjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxm
-b3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2Vj
-dXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4
-MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIg
-TWFuY2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2Rv
-IENBIExpbWl0ZWQxJDAiBgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2
-aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBxM4KK0HDr
-c4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP9nQ95IDC
-+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8
-j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWC
-iIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtG
-Cd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz6YiO/O1R65Nx
-Tq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4EFgQU
-PNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
-/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
-Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNo
-dHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNl
-cy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
-4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiF
-Gv45jN5bBAS0VPmjZ55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXG
-De+X3EyrEeFryzHRbPtIgKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsF
-Vy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfU
-a7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6s
-Cx1HRR3B7Hzs/Sk=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJH
-QjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxm
-b3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1
-c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0y
-ODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVy
-IE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9k
-byBDQSBMaW1pdGVkMSUwIwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNl
-cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhT
-WvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh73TkVvFVI
-xO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9
-C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/
-oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW1O24zG71++IsWL1/
-T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7kUlcsutT6vif
-R4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1UdDgQW
-BBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
-ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2
-hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2Vy
-dmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
-uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdT
-mw7pSqBYaWcOrp32pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+C
-l5EfKNsYEYwq5GWDVxISjBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/g
-hhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVF
-wL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOj
-GM9O9y5Xt5hwXsjEeLBi
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQG
-EwJVUzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREw
-DwYDVQQLEwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQw
-MjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy
-ZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEB
-AQUAA4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlR
-EmlvMVW5SXIACH7TpWJENySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+Lth
-zfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2io74CTADKAqjuAQIxZA9SLRN0
-dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBoBgNVHR8E
-YTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwg
-U2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNV
-BAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIx
-MDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5fpFpRhgTCgJ3
-pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAMBgNV
-HRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3
-DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN
-QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomA
-sH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6
-w4pl
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGp
-MQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBM
-YWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENv
-LjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx
-ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDEx
-ODE4NTVaFw0wODExMjgxODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UE
-CBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0Rp
-Z2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDEx
-FjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0BCQEWEmNhQGRp
-Z3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdfWvnTLnUv2Chi0ZMv/E3U
-q4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uKxBmd9LIO/BZsubEF
-koPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBEzUNKcI5YhZXh
-TizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F5X5yP4Wd
-lGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMvOnNn
-7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG
-9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+
-LegzZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvV
-WlHG4VMElo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX
-8ngvYzZAOONGDx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn8
-6Oawde3uPclwx12qgUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsT
-F7ANUkz+/m9c4pFuHf2kYtdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQG
-EwJVUzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREw
-DwYDVQQLEwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3
-MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVy
-ZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEB
-AQUAA4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fB
-w18DW9Fvrn5C6mYjuGODVvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87e
-ZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd
-55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBoBgNVHR8E
-YTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwg
-U2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNV
-BAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIw
-OTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6CTShlgDzJQW6s
-NS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAMBgNV
-HRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3
-DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR
-xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLb
-dHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlih
-w6ID
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGp
-MQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBM
-YWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENv
-LjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx
-ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAy
-MjQ2MTZaFw0wODExMjcyMjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UE
-CBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0Rp
-Z2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgWDIx
-FjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0BCQEWEmNhQGRp
-Z3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbVp9oaBBg5kkp4o4HC9Xd6
-ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWwBZoPFflrWXJW8vo5
-/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl5WJp3OXuAFK9
-MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi3sOP17ih
-YqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+QVCv
-bK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG
-9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWog
-WxyQ2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6
-HE3K1GjNI3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV
-6YyDfFk/xPEL553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8
-PzGn0EdzMzkbzE5q10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30
-sPDst2yC7S8xmUJMqbINuBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NB
-X0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
-HChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
-c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAy
-MDcxNjE2NDBaFw0yMDAyMDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0
-Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29y
-cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg
-RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xp
-ZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7NySpj10InJrWPNTTVRaoTU
-rcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0iJBeAZfv6lOm3fzB
-3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn5JVn1j+SgF7y
-NH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHdBgNVHR8E
-gdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUAw
-PgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy
-ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0
-Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
-IoAPMjAwMDAyMDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQD
-AgEGMB8GA1UdIwQYMBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQW
-BBSEi3T9xY3A/ydtIDdFfP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2
-fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWA
-O9GK9Q6nIMstZVXQkvTnhLUGJoMShAusO7JE7r3PQNsgDrpuFOow4DtifH+L
-a3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/GpsKkMWr2tGzhtQvJFJcem3G8v7l
-TRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKdzmVml64mXg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xf
-Q1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
-KGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVz
-dC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wMDAyMDQxNzIwMDBaFw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtF
-bnRydXN0Lm5ldDE/MD0GA1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMg
-aW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg
-MjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5l
-dCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0G
-CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO8GCGD9JYf9Mzly0XonUw
-tZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaBbL3+qPZ1V1eMkGxK
-wz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2dWcTC5/oVzbI
-XQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4QgEBBAQD
-AgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoTC0Vu
-dHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAy
-MDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0
-IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNV
-BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIw
-NDE3NTAwMFowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc
-/vuLkpyw8m4iMB0GA1UdDgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNV
-HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkq
-hkiG9w0BAQQFAAOBgQBi24GRzsiad0Iv7L0no1MPUBvqTpLwqa+poLpIYcvv
-yQbvH9X07t9WLebKahlzqlO+krNQAraFJnJj2HVQYnUUt7NQGj/KEQALhUVp
-bbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1UyrrJzOCE98g+EZfTYAkYvAX/
-bIkz8OwVDw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNf
-MjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsT
-HChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1
-c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEy
-MjQxNzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0
-Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29y
-cC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkg
-RW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2Vy
-dGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4
-QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/EC
-DNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuXMlBvPci6Zgzj
-/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzWnLLP
-KQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZd
-enoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
-4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB
-0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJ
-FrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
-AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFh
-fGPjK50xA3B20qMooPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVU
-KcgF7bISKo30Axv/55IQh7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaoho
-wXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2
-+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof888
-6ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UE
-BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50
-cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBs
-aW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExp
-bWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0
-aW9uIEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBa
-MIHJMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNV
-BAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3Jw
-LiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50
-cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GL
-ADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSv
-x1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux5zDeg7K6PvHV
-iTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTmT173
-iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkw
-ggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50
-cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0Ff
-SW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UE
-CxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50
-cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYD
-VQQDEwRDUkwxMCygKqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9D
-bGllbnQxLmNybDArBgNVHRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkx
-MDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW
-/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwG
-A1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
-hvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQ
-OokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzzwy5E97BnRqqS5TvaHBkU
-ODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYGJqibGapE
-PHayXOw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UE
-BhMCVVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50
-cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
-MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UE
-AxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQsw
-CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3
-dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlh
-Yi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTow
-OAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
-b24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0
-VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHIN
-iC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3wkrYKZImZNHk
-mGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcwggHT
-MBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHY
-pIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
-BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChs
-aW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBM
-aW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNo
-dHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAi
-gA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMC
-AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYE
-FPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9
-B0EABAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKn
-CqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2Zcgx
-xufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd2cNgQ4xYDiKWL2KjLB+6
-rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG
-EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1
-cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4
-MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgx
-LTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0
-eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2R
-FGiYCh7+2gRvE4RiIcPRfM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO
-/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuv
-K9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAGA1UdHwRp
-MGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEt
-MCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
-MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjAL
-BgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gjIBBPM5iQn9Qw
-HQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMBAf8w
-GgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GB
-AFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2u
-FHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJV
-UzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1
-aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0
-MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoT
-E0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJl
-IEdsb2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAuucXkAJlsTRVPEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQy
-td4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORR
-OhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxnhcXIw2EC
-AwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8w
-HwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6o
-oHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf
-2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkAZ70Br83gcfxa
-z2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIYNMR1
-pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJV
-UzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1
-aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcN
-MjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZh
-eCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2lu
-ZXNzIENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fe
-k6lfWg0XTzQaDJj0ItlZ1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5
-/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4aIZX5UkxVWsUPOE9G+m34LjXW
-HXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBkMBEGCWCG
-SAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4
-MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBq
-R3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnm
-JXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+WB5Hh1Q+WKG1
-tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+KpYr
-tWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG
-EwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlm
-YXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5
-MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXgg
-U2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0Et
-MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF
-7Y6yEb3+6+e0dMKP/wXn2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKD
-pkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HM
-HMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAGA1UdHwRp
-MGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBT
-ZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y
-MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjAL
-BgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBqy/3YIHqngnYw
-HQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMBAf8w
-GgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GB
-AAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
-0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkt
-y3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgw
-FgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRy
-dXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg
-R2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1
-MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYD
-VQQLEx5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMT
-GkdURSBDeWJlclRydXN0IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUA
-A4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4usJTQGz0O9pTAipTHBsiQl8i4
-ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcqlHHK6XALn
-ZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8F
-LztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh3
-46B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq
-81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0PlZPvy5TYnh+d
-XIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgw
-FgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRy
-dXN0IFJvb3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQsw
-CQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQD
-ExNHVEUgQ3liZXJUcnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
-iQKBgQC45k+625h8cXyvRLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8K
-DPufpz+iCWaEVh43KRuH6X4MypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPw
-KfWVWgkWYXcKIiXUT0Wqx73llt/51KiOQswkwB6RJ0q1bQaAYznEol44AwID
-AQABMA0GCSqGSIb3DQEBBAUAA4GBABKzdcZfHeFhVYAA1IFLezEPI2PnPfMD
-+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWlIjeaY8JIILTbcuPI9tl8vrGv
-U9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9ApybW1EDp3zdHSo1TRJ6V6e
-6bR64eVaH4QwnNOfpSXY
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYT
-AlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVz
-dCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBC
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
-AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEH
-CIjaWC9mOSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlC
-GDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7
-csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAj
-Nvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdRe
-JivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQAB
-o1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9
-qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjANBgkq
-hkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Qzxpe
-R+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWV
-Yrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot
-2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeX
-xx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
-Mw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzEL
-MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNV
-BAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05
-ODA5MDExMjAwMDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkw
-FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRsw
-GQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQDaDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR
-4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc
-71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4
-bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgK
-OOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMW
-ea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DP
-AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQUYHtmGkUNl8qJ
-UC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOC
-AQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq75bCd
-PTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q
-gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT
-2iHRrH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlD
-NPYPhyk7ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBg
-Hcl5JLL2bP2oZg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjEuMCwGA1UECxMlSVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTEuMCwGA1UEAxMlSVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAx
-MTIyOTAwNTkzOFoXDTI1MTIyNzAwNTkzOFowggESMQswCQYDVQQGEwJFUzES
-MBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNV
-BAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzAp
-BgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxLjAs
-BgNVBAsTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
-LjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywSzHb5
-BlmvXSHU0lq4oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBS
-YmL9Yzt9fuzuOOpi9GyocY3h6YvJP8a1zZRCb92CRTzo3wno7wpVqVZHYUxJ
-ZHMQKD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBTrsxl588GlHKzc
-uh9morKbadB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKb
-adB4CKGCARqkggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl
-bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJu
-ZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFp
-bC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0Eg
-Q0xBU0UxIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMg
-Q0EgQ0xBU0UxIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcN
-AQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E
-BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUH
-AwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB
-FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcw
-GgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0Bt
-YWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRpZmlj
-YXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC
-BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQt
-FitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3Js
-MD8GCWCGSAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jl
-dm9jYXRpb25DTEFTRTEuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93
-d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFMS5odG1sPzA6BglghkgB
-hvhCAQgELRYraHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFT
-RTEuaHRtbDBzBgNVHR8EbDBqMDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9p
-cHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMDWgM6Axhi9odHRwOi8vd3d3YmFj
-ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0UxLmNybDAvBggrBgEFBQcB
-AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI
-hvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuKYn4VLenZMdMu9Ccj/1ur
-xUq2ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpjV4F1Wo7ojPsCwJTG
-Kbqz3Bzosq/SLmJbGqmODszFV0VRFOlOHIilkfSj945RyKm+hjM+5i9Ibq9U
-kE6tsSU=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjEuMCwGA1UECxMlSVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTEuMCwGA1UEAxMlSVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAx
-MTIyOTAxMDE0NFoXDTI1MTIyNzAxMDE0NFowggESMQswCQYDVQQGEwJFUzES
-MBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNV
-BAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzAp
-BgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxLjAs
-BgNVBAsTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
-LjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZH49N
-zjaY2uQARIwo2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY
-8jjsbJ0gA8DvqqPGZARRLXgNo9KoOtYkTOmWehisEyMiG3zoMRGzXwmqMHBx
-RiVrSXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBS4k/8uy9wsjqLn
-ev42USGjmFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGj
-mFsMNKGCARqkggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl
-bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJu
-ZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFp
-bC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0Eg
-Q0xBU0UzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMg
-Q0EgQ0xBU0UzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcN
-AQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E
-BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUH
-AwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB
-FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcw
-GgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0Bt
-YWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRpZmlj
-YXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC
-BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQt
-FitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3Js
-MD8GCWCGSAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jl
-dm9jYXRpb25DTEFTRTMuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93
-d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFMy5odG1sPzA6BglghkgB
-hvhCAQgELRYraHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFT
-RTMuaHRtbDBzBgNVHR8EbDBqMDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9p
-cHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMDWgM6Axhi9odHRwOi8vd3d3YmFj
-ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0UzLmNybDAvBggrBgEFBQcB
-AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI
-hvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dDqsfwfewPxqmurpYPdikc
-4gYtfibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9D6eSb9ijBmgpjnn1
-/7/5p6/ksc7C0YBCJwUENPjDfxZ4IwwHJPJGR607VNCv1TGyr33I6unUVtkO
-E7LFRVA=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcN
-MDExMjI5MDEwNTMyWhcNMjUxMjI3MDEwNTMyWjCCARQxCzAJBgNVBAYTAkVT
-MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwG
-A1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjEr
-MCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEv
-MC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8m2md
-d81u4D/u6zJfX5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4Wwd
-ByOgF9H5fahGRpEiqLJpxq339fWUoTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1
-e+J8eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUZyaW56G/
-2LUDnf473P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf47
-3P7yiuYV3TChggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlC
-YXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIElu
-dGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBz
-QG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBT
-IENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT
-JklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJ
-KoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM
-BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYI
-KwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYB
-BAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEE
-BAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB
-D2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBDQSBD
-ZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG
-SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgB
-hvhCAQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xB
-U0VBMS5jcmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lw
-czIwMDIvcmV2b2NhdGlvbkNMQVNFQTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAW
-Lmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTEuaHRt
-bD8wOwYJYIZIAYb4QgEIBC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIv
-cG9saWN5Q0xBU0VBMS5odG1sMHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93
-d3cuaXBzLmVzL2lwczIwMDIvaXBzMjAwMkNMQVNFQTEuY3JsMDagNKAyhjBo
-dHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5j
-cmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5p
-cHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyAAIQVCtWYUQxkxZwCWINm
-yq0eB81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeFaQoO42Hu6r4okzPV
-7Oi+xNtff6j5YzHIa5biKcJboOeXNp13XjFr/tOn2yrb25aLH2betgPAK7N4
-1lUH5Y85UN4HI3LmvSAUS7SG
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcN
-MDExMjI5MDEwNzUwWhcNMjUxMjI3MDEwNzUwWjCCARQxCzAJBgNVBAYTAkVT
-MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwG
-A1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjEr
-MCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEv
-MC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvNG7uG
-BiJ2MwwSbUhWYdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHU
-VqLyjRGZ/fZ98cfEXgIqmuJKtROKAP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4
-Ninn6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUHp9XUEe2
-YZM50yz82l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz8
-2l09BXW3mQKhggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlC
-YXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIElu
-dGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBz
-QG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBT
-IENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT
-JklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJ
-KoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM
-BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYI
-KwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYB
-BAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEE
-BAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB
-D2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBDQSBD
-ZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG
-SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgB
-hvhCAQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xB
-U0VBMy5jcmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lw
-czIwMDIvcmV2b2NhdGlvbkNMQVNFQTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAW
-Lmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTMuaHRt
-bD8wOwYJYIZIAYb4QgEIBC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIv
-cG9saWN5Q0xBU0VBMy5odG1sMHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93
-d3cuaXBzLmVzL2lwczIwMDIvaXBzMjAwMkNMQVNFQTMuY3JsMDagNKAyhjBo
-dHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5j
-cmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5p
-cHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca2on0eisxeewBwMwB9dbB
-/MjD81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI3y2s6Q73nMify5NF
-8bpqxmdRSmlPa/59Cy9SKcJQrSRE7SOzSMtEQMEDlQwKeAYSAfWRMS1Jjbs/
-RU4s4OjNtckUFQzjB4ObJnXv
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjEzMDEGA1UECxMqSVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MTMwMQYDVQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlw
-cy5lczAeFw0wMTEyMjkwMDUzNThaFw0yNTEyMjcwMDUzNThaMIIBHDELMAkG
-A1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vs
-b25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNl
-cyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYw
-OTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFpbmVkIENBcyBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1h
-aWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJspQg
-vJhPUOtopKdJC7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCB
-hYEFcYGdtJUZqV92NC5jNzVXjrQfQj8VXOF6wV8TGDIxya2+o8eDZh65nAQT
-y2nBBt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQIDAQABo4IEQzCCBD8w
-HQYDVR0OBBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCC
-AUGAFKGtMbH5PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQG
-EwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmEx
-LjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMu
-bC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0
-NTIxMzAxBgNVBAsTKklQUyBDQSBDaGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTEzMDEGA1UEAxMqSVBTIENBIENoYWluZWQgQ0FzIENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5p
-cHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRk
-MGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggr
-BgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYK
-KwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBz
-QG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglg
-hkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkg
-aHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3
-Lmlwcy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5p
-cHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYt
-aHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/
-MDkGCWCGSAGG+EIBBwQsFipodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jl
-bmV3YWxDQUMuaHRtbD8wNwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBz
-LmVzL2lwczIwMDIvcG9saWN5Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYo
-aHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCg
-LoYsaHR0cDovL3d3d2JhY2suaXBzLmVzL2lwczIwMDIvaXBzMjAwMkNBQy5j
-cmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5p
-cHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1WWKJBGyi3leGmGpVfp3hA
-K+/blkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfNHnNDJGD1HWHc3Jag
-vPsd4+cSACczAsDAK1M92GsDgaPb1pOVIO/Tln4mkImcJpvNb2ar7QMiRDjM
-Wb2f2/YHogF/JsRj9SVCXmK9
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICtzCCAiACAQAwDQYJKoZIhvcNAQEEBQAwgaMxCzAJBgNVBAYTAkVTMRIw
-EAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UE
-ChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVz
-MRcwFQYDVQQDEw5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBz
-QG1haWwuaXBzLmVzMB4XDTk4MDEwMTIzMjEwN1oXDTA5MTIyOTIzMjEwN1ow
-gaMxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcT
-CUJBUkNFTE9OQTEZMBcGA1UEChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UE
-CxMPQ2VydGlmaWNhY2lvbmVzMRcwFQYDVQQDEw5JUFMgU0VSVklET1JFUzEe
-MBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQCsT1J0nznqjtwlxLyYXZhkJAk8IbPMGbWOlI6H0fg3
-PqHILVikgDVboXVsHUUMH2Fjal5vmwpMwci4YSM1gf/+rHhwLWjhOgeYlQJU
-3c0jt4BT18g3RXIGJBK6E2Ehim51KODFDzT9NthFf+G4Nu+z4cYgjui0OLzh
-PvYR3oydAQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACzzw3lYJN7GO9HgQmm4
-7mSzPWIBubOE3yN93ZjPEKn+ANgilgUTB1RXxafey9m4iEL2mdsUdx+2/iU9
-4aI+A6mB0i1sR/WWRowiq8jMDQ6XXotBtDvECgZAHd1G9AHduoIuPD14cJ58
-GNCr+Lh3B0Zx8coLY1xq+XKU1QFPoNtC
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYT
-AkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEu
-MCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5s
-LjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1
-MjE0MDIGA1UECxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9u
-IEF1dGhvcml0eTE0MDIGA1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu
-aXBzLmVzMB4XDTAxMTIyOTAxMTAxOFoXDTI1MTIyNzAxMTAxOFowggEeMQsw
-CQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJj
-ZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZp
-Y2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEIt
-NjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3RhbXBpbmcgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBUaW1lc3RhbXBp
-bmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lw
-c0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLju
-VqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4
-Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6
-KaFYq6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAw
-ggR8MB0GA1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSC
-AUcwggFDgBSL0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkG
-A1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vs
-b25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNl
-cyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYw
-OTI5NDUyMTQwMgYDVQQLEytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5MTQwMgYDVQQDEytJUFMgQ0EgVGltZXN0YW1waW5n
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNA
-bWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsG
-A1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUF
-BwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGC
-NwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw
-EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5l
-czBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl
-IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwW
-Gmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFo
-dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcu
-Y3JsMEUGCWCGSAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAy
-L3Jldm9jYXRpb25UaW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUW
-M2h0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGlu
-Zy5odG1sPzBABglghkgBhvhCAQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBz
-MjAwMi9wb2xpY3lUaW1lc3RhbXBpbmcuaHRtbDB/BgNVHR8EeDB2MDegNaAz
-hjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBp
-bmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9p
-cHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYB
-BQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEA
-ZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk36MNbsMRnLWha
-sl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I3pGW7hdb
-rqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQG
-EwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9v
-dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMg
-Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNa
-Fw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9W
-YWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1
-lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMukJ0KX0J+D
-isPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj18
-2d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Sp
-x2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZ
-yH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospUxbF6lR1xHkop
-igPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4wPQYI
-KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFk
-aXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlh
-bmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBw
-YXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
-ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRp
-ZmljYXRpb24gcHJhY3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmlj
-YXRlIFBvbGljeS4wIgYIKwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMu
-Ym0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYw
-gaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJN
-MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290
-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCLMA4GA1UdDwEB/wQEAwIB
-BjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lofFIk3Wdv
-OXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10
-buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe
-/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6
-isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQ
-NiOKSnQ2+Q==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD
-ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
-Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRp
-b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv
-bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy
-NjAwMjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x
-NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24g
-QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x
-IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2f
-NUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChM
-MFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqYJJgpp0lZpd34
-t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs3x/b
-e0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0Wu
-PIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
-PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUF
-ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg
-U2VjdXJpdHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAx
-NDlaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT
-QSBTZWN1cml0eSAxMDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQDV3f5mCc8kPD6ugU5OisRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dY
-rIMKo1W1exeQFYRMiu4mmdxY78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYt
-bzZUaMjShFbuklNhCbM/OZuoyZu9zp9+1BlqFikYvtc6adwlWzMaUQIDAQAB
-o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSME
-GDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAdBgNVHQ4EFgQUxMAcpAeU/c1N
-AdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEAPy1q4yZDlX2Jl2X7deRy
-HUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdNT1+nr6JGFLkM88y9
-am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgDmMrzVcydro7B
-qkWY+o8aoI2II/EVQQ2lRj6RP4vr93E=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUF
-ADA6MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0Eg
-U2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5
-MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJT
-QSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37
-RqtBaB4Y6lXIL5F4iSj7Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E
-0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J
-6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iHKrtjEAMq
-s6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzD
-uvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2Mw
-YTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAW
-gBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NRMKSq6UWuNST6
-/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmYv/3V
-EhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5g
-EydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
-f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJq
-aHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEk
-llgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
-pKnXwiJPZ9d37CAFYd4=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJK
-UDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0
-eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMw
-OTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1
-c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RD
-QTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8
-V6UMbXaKL0u/ZPtM7orw8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpx
-xpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uMDPpVmDvY6CKhS3E4eayXkmmz
-iX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX5HA49LY6
-tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819
-uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/L
-TX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZ
-aNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g0dNq
-/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94
-nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
-Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNn
-PaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfci
-oU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
-FL39vmwLAw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJG
-STEPMA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENB
-MB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMC
-RkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue
-+H887dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mX
-y47vPxVnqIJyY1MPQYx9EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNY
-wBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JF
-hfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF6452F/NM8Ec
-yonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW
-1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB
-/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEB
-BQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuXZfsSZ9gqXLar
-5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxVyhbM
-p6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2
-nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv
-kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2y
-Ix4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJG
-STEPMA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENB
-MB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMC
-RkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE
-+hY3/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gX
-GM2RX/uJ4+q/Tl18GybTdXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQ
-TiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMGf+dJQMjFAbJUWmYdPfz56TwK
-noG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8PtOFCx4j1
-P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURr
-BGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB
-/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEB
-BQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zilzqsWuasvfDXL
-rNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEIcbCd
-jdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr4
-50kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
-Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkeja
-nZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG
-EwJOTDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQD
-Ex1TdGFhdCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIz
-NDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVT
-dGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRl
-cmxhbmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAmNK1URF6gaYUmHFtvsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rF
-DBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02PjLwYdjeFnejKScfST5gTCaI+
-Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGcaC1Hoi6Ce
-UJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7l
-r7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4Zl
-kuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGO
-MAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDwwOgYIKwYBBQUH
-AgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9vdC1w
-b2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg
-0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
-/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVF
-IGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0
-C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
-nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBp
-IzlWYGeQiy52OfsRiJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYV
-wSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYT
-AkRFMRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYD
-VQQKEzFUQyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3
-b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENB
-MSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAe
-Fw05ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJE
-RTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UE
-ChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29y
-a3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTEp
-MCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0yAClxgwENv4wB3NrGrTmk
-qYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDwTFXlay3HhQswHJJO
-gtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8/vhYnvgpjbB7
-zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQFMAMBAf8w
-DgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G
-CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+W
-LDO/jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xR
-T3h2oNmsGb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/Ac
-ASZ4smZHcFFk
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYT
-AkRFMRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYD
-VQQKEzFUQyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3
-b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENB
-MSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAe
-Fw05ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJE
-RTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UE
-ChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3VyaXR5IGluIERhdGEgTmV0d29y
-a3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTEp
-MCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUFLg2N7KBAahwOJ6ZQkmtQ
-GwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGwDtf7pBc9r6tpepYn
-v68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDWw1Krj10nnGvA
-o+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQFMAMBAf8w
-DgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G
-CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4
-iJIETb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yC
-GdHHsbHD2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQS
-CdS7kjXvD9s0
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQG
-EwJESzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50
-ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTda
-MEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNV
-BAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4Nr
-XceO+YQwzho7+vvOi20jxsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaq
-HF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5
-Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc5IogCSEW
-Vmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8n
-mHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwID
-AQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBY
-oFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIEludGVybmV0MR0w
-GwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JMMTAr
-BgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjAL
-BgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
-HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8w
-HQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
-gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKs
-LtB9KOy282A4aW8+2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7T
-mHnaCB4Mb7j4Fifvwm899qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE
-64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQ
-V0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQG
-EwJESzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0w
-MzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQww
-CgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSj
-hFuHnEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8
-z3sM8W9Hpg1DTeLpHTk0zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJH
-hNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvViGjaXbXqzRowwYCDdlCqT9HU
-3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBdedObaE+3p
-Hx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTw
-tyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
-Af8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYB
-BQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBvc2l0b3J5MIGd
-BggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBmcmEg
-ZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x
-LiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg
-T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEG
-A1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERD
-MRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm
-aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0Q
-BCQwIoAPMjAwMzAyMTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0j
-BBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4S
-GSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDAN
-BgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBu
-o7E4A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjND
-fZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8Aqt
-FxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoBmbgGglGBTvH1tJFUuSN6
-AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1AoLbrIyi
-gfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2Lq
-L19iUw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBl
-cnNvbmFsIEJhc2ljIENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNp
-Y0B0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVow
-gcsxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNV
-BAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAm
-BgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xITAfBgNV
-BAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBDQTEoMCYGCSqGSIb3DQEJARYZ
-cGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOB
-jQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53dXLdjUmbllegeNTK
-P1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdKwPQIcOk8RHtQ
-fmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7G1sY0b8j
-kyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOB
-gQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
-c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95
-B21P9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBl
-cnNvbmFsIEZyZWVtYWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1m
-cmVlbWFpbEB0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIz
-NTk1OVowgdExCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUx
-EjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UEChMRVGhhd3RlIENvbnN1bHRp
-bmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x
-JDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBDQTErMCkGCSqG
-SIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhhd3RlLmNvbTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfYDFG26nKRsIRefS0N
-j3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5ErHzmj+hND3Ef
-QDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVquzgkCGqY
-x7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
-hkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
-MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgC
-neSa/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr
-5PjRzneigQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MRowGAYDVQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBl
-cnNvbmFsIFByZW1pdW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXBy
-ZW1pdW1AdGhhd3RlLmNvbTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5
-NTlaMIHPMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIw
-EAYDVQQHEwlDYXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5n
-MSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMSMw
-IQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJlbWl1bSBDQTEqMCgGCSqGSIb3
-DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0VsBd/eJxZRNkERbGw7
-7f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWIEt12TfIa/G8j
-Hnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYDZicRFTuq
-W/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
-b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVx
-eTBhKXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1
-KzGJ
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy
-dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3Rl
-IFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl
-cnZlckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1
-OVowgc4xCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQ
-BgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENvbnN1bHRpbmcg
-Y2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24x
-ITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3
-DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhI
-NTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQug2SBhRz1JPL
-lyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/qgeN
-9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
-AQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
-hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZ
-a4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcU
-Qg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du
-MR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy
-dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3Rl
-IFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
-ZS5jb20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkG
-A1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2Fw
-ZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE
-CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQ
-VGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRz
-QHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I
-/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC
-6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCXL+eQbcAoQpnX
-TEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzARMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWD
-TSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
-QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdni
-TCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMC
-WkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmls
-bGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmlj
-YXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcw
-MTAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTAT
-BgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
-BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24x
-HzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcN
-AQEBBQADgY0AMIGJAoGBANYrWHhhRYZT6jR7UZztsOYuGA7+4F+oJ9O0yeB8
-WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQaWt9MevPZQx08EHp5JduQ/vBR
-5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL8vg7ij5FrHGSALSQQZj7
-X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
-AQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC9RAIDb/LogWK
-0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQpgCed/r8
-zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZCayJ
-SdM=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUF
-ADCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
-HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVU
-Ti1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0
-ODM5WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgT
-AlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVT
-RVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVz
-dC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNh
-dGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZV
-hawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAb
-GHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZ
-NaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hAReYFmnjDRy7rh4
-xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwiP8vv
-/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7i
-gEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD
-AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf
-8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0
-LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G
-CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXh
-i6r/fWRRzwr/vH3YIWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUq
-f9FuVSTiuwL7MT++6LzsQCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAf
-hZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvP
-NximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+
-FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjis
-H8SE
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUF
-ADCBkzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
-HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVU
-TiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2
-MzBaMIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNh
-bHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
-ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMS
-VVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+O
-GQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrr
-U0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrL
-Z9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykqlXvY8qdOD1R8
-oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv33i+
-Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4Gr
-MIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
-MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8v
-Y3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUE
-IzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
-DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHc
-rpY6CiM+iVnJowftGzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuM
-FrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1
-+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdO
-jtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jF
-VkwPDPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUF
-ADCBrjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
-HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVU
-Ti1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAe
-Fw05OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJV
-UzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
-VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93
-d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGll
-bnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxq
-mNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqk
-kqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6lL8/K2m2qL+us
-obNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHGTPNp
-saguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZU
-Ot4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
-6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0G
-A1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJ
-hkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll
-bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEF
-BQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rk
-MPxTbyUkxsrt4jFcKw7u7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK
-2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/
-bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJR
-warVNZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf
-6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQ
-jvLzxq4oW6fw8zYX/MMF08oDSlQ=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUF
-ADCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
-HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVU
-Ti1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5
-MTgxOTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQH
-Ew5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3
-b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNV
-BAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZ
-FvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6N
-q9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEH
-OG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNdoI6yqqr2jmmI
-BsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjfPe58
-BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhb
-AgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWG
-M2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3
-YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
-BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0o
-XnWO6y1n7k57K9cM//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjA
-bPLPSbtNk28GpgoiskliCE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59
-Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4f
-Fm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchq
-J/kniCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0q
-UZ6B+dQ7XnASfxAynB67nfhmqA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUF
-ADCBlTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0
-IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEw
-HwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVU
-Ti1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4
-NDAzNlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMO
-U2FsdCBMYWtlIENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29y
-azEhMB8GA1UECxMYaHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR0wGwYDVQQD
-ExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r55
-96Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc
-/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2
-yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+pKvEHDHd17bR
-5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7RwvC
-bNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEA
-AaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0
-cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNy
-bDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw
-DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXF
-wfNfLEzIR1pp6ujwNTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T
-7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85
-dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U
-+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCA
-GKCGhU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2o
-Ps0AH8g=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD
-ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
-Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRp
-b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv
-bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy
-NTIyMjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x
-NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24g
-QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x
-IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw
-8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m
-+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8YTfwggtFzVXSN
-dnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwGlN+V
-YH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8so
-gTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
-nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlD
-ZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
-Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRp
-b24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNv
-bS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYy
-NjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4x
-NTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
-QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x
-IDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3
-DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc
-65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQ
-b7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcn
-wbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4
-OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZ
-oDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
-W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8x
-CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UE
-CxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eTAeFw05NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNV
-BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
-c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCB
-nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3
-noaACpEO+jglr0aIguVzqKCbJF0NH8xlbgyw0FaEGIeaBpsQoXPftFg5a27B
-9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR4k5FVmkfeAKA2txHkSm7NsljXMXg
-1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATANBgkqhkiG9w0BAQIFAAOBgQBM
-P7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZoEWx8QszznC7EBz8UsA9P
-/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5FvjqBUuUfx3CHMjj
-t/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89FxlA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcEx
-CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE
-CxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt
-IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU
-cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
-gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG
-A1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j
-LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln
-biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq
-0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9
-Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSmFc/IReumXY6c
-PvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9Zr
-bWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
-uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4i
-P/68DzFc6PLZ
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHK
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV
-BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5
-IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD
-BgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3
-MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s
-IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV
-BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg
-dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFBy
-aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRR
-ZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO8ESlV8dAWB6j
-Rx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJrKsh
-JlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7P
-oBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
-6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHh
-v2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQ
-BfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N
-y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUf
-xJM8/XmPBNQ+T+r3ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFM
-DSZl4kSAHsef493oCtrspSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5
-SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXV
-OBRgmaNL3gaWcSzy27YfpO8/7g==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDnjCCAwegAwIBAgIQK2jUo0aexTsoCas4XX8nIDANBgkqhkiG9w0BAQUF
-ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1
-BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwHhcNMDAwODA0MDAwMDAwWhcNMDQwODAzMjM1OTU5WjCBpzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov
-L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAx
-IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQC57V56Ondfzl86UvzNZPdxtW9qlsZZklWUXS9bLsER
-6iaKy6eBPPZaRN56Ey/9WlHZezcmSsAnPwQDalbBgyzhb1upVFAkSsYuekyh
-WzdUJCExH6F4GHansXDaItBq/gdiQMb39pt9DAa4S8co5GYjhFHvRreT2IEz
-y+U2rMboBQIDAQABo4IBEDCCAQwwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT
-CE9DU1AgMS0xMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwudmVyaXNp
-Z24uY29tL3BjYTEuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEIGCCsGAQUF
-BwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j
-b20vb2NzcC9zdGF0dXMwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcBATAqMCgG
-CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vUlBBMAkGA1Ud
-EwQCMAAwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBBQUAA4GBAHCQ3bjkvlMX
-fH8C6dX3i5mTMWCNfuZgayTvYKzSzpHegG0JpNO4OOVEynJeDS3Bd5y9LAN4
-KY2kpXeH9fErJq3MB2w6VFoo4AnzTQoEytRYaQuns/XdAaXn3PAfusFdkI2z
-6k/BEVmXarIrE7HarZehs7GgIFvKMquNzxPwHynD
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQL
-Ey5DbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UE
-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGf
-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZM
-JaLtVRKXxaeAufqDwSCg+i8VDXyhYGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvE
-erf4Zh+AVPy3wo5ZShRXRtGak75BkQO7FYCTXOvnzAhsPz6zSvz/S2wj1VCC
-JkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBAIob
-K/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxgJ8pFUs4W7z8GZOeUaHxg
-MxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Ncr6Pc5iaAIzy4RHT3
-Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHB
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNV
-BAsTM0NsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4g
-LSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24g
-VHJ1c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTla
-MIHBMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6
-BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIElu
-Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNp
-Z24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-p4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkf
-rbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjwDqL7MWzJ5m+Z
-Jwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEAATAN
-BgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/
-7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
-rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6x
-RnInjBJ7xUS0rg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcox
-CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UE
-CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkg
-VmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMG
-A1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcx
-NjIzNTk1OVowgcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwg
-SW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UE
-CxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1
-c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJp
-bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY8
-1nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDOJxOeBUebMXoT
-2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7C9UT
-AJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQ
-HgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
-qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVC
-YQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekh
-ktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf
-0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydE
-p85EXdQbkJgNHkKUsQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377B
-MnMiIYtYgXsVkXq642RIsH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab
-5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//jGHyJizNdrDPX
-p/naOlXJWBD5qu9ats9LS98q
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDnjCCAwegAwIBAgIQCUYX5h3Y1BygDKBi6HmKpzANBgkqhkiG9w0BAQUF
-ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1
-BgNVBAsTLkNsYXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwHhcNMDAwODAxMDAwMDAwWhcNMDQwNzMxMjM1OTU5WjCBpzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov
-L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAy
-IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQDQymMxYX9ENHwFfQs9apDLeUt3Cj9LxyPlwGItfpx+
-PoiHkdCs6E1Jh6KWkIrdBKUCP4yb6Yn+YqDiWr3I3bR45qVCkwhnAcAgTddc
-9F3as+M3plIaLExlTYqH2aij8UlUuzxcgFFoxvtJ/wtVqxXd+5rBuR10DbKM
-RF2J/J/5gwIDAQABo4IBEDCCAQwwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT
-CE9DU1AgMS0yMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwudmVyaXNp
-Z24uY29tL3BjYTIuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEIGCCsGAQUF
-BwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j
-b20vb2NzcC9zdGF0dXMwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcBATAqMCgG
-CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vUlBBMAkGA1Ud
-EwQCMAAwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBBQUAA4GBAB99CW4kRnUE
-nPMmm+M5bhfvvL2iG9IChIar0ECXLMRDiDcZayKoA3FQnSDcNmAgmnMtc1Vs
-WJsswrQ0LHozQsqR2elDr88e4PXEeqs/cmMeqTfhWzuIsxOGgpBXy1f/9Fa+
-It3jl6jhvCJDwt1N2/aBnpIUnjkPE1TegtjAXjSN
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQL
-Ey5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UE
-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGf
-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69q
-RUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94f56TuZoAqiN91qyFomNFx3In
-zPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Olhec9vn2a
-/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtM
-EivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPw
-TtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzk
-uxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcEx
-CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE
-CxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt
-IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU
-cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
-gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG
-A1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j
-LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln
-biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM
-XtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXX
-wc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg013gfqLptQ5GV
-j0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01U
-bSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
-F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo
-1KpYoJ2daZH9
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHK
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV
-BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5
-IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD
-BgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3
-MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s
-IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV
-BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg
-dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFBy
-aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2
-R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2tKmFZpGcmTNDo
-vFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUccLwg
-TS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+V
-k7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
-Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJ
-OxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my
-/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
-j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoA
-Wii/gt/4uhMdUIaC/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8S
-GhJouPtmmRQURVyu565pF4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbb
-o27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh
-/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDojCCAwugAwIBAgIQLpaev7ZibOx76XPM42zBhDANBgkqhkiG9w0BAQUF
-ADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1
-BgNVBAsTLkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwHhcNMDAwODA0MDAwMDAwWhcNMDQwODAzMjM1OTU5WjCBpzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov
-L3d3dy52ZXJpc2lnbi5jb20vUlBBIChjKTAwMS4wLAYDVQQDEyVDbGFzcyAz
-IFB1YmxpYyBQcmltYXJ5IE9DU1AgUmVzcG9uZGVyMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQDx5AgOg7t140jluNum8Lmr6Txix141W9ACVBHYydFW
-uXZLuat65s269gwE1n7WsAplrE454/H3LaMlOe+wi8++2wxdbnD0B81w9zrA
-PjUW7XiMQ8/CJi5H1oZ9nPG+1mcMIiWkymXmH3p4KC8/BdsEIb/hRWb+PLeC
-7Vq4FhW5VQIDAQABo4IBFDCCARAwIAYDVR0RBBkwF6QVMBMxETAPBgNVBAMT
-CE9DU1AgMS0zMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwudmVyaXNp
-Z24uY29tL3BjYTMuMS4xLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCTBCBggr
-BgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGmJhYkaHR0cDovL29jc3AudmVyaXNp
-Z24uY29tL29jc3Avc3RhdHVzMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQEw
-KjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL1JQQTAJ
-BgNVHRMEAjAAMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQUFAAOBgQAC9lNj
-wKke8tCLMzCPSJtMsFa0g3FKvtxQ2PW24AvbvXhP6c8JNNopSZ0Bc1qRkYJU
-LBMK03cjzzf8Y96n4/a3tWlFKEnDkdyqRxypiJksBSqNjYr6YuJatwAgXTnE
-KMLL/J6oia5bPY4S6jKy/OsU1wkVGsDNG9W1FU5B1ZbjTg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcEx
-CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE
-CxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt
-IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU
-cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
-gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG
-A1UECxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j
-LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln
-biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6
-8OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDMHO0oW369atyzkSTK
-QWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtKqsGgtG7rL+VX
-xbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwjcSGI
-L4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
-cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckzt
-ImRPT8qAkbYp
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHK
-MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV
-BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5
-IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBD
-BgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3
-MTYyMzU5NTlaMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24s
-IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNV
-BAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQg
-dXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFBy
-aW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYl
-S+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ+mGuqPKljYXC
-KtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM8BDc
-VHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdL
-MEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
-ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDD
-Zq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1Wr
-IhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
-mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csK
-vE+MW8VLADsfKoKmfjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluP
-QSjA1egtTaRezarZ7c7c2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kP
-mF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr
-9Xgn2uf3ZkPznoM+IKrDNWCRzg==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzEL
-MAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMu
-MS4wLAYDVQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5MB4XDTk0MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UE
-BhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
-VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGb
-MA0GCSqGSIb3DQEBAQUAA4GJADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6O
-LDfO6zV4ZFQD5YRAUcm/jwjiioII0haGN1XpsSECrXZogZoFokvJSyVmIlZs
-iAeP94FZbYQHZXATcXY+m3dM41CJVphIuR2nKRoTLkoRWZweFdVJVCxzOmmC
-sZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZIhvcNAQECBQADfgBl3X7hsuyw
-4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3YQO2WxZpO8ZECAyIUwxr
-l0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc1/p3yjkWWW8O6tO1
-g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDnzCCAwygAwIBAgIRAP9F1SddJPuzwjkkU1fhT94wDQYJKoZIhvcNAQEF
-BQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5
-LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5MB4XDTAwMDgwNDAwMDAwMFoXDTA0MDgwMzIzNTk1OVowgZ4x
-FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
-cnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6
-Ly93d3cudmVyaXNpZ24uY29tL1JQQSAoYykwMDElMCMGA1UEAxMcU2VjdXJl
-IFNlcnZlciBPQ1NQIFJlc3BvbmRlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAuFGZZIUO7rMKaPC/Y3YdU/X8oXiMM+6f9L452psPTUepjyDoS0S9
-zs17kNEw6JDEJXuJKN699pMd/7n/krWpjeSuzOLDB4Nqo3IQASdiIqY1Jjkt
-ns9gDPxHpNfQQninHWzQy08VpykKtJVFxLHnWgnXOZXYHTWewr2zXcEMSx8C
-AwEAAaOCAR0wggEZMCAGA1UdEQQZMBekFTATMREwDwYDVQQDEwhPQ1NQIDEt
-NDA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLnZlcmlzaWduLmNvbS9S
-U0FTZWN1cmVTZXJ2ZXItcC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwkwQgYI
-KwYBBQUHAQEENjA0MDIGCCsGAQUFBzABpiYWJGh0dHA6Ly9vY3NwLnZlcmlz
-aWduLmNvbS9vY3NwL3N0YXR1czBEBgNVHSAEPTA7MDkGC2CGSAGG+EUBBwEB
-MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9SUEEw
-CQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQEFBQADfgAAsxBT
-ZpxJky4xoAJC0lhXfmah/huKYRhQQCweK0Gl1tv/rAgcWgVtAlwqtpZPR9u+
-TtvOzLqGuBjOsRKRX2P380g+zPFNE+RtCZR4AJLLoyCdBgtqoEMHztEZbI8Y
-dZqfFzP9qSa44+LewqjEWop/mNYHBmvMVp6GcM7U7w==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUF
-ADCBwTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTww
-OgYDVQQLEzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24g
-QXV0aG9yaXR5IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJ
-bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlT
-aWduIFRydXN0IE5ldHdvcmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1
-OTU5WjCBpTEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBh
-dCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTAwMSwwKgYDVQQD
-EyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1dGhvcml0eSBDQTCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVlizrQJIkRpivglWtvtDbc2
-fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU/OB4naCTuQk9I1F/
-RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11S7zi6ESHzeZB
-CiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/AgEAMEUG
-A1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0dHBz
-Oi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0
-cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIG
-CCsGAQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJp
-c2lnbi5jb20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2
-DcIBcBlK0lRWHqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQn
-Keg3S/LvRJdrF1Eaw1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937n
-tag+RaypJXUie28/sJyU58dzq6wf7iWbwBbtt8pb8BQ=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMC
-VVMxDTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25h
-bCBTZXJ2aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcN
-MDAwODE2MjI1MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzEN
-MAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNl
-cnZpY2UgQXNzb2NpYXRpb24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZ
-DK9vZBv42pWUJGkzEXDK41Z0ohdXZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJ
-XLB1LRckaeNCYOTudNargFbYiCjh+20i/SN8RnNPflRzHqgsVVh1t0zzWkWl
-Ahr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU58fy+pmjIlC++QU3o63tmsPm
-7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/ghalMCXI5Etuz9c9OYmTa
-xhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E1w0cslSsMoW0ZA3e
-QbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/ca3CBfYDdYDO
-qU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
-SIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHbmQdp
-NSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ
-kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoL
-axhNdBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/Rt
-Ldh6yumJivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8
-ofyrEK9ca3CnB+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUF
-ADBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlz
-YSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMT
-E1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0
-MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UE
-CxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAa
-BgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh
-28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8bRaVK7362
-rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81
-q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtF
-Wsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0
-lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaLdXe6YJ2E5/4t
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOC
-AQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
-zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKht
-cbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGI
-xHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
-YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/
-hC3euiInlhBx6yLt398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQK
-EwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEG
-A1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0
-aW9uMB4XDTAyMDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UE
-ChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAx
-BgNVBAMTKmJlVFJVU1RlZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRh
-dGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALx+xDmcjOPW
-HIb/ymKt4H8wRXqOGrO4x/nRNv8i805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R
-9U+jK7wYFuK13XneIviCfsuBH/0nLI/6l2Qijvj/YaOcGx6Sj8CoCd8JEey3
-fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92BFODEPM2dMPgwqZfT7syj0B9f
-HBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+YmpkbIq2eszh+6l/ePazIjm
-iSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7eHgZFLL8kFKJOGJg
-B7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIaMA8GA1UdEwEB
-/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4AAAEJKIOR
-MTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3IgdXNl
-IG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu
-dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5k
-YXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmlj
-YXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0
-eSBBZ3JlZW1lbnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVT
-VGVkIHdlYiBzaXRlLCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVj
-dHNfc2VydmljZXMvaW5kZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3
-dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWww
-HQYDVR0OBBYEFEU9w6nR3D8kVpgccxiIav+DR+22MB8GA1UdIwQYMBaAFEU9
-w6nR3D8kVpgccxiIav+DR+22MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
-AQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCAWXf82n+0S9/DZEtqTg6t8n1Z
-dwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu67RMdmgduyzFiEuhjA6p9
-beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AYgkHNZTfqjjJ+vWuZ
-XTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb4cV97yHgjQ5d
-UX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9CReJf8Py
-05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQG
-EwJXVzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQg
-Um9vdCBDQXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYy
-MDE0MjEwNFoXDTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNV
-BAoTCWJlVFJVU1RlZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRow
-GAYDVQQDExFiZVRSVVNUZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBANS0c3oTCjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4
-SP+00PpeQY1hRIfo7clY+vyTmt9P6j41ffgzeubx181vSUs9Ty1uDoM6GHh3
-o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwMjmVZxXH/YgmPqsWPzGCgc0rXOD8V
-cr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX2P8ZDoMbjNx4RWc0PfSvHI3k
-bWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2NR47rtMNE5qdMf1ZD6Li8
-tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5jrEq2I8QBoa2k5MUC
-AwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNVHSAEggFQMIIB
-TDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQagfFSZWxp
-YW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVz
-IGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0
-ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9u
-IHByYWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJl
-VFJVU1RlZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29t
-L3ZhdWx0L3Rlcm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNU
-ZWQuY29tL3ZhdWx0L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYD
-VQQKEwliZVRSVVNUZWQxCzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub
-2M3eKjEENGvKBxirZzAfBgNVHSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxir
-ZzAOBgNVHQ8BAf8EBAMCAf4wDQYJKoZIhvcNAQEFBQADggEBAHlh26Nebhax
-6nZR+csVm8tpvuaBa58oH2U+3RGFktToQb9+M70j5/Egv6S0phkBxoyNNXxl
-pE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2jCBHOElQBp1yZzrwmAOtlmdE
-/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe1lMBzW1MaFVA4e5rxyoA
-AEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5mlWXKWWuGVUlBXJH
-0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYctmBjRYoQtLpG
-EK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQK
-EwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEG
-A1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0
-aW9uMB4XDTAyMDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UE
-ChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAx
-BgNVBAMTKmJlVFJVU1RlZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRh
-dGlvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1
-Q+xVkrYwfTVXDNvzDSduTPdQqJtOK2/b9a0cS12zqcH+e0TrW6MFDR/FNCsw
-ACnxeECypP869AGIF37m1CbTukzqMvtDd5eHI8XbQ6P1KqNRXuE70mVpflUV
-m3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdjDheT389Lrm5zdeDzqrmkwAkb
-hepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCeyv78IZTuEyhL11xeDGbu
-6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCktVjMFu5dZfsZJT4nX
-LySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMBMIIBtwYDVR0g
-BIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYIKwYBBQUH
-AgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRpZmlj
-YXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug
-b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29u
-ZGl0aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0
-YXRlbWVudCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGlj
-aCBjYW4gYmUgZm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0
-cHM6Ly93d3cuYmV0cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRl
-eC5odG1sMEIGCCsGAQUFBwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29t
-L3Byb2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQD
-AgAHMIGJBgNVHR8EgYEwfzB9oHugeaR3MHUxEjAQBgNVBAoTCWJlVFJVU1Rl
-ZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMTMwMQYDVQQDEypiZVRS
-VVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1wbGVtZW50YXRpb24xDTALBgNV
-BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEwODI0MjdagQ8yMDIyMDQx
-MTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFH1w5a44iwY/qhwa
-j/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQwqoSEFjAMBgNV
-HRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkq
-hkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ5V04
-ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB
-evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220
-Y/ozADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2
-KjiS2d2kXgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFi
-aDrmLzfzgYYhxKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep
-9w==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUF
-ADBiMRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBS
-b290IENBczEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1w
-bGVtZW50YXRpb24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBi
-MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290
-IENBczEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVt
-ZW50YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQw
-CY5X0LkGLG9uJIAiv11DpvpPrILnHGhwhRujbrWqeNluB0s/6d/16uhUoWGK
-Di9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I1DpAa5LxmZZk3tv/ePTulh1HiXzU
-vrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPktPDgaTuID0GQ+NRxQyTBjyZL
-O1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnUGxlkVgoZ98zh/4avflhe
-rHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8ercmsl9fNTGwxMLvF1
-S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIYMIICFDAMBgNV
-HRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+AAADCSiD
-kTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20v
-cHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB
-OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBj
-cmVhdGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRo
-ZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlv
-bnMgb2YgdXNlLCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1l
-bnQgYW5kIHRoZSBSZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2Fu
-IGJlIGZvdW5kIGF0IHRoZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93
-d3cuYmV0cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1s
-MAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSp7BR++dlDzFMrFK3P9/BZiUHN
-GTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxStz/fwWYlBzRkwDQYJKoZIhvcNAQEF
-BQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g6IHHtt9DwSwddUvUQo3neqh0
-3GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuKmET7m9cqg5c0Lcd9NUwt
-NLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbdLrML3kqNWz2rDcI1
-UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28BbJ1zTcwfBwvNM
-m2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3SK41ty8y
-mmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
-MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
-IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
-dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
-li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
-rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
-WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
-F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
-xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
-Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
-dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
-IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
-c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
-ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
-KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
-KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
-y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
-dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
-VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
-fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
-7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
-cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
-mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
-SnQ2+Q==
------END CERTIFICATE-----
-
------BEGIN CERTIFICATE-----
-MIIETzCCAzegAwIBAgIEO63vKTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIzMTQxODE3WhcNMTEw
-OTIzMTMxODE3WjB1MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
-LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWdu
-ZXQgLSBDQSBLbGFzYSAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4SRW9Q58g5DY1Hw7h
-gCRKBEdPdGn0MFHsfw7rlu/oQm7IChI/uWd9q5wwo77YojtTDjRnpgZsjqBeynX8T90vFILqsY2K
-5CF1OESalwvVr3sZiQX79lisuFKat92u6hBFikFIVxfHHB67Af+g7u0dEHdDW7lwy81MwFYxBTRy
-9wIDAQABo4IBbTCCAWkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwggEEBgNVHSAE
-gfwwgfkwgfYGDSsGAQQBvj8CAQoBAQAwgeQwgZoGCCsGAQUFBwICMIGNGoGKQ2VydHlmaWthdCB3
-eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtOiAiUG9saXR5a2EgQ2VydHlmaWthY2ppIGRs
-YSBSb290Q0EiLiBDZXJ0eWZpa2F0IHd5c3Rhd2lvbnkgcHJ6ZXogUm9vdENBIHcgaGllcmFyY2hp
-aSBDQyBTaWduZXQuMEUGCCsGAQUFBwIBFjlodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0b3Jp
-dW0vZG9rdW1lbnR5L3BjX3Jvb3RjYS50eHQwHwYDVR0jBBgwFoAUwJvFIw0C4aZOSGsfAOnjmhQb
-sa8wHQYDVR0OBBYEFMODHtVZd1T7TftXR/nEI1zR54njMA0GCSqGSIb3DQEBBQUAA4IBAQBRIHQB
-FIGh8Jpxt87AgSLwIEEk4+oGy769u3NtoaR0R3WNMdmt7fXTi0tyTQ9V4AIszxVjhnUPaKnF1KYy
-f8Tl+YTzk9ZfFkZ3kCdSaILZAOIrmqWNLPmjUQ5/JiMGho0e1YmWUcMci84+pIisTsytFzVP32/W
-+sz2H4FQAvOIMmxB7EJX9AdbnXn9EXZ+4nCqi0ft5z96ZqOJJiCB3vSaoYg+wdkcvb6souMJzuc2
-uptXtR1Xf3ihlHaGW+hmnpcwFA6AoNrom6Vgzk6U1ienx0Cw28BhRSKqzKkyXkuK8gRflZUx84uf
-tXncwKJrMiE3lvgOOBITRzcahirLer4c
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIE9zCCA9+gAwIBAgIEPL/xoTANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MSAwHgYDVQQDExdDQyBTaWduZXQgLSBQQ0EgS2xhc2EgMjAeFw0wMjA0MTkxMDI5NTNa
-Fw0xNzA0MTgxMjUzMDdaMHUxCzAJBgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4g
-eiBvLm8uMSQwIgYDVQQLExtDZW50cnVtIENlcnR5ZmlrYWNqaSBTaWduZXQxHzAdBgNVBAMTFkND
-IFNpZ25ldCAtIENBIEtsYXNhIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqgLJu
-QqY4yavbSgHg8CyfKTx4BokNSDOVz4eD9vptUr11Kqd06ED1hlH7Sg0goBFAfntNU/QTKwSBaNui
-me7C4sSEdgsKrPoAhGb4Mq8y7Ty7RqZz7mkzNMqzL2L2U4yQ2QjvpH8MH0IBqOWEcpSkpwnrCDIm
-RoTfd+YlZWKi2JceQixUUYIQ45Ox8+x8hHbvvZdgqtcvo8PW27qoHkp/7hMuJ44kDAGrmxffBXl/
-OBRZp0uO1CSLcMcVJzyr2phKhy406MYdWrtNPEluGs0GFDzd0nrIctiWAO4cmct4S72S9Q6e//0G
-O9f3/Ca5Kb2I1xYLj/xE+HgjHX9aD2MhAgMBAAGjggGMMIIBiDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjCB4wYDVR0gBIHbMIHYMIHVBg0rBgEEAb4/AhQKAQEAMIHDMHUGCCsGAQUF
-BwICMGkaZ0NlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
-eWthIENlcnR5ZmlrYWNqaSBQQ0EyIC0gQ2VydHlmaWthdHkgVXJ6ZWRvdyBLbGFzeSAyIi4wSgYI
-KwYBBQUHAgEWPmh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9kb2t1bWVudHkva2xh
-c2EyL3BjX3BjYTIudHh0MD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly93d3cuc2lnbmV0LnBsL3Jl
-cG96eXRvcml1bS9jcmwvcGNhMi5jcmwwHwYDVR0jBBgwFoAUwGxGyl2CfpYHRonE82AVXO08kMIw
-HQYDVR0OBBYEFLtFBlILy4HNKVSzvHxBTM0HDowlMA0GCSqGSIb3DQEBBQUAA4IBAQBWTsCbqXrX
-hBBev5v5cIuc6gJM8ww7oR0uMQRZoFSqvQUPWBYM2/TLI/f8UM9hSShUVj3zEsSj/vFHagUVmzuV
-Xo5u0WK8iaqATSyEVBhADHrPG6wYcLKJlagge/ILA0m+SieyP2sjYD9MUB9KZIEyBKv0429UuDTw
-6P7pslxMWJBSNyQxaLIs0SRKsqZZWkc7ZYAj2apSkBMX2Is1oHA+PwkF6jQMwCao/+CndXPUzfCF
-6caa9WwW31W26MlXCvSmJgfiTPwGvm4PkPmOnmWZ3CczzhHl4q7ztHFzshJH3sZWDnrWwBFjzz5e
-Pr3WHV1wA7EY6oT4zBx+2gT9XBTB
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEUzCCAzugAwIBAgIEPq+qjzANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQGEwJQTDE3MDUGA1UE
-ChMuQ1ppQyBDZW50cmFzdCBTQSB3IGltaWVuaXUgTWluaXN0cmEgR29zcG9kYXJraTEZMBcGA1UE
-AxMQQ1ppQyBDZW50cmFzdCBTQTAeFw0wMzA0MzAxMDUwNTVaFw0wODA0MjgxMDUwNTVaMGgxCzAJ
-BgNVBAYTAlBMMR8wHQYDVQQKExZUUCBJbnRlcm5ldCBTcC4geiBvLm8uMR8wHQYDVQQDExZDQyBT
-aWduZXQgLSBDQSBLbGFzYSAzMRcwFQYDVQQFEw5OdW1lciB3cGlzdTogNDCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBALVdeOM62cPH2NERFxbS5FIp/HSv3fgesdVsTUFxZbGtE+/E0RMl
-KZQJHH9emx7vRYubsi4EOLCjYsCOTFvgGRIpZzx7R7T5c0Di5XFkRU4gjBl7aHJoKb5SLzGlWdoX
-GsekVtl6keEACrizV2EafqjI8cnBWY7OxQ1ooLQp5AeFjXg+5PT0lO6TUZAubqjFbhVbxSWjqvdj
-93RGfyYE76MnNn4c2xWySD07n7uno06TC0IJe6+3WSX1h+76VsIFouWBXOoM7cxxiLjoqdBVu24+
-P8e81SukE7qEvOwDPmk9ZJFtt1nBNg8a1kaixcljrA/43XwOPz6qnJ+cIj/xywECAwEAAaOCAQow
-ggEGMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMDMGA1UdIAEB/wQpMCcwJQYEVR0g
-ADAdMBsGCCsGAQUFBwIBFg93d3cuY2VudHJhc3QucGwwgY4GA1UdIwSBhjCBg4AU2a7r85Cp1iJN
-W0Ca1LR6VG3996ShZaRjMGExCzAJBgNVBAYTAlBMMTcwNQYDVQQKEy5DWmlDIENlbnRyYXN0IFNB
-IHcgaW1pZW5pdSBNaW5pc3RyYSBHb3Nwb2RhcmtpMRkwFwYDVQQDExBDWmlDIENlbnRyYXN0IFNB
-ggQ9/0sQMB0GA1UdDgQWBBR7Y8wZkHq0zrY7nn1tFSdQ0PlJuTANBgkqhkiG9w0BAQUFAAOCAQEA
-ldt/svO5c1MU08FKgrOXCGEbEPbQxhpM0xcd6Iv3dCo6qugEgjEs9Qm5CwUNKMnFsvR27cJWUvZb
-MVcvwlwCwclOdwF6u/QRS8bC2HYErhYo9bp9yuxxzuow2A94c5fPqfVrjXy+vDouchAm6+A5Wjzv
-J8wxVFDCs+9iGACmyUWr/JGXCYiQIbQkwlkRKHHlan9ymKf1NvIej/3EpeT8fKr6ywxGuhAfqofW
-pg3WJY/RCB4lTzD8vZGNwfMFGkWhJkypad3i9w3lGmDVpsHaWtCgGfd0H7tUtWPkP+t7EjIRCD9J
-HYnTR+wbbewc5vOI+UobR15ynGfFIaSIiMTVtQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEejCCA2KgAwIBAgIEP4vk6TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQ
-TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2Vu
-dHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBD
-QSBLbGFzYSAyMB4XDTAzMTAxNDExNTgyMloXDTE3MDQxODEyNTMwN1owdzELMAkG
-A1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6IG8uby4xJDAiBgNV
-BAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEhMB8GA1UEAxMYQ0MgU2ln
-bmV0IC0gT0NTUCBLbGFzYSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo
-VCsaBStblXQYVNthe3dvaCrfvKpPXngh4almm988iIlEv9CVTaAdCfaJNihvA+Vs
-Qw8++ix1VqteMQE474/MV/YaXigP0Zr0QB+g+/7PWVlv+5U9Gzp9+Xx4DJay8AoI
-iB7Iy5Qf9iZiHm5BiPRIuUXT4ZRbZRYPh0/76vgRsQIDAQABo4IBkjCCAY4wDgYD
-VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMJMEEGA1UdHwQ6MDgwNqA0
-oDKGMGh0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9jcmwva2xhc2Ey
-LmNybDCB2AYDVR0gBIHQMIHNMIHKBg4rBgEEAb4/AoFICgwBADCBtzBsBggrBgEF
-BQcCAjBgGl5DZXJ0eWZpa2F0IHd5ZGFueSB6Z29kbmllIHogZG9rdW1lbnRlbSAi
-UG9saXR5a2EgQ2VydHlmaWthY2ppIC0gQ2VydHlmaWthdHkgcmVzcG9uZGVyb3cg
-T0NTUCIuMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnNpZ25ldC5wbC9yZXBvenl0
-b3JpdW0vZG9rdW1lbnR5L3BjX29jc3BfMV8wLnBkZjAfBgNVHSMEGDAWgBS7RQZS
-C8uBzSlUs7x8QUzNBw6MJTAdBgNVHQ4EFgQUKEVrOY7cEHvsVgvoyZdytlbtgwEw
-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAQrRg5MV6dxr0HU2IsLInxhvt
-iUVmSFkIUsBCjzLoewOXA16d2oDyHhI/eE+VgAsp+2ANjZu4xRteHIHoYMsN218M
-eD2MLRsYS0U9xxAFK9gDj/KscPbrrdoqLvtPSMhUb4adJS9HLhvUe6BicvBf3A71
-iCNe431axGNDWKnpuj2KUpj4CFHYsWCXky847YtTXDjri9NIwJJauazsrSjK+oXp
-ngRS506mdQ7vWrtApkh8zhhWp7duCkjcCo1O8JxqYr2qEW1fXmgOISe010v2mmuv
-hHxPyVwoAU4KkOw0nbXZn53yak0is5+XmAjh0wWue44AssHrjC9nUh3mkLt6eQ==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEezCCA2OgAwIBAgIEP4vnLzANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJQ
-TDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEfMB0GA1UEAxMWQ0Mg
-U2lnbmV0IC0gQ0EgS2xhc2EgMzEXMBUGA1UEBRMOTnVtZXIgd3Bpc3U6IDQwHhcN
-MDMxMDE0MTIwODAwWhcNMDgwNDI4MTA1MDU1WjB3MQswCQYDVQQGEwJQTDEfMB0G
-A1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBD
-ZXJ0eWZpa2FjamkgU2lnbmV0MSEwHwYDVQQDExhDQyBTaWduZXQgLSBPQ1NQIEts
-YXNhIDMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM/9GwvARNuCVN+PqZmO
-4FqH8vTqhenUyqRkmAVT4YhLu0a9AXeLAYVDu+NTkYzsAUMAfu55rIKHNLlm6WbF
-KvLiKKz4p4pbUr+ToPcwl/TDotidloUdBAxDg0SL+PmQqACZDe3seJho2IYf2vDL
-/G4TLMbKmNB0mlWFuN0f4fJNAgMBAAGjggGgMIIBnDAOBgNVHQ8BAf8EBAMCB4Aw
-EwYDVR0lBAwwCgYIKwYBBQUHAwkwTwYDVR0fBEgwRjBEoEKgQIY+aHR0cDovL3d3
-dy5zaWduZXQucGwva3dhbGlmaWtvd2FuZS9yZXBvenl0b3JpdW0vY3JsL2tsYXNh
-My5jcmwwgdgGA1UdIASB0DCBzTCBygYOKwYBBAG+PwKCLAoCAQAwgbcwbAYIKwYB
-BQUHAgIwYBpeQ2VydHlmaWthdCB3eWRhbnkgemdvZG5pZSB6IGRva3VtZW50ZW0g
-IlBvbGl0eWthIENlcnR5ZmlrYWNqaSAtIENlcnR5ZmlrYXR5IHJlc3BvbmRlcm93
-IE9DU1AiLjBHBggrBgEFBQcCARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5
-dG9yaXVtL2Rva3VtZW50eS9wY19vY3NwXzFfMC5wZGYwHwYDVR0jBBgwFoAUe2PM
-GZB6tM62O559bRUnUND5SbkwHQYDVR0OBBYEFG4jnCMvBALRQXtmDn9TyXQ/EKP+
-MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEBACXrKG5Def5lpRwmZom3UEDq
-bl7y4U3qomG4B+ok2FVZGgPZti+ZgvrenPj7PtbYCUBPsCSTNrznKinoT3gD9lQQ
-xkEHwdc6VD1GlFp+qI64u0+wS9Epatrdf7aBnizrOIB4LJd4E2TWQ6trspetjMIU
-upyWls1BmYUxB91R7QkTiAUSNZ87s3auhZuG4f0V0JLVCcg2rn7AN1rfMkgxCbHk
-GxiQbYWFljl6aatxR3odnnzVUe1I8uoY2JXpmmUcOG4dNGuQYziyKG3mtXCQWvug
-5qi9Mf3KUh1oSTKx6HfLjjNl1+wMB5Mdb8LF0XyZLdJM9yIZh7SBRsYm9QiXevY=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFGjCCBAKgAwIBAgIEPL7eEDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwNDE4MTQ1NDA4WhcNMjYw
-OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
-LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu
-ZXQgLSBQQ0EgS2xhc2EgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7BrBlbN5ma
-M5eg0BOTqoZ+9NBDvU8Lm5rTdrMswFTCathzpVVLK/JD4K3+4oCZ9SRAspEXE4gvwb08ASY6w5s+
-HpRkeJw8YzMFR5kDZD5adgnCAy4vDfIXYZgppXPaTQ8wnfUZ7BZ7Zfa7QBemUIcJIzJBB0UqgtxW
-Ceol9IekpBRVmuuSA6QG0Jkm+pGDJ05yj2eQG8jTcBENM7sVA8rGRMyFA4skSZ+D0OG6FS2xC1i9
-JyN0ag1yII/LPx8HK5J4W9MaPRNjAEeaa2qI9EpchwrOxnyVbQfSedCG1VRJfAsE/9tT9CMUPZ3x
-W20QjQcSZJqVcmGW9gVsXKQOVLsCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
-AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQEBMIHkMIGaBggrBgEFBQcC
-AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
-eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6
-IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z
-aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw
-OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy
-bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUwGxGyl2CfpYHRonE
-82AVXO08kMIwDQYJKoZIhvcNAQEFBQADggEBABp1TAUsa+BeVWg4cjowc8yTJ5XN3GvN96GObMkx
-UGY7U9kVrLI71xBgoNVyzXTiMNDBvjh7vdPWjpl5SDiRpnnKiOFXA43HvNWzUaOkTu1mxjJsZsan
-ot1Xt6j0ZDC+03FjLHdYMyM9kSWp6afb4980EPYZCcSzgM5TOGfJmNii5Tq468VFKrX+52Aou1G2
-2Ohu+EEOlOrG7ylKv1hHUJJCjwN0ZVEIn1nDbrU9FeGCz8J9ihVUvnENEBbBkU37PWqWuHitKQDV
-tcwTwJJdR8cmKq3NmkwAm9fPacidQLpaw0WkuGrS+fEDhu1Nhy9xELP6NA9GRTCNxm/dXlcwnmY=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIFGjCCBAKgAwIBAgIEPV0tNDANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDIwODE2MTY0OTU2WhcNMjYw
-OTIxMTU0MjE5WjB2MQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
-LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MSAwHgYDVQQDExdDQyBTaWdu
-ZXQgLSBQQ0EgS2xhc2EgMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALN3LanJtdue
-Ne6geWUTFENa+lEuzqELcoqhYB+a/tJcPEkc6TX/bYPzalRRjqs+quMP6KZTU0DixOrV+K7iWaqA
-iQ913HX5IBLmKDCrTVW/ZvSDpiBKbxlHfSNuJxAuVT6HdbzK7yAW38ssX+yS2tZYHZ5FhZcfqzPE
-OpO94mAKcBUhk6T/ki0evXX/ZvvktwmF3hKattzwtM4JMLurAEl8SInyEYULw5JdlfcBez2Tg6Db
-w34hA1A+ckTwhxzecrB8TUe2BnQKOs9vr2cCACpFFcOmPkM0Drtjctr1QHm1tYSqRFRf9VcV5tfC
-3P8QqoK4ONjtLPHc9x5NE1uK/FMCAwEAAaOCAbMwggGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
-AQH/BAQDAgEGMIIBBAYDVR0gBIH8MIH5MIH2Bg0rBgEEAb4/AgEKAQECMIHkMIGaBggrBgEFBQcC
-AjCBjRqBikNlcnR5ZmlrYXQgd3lzdGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0
-eWthIENlcnR5ZmlrYWNqaSBkbGEgUm9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6
-IFJvb3RDQSB3IGhpZXJhcmNoaWkgQ0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5z
-aWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY19yb290Y2EudHh0MEQGA1UdHwQ9MDsw
-OaA3oDWGM2h0dHA6Ly93d3cuc2lnbmV0LnBsL3JlcG96eXRvcml1bS9yb290Y2Evcm9vdGNhLmNy
-bDAfBgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAdBgNVHQ4EFgQUXvthcPHlH5BgGhlM
-ErJNXWlhlgAwDQYJKoZIhvcNAQEFBQADggEBACIce95Mvn710KCAISA0CuHD4aznTU6pLoCDShW4
-7OR+GTpJUm1coTcUqlBHV9mra4VFrBcBuOkHZoBLq/jmE0QJWnpSEULDcH9J3mF0nqO9SM+mWyJG
-dsJF/XU/7smummgjMNQXwzQTtWORF+6v5KUbWX85anO2wR+M6YTBWC55zWpWi4RG3vkHFs5Ze2oF
-JTlpuxw9ZgxTnWlwI9QR2MvEhYIUMKMOWxw1nt0kKj+5TCNQQGh/VJJ1dsiroGh/io1DOcePEhKz
-1Ag52y6Wf0nJJB9yk0sFakqZH18F7eQecQImgZyyeRtsG95leNugB3BXWCW+KxwiBrtQTXv4dTE=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEzzCCA7egAwIBAgIEO6ocGTANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MRswGQYDVQQDExJDQyBTaWduZXQgLSBSb290Q0EwHhcNMDEwOTIwMTY0MjE5WhcNMjYw
-OTIxMTU0MjE5WjBxMQswCQYDVQQGEwJQTDEfMB0GA1UEChMWVFAgSW50ZXJuZXQgU3AuIHogby5v
-LjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2FjamkgU2lnbmV0MRswGQYDVQQDExJDQyBTaWdu
-ZXQgLSBSb290Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrr2vydnNpELfGW3Ks
-ARiDhJvwDtUe4AbWev+OfMc3+vA29nX8ZmIwno3gmItjo5DbUCCRiCMq5c9epcGu+kg4a3BJChVX
-REl8gVh0ST15rr3RKrSc4VgsvQzl0ZUraeQLl8JoRT5PLsUj3qwF78jUCQVckiiLVcnGfZtFCm+D
-CJXliQBDMB9XFAUEiO/DtEBs0B7wJGx7lgJeJpQUcGiaOPjcJDYOk7rNAYmmD2gWeSlepufO8luU
-YG/YDxTC4mqhRqfa4MnVO5dqy+ICj2UvUpHbZDB0KfGRibgBYeQP1kuqgIzJN4UqknVAJb0aMBSP
-l+9k2fAUdchx1njlbdcbAgMBAAGjggFtMIIBaTAPBgNVHRMBAf8EBTADAQH/MIIBBAYDVR0gBIH8
-MIH5MIH2Bg0rBgEEAb4/AgEKAQEAMIHkMIGaBggrBgEFBQcCAjCBjRqBikNlcnR5ZmlrYXQgd3lz
-dGF3aW9ueSB6Z29kbmllIHogZG9rdW1lbnRlbTogIlBvbGl0eWthIENlcnR5ZmlrYWNqaSBkbGEg
-Um9vdENBIi4gQ2VydHlmaWthdCB3eXN0YXdpb255IHByemV6IFJvb3RDQSB3IGhpZXJhcmNoaWkg
-Q0MgU2lnbmV0LjBFBggrBgEFBQcCARY5aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVt
-L2Rva3VtZW50eS9wY19yb290Y2EudHh0MB0GA1UdDgQWBBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAf
-BgNVHSMEGDAWgBTAm8UjDQLhpk5Iax8A6eOaFBuxrzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
-AQEFBQADggEBAGnY5QmYqnnO9OqFOWZxxb25UHRnaRF6IV9aaGit5BZufZj2Tq3v8L3SgE34GOoI
-cdRMMG5JEpEU4mN/Ef3oY6Eo+7HfqaPHI4KFmbDSPiK5s+wmf+bQSm0Yq5/h4ZOdcAESlLQeLSt1
-CQk2JoKQJ6pyAf6xJBgWEIlm4RXE4J3324PUiOp83kW6MDvaa1xY976WyInr4rwoLgxVl11LZeKW
-ha0RJJxJgw/NyWpKG7LWCm1fglF8JH51vZNndGYq1iKtfnrIOvLZq6bzaCiZm1EurD8HE6P7pmAB
-KK6o3C2OXlNfNIgwkDN/cDqk5TYsTkrpfriJPdxXBH8hQOkW89g=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIID/TCCA2agAwIBAgIEP4/gkTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJQTDEfMB0GA1UE
-ChMWVFAgSW50ZXJuZXQgU3AuIHogby5vLjEkMCIGA1UECxMbQ2VudHJ1bSBDZXJ0eWZpa2Fjamkg
-U2lnbmV0MR8wHQYDVQQDExZDQyBTaWduZXQgLSBDQSBLbGFzYSAxMB4XDTAzMTAxNzEyMjkwMloX
-DTExMDkyMzExMTgxN1owdjELMAkGA1UEBhMCUEwxHzAdBgNVBAoTFlRQIEludGVybmV0IFNwLiB6
-IG8uby4xJDAiBgNVBAsTG0NlbnRydW0gQ2VydHlmaWthY2ppIFNpZ25ldDEgMB4GA1UEAxMXQ0Mg
-U2lnbmV0IC0gVFNBIEtsYXNhIDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJYrISEtSsd
-uHajROh5/n7NGrkpYTT9NEaPe9+ucuQ37KxIbfJwXJjgUc1dw4wCkcQ12FJarD1X6mSQ4cfN/60v
-LfKI5ZD4nhJTMKlAj1pX9ScQ/MuyvKStCbn5WTkjPhjRAM0tdwXSnzuTEunfw0Oup559y3Iqxg1c
-ExflB6cfAgMBAAGjggGXMIIBkzBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8vd3d3LnNpZ25ldC5w
-bC9yZXBvenl0b3JpdW0vY3JsL2tsYXNhMS5jcmwwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQM
-MAoGCCsGAQUFBwMIMIHaBgNVHSAEgdIwgc8wgcwGDSsGAQQBvj8CZAoRAgEwgbowbwYIKwYBBQUH
-AgIwYxphQ2VydHlmaWthdCB3eXN0YXdpb255IHpnb2RuaWUgeiBkb2t1bWVudGVtICJQb2xpdHlr
-YSBDZXJ0eWZpa2FjamkgQ0MgU2lnbmV0IC0gWm5ha293YW5pZSBjemFzZW0iLjBHBggrBgEFBQcC
-ARY7aHR0cDovL3d3dy5zaWduZXQucGwvcmVwb3p5dG9yaXVtL2Rva3VtZW50eS9wY190c2ExXzJf
-MS5wZGYwHwYDVR0jBBgwFoAUw4Me1Vl3VPtN+1dH+cQjXNHnieMwHQYDVR0OBBYEFJdDwEqtcavO
-Yd9u9tej53vWXwNBMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADgYEAnpiQkqLCJQYXUrqMHUEz
-+z3rOqS0XzSFnVVLhkVssvXc8S3FkJIiQTUrkScjI4CToCzujj3EyfNxH6yiLlMbskF8I31JxIeB
-vueqV+s+o76CZm3ycu9hb0I4lswuxoT+q5ZzPR8Irrb51rZXlolR+7KtwMg4sFDJZ8RNgOf7tbA=
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIGFTCCBX6gAwIBAgIBEDANBgkqhkiG9w0BAQUFADCBvjELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UE
-ChMfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9z
-dG1hc3RlcjEgMB4GA1UEAxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkq
-hkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDYwODE2MjA0NjUy
-WhcNMTYwODEzMjA0NjUyWjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0luZGlh
-bmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdhcmUgaW4g
-dGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKSG9zdG1hc3RlcjEeMBwGA1UE
-AxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZob3N0bWFz
-dGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
-uTlCOrOYvCe0Qszlz90rVIQkS2UDa7R+qCTkRE5ipKC+3OZXGgv2EOYk/IOuCE3D
-8+tlTAl8MwvmwOHgL0GWnjoluR95narhNiV9Px8xyL2Z8kctwrWXbEii0Ot48VcN
-IQMDW5GK8Ww5puMKZr8+bXF2HFzkt8gwaCtrojcF4fLGcm3//bR13CKWbOzacANZ
-gAi00pD70ppjJU/uNVOe5HX6x/Id+50G6jwasanEzhteYJdbbHaMqrL4J6XbTwgJ
-ZciB0ifOZkwTBvQiRJpTkTWPyn/HptMbJGOwwiNbcgtWV7QVLW1GB3HYVum47Zwp
-XcXVM4Fs4XLwfx1Ti87LGdAJJYDS5K1F2prHKW5MsmFLJg61Nd6dZPRDLJLaOPEq
-0Jxa1NdfDjJ8rXOIcuLRAozjBui23vUhfOW9z4kpVIg+c+ylV2Oh/7f+fO731P7E
-AqsTFmiU7svcvkm2OKslolpnQ+pqGFLM4laQE/Q0kjogm7LiOpRssBW/ZfZ7pPLZ
-Ru0/AXrgKwQIM8mLazwlD3wHKPRElhIkxSv4qZ95zgJo6ky/7BpzZ/OAlz3BICbN
-WQhW/MBQVFiC6ivhjDq3AzgyykLShB0eIMRN0SBfTy3/aNfIJbqLmTNookXPoSP7
-+mg5OVzVBvDv5ZskWSl8kJB1DzJbN+DOr/i8V3Ugl90CAwEAAaOCAZ0wggGZMB0G
-A1UdDgQWBBTON+buqfoMXkWdtvObUS11tnY77DCB6wYDVR0jBIHjMIHggBQHrehB
-HX+91r8bgXo/jEuI3gTS+qGBxKSBwTCBvjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
-B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh
-cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEg
-MB4GA1UEAxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEW
-Fmhvc3RtYXN0ZXJAc3BpLWluYy5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zARBglg
-hkgBhvhCAQEEBAMCAQYwCQYDVR0SBAIwADArBglghkgBhvhCAQ0EHhYcVGlueUNB
-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAhBgNVHREEGjAYgRZob3N0bWFzdGVyQHNw
-aS1pbmMub3JnMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQA5HQcqwPE/
-RaN8cb8H1G34rkvSEsj4l8UIivMFEWIKnF3SQT8KVcD7j/eJuhMazwRlTs8Rnu6V
-/uTC10w7SS6gELwDqAzR4PiXTzfkW8OJemyQn6JWXKfq2pR1n4fvwEn7htjeNS69
-iFKlFXyE9j2jhGaps1CKHfe1YX0MuwO4Jw==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEFTCCA36gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBvjELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UE
-ChMfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9z
-dG1hc3RlcjEgMB4GA1UEAxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkq
-hkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDMwMTE1MTYyOTE3
-WhcNMDcwMTE0MTYyOTE3WjCBvjELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0luZGlh
-bmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdhcmUgaW4g
-dGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEgMB4GA1UE
-AxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEWFmhvc3Rt
-YXN0ZXJAc3BpLWluYy5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPB6
-rdoiLR3RodtM22LMcfwfqb5OrJNl7fwmvskgF7yP6sdD2bOfDIXhg9852jhY8/kL
-VOFe1ELAL2OyN4RAxk0rliZQVgeTgqvgkOVIBbNwgnjN6mqtuWzFiPL+NXQExq40
-I3whM+4lEiwSHaV+MYxWanMdhc+kImT50LKfkxcdAgMBAAGjggEfMIIBGzAdBgNV
-HQ4EFgQUB63oQR1/vda/G4F6P4xLiN4E0vowgesGA1UdIwSB4zCB4IAUB63oQR1/
-vda/G4F6P4xLiN4E0vqhgcSkgcEwgb4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdJ
-bmRpYW5hMRUwEwYDVQQHEwxJbmRpYW5hcG9saXMxKDAmBgNVBAoTH1NvZnR3YXJl
-IGluIHRoZSBQdWJsaWMgSW50ZXJlc3QxEzARBgNVBAsTCmhvc3RtYXN0ZXIxIDAe
-BgNVBAMTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo
-b3N0bWFzdGVyQHNwaS1pbmMub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
-AQEEBQADgYEAm/Abn8c2y1nO3fgpAIslxvi9iNBZDhQtJ0VQZY6wgSfANyDOR4DW
-iexO/AlorB49KnkFS7TjCAoLOZhcg5FaNiKnlstMI5krQmau1Qnb/vGSNsE/UGms
-1ts+QYPUs0KmGEAFUri2XzLy+aQo9Kw74VBvqnxvaaMeY5yMcKNOieY=
------END CERTIFICATE-----
diff --git a/gcr/tests/files/cacert.org.cer b/gcr/tests/files/cacert.org.cer
deleted file mode 100644
index 719b0ff2..00000000
--- a/gcr/tests/files/cacert.org.cer
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/cacert.org.pem b/gcr/tests/files/cacert.org.pem
deleted file mode 100644
index e7dfc829..00000000
--- a/gcr/tests/files/cacert.org.pem
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
-IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
-IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
-Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
-BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
-MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
-ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
-8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
-zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
-fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
-w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
-G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
-epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
-laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
-QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
-fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
-YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
-ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
-gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
-MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
-IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
-dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
-czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
-dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
-aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
-AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
-b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
-ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
-nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
-18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
-gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
-Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
-sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
-SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
-CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
-GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
-zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
-omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
------END CERTIFICATE-----
diff --git a/gcr/tests/files/client.crt b/gcr/tests/files/client.crt
deleted file mode 100644
index a4bc2fcc..00000000
--- a/gcr/tests/files/client.crt
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/client.key b/gcr/tests/files/client.key
deleted file mode 100644
index 206f5272..00000000
--- a/gcr/tests/files/client.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAwSA0Mz92De30Mc0A/P9vzstLERoqGhnwBw0HKbcsQ50KdcYS
-cp/Rv2WRPlxpe7kYAzzhqFMInufv1FU2uoYozuNsF1Jf5lR+SolA+E5cPb7SeJhC
-Jwf3afPvyTGaOVuLO93d8zUGU74L/741Z/YQCE5FUCO8msc2iQmnc9M1EnVZa14d
-5T0/B8aZYcpVzUiC9EUwfTzrTghnNfkJzEiD9vnqDbsDsIE+H8o7+opMMsUU0ZzV
-PZqy9j8/f4943rL6V4UdK0JO7tEGL+XiFzNl2fCrcEZPqaeMQ3vBq7azukDTrtJe
-KY06RiLl+DCykweLx8laZjIHKlSZAFHPB+bvsQIDAQABAoIBAQCQUI1RYnHIdPFO
-qZ+8bvDQ+g8tR30ApjM8QZsBrDRyjg579bhhWVY2jSJdFFdqseTkvoDt9KZzgGQy
-Kj9MYOZru3xRbSfmiWsaLbiUFJJPPaIvpa+BVS2oSjX8BYn2pJbF9MRfclc5CsIS
-qMNl3XUbj8mx2hKdIpJ5EvLD1adKE4Se6peqSZAmEHONNCsrMrQ0GSQqV3viInJr
-tc3kp3HcPffSROWqmc6jAJ77Cs3ApgJavL5RGjx30Kd+dKVq4PXZ+IhWM8dOSput
-wcyxEosiP/W2g0rDgNW2mGOVOwa/D5SnOolicHifdV7idjwLAjkyYgvmBMNSsECj
-yKBkE0gxAoGBAN8iHMumyvriHuj9bSLZ1bcyYFz7jIwUxpHTT7VqN/j/Y1BoBIBy
-ZZLDGMa+ID/brpRHzJQAKSNtbFQ0S1HTSKcFud5OWE8Rp3pQJU+sdeO3pCMWAD1z
-Q4ggF07JjTSSnK+4fcXgEN9P2OdfXy7Rj3HFpSahql55Kp5udoUdzUVFAoGBAN2S
-krlcEuqsEYjqsCJw5pctIwPMvCM51JgirrdETwSGquMklSrobH0PHMlR67gsA/9I
-UGShT0LL4UWYpBn/4xLrLbua5aHIBfQQZp9K6jDZddWS+EFL5JkO/Up4/qM6fUbH
-CuweVv1gd6i2Ti35K60mgx6MqVunaB1k8Q9P3Pl9AoGALSVtxha9Qv21W1bLWh3R
-C/v5W1baHQ2nD6I9omsXYB3sLjydjI+Y1ZT70lptk/4S2JWeYuOVb0GYhYD/LFMf
-hAu4i642V+kuhaTpp7ExOR3S6/ZrngNQSp6TmLFXDKgNY9BkQkEPqN8y971oOMTV
-zSM8QxC6s9q4MM4Q1OYuvjECgYEAsO2V1AW95T45Ukd1FktpFlaomyQlJ0vKgyFO
-unEFV+vhETfpFTY7SzGCHxAXVh1vo62u5Gwayo/a9qQIhepa/IRnJGNv8luyxU1D
-ZPeBQjija0PMkPd1NvNNNuafDuBpoNbX1ev0MqeRZVsN2pAZXE5gbUiNA+8NqEsu
-Yre3EFECgYEA13rXE76zZgsefx+2spjqJDUWEmTDd1460xTtxCCgL9dy4rW5bgwo
-MvINphSUXOwSkn8Oja/IvpN28zSj9W/ci5wU52P5w4blkBmuj8UoCjP2FN1b1OBa
-86mkwVsCYUyyI2apuwrHP77yeb8jXZb+reqSns3hU+HyO/nUTVmnews=
------END RSA PRIVATE KEY-----
diff --git a/gcr/tests/files/client.pem b/gcr/tests/files/client.pem
deleted file mode 100644
index 04bc8ac7..00000000
--- a/gcr/tests/files/client.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC3DCCAkUCAQkwDQYJKoZIhvcNAQEFBQAwgYYxEzARBgoJkiaJk/IsZAEZFgND
-T00xFzAVBgoJkiaJk/IsZAEZFgdFWEFNUExFMR4wHAYDVQQLExVDZXJ0aWZpY2F0
-ZSBBdXRob3JpdHkxFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMR0wGwYJKoZIhvcN
-AQkBFg5jYUBleGFtcGxlLmNvbTAeFw0xMTAxMTgwNjA0MTFaFw0yMTAxMTUwNjA0
-MTFaMGIxEzARBgoJkiaJk/IsZAEZFgNDT00xFzAVBgoJkiaJk/IsZAEZFgdFWEFN
-UExFMQ8wDQYDVQQDEwZDbGllbnQxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFt
-cGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEgNDM/dg3t
-9DHNAPz/b87LSxEaKhoZ8AcNBym3LEOdCnXGEnKf0b9lkT5caXu5GAM84ahTCJ7n
-79RVNrqGKM7jbBdSX+ZUfkqJQPhOXD2+0niYQicH92nz78kxmjlbizvd3fM1BlO+
-C/++NWf2EAhORVAjvJrHNokJp3PTNRJ1WWteHeU9PwfGmWHKVc1IgvRFMH08604I
-ZzX5CcxIg/b56g27A7CBPh/KO/qKTDLFFNGc1T2asvY/P3+PeN6y+leFHStCTu7R
-Bi/l4hczZdnwq3BGT6mnjEN7wau2s7pA067SXimNOkYi5fgwspMHi8fJWmYyBypU
-mQBRzwfm77ECAwEAATANBgkqhkiG9w0BAQUFAAOBgQA3LuElj2QB9wQvmIxk2Jmb
-IPP2/WS8dwPoCv/N3+6nTx8yRsrILf4QsnEbbsxoYO5jW4r9Kt8m8B/M7YgnBDE9
-zlm7JbXKZf2isSm5TyT627Ymzxrzs5d+7o2eS7SN1DB6PyvRh2ye7EMbyEYD8ULi
-itDUkYkssNCVivYwVvJoMg==
------END CERTIFICATE-----
diff --git a/gcr/tests/files/collabora-ca.cer b/gcr/tests/files/collabora-ca.cer
deleted file mode 100644
index 2842c696..00000000
--- a/gcr/tests/files/collabora-ca.cer
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-certificate-dsa.cer b/gcr/tests/files/der-certificate-dsa.cer
deleted file mode 100755
index 024f3c1b..00000000
--- a/gcr/tests/files/der-certificate-dsa.cer
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-certificate.crt b/gcr/tests/files/der-certificate.crt
deleted file mode 100644
index 56fa8491..00000000
--- a/gcr/tests/files/der-certificate.crt
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-dsa-1024.key b/gcr/tests/files/der-dsa-1024.key
deleted file mode 100644
index 61af5251..00000000
--- a/gcr/tests/files/der-dsa-1024.key
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-PBE-MD5-DES.p8 b/gcr/tests/files/der-key-PBE-MD5-DES.p8
deleted file mode 100644
index 71b7d61b..00000000
--- a/gcr/tests/files/der-key-PBE-MD5-DES.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-PBE-SHA1-3DES.p8 b/gcr/tests/files/der-key-PBE-SHA1-3DES.p8
deleted file mode 100644
index 1c37fe10..00000000
--- a/gcr/tests/files/der-key-PBE-SHA1-3DES.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-PBE-SHA1-DES.p8 b/gcr/tests/files/der-key-PBE-SHA1-DES.p8
deleted file mode 100644
index 99896139..00000000
--- a/gcr/tests/files/der-key-PBE-SHA1-DES.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-PBE-SHA1-RC2-40.p8 b/gcr/tests/files/der-key-PBE-SHA1-RC2-40.p8
deleted file mode 100644
index 820926cc..00000000
--- a/gcr/tests/files/der-key-PBE-SHA1-RC2-40.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-PBE-SHA1-RC4-128.p8 b/gcr/tests/files/der-key-PBE-SHA1-RC4-128.p8
deleted file mode 100644
index 2888450c..00000000
--- a/gcr/tests/files/der-key-PBE-SHA1-RC4-128.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-dsa.p8 b/gcr/tests/files/der-key-dsa.p8
deleted file mode 100644
index 8b61684e..00000000
--- a/gcr/tests/files/der-key-dsa.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-encrypted-pkcs5.p8 b/gcr/tests/files/der-key-encrypted-pkcs5.p8
deleted file mode 100644
index 68c6b4a5..00000000
--- a/gcr/tests/files/der-key-encrypted-pkcs5.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-v2-des.p8 b/gcr/tests/files/der-key-v2-des.p8
deleted file mode 100644
index 4cd80348..00000000
--- a/gcr/tests/files/der-key-v2-des.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key-v2-des3.p8 b/gcr/tests/files/der-key-v2-des3.p8
deleted file mode 100644
index 9e2999c8..00000000
--- a/gcr/tests/files/der-key-v2-des3.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-key.p8 b/gcr/tests/files/der-key.p8
deleted file mode 100644
index 16505632..00000000
--- a/gcr/tests/files/der-key.p8
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/der-rsa-1024.key b/gcr/tests/files/der-rsa-1024.key
deleted file mode 100644
index 878fda5b..00000000
--- a/gcr/tests/files/der-rsa-1024.key
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/dhansak-collabora.cer b/gcr/tests/files/dhansak-collabora.cer
deleted file mode 100644
index c411e7d6..00000000
--- a/gcr/tests/files/dhansak-collabora.cer
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/email.p12 b/gcr/tests/files/email.p12
deleted file mode 100644
index d45d0f8d..00000000
--- a/gcr/tests/files/email.p12
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/generic-dsa.crt b/gcr/tests/files/generic-dsa.crt
deleted file mode 100644
index 5658a20c..00000000
--- a/gcr/tests/files/generic-dsa.crt
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/generic-dsa.key b/gcr/tests/files/generic-dsa.key
deleted file mode 100644
index cdd7ca54..00000000
--- a/gcr/tests/files/generic-dsa.key
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN DSA PRIVATE KEY-----
-MIIBuwIBAAKBgQCdLeaVVA8HNMKFr0UUQe/bj6mJvO+I67hxn/KzCWnMjw9h6vtu
-TI06OI4XXmEHCVdUxykTkp1NSaTanoV8seEbJyyUgFQFBVaFOE8xDHp5RZghAKpd
-XFP2Yn8wj8y2VYSOveFKXj9ySj9A38nbG8mF0imBXNg/nL/EPCynR7JBVwIVAM1D
-KUetENlaaH+QeAO3IwcENMSZAoGBAJFujxH2WB5bU+sjjePwBTRev6qtYzPAXPd+
-srC747afIasS0Q/+pE0Q40bjdGNipf3fs5Cq8s0tYTYeNzAqUej1X5YI7TP+uJyR
-L7QdD06pg1BbdaAzSxnnGjf2b25IvPRdxgy1XetgOmT+qA8nXeLROgTLNOQqxG83
-ymuMi/w7AoGAfXLlo8mCQgAGy7y32k/2Onv8LXAL5hcQUEM7WQhHkU2QaXgh7sqm
-Ol4vvM97YZi5JIlR0wjP7+dZiJJnYSY5PMaGpAIk7hLGsPbJW6TnozAXwCPli1Xu
-ocubvrDWjZ/zSesnO3siGPCIuP97IqVbBKGQG/vJUwFL0ewb/+FUa78CFHgQdcw2
-4vVlnuMrqdmrfXMvzbrw
------END DSA PRIVATE KEY-----
diff --git a/gcr/tests/files/generic-dsa.pem b/gcr/tests/files/generic-dsa.pem
deleted file mode 100644
index 0d81ef21..00000000
--- a/gcr/tests/files/generic-dsa.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDkjCCAvugAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBhjETMBEGCgmSJomT8ixk
-ARkWA0NPTTEXMBUGCgmSJomT8ixkARkWB0VYQU1QTEUxHjAcBgNVBAsTFUNlcnRp
-ZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAxMOY2EuZXhhbXBsZS5jb20xHTAbBgkq
-hkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMB4XDTA3MTIyMDE4NDc0N1oXDTA4MDEx
-OTE4NDc0N1owbDETMBEGCgmSJomT8ixkARkWA0NPTTEXMBUGCgmSJomT8ixkARkW
-B0VYQU1QTEUxFDASBgNVBAMTC0dlbmVyaWMgRFNBMSYwJAYJKoZIhvcNAQkBFhdn
-ZW5lcmljLWRzYUBleGFtcGxlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCd
-LeaVVA8HNMKFr0UUQe/bj6mJvO+I67hxn/KzCWnMjw9h6vtuTI06OI4XXmEHCVdU
-xykTkp1NSaTanoV8seEbJyyUgFQFBVaFOE8xDHp5RZghAKpdXFP2Yn8wj8y2VYSO
-veFKXj9ySj9A38nbG8mF0imBXNg/nL/EPCynR7JBVwIVAM1DKUetENlaaH+QeAO3
-IwcENMSZAoGBAJFujxH2WB5bU+sjjePwBTRev6qtYzPAXPd+srC747afIasS0Q/+
-pE0Q40bjdGNipf3fs5Cq8s0tYTYeNzAqUej1X5YI7TP+uJyRL7QdD06pg1BbdaAz
-SxnnGjf2b25IvPRdxgy1XetgOmT+qA8nXeLROgTLNOQqxG83ymuMi/w7A4GEAAKB
-gH1y5aPJgkIABsu8t9pP9jp7/C1wC+YXEFBDO1kIR5FNkGl4Ie7KpjpeL7zPe2GY
-uSSJUdMIz+/nWYiSZ2EmOTzGhqQCJO4SxrD2yVuk56MwF8Aj5YtV7qHLm76w1o2f
-80nrJzt7IhjwiLj/eyKlWwShkBv7yVMBS9HsG//hVGu/oxAwDjAMBgNVHRMBAf8E
-AjAAMA0GCSqGSIb3DQEBBQUAA4GBAPRyHCHjWKKVHZ7wSJQOS/Ve8e4DWFiuP9J8
-X4/sXEg59yWjScy9EovZVj5iELZI6OqUArvwVV6w6tewK0BAed4UGp+TyTHjPuJG
-WGxBm2AhtZUlYmpHQ+gA+E9weeFNQWP1QOATmFQ+r18eNH0rUONnR3G0XUYQTgd1
-LgEYxM4t
------END CERTIFICATE-----
diff --git a/gcr/tests/files/gnupg-homedir/pubring.gpg b/gcr/tests/files/gnupg-homedir/pubring.gpg
deleted file mode 100644
index 10b1372d..00000000
--- a/gcr/tests/files/gnupg-homedir/pubring.gpg
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/gnupg-homedir/secring.gpg b/gcr/tests/files/gnupg-homedir/secring.gpg
deleted file mode 100644
index 4a21e26c..00000000
--- a/gcr/tests/files/gnupg-homedir/secring.gpg
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/gnupg-homedir/trustdb.gpg b/gcr/tests/files/gnupg-homedir/trustdb.gpg
deleted file mode 100644
index 3824098b..00000000
--- a/gcr/tests/files/gnupg-homedir/trustdb.gpg
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/gnupg-mock/mock-arguments-environ b/gcr/tests/files/gnupg-mock/mock-arguments-environ
deleted file mode 100755
index 5282a2f0..00000000
--- a/gcr/tests/files/gnupg-mock/mock-arguments-environ
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-while getopts '1:2:' arg; do
- case $arg in
- 1)
- echo $OPTARG
- ;;
- 2)
- echo $OPTARG
- ;;
- *)
- echo "invalid argument: $arg"
- exit 2
- ;;
- esac
-done
-
-echo -n $ENVIRON1 >&2
-echo $ENVIRON2 >&2
diff --git a/gcr/tests/files/gnupg-mock/mock-echo b/gcr/tests/files/gnupg-mock/mock-echo
deleted file mode 100755
index 7c4e251a..00000000
--- a/gcr/tests/files/gnupg-mock/mock-echo
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-while read line; do
- echo "$line"
-done
diff --git a/gcr/tests/files/gnupg-mock/mock-fail-exit b/gcr/tests/files/gnupg-mock/mock-fail-exit
deleted file mode 100755
index 4d5634bb..00000000
--- a/gcr/tests/files/gnupg-mock/mock-fail-exit
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-exit $1
diff --git a/gcr/tests/files/gnupg-mock/mock-fail-signal b/gcr/tests/files/gnupg-mock/mock-fail-signal
deleted file mode 100755
index decf8a4b..00000000
--- a/gcr/tests/files/gnupg-mock/mock-fail-signal
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-echo $1 > /tmp/xxx
-kill -s $1 $$
-sleep 5
diff --git a/gcr/tests/files/gnupg-mock/mock-simple-error b/gcr/tests/files/gnupg-mock/mock-simple-error
deleted file mode 100755
index 30bb6a97..00000000
--- a/gcr/tests/files/gnupg-mock/mock-simple-error
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-echo -n "line 1: " >&2
-echo "more line 1" >&2
-echo "line 2" >&2
-echo "line 3" >&2 \ No newline at end of file
diff --git a/gcr/tests/files/gnupg-mock/mock-simple-output b/gcr/tests/files/gnupg-mock/mock-simple-output
deleted file mode 100755
index 0d145fcc..00000000
--- a/gcr/tests/files/gnupg-mock/mock-simple-output
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-echo -n "simple-"
-echo -n "outp"
-echo "ut" \ No newline at end of file
diff --git a/gcr/tests/files/gnupg-mock/mock-status-and-attribute b/gcr/tests/files/gnupg-mock/mock-status-and-attribute
deleted file mode 100755
index abf8607a..00000000
--- a/gcr/tests/files/gnupg-mock/mock-status-and-attribute
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-# This script is used with test-gnupg-process
-# Needs to be run with /bin/bash in order to handle two digit
-# file descriptor redirects
-
-set -euf
-
-SFD=
-AFD=
-
-# Not real 'long' option parsing, but good enough for this
-while [ $# -gt 1 ]; do
- if [ "$1" = --status-fd ]; then
- SFD=$2
- shift
- elif [ "$1" = --attribute-fd ]; then
- AFD=$2
- shift
- fi
- shift
-done
-
-# No FD passed :(
-if [ -z "$AFD" ]; then
- exit 22
-fi
-if [ -z "$SFD" ]; then
- exit 23
-fi
-
-echo -n "1lc923g4laoeurc23rc2" >&$AFD
-echo "[GNUPG:] SCHEMA one two three four " >&$SFD
-echo -n "41lcg2r23c4gr3" >&$AFD
diff --git a/gcr/tests/files/gnupg-mock/mock-status-and-output b/gcr/tests/files/gnupg-mock/mock-status-and-output
deleted file mode 100755
index 0fd544b4..00000000
--- a/gcr/tests/files/gnupg-mock/mock-status-and-output
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-FD=
-
-# Not real 'long' option parsing, but good enough for this
-while [ $# -gt 1 ]; do
- if [ "$1" = --status-fd ]; then
- FD=$2
- shift
- fi
- shift
-done
-
-# No FD passed :(
-if [ -z "$FD" ]; then
- exit 22
-fi
-
-echo "Here's some output"
-echo "[GNUPG:] SCHEMA one two three four " >&$FD
-echo "More output"
diff --git a/gcr/tests/files/gnupg-mock/mock-with-homedir b/gcr/tests/files/gnupg-mock/mock-with-homedir
deleted file mode 100755
index c537e03a..00000000
--- a/gcr/tests/files/gnupg-mock/mock-with-homedir
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# This script is used with test-gnupg-process
-set -euf
-
-HOMEDIR=
-
-# Not real 'long' option parsing, but good enough for this
-while [ $# -gt 1 ]; do
- if [ "$1" = --homedir ]; then
- HOMEDIR=$2
- shift
- fi
- shift
-done
-
-# No homedir passed :(
-if [ -z "$HOMEDIR" ]; then
- exit 22
-fi
-
-echo "DIR: $HOMEDIR"
diff --git a/gcr/tests/files/openssh_keys.pub b/gcr/tests/files/openssh_keys.pub
deleted file mode 100644
index 00d294bc..00000000
--- a/gcr/tests/files/openssh_keys.pub
+++ /dev/null
@@ -1,2 +0,0 @@
-ssh-dss AAAAB3NzaC1kc3MAAACBAL4z+ad0ZJYzMOQuGp00UJ+AijKhrPVUEYLcxBmFQonb/KIlLSWJua4Rl9DB4tDj30Y9c/oApqC4n+FIYlUZMSnxmpvcLF6aeXOiHHPvm0EDYjjyVubyYQWI7CROrrzSc+x++ha3TuJEvF3PlKlZmTKKVYEkZNjwFqYysGyPxPalAAAAFQDtDSEF9Gvnv5fQtSbbsp7j78uVBwAAAIAtNpAg/Mbd/E2241enedB9AxAbJWZ5QYnoPe6/zx5dOmU7+qz8mG6tgvF8F7IgXPabuAKslzTDGS3zgaEhWicDS3CIYik2UR8hXdxfovIEqZKZe7u02FCEoXYCEiFUAdzDGzjI7PswgtEJWWNqKeNis3HmDDha9lMkqz/3fLZGXwAAAIEAiaRPYKZDMoJG+aVZ5A3R/m2gl+mYE2MsjPKXuBKcrZ6ItA9BMe4G/An0/+E3A+DuoGxdeNNMF8U9Dy2N8Sch/Ngtg2E/FBo5geljWobJXd1jxmPtF2WAliYJXDdIt6RBVPGL9H/KSjDmBMsVd42wxVJywawzypklVZjSUuWuBMI= dsa-key@example.com
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCs8z2y0cCPYRAPkq8tAt6FC/kdfnR/p8B2ZoY0oiLNt7kQEwJfexgwLqTxWYd2fSDUSSDPrsqAxZAwLLS/eF04kXiJO2VfqAWFpTLNToERHpFF1yZQe26ELTlNNfna7LqfCRvpNDwu6AqndsT3eFt7DWvBDXbbEiTLW21Z2OFAAH/J2iCFn4c0a8Myf7IaMYcy5GG3mpk39kEO4aNV/67U7kfooek24ObwD0vlXzlsi5VZIUFOIUi0UdkNEMCtUWpfkZ1STUlmwp9HVM7xb7/9PESQKDnZdxpB09S9cIjdpDecpDlMDDEbEUECM1PIas3ndhB7gAN1i2JsPHTcXZ1 rsa-key@example.com
diff --git a/gcr/tests/files/pem-dsa-1024.key b/gcr/tests/files/pem-dsa-1024.key
deleted file mode 100644
index ccb1e7b9..00000000
--- a/gcr/tests/files/pem-dsa-1024.key
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN DSA PRIVATE KEY-----
-MIIBuwIBAAKBgQCQ7Atgc1g5x1Tq+PZLsD/DU5jWl3K/rlQAed6i06Yfr/snYwoD
-igGj0M1ioQdFpXSifstGL08IhbecYbvpVKYKKWaK1Uu6XAenL9ixEFJJZwsznfLF
-nmSkcGTvzwtyNsXHLNVc6zKRdDC+yaAD1OSE+6qE15Vxs41rWslbtz4/ewIVAPoh
-ShOFwhv+uq2rJAokMMYH1WJxAoGALeBXUfXa7pfz1DxUWVo+lKCAco8MZsmK6+1X
-YvarFVgC2DWerR3h7DakWfvu6kjlm55qjLT1KVk2s8yIGl2VfHM5F14s/+DzDTcR
-5DDbZkjC60dKoQpKMpdFBTH/LHxpUSIMnURra2sPACYuHr6zzIYUdqpRjMVVyav5
-5fOQI/wCgYBUc0RR23nU7t8LvOvUO7bLt7hYRgO5VwgAdd0xjrWwJm1LINxe/zdr
-38TqKYOx9/AqOe1MYZ7WhxJyn/87fGlq3RttdI9WpLS+xcQ4XlKEI6O4iuZebVUA
-+Xg556SGJVmCGJw7T6jZQzjHbw5cr8mjCh7XKLufIJHVlOMlCgnqAAIVAIdvhPcJ
-1REI37DL+h8cVpwJxBPs
------END DSA PRIVATE KEY-----
diff --git a/gcr/tests/files/pem-pkcs8.key b/gcr/tests/files/pem-pkcs8.key
deleted file mode 100644
index 1f0d5edb..00000000
--- a/gcr/tests/files/pem-pkcs8.key
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIf4lXzcHXqAICAggA
-MBQGCCqGSIb3DQMHBAhV8iKHmoUJDQSCAoDK4fY/dfIzOof1QlYV8mhr0OmhaIAe
-aaDz4rER6+OGwq7WQ32ErmHBiJRI8oQRrxy4oHTXx8TR+JxQT1io9V9jjXZCS8HT
-Ek0J69pgjPdIUnlZYV1GdJUJq7tWxTKJJFr1tsB0XzgugQLYcui4ikrZ6rHE9PVh
-SXFIEbns42xHIvtQ/j3c6ScS63UNpSsKe5pWRNgHUHpjSGPAaZogOdMfStmj3tdN
-nIH3mjIM8uisN9nyPV42aziZi5mO9F5JHlNp1H5pDAUWOKkKoXw27MgXnxvSkLAX
-HSgpPuK5ejqXu4nkciwHnr4eULV0biwqpmYEWxC4aNuog/t3DoL1gkC74J07jjUU
-3gZwxjKsAWfIKnNURsHlBAcYClug5ZWs9ru/4sc27bNV9qRKbHcgGD+nzfTXxZZ2
-BG5eSBVpYT2Jzdkpw8puSHwNW5mQcuY4E+ZEERFsW8q1raPSgYVk5rM8TiVdTD5x
-UwQG7ADidVSVTR5KGV8wmonbuDu9b61GgU7VBslEK9Lsd92FO0/u09FF6DgCcICD
-yRJ0nM0o9S9FI1lqKoxAdgWyFwrKkBVZ05IDHw+jS6r7D/2irYetPJmVO/dvi87r
-aaLvyvzU3nz4LiWHmSl2AgDanjDcxtjGoWR2cc+J0v3r/+VEOctrc5EuAnlhl9Yj
-kFcfZDfqthCNb49qNGDgQMGrKTt+Dvrka/ZZxXBN3v96L3K4O32j9c97sZ8LEFaI
-RHl91Mx2okjrT9q2+Gef2UR9XEzuFEBRBqxktltlrIQIncn6Xx/TjEvIhf2Dgo4W
-isaAwTazyZrzATTWR1JS6Hdm7Eb/nCEHAFmVUbQm0d5BDfKmnRsNaaZK
------END ENCRYPTED PRIVATE KEY-----
diff --git a/gcr/tests/files/pem-rsa-enc.key b/gcr/tests/files/pem-rsa-enc.key
deleted file mode 100644
index 65439fe6..00000000
--- a/gcr/tests/files/pem-rsa-enc.key
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,24522D4CE5F5CD7B
-
-2H/8j0HYUya7LWEUxpgjp/LVcCX7yZB7SoREdoJdcqJEBUMWVxU/2OfVB8EZupmy
-7YHcnn5v1JwwtmAXAtqM9JGlvNWaRr1m4zDrhJn1fY3tu8YGtMR49IOZmOUBK+X+
-IxWAwaFDqLntuGZZnAmRJtgFVYVABEs5yM9zgoCGDaU4WMK3caD7Jnw8jH5m0nqQ
-XiQ1y1dHxFJmAgG0b5h2z7zjQTmmXd3IhXqSqsE/9ryruCCYa0Z7aAN5oAmO89I9
-gOyy3J4h76mTNFfF5btV4Jllwd4LkgGOmm69UxAyUTGzwYJ5gxgB3xFzGBwpVlcu
-72PrQCrjZqZ6rj6cTPGUYzcyMtEw3Xd6mFhApqJpVRZwNWUAMMJwHl2oWwKcIxfV
-y+OftRX6kc+cunrxCkl9aKuHDoJPEq+/Uh+AEXqir+942Vull0WPyuWUjaPKR1xJ
-poYsNfHRWq+klKCggQQL6jwuVbDLhbaXfgaNBQO1XMracgfmnO1PQPw8JSQ5iOkm
-Ybt2oHAEnrEWxZGn1PfRq6Z8HAbBlQpfmG7SMJZdQjlndKA6GR+tN5krKfpj6uak
-0eklm0Nb0YcDzJ3qqHXxIimK3Kh/WRZ1hVTnX4mS9u3HNQMo5Ov6z8OQN+Q45ffi
-ZDFkVwUTEJ+iwmCG7XnxX0v8Bv5LZmAnPu95KQTp4Ds0AZ6Sp+RqxvhnCO25cgWj
-+N5jHGzsDk9/Jw7rAHz8pnl3sziNBWdAk5ASPA28HCQQo5peWnWajM3Pk98+/wHY
-blTh7gw77gTake6hpiegnhNUXwGm6BXEqmyu7mPW0z5XFRb9W7bpog==
------END RSA PRIVATE KEY-----
diff --git a/gcr/tests/files/personal.p12 b/gcr/tests/files/personal.p12
deleted file mode 100644
index 7ae3d05d..00000000
--- a/gcr/tests/files/personal.p12
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/pubring.gpg b/gcr/tests/files/pubring.gpg
deleted file mode 100644
index 10b1372d..00000000
--- a/gcr/tests/files/pubring.gpg
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/secring.gpg b/gcr/tests/files/secring.gpg
deleted file mode 100644
index 4a21e26c..00000000
--- a/gcr/tests/files/secring.gpg
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/test-x509-swiss.p7b b/gcr/tests/files/test-x509-swiss.p7b
deleted file mode 100755
index d45b9e0e..00000000
--- a/gcr/tests/files/test-x509-swiss.p7b
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/unclient.p12 b/gcr/tests/files/unclient.p12
deleted file mode 100644
index 321b4475..00000000
--- a/gcr/tests/files/unclient.p12
+++ /dev/null
Binary files differ
diff --git a/gcr/tests/files/werner-koch.asc b/gcr/tests/files/werner-koch.asc
deleted file mode 100644
index eb70c972..00000000
--- a/gcr/tests/files/werner-koch.asc
+++ /dev/null
@@ -1,71 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.11 (GNU/Linux)
-
-mQGiBDWiHh4RBAD+l0rg5p9rW4M3sKvmeyzhs2mDxhRKDTVVUnTwpMIR2kIA9pT4
-3No/coPajDvhZTaDM/vSz25IZDZWJ7gEu86RpoEdtr/eK8GuDcgsWvFs5+YpCDwW
-G2dx39ME7DN+SRvEE1xUm4E9G2Nnd2UNtLgg82wgi/ZK4Ih9CYDyo0a9awCgisn3
-RvZ/MREJmQq1+SjJgDx+c2sEAOEnxGYisqIKcOTdPOTTie7o7x+nem2uac7uOW68
-N+wRWxhGPIxsOdueMIa7U94Wg/Ydn4f2WngJpBvKNaHYmW8j1Q5zvZXXpIWRXSvy
-TR641BceGHNdYiR/PiDBJsGQ3ac7n7pwhV4qex3IViRDJWz5Dzr88x+Oju63KtxY
-urUIBACi7d1rUlHr4ok7iBRlWHYXU2hpUIQ8C+UOE1XXT+HB7mZLSRONQnWMyXnq
-bAAW+EUUX2xpb54CevAg4eOilt0es8GZMmU6c0wdUsnMWWqOKHBFFlDIvyI27aZ9
-quf0yvby63kFCanQKc0QnqGXQKzuXbFqBYW2UQrYgjXji8rd8bQnV2VybmVyIEtv
-Y2ggKGdudXBnIHNpZykgPGRkOWpuQGdudS5vcmc+iGEEExECACECF4AFCQ4Uh/0F
-AkG8aF4GCwkIBwMCAxUCAwMWAgECHgEACgkQaLeriVdUjc0EkwCfTXfXdqDS2COs
-ZRm0OUphuY0h4x4AnRSlWyPGnKUFxKOw8TwwCSLsdvZHmQGiBDbtSOkRBACURhKn
-GIFyXIeX61GAY9hJA5FgG4UalV55ohdz4whBgDzDGLE3XYlO8HCn4ggKilll6MOw
-Y0yZeg6PEU9Y3SqTzpQSV6qj2M7MgcS8xOpi6bNCu0iyZUik0KklUXMdI8e/CVmB
-pQJT9CofbD1dsP6z4dC6z3jil0+5Wbfw6yIXzwCgy/7Fagq5mN0H760/JEiiXILS
-1n0D/3H26lTaxo1vGput9Td1FQN7Vn6YDP0/To5ipsOODROV3zyUwF5QleY+8zTF
-JA3qD5KxRfA726WELOF1mB6Mw44UdkPniOoGdMH5oSx6qnNnlVZBBu3U+e1qfQwL
-QjHu0WX4Z2q00DKpWLThGv7Loh5NKi6OfTbMhfHoevCAzQnmA/wKc6J8GqthENTh
-KXxZaei3Ep0t+PlBmbUzuAYCXZhI6/0KyD6emyQ7LYIaPv9qEfMkMLhxicG0v/AA
-wOCBRKS3bkqc6wAYaO0bjUHJvem3HkWPux82t83+6YPyRnVjm/mwt0uEyKSvt7Md
-2DVrO3lEcKRkRHiYuf0nonPhl5Rs5bQaV2VybmVyIEtvY2ggPHdrQGdudXBnLm9y
-Zz6IawQTEQIAIwIXgAIZAQUJE2uL/wUCQllAcgULBwoDAgMVAgMDFgIBAh4BABIH
-ZUdQRwABAQkQXeJJllsDWKI6xwCfV3paxYsk7KQmrtOUxNmZb004OQoAn3uq9imO
-pgxqsXhXaLfz5IqZu5O7tBxXZXJuZXIgS29jaCA8d2tAZzEwY29kZS5jb20+iGME
-ExECACMCGwMCHgECF4AFCRNri/8FAkJZQHoFCwcKAwIDFQIDAxYCAQAKCRBd4kmW
-WwNYouXsAJ9nbkvbiJZvNlzwBL98x7YB+u9fsgCfXE6vHv6DJk7Eh9CY+Gcdn6kC
-G8i0C1dlcm5lciBLb2NoiGMEExECABsFAjbtSOoFCQzJfIADCwoDAxUDAgMWAgEC
-F4AAEgkQXeJJllsDWKIHZUdQRwABAbXWAJ9SCW0ieOpL7AY6vF+OIaMmw2ZW1gCg
-kto0eWfgpjAuVg6jXqR1wHt2pQO0HVdlcm5lciBLb2NoIDx3ZXJuZXJAZnNmZS5v
-cmc+iGMEExECACMCGwMFCRNri/8CHgECF4AFAkJZQHoFCwcKAwIDFQIDAxYCAQAK
-CRBd4kmWWwNYovxpAJ0ftTtETxhK8aKfIok/+43wNbQASwCfSFCPuVKTNHpv4JJ7
-9feDCtfxxLG5AaIEQF3aTxEEAP9SgfIbIPL6BQ1nqoblsTYoiwWPL48uBZPjkDfy
-8XsVR5V9aRQlggC4x4/MD3Ip5AUgReI7PcHnp4m3vcVLXPl+/7i7hAwd84iKzgN8
-I8VW0EevflcNm7nbWEnpjaGxJWFbhSLI1DmqnafoU8nZgGp2QoE+flgGDd559C3S
-iHRTAKDbqgS3EDhTbwfS+bAhW5Xi8/2CPwP9HueeuW9M/cyt8UvliLsj2eYMEIy7
-CeSLO13XfnqCjcnHK+b59/ADd99dpMaq3gKj7Aj1RIsRV2qWDJpDNXVxP7Cy+Fzx
-elQsytPQOV8H8AkB+RgmSyfxlNRUkC3sQU6jR9IwmPD4iB5fp/SqUpn++77TAArX
-qsfHbmlnwcuU1EAD/i7CEhxLBYS1N77hwxL8DWCqjpi+1PKG+6dc0BQFIU3uUhbz
-LGfqEobUDhveqgtlsvoEZ/lR8RgMv/uOjXEgiATQyTEa7s3M2vjXlpLjXjzklma3
-Lqmcam3dEf/5OR02yZif6hPU/x8f/VQle0kKNKdOCV1+dlo8aJH2UIZRRIvtiJcE
-GBECAA8CGwIFCQcbVgAFAkR1rB0AUkcgBBkRAgAGBQJEdawTAAoJEGB4TpQBClft
-2RMAn1XiL/bC9hByZInCJTaCd8WS8kYCAKCfpAWwLIxkfwAeD/RI+2p00nQfvAkQ
-XeJJllsDWKKx7QCguc4/HiEs64Ey5p6Yihy67X8E0YsAnRXMFdXVP7ww8uldljPi
-D1TgyurpuQELBEBd2ykBCADRKFS0lZw/2MawS97P3nVyt2FF9XWb8si7T9Jgl+NR
-F93uqUOIC15s3u5SVPcwdIhoG04wYKHTLKhyBAjFp4azfLmiIBDDp37DY3SAtJT6
-TsgULR+yFkXbRvuIOU5N/0WxzrK6JJwlFVEyaPX7zmWVKMCj+SMj2FrmltuVS0aC
-f0io3n97bUAvuU3dgjTFoHqW4017smfbE4VMwnLYi3/1SS9s0ysKM6Px5yEM3oQi
-OW/9pS48wSFfs3lXi8N1BikgPdU5FFA+5BGSUhxyFf+lqdjwcByBC7LT3dCrFeWQ
-OL0UeVh6wG48O63j8jue7mfTm+559uXnD/J65PiHcZTnAAYpiE8EGBECAA8FAkBd
-2ykCGwwFCQNY7wAACgkQXeJJllsDWKIS1gCgoJ2z4OnA0dVt7ZM/PeAsKXA0KFUA
-n3AV3yuZKX4WHw5Pnf5sLmF5LUkluQELBEO4FiIBCADRWoeCwf4lVIJQahM7ytFR
-vPMrkSZQy072/I6/4QPKsaHI+HnoB8PjTmBpyBDLK8Y6Of3Y1hNb77xe+m2g+8Wq
-/BUKHvUi1F+xzszpnixtMr+QOiy6U7kCJA6fGvq0qmzrXGcv5rXpGvWwyZfymTLW
-4X2WKgNL8bhODy0uJ9ZR/fhjE7nnIHgIboSnBAUPHCsI9BFumsbU8FKsKJCOBqzi
-HEyDHbix7uP6ByYslH2tUw9WdQU8Yzo2mWojghXpjE7UT0tAb4QNTdwurLgiEIH5
-umsM43elr1/2nd06KigQX+NR4MqytR+28JtEEKvULwJZpmExs4B+OB4x8l+6Lc0/
-AAYpiE8EGBECAA8FAkO4FiICGwwFCQPBFYAACgkQXeJJllsDWKJdywCeNyRtO1/y
-IyiNkotYRfO5y3xuHocAnAyA4jaxa702sRs4iPR/WWJkMgEqmI4EQ7f6xwEEANCZ
-GXorXMkDKpNsRnf+ZhqHOPmDcEKPDkplcCL2PFACN7QaK4ReoWvZ4mqmVOL3ZXU5
-1zFNI9aD3JAIToET2jr2hGYWFExdBf9eaYgBeXZGUOnbJl1VJDzWDGU6ZHNpwPiA
-AgYjpsoBgZCxbl7x0VtYukjc9vIkR/1GXGC4v9ohACCBVlCZtCZXZXJuZXIgS29j
-aCAoZGlzdCBzaWcpIDxkZDlqbkBnbnUub3JnPoi8BBMBAgAmBQJDt/rIAhsDBQkF
-o5qABgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQU7Yg0BzgxjB5owQAh0MO0kuQ
-7hM6AKj8YK4bRGapHBmeIniaer9Y6vwXgErfDUci7BUQTxXoFFTgKHHzBz39bzeS
-tyQgTm5plGaOEJcJayIr07DaeBtcC/dMoVUJswybKMFtP7fUz05PRKjChvxrWzhe
-/Yn6BAmPF+6YxQo2W98rzq0THS5wKJjXmHw=
-=F0ww
------END PGP PUBLIC KEY BLOCK-----
diff --git a/gcr/tests/frob-certificate.c b/gcr/tests/frob-certificate.c
deleted file mode 100644
index a84dbc7f..00000000
--- a/gcr/tests/frob-certificate.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer user_data)
-{
- GcrCertificateWidget *details;
- GtkDialog *dialog = GTK_DIALOG (user_data);
-
- details = g_object_new (GCR_TYPE_CERTIFICATE_WIDGET,
- "attributes", gcr_parser_get_parsed_attributes (parser),
- NULL);
-
- gtk_widget_show (GTK_WIDGET (details));
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
-
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-}
-
-static void
-test_certificate (const gchar *path)
-{
- GcrParser *parser;
- GError *err = NULL;
- guchar *data;
- gsize n_data;
- GtkWidget *dialog;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- dialog = gtk_dialog_new ();
- g_object_ref_sink (dialog);
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), dialog);
- if (!gcr_parser_parse_data (parser, data, n_data, &err))
- g_error ("couldn't parse data: %s", err->message);
-
- g_object_unref (parser);
- g_free (data);
-
- gtk_widget_show (dialog);
- g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
- gtk_main ();
-
- g_object_unref (dialog);
-}
-
-int
-main(int argc, char *argv[])
-{
- gtk_init (&argc, &argv);
- g_set_prgname ("frob-certificate");
-
- if (argc > 1)
- test_certificate (argv[1]);
- else
- test_certificate (SRCDIR "/files/der-certificate.crt");
-
- return 0;
-}
diff --git a/gcr/tests/frob-combo-selector.c b/gcr/tests/frob-combo-selector.c
deleted file mode 100644
index fd9fc868..00000000
--- a/gcr/tests/frob-combo-selector.c
+++ /dev/null
@@ -1,95 +0,0 @@
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer user_data)
-{
- GcrSimpleCollection *collection = user_data;
- GcrRenderer *renderer;
-
- renderer = gcr_renderer_create (gcr_parser_get_parsed_label (parser),
- gcr_parser_get_parsed_attributes (parser));
-
- if (renderer) {
- gcr_simple_collection_add (collection, G_OBJECT (renderer));
- g_object_unref (renderer);
- }
-}
-
-static void
-add_to_selector (GcrParser *parser, const gchar *path)
-{
- GError *err = NULL;
- guchar *data;
- gsize n_data;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- if (!gcr_parser_parse_data (parser, data, n_data, &err))
- g_error ("couldn't parse data: %s", err->message);
-
- g_free (data);
-}
-
-int
-main (int argc, char *argv[])
-{
- GcrCollection *collection;
- GcrComboSelector *selector;
- GtkDialog *dialog;
- GcrParser *parser;
- GObject *selected;
- int i;
-
- gtk_init (&argc, &argv);
-
- dialog = GTK_DIALOG (gtk_dialog_new ());
- g_object_ref_sink (dialog);
-
- collection = gcr_simple_collection_new ();
- selector = gcr_combo_selector_new (collection);
-
- gtk_widget_show (GTK_WIDGET (selector));
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (selector));
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), collection);
-
- if (argc == 1) {
- add_to_selector (parser, "files/ca-certificates.crt");
- } else {
- for (i = 1; i < argc; ++i)
- add_to_selector (parser, argv[i]);
- }
-
- g_object_unref (parser);
- g_object_unref (collection);
-
- gtk_dialog_run (dialog);
-
- selected = gcr_combo_selector_get_selected (selector);
- if (selected == NULL) {
- g_print ("nothing selected\n");
- } else {
- gchar *label;
- g_object_get (selected, "label", &label, NULL);
- g_print ("selected: %s\n", label);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
-
- return 0;
-}
diff --git a/gcr/tests/frob-gnupg-selector.c b/gcr/tests/frob-gnupg-selector.c
deleted file mode 100644
index 444483ee..00000000
--- a/gcr/tests/frob-gnupg-selector.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-#include "gcr/gcr-gnupg-collection.h"
-#include "gcr/gcr-gnupg-key.h"
-#include "gcr/gcr-list-selector-private.h"
-#include "gcr/gcr-live-search.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static void
-on_collection_loaded (GObject *source, GAsyncResult *result, gpointer unused)
-{
- GError *error = NULL;
-
- _gcr_gnupg_collection_load_finish (GCR_GNUPG_COLLECTION (source), result, &error);
- if (error) {
- g_warning ("collection load failed: %s", error->message);
- g_clear_error (&error);
- }
-}
-
-int
-main (int argc, char *argv[])
-{
- GcrCollection *collection;
- GcrListSelector *selector;
- GtkWidget *scroll;
- GtkDialog *dialog;
- GtkWidget *search;
- GtkBox *box;
-
- gtk_init (&argc, &argv);
-
- dialog = GTK_DIALOG (gtk_dialog_new ());
- g_object_ref_sink (dialog);
-
- collection = _gcr_gnupg_collection_new (NULL);
- selector = gcr_list_selector_new (collection);
- search = _gcr_live_search_new (GTK_WIDGET (selector));
- _gcr_list_selector_set_live_search (selector, GCR_LIVE_SEARCH (search));
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (selector));
-
- box = GTK_BOX (gtk_dialog_get_content_area (dialog));
- gtk_box_pack_start (box, GTK_WIDGET (scroll), TRUE, TRUE, 0);
- gtk_box_pack_end (box, search, FALSE, TRUE, 0);
-
- gtk_widget_show (GTK_WIDGET (selector));
- gtk_widget_show (scroll);
-
- _gcr_gnupg_collection_load_async (GCR_GNUPG_COLLECTION (collection), NULL,
- on_collection_loaded, NULL);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-
- g_object_unref (collection);
-
- gtk_dialog_run (dialog);
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
-
- return 0;
-}
diff --git a/gcr/tests/frob-key.c b/gcr/tests/frob-key.c
deleted file mode 100644
index 3eedb493..00000000
--- a/gcr/tests/frob-key.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer unused)
-{
- GcrKeyWidget *details;
- GtkDialog *dialog;
-
- dialog = GTK_DIALOG (gtk_dialog_new ());
- g_object_ref_sink (dialog);
-
- details = gcr_key_widget_new (gcr_parser_get_parsed_attributes (parser));
- gtk_widget_show (GTK_WIDGET (details));
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
- gtk_dialog_run (dialog);
-
- g_object_unref (dialog);
- g_object_unref (details);
-}
-
-static void
-test_key (const gchar *path)
-{
- GcrParser *parser;
- GError *err = NULL;
- guchar *data;
- gsize n_data;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), NULL);
- if (!gcr_parser_parse_data (parser, data, n_data, &err))
- g_error ("couldn't parse data: %s", err->message);
-
- g_object_unref (parser);
- g_free (data);
-}
-
-int
-main(int argc, char *argv[])
-{
- gtk_init (&argc, &argv);
- g_set_prgname ("frob-key");
-
- if (argc > 1)
- test_key (argv[1]);
- else
- test_key (SRCDIR "/files/pem-dsa-1024.key");
-
- return 0;
-}
diff --git a/gcr/tests/frob-openpgp.c b/gcr/tests/frob-openpgp.c
deleted file mode 100644
index b83305af..00000000
--- a/gcr/tests/frob-openpgp.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-#include "gcr/gcr-openpgp.h"
-#include "gcr/gcr-record.h"
-
-#include "egg/egg-armor.h"
-
-static void
-on_packet_print_records (GPtrArray *records,
- const guchar *packet,
- gsize n_packet,
- gpointer user_data)
-{
- gchar *string;
- guint i;
-
- for (i = 0; i < records->len; i++) {
- string = _gcr_record_format (records->pdata[i]);
- g_print ("%s\n", string);
- g_free (string);
- }
-}
-
-static gboolean
-parse_binary (gconstpointer contents,
- gsize length)
-{
- guint packets;
-
- packets = _gcr_openpgp_parse (contents, length,
- GCR_OPENPGP_PARSE_KEYS |
- GCR_OPENPGP_PARSE_ATTRIBUTES,
- on_packet_print_records, NULL);
-
- return (packets > 0);
-}
-
-static void
-on_armor_parsed (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
- GHashTable *headers,
- gpointer user_data)
-{
- const gchar *value;
- gboolean *result = user_data;
-
- value = g_hash_table_lookup (headers, "Version");
- g_assert_cmpstr (value, ==, "GnuPG v1.4.11 (GNU/Linux)");
-
- *result = parse_binary (data, n_data);
-}
-
-static gboolean
-parse_armor_or_binary (gconstpointer contents,
- gsize length)
-{
- gboolean result;
- guint parts;
-
- parts = egg_armor_parse (contents, length, on_armor_parsed, &result);
- if (parts == 0)
- result = parse_binary (contents, length);
- return result;
-}
-
-int
-main(int argc, char *argv[])
-{
- GError *error = NULL;
- gchar *contents;
- gsize length;
- int ret;
-
- g_set_prgname ("frob-openpgp");
-
- if (argc != 2) {
- g_printerr ("usage: frob-openpgp filename\n");
- return 2;
- }
-
- if (!g_file_get_contents (argv[1], &contents, &length, &error)) {
- g_printerr ("frob-openpgp: couldn't read file: %s: %s", argv[1], error->message);
- g_error_free (error);
- return 1;
- }
-
- ret = 0;
- if (!parse_armor_or_binary (contents, length)) {
- g_printerr ("frob-openpgp: no openpgp data found in data");
- ret = 1;
- }
-
- g_free (contents);
- return ret;
-}
diff --git a/gcr/tests/frob-parser.c b/gcr/tests/frob-parser.c
deleted file mode 100644
index 2459a10a..00000000
--- a/gcr/tests/frob-parser.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static gboolean
-dump_certificate (GckAttributes *attrs, const gchar *filename)
-{
- GckAttribute *attr;
- GcrCertificate *cert;
- gchar *subject;
- gulong klass;
-
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) ||
- klass != CKO_CERTIFICATE)
- return FALSE;
-
- attr = gck_attributes_find (attrs, CKA_VALUE);
- if (!attr)
- return FALSE;
-
- cert = gcr_simple_certificate_new_static (attr->value, attr->length);
- subject = gcr_certificate_get_subject_dn (cert);
- g_print ("%s: parsed certificate: %s\n", filename, subject);
- g_free (subject);
- g_object_unref (cert);
-
- return TRUE;
-}
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer user_data)
-{
- GckAttributes *attrs;
- const gchar **pointer_filename = (const gchar**)user_data;
-
- attrs = gcr_parser_get_parsed_attributes (parser);
- g_return_if_fail (attrs);
-
- if (!dump_certificate (attrs, *pointer_filename))
- g_print ("%s: parsed %s\n", *pointer_filename,
- gcr_parser_get_parsed_description (parser));
-}
-
-int
-main(int argc, char *argv[])
-{
- GcrParser *parser;
- GError *error = NULL;
- gchar *contents;
- gsize len;
- GDir *dir;
- const gchar *filename;
- gchar *path;
-
- g_type_init ();
- g_set_prgname ("frob-parser");
-
- if (argc != 2) {
- g_printerr ("usage: frob-parser directory\n");
- return 2;
- }
-
- dir = g_dir_open (argv[1], 0, &error);
- if (!dir) {
- g_printerr ("couldn't list directory: %s: %s\n", argv[1], error->message);
- g_clear_error (&error);
- return 1;
- }
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), &filename);
-
- for (;;) {
- filename = g_dir_read_name (dir);
- if (!filename)
- break;
- if (filename[0] == '.')
- continue;
-
- path = g_build_filename (argv[1], filename, NULL);
- g_file_get_contents (path, &contents, &len, &error);
- g_free (path);
-
- if (error) {
- g_printerr ("%s: couldn't read file: %s\n", filename, error->message);
- g_clear_error (&error);
- continue;
- }
-
- gcr_parser_parse_data (parser, (const guchar *)contents, len, &error);
- g_free (contents);
-
- if (error) {
- g_warning ("%s: couldn't parse: %s\n", filename, error->message);
- g_clear_error (&error);
- }
-
- g_print ("%s: finished parsing\n", filename);
- }
-
- g_dir_close (dir);
- g_object_unref (parser);
-
- return 0;
-}
diff --git a/gcr/tests/frob-tree-selector.c b/gcr/tests/frob-tree-selector.c
deleted file mode 100644
index 313781e6..00000000
--- a/gcr/tests/frob-tree-selector.c
+++ /dev/null
@@ -1,208 +0,0 @@
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#define TEST_TYPE_COLLECTION (test_collection_get_type ())
-#define TEST_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_COLLECTION, TestCollection))
-#define TEST_IS_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_COLLECTION))
-
-typedef struct _TestCollection TestCollection;
-typedef struct _TestCollectionClass TestCollectionClass;
-typedef struct _TestCollectionPrivate TestCollectionPrivate;
-
-struct _TestCollection {
- GcrSimpleCollection parent;
- gchar *label;
-};
-
-struct _TestCollectionClass {
- GcrSimpleCollectionClass parent_class;
-};
-
-GType test_collection_get_type (void) G_GNUC_CONST;
-
-enum {
- PROP_0,
- PROP_LABEL,
-};
-
-G_DEFINE_TYPE (TestCollection, test_collection, GCR_TYPE_SIMPLE_COLLECTION);
-
-static GHashTable *all_collections = NULL;
-
-static void
-test_collection_init (TestCollection *self)
-{
-
-}
-
-static void
-test_collection_finalize (GObject *obj)
-{
- TestCollection *self = TEST_COLLECTION (obj);
- g_free (self->label);
- g_hash_table_remove (all_collections, self);
- G_OBJECT_CLASS (test_collection_parent_class)->finalize (obj);
-}
-
-static void
-test_collection_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TestCollection *self = TEST_COLLECTION (obj);
- switch (prop_id) {
- case PROP_LABEL:
- g_value_set_string (value, self->label);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-test_collection_class_init (TestCollectionClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->get_property = test_collection_get_property;
- gobject_class->finalize = test_collection_finalize;
-
- g_object_class_install_property (gobject_class, PROP_LABEL,
- g_param_spec_string ("label", "label", "label", NULL, G_PARAM_READABLE));
-}
-
-static GcrSimpleCollection *
-test_collection_instance (const gchar *label)
-{
- TestCollection *collection = NULL;
-
- g_assert (label);
-
- if (!all_collections) {
- all_collections = g_hash_table_new (g_str_hash, g_str_equal);
- } else {
- collection = g_hash_table_lookup (all_collections, label);
- if (collection != NULL)
- return g_object_ref (collection);
- }
-
- collection = g_object_new (TEST_TYPE_COLLECTION, NULL);
- collection->label = g_strdup (label);
- g_hash_table_insert (all_collections, collection->label, collection);
- return GCR_SIMPLE_COLLECTION (collection);
-}
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer user_data)
-{
- GcrSimpleCollection *collection = user_data;
- GcrSimpleCollection *testcol;
- GcrRenderer *renderer;
- gchar *group;
-
- renderer = gcr_renderer_create (gcr_parser_get_parsed_label (parser),
- gcr_parser_get_parsed_attributes (parser));
- if (renderer == NULL)
- return;
-
- if (GCR_IS_CERTIFICATE (renderer))
- group = gcr_certificate_get_subject_part (GCR_CERTIFICATE (renderer), "O");
- else
- group = g_strdup (G_OBJECT_TYPE_NAME (renderer));
-
-
- testcol = test_collection_instance (group);
- if (!gcr_simple_collection_contains (collection, G_OBJECT (testcol)))
- gcr_simple_collection_add (collection, G_OBJECT (testcol));
-
- gcr_simple_collection_add (GCR_SIMPLE_COLLECTION (testcol), G_OBJECT (renderer));
- g_object_unref (renderer);
- g_object_unref (testcol);
- g_free (group);
-}
-
-static void
-add_to_selector (GcrParser *parser, const gchar *path)
-{
- GError *err = NULL;
- guchar *data;
- gsize n_data;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- if (!gcr_parser_parse_data (parser, data, n_data, &err))
- g_error ("couldn't parse data: %s", err->message);
-
- g_free (data);
-}
-
-int
-main (int argc, char *argv[])
-{
- GcrCollection *collection;
- GcrTreeSelector *selector;
- GtkDialog *dialog;
- GcrParser *parser;
- GtkWidget *scroll;
- GList *selected, *l;
- int i;
-
- gtk_init (&argc, &argv);
-
- dialog = GTK_DIALOG (gtk_dialog_new ());
- g_object_ref_sink (dialog);
-
- collection = gcr_simple_collection_new ();
- selector = gcr_tree_selector_new (collection, GCR_CERTIFICATE_COLUMNS);
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (selector));
- gtk_widget_show_all (scroll);
-
- gtk_widget_show (GTK_WIDGET (selector));
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (scroll), TRUE, TRUE, 0);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), collection);
-
- if (argc == 1) {
- add_to_selector (parser, SRCDIR "/files/ca-certificates.crt");
- } else {
- for (i = 1; i < argc; ++i)
- add_to_selector (parser, argv[i]);
- }
-
- g_object_unref (parser);
- g_object_unref (collection);
-
- gtk_dialog_run (dialog);
-
- selected = gcr_tree_selector_get_selected (selector);
- for (l = selected; l; l = g_list_next (l)) {
- gchar *label;
- g_object_get (l->data, "label", &label, NULL);
- g_print ("selected: %s\n", label);
- g_free (label);
- }
- g_list_free (selected);
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
- g_object_unref (dialog);
-
- return 0;
-}
diff --git a/gcr/tests/frob-unlock-options.c b/gcr/tests/frob-unlock-options.c
deleted file mode 100644
index fdcf116e..00000000
--- a/gcr/tests/frob-unlock-options.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2010 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static void
-test_unlock_options (void)
-{
- GcrUnlockOptionsWidget *unlock;
- GtkDialog *dialog;
-
- dialog = GTK_DIALOG (gtk_dialog_new ());
- g_object_ref_sink (dialog);
-
- unlock = GCR_UNLOCK_OPTIONS_WIDGET (gcr_unlock_options_widget_new ());
- gtk_widget_show (GTK_WIDGET (unlock));
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (unlock));
-
- gcr_unlock_options_widget_set_sensitive (unlock, GCR_UNLOCK_OPTION_IDLE, FALSE,
- "This is a test of the tooltip.");
- gcr_unlock_options_widget_set_sensitive (unlock, GCR_UNLOCK_OPTION_ALWAYS, TRUE, NULL);
- gcr_unlock_options_widget_set_label (unlock, GCR_UNLOCK_OPTION_IDLE, "Disabled label test");
- gcr_unlock_options_widget_set_ttl (unlock, 80);
- gcr_unlock_options_widget_set_choice (unlock, GCR_UNLOCK_OPTION_ALWAYS);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 400);
- gtk_dialog_run (dialog);
-
- g_printerr ("choice: %s\n",
- gcr_unlock_options_widget_get_choice (unlock));
-
- g_printerr ("ttl: %u\n",
- gcr_unlock_options_widget_get_ttl (unlock));
-
- g_printerr ("idle sensitive: %s\n",
- gcr_unlock_options_widget_get_sensitive (unlock, GCR_UNLOCK_OPTION_IDLE) ? "T" : "F");
-
- g_printerr ("always sensitive: %s\n",
- gcr_unlock_options_widget_get_sensitive (unlock, GCR_UNLOCK_OPTION_ALWAYS) ? "T" : "F");
-
- g_printerr ("label: %s\n",
- gcr_unlock_options_widget_get_label (unlock, GCR_UNLOCK_OPTION_ALWAYS));
-
- g_object_unref (dialog);
-}
-
-int
-main(int argc, char *argv[])
-{
- gtk_init (&argc, &argv);
- g_set_prgname ("frob-unlock-options");
-
- test_unlock_options ();
-
- return 0;
-}
diff --git a/gcr/tests/frob-unlock.c b/gcr/tests/frob-unlock.c
deleted file mode 100644
index b39f218f..00000000
--- a/gcr/tests/frob-unlock.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * gnome-keyring
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-#include "gcr/gcr-unlock-renderer.h"
-#include "gcr/gcr-viewer-window.h"
-
-#include <gtk/gtk.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static gboolean
-delete_event(GtkWidget *widget,
- GdkEvent *event,
- gpointer data)
-{
- gtk_main_quit ();
- return FALSE;
-}
-
-static void
-on_parser_parsed (GcrParser *parser, gpointer unused)
-{
-
-}
-
-static void
-on_parser_authenticate (GcrParser *parser,
- gint count,
- gpointer user_data)
-{
- GcrUnlockRenderer *renderer;
- GtkWindow *window;
-
- window = GTK_WINDOW (gcr_viewer_window_new ());
- g_object_ref_sink (window);
-
- renderer = _gcr_unlock_renderer_new_for_parsed (parser);
- gcr_viewer_add_renderer (GCR_VIEWER (window), GCR_RENDERER (renderer));
- g_object_unref (renderer);
-
- gtk_window_set_default_size (window, 550, 400);
- gtk_container_set_border_width (GTK_CONTAINER (window), 20);
-
- g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL);
- gtk_widget_show (GTK_WIDGET (window));
-
- gtk_main ();
-
- g_object_unref (window);
-
-}
-
-static void
-test_key (const gchar *path)
-{
- GcrParser *parser;
- GError *err = NULL;
- guchar *data;
- gsize n_data;
-
- if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
- g_error ("couldn't read file: %s", path);
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), NULL);
- g_signal_connect (parser, "authenticate", G_CALLBACK (on_parser_authenticate), NULL);
- if (!gcr_parser_parse_data (parser, data, n_data, &err))
- g_error ("couldn't parse data: %s", err->message);
-
- g_object_unref (parser);
- g_free (data);
-}
-
-int
-main(int argc, char *argv[])
-{
- gtk_init (&argc, &argv);
- g_set_prgname ("frob-unlock");
-
- if (argc > 1) {
- test_key (argv[1]);
- } else {
- test_key (SRCDIR "/files/email.p12");
- }
-
- return 0;
-}
diff --git a/gcr/tests/test-certificate-chain.c b/gcr/tests/test-certificate-chain.c
deleted file mode 100644
index 715bd495..00000000
--- a/gcr/tests/test-certificate-chain.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-testing.h"
-
-#include "gck/gck-mock.h"
-#include "gck/gck-test.h"
-
-#include "pkcs11/pkcs11.h"
-#include "pkcs11/pkcs11x.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-
-/* ---------------------------------------------------------------------------
- * A Mock certificate that checks that it's always called on the
- * same thread. A GcrCertificate implemented on top of a non-thread-safe
- * crypto library would require this behavior.
- */
-
-GType mock_certificate_get_type (void);
-
-#define MOCK_CERTIFICATE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), mock_certificate_get_type (), MockCertificate))
-
-typedef struct _MockCertificate {
- GObject parent;
- GThread *created_on;
- gpointer data;
- gsize n_data;
-} MockCertificate;
-
-typedef struct _MockCertificateClass {
- GObjectClass parent_class;
-} MockCertificateClass;
-
-static void mock_certificate_iface (GcrCertificateIface *iface);
-G_DEFINE_TYPE_WITH_CODE (MockCertificate, mock_certificate, G_TYPE_OBJECT,
- GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
- G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, mock_certificate_iface);
-);
-
-static void
-mock_certificate_init (MockCertificate *self)
-{
- self->created_on = g_thread_self ();
-}
-
-static void
-mock_certificate_finalize (GObject *obj)
-{
- MockCertificate *self = MOCK_CERTIFICATE (obj);
- g_assert (self->created_on == g_thread_self ());
- g_free (self->data);
- G_OBJECT_CLASS (mock_certificate_parent_class)->finalize (obj);
-}
-
-static void
-mock_certificate_class_init (MockCertificateClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = mock_certificate_finalize;
- gobject_class->get_property = gcr_certificate_mixin_get_property;
- gcr_certificate_mixin_class_init (gobject_class);
-}
-
-static gconstpointer
-mock_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
-{
- MockCertificate *self = MOCK_CERTIFICATE (base);
- g_assert (self->created_on == g_thread_self ());
- *n_data = self->n_data;
- return self->data;
-}
-
-static void
-mock_certificate_iface (GcrCertificateIface *iface)
-{
- iface->get_der_data = (gpointer)mock_certificate_real_get_der_data;
-}
-
-static GcrCertificate*
-mock_certificate_new (gconstpointer data, gsize n_data)
-{
- MockCertificate *self = g_object_new (mock_certificate_get_type (), NULL);
- self->data = g_memdup (data, n_data);
- self->n_data = n_data;
- g_assert (self->created_on == g_thread_self ());
- return GCR_CERTIFICATE (self);
-}
-
-/* ----------------------------------------------------------------------------
- * TESTS
- */
-
-typedef struct {
- GcrCertificate *cert_self;
- GcrCertificate *cert_ca;
- GcrCertificate *cert_signed;
- CK_FUNCTION_LIST funcs;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GList *modules = NULL;
- CK_FUNCTION_LIST_PTR f;
- gchar *contents;
- gsize n_contents;
- const gchar *uris[2];
- CK_RV rv;
- GckModule *module;
-
- rv = gck_mock_C_GetFunctionList (&f);
- gck_assert_cmprv (rv, ==, CKR_OK);
- memcpy (&test->funcs, f, sizeof (test->funcs));
-
- /* Open a session */
- rv = (test->funcs.C_Initialize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-
- g_assert (!modules);
- module = gck_module_new (&test->funcs);
- modules = g_list_prepend (modules, module);
- gcr_pkcs11_set_modules (modules);
- uris[0] = GCK_MOCK_SLOT_ONE_URI;
- uris[1] = NULL;
- gcr_pkcs11_set_trust_lookup_uris (uris);
- gcr_pkcs11_set_trust_store_uri (GCK_MOCK_SLOT_ONE_URI);
- gck_list_unref_free (modules);
-
- /* A self-signed certificate */
- if (!g_file_get_contents (SRCDIR "/files/der-certificate.crt", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->cert_self = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
- g_free (contents);
-
- /* A signed certificate */
- if (!g_file_get_contents (SRCDIR "/files/dhansak-collabora.cer", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->cert_signed = mock_certificate_new (contents, n_contents);
- g_free (contents);
-
- /* The signer for the above certificate */
- if (!g_file_get_contents (SRCDIR "/files/collabora-ca.cer", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->cert_ca = mock_certificate_new (contents, n_contents);
- g_free (contents);
-}
-
-static void
-add_certificate_to_module (GcrCertificate *certificate)
-{
- GckAttributes *attrs;
- gconstpointer data;
- gsize n_data, n_subject;
- gpointer subject;
-
- data = gcr_certificate_get_der_data (certificate, &n_data);
- g_assert (data);
-
- subject = gcr_certificate_get_subject_raw (certificate, &n_subject);
- g_assert (subject);
-
- /* Add a certificate to the module */
- attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_VALUE, data, n_data);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509);
- gck_attributes_add_data (attrs, CKA_SUBJECT, subject, n_subject);
- gck_mock_module_take_object (attrs);
-
- g_free (subject);
-}
-
-static void
-add_anchor_to_module (GcrCertificate *certificate, const gchar *purpose)
-{
- GckAttributes *attrs;
- gconstpointer data;
- gsize n_data;
-
- data = gcr_certificate_get_der_data (certificate, &n_data);
- g_assert (data);
-
- /* And add a pinned certificate for the signed certificate */
- attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, data, n_data);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION);
- gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
- gck_mock_module_take_object (attrs);
-}
-
-static void
-add_pinned_to_module (GcrCertificate *certificate, const gchar *purpose, const gchar *host)
-{
- GckAttributes *attrs;
- gconstpointer data;
- gsize n_data;
-
- data = gcr_certificate_get_der_data (certificate, &n_data);
- g_assert (data);
-
- /* And add a pinned certificate for the signed certificate */
- attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, data, n_data);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION);
- gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, CKT_X_PINNED_CERTIFICATE);
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose);
- gck_attributes_add_string (attrs, CKA_X_PEER, host);
- gck_mock_module_take_object (attrs);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- CK_RV rv;
-
- g_object_unref (test->cert_self);
- g_object_unref (test->cert_signed);
- g_object_unref (test->cert_ca);
-
- rv = (test->funcs.C_Finalize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-}
-
-static void
-test_new (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
-
- chain = gcr_certificate_chain_new ();
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 0);
-
- g_assert (gcr_certificate_chain_get_endpoint (chain) == NULL);
-
- g_object_unref (chain);
-}
-
-static void
-test_new_with_cert (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GcrCertificate *check;
- guint status, length;
-
- chain = gcr_certificate_chain_new ();
- gcr_certificate_chain_add (chain, test->cert_signed);
- gcr_certificate_chain_add (chain, test->cert_ca);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
-
- status = G_MAXUINT;
- length = 0;
- g_object_get (chain, "status", &status, "length", &length, NULL);
- g_assert_cmpuint (status, ==, GCR_CERTIFICATE_CHAIN_UNKNOWN);
- g_assert_cmpuint (length, ==, 2);
-
- check = gcr_certificate_chain_get_certificate (chain, 1);
- g_assert (check == test->cert_ca);
-
- /* Not yet completed */
- check = gcr_certificate_chain_get_anchor (chain);
- g_assert (check == NULL);
-
- check = gcr_certificate_chain_get_endpoint (chain);
- g_assert (check == test->cert_signed);
-
- g_object_unref (chain);
-}
-
-static void
-test_selfsigned (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Add a self-signed certificate */
- gcr_certificate_chain_add (chain, test->cert_self);
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_SELFSIGNED);
-
- g_object_unref (chain);
-}
-
-static void
-test_incomplete (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Add a signed certificate */
- gcr_certificate_chain_add (chain, test->cert_signed);
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_INCOMPLETE);
-
- g_object_unref (chain);
-}
-
-static void
-test_empty (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Add no certificate */
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
-
- g_object_unref (chain);
-}
-
-static void
-test_trim_extras (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Add two unrelated certificates */
- gcr_certificate_chain_add (chain, test->cert_self);
- gcr_certificate_chain_add (chain, test->cert_signed);
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_SELFSIGNED);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
-
- g_object_unref (chain);
-}
-
-static void
-fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- *((GAsyncResult**)user_data) = result;
- g_object_ref (result);
- egg_test_wait_stop ();
-}
-
-static void
-test_complete_async (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
- GAsyncResult *result = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Add a whole bunch of certificates */
- gcr_certificate_chain_add (chain, test->cert_signed);
- gcr_certificate_chain_add (chain, test->cert_ca);
- gcr_certificate_chain_add (chain, test->cert_self);
-
- gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- if (!gcr_certificate_chain_build_finish (chain, result, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
- g_object_unref (result);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_SELFSIGNED);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_anchor (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* Two certificates in chain with ca trust anchor */
- gcr_certificate_chain_add (chain, test->cert_signed);
- gcr_certificate_chain_add (chain, test->cert_ca);
- add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_ANCHORED);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
- g_assert (gcr_certificate_chain_get_anchor (chain) == test->cert_ca);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_anchor_and_lookup_ca (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* One signed certificate, with CA in pkcs11, and trust anchor */
- gcr_certificate_chain_add (chain, test->cert_signed);
- add_certificate_to_module (test->cert_ca);
- add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
-
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_ANCHORED);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
- g_assert (gcr_certificate_chain_get_anchor (chain) != NULL);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_pinned (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* One certificate, and add CA to pkcs11 */
- gcr_certificate_chain_add (chain, test->cert_signed);
- gcr_certificate_chain_add (chain, test->cert_ca);
- add_pinned_to_module (test->cert_signed, GCR_PURPOSE_CLIENT_AUTH, "pinned.example.com");
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
-
- /* But we don't allow the lookup to happen */
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- "pinned.example.com", 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_PINNED);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
- g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
-
- g_object_unref (chain);
-}
-
-static void
-test_without_lookups (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- chain = gcr_certificate_chain_new ();
-
- /* One certificate, and add CA to pkcs11 */
- gcr_certificate_chain_add (chain, test->cert_signed);
- add_certificate_to_module (test->cert_ca);
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
-
- /* But we don't allow the lookup to happen */
- if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, GCR_CERTIFICATE_CHAIN_NO_LOOKUPS,
- NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_INCOMPLETE);
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
- g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_lookup_error (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- /* Make the lookup fail */
- test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
-
- chain = gcr_certificate_chain_new ();
-
- /* Two certificates in chain with ca trust anchor */
- gcr_certificate_chain_add (chain, test->cert_signed);
- add_certificate_to_module (test->cert_ca);
-
- g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
-
- if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_clear_error (&error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_anchor_error (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
-
- /* Make the lookup fail */
- test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
-
- chain = gcr_certificate_chain_new ();
-
- /* Two certificates in chain with ca trust anchor */
- gcr_certificate_chain_add (chain, test->cert_signed);
- add_certificate_to_module (test->cert_ca);
-
- if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, &error))
- g_assert_not_reached ();
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_clear_error (&error);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
-
- g_object_unref (chain);
-}
-
-static void
-test_with_anchor_error_async (Test *test, gconstpointer unused)
-{
- GcrCertificateChain *chain;
- GError *error = NULL;
- GAsyncResult *result;
-
- /* Make the lookup fail */
- test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
-
- chain = gcr_certificate_chain_new ();
-
- /* Two certificates in chain with ca trust anchor */
- gcr_certificate_chain_add (chain, test->cert_signed);
- add_certificate_to_module (test->cert_ca);
-
- gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
- NULL, 0, NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- if (gcr_certificate_chain_build_finish (chain, result, &error))
- g_assert_not_reached ();
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_clear_error (&error);
- g_object_unref (result);
-
- g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
- GCR_CERTIFICATE_CHAIN_UNKNOWN);
-
- g_object_unref (chain);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-certificate-chain");
-
- g_test_add ("/gcr/certificate-chain/new", Test, NULL, setup, test_new, teardown);
- g_test_add ("/gcr/certificate-chain/new_with_cert", Test, NULL, setup, test_new_with_cert, teardown);
- g_test_add ("/gcr/certificate-chain/selfsigned", Test, NULL, setup, test_selfsigned, teardown);
- g_test_add ("/gcr/certificate-chain/incomplete", Test, NULL, setup, test_incomplete, teardown);
- g_test_add ("/gcr/certificate-chain/empty", Test, NULL, setup, test_empty, teardown);
- g_test_add ("/gcr/certificate-chain/trim_extras", Test, NULL, setup, test_trim_extras, teardown);
- g_test_add ("/gcr/certificate-chain/complete_async", Test, NULL, setup, test_complete_async, teardown);
- g_test_add ("/gcr/certificate-chain/with_anchor", Test, NULL, setup, test_with_anchor, teardown);
- g_test_add ("/gcr/certificate-chain/with_anchor_and_lookup_ca", Test, NULL, setup, test_with_anchor_and_lookup_ca, teardown);
- g_test_add ("/gcr/certificate-chain/with_pinned", Test, NULL, setup, test_with_pinned, teardown);
- g_test_add ("/gcr/certificate-chain/without_lookups", Test, NULL, setup, test_without_lookups, teardown);
- g_test_add ("/gcr/certificate-chain/with_lookup_error", Test, NULL, setup, test_with_lookup_error, teardown);
- g_test_add ("/gcr/certificate-chain/with_anchor_error", Test, NULL, setup, test_with_anchor_error, teardown);
- g_test_add ("/gcr/certificate-chain/with_anchor_error_async", Test, NULL, setup, test_with_anchor_error_async, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-certificate.c b/gcr/tests/test-certificate.c
deleted file mode 100644
index 6fb68c98..00000000
--- a/gcr/tests/test-certificate.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-
-typedef struct {
- GcrCertificate *certificate;
- GcrCertificate *dsa_cert;
- GcrCertificate *dhansak_cert;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- gchar *contents;
- gsize n_contents;
-
- if (!g_file_get_contents (SRCDIR "/files/der-certificate.crt", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->certificate = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
- g_assert (test->certificate);
- g_free (contents);
-
- if (!g_file_get_contents (SRCDIR "/files/der-certificate-dsa.cer", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->dsa_cert = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
- g_assert (test->dsa_cert);
- g_free (contents);
-
- if (!g_file_get_contents (SRCDIR "/files/dhansak-collabora.cer", &contents, &n_contents, NULL))
- g_assert_not_reached ();
- test->dhansak_cert = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
- g_assert (test->certificate);
- g_free (contents);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_object_unref (test->certificate);
- g_object_unref (test->dsa_cert);
- g_object_unref (test->dhansak_cert);
-}
-
-static void
-test_issuer_cn (Test *test, gconstpointer unused)
-{
- gchar *cn = gcr_certificate_get_issuer_cn (test->certificate);
- g_assert (cn);
- g_assert_cmpstr (cn, ==, "http://www.valicert.com/");
- g_free (cn);
-}
-
-static void
-test_issuer_dn (Test *test, gconstpointer unused)
-{
- gchar *dn = gcr_certificate_get_issuer_dn (test->certificate);
- g_assert (dn);
- g_assert_cmpstr (dn, ==, "L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 3 Policy Validation Authority, CN=http://www.valicert.com/, EMAIL=info@valicert.com");
- g_free (dn);
-}
-
-static void
-test_issuer_part (Test *test, gconstpointer unused)
-{
- gchar *part = gcr_certificate_get_issuer_part (test->certificate, "l");
- g_assert (part);
- g_assert_cmpstr (part, ==, "ValiCert Validation Network");
- g_free (part);
-}
-
-static void
-test_issuer_raw (Test *test, gconstpointer unused)
-{
- gpointer der;
- gsize n_der;
-
- der = gcr_certificate_get_issuer_raw (test->certificate, &n_der);
- g_assert (der);
- egg_assert_cmpsize (n_der, ==, 190);
- g_free (der);
-}
-
-static void
-test_subject_cn (Test *test, gconstpointer unused)
-{
- gchar *cn = gcr_certificate_get_subject_cn (test->certificate);
- g_assert (cn);
- g_assert_cmpstr (cn, ==, "http://www.valicert.com/");
- g_free (cn);
-
- cn = gcr_certificate_get_subject_cn (test->dhansak_cert);
- g_assert (cn);
- g_assert_cmpstr (cn, ==, "dhansak.collabora.co.uk");
- g_free (cn);
-}
-
-static void
-test_subject_dn (Test *test, gconstpointer unused)
-{
- gchar *dn = gcr_certificate_get_subject_dn (test->certificate);
- g_assert (dn);
- g_assert_cmpstr (dn, ==, "L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 3 Policy Validation Authority, CN=http://www.valicert.com/, EMAIL=info@valicert.com");
- g_free (dn);
-
- dn = gcr_certificate_get_subject_dn (test->dhansak_cert);
- g_assert (dn);
- g_assert_cmpstr (dn, ==, "CN=dhansak.collabora.co.uk, EMAIL=sysadmin@collabora.co.uk");
- g_free (dn);
-
-}
-
-static void
-test_subject_part (Test *test, gconstpointer unused)
-{
- gchar *part = gcr_certificate_get_subject_part (test->certificate, "OU");
- g_assert (part);
- g_assert_cmpstr (part, ==, "ValiCert Class 3 Policy Validation Authority");
- g_free (part);
-
- part = gcr_certificate_get_subject_part (test->dhansak_cert, "EMAIL");
- g_assert (part);
- g_assert_cmpstr (part, ==, "sysadmin@collabora.co.uk");
- g_free (part);
-
-}
-
-static void
-test_subject_raw (Test *test, gconstpointer unused)
-{
- gpointer der;
- gsize n_der;
-
- der = gcr_certificate_get_subject_raw (test->certificate, &n_der);
- g_assert (der);
- egg_assert_cmpsize (n_der, ==, 190);
- g_free (der);
-
- der = gcr_certificate_get_subject_raw (test->dhansak_cert, &n_der);
- g_assert (der);
- egg_assert_cmpsize (n_der, ==, 77);
- g_free (der);
-}
-
-static void
-test_issued_date (Test *test, gconstpointer unused)
-{
- GDate *date = gcr_certificate_get_issued_date (test->certificate);
- g_assert (date);
- g_assert_cmpuint (g_date_get_year (date), ==, 1999);
- g_assert_cmpuint (g_date_get_month (date), ==, 6);
- g_assert_cmpuint (g_date_get_day (date), ==, 26);
- g_date_free (date);
-}
-
-static void
-test_expiry_date (Test *test, gconstpointer unused)
-{
- GDate *date = gcr_certificate_get_expiry_date (test->certificate);
- g_assert (date);
- g_assert_cmpuint (g_date_get_year (date), ==, 2019);
- g_assert_cmpuint (g_date_get_month (date), ==, 6);
- g_assert_cmpuint (g_date_get_day (date), ==, 26);
- g_date_free (date);
-}
-
-static void
-test_serial_number (Test *test, gconstpointer unused)
-{
- gsize n_serial;
- guchar *serial;
- gchar *hex;
-
- serial = gcr_certificate_get_serial_number (test->certificate, &n_serial);
- g_assert (serial);
- g_assert_cmpuint (n_serial, ==, 1);
- g_assert (memcmp (serial, "\1", n_serial) == 0);
- g_free (serial);
-
- hex = gcr_certificate_get_serial_number_hex (test->certificate);
- g_assert (hex);
- g_assert_cmpstr (hex, ==, "01");
- g_free (hex);
-}
-
-static void
-test_fingerprint (Test *test, gconstpointer unused)
-{
- gsize n_print;
- guchar *print = gcr_certificate_get_fingerprint (test->certificate, G_CHECKSUM_MD5, &n_print);
- g_assert (print);
- g_assert_cmpuint (n_print, ==, g_checksum_type_get_length (G_CHECKSUM_MD5));
- g_assert (memcmp (print, "\xa2\x6f\x53\xb7\xee\x40\xdb\x4a\x68\xe7\xfa\x18\xd9\x10\x4b\x72", n_print) == 0);
- g_free (print);
-}
-
-static void
-test_fingerprint_hex (Test *test, gconstpointer unused)
-{
- gchar *print = gcr_certificate_get_fingerprint_hex (test->certificate, G_CHECKSUM_MD5);
- g_assert (print);
- g_assert_cmpstr (print, ==, "A2 6F 53 B7 EE 40 DB 4A 68 E7 FA 18 D9 10 4B 72");
- g_free (print);
-}
-
-static void
-test_certificate_key_size (Test *test, gconstpointer unused)
-{
- guint key_size = gcr_certificate_get_key_size (test->certificate);
- g_assert_cmpuint (key_size, ==, 1024);
-
- key_size = gcr_certificate_get_key_size (test->dsa_cert);
- g_assert_cmpuint (key_size, ==, 1024);
-}
-
-static void
-test_certificate_is_issuer (Test *test, gconstpointer unused)
-{
- gboolean ret = gcr_certificate_is_issuer (test->certificate, test->certificate);
- g_assert (ret == TRUE);
-
- ret = gcr_certificate_is_issuer (test->certificate, test->dsa_cert);
- g_assert (ret == FALSE);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-certificate");
-
- g_test_add ("/gcr/certificate/issuer_cn", Test, NULL, setup, test_issuer_cn, teardown);
- g_test_add ("/gcr/certificate/issuer_dn", Test, NULL, setup, test_issuer_dn, teardown);
- g_test_add ("/gcr/certificate/issuer_part", Test, NULL, setup, test_issuer_part, teardown);
- g_test_add ("/gcr/certificate/issuer_raw", Test, NULL, setup, test_issuer_raw, teardown);
- g_test_add ("/gcr/certificate/subject_cn", Test, NULL, setup, test_subject_cn, teardown);
- g_test_add ("/gcr/certificate/subject_dn", Test, NULL, setup, test_subject_dn, teardown);
- g_test_add ("/gcr/certificate/subject_part", Test, NULL, setup, test_subject_part, teardown);
- g_test_add ("/gcr/certificate/subject_raw", Test, NULL, setup, test_subject_raw, teardown);
- g_test_add ("/gcr/certificate/issued_date", Test, NULL, setup, test_issued_date, teardown);
- g_test_add ("/gcr/certificate/expiry_date", Test, NULL, setup, test_expiry_date, teardown);
- g_test_add ("/gcr/certificate/serial_number", Test, NULL, setup, test_serial_number, teardown);
- g_test_add ("/gcr/certificate/fingerprint", Test, NULL, setup, test_fingerprint, teardown);
- g_test_add ("/gcr/certificate/fingerprint_hex", Test, NULL, setup, test_fingerprint_hex, teardown);
- g_test_add ("/gcr/certificate/certificate_key_size", Test, NULL, setup, test_certificate_key_size, teardown);
- g_test_add ("/gcr/certificate/certificate_is_issuer", Test, NULL, setup, test_certificate_is_issuer, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-fingerprint.c b/gcr/tests/test-fingerprint.c
deleted file mode 100644
index 0270758b..00000000
--- a/gcr/tests/test-fingerprint.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-#define GCR_COMPILATION 1
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-#include "gcr/gcr-fingerprint.h"
-
-#include "gck/gck-test.h"
-
-#include "pkcs11/pkcs11n.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-
-typedef struct {
- gpointer cert_rsa;
- gsize n_cert_rsa;
- gpointer key_rsa;
- gsize n_key_rsa;
- gpointer cert_dsa;
- gsize n_cert_dsa;
- gpointer key_dsa;
- gsize n_key_dsa;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
-
- g_file_get_contents (SRCDIR "/files/client.crt", (gchar**)&test->cert_rsa,
- &test->n_cert_rsa, &error);
- g_assert_no_error (error);
- g_assert (test->cert_rsa);
-
- g_file_get_contents (SRCDIR "/files/client.key", (gchar**)&test->key_rsa,
- &test->n_key_rsa, &error);
- g_assert_no_error (error);
- g_assert (test->key_rsa);
-
- g_file_get_contents (SRCDIR "/files/generic-dsa.crt", (gchar**)&test->cert_dsa,
- &test->n_cert_dsa, &error);
- g_assert_no_error (error);
- g_assert (test->cert_dsa);
-
- g_file_get_contents (SRCDIR "/files/generic-dsa.key", (gchar**)&test->key_dsa,
- &test->n_key_dsa, &error);
- g_assert_no_error (error);
- g_assert (test->key_dsa);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_free (test->cert_rsa);
- g_free (test->key_rsa);
- g_free (test->cert_dsa);
- g_free (test->key_dsa);
-}
-
-static void
-on_parser_parsed (GcrParser *parser,
- gpointer user_data)
-{
- GckAttributes **attrs = user_data;
- g_assert (!*attrs);
- *attrs = gcr_parser_get_parsed_attributes (parser);
- g_assert (*attrs);
- gck_attributes_ref (*attrs);
-}
-
-static GckAttributes*
-parse_attributes_for_key (gpointer data, gsize n_data)
-{
- GcrParser *parser;
- GckAttributes *attrs = NULL;
- GError *error = NULL;
-
- parser = gcr_parser_new ();
- g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), &attrs);
- gcr_parser_parse_data (parser, data, n_data, &error);
- g_assert_no_error (error);
- g_object_unref (parser);
-
- g_assert (attrs);
- return attrs;
-}
-
-static GckAttributes *
-build_attributes_for_cert (guchar *data,
- gsize n_data)
-{
- GckAttributes *attrs;
-
- attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_VALUE, data, n_data);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509);
-
- return attrs;
-}
-
-static gconstpointer
-parse_subject_public_key_info_for_cert (gpointer data, gsize n_data, gsize *n_info)
-{
- gconstpointer info;
- GNode *asn;
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- g_assert (asn);
-
- info = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", NULL), n_info);
- g_assert (info);
-
- egg_asn1x_destroy (asn);
- return info;
-}
-
-static void
-test_rsa (Test *test, gconstpointer unused)
-{
- GckAttributes *key, *cert;
- gconstpointer info;
- gsize n_info;
- guchar *fingerprint1, *fingerprint2, *fingerprint3;
- gsize n_fingerprint1, n_fingerprint2, n_fingerprint3;
-
- key = parse_attributes_for_key (test->key_rsa, test->n_key_rsa);
- info = parse_subject_public_key_info_for_cert (test->cert_rsa, test->n_cert_rsa, &n_info);
- cert = build_attributes_for_cert (test->cert_rsa, test->n_cert_rsa);
-
- fingerprint1 = gcr_fingerprint_from_subject_public_key_info (info, n_info, G_CHECKSUM_SHA1, &n_fingerprint1);
- fingerprint2 = gcr_fingerprint_from_attributes (key, G_CHECKSUM_SHA1, &n_fingerprint2);
- fingerprint3 = gcr_fingerprint_from_attributes (cert, G_CHECKSUM_SHA1, &n_fingerprint3);
-
- egg_assert_cmpmem (fingerprint1, n_fingerprint1, ==, fingerprint2, n_fingerprint2);
- egg_assert_cmpmem (fingerprint1, n_fingerprint1, ==, fingerprint3, n_fingerprint3);
-
- g_free (fingerprint1);
- g_free (fingerprint2);
- g_free (fingerprint3);
-
- gck_attributes_unref (key);
- gck_attributes_unref (cert);
-}
-
-static void
-test_dsa (Test *test, gconstpointer unused)
-{
- GckAttributes *key, *cert;
- gconstpointer info;
- gsize n_info;
- guchar *fingerprint1, *fingerprint2, *fingerprint3;
- gsize n_fingerprint1, n_fingerprint2, n_fingerprint3;
-
- key = parse_attributes_for_key (test->key_dsa, test->n_key_dsa);
- info = parse_subject_public_key_info_for_cert (test->cert_dsa, test->n_cert_dsa, &n_info);
- cert = build_attributes_for_cert (test->cert_dsa, test->n_cert_dsa);
-
- fingerprint1 = gcr_fingerprint_from_subject_public_key_info (info, n_info, G_CHECKSUM_SHA1, &n_fingerprint1);
- fingerprint2 = gcr_fingerprint_from_attributes (key, G_CHECKSUM_SHA1, &n_fingerprint2);
- fingerprint3 = gcr_fingerprint_from_attributes (cert, G_CHECKSUM_SHA1, &n_fingerprint3);
-
- egg_assert_cmpmem (fingerprint1, n_fingerprint1, ==, fingerprint2, n_fingerprint2);
- egg_assert_cmpmem (fingerprint1, n_fingerprint1, ==, fingerprint3, n_fingerprint3);
-
- g_free (fingerprint1);
- g_free (fingerprint2);
- g_free (fingerprint3);
-
- gck_attributes_unref (key);
- gck_attributes_unref (cert);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
-
- g_test_add ("/gcr/fingerprint/rsa", Test, NULL, setup, test_rsa, teardown);
- g_test_add ("/gcr/fingerprint/dsa", Test, NULL, setup, test_dsa, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-gnupg-collection.c b/gcr/tests/test-gnupg-collection.c
deleted file mode 100644
index c8304a78..00000000
--- a/gcr/tests/test-gnupg-collection.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-gnupg-collection.h"
-#include "gcr/gcr-gnupg-key.h"
-#include "gcr/gcr-record.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-
-typedef struct {
- GcrGnupgCollection *collection;
- gchar *directory;
- GHashTable *keys;
- GAsyncResult *result;
-} Test;
-
-static void
-on_collection_added (GcrCollection *collection, GObject *object, gpointer user_data)
-{
- Test *test = user_data;
- GcrGnupgKey *key;
- const gchar *keyid;
-
- g_assert (GCR_COLLECTION (test->collection) == collection);
-
- g_assert (GCR_IS_GNUPG_KEY (object));
- key = GCR_GNUPG_KEY (object);
-
- keyid = _gcr_gnupg_key_get_keyid (key);
- g_assert (keyid);
- g_assert (!g_hash_table_lookup (test->keys, keyid));
-
- g_hash_table_insert (test->keys, g_strdup (keyid), key);
-}
-
-static void
-on_collection_removed (GcrCollection *collection, GObject *object, gpointer user_data)
-{
- Test *test = user_data;
- GcrGnupgKey *key;
- const gchar *keyid;
-
- g_assert (GCR_COLLECTION (test->collection) == collection);
- g_assert (GCR_IS_GNUPG_KEY (object));
-
- keyid = _gcr_gnupg_key_get_keyid (GCR_GNUPG_KEY (object));
- key = g_hash_table_lookup (test->keys, keyid);
- g_assert (key == GCR_GNUPG_KEY (object));
-
- if (!g_hash_table_remove (test->keys, keyid))
- g_assert_not_reached ();
-}
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GcrCollection *collection;
-
- test->directory = g_build_filename (SRCDIR, "files", "gnupg-homedir", NULL);
-
- collection = _gcr_gnupg_collection_new (test->directory);
- test->collection = GCR_GNUPG_COLLECTION (collection);
-
- test->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- g_signal_connect (collection, "added", G_CALLBACK (on_collection_added), test);
- g_signal_connect (collection, "removed", G_CALLBACK (on_collection_removed), test);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_hash_table_destroy (test->keys);
-
- if (test->result)
- g_object_unref (test->result);
-
- g_object_unref (test->collection);
- g_free (test->directory);
-}
-
-static void
-on_async_ready (GObject *source, GAsyncResult *res, gpointer user_data)
-{
- Test *test = user_data;
- g_assert (G_OBJECT (test->collection) == source);
- g_assert (test->result == NULL);
- test->result = g_object_ref (res);
- egg_test_wait_stop ();
-}
-
-static void
-test_properties (Test *test, gconstpointer unused)
-{
- gchar *directory;
- g_object_get (test->collection, "directory", &directory, NULL);
- g_assert_cmpstr (directory, ==, test->directory);
- g_free (directory);
-}
-
-static void
-test_load (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GcrGnupgKey *key;
- GList *l, *objects;
- GcrRecord *record;
- GHashTable *check;
-
- _gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
- egg_test_wait_until (500000);
-
- g_assert (test->result);
- _gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
- g_assert_no_error (error);
-
- /* Werner Koch (a public key) */
- key = g_hash_table_lookup (test->keys, "5DE249965B0358A2");
- g_assert (GCR_IS_GNUPG_KEY (key));
- g_assert (_gcr_gnupg_key_get_secret_records (key) == NULL);
-
- /* Test Number 2 (a secret key)*/
- key = g_hash_table_lookup (test->keys, "268FEE686262C395");
- g_assert (GCR_IS_GNUPG_KEY (key));
- g_assert (_gcr_gnupg_key_get_secret_records (key));
-
- /* The length of collection should be correct */
- g_assert_cmpuint (g_hash_table_size (test->keys), ==,
- gcr_collection_get_length (GCR_COLLECTION (test->collection)));
-
- /* The list of objects should be correct */
- objects = gcr_collection_get_objects (GCR_COLLECTION (test->collection));
- g_assert_cmpuint (g_hash_table_size (test->keys), ==, g_list_length (objects));
- check = g_hash_table_new (g_str_hash, g_str_equal);
- for (l = objects; l != NULL; l = g_list_next (l)) {
- g_assert (GCR_IS_GNUPG_KEY (l->data));
- key = g_hash_table_lookup (test->keys, _gcr_gnupg_key_get_keyid (l->data));
- g_assert (key == l->data);
- g_hash_table_replace (check, (gchar*)_gcr_gnupg_key_get_keyid (l->data), "");
- }
- g_assert_cmpuint (g_hash_table_size (check), ==, g_hash_table_size (test->keys));
- g_hash_table_destroy (check);
- g_list_free (objects);
-
- /* Phillip R. Zimmerman's key should have a photo */
- key = g_hash_table_lookup (test->keys, "C7463639B2D7795E");
- g_assert (GCR_IS_GNUPG_KEY (key));
- record = _gcr_records_find (_gcr_gnupg_key_get_public_records (key), GCR_RECORD_SCHEMA_XA1);
- g_assert (record);
-}
-
-static void
-test_reload (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GcrGnupgKey *key;
-
- _gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
- egg_test_wait_until (500);
- g_assert (test->result);
- _gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
- g_assert_no_error (error);
-
- g_object_unref (test->result);
- test->result = NULL;
-
- _gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
- egg_test_wait_until (500000);
- g_assert (test->result);
- _gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
- g_assert_no_error (error);
-
- /* Werner Koch (a public key) */
- key = g_hash_table_lookup (test->keys, "5DE249965B0358A2");
- g_assert (GCR_IS_GNUPG_KEY (key));
- g_assert (_gcr_gnupg_key_get_secret_records (key) == NULL);
-
- /* Test Number 2 (a secret key)*/
- key = g_hash_table_lookup (test->keys, "268FEE686262C395");
- g_assert (GCR_IS_GNUPG_KEY (key));
- g_assert (_gcr_gnupg_key_get_secret_records (key));
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-gnupg-collection");
-
- g_test_add ("/gcr/gnupg-collection/properties", Test, NULL, setup, test_properties, teardown);
- g_test_add ("/gcr/gnupg-collection/load", Test, NULL, setup, test_load, teardown);
- g_test_add ("/gcr/gnupg-collection/reload", Test, NULL, setup, test_reload, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-gnupg-key.c b/gcr/tests/test-gnupg-key.c
deleted file mode 100644
index 59008041..00000000
--- a/gcr/tests/test-gnupg-key.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-record.h"
-#include "gcr/gcr-gnupg-key.h"
-#include "gcr/gcr-gnupg-records.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef struct {
- GPtrArray *records;
- GPtrArray *pubset;
- GPtrArray *secset;
- GcrGnupgKey *key;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GPtrArray *records;
-
- records = g_ptr_array_new_with_free_func (_gcr_record_free);
- g_ptr_array_add (records, _gcr_record_parse_colons ("pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:f::::::::Werner Koch <wk@g10code.com>:\n", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:f::::::::Werner Koch <wk@gnupg.org>:\n", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("sub:f:1536:16:06AD222CADF6A6E1:919537416:1036177416:::::e:\n", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("fpr:::::::::CF8BCC4B18DE08FCD8A1615906AD222CADF6A6E1:\n", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc:\n", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4:", -1));
- test->records = records;
-
- test->key = _gcr_gnupg_key_new (records, NULL);
-
- records = g_ptr_array_new_with_free_func (_gcr_record_free);
- g_ptr_array_add (records, _gcr_record_parse_colons ("pub:u:2048:1:4842D952AFC000FD:1305189489:::u:::scESC:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:u::::1305189849::D0A8FA7B15DC4BE3F8F03A49C372F2718C78AFC0::Dr. Strangelove <lovingbomb@example.com>:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:u::::1305189489::D449F1605254754B0BBFA424FC34E50609103BBB::Test Number 1 (unlimited) <test-number-1@example.com>:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("sub:u:2048:1:4852132BBED15014:1305189489::::::e:", -1));
- test->pubset = records;
-
- records = g_ptr_array_new_with_free_func (_gcr_record_free);
- g_ptr_array_add (records, _gcr_record_parse_colons ("sec::2048:1:4842D952AFC000FD:1305189489::::::::::", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:::::::D449F1605254754B0BBFA424FC34E50609103BBB::Test Number 1 (unlimited) <test-number-1@example.com>:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("uid:::::::D0A8FA7B15DC4BE3F8F03A49C372F2718C78AFC0::Dr. Strangelove <lovingbomb@example.com>:", -1));
- g_ptr_array_add (records, _gcr_record_parse_colons ("ssb::2048:1:4852132BBED15014:1305189489::::::::::", -1));
- test->secset = records;
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_object_unref (test->key);
- g_assert (!GCR_IS_GNUPG_KEY (test->key));
-
- g_ptr_array_unref (test->records);
- g_ptr_array_unref (test->pubset);
- g_ptr_array_unref (test->secset);
-}
-
-static void
-test_label (Test *test, gconstpointer unused)
-{
- gchar *label;
-
- g_object_get (test->key, "label", &label, NULL);
- g_assert_cmpstr (label, ==, "Werner Koch <wk@g10code.com>");
-
- g_free (label);
-}
-
-static void
-test_markup (Test *test, gconstpointer unused)
-{
- gchar *markup;
-
- g_object_get (test->key, "markup", &markup, NULL);
- g_assert_cmpstr (markup, ==, "Werner Koch\n<small>wk@g10code.com</small>");
-
- g_free (markup);
-}
-
-static void
-test_description (Test *test, gconstpointer unused)
-{
- gchar *description;
-
- g_object_get (test->key, "description", &description, NULL);
- g_assert_cmpstr (description, ==, "PGP Key");
-
- g_free (description);
-}
-
-static void
-test_records (Test *test, gconstpointer unused)
-{
- GPtrArray *records;
-
- g_object_get (test->key, "public-records", &records, NULL);
- g_assert (records == test->records);
-
- _gcr_gnupg_key_set_public_records (test->key, records);
- g_assert (records == _gcr_gnupg_key_get_public_records (test->key));
-
- g_ptr_array_unref (records);
-}
-
-static void
-test_keyid (Test *test, gconstpointer unused)
-{
- gchar *keyid;
-
- g_object_get (test->key, "keyid", &keyid, NULL);
- g_assert_cmpstr (keyid, ==, "6C7EE1B8621CC013");
-
- g_free (keyid);
-
- g_assert_cmpstr (_gcr_gnupg_key_get_keyid (test->key), ==, "6C7EE1B8621CC013");
-}
-
-static void
-test_short_keyid (Test *test, gconstpointer unused)
-{
- gchar *keyid;
-
- g_object_get (test->key, "short-keyid", &keyid, NULL);
- g_assert_cmpstr (keyid, ==, "621CC013");
-
- g_free (keyid);
-}
-
-static void
-test_keyid_for_records (Test *test, gconstpointer unused)
-{
- const gchar *keyid;
-
- keyid = _gcr_gnupg_records_get_keyid (test->records);
- g_assert_cmpstr (keyid, ==, "6C7EE1B8621CC013");
-}
-
-static void
-test_with_secret (Test *test, gconstpointer unused)
-{
- GcrGnupgKey *key;
- GPtrArray *secset;
-
- key = _gcr_gnupg_key_new (test->pubset, test->secset);
- g_assert (GCR_IS_GNUPG_KEY (key));
-
- g_object_get (key, "secret-records", &secset, NULL);
- g_assert (secset == _gcr_gnupg_key_get_secret_records (key));
- g_object_set (key, "secret-records", secset, NULL);
-
- g_object_unref (key);
-}
-
-static void
-test_no_change_keyid (Test *test, gconstpointer unused)
-{
- if (g_test_trap_fork (50000, G_TEST_TRAP_SILENCE_STDERR)) {
- /* Changing the keyid. This should fail with a warning */
- _gcr_gnupg_key_set_public_records (test->key, test->pubset);
- exit (0);
- }
-
- g_test_trap_assert_failed ();
- g_test_trap_assert_stderr ("*fingerprint is no longer the same:*");
-}
-
-static void
-test_secret_mismatched_keyid (Test *test, gconstpointer unused)
-{
- if (g_test_trap_fork (50000, G_TEST_TRAP_SILENCE_STDERR)) {
- /* Different keyid for secret part. This should fail with a warning */
- _gcr_gnupg_key_set_secret_records (test->key, test->secset);
- exit (0);
- }
-
- g_test_trap_assert_failed ();
- g_test_trap_assert_stderr ("*pub and sec parts are not the same:*");
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
-
- g_test_add ("/gcr/gnupg-key/label", Test, NULL, setup, test_label, teardown);
- g_test_add ("/gcr/gnupg-key/description", Test, NULL, setup, test_description, teardown);
- g_test_add ("/gcr/gnupg-key/markup", Test, NULL, setup, test_markup, teardown);
- g_test_add ("/gcr/gnupg-key/records", Test, NULL, setup, test_records, teardown);
- g_test_add ("/gcr/gnupg-key/keyid", Test, NULL, setup, test_keyid, teardown);
- g_test_add ("/gcr/gnupg-key/short_keyid", Test, NULL, setup, test_short_keyid, teardown);
- g_test_add ("/gcr/gnupg-key/keyid_for_records", Test, NULL, setup, test_keyid_for_records, teardown);
- g_test_add ("/gcr/gnupg-key/with_secret", Test, NULL, setup, test_with_secret, teardown);
- g_test_add ("/gcr/gnupg-key/no_change_keyid", Test, NULL, setup, test_no_change_keyid, teardown);
- g_test_add ("/gcr/gnupg-key/secret_mismatched_keyid", Test, NULL, setup, test_secret_mismatched_keyid, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-gnupg-process.c b/gcr/tests/test-gnupg-process.c
deleted file mode 100644
index 740b2329..00000000
--- a/gcr/tests/test-gnupg-process.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-callback-output-stream.h"
-#include "gcr/gcr-gnupg-process.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-
-#define WAIT 50000
-
-typedef struct {
- GcrGnupgProcess *process;
- GAsyncResult *result;
- GString *output_buf;
- GString *error_buf;
- GString *attribute_buf;
- GcrRecord *record;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- test->output_buf = g_string_new ("");
- test->error_buf = g_string_new ("");
- test->attribute_buf = g_string_new ("");
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_assert (!test->result);
- g_assert (!test->process);
- if (test->output_buf)
- g_string_free (test->output_buf, TRUE);
- if (test->error_buf)
- g_string_free (test->error_buf, TRUE);
- if (test->attribute_buf)
- g_string_free (test->attribute_buf, TRUE);
- _gcr_record_free (test->record);
-}
-
-static void
-test_create (Test *test, gconstpointer unused)
-{
- gchar *value;
-
- test->process = _gcr_gnupg_process_new ("/the/directory", "/path/to/executable");
-
- g_object_get (test->process, "directory", &value, NULL);
- g_assert_cmpstr (value, ==, "/the/directory");
- g_free (value);
-
- g_object_get (test->process, "executable", &value, NULL);
- g_assert_cmpstr (value, ==, "/path/to/executable");
- g_free (value);
-
- g_clear_object (&test->process);
-}
-
-static void
-on_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- Test *test = user_data;
-
- g_assert (G_OBJECT (test->process) == source);
- g_assert (test->result == NULL);
- g_assert (g_async_result_get_source_object (result) == source);
-
- test->result = g_object_ref (result);
- egg_test_wait_stop ();
-}
-
-static gchar*
-build_script_path (const gchar *name)
-{
- gchar *path;
-
- path = g_build_filename (SRCDIR, "files", "gnupg-mock", name, NULL);
-
- return path;
-}
-
-static gssize
-on_process_output_data (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error)
-{
- Test *test = user_data;
- g_string_append_len (test->output_buf, buffer, count);
- return count;
-}
-
-static gssize
-on_process_attribute_data (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error)
-{
- Test *test = user_data;
- g_string_append_len (test->attribute_buf, buffer, count);
- return count;
-}
-
-static void
-on_process_error_line (GcrGnupgProcess *process, const gchar *line, gpointer user_data)
-{
- Test *test = user_data;
-
- g_assert (process == test->process);
- g_assert (line);
- g_assert (!strchr (line, '\n'));
-
- g_string_append_printf (test->error_buf, "%s\n", line);
-}
-
-static void
-on_process_status_record (GcrGnupgProcess *process, GcrRecord *record, gpointer user_data)
-{
- Test *test = user_data;
-
- g_assert (process == test->process);
- g_assert (record);
-
- g_assert (!test->record);
- test->record = _gcr_record_copy (record);
-}
-
-static void
-test_run_simple_output (Test *test, gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- GOutputStream *output;
- GError *error = NULL;
- gboolean ret;
- gchar *script;
-
- script = build_script_path ("mock-simple-output");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- output = _gcr_callback_output_stream_new (on_process_output_data, test, NULL);
- _gcr_gnupg_process_set_output_stream (test->process, output);
- g_object_unref (output);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert_cmpstr ("simple-output\n", ==, test->output_buf->str);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_simple_error (Test *test, gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- GError *error = NULL;
- gchar *script;
- gboolean ret;
-
- script = build_script_path ("mock-simple-error");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- g_signal_connect (test->process, "error-line", G_CALLBACK (on_process_error_line), test);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert_cmpstr ("line 1: more line 1\nline 2\nline 3\n", ==, test->error_buf->str);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_status_and_output (Test *test, gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- GOutputStream *output;
- GError *error = NULL;
- gchar *script;
- gboolean ret;
-
- script = build_script_path ("mock-status-and-output");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- output = _gcr_callback_output_stream_new (on_process_output_data, test, NULL);
- _gcr_gnupg_process_set_output_stream (test->process, output);
- g_object_unref (output);
-
- g_signal_connect (test->process, "status-record", G_CALLBACK (on_process_status_record), test);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, GCR_GNUPG_PROCESS_WITH_STATUS,
- NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert (test->record);
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 0), ==, "SCHEMA");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 1), ==, "one");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 2), ==, "two");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 3), ==, "three");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 4), ==, "four");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 5), ==, NULL);
- g_assert_cmpstr ("Here's some output\nMore output\n", ==, test->output_buf->str);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_status_and_attribute (Test *test, gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- GOutputStream *output;
- GError *error = NULL;
- gchar *script;
- gboolean ret;
-
- script = build_script_path ("mock-status-and-attribute");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- output = _gcr_callback_output_stream_new (on_process_attribute_data, test, NULL);
- _gcr_gnupg_process_set_attribute_stream (test->process, output);
- g_object_unref (output);
-
- g_signal_connect (test->process, "status-record", G_CALLBACK (on_process_status_record), test);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL,
- GCR_GNUPG_PROCESS_WITH_STATUS | GCR_GNUPG_PROCESS_WITH_ATTRIBUTES,
- NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert (test->record);
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 0), ==, "SCHEMA");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 1), ==, "one");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 2), ==, "two");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 3), ==, "three");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 4), ==, "four");
- g_assert_cmpstr (_gcr_record_get_raw (test->record, 5), ==, NULL);
- g_assert_cmpstr ("1lc923g4laoeurc23rc241lcg2r23c4gr3", ==, test->attribute_buf->str);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-
-static void
-test_run_arguments_and_environment (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GOutputStream *output;
- gchar *script;
- gboolean ret;
-
- const gchar *argv[] = {
- "-1", "value1",
- "-2", "value2",
- NULL
- };
-
- const gchar *envp[] = {
- "ENVIRON1=VALUE1",
- "ENVIRON2=VALUE2",
- NULL
- };
-
- script = build_script_path ("mock-arguments-environ");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- output = _gcr_callback_output_stream_new (on_process_output_data, test, NULL);
- _gcr_gnupg_process_set_output_stream (test->process, output);
- g_object_unref (output);
-
- g_signal_connect (test->process, "error-line", G_CALLBACK (on_process_error_line), test);
-
- _gcr_gnupg_process_run_async (test->process, argv, envp, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- if (error) {
- g_printerr ("%s\n", test->error_buf->str);
- g_assert_no_error (error);
- }
- g_assert (ret == TRUE);
-
- g_assert_cmpstr ("value1\nvalue2\n", ==, test->output_buf->str);
- g_assert_cmpstr ("VALUE1VALUE2\n", ==, test->error_buf->str);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_with_homedir (Test *test, gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- GOutputStream *output;
- GError *error = NULL;
- gchar *script;
- gchar *check;
- gboolean ret;
-
- script = build_script_path ("mock-with-homedir");
- test->process = _gcr_gnupg_process_new (SRCDIR, script);
- g_free (script);
-
- output = _gcr_callback_output_stream_new (on_process_output_data, test, NULL);
- _gcr_gnupg_process_set_output_stream (test->process, output);
- g_object_unref (output);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- check = g_strdup_printf ("DIR: %s\n", SRCDIR);
- g_assert_cmpstr (check, ==, test->output_buf->str);
- g_free (check);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_with_input_and_output (Test *test,
- gconstpointer unused)
-{
- const gchar *argv[] = { NULL };
- const gchar *data = "one\ntwenty two\nthree\nfourty four\n";
- GInputStream *input;
- GOutputStream *output;
- GError *error = NULL;
- GString *string;
- gchar *script;
- gboolean ret;
-
- script = build_script_path ("mock-echo");
- test->process = _gcr_gnupg_process_new (SRCDIR, script);
- g_free (script);
-
- input = g_memory_input_stream_new_from_data ((gpointer)data, -1, NULL);
- output = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
-
- _gcr_gnupg_process_set_input_stream (test->process, input);
- _gcr_gnupg_process_set_output_stream (test->process, output);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- string = g_string_new_len (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (output)),
- g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (output)));
- g_assert_cmpstr (data, ==, string->str);
- g_string_free (string, TRUE);
-
- g_clear_object (&input);
- g_clear_object (&output);
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-
-}
-
-static void
-test_run_bad_executable (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gchar *script;
- const gchar *argv[] = { NULL };
- gboolean ret;
-
- script = build_script_path ("mock-invalid");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT);
- g_clear_error (&error);
- g_assert (ret == FALSE);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_fail_exit (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gchar *script;
- const gchar *argv[] = { "55" };
- gboolean ret;
-
- script = build_script_path ("mock-fail-exit");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED);
- g_assert_cmpstr (error->message, ==, "Gnupg process exited with code: 55");
- g_clear_error (&error);
- g_assert (ret == FALSE);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_fail_signal (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gchar *script;
- const gchar *argv[] = { "15" };
- gboolean ret;
-
- script = build_script_path ("mock-fail-signal");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, NULL, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED);
- g_assert_cmpstr (error->message, ==, "Gnupg process was terminated with signal: 15");
- g_clear_error (&error);
- g_assert (ret == FALSE);
-
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static void
-test_run_and_cancel (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gchar *script;
- const gchar *argv[] = { "15" };
- GCancellable *cancellable;
- gboolean ret;
-
- cancellable = g_cancellable_new ();
-
- script = build_script_path ("mock-simple-output");
- test->process = _gcr_gnupg_process_new (NULL, script);
- g_free (script);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, cancellable, on_async_ready, test);
- g_cancellable_cancel (cancellable);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&error);
- g_assert (ret == FALSE);
-
- g_object_unref (cancellable);
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-static gssize
-on_process_output_cancel (gconstpointer buffer,
- gsize count,
- GCancellable *cancellable,
- gpointer user_data,
- GError **error)
-{
- g_cancellable_cancel (cancellable);
- g_cancellable_set_error_if_cancelled (cancellable, error);
- return -1;
-}
-
-static void
-test_run_and_cancel_later (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GOutputStream *output;
- gchar *script;
- const gchar *argv[] = { "15" };
- GCancellable *cancellable;
- gboolean ret;
-
- cancellable = g_cancellable_new ();
-
- script = build_script_path ("mock-simple-output");
- test->process = _gcr_gnupg_process_new (NULL, script);
- output = _gcr_callback_output_stream_new (on_process_output_cancel, NULL, NULL);
- _gcr_gnupg_process_set_output_stream (test->process, output);
- g_object_unref (output);
- g_free (script);
-
- _gcr_gnupg_process_run_async (test->process, argv, NULL, 0, cancellable, on_async_ready, test);
- egg_test_wait_until (WAIT);
-
- g_assert (test->result);
- ret = _gcr_gnupg_process_run_finish (test->process, test->result, &error);
- g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_clear_error (&error);
- g_assert (ret == FALSE);
-
- g_object_unref (cancellable);
- g_clear_object (&test->result);
- g_clear_object (&test->process);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-gnupg-process");
-
- g_test_add ("/gcr/gnupg-process/create", Test, NULL, setup, test_create, teardown);
- g_test_add ("/gcr/gnupg-process/run_simple_output", Test, NULL, setup, test_run_simple_output, teardown);
- g_test_add ("/gcr/gnupg-process/run_simple_error", Test, NULL, setup, test_run_simple_error, teardown);
- g_test_add ("/gcr/gnupg-process/run_status_and_output", Test, NULL, setup, test_run_status_and_output, teardown);
- g_test_add ("/gcr/gnupg-process/run_status_and_attribute", Test, NULL, setup, test_run_status_and_attribute, teardown);
- g_test_add ("/gcr/gnupg-process/run_arguments_and_environment", Test, NULL, setup, test_run_arguments_and_environment, teardown);
- g_test_add ("/gcr/gnupg-process/run_with_homedir", Test, NULL, setup, test_run_with_homedir, teardown);
- g_test_add ("/gcr/gnupg-process/run_with_input_and_output", Test, NULL, setup, test_run_with_input_and_output, teardown);
- g_test_add ("/gcr/gnupg-process/run_bad_executable", Test, NULL, setup, test_run_bad_executable, teardown);
- g_test_add ("/gcr/gnupg-process/run_fail_exit", Test, NULL, setup, test_run_fail_exit, teardown);
- g_test_add ("/gcr/gnupg-process/run_fail_signal", Test, NULL, setup, test_run_fail_signal, teardown);
- g_test_add ("/gcr/gnupg-process/run_and_cancel", Test, NULL, setup, test_run_and_cancel, teardown);
- g_test_add ("/gcr/gnupg-process/run_and_cancel_later", Test, NULL, setup, test_run_and_cancel_later, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-memory-icon.c b/gcr/tests/test-memory-icon.c
deleted file mode 100644
index c232be19..00000000
--- a/gcr/tests/test-memory-icon.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-memory-icon.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef struct {
- GIcon *icon;
- GAsyncResult *result;
-} Test;
-
-static const guint8 test_data[256] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
- 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
-};
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- test->icon = _gcr_memory_icon_new ("application/octet-stream",
- test_data, sizeof (test_data));
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_object_unref (test->icon);
- if (test->result)
- g_object_unref (test->result);
-}
-
-static void
-test_equal_same (Test *test, gconstpointer unused)
-{
- g_assert (g_icon_equal (test->icon, test->icon) == TRUE);
-}
-
-static void
-test_equal_not (Test *test, gconstpointer unused)
-{
- GIcon *icon;
-
- icon = g_themed_icon_new ("folder");
- g_assert (g_icon_equal (test->icon, icon) == FALSE);
- g_object_unref (icon);
-}
-
-static void
-test_equal_data (Test *test, gconstpointer unused)
-{
- GIcon *icon;
-
- icon = _gcr_memory_icon_new ("application/octet-stream",
- test_data, sizeof (test_data));
- g_assert (g_icon_equal (test->icon, icon) == TRUE);
- g_assert_cmpuint (g_icon_hash (test->icon), ==, g_icon_hash (icon));
- g_object_unref (icon);
-}
-
-static void
-test_different_type (Test *test, gconstpointer unused)
-{
- GIcon *icon;
-
- icon = _gcr_memory_icon_new ("application/x-other",
- test_data, sizeof (test_data));
- g_assert (g_icon_equal (test->icon, icon) == FALSE);
- g_assert_cmpuint (g_icon_hash (test->icon), !=, g_icon_hash (icon));
- g_object_unref (icon);
-}
-
-static void
-test_different_offset (Test *test, gconstpointer unused)
-{
- GIcon *icon;
-
- icon = _gcr_memory_icon_new_full ("application/octet-stream", (gpointer)test_data,
- sizeof (test_data) - 16, 16, NULL);
- g_assert (g_icon_equal (test->icon, icon) == FALSE);
- g_assert_cmpuint (g_icon_hash (test->icon), !=, g_icon_hash (icon));
- g_object_unref (icon);
-}
-
-static void
-test_load_sync (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GInputStream *is;
- gchar buf[1024];
- gsize length;
- gchar *type;
-
- is = g_loadable_icon_load (G_LOADABLE_ICON (test->icon), 0, &type, NULL, &error);
- g_assert (is != NULL);
- g_assert_no_error (error);
- g_assert_cmpstr (type, ==, "application/octet-stream");
-
- if (!g_input_stream_read_all (is, buf, sizeof (buf), &length, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
- egg_assert_cmpsize (length, ==, sizeof (test_data));
- egg_assert_cmpmem (buf, length, ==, test_data, sizeof (test_data));
-
- g_free (type);
- g_object_unref (is);
-}
-
-static void
-on_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- Test *test = user_data;
-
- g_assert (G_OBJECT (test->icon) == source);
- g_assert (test->result == NULL);
- g_assert (g_async_result_get_source_object (result) == source);
-
- test->result = g_object_ref (result);
- egg_test_wait_stop ();
-}
-
-static void
-test_load_async (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GInputStream *is;
- gchar buf[1024];
- gsize length;
- gchar *type;
-
- g_loadable_icon_load_async (G_LOADABLE_ICON (test->icon), 0, NULL, on_async_ready, test);
- egg_test_wait_until (500);
-
- g_assert (test->result);
- is = g_loadable_icon_load_finish (G_LOADABLE_ICON (test->icon), test->result, &type, &error);
- g_assert (is != NULL);
- g_assert_no_error (error);
- g_assert_cmpstr (type, ==, "application/octet-stream");
-
- if (!g_input_stream_read_all (is, buf, sizeof (buf), &length, NULL, &error))
- g_assert_not_reached ();
- g_assert_no_error (error);
- egg_assert_cmpsize (length, ==, sizeof (test_data));
- egg_assert_cmpmem (buf, length, ==, test_data, sizeof (test_data));
-
- g_free (type);
- g_object_unref (is);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
-
- g_test_add ("/gcr/memory-icon/equal_same", Test, NULL, setup, test_equal_same, teardown);
- g_test_add ("/gcr/memory-icon/equal_not", Test, NULL, setup, test_equal_not, teardown);
- g_test_add ("/gcr/memory-icon/equal_data", Test, NULL, setup, test_equal_data, teardown);
- g_test_add ("/gcr/memory-icon/different_type", Test, NULL, setup, test_different_type, teardown);
- g_test_add ("/gcr/memory-icon/different_offset", Test, NULL, setup, test_different_offset, teardown);
- g_test_add ("/gcr/memory-icon/load_sync", Test, NULL, setup, test_load_sync, teardown);
- g_test_add ("/gcr/memory-icon/load_async", Test, NULL, setup, test_load_async, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-openpgp.c b/gcr/tests/test-openpgp.c
deleted file mode 100644
index be41f407..00000000
--- a/gcr/tests/test-openpgp.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-#include "gcr/gcr-openpgp.h"
-#include "gcr/gcr-record.h"
-
-#include "egg/egg-armor.h"
-#include "egg/egg-testing.h"
-
-#include <gcrypt.h>
-#include <glib.h>
-#include <string.h>
-
-typedef struct {
- const gchar *name;
- const gchar **records;
- const gchar *filename;
- const gchar *version;
- GcrOpenpgpParseFlags flags;
-} Fixture;
-
-static const gchar *werner_koch_records[] = {
- "pub:e:1024:17:68B7AB8957548DCD:899816990:1136043547::o:::sca:\n"
- "fpr:::::::::6BD9050FD8FC941B43412DCC68B7AB8957548DCD:\n"
- "uid:e::::1102866526::B712A25DC2ABEF1579696C2925859931078C2C3E::Werner Koch (gnupg sig) <dd9jn@gnu.org>:\n",
-
- "pub:e:1024:17:5DE249965B0358A2:921520361:1247335656::o:::sc:\n"
- "fpr:::::::::A4D94E92B0986AB5EE9DCD755DE249965B0358A2:\n"
- "uid:e::::1113145458::F5B5738FAFB7543A01BAB31A6D767FBC789FF8A8::Werner Koch <wk@gnupg.org>:\n"
- "uid:e::::1113145466::60095F7DAD08129CCE39E15BEB6BBE21937E3AA6::Werner Koch <wk@g10code.com>:\n"
- "uid:e::::921520362::392B892CF897AD0F03EB26343C4C20A48B36513E::Werner Koch:\n"
- "uid:e::::1113145466::3E000C0F7D13A3C57C633C16ABDC97F12EAF16C1::Werner Koch <werner@fsfe.org>:\n"
- "sub:e:1024:17:60784E94010A57ED:1079892559:1199124559:::::s:\n"
- "sub:e:2048:1:7299C628B604F148:1079892777:1136052777:::::e:\n"
- "sub:e:2048:1:35E52D69C3680A6E:1136137762:1199123362:::::e:\n",
-
- "pub:e:1024:1:53B620D01CE0C630:1136130759:1230738759::o:::sc:\n"
- "fpr:::::::::7B96D396E6471601754BE4DB53B620D01CE0C630:\n"
- "uid:e::::1136130760::142B958D9816ECF810DBB83BD257E5C7DB36C99A::Werner Koch (dist sig) <dd9jn@gnu.org>:\n",
-
- NULL
-};
-
-static const gchar *werner_sig_records[] = {
- "pub:e:1024:17:68B7AB8957548DCD:899816990:1136043547::o:::sca:\n"
- "fpr:::::::::6BD9050FD8FC941B43412DCC68B7AB8957548DCD:\n"
- "uid:e::::1102866526::B712A25DC2ABEF1579696C2925859931078C2C3E::Werner Koch (gnupg sig) <dd9jn@gnu.org>:\n"
- "sig:::17:68B7AB8957548DCD:1102866526:::::13x:\n",
-
- "pub:e:1024:17:5DE249965B0358A2:921520361:1247335656::o:::sc:\n"
- "fpr:::::::::A4D94E92B0986AB5EE9DCD755DE249965B0358A2:\n"
- "uid:e::::1113145458::F5B5738FAFB7543A01BAB31A6D767FBC789FF8A8::Werner Koch <wk@gnupg.org>:\n"
- "sig:::17:5DE249965B0358A2:1113145458:::::13x:\n"
- "uid:e::::1113145466::60095F7DAD08129CCE39E15BEB6BBE21937E3AA6::Werner Koch <wk@g10code.com>:\n"
- "sig:::17:5DE249965B0358A2:1113145466:::::13x:\n"
- "uid:e::::921520362::392B892CF897AD0F03EB26343C4C20A48B36513E::Werner Koch:\n"
- "sig:::17:5DE249965B0358A2:921520362:::::13x:\n"
- "uid:e::::1113145466::3E000C0F7D13A3C57C633C16ABDC97F12EAF16C1::Werner Koch <werner@fsfe.org>:\n"
- "sig:::17:5DE249965B0358A2:1113145466:::::13x:\n"
- "sub:e:1024:17:60784E94010A57ED:1079892559:1199124559:::::s:\n"
- "sig:::17:5DE249965B0358A2:1148562461:::::18x:\n"
- "sub:e:2048:1:7299C628B604F148:1079892777:1136052777:::::e:\n"
- "sig:::17:5DE249965B0358A2:1079892777:::::18x:\n"
- "sub:e:2048:1:35E52D69C3680A6E:1136137762:1199123362:::::e:\n"
- "sig:::17:5DE249965B0358A2:1136137762:::::18x:\n",
-
- "pub:e:1024:1:53B620D01CE0C630:1136130759:1230738759::o:::sc:\n"
- "fpr:::::::::7B96D396E6471601754BE4DB53B620D01CE0C630:\n"
- "uid:e::::1136130760::142B958D9816ECF810DBB83BD257E5C7DB36C99A::Werner Koch (dist sig) <dd9jn@gnu.org>:\n"
- "sig:::1:53B620D01CE0C630:1136130760:::::13x:\n",
-
- NULL
-};
-
-static const gchar *pubring_records[] = {
- "pub:o:2048:1:4842D952AFC000FD:1305189489:::o:::scSCE:\n"
- "fpr:::::::::61A6EA3E0115080227A32EC94842D952AFC000FD:\n"
- "uid:o::::1305189489::D449F1605254754B0BBFA424FC34E50609103BBB::Test Number 1 (unlimited) <test-number-1@example.com>:\n"
- "uid:o::::1305189849::D0A8FA7B15DC4BE3F8F03A49C372F2718C78AFC0::Dr. Strangelove <lovingbomb@example.com>:\n"
- "sub:o:2048:1:4852132BBED15014:1305189489::::::e:\n",
-
- "pub:e:1024:1:268FEE686262C395:1305189628:1305276028::o:::sc:\n"
- "fpr:::::::::A4853C22EA82C8ADC6692751268FEE686262C395:\n"
- "uid:e::::1305189628::2E9D48BD771DA765D2B48A0233D0E8F393F6E839::Test Number 2 (all gone) <test-number-2@example.com>:\n"
- "sub:e:1024:1:C5877FABF4772E4F:1305189628:1305276028:::::e:\n",
-
- "pub:e:1024:17:68B7AB8957548DCD:899816990:1136043547::o:::sca:\n"
- "fpr:::::::::6BD9050FD8FC941B43412DCC68B7AB8957548DCD:\n"
- "uid:e::::1102866526::B712A25DC2ABEF1579696C2925859931078C2C3E::Werner Koch (gnupg sig) <dd9jn@gnu.org>:\n",
-
- "pub:e:1024:17:5DE249965B0358A2:921520361:1247335656::o:::sc:\n"
- "fpr:::::::::A4D94E92B0986AB5EE9DCD755DE249965B0358A2:\n"
- "uid:e::::1113145458::F5B5738FAFB7543A01BAB31A6D767FBC789FF8A8::Werner Koch <wk@gnupg.org>:\n"
- "uid:e::::1113145466::60095F7DAD08129CCE39E15BEB6BBE21937E3AA6::Werner Koch <wk@g10code.com>:\n"
- "uid:e::::921520362::392B892CF897AD0F03EB26343C4C20A48B36513E::Werner Koch:\n"
- "uid:e::::1113145466::3E000C0F7D13A3C57C633C16ABDC97F12EAF16C1::Werner Koch <werner@fsfe.org>:\n"
- "sub:e:1024:17:60784E94010A57ED:1079892559:1199124559:::::s:\n"
- "sub:e:2048:1:7299C628B604F148:1079892777:1136052777:::::e:\n"
- "sub:e:2048:1:35E52D69C3680A6E:1136137762:1199123362:::::e:\n",
-
- "pub:o:1024:17:C7463639B2D7795E:978642983:::o:::scSCE:\n"
- "fpr:::::::::055FC78F112193492C4F37AFC7463639B2D7795E:\n"
- "rvk:o::17::::::3FC732041D23E9EA66DDB5009C9DBC21DF74DC61:80:\n"
- "uid:o::::978642983::44C6F00AAE524A8955CAB76F2BB16126530BB203::Philip R. Zimmermann <prz@mit.edu>:\n"
- "uid:o::::978643127::BD93DF0D0D564E85F73ECBECFFB1B5BA5FF2838D::Philip R. Zimmermann <prz@acm.org>:\n"
- "uat:o::::978751266::E0F87F37495D4ED247BB66A08D7360D8D81F9976::1 3391:\n"
- "uat:o::::1013326898::10A2C49F62C540090ECD679C518AACAA8E960BA5::1 3479:\n"
- "uid:o::::1052692250::09D1F68A1C44AC42E7FCC5615EEDBB0FD581DCDE::Philip R. Zimmermann <prz@philzimmermann.com>:\n"
- "sub:o:3072:16:C4EB1C56A8E92834:978642983::::::e:\n",
-
- "pub:o:4096:1:DB698D7199242560:1012189561:::o:::scSCEA:\n"
- "fpr:::::::::7D92FD313AB6F3734CC59CA1DB698D7199242560:\n"
- "uid:o::::1012189561::0E5FC22DD5518890217F20F1FF832597932B46C1::David M. Shaw <dshaw@jabberwocky.com>:\n"
- "sub:o:2048:16:AE2827D11643B926:1012189956:1327549956:::::e:\n"
- "sub:o:1024:17:E2665C8749E1CBC9:1012190171:1327550171:::::sca:\n",
-
- "pub:o:2048:1:9710B89BCA57AD7C:1102303986:::o:::scSC:\n"
- "fpr:::::::::50BB6FFC9719DFD2BEBB04C69710B89BCA57AD7C:\n"
- "uid:o::::1112650864::A96F758EFD5D67EA9450860C7D15A96DAA1B40E2::PGP Global Directory Verification Key:\n"
- "uat:o::::1112650864::83B0B68B95892BBCE32F04BA0FBAC6CEAD4EDE49::1 3422:\n",
-
- "pub:e:1024:1:53B620D01CE0C630:1136130759:1230738759::o:::sc:\n"
- "fpr:::::::::7B96D396E6471601754BE4DB53B620D01CE0C630:\n"
- "uid:e::::1136130760::142B958D9816ECF810DBB83BD257E5C7DB36C99A::Werner Koch (dist sig) <dd9jn@gnu.org>:\n",
-
- NULL
-};
-
-static const gchar *secring_records[] = {
- "sec::2048:1:4842D952AFC000FD:1305189489::::::::::\n"
- "fpr:::::::::61A6EA3E0115080227A32EC94842D952AFC000FD:\n"
- "uid:::::::D449F1605254754B0BBFA424FC34E50609103BBB::Test Number 1 (unlimited) <test-number-1@example.com>:\n"
- "uid:::::::D0A8FA7B15DC4BE3F8F03A49C372F2718C78AFC0::Dr. Strangelove <lovingbomb@example.com>:\n"
- "ssb::2048:1:4852132BBED15014:1305189489::::::::::\n",
-
- "sec::1024:1:268FEE686262C395:1305189628:1305276028:::::::::\n"
- "fpr:::::::::A4853C22EA82C8ADC6692751268FEE686262C395:\n"
- "uid:::::::2E9D48BD771DA765D2B48A0233D0E8F393F6E839::Test Number 2 (all gone) <test-number-2@example.com>:\n"
- "ssb::1024:1:C5877FABF4772E4F:1305189628::::::::::\n",
-
- NULL
-};
-
-static Fixture fixtures[] = {
- {
- "werner_koch",
- werner_koch_records,
- SRCDIR "/files/werner-koch.asc",
- "GnuPG v1.4.11 (GNU/Linux)",
- GCR_OPENPGP_PARSE_KEYS
- },
- {
- "werner_koch_with_sigs",
- werner_sig_records,
- SRCDIR "/files/werner-koch.asc",
- "GnuPG v1.4.11 (GNU/Linux)",
- GCR_OPENPGP_PARSE_KEYS | GCR_OPENPGP_PARSE_SIGNATURES
- },
- {
- "pubring",
- pubring_records,
- SRCDIR "/files/pubring.gpg",
- NULL,
- GCR_OPENPGP_PARSE_KEYS
- },
- {
- "secring",
- secring_records,
- SRCDIR "/files/secring.gpg",
- NULL,
- GCR_OPENPGP_PARSE_KEYS
- }
-};
-
-typedef struct {
- const gchar **at;
- const Fixture *fixture;
-} Test;
-
-static void
-setup (Test *test,
- gconstpointer data)
-{
- const Fixture *fixture = data;
- test->fixture = fixture;
- test->at = fixture->records;
-}
-
-static void
-teardown (Test *test,
- gconstpointer data)
-{
-
-}
-
-static void
-compare_fixture_with_records (const gchar *fixture,
- GPtrArray *records)
-{
- gchar *record;
- gchar **lines;
- guint i;
-
- lines = g_strsplit (fixture, "\n", -1);
- for (i = 0; i < records->len; i++) {
- record = _gcr_record_format (records->pdata[i]);
- g_assert_cmpstr (record, ==, lines[i]);
- g_free (record);
- }
-
- if (lines[i] == NULL) {
- g_test_message ("more openpgp records parsed than in fixture");
- g_assert_not_reached ();
- }
-
- g_strfreev (lines);
-}
-
-static void
-on_openpgp_packet (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
- gpointer user_data)
-{
- Test *test = user_data;
- guint seen;
-
- /* Should be parseable again */
- seen = _gcr_openpgp_parse (outer, n_outer, test->fixture->flags |
- GCR_OPENPGP_PARSE_NO_RECORDS, NULL, NULL);
- g_assert_cmpuint (seen, ==, 1);
-
- if (*(test->at) == NULL) {
- g_test_message ("more openpgp packets parsed than in fixture");
- g_assert_not_reached ();
- }
-
- compare_fixture_with_records (*(test->at), records);
- test->at++;
-}
-
-static void
-on_armor_parsed (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
- GHashTable *headers,
- gpointer user_data)
-{
- Test *test = user_data;
- const gchar *value;
- guint seen;
-
- if (test->fixture->version) {
- value = g_hash_table_lookup (headers, "Version");
- g_assert_cmpstr (value, ==, test->fixture->version);
- }
-
- seen = _gcr_openpgp_parse (data, n_data, test->fixture->flags,
- on_openpgp_packet, test);
- g_assert_cmpuint (seen, >, 0);
-
- if (*(test->at) != NULL) {
- g_test_message ("less openpgp packets parsed than in fixture");
- g_assert_not_reached ();
- }
-}
-
-static void
-test_openpgp_armor (Test *test,
- gconstpointer data)
-{
- GError *error = NULL;
- gchar *armor;
- gsize length;
- guint parts;
-
- g_file_get_contents (test->fixture->filename, &armor, &length, &error);
- g_assert_no_error (error);
-
- parts = egg_armor_parse (armor, length, on_armor_parsed, test);
- g_assert_cmpuint (parts, ==, 1);
-
- g_free (armor);
-}
-
-static void
-test_openpgp_binary (Test *test,
- gconstpointer data)
-{
- GError *error = NULL;
- gchar *binary;
- gsize length;
- guint seen;
-
- g_file_get_contents (test->fixture->filename, &binary, &length, &error);
- g_assert_no_error (error);
-
- seen = _gcr_openpgp_parse (binary, length, test->fixture->flags,
- on_openpgp_packet, test);
- g_assert_cmpuint (seen, >, 0);
-
- if (*(test->at) != NULL) {
- g_test_message ("less openpgp packets parsed than in fixture");
- g_assert_not_reached ();
- }
-
- g_free (binary);
-}
-
-int
-main (int argc, char **argv)
-{
- guint i;
- gchar *test_path;
-
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-openpgp");
-
- for (i = 0; i < G_N_ELEMENTS (fixtures); i++) {
- test_path = g_strdup_printf ("/gcr/openpgp/%s", fixtures[i].name);
- if (g_str_has_suffix (fixtures[i].filename, ".asc"))
- g_test_add (test_path, Test, fixtures + i, setup, test_openpgp_armor, teardown);
- else
- g_test_add (test_path, Test, fixtures + i, setup, test_openpgp_binary, teardown);
- g_free (test_path);
- }
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-openssh.c b/gcr/tests/test-openssh.c
deleted file mode 100644
index 81634daf..00000000
--- a/gcr/tests/test-openssh.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-#include "gcr/gcr-openssh.h"
-
-#include "egg/egg-testing.h"
-
-#include <gcrypt.h>
-#include <glib.h>
-#include <string.h>
-
-typedef struct {
- const gchar *expected_label;
- const gchar *expected_options;
-} Test;
-
-#define OPENSSH_PUBLIC_RSA1 \
- "2048 65537 19574029774826276058535216798260123376543523095248321838931" \
- "8476099051534660565418100376122247153936738716140984293302866595208305" \
- "7124376564328644357957081508003798389808113087527047927841196160520784" \
- "3971799891833860159372766201922902824211581515042106928142039998651198" \
- "7806024885997262427984841536983221992403267030558391252672804492615887" \
- "9294713324466630490990131504557923061505441555447586185019409756877006" \
- "5871190731807718592844942425524851665039303855329966512492845780563670" \
- "0617451083369174928502647995734856960603065454655489558179113130210712" \
- "74638931037011169213563881172297734240201883475566393175838117784693 r" \
- "sa-key@example.com\n"
-
-#define OPENSSH_PUBLIC_RSA2 \
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCs8z2y0cCPYRAPkq8tAt6FC/kdfnR/p" \
- "8B2ZoY0oiLNt7kQEwJfexgwLqTxWYd2fSDUSSDPrsqAxZAwLLS/eF04kXiJO2VfqAWFpTL" \
- "NToERHpFF1yZQe26ELTlNNfna7LqfCRvpNDwu6AqndsT3eFt7DWvBDXbbEiTLW21Z2OFAA" \
- "H/J2iCFn4c0a8Myf7IaMYcy5GG3mpk39kEO4aNV/67U7kfooek24ObwD0vlXzlsi5VZIUF" \
- "OIUi0UdkNEMCtUWpfkZ1STUlmwp9HVM7xb7/9PESQKDnZdxpB09S9cIjdpDecpDlMDDEbE" \
- "UECM1PIas3ndhB7gAN1i2JsPHTcXZ1 rsa-key@example.com\r\n" \
- "# Comment\n"
-
-#define OPENSSH_PUBLIC_DSA2 \
- "ssh-dss AAAAB3NzaC1kc3MAAACBAL4z+ad0ZJYzMOQuGp00UJ+AijKhrPVUEYLcxBmFQo" \
- "nb/KIlLSWJua4Rl9DB4tDj30Y9c/oApqC4n+FIYlUZMSnxmpvcLF6aeXOiHHPvm0EDYjjy" \
- "VubyYQWI7CROrrzSc+x++ha3TuJEvF3PlKlZmTKKVYEkZNjwFqYysGyPxPalAAAAFQDtDS" \
- "EF9Gvnv5fQtSbbsp7j78uVBwAAAIAtNpAg/Mbd/E2241enedB9AxAbJWZ5QYnoPe6/zx5d" \
- "OmU7+qz8mG6tgvF8F7IgXPabuAKslzTDGS3zgaEhWicDS3CIYik2UR8hXdxfovIEqZKZe7" \
- "u02FCEoXYCEiFUAdzDGzjI7PswgtEJWWNqKeNis3HmDDha9lMkqz/3fLZGXwAAAIEAiaRP" \
- "YKZDMoJG+aVZ5A3R/m2gl+mYE2MsjPKXuBKcrZ6ItA9BMe4G/An0/+E3A+DuoGxdeNNMF8" \
- "U9Dy2N8Sch/Ngtg2E/FBo5geljWobJXd1jxmPtF2WAliYJXDdIt6RBVPGL9H/KSjDmBMsV" \
- "d42wxVJywawzypklVZjSUuWuBMI= dsa-key@example.com \n"
-
-#define EXTRA_LINES_WITHOUT_KEY \
- "\n# Comment\n\n" \
- "20aa3\n" \
- "not a key\n"
-
-static void
-setup (Test *test,
- gconstpointer unused)
-{
-
-}
-
-static void
-teardown (Test *test,
- gconstpointer unused)
-{
-
-}
-
-static void
-on_openssh_pub_parse (GckAttributes *attrs,
- const gchar *label,
- const gchar *options,
- const gchar *outer,
- gsize n_outer,
- gpointer user_data)
-{
- Test *test = user_data;
- guint keys;
-
- if (test->expected_label)
- g_assert_cmpstr (label, ==, test->expected_label);
- if (test->expected_options)
- g_assert_cmpstr (options, ==, test->expected_options);
-
- /* The block should parse properly */
- keys = _gcr_openssh_pub_parse (outer, n_outer, NULL, NULL);
- g_assert_cmpuint (keys, ==, 1);
-}
-
-static void
-test_parse_v1_rsa (Test *test,
- gconstpointer unused)
-{
- const gchar *data = OPENSSH_PUBLIC_RSA1 EXTRA_LINES_WITHOUT_KEY;
- gint keys;
-
- test->expected_label = "rsa-key@example.com";
-
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
- g_assert_cmpint (keys, ==, 1);
-
-}
-
-static void
-test_parse_v2_rsa (Test *test,
- gconstpointer unused)
-{
- const gchar *data = OPENSSH_PUBLIC_RSA2 EXTRA_LINES_WITHOUT_KEY;
- gint keys;
-
- test->expected_label = "rsa-key@example.com";
-
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
- g_assert_cmpint (keys, ==, 1);
-}
-
-static void
-test_parse_v2_dsa (Test *test,
- gconstpointer unused)
-{
- const gchar *data = OPENSSH_PUBLIC_DSA2 EXTRA_LINES_WITHOUT_KEY;
- gint keys;
-
- test->expected_label = "dsa-key@example.com";
-
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
- g_assert_cmpint (keys, ==, 1);
-}
-
-static void
-test_parse_v1_options (Test *test,
- gconstpointer unused)
-{
- const gchar *data = "option1,option2=\"value 2\",option3 " OPENSSH_PUBLIC_RSA1;
- gint keys;
-
- test->expected_options = "option1,option2=\"value 2\",option3";
-
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
- g_assert_cmpint (keys, ==, 1);
-}
-
-static void
-test_parse_v2_options (Test *test,
- gconstpointer unused)
-{
- const gchar *data = "option1,option2=\"value 2\",option3 " OPENSSH_PUBLIC_RSA2;
- gint keys;
-
- test->expected_options = "option1,option2=\"value 2\",option3";
-
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
- g_assert_cmpint (keys, ==, 1);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-gnupg-process");
-
- g_test_add ("/gcr/openssh/parse_v1_rsa", Test, NULL, setup, test_parse_v1_rsa, teardown);
- g_test_add ("/gcr/openssh/parse_v2_rsa", Test, NULL, setup, test_parse_v2_rsa, teardown);
- g_test_add ("/gcr/openssh/parse_v2_dsa", Test, NULL, setup, test_parse_v2_dsa, teardown);
- g_test_add ("/gcr/openssh/parse_v1_options", Test, NULL, setup, test_parse_v1_options, teardown);
- g_test_add ("/gcr/openssh/parse_v2_options", Test, NULL, setup, test_parse_v2_options, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-parser.c b/gcr/tests/test-parser.c
deleted file mode 100644
index 6984be29..00000000
--- a/gcr/tests/test-parser.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* unit-test-pkix-parser.c: Test PKIX parser
-
- Copyright (C) 2007 Stefan Walter
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stef@memberwebs.com>
-*/
-
-#include "config.h"
-
-#include "egg/egg-error.h"
-#include "egg/egg-secure-memory.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "gck/gck.h"
-
-#include <glib.h>
-#include <gcrypt.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- * Each test looks like (on one line):
- * void unit_test_xxxxx (CuTest* cu)
- *
- * Each setup looks like (on one line):
- * void unit_setup_xxxxx (void);
- *
- * Each teardown looks like (on one line):
- * void unit_teardown_xxxxx (void);
- *
- * Tests be run in the order specified here.
- */
-
-typedef struct {
- GcrParser *parser;
- const gchar* filedesc;
-} Test;
-
-static void
-ensure_block_can_be_parsed (GcrDataFormat format,
- gconstpointer block,
- gsize n_block)
-{
- GcrParser *parser;
- gboolean result;
- GError *error = NULL;
-
- g_assert (block);
- g_assert (n_block);
-
- parser = gcr_parser_new ();
- gcr_parser_format_disable (parser, -1);
- gcr_parser_format_enable (parser, format);
- result = gcr_parser_parse_data (parser, block, n_block, &error);
-
- if (!result) {
- g_critical ("The data returned from gcr_parser_get_parsed_block() "
- "cannot be parsed: %s", error->message);
- g_assert_not_reached ();
- }
-
- g_object_unref (parser);
-}
-
-static void
-parsed_item (GcrParser *par, gpointer user_data)
-{
- GckAttributes *attrs;
- const gchar *description;
- const gchar *label;
- Test *test = user_data;
- gconstpointer block;
- gsize n_block;
- GcrDataFormat format;
-
- g_assert (GCR_IS_PARSER (par));
- g_assert (par == test->parser);
-
- attrs = gcr_parser_get_parsed_attributes (test->parser);
- g_assert (attrs);
-
- description = gcr_parser_get_parsed_description (test->parser);
- label = gcr_parser_get_parsed_label (test->parser);
- block = gcr_parser_get_parsed_block (test->parser, &n_block);
- format = gcr_parser_get_parsed_format (test->parser);
- ensure_block_can_be_parsed (format, block, n_block);
-
- if (g_test_verbose ())
- g_print ("%s: '%s'\n", description, label);
-}
-
-static gboolean
-authenticate (GcrParser *par, gint state, gpointer user_data)
-{
- Test *test = user_data;
-
- g_assert (GCR_IS_PARSER (par));
- g_assert (par == test->parser);
-
- switch (state) {
- case 0:
- gcr_parser_add_password (test->parser, "booo");
- return TRUE;
- default:
- g_printerr ("decryption didn't work for: %s", test->filedesc);
- g_assert_not_reached ();
- return FALSE;
- };
-}
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- test->parser = gcr_parser_new ();
- g_signal_connect (test->parser, "parsed", G_CALLBACK (parsed_item), test);
- g_signal_connect (test->parser, "authenticate", G_CALLBACK (authenticate), test);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_object_unref (test->parser);
-}
-
-static void
-test_parse_one (Test *test,
- gconstpointer user_data)
-{
- const gchar *path = user_data;
- gchar *contents;
- GError *error = NULL;
- gboolean result;
- gsize len;
-
- if (!g_file_get_contents (path, &contents, &len, NULL))
- g_assert_not_reached ();
-
- test->filedesc = path;
- result = gcr_parser_parse_data (test->parser, (const guchar *)contents, len, &error);
- g_assert_no_error (error);
- g_assert (result);
-
- g_free (contents);
-}
-
-static void
-test_parse_null (void)
-{
- GcrParser *parser = gcr_parser_new ();
- GError *error = NULL;
- gboolean result;
-
- result = gcr_parser_parse_data (parser, NULL, 0, &error);
- g_assert_error (error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED);
- g_assert (!result);
- g_error_free (error);
-
- g_object_unref (parser);
-}
-
-static void
-test_parse_empty (void)
-{
- GcrParser *parser = gcr_parser_new ();
- GError *error = NULL;
- gboolean result;
-
- result = gcr_parser_parse_data (parser, (const guchar *)"", 0, &error);
- g_assert_error (error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED);
- g_assert (!result);
- g_error_free (error);
-
- g_object_unref (parser);
-}
-
-int
-main (int argc, char **argv)
-{
- const gchar *filename;
- GError *error = NULL;
- GPtrArray *strings;
- GDir *dir;
- gchar *path;
- gchar *lower;
- gchar *test;
- int ret;
-
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-parser");
-
- strings = g_ptr_array_new_with_free_func (g_free);
- dir = g_dir_open (SRCDIR "/files", 0, &error);
- g_assert_no_error (error);
-
- for (;;) {
- filename = g_dir_read_name (dir);
- if (!filename)
- break;
- if (filename[0] == '.')
- continue;
-
- path = g_build_filename (SRCDIR "/files", filename, NULL);
-
- if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
- g_free (path);
- continue;
- }
-
- lower = g_ascii_strdown (filename, -1);
- test = g_strdup_printf ("/gcr/parser/%s",
- g_strcanon (lower, "abcdefghijklmnopqrstuvwxyz012345789", '_'));
- g_free (lower);
-
- g_test_add (test, Test, path, setup, test_parse_one, teardown);
- g_ptr_array_add (strings, path);
- g_ptr_array_add (strings, test);
- }
-
- g_dir_close (dir);
-
- g_test_add_func ("/gcr/parser/parse_null", test_parse_null);
- g_test_add_func ("/gcr/parser/parse_empty", test_parse_empty);
-
- ret = g_test_run ();
- g_ptr_array_free (strings, TRUE);
- return ret;
-}
diff --git a/gcr/tests/test-pkcs11-certificate.c b/gcr/tests/test-pkcs11-certificate.c
deleted file mode 100644
index dd03371b..00000000
--- a/gcr/tests/test-pkcs11-certificate.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "egg/egg-asn1x.h"
-#include "egg/egg-asn1-defs.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "egg/egg-testing.h"
-
-#include "gck/gck-mock.h"
-#include "gck/gck-test.h"
-
-#include "pkcs11/pkcs11n.h"
-
-#include <glib.h>
-
-#include <errno.h>
-
-typedef struct {
- gpointer cert_data;
- gsize n_cert_data;
- gpointer cert2_data;
- gsize n_cert2_data;
- CK_FUNCTION_LIST funcs;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GList *modules = NULL;
- GckAttributes *attrs;
- CK_FUNCTION_LIST_PTR f;
- GckModule *module;
- gconstpointer subject;
- gsize n_subject;
- GNode *asn, *node;
- CK_RV rv;
-
- if (!g_file_get_contents (SRCDIR "/files/der-certificate.crt", (gchar**)&test->cert_data,
- &test->n_cert_data, NULL))
- g_assert_not_reached ();
- g_assert (test->cert_data);
-
- if (!g_file_get_contents (SRCDIR "/files/der-certificate-dsa.cer", (gchar**)&test->cert2_data,
- &test->n_cert2_data, NULL))
- g_assert_not_reached ();
- g_assert (test->cert2_data);
-
- rv = gck_mock_C_GetFunctionList (&f);
- gck_assert_cmprv (rv, ==, CKR_OK);
- memcpy (&test->funcs, f, sizeof (test->funcs));
-
- /* Open a session */
- rv = (test->funcs.C_Initialize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-
- g_assert (!modules);
- module = gck_module_new (&test->funcs);
- modules = g_list_prepend (modules, module);
- gcr_pkcs11_set_modules (modules);
- gck_list_unref_free (modules);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate",
- test->cert_data, test->n_cert_data);
- g_assert (asn);
- node = egg_asn1x_node (asn, "tbsCertificate", "subject", NULL);
- subject = egg_asn1x_get_raw_element (node, &n_subject);
-
- /* Add a certificate to the module */
- attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_VALUE, test->cert_data, test->n_cert_data);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509);
- gck_attributes_add_data (attrs, CKA_SUBJECT, subject, n_subject);
- gck_mock_module_take_object (attrs);
-
- egg_asn1x_destroy (asn);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- CK_RV rv;
-
- g_free (test->cert_data);
- g_free (test->cert2_data);
-
- rv = (test->funcs.C_Finalize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-}
-
-static void
-test_lookup_certificate_issuer (Test *test, gconstpointer unused)
-{
- GcrCertificate *cert, *issuer;
- GError *error = NULL;
- GckAttributes *attrs;
- GckAttribute *attr;
- gconstpointer der;
- gsize n_der;
-
- cert = gcr_simple_certificate_new_static (test->cert_data, test->n_cert_data);
- g_assert (cert);
-
- /* Should be self-signed, so should find itself (added in setup) */
- issuer = gcr_pkcs11_certificate_lookup_issuer (cert, NULL, &error);
- g_assert (GCR_IS_PKCS11_CERTIFICATE (issuer));
- g_assert (error == NULL);
-
- /* Should be the same certificate */
- der = gcr_certificate_get_der_data (issuer, &n_der);
- egg_assert_cmpsize (n_der, ==, test->n_cert_data);
- g_assert (memcmp (der, test->cert_data, test->n_cert_data) == 0);
-
- /* Should return the same certificate here too */
- attrs = gcr_pkcs11_certificate_get_attributes (GCR_PKCS11_CERTIFICATE (issuer));
- g_assert (attrs);
- attr = gck_attributes_find (attrs, CKA_VALUE);
- g_assert (attr);
- egg_assert_cmpsize (attr->length, ==, test->n_cert_data);
- g_assert (memcmp (attr->value, test->cert_data, test->n_cert_data) == 0);
-
- /* Should return the same certificate here too */
- attrs = NULL;
- g_object_get (issuer, "attributes", &attrs, NULL);
- g_assert (attrs);
- attr = gck_attributes_find (attrs, CKA_VALUE);
- g_assert (attr);
- egg_assert_cmpsize (attr->length, ==, test->n_cert_data);
- g_assert (memcmp (attr->value, test->cert_data, test->n_cert_data) == 0);
- gck_attributes_unref (attrs);
-
- g_object_unref (cert);
- g_object_unref (issuer);
-}
-
-static void
-test_lookup_certificate_issuer_not_found (Test *test, gconstpointer unused)
-{
- GcrCertificate *cert, *issuer;
- GError *error = NULL;
-
- cert = gcr_simple_certificate_new_static (test->cert2_data, test->n_cert2_data);
- g_assert (cert);
-
- /* Issuer shouldn't be found */
- issuer = gcr_pkcs11_certificate_lookup_issuer (cert, NULL, &error);
- g_assert (issuer == NULL);
- g_assert (error == NULL);
-
- g_object_unref (cert);
-}
-
-static void
-fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- *((GAsyncResult**)user_data) = result;
- g_object_ref (result);
- egg_test_wait_stop ();
-}
-
-static void
-test_lookup_certificate_issuer_async (Test *test, gconstpointer unused)
-{
- GAsyncResult *result = NULL;
- GcrCertificate *cert, *issuer;
- GError *error = NULL;
- gconstpointer der;
- gsize n_der;
-
- cert = gcr_simple_certificate_new_static (test->cert_data, test->n_cert_data);
- g_assert (cert);
-
- /* Should be self-signed, so should find itself (added in setup) */
- gcr_pkcs11_certificate_lookup_issuer_async (cert, NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- issuer = gcr_pkcs11_certificate_lookup_issuer_finish (result, &error);
- g_assert (GCR_IS_PKCS11_CERTIFICATE (issuer));
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- /* Should be the same certificate */
- der = gcr_certificate_get_der_data (issuer, &n_der);
- egg_assert_cmpsize (n_der, ==, test->n_cert_data);
- g_assert (memcmp (der, test->cert_data, test->n_cert_data) == 0);
-
- g_object_unref (cert);
- g_object_unref (issuer);
-}
-
-static void
-test_lookup_certificate_issuer_failure (Test *test, gconstpointer unused)
-{
- GcrCertificate *cert, *issuer;
- GError *error = NULL;
-
- cert = gcr_simple_certificate_new_static (test->cert_data, test->n_cert_data);
- g_assert (cert);
-
- /* Make the lookup fail */
- test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
-
- issuer = gcr_pkcs11_certificate_lookup_issuer (cert, NULL, &error);
- g_assert (issuer == NULL);
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_assert (error->message);
- g_clear_error (&error);
-
- g_object_unref (cert);
-}
-
-static void
-test_lookup_certificate_issuer_fail_async (Test *test, gconstpointer unused)
-{
- GAsyncResult *result = NULL;
- GcrCertificate *cert, *issuer;
- GError *error = NULL;
-
- cert = gcr_simple_certificate_new_static (test->cert_data, test->n_cert_data);
- g_assert (cert);
-
- /* Make the lookup fail */
- test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
-
- /* Should be self-signed, so should find itself (added in setup) */
- gcr_pkcs11_certificate_lookup_issuer_async (cert, NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- issuer = gcr_pkcs11_certificate_lookup_issuer_finish (result, &error);
- g_assert (issuer == NULL);
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_assert (error->message);
- g_clear_error (&error);
- g_object_unref (result);
- result = NULL;
-
- g_object_unref (cert);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-pkcs11-certificate");
-
- g_test_add ("/gcr/pkcs11-certificate/lookup_certificate_issuer", Test, NULL, setup, test_lookup_certificate_issuer, teardown);
- g_test_add ("/gcr/pkcs11-certificate/lookup_certificate_issuer_not_found", Test, NULL, setup, test_lookup_certificate_issuer_not_found, teardown);
- g_test_add ("/gcr/pkcs11-certificate/lookup_certificate_issuer_async", Test, NULL, setup, test_lookup_certificate_issuer_async, teardown);
- g_test_add ("/gcr/pkcs11-certificate/lookup_certificate_issuer_failure", Test, NULL, setup, test_lookup_certificate_issuer_failure, teardown);
- g_test_add ("/gcr/pkcs11-certificate/lookup_certificate_issuer_fail_async", Test, NULL, setup, test_lookup_certificate_issuer_fail_async, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-record.c b/gcr/tests/test-record.c
deleted file mode 100644
index cfb65932..00000000
--- a/gcr/tests/test-record.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-record.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-typedef struct {
- GcrRecord *record;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- test->record = _gcr_record_parse_colons ("one:tab\\there::YW9ldTM4Mzg=:f\xfc""nf:3533333:-88", -1);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- _gcr_record_free (test->record);
-}
-
-static void
-test_count (Test *test, gconstpointer unused)
-{
- g_assert_cmpuint (_gcr_record_get_count (test->record), ==, 7);
-}
-
-static void
-test_parse_colons (void)
-{
- GcrRecord *record;
-
- record = _gcr_record_parse_colons ("one:two::four::six", -1);
- g_assert (record);
-
- g_assert_cmpstr (_gcr_record_get_raw (record, 0), ==, "one");
- g_assert_cmpstr (_gcr_record_get_raw (record, 1), ==, "two");
- g_assert_cmpstr (_gcr_record_get_raw (record, 2), ==, "");
- g_assert_cmpstr (_gcr_record_get_raw (record, 3), ==, "four");
- g_assert_cmpstr (_gcr_record_get_raw (record, 4), ==, "");
- g_assert_cmpstr (_gcr_record_get_raw (record, 5), ==, "six");
- g_assert (_gcr_record_get_raw (record, 6) == NULL);
-
- _gcr_record_free (record);
-}
-
-static void
-test_parse_spaces (void)
-{
- GcrRecord *record;
-
- record = _gcr_record_parse_spaces (" one two four six ", -1);
- g_assert (record);
-
- g_assert_cmpstr (_gcr_record_get_raw (record, 0), ==, "one");
- g_assert_cmpstr (_gcr_record_get_raw (record, 1), ==, "two");
- g_assert_cmpstr (_gcr_record_get_raw (record, 2), ==, "four");
- g_assert_cmpstr (_gcr_record_get_raw (record, 3), ==, "six");
- g_assert (_gcr_record_get_raw (record, 4) == NULL);
- g_assert_cmpuint (_gcr_record_get_count (record), ==, 4);
-
- _gcr_record_free (record);
-}
-
-static void
-test_parse_part (void)
-{
- GcrRecord *record;
-
- record = _gcr_record_parse_colons ("one:two::four::six", 8);
- g_assert (record);
-
- g_assert_cmpstr (_gcr_record_get_raw (record, 0), ==, "one");
- g_assert_cmpstr (_gcr_record_get_raw (record, 1), ==, "two");
- g_assert_cmpstr (_gcr_record_get_raw (record, 2), ==, "");
- g_assert (_gcr_record_get_raw (record, 3) == NULL);
-
- _gcr_record_free (record);
-}
-
-static void
-test_parse_too_long (void)
-{
- GcrRecord *record;
-
- /* Too many columns */
- record = _gcr_record_parse_colons (":::::::::::::::::::::::::::::::::::::::::::::::::::::", -1);
- g_assert (record == NULL);
-}
-
-static void
-test_find (void)
-{
- GcrRecord *uid, *pub, *one, *check;
- GPtrArray *records;
-
- records = g_ptr_array_new_with_free_func (_gcr_record_free);
-
- one = _gcr_record_parse_colons ("one:two::four::six", -1);
- g_ptr_array_add (records, one);
- pub = _gcr_record_parse_colons ("pub:two", -1);
- g_ptr_array_add (records, pub);
- uid = _gcr_record_parse_colons ("uid:two", -1);
- g_ptr_array_add (records, uid);
-
- check = _gcr_records_find (records, GCR_RECORD_SCHEMA_PUB);
- g_assert (check == pub);
-
- check = _gcr_records_find (records, GCR_RECORD_SCHEMA_UID);
- g_assert (check == uid);
-
- g_ptr_array_unref (records);
-}
-
-static void
-test_get_string (Test *test, gconstpointer unused)
-{
- gchar *value = _gcr_record_get_string (test->record, 1);
- g_assert (value);
-
- g_assert_cmpstr (value, ==, "tab\there");
- g_free (value);
-}
-
-static void
-test_get_string_null (Test *test, gconstpointer unused)
-{
- gchar *value = _gcr_record_get_string (test->record, 35);
- g_assert (value == NULL);
-}
-
-static void
-test_get_string_latin1 (Test *test, gconstpointer unused)
-{
- gchar *value = _gcr_record_get_string (test->record, 4);
- g_assert (value);
-
- g_assert_cmpstr (value, ==, "f\xc3\xbc""nf");
- g_assert (g_utf8_validate (value, -1, NULL));
- g_free (value);
-}
-
-static void
-test_get_uint (Test *test, gconstpointer unused)
-{
- guint value = 0;
-
- if (!_gcr_record_get_uint (test->record, 5, &value))
- g_assert_not_reached ();
- g_assert_cmpuint (value, ==, 3533333);
-}
-
-static void
-test_get_uint_range (Test *test, gconstpointer unused)
-{
- guint value = 0;
-
- if (_gcr_record_get_uint (test->record, 6, &value))
- g_assert_not_reached ();
-}
-
-static void
-test_get_uint_invalid (Test *test, gconstpointer unused)
-{
- guint value = 0;
-
- if (_gcr_record_get_uint (test->record, 0, &value))
- g_assert_not_reached ();
-}
-
-static void
-test_get_base64 (Test *test, gconstpointer unused)
-{
- gchar *value;
- gsize n_value;
-
- value = _gcr_record_get_base64 (test->record, 3, &n_value);
- g_assert (value);
- egg_assert_cmpsize (n_value, ==, 8);
- g_assert (memcmp (value, "aoeu3838", n_value) == 0);
-
- g_free (value);
-}
-
-
-static void
-test_free_null (void)
-{
- _gcr_record_free (NULL);
-}
-
-static void
-test_get_schema (Test *test, gconstpointer unused)
-{
- GQuark schema;
- GQuark check;
-
- /* Initialize this quark */
- check = g_quark_from_static_string ("one");
-
- schema = _gcr_record_get_schema (test->record);
- g_assert (check == schema);
- g_assert_cmpstr (g_quark_to_string (schema), ==, "one");
-}
-
-static void
-test_copy (Test *test, gconstpointer unused)
-{
- GcrRecord *copy;
- guint count, i;
-
- copy = _gcr_record_copy (test->record);
-
- count = _gcr_record_get_count (test->record);
- g_assert_cmpuint (_gcr_record_get_count (copy), ==, count);
- for (i = 0; i < count; i++) {
- g_assert_cmpstr (_gcr_record_get_raw (copy, i), ==,
- _gcr_record_get_raw (test->record, i));
- }
-
- g_assert (_gcr_record_get_raw (copy, count) == NULL);
- _gcr_record_free (copy);
-}
-
-static void
-test_boxed (Test *test, gconstpointer unused)
-{
- GcrRecord *copy;
- guint count, i;
-
- copy = g_boxed_copy (GCR_TYPE_RECORD, test->record);
-
- count = _gcr_record_get_count (test->record);
- g_assert_cmpuint (_gcr_record_get_count (copy), ==, count);
- for (i = 0; i < count; i++) {
- g_assert_cmpstr (_gcr_record_get_raw (copy, i), ==,
- _gcr_record_get_raw (test->record, i));
- }
-
- g_assert (_gcr_record_get_raw (copy, count) == NULL);
- g_boxed_free (GCR_TYPE_RECORD, copy);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
-
- g_test_add_func ("/gcr/record/parse_colons", test_parse_colons);
- g_test_add_func ("/gcr/record/parse_colons", test_parse_spaces);
- g_test_add_func ("/gcr/record/parse_part", test_parse_part);
- g_test_add_func ("/gcr/record/parse_too_long", test_parse_too_long);
- g_test_add_func ("/gcr/record/free_null", test_free_null);
- g_test_add_func ("/gcr/record/find", test_find);
- g_test_add ("/gcr/record/count", Test, NULL, setup, test_count, teardown);
- g_test_add ("/gcr/record/copy", Test, NULL, setup, test_copy, teardown);
- g_test_add ("/gcr/record/boxed", Test, NULL, setup, test_boxed, teardown);
- g_test_add ("/gcr/record/get_string", Test, NULL, setup, test_get_string, teardown);
- g_test_add ("/gcr/record/get_string_null", Test, NULL, setup, test_get_string_null, teardown);
- g_test_add ("/gcr/record/get_string_latin1", Test, NULL, setup, test_get_string_latin1, teardown);
- g_test_add ("/gcr/record/get_uint", Test, NULL, setup, test_get_uint, teardown);
- g_test_add ("/gcr/record/get_uint_invalid", Test, NULL, setup, test_get_uint_invalid, teardown);
- g_test_add ("/gcr/record/get_uint_range", Test, NULL, setup, test_get_uint_range, teardown);
- g_test_add ("/gcr/record/get_base64", Test, NULL, setup, test_get_base64, teardown);
- g_test_add ("/gcr/record/get_schema", Test, NULL, setup, test_get_schema, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-secret-exchange.c b/gcr/tests/test-secret-exchange.c
deleted file mode 100644
index 79647450..00000000
--- a/gcr/tests/test-secret-exchange.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr.h"
-
-#include <glib.h>
-
-#include <errno.h>
-
-typedef struct {
- GcrSecretExchange *caller;
- GcrSecretExchange *callee;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- test->caller = gcr_secret_exchange_new (NULL);
- g_assert (GCR_IS_SECRET_EXCHANGE (test->caller));
- test->callee = gcr_secret_exchange_new (NULL);
- g_assert (GCR_IS_SECRET_EXCHANGE (test->callee));
-}
-
-static void
-teardown (Test *test,
- gconstpointer unused)
-{
- g_object_unref (test->caller);
- g_assert (!GCR_IS_SECRET_EXCHANGE (test->caller));
- g_object_unref (test->callee);
- g_assert (!GCR_IS_SECRET_EXCHANGE (test->callee));
-}
-
-static void
-test_perform_exchange (Test *test,
- gconstpointer unused)
-{
- gchar *exchange;
-
- exchange = gcr_secret_exchange_begin (test->caller);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->callee, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- exchange = gcr_secret_exchange_send (test->callee, "the secret", -1);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->caller, exchange))
- g_assert_not_reached ();
-
- g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "the secret");
-
- g_free (exchange);
-}
-
-static void
-test_perform_reverse (Test *test,
- gconstpointer unused)
-{
- gchar *exchange;
-
- exchange = gcr_secret_exchange_begin (test->caller);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->callee, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- exchange = gcr_secret_exchange_send (test->callee, NULL, -1);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->caller, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- g_assert (gcr_secret_exchange_get_secret (test->caller, NULL) == NULL);
-
- exchange = gcr_secret_exchange_send (test->caller, "reverse secret", -1);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->callee, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- g_assert_cmpstr (gcr_secret_exchange_get_secret (test->callee, NULL), ==, "reverse secret");
-}
-
-static void
-test_perform_multiple (Test *test,
- gconstpointer unused)
-{
- gchar *exchange;
-
- exchange = gcr_secret_exchange_begin (test->caller);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->callee, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- exchange = gcr_secret_exchange_send (test->callee, "first secret", -1);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->caller, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "first secret");
-
- exchange = gcr_secret_exchange_send (test->callee, "second secret", -1);
- g_assert (exchange);
-
- if (!gcr_secret_exchange_receive (test->caller, exchange))
- g_assert_not_reached ();
-
- g_free (exchange);
-
- g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "second secret");
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-secret-exchange");
-
- g_test_add ("/gcr/secret-exchange/perform-exchange", Test, NULL, setup, test_perform_exchange, teardown);
- g_test_add ("/gcr/secret-exchange/perform-reverse", Test, NULL, setup, test_perform_reverse, teardown);
- g_test_add ("/gcr/secret-exchange/perform-multiple", Test, NULL, setup, test_perform_multiple, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-simple-certificate.c b/gcr/tests/test-simple-certificate.c
deleted file mode 100644
index 60441359..00000000
--- a/gcr/tests/test-simple-certificate.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Collabora Ltd
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "gck/gck-test.h"
-
-#include "pkcs11/pkcs11n.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-
-typedef struct {
- gpointer cert_data;
- gsize n_cert_data;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- if (!g_file_get_contents (SRCDIR "/files/der-certificate.crt", (gchar**)&test->cert_data,
- &test->n_cert_data, NULL))
- g_assert_not_reached ();
- g_assert (test->cert_data);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- g_free (test->cert_data);
-}
-
-static void
-test_new (Test *test, gconstpointer unused)
-{
- GcrCertificate *cert;
- gconstpointer der;
- gsize n_der;
-
- cert = gcr_simple_certificate_new (test->cert_data, test->n_cert_data);
- g_assert (GCR_IS_SIMPLE_CERTIFICATE (cert));
-
- der = gcr_certificate_get_der_data (cert, &n_der);
- g_assert (der);
- egg_assert_cmpmem (der, n_der, ==, test->cert_data, test->n_cert_data);
-
- g_object_unref (cert);
-}
-
-static void
-test_new_static (Test *test, gconstpointer unused)
-{
- GcrCertificate *cert;
- gconstpointer der;
- gsize n_der;
-
- cert = gcr_simple_certificate_new_static (test->cert_data, test->n_cert_data);
- g_assert (GCR_IS_SIMPLE_CERTIFICATE (cert));
-
- der = gcr_certificate_get_der_data (cert, &n_der);
- g_assert (der);
- egg_assert_cmpsize (n_der, ==, test->n_cert_data);
- g_assert (der == test->cert_data); /* Must be same pointer */
-
- g_object_unref (cert);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-simple-certificate");
-
- g_test_add ("/gcr/simple-certificate/new", Test, NULL, setup, test_new, teardown);
- g_test_add ("/gcr/simple-certificate/new_static", Test, NULL, setup, test_new_static, teardown);
-
- return g_test_run ();
-}
diff --git a/gcr/tests/test-trust.c b/gcr/tests/test-trust.c
deleted file mode 100644
index d41596cf..00000000
--- a/gcr/tests/test-trust.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2010 Stefan Walter
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stef@memberwebs.com>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-internal.h"
-
-#include "gck/gck-mock.h"
-#include "gck/gck-test.h"
-
-#include "pkcs11/pkcs11.h"
-#include "pkcs11/pkcs11n.h"
-#include "pkcs11/pkcs11x.h"
-
-#include "egg/egg-testing.h"
-
-#include <glib.h>
-
-#include <errno.h>
-
-typedef struct {
- CK_FUNCTION_LIST funcs;
- GcrCertificate *certificate;
-} Test;
-
-static void
-setup (Test *test, gconstpointer unused)
-{
- GList *modules = NULL;
- CK_FUNCTION_LIST_PTR f;
- GckModule *module;
- gchar *contents;
- const gchar *uris[2];
- gsize len;
- CK_RV rv;
-
- if (!g_file_get_contents (SRCDIR "/files/der-certificate.crt", &contents, &len, NULL))
- g_assert_not_reached ();
- g_assert (contents);
-
- test->certificate = gcr_simple_certificate_new ((const guchar *)contents, len);
- g_free (contents);
-
- rv = gck_mock_C_GetFunctionList (&f);
- gck_assert_cmprv (rv, ==, CKR_OK);
- memcpy (&test->funcs, f, sizeof (test->funcs));
-
- /* Open a session */
- rv = (test->funcs.C_Initialize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-
- g_assert (!modules);
- module = gck_module_new (&test->funcs);
- modules = g_list_prepend (modules, module);
- gcr_pkcs11_set_modules (modules);
- gck_list_unref_free (modules);
-
- uris[0] = GCK_MOCK_SLOT_ONE_URI;
- uris[1] = NULL;
-
- gcr_pkcs11_set_trust_store_uri (GCK_MOCK_SLOT_ONE_URI);
- gcr_pkcs11_set_trust_lookup_uris (uris);
-}
-
-static void
-teardown (Test *test, gconstpointer unused)
-{
- CK_RV rv;
-
- g_object_unref (test->certificate);
-
- rv = (test->funcs.C_Finalize) (NULL);
- gck_assert_cmprv (rv, ==, CKR_OK);
-}
-
-static void
-test_is_pinned_none (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gboolean trust;
-
- trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert_cmpint (trust, ==, FALSE);
- g_assert (error == NULL);
-}
-
-static void
-test_add_and_is_pinned (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gboolean trust;
- gboolean ret;
-
- trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert_cmpint (trust, ==, FALSE);
- g_assert (error == NULL);
-
- ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
-
- trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert_cmpint (trust, ==, TRUE);
- g_assert (error == NULL);
-}
-
-static void
-test_add_certificate_pinned_fail (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gboolean ret;
-
- /* Make this function fail */
- test->funcs.C_CreateObject = gck_mock_fail_C_CreateObject;
-
- ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_CLIENT_AUTH, "peer", NULL, &error);
- g_assert (ret == FALSE);
- g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
- g_clear_error (&error);
-}
-
-static void
-test_add_and_remov_pinned (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gboolean trust;
- gboolean ret;
-
- ret = gcr_trust_add_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
-
- trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert_cmpint (trust, ==, TRUE);
- g_assert (error == NULL);
-
- ret = gcr_trust_remove_pinned_certificate (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
-
- trust = gcr_trust_is_certificate_pinned (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, &error);
- g_assert_cmpint (trust, ==, FALSE);
- g_assert (error == NULL);
-}
-
-static void
-fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- *((GAsyncResult**)user_data) = result;
- g_object_ref (result);
- egg_test_wait_stop ();
-}
-
-static void
-test_add_and_is_pinned_async (Test *test, gconstpointer unused)
-{
- GAsyncResult *result = NULL;
- GError *error = NULL;
- gboolean trust;
- gboolean ret;
-
- gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- trust = gcr_trust_is_certificate_pinned_finish (result, &error);
- g_assert (trust == FALSE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- gcr_trust_add_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host",
- NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- ret = gcr_trust_add_pinned_certificate_finish (result, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- trust = gcr_trust_is_certificate_pinned_finish (result, &error);
- g_assert (trust == TRUE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-}
-
-static void
-test_add_and_remov_pinned_async (Test *test, gconstpointer unused)
-{
- GAsyncResult *result = NULL;
- GError *error = NULL;
- gboolean trust;
- gboolean ret;
-
- gcr_trust_add_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- ret = gcr_trust_add_pinned_certificate_finish (result, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- trust = gcr_trust_is_certificate_pinned_finish (result, &error);
- g_assert (trust == TRUE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- gcr_trust_remove_pinned_certificate_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- ret = gcr_trust_remove_pinned_certificate_finish (result, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-
- gcr_trust_is_certificate_pinned_async (test->certificate, GCR_PURPOSE_EMAIL, "host", NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
- trust = gcr_trust_is_certificate_pinned_finish (result, &error);
- g_assert (trust == FALSE);
- g_assert (error == NULL);
- g_object_unref (result);
- result = NULL;
-}
-
-static void
-test_is_certificate_anchored_not (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- gboolean ret;
-
- ret = gcr_trust_is_certificate_anchored (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
- g_assert (ret == FALSE);
- g_assert (error == NULL);
-}
-
-static void
-test_is_certificate_anchored_yes (Test *test, gconstpointer unused)
-{
- GError *error = NULL;
- GckAttributes *attrs;
- gconstpointer der;
- gsize n_der;
- gboolean ret;
-
- /* Create a certificate root trust */
- attrs = gck_attributes_new ();
- der = gcr_certificate_get_der_data (test->certificate, &n_der);
- gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, der, n_der);
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION);
- gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
- gck_attributes_add_string (attrs, CKA_X_PURPOSE, GCR_PURPOSE_CLIENT_AUTH);
- gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
- gck_mock_module_take_object (attrs);
-
- ret = gcr_trust_is_certificate_anchored (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
- g_assert (ret == TRUE);
- g_assert (error == NULL);
-}
-
-static void
-test_is_certificate_anchored_async (Test *test, gconstpointer unused)
-{
- GAsyncResult *result = NULL;
- GError *error = NULL;
- gboolean ret;
-
- gcr_trust_is_certificate_anchored_async (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, fetch_async_result, &result);
- egg_test_wait_until (500);
- g_assert (result);
-
- ret = gcr_trust_is_certificate_anchored_finish (result, &error);
- g_assert (ret == FALSE);
- g_assert (error == NULL);
-
- g_object_unref (result);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
- g_set_prgname ("test-trust");
-
- g_test_add ("/gcr/trust/is_pinned_none", Test, NULL, setup, test_is_pinned_none, teardown);
- g_test_add ("/gcr/trust/add_and_is_pinned", Test, NULL, setup, test_add_and_is_pinned, teardown);
- g_test_add ("/gcr/trust/add_certificate_pinned_fail", Test, NULL, setup, test_add_certificate_pinned_fail, teardown);
- g_test_add ("/gcr/trust/add_and_remov_pinned", Test, NULL, setup, test_add_and_remov_pinned, teardown);
- g_test_add ("/gcr/trust/add_and_is_pinned_async", Test, NULL, setup, test_add_and_is_pinned_async, teardown);
- g_test_add ("/gcr/trust/add_and_remov_pinned_async", Test, NULL, setup, test_add_and_remov_pinned_async, teardown);
- g_test_add ("/gcr/trust/is_certificate_anchored_not", Test, NULL, setup, test_is_certificate_anchored_not, teardown);
- g_test_add ("/gcr/trust/is_certificate_anchored_yes", Test, NULL, setup, test_is_certificate_anchored_yes, teardown);
- g_test_add ("/gcr/trust/is_certificate_anchored_async", Test, NULL, setup, test_is_certificate_anchored_async, teardown);
-
- return egg_tests_run_in_thread_with_loop ();
-}
diff --git a/gcr/tests/test-util.c b/gcr/tests/test-util.c
deleted file mode 100644
index 96819ac6..00000000
--- a/gcr/tests/test-util.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- Copyright (C) 2011 Collabora Ltd.
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <stefw@collabora.co.uk>
-*/
-
-#include "config.h"
-
-#include "gcr/gcr-base.h"
-#include "gcr/gcr-util.h"
-
-#include <errno.h>
-
-static void
-on_line_parsed_match_template (const gchar *line, gpointer user_data)
-{
- const gchar ***matching = user_data;
-
- g_assert (matching);
- g_assert (*matching);
-
- /* Must be another line to match */
- g_assert ((*matching)[0]);
-
- /* Match this line against expected, and increment to next */
- g_assert_cmpstr ((*matching)[0], ==, line);
- (*matching)++;
-}
-
-static void
-test_parse_lines (void)
-{
- GString *string = g_string_new ("first line\nsecond line\n\nlast line");
- const gchar *matches[] = { "first line", "second line", "", NULL };
- const gchar **matching = matches;
-
- _gcr_util_parse_lines (string, FALSE, on_line_parsed_match_template, &matching);
-
- /* All lines should have matched */
- g_assert (*matching == NULL);
-
- /* The last line should still be here */
- g_assert_cmpstr (string->str, ==, "last line");
- g_string_free (string, TRUE);
-}
-
-static void
-test_parse_lines_and_last (void)
-{
- GString *string = g_string_new ("first line\nsecond line\n\nlast line");
- const gchar *matches[] = { "first line", "second line", "", "last line", NULL };
- const gchar **matching = matches;
-
- _gcr_util_parse_lines (string, FALSE, on_line_parsed_match_template, &matching);
- _gcr_util_parse_lines (string, TRUE, on_line_parsed_match_template, &matching);
-
- /* All lines should have matched */
- g_assert (*matching == NULL);
-
- /* No more data */
- g_assert_cmpstr (string->str, ==, "");
- g_assert_cmpuint (string->len, ==, 0);
- g_string_free (string, TRUE);
-}
-
-static void
-test_parse_lines_dos (void)
-{
- GString *string = g_string_new ("first line\r\nsecond line\r\n\r\nlast line");
- const gchar *matches[] = { "first line", "second line", "", "last line", NULL };
- const gchar **matching = matches;
-
- _gcr_util_parse_lines (string, FALSE, on_line_parsed_match_template, &matching);
- _gcr_util_parse_lines (string, TRUE, on_line_parsed_match_template, &matching);
-
- /* All lines should have matched */
- g_assert (*matching == NULL);
-
- /* No more data */
- g_assert_cmpstr (string->str, ==, "");
- g_assert_cmpuint (string->len, ==, 0);
- g_string_free (string, TRUE);
-}
-
-int
-main (int argc, char **argv)
-{
- g_type_init ();
- g_test_init (&argc, &argv, NULL);
-
- g_test_add_func ("/gcr/util/test_parse_lines", test_parse_lines);
- g_test_add_func ("/gcr/util/test_parse_lines_and_last", test_parse_lines_and_last);
- g_test_add_func ("/gcr/util/test_parse_lines_dos", test_parse_lines_dos);
-
- return g_test_run ();
-}