diff --git a/pace-gui/src/chat-gui.py b/pace-gui/src/chat-gui.py
deleted file mode 100755
index 9a10c20..0000000
--- a/pace-gui/src/chat-gui.py
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/usr/bin/env python
-# coding: utf-8
-
-import sys
-try:
- import pygtk
- pygtk.require("2.0")
- import gtk, gobject, glib
- import pango
-except:
- sys.exit(1)
-
-try:
- import pace
-except:
- print >> sys.stderr, "Could not import pace module, please install pyPACE"
- sys.exit(1)
-
-CVC = "\x7F\x21\x82\x01\x41\x7F\x4E\x81\xFA\x5F\x29\x01\x00\x42\x0D\x5A\x5A\x44\x56\x43\x41\x41\x54\x41\x30\x30\x30\x33\x7F\x49\x4F\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03\x86\x41\x04\x19\xD1\x75\x45\xD3\xFE\x0B\x34\x3E\x7E\xE2\xAE\x4E\x2B\xC9\x2D\x51\x35\x1C\xC1\x17\xA4\x7F\xA9\x51\x9A\xDB\x1E\x40\x5E\xE6\xB8\x12\x12\x80\xBC\xC2\xFF\xF0\x35\x7A\x19\x7D\xE7\x39\xA7\xFD\x2E\xF0\x22\x10\xEF\x34\x3C\xDB\xE7\x9E\xF9\x4B\x8E\x28\x59\x1B\xB9\x5F\x20\x0B\x5A\x5A\x44\x4B\x42\x32\x30\x30\x30\x30\x52\x7F\x4C\x12\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x02\x02\x53\x05\x00\x03\x01\xDF\x04\x5F\x25\x06\x01\x00\x00\x02\x01\x07\x5F\x24\x06\x01\x00\x00\x03\x03\x01\x65\x5E\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x80\x20\x75\xE0\xC4\xAC\x36\xC2\x5A\x33\xAC\x0E\x9A\x75\xEB\x79\x2A\x72\xF3\x31\xA5\x1E\x28\x63\x4E\xCC\x2E\xD6\x2E\x54\xF3\xC6\x93\xDA\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x02\x80\x20\x18\x12\x65\x74\x49\xFC\xF1\xD3\xDA\xD8\x3D\x13\x14\x29\x17\x5C\x61\x8B\x21\xBA\xF0\xAF\x44\xAC\xE3\x8C\xB2\xC1\x2C\xEB\x2A\x56\x5F\x37\x40\x54\x0F\x85\x09\x12\xAB\xD3\x51\xF8\xF5\x56\x9B\x53\x4A\x5C\x8F\x64\x54\x5B\x51\xA7\x34\x70\xBE\x5A\xD2\x89\xC1\x9A\x5E\x13\x52\x53\xD3\xBB\x15\x52\x26\x21\x7B\x41\xE7\xF0\x68\xB3\x52\x3F\x3A\x63\x92\x22\xAF\x2B\x62\x8C\x39\x7D\x4F\xD4\x02\x1E\xDE\x00\xDC"
-
-DESCRIPTION = "\x30\x82\x01\x90\x06\x0A\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x01\xA1\x16\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\xA2\x24\x13\x22\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x2E\x64\x65\x2F\x64\x76\x63\x61\xA3\x18\x0C\x16\x44\x65\x75\x74\x73\x63\x68\x65\x20\x4B\x72\x65\x64\x69\x74\x62\x61\x6E\x6B\x20\x41\x47\xA4\x13\x13\x11\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x64\x6B\x62\x2E\x64\x65\xA5\x82\x01\x13\x0C\x82\x01\x0F\x54\x61\x75\x62\x65\x6E\x73\x74\x72\x2E\x20\x37\x2D\x39\x0D\x0A\x31\x30\x31\x31\x37\x20\x42\x65\x72\x6C\x69\x6E\x0D\x0A\x69\x6E\x66\x6F\x40\x64\x6B\x62\x2E\x64\x65\x0D\x0A\x45\x72\xC3\xB6\x66\x66\x6E\x75\x6E\x67\x20\x65\x69\x6E\x65\x73\x20\x4B\x6F\x6E\x74\x6F\x73\x0D\x0A\x42\x65\x72\x6C\x69\x6E\x65\x72\x20\x42\x65\x61\x75\x66\x74\x72\x61\x67\x74\x65\x72\x20\x66\xC3\xBC\x72\x20\x44\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x20\x75\x6E\x64\x20\x49\x6E\x66\x6F\x72\x6D\x61\x74\x69\x6F\x6E\x73\x66\x72\x65\x69\x68\x65\x69\x74\x2C\x20\x41\x6E\x20\x64\x65\x72\x20\x55\x72\x61\x6E\x69\x61\x20\x34\x2D\x31\x30\x2C\x20\x31\x30\x37\x38\x37\x20\x42\x65\x72\x6C\x69\x6E\x2C\x20\x30\x33\x30\x2F\x31\x33\x20\x38\x38\x39\x2D\x30\x2C\x20\x6D\x61\x69\x6C\x62\x6F\x78\x40\x64\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x2D\x62\x65\x72\x6C\x69\x6E\x2E\x64\x65\x2C\x20\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x64\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x2D\x62\x65\x72\x6C\x69\x6E\x2E\x64\x65\x0D\x0A\x45\x72\xC3\xB6\x66\x66\x6E\x75\x6E\x67\x20\x65\x69\x6E\x65\x73\x20\x4B\x6F\x6E\x74\x6F\x73\x0D\x0A"
-
-at_chat_strings = [
- "Altersverifikation", #"Age Verification",
- "Community ID Verification",
- "Pseudonymfunktion", #"Restrictied Identification",
- "Priviligiertes Terminal", #"Privileged Terminal",
- "Verwendung der CAN", #"CAN allowed",
- "PIN Managment",
- "Zertifikat einspielen", #"Install Certificate",
- "Qualifiziertes Zertifikat einspielen", #"Install Qualified Certificate",
- "Dokumenttyp lesen", #"Read DG 1",
- "Staat lesen", #"Read DG 2",
- "Ablaufdatum lesen", #"Read DG 3",
- "Vorname lesen", #"Read DG 4",
- "Nachname lesen", #"Read DG 5",
- u"Künstlername lesen", #"Read DG 6",
- "Doktorgrad lesen", #"Read DG 7",
- "Geburtsdatum lesen", #"Read DG 8",
- "Geburtsort lesen", #"Read DG 9",
- u"Ungültig", #"Read DG 10",
- u"Ungültig", #"Read DG 11",
- u"Ungültig", #"Read DG 12",
- u"Ungültig", #"Read DG 13",
- u"Ungültig", #"Read DG 14",
- u"Ungültig", #"Read DG 15",
- u"Ungültig", #"Read DG 16",
- "Adresse lesen", #"Read DG 17",
- u"Gemeindeschlüssel lesen", #"Read DG 18",
- u"Ungültig", #"Read DG 19",
- u"Ungültig", #"Read DG 20",
- u"Ungültig", #"Read DG 21",
- u"Ungültig", #"RFU",
- u"Ungültig", #"RFU",
- u"Ungültig", #"RFU",
- u"Ungültig", #"RFU",
- u"Ungültig", #"Write DG 21",
- u"Ungültig", #"Write DG 20",
- u"Ungültig", #"Write DG 19",
- u"Gemeindeschlüssel schreiben", #"Write DG 18",
- u"Adresse schreiben", #"Write DG 17"
-]
-
-def countBits(bitstring):
- numbits = 0
- for c in bitstring:
- for i in range(8):
- if ord(c) & 1 << i:
- numbits += 1
- return numbits
-
-class MokoWindow(gtk.Window):
- """
- Base class for all our dialogues. It's a simple gtk.Window, with a title at
- the top and to buttons at the bottom. In the middle there is a vBox where
- we can put custom stuff for each dialoge.
- All the dialoges are stored as a double-linked list, so the navigation from
- one window to another is easy
- """
-
- def __init__(self, title, predecessor, successor):
- super(MokoWindow, self).__init__()
-
- self.title_str = title
- self.predecessor = predecessor
- self.successor = successor
-
- assert(isinstance(self.title_str, basestring))
-
- self.connect("destroy", gtk.main_quit)
- self.set_default_size(480, 640) #Display resolution of the OpenMoko
-
- #Main VBox, which consists of the title, the body, and the buttons
- #The size of the elements is inhomogenous and the spacing between elements is 5 pixel
- self.__vb = gtk.VBox(False, 5)
- self.add(self.__vb)
-
- #Title label at the top of the window
- lblTitle = gtk.Label(self.title_str)
- lblTitle.modify_font(pango.FontDescription("sans 14"))
- lblTitle.set_alignment(0.5, 0.0)
- self.__vb.pack_start(lblTitle, False, False)
-
- #Body VBox for custom widgets
- self.body = gtk.VBox(False)
- #Add a scrollbar in case we must display lots of information
- #Only use a vertical spacebar, not a horizontal one
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- scrolled_window.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
- self.__vb.pack_start(scrolled_window)
- scrolled_window.add_with_viewport(self.body)
-
- #Add two buttons at the bottom of the window
- hbox = gtk.HBox(True, 5)
- btnBack = gtk.Button(stock="gtk-go-back")
- btnBack.set_size_request(150, 75)
- btnBack.connect("clicked", self.btnBack_clicked, None)
- hbox.pack_start(btnBack, True, True)
- btnForward = gtk.Button(stock="gtk-go-forward")
- btnForward.set_size_request(150, 75)
- btnForward.connect("clicked", self.btnForward_clicked, None)
- hbox.pack_start(btnForward, True, True)
- self.__vb.pack_start(hbox, False, False)
-
- def btnBack_clicked(self, widget, data=None):
- if self.predecessor == None:
- gtk.main_quit()
- else:
- self.hide()
- self.predecessor.show()
-# raise NotImplementedError("Please implement this method in a subclass")
-
- def btnForward_clicked(self, widget, data=None):
- if self.successor == None:
- pass
- else:
- self.hide()
- self.successor.show_all()
-# raise NotImplementedError("Please implement this method in a subclass")
-
-class CertificateDescriptionWindow(MokoWindow):
-
- def __init__(self, description):
- super(CertificateDescriptionWindow, self).__init__("Dienstanbieter", None, None)
-
- self.description = description
- self.terms_str = pace.get_termsOfUsage(self.description)
- self.terms_array = self.terms_str.split("\r\n")
- print self.terms_array
-
- self.successor = MainWindow(binchat, self) #FIXME: Get rid of global var
-
- for s in self.terms_array:
- s = s.replace(", ", "\n").strip()
- lbl = gtk.Label(s)
- lbl.set_alignment(0.0, 0.0)
- lbl.set_line_wrap(True)
- lbl.modify_font(pango.FontDescription("bold"))
- lbl.set_width_chars(60)
- self.body.pack_start(lbl, False, False, 5)
-
- self.show_all()
-
-class MainWindow(MokoWindow):
-
- def __init__(self, chat, predecessor):
- super(MainWindow, self).__init__("Zugriffsrechte", None, None)
-
- self.chat = chat
- self.predecessor = predecessor
-
- self.rel_auth = []
- for c in self.chat:
- self.rel_auth.append(ord(c))
- self.rel_auth_len = len(self.rel_auth)
-
- self.access_rights = []
-
- #Extract the access rights from the CHAT and display them in the window
- j = 0
- for i in range((self.rel_auth_len - 1) * 8 - 2):
- if (i % 8 == 0):
- j += 1
- if self.rel_auth[self.rel_auth_len - j] & (1 << (i % 8)):
- chk = customCheckButton(at_chat_strings[i], i, self.body)
- self.access_rights.append(chk)
-
-# self.show_all()
-
- def btnForward_clicked(self, widget, data=None):
- """ Check wether any access right have been deselected and modify the
- CHAT accordingly """
-
- for right in self.access_rights:
- if not right.is_active():
- idx = right.idx
- self.chat_array[len(self.chat) - 1 - idx / 8] ^= (1 << (idx % 8))
-
-class customCheckButton(object):
- """This class provides a custom version of gtk.CheckButton.
- The main difference isthat the checkbox can be placed at the right
- side of the label and that we can store an index with the button"""
-
- def __init__(self, label, index, vbox):
- #Setup a label with the name of the access right
- self.lbl = gtk.Label(label)
- self.lbl.set_alignment(0.0, 0.5)
- self.lbl.set_padding(20, 0)
- self.lbl.modify_font(pango.FontDescription("bold"))
-
- #...and a checkbox on the right side of the label
- self.idx = index
- self.chk = gtk.CheckButton("")
- self.chk.set_active(True)
- self.chk.set_alignment(1.0, 0.5)
-
- #Insert the label and the checkbox in the vbox and add a seperator
- hbox = gtk.HBox()
- hbox.pack_start(self.lbl, True, True)
- hbox.pack_start(self.chk, False, False)
- vbox.pack_start(gtk.HSeparator())
- vbox.pack_start(hbox)
-
- def is_active(self):
- return self.chk.get_active()
-
-if __name__ == "__main__":
- cvc = pace.d2i_CV_CERT(CVC)
- chat = pace.cvc_get_chat(cvc)
-# pace.cv_chat_dump(chat)
- binchat = pace.get_binary_chat(chat)
-# print "%r" % binchat
-# print "%d Bits set in CHAT" % countBits(binchat)
-
- desc = pace.d2i_CVC_CERTIFICATE_DESCRIPTION(DESCRIPTION)
- desc_txt = pace.get_termsOfUsage(desc)
-# print desc_txt
-
-# w = MainWindow(binchat)
- w = CertificateDescriptionWindow(desc)
- gtk.main()
diff --git a/pace-gui/src/pinpad.py b/pace-gui/src/pinpad.py
index c6dff45..859193a 100644
--- a/pace-gui/src/pinpad.py
+++ b/pace-gui/src/pinpad.py
@@ -1,22 +1,267 @@
#!/usr/bin/env python
+# coding: utf-8
-import sys, os
-import subprocess
+import sys, os, subprocess
from threading import Thread, Event
try:
import pygtk
pygtk.require("2.0")
-except:
- pass
-try:
- import gtk, gobject, glib
- import pango
+ import gtk, gobject, glib, pango
except:
sys.exit(1)
-#glade_dir is set by the build system
+try:
+ import pace
+except:
+ print >> sys.stderr, "Could not import pace module, please install pyPACE"
+ sys.exit(1)
+
from pinpad_globals import *
+at_chat_strings = [
+ "Altersverifikation", #"Age Verification",
+ "Community ID Verification",
+ "Pseudonymfunktion", #"Restrictied Identification",
+ "Priviligiertes Terminal", #"Privileged Terminal",
+ "Verwendung der CAN", #"CAN allowed",
+ "PIN Managment",
+ "Zertifikat einspielen", #"Install Certificate",
+ "Qualifiziertes Zertifikat einspielen", #"Install Qualified Certificate",
+ "Dokumenttyp lesen", #"Read DG 1",
+ "Staat lesen", #"Read DG 2",
+ "Ablaufdatum lesen", #"Read DG 3",
+ "Vorname lesen", #"Read DG 4",
+ "Nachname lesen", #"Read DG 5",
+ u"Künstlername lesen", #"Read DG 6",
+ "Doktorgrad lesen", #"Read DG 7",
+ "Geburtsdatum lesen", #"Read DG 8",
+ "Geburtsort lesen", #"Read DG 9",
+ u"Ungültig", #"Read DG 10",
+ u"Ungültig", #"Read DG 11",
+ u"Ungültig", #"Read DG 12",
+ u"Ungültig", #"Read DG 13",
+ u"Ungültig", #"Read DG 14",
+ u"Ungültig", #"Read DG 15",
+ u"Ungültig", #"Read DG 16",
+ "Adresse lesen", #"Read DG 17",
+ u"Gemeindeschlüssel lesen", #"Read DG 18",
+ u"Ungültig", #"Read DG 19",
+ u"Ungültig", #"Read DG 20",
+ u"Ungültig", #"Read DG 21",
+ u"Ungültig", #"RFU",
+ u"Ungültig", #"RFU",
+ u"Ungültig", #"RFU",
+ u"Ungültig", #"RFU",
+ u"Ungültig", #"Write DG 21",
+ u"Ungültig", #"Write DG 20",
+ u"Ungültig", #"Write DG 19",
+ u"Gemeindeschlüssel schreiben", #"Write DG 18",
+ u"Adresse schreiben", #"Write DG 17"
+]
+
+def countBits(bitstring):
+ numbits = 0
+ for c in bitstring:
+ for i in range(8):
+ if ord(c) & 1 << i:
+ numbits += 1
+ return numbits
+
+class MokoWindow(gtk.Window):
+ """
+ Base class for all our dialogues. It's a simple gtk.Window, with a title at
+ the top and to buttons at the bottom. In the middle there is a vBox where
+ we can put custom stuff for each dialoge.
+ All the dialoges are stored as a double-linked list, so the navigation from
+ one window to another is easy
+ """
+
+ def __init__(self, title, predecessor, successor):
+ super(MokoWindow, self).__init__()
+
+ self.title_str = title
+ self.predecessor = predecessor
+ self.successor = successor
+
+ assert(isinstance(self.title_str, basestring))
+
+ self.connect("destroy", gtk.main_quit)
+ self.set_default_size(480, 640) #Display resolution of the OpenMoko
+ self.set_resizable(False)
+
+ #Main VBox, which consists of the title, the body, and the buttons
+ #The size of the elements is inhomogenous and the spacing between elements is 5 pixel
+ self.__vb = gtk.VBox(False, 5)
+ self.add(self.__vb)
+
+ #Title label at the top of the window
+ lblTitle = gtk.Label(self.title_str)
+ lblTitle.modify_font(pango.FontDescription("sans 14"))
+ lblTitle.set_alignment(0.5, 0.0)
+ self.__vb.pack_start(lblTitle, False, False)
+
+ #Body VBox for custom widgets
+ self.body = gtk.VBox(False)
+ #Add a scrollbar in case we must display lots of information
+ #Only use a vertical spacebar, not a horizontal one
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scrolled_window.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
+ self.__vb.pack_start(scrolled_window)
+ scrolled_window.add_with_viewport(self.body)
+
+ #Add two buttons at the bottom of the window
+ hbox = gtk.HBox(True, 5)
+ btnBack = gtk.Button(stock="gtk-go-back")
+ btnBack.set_size_request(150, 75)
+ btnBack.connect("clicked", self.btnBack_clicked, None)
+ hbox.pack_start(btnBack, True, True)
+ btnForward = gtk.Button(stock="gtk-go-forward")
+ btnForward.set_size_request(150, 75)
+ btnForward.connect("clicked", self.btnForward_clicked, None)
+ hbox.pack_start(btnForward, True, True)
+ self.__vb.pack_start(hbox, False, False)
+
+ def btnBack_clicked(self, widget, data=None):
+ if self.predecessor == None:
+ gtk.main_quit()
+ else:
+ self.hide()
+ self.predecessor.show()
+# raise NotImplementedError("Please implement this method in a subclass")
+
+ def btnForward_clicked(self, widget, data=None):
+ if self.successor == None:
+ pass
+ else:
+ self.hide()
+ self.successor.show_all()
+# raise NotImplementedError("Please implement this method in a subclass")
+
+class CertificateDescriptionWindow(MokoWindow):
+
+ def __init__(self, description):
+ super(CertificateDescriptionWindow, self).__init__("Dienstanbieter", None, None)
+
+ self.description = description
+ self.terms_str = pace.get_termsOfUsage(self.description)
+ self.terms_array = self.terms_str.split("\r\n")
+ print self.terms_array
+
+ self.successor = MainWindow(binchat, self) #FIXME: Get rid of global var
+
+ for s in self.terms_array:
+ s = s.replace(", ", "\n").strip()
+ lbl = gtk.Label(s)
+ lbl.set_alignment(0.0, 0.0)
+ lbl.set_width_chars(60)
+# lbl.set_line_wrap(True)
+ lbl.modify_font(pango.FontDescription("bold"))
+ self.body.pack_start(gtk.HSeparator())
+ self.body.pack_start(lbl, False, False, 2)
+
+ self.show_all()
+
+class MainWindow(MokoWindow):
+
+ def __init__(self, chat, predecessor):
+ super(MainWindow, self).__init__("Zugriffsrechte", None, None)
+
+ self.chat = chat
+ self.predecessor = predecessor
+ self.successor = PinpadWindow(self)
+
+ self.rel_auth = []
+ for c in self.chat:
+ self.rel_auth.append(ord(c))
+ self.rel_auth_len = len(self.rel_auth)
+
+ self.access_rights = []
+
+ #Extract the access rights from the CHAT and display them in the window
+ j = 0
+ for i in range((self.rel_auth_len - 1) * 8 - 2):
+ if (i % 8 == 0):
+ j += 1
+ if self.rel_auth[self.rel_auth_len - j] & (1 << (i % 8)):
+ chk = customCheckButton(at_chat_strings[i], i, self.body)
+ self.access_rights.append(chk)
+
+# self.show_all()
+
+ def btnForward_clicked(self, widget, data=None):
+ """ Check wether any access right have been deselected and modify the
+ CHAT accordingly """
+
+ for right in self.access_rights:
+ if not right.is_active():
+ idx = right.idx
+ self.chat_array[len(self.chat) - 1 - idx / 8] ^= (1 << (idx % 8))
+
+ #super(MainWindow, self).btnForward_clicked(widget, data)
+ self.hide()
+ PinpadGTK()
+
+class customCheckButton(object):
+ """This class provides a custom version of gtk.CheckButton.
+ The main difference isthat the checkbox can be placed at the right
+ side of the label and that we can store an index with the button"""
+
+ def __init__(self, label, index, vbox):
+ #Setup a label with the name of the access right
+ self.lbl = gtk.Label(label)
+ self.lbl.set_alignment(0.0, 0.5)
+ self.lbl.set_padding(20, 0)
+ self.lbl.modify_font(pango.FontDescription("bold"))
+
+ #...and a checkbox on the right side of the label
+ self.idx = index
+ self.chk = gtk.CheckButton("")
+ self.chk.set_active(True)
+ self.chk.set_alignment(1.0, 0.5)
+
+ #Insert the label and the checkbox in the vbox and add a seperator
+ hbox = gtk.HBox()
+ hbox.pack_start(self.lbl, True, True)
+ hbox.pack_start(self.chk, False, False)
+ vbox.pack_start(gtk.HSeparator())
+ vbox.pack_start(hbox)
+
+ def is_active(self):
+ return self.chk.get_active()
+"""
+class PinpadWindow(MokoWindow):
+
+ def __init__(self, predecessor):
+ super(PinpadWindow, self).__init__("Bitte PIN eingeben", predecessor, None)
+
+ self.body.pack_start(gtk.HSeparator())
+ #This textfield is used to display the number of digits entered
+ txtDisplay = gtk.Entry(10)
+ txtDisplay.set_visibility(False)
+ txtDisplay.set_alignment(0.5)
+ txtDisplay.set_editable(False)
+ self.body.pack_start(txtDisplay, True, True, 5)
+ self.body.pack_start(gtk.HSeparator())
+
+ #Status label that indicates whether or not the card is in the field of
+ #the reader
+ #The label is updated by a thread that polls the reader for the ATR/ATS
+ lblCardStatus = gtk.Label("Ausweis nicht gefunden")
+ self.body.pack_start(lblCardStatus)
+
+ #This table is used to arrange the buttons that make up our pinpad
+ grid = gtk.Table(4, 3, True)
+ self.body.pack_start(grid)
+ for i in range(12):
+ if i == 9: #Del
+ pass
+ elif i == 11: #Enter
+ pass
+ else:
+ btn = gtk.Button(str(i))
+ #grid.pack_start(btn, False, False)
+"""
class PinpadGTK:
"""This a simple GTK based GUI to enter a PIN"""
@@ -33,9 +278,10 @@ class PinpadGTK:
try:
self.builder.add_from_file(self.gladefile)
except glib.GError, e:
+ #If we encounter an exception at startup, we display a popup with
+ #the error message
popup = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
- gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
- e.message)
+ gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, e.message)
popup.run()
popup.destroy()
raise e
@@ -239,6 +485,17 @@ class cardChecker(Thread):
self._paused.clear()
if __name__ == "__main__":
- gobject.threads_init()
- pinpad = PinpadGTK()
+ cvc = pace.d2i_CV_CERT(TEST_CVC)
+ chat = pace.cvc_get_chat(cvc)
+# pace.cv_chat_dump(chat)
+ binchat = pace.get_binary_chat(chat)
+# print "%r" % binchat
+# print "%d Bits set in CHAT" % countBits(binchat)
+
+ desc = pace.d2i_CVC_CERTIFICATE_DESCRIPTION(TEST_DESCRIPTION)
+ desc_txt = pace.get_termsOfUsage(desc)
+# print desc_txt
+
+# w = MainWindow(binchat)
+ w = CertificateDescriptionWindow(desc)
gtk.main()
diff --git a/pace-gui/src/pinpad_globals.py.in b/pace-gui/src/pinpad_globals.py.in
index 2ab2999..4c21876 100644
--- a/pace-gui/src/pinpad_globals.py.in
+++ b/pace-gui/src/pinpad_globals.py.in
@@ -6,3 +6,7 @@ glade_dir = "@prefix@/share/" + name
STR_NO_CARD = "Keine Karte gefunden"
STR_CARD_FOUND = "Karte gefunden"
ePA_ATR = "3b:84:80:01:00:00:90:00:95"
+
+TEST_CVC = "\x7F\x21\x82\x01\x41\x7F\x4E\x81\xFA\x5F\x29\x01\x00\x42\x0D\x5A\x5A\x44\x56\x43\x41\x41\x54\x41\x30\x30\x30\x33\x7F\x49\x4F\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03\x86\x41\x04\x19\xD1\x75\x45\xD3\xFE\x0B\x34\x3E\x7E\xE2\xAE\x4E\x2B\xC9\x2D\x51\x35\x1C\xC1\x17\xA4\x7F\xA9\x51\x9A\xDB\x1E\x40\x5E\xE6\xB8\x12\x12\x80\xBC\xC2\xFF\xF0\x35\x7A\x19\x7D\xE7\x39\xA7\xFD\x2E\xF0\x22\x10\xEF\x34\x3C\xDB\xE7\x9E\xF9\x4B\x8E\x28\x59\x1B\xB9\x5F\x20\x0B\x5A\x5A\x44\x4B\x42\x32\x30\x30\x30\x30\x52\x7F\x4C\x12\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x02\x02\x53\x05\x00\x03\x01\xDF\x04\x5F\x25\x06\x01\x00\x00\x02\x01\x07\x5F\x24\x06\x01\x00\x00\x03\x03\x01\x65\x5E\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x80\x20\x75\xE0\xC4\xAC\x36\xC2\x5A\x33\xAC\x0E\x9A\x75\xEB\x79\x2A\x72\xF3\x31\xA5\x1E\x28\x63\x4E\xCC\x2E\xD6\x2E\x54\xF3\xC6\x93\xDA\x73\x2D\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x03\x02\x80\x20\x18\x12\x65\x74\x49\xFC\xF1\xD3\xDA\xD8\x3D\x13\x14\x29\x17\x5C\x61\x8B\x21\xBA\xF0\xAF\x44\xAC\xE3\x8C\xB2\xC1\x2C\xEB\x2A\x56\x5F\x37\x40\x54\x0F\x85\x09\x12\xAB\xD3\x51\xF8\xF5\x56\x9B\x53\x4A\x5C\x8F\x64\x54\x5B\x51\xA7\x34\x70\xBE\x5A\xD2\x89\xC1\x9A\x5E\x13\x52\x53\xD3\xBB\x15\x52\x26\x21\x7B\x41\xE7\xF0\x68\xB3\x52\x3F\x3A\x63\x92\x22\xAF\x2B\x62\x8C\x39\x7D\x4F\xD4\x02\x1E\xDE\x00\xDC"
+
+TEST_DESCRIPTION = "\x30\x82\x01\x90\x06\x0A\x04\x00\x7F\x00\x07\x03\x01\x03\x01\x01\xA1\x16\x0C\x14\x42\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x20\x47\x6D\x62\x48\xA2\x24\x13\x22\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x62\x75\x6E\x64\x65\x73\x64\x72\x75\x63\x6B\x65\x72\x65\x69\x2E\x64\x65\x2F\x64\x76\x63\x61\xA3\x18\x0C\x16\x44\x65\x75\x74\x73\x63\x68\x65\x20\x4B\x72\x65\x64\x69\x74\x62\x61\x6E\x6B\x20\x41\x47\xA4\x13\x13\x11\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x64\x6B\x62\x2E\x64\x65\xA5\x82\x01\x13\x0C\x82\x01\x0F\x54\x61\x75\x62\x65\x6E\x73\x74\x72\x2E\x20\x37\x2D\x39\x0D\x0A\x31\x30\x31\x31\x37\x20\x42\x65\x72\x6C\x69\x6E\x0D\x0A\x69\x6E\x66\x6F\x40\x64\x6B\x62\x2E\x64\x65\x0D\x0A\x45\x72\xC3\xB6\x66\x66\x6E\x75\x6E\x67\x20\x65\x69\x6E\x65\x73\x20\x4B\x6F\x6E\x74\x6F\x73\x0D\x0A\x42\x65\x72\x6C\x69\x6E\x65\x72\x20\x42\x65\x61\x75\x66\x74\x72\x61\x67\x74\x65\x72\x20\x66\xC3\xBC\x72\x20\x44\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x20\x75\x6E\x64\x20\x49\x6E\x66\x6F\x72\x6D\x61\x74\x69\x6F\x6E\x73\x66\x72\x65\x69\x68\x65\x69\x74\x2C\x20\x41\x6E\x20\x64\x65\x72\x20\x55\x72\x61\x6E\x69\x61\x20\x34\x2D\x31\x30\x2C\x20\x31\x30\x37\x38\x37\x20\x42\x65\x72\x6C\x69\x6E\x2C\x20\x30\x33\x30\x2F\x31\x33\x20\x38\x38\x39\x2D\x30\x2C\x20\x6D\x61\x69\x6C\x62\x6F\x78\x40\x64\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x2D\x62\x65\x72\x6C\x69\x6E\x2E\x64\x65\x2C\x20\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x64\x61\x74\x65\x6E\x73\x63\x68\x75\x74\x7A\x2D\x62\x65\x72\x6C\x69\x6E\x2E\x64\x65\x0D\x0A\x45\x72\xC3\xB6\x66\x66\x6E\x75\x6E\x67\x20\x65\x69\x6E\x65\x73\x20\x4B\x6F\x6E\x74\x6F\x73\x0D\x0A"