source: trunk/CrypPlugins/SmartCard/SmartCard.cs @ 2380

Last change on this file since 2380 was 2334, checked in by Matthäus Wander, 11 years ago

removed 1006 occurences of DisplayLevel in 218 files (see #122)

File size: 9.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Cryptool.PluginBase.IO;
6using Cryptool.PluginBase;
7using System.ComponentModel;
8using Cryptool.PluginBase.Miscellaneous;
9using System.Windows.Controls;
10using Cryptool.PluginBase.Cryptography;
11
12namespace SmartCard
13{
14  [Author("Malte Gronau", null, "", "")]
15  [PluginInfo(false, "SmartCard", "SmartCard operations.", "SmartCard/DetailedDescription/Description.xaml", "SmartCard/Images/SmartCard.png")]
16  public class SmartCard : IThroughput
17  {
18    # region private variables
19    private SmartCardSettings settings = new SmartCardSettings();
20    // smartcard command input as hex-text
21    private String dataInput;
22    // apdu data to send to card
23    private byte[] APDUData = null;
24    // rapdu data receiving from card
25    private byte[] response = null;
26    // log string output
27    private String logString;
28    # endregion
29
30    #region events
31    public event StatusChangedEventHandler OnPluginStatusChanged;
32
33    private void PluginStatusChanged(int imageNumber)
34    {
35      if (OnPluginStatusChanged != null)
36      {
37        OnPluginStatusChanged(this, new StatusEventArgs(StatusChangedMode.ImageUpdate, imageNumber));
38      }
39    }
40
41    public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
42    private void GuiLogMessage(string message, NotificationLevel logLevel)
43    {
44      EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
45    }
46
47    public event PluginProgressChangedEventHandler OnPluginProgressChanged;
48    private void ProgressEnd()
49    {
50        EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(1, 1));
51    }
52
53    private void ProgressStart()
54    {
55        EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(0, 1));
56    }
57
58    # endregion events
59
60    # region constructor
61    public SmartCard()
62    {
63      settings.OnGuiLogNotificationOccured += settings_OnGuiLogNotificationOccured;
64    }
65
66    void settings_OnGuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
67    {
68      GuiLogMessage(args.Message, args.NotificationLevel);
69    }
70    # endregion
71
72    #region IO
73
74    [PropertyInfo(Direction.InputData, "Data Input", "The input as readable Hex String.", "", true, false, QuickWatchFormat.Text, null)]
75    public String DataInput
76    {
77        get
78        {
79            return dataInput;
80        }
81        set
82        {
83            dataInput = value;
84            APDUData = HexStringToByte(dataInput);
85            // HexStringToByte returns null if conversion failed
86            if (APDUData == null)
87            {
88                GuiLogMessage("InputData is not valid hex data.", NotificationLevel.Error);
89            }
90            OnPropertyChanged("DataInput");
91        }
92    }
93
94    [PropertyInfo(Direction.OutputData, "Logging Output", "Logging output of APDU/RAPDU", "", true, false, QuickWatchFormat.Text, null)]
95    public String LogString
96    {
97        get
98        {
99            return logString;
100        }
101        set
102        {
103            logString = value;
104            OnPropertyChanged("LogString");
105        }
106    }
107
108    [PropertyInfo(Direction.OutputData, "Response", "The response of the card reader.", "", true, false, QuickWatchFormat.Hex, null)]
109    public byte[] Response
110    {
111      get { return response; }
112        set
113        {
114          this.response = value;
115          OnPropertyChanged("Response"); 
116        }
117    } 
118    #endregion
119
120    # region IPlugin-Methods
121    public ISettings Settings
122    {
123      get { return settings; }
124    }
125
126    public UserControl Presentation
127    {
128      get { return null; }
129    }
130
131    public UserControl QuickWatchPresentation
132    {
133      get { return null; }
134    }
135
136    public void PreExecution()
137    {
138    }
139
140    public void Execute()
141    {
142        ProgressStart();
143        GuiLogMessage("Executing smartcard plugin.", NotificationLevel.Debug);
144
145        // data to send ?
146        if (this.APDUData == null)
147        {
148            GuiLogMessage("No data to send.", NotificationLevel.Error);
149            return;
150        } 
151       
152        // APDU >= 4 !!
153        if (this.APDUData.Length < 4)
154        {
155            GuiLogMessage("Invalid APDU.", NotificationLevel.Error);
156            return;
157        }
158
159
160      // just virtual reader ??  -> response = 0x9000
161        if (settings.Collection[settings.CardReader] == SmartCardSettings.VirtualReader)
162        {
163            byte[] bResponse = new byte[2];
164            bResponse[0] = 0x64;
165            bResponse[1] = 0xA1;
166
167            // output response data
168            this.Response = bResponse;
169
170            // create logging output
171            this.LogString = "APDU:\n" +
172                             dataInput +
173                             "\n" +
174                             "RAPDU:\n" +
175                             HexValuesToHexString(bResponse) +
176                             "\n----------------------------";
177        }
178        else
179        {
180            int Context = pcscWrapper.EstablishContext();
181            if (Context == pcscWrapper.INVALID_HANDLE)
182            {
183                GuiLogMessage("Could not establish PC/SC Context.", NotificationLevel.Error);
184                return;
185            }
186
187            int hCard = pcscWrapper.Connect(Context, settings.Collection[settings.CardReader]);
188            if (hCard == pcscWrapper.INVALID_HANDLE)
189            {
190                GuiLogMessage("Could not establish connection to reader: " + settings.Collection[settings.CardReader], NotificationLevel.Error);
191                return;
192            }
193
194            byte[] tmpResponse = pcscWrapper.Transmit(hCard, APDUData);
195            if (tmpResponse == null)
196            {
197                GuiLogMessage("Transmission of APDU failed.", NotificationLevel.Error);
198                return;
199            }
200
201            if (tmpResponse.Length < 2)
202            {
203                GuiLogMessage("invalid response data: " + HexValuesToHexString(tmpResponse), NotificationLevel.Error);
204                return;
205            }
206
207            // output response data
208            this.Response = tmpResponse;
209
210            // create logging output
211            this.LogString = "APDU:\n" +
212                             dataInput +
213                             "\n" +
214                             "RAPDU:\n" +
215                             HexValuesToHexString(this.response) +
216                             "\n----------------------------";
217
218
219            // disconnect reader and release PC/SC context
220            if (pcscWrapper.Disconnect(hCard, pcscWrapper.SCARD_LEAVE_CARD) != pcscWrapper.SCARD_S_SUCCESS)
221            {
222                GuiLogMessage("Disconnection failed.", NotificationLevel.Error);
223                return;
224            }
225            if (pcscWrapper.ReleaseContext(Context) != pcscWrapper.SCARD_S_SUCCESS)
226            {
227                GuiLogMessage("Release context failed.", NotificationLevel.Error);
228                return;
229            }
230        }
231
232      GuiLogMessage("Execution of smartcard command succeeded.", NotificationLevel.Debug);
233      ProgressEnd();
234    }
235
236    public void PostExecution()
237    {
238    }
239
240    public void Pause()
241    {
242    }
243
244    public void Stop()
245    {
246    }
247
248    public void Initialize()
249    {
250
251    }
252
253    public void Dispose()
254    {
255    }
256
257    #endregion IPlugin-Methods
258
259    #region INotifyPropertyChanged Members
260
261    public event PropertyChangedEventHandler PropertyChanged;
262
263    protected void OnPropertyChanged(string name)
264    {
265      EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
266    }
267
268    #endregion
269
270      #region Hilfsmethoden
271
272    private static String HexValuesToHexString(byte[] bytes)
273    {
274        String sTemp = "";
275
276        for (int i = 0; i < bytes.Length; i++)
277        {
278            sTemp += bytes[i].ToString("X2");
279        }
280
281        return sTemp;
282    }
283
284    private byte[] HexStringToByte(String hexString)
285    {
286        // String in bytes konvertieren
287        if (hexString == null)
288            return null;
289
290        if (hexString.Length % 2 == 1)
291            hexString = '0' + hexString; // Up to you whether to pad the first or last byte
292
293        byte[] data = new byte[hexString.Length / 2];
294
295        for (int i = 0; i < data.Length; i++)
296        {
297            try
298            {
299                data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
300            }
301            catch (System.OverflowException)
302            {
303                GuiLogMessage("Conversion from string to byte overflowed.", NotificationLevel.Error);
304                return null;
305            }
306            catch (System.FormatException)
307            {
308                GuiLogMessage("The string is not formatted as a byte.", NotificationLevel.Error);
309                return null;
310            }
311            catch (System.ArgumentNullException)
312            {
313                GuiLogMessage("The string is null.", NotificationLevel.Error);
314                return null;
315            }
316        }
317
318        return data;
319    }
320
321      #endregion
322  }
323}
Note: See TracBrowser for help on using the repository browser.