Statistics
| Branch: | Revision:

m2u-upass-core / src / my / com / upass / gemalto / GemaltoTokenControllerImpl.java @ 5:f608e6319b70

History | View | Annotate | Download (16 KB)

1 0:02300db8682b hadi
/*
2
 * Copyright (c) 2012 Penril Datability (M) Sdn Bhd All rights reserved.
3
 *
4
 * This software is copyrighted. Under the copyright laws, this software
5
 * may not be copied, in whole or in part, without prior written consent
6
 * of Penril Datability (M) Sdn Bhd or its assignees. This software is
7
 * provided under the terms of a license between Penril Datability (M)
8
 * Sdn Bhd and the recipient, and its use is subject to the terms of that
9
 * license.
10
 */
11
package my.com.upass.gemalto;
12
13
14
import java.util.Date;
15
import java.util.HashMap;
16
import ocra.Ocra;
17
import my.com.upass.Constants;
18
import my.com.upass.TokenBean;
19
import my.com.upass.vasco.TokenController;
20
21
/*
22
 * <pre>
23
 * PROGRAMMER: Enson Yeoh
24
 * CHANGE-NO:
25
 * TASK-NO:
26
 * DATE CREATED: Oct 5, 2012
27
 * TAG AS:
28
 * REASON(S):
29
 * MODIFICATION:
30
 * </pre>
31
 *
32
 *
33
 * Requirements:
34
 * 1) Retrieve the tokenBean and override the existing tokenBean object.
35
 * 2) Override the existing serial number with the given tokenBean.
36
 * 3) Override the existing authentication mode with the given tokenBean.
37
 * 4) Override the existing blob with the given tokenBean.
38
 * 5) Update useCount (total number of usage of the given token)
39
 * 6) Update errorCount (total number of errors attempted by the given token)
40
 * 7) Update last first time (the first usage date of the given token)
41
 * 8) Update last used time (the last usage date of the given token)
42
 * 9) Update the tokenBean object whenever there is changes.
43
 * 10) Verify token with the given password (OTP)
44
 * 11) Blob synchronization.
45
 * 12) Check last authentication
46
 *
47
 *
48
 */
49
50
public class GemaltoTokenControllerImpl implements TokenController
51
{
52
        private Ocra myocra = new Ocra();
53
54
        private TokenBean tb;
55
        private int retCode;
56
        private String serialNumber;
57
        private String authMode;
58
        private byte[] blob;
59
        private int useCount;
60
        private int errorCount;
61
        private Date lastTimeUsed;
62
        private Date firstTimeUsed;
63
        private Date lastAuthentication;
64
        private Date tokenExpectedDateTime;
65
66
        /**
67
         * this will override the existing tokenBean object
68
         * this will override the existing serial number, authentication mode and blob
69
         *
70
         * @param tokenBean
71
         */
72
        public GemaltoTokenControllerImpl(TokenBean tokenBean)
73
        {
74
                this.tb = tokenBean;
75
                setSerialNumber();
76
                setAuthMode();
77
                setBlob();
78
        }
79
80
        /**
81
         * this will override the existing last authentication date
82
         *
83
         * @param LastAuthentication
84
         */
85
        public void setLastAuthentication(Date lastAuthentication)
86
        {
87
                this.lastAuthentication = lastAuthentication;
88
        }
89
90
        /**
91
         * this will return updated last authentication date
92
         *
93
         * @return
94
         */
95
        public Date getLastAuthentication()
96
        {
97
                return lastAuthentication;
98
        }
99
100
        /**
101
         * this will override the existing token expected date and time
102
         *
103
         * @param LastAuthentication
104
         */
105
        public void setTokenExpectedDateTime(Date tokenExpectedDateTime)
106
        {
107
                this.tokenExpectedDateTime = tokenExpectedDateTime;
108
        }
109
110
        /**
111
         * this will return updated token expected date and time
112
         *
113
         * @return
114
         */
115
        public Date getTokenExpectedDateTime()
116
        {
117
                return tokenExpectedDateTime;
118
        }
119
120
        /**
121
         * this will override the existing tokenBean
122
         *
123
         */
124
        public void setObject(TokenBean tokenBean)
125
        {
126
                this.tb = tokenBean;
127
        }
128
129
        /**
130
         * this will return the updated object (tokenBean)
131
         *
132
         */
133
        public TokenBean getUpdatedObject()
134
        {
135
                return tb;
136
        }
137
138
        /**
139
         * this will override the existing serial number
140
         *
141
         */
142
        private void setSerialNumber()
143
        {
144
                this.serialNumber = tb.getVserialNumber();
145
        }
146
147
        /**
148
         * this will override the existing authentication mode
149
         *
150
         */
151
        private void setAuthMode()
152
        {
153
                this.authMode = tb.getVdpAuthMode();
154
        }
155
156
        /**
157
         * this will override the existing blob
158
         *
159
         */
160
        private void setBlob()
161
        {
162
                this.blob = tb.getVdpCipherText();
163
        }
164
165
        /**
166
         * this will return the updated blob
167
         *
168
         */
169
        public byte[] getUpdatedBlob()
170
        {
171
                return this.blob;
172
        }
173
174
        /**
175
         * this will override the existing useCount
176
         *
177
         */
178
        public void setUseCount()
179
        {
180
                this.useCount = tb.getVuseCount();
181
        }
182
183
        /**
184
         * this will increase the existing useCount by 1 whenever it is invoked.
185
         *
186
         */
187
        public void increaseUseCount()
188
        {
189
                this.useCount++;
190
        }
191
192
        /**
193
         * this will return the updated useCount
194
         *
195
         */
196
        public int getUseCount()
197
        {
198
                return this.useCount;
199
        }
200
201
        /**
202
         * this will override the existing errorCount
203
         *
204
         */
205
        public void setErrorCount()
206
        {
207
                this.errorCount = tb.getVerrorCount();
208
        }
209
210
        /**
211
         * this will increase the existing errorCount by 1 whenever it is invoked.
212
         *
213
         */
214
        public void increaseErrorCount()
215
        {
216
                this.errorCount++;
217
        }
218
219
        /**
220
         * this will return the updated errorCount
221
         *
222
         */
223
        public int getErrorCount()
224
        {
225
                return this.errorCount;
226
        }
227
228
        /**
229
         * this will override the existing first used date
230
         *
231
         */
232
        public void setFirstTimeUsed()
233
        {
234
                this.firstTimeUsed = tb.getVdateFirstUsed();
235
        }
236
237
        /**
238
         * case 1: if first used date is null, then first used date will be override by current date.
239
         * case 2: throw exception if first used date is after last used date.
240
         *
241
         * @param currentDate
242
         * @throws Exception
243
         */
244
        public void setFirstTimeUsed(Date currentDate) throws Exception
245
        {
246
                if(this.firstTimeUsed == null)
247
                {
248
                        this.firstTimeUsed = currentDate;
249
                }
250
                else if(this.firstTimeUsed.compareTo(this.lastTimeUsed) > 0)
251
                {
252
                        throw new Exception("Invalid date. First used date cannot be after last used date.");
253
                }
254
        }
255
256
        /**
257
         * this will return the updated first used date
258
         *
259
         */
260
        public Date getFirstTimeUsed()
261
        {
262
                return firstTimeUsed;
263
        }
264
265
        /**
266
         * this will override the existing last used date.
267
         *
268
         */
269
        public void setLastTimeUsed()
270
        {
271
                this.lastTimeUsed = tb.getVdateFirstUsed();
272
        }
273
274
        /**
275
         * case 1: if last used date is null, then last used date will be override by current date.
276
         * case 2: if last used date is before the current date, then last used date will be override by current date.
277
         * case 3: throw exception if last used date is after the current date.
278
         * case 4: throw exception if last used date is before first used date.
279
         *
280
         * @param currentDate
281
         * @throws Exception
282
         */
283
        public void setLastTimeUsed(Date currentDate) throws Exception
284
        {
285
                if(this.lastTimeUsed == null)
286
                {
287
                        this.lastTimeUsed = currentDate;
288
                }
289
                else if(this.lastTimeUsed.compareTo(currentDate) < 0)
290
                {
291
                        this.lastTimeUsed = currentDate;
292
                }
293
                else if(this.lastTimeUsed.compareTo(currentDate) > 0)
294
                {
295
                        throw new Exception("Invalid date. Last used date cannot be after current date.");
296
                }
297
                else if(this.lastTimeUsed.compareTo(this.firstTimeUsed) < 0)
298
                {
299
                        throw new Exception("Invalid date. Last used date cannot be before first used date.");
300
                }
301
        }
302
303
        /**
304
         * this will return the updated last used date
305
         *
306
         */
307
        public Date getLastTimeUsed()
308
        {
309
                return lastTimeUsed;
310
        }
311
312
        /**
313
         * this will return the updated returned code by each invoked method
314
         * it also acts as last returned error code.
315
         *
316
         */
317
        public int getRetCode()
318
        {
319
                return retCode;
320
        }
321
322
        /**
323
         * this will return the updated error text based on the error code
324
         *
325
         */
326
        public String getLastError()
327
        {
328
                String code = null;
329
330
                switch(this.retCode)
331
                {
332
                        case 0: code = "0";
333
                        case 1: code = "1";
334
                        case 2: code = "18";
335
                        case 3: code = "19";
336
                        case 4: code = "20";
337
                        case 5: code = "21";
338
                        case 6: code = "22";
339
                        case 7: code = "3";
340
                        case 8: code = "23";
341
                        case 9: code = "24";
342
                        case 10: code = "25";
343
                        case 11: code = "26";
344
                        default:
345
                                try
346
                                {
347
                                        throw new Exception("Invalid error code.");
348
                                }
349
                                catch (Exception e)
350
                                {
351
                                        e.printStackTrace();
352
                                }
353
                }
354
355
                return Constants.getErrText(code).get(code);
356
        }
357
358
        /**
359
         * Verify the entered On Time Password (OTP/password) for the given token
360
         *
361
         */
362
        public int verifyToken(String otp, String userAlias, String pin) throws Exception
363
        {
364
                return verifyToken(otp);
365
        }
366
        /**
367
         * Verify the entered On Time Password (OTP/password) for the given token
368
         *
369
         */
370
371
        public int verifyToken(String password)
372
        {
373
                int[] blobLen = new int[1];
374
                blobLen[0]=500;
375
376
                String[] blobInString = new String[1];
377
                blobInString[0] = new String(this.blob);
378
379
                //Time based OTP verification
380
                //Authentication window need to be bigger for first OTP verification.
381
                int result = myocra.comAuthBlob(0, 0, this.serialNumber, Constants.getAuthenticationMode(this.authMode), 20, 1, 100,
382
                                                        new byte[0], 0,
383
                                                        new byte[0], 0,
384
                                                        new byte[0], 0,
385
                                                        6, password,
386
                                                        blobInString, blobLen);
387
388
                this.useCount++;
389
                this.firstTimeUsed = new Date();
390
                this.lastTimeUsed = new Date();
391
392
                if(result == 0)
393
                {
394
                        this.blob = blobInString[0].getBytes();
395
                        this.retCode = result;
396
                        updateTokenObject();
397
                }
398
                else
399
                {
400
                        try
401
                        {
402
                                this.errorCount++;
403
                                this.retCode = result;
404
                                updateTokenObject();
405
                                return errorCodeConversion(result);
406
                        }
407
                        catch (Exception e)
408
                        {
409
                                e.printStackTrace();
410
                        }
411
                }
412
413
                return Constants.ERR_SUCCESS;
414
        }
415
416
        /**
417
         * Check last successful authentication
418
         *
419
         * @return
420
         */
421
        public int checkLastAuthentication()
422
        {
423
                String[] blobInString = new String[1];
424
                blobInString[0] = new String(this.blob);
425
                int [] LastAuthTime = new int[1];
426
        int [] TokenExpectedTime = new int[1];
427
428
                int result = myocra.comGetInfo(0, 0, serialNumber, Constants.getAuthenticationMode("AUTH_OCRA"), blobInString, blobInString[0].length(), LastAuthTime, TokenExpectedTime);
429
430
                if(result == 0)
431
                {
432
                        //For first use of blob, LastAuthTimeDate returns a value of 0 or in Date format, Thu Jan 01 07:30:00 SGT 1970.
433
                        if(LastAuthTime[0] == 0)
434
                        {
435
                                System.out.println("No Last authentication.");
436
                        }
437
                        else
438
                        {
439
                                this.blob = blobInString[0].getBytes();
440
                                this.lastAuthentication = new Date(Long.parseLong(""+LastAuthTime[0])* 1000);
441
                    this.tokenExpectedDateTime = new Date(Long.parseLong(""+TokenExpectedTime[0])* 1000);
442
                    this.retCode = result;
443
                        }
444
                }
445
                else
446
                {
447
                        try
448
                        {
449
                                this.errorCount++;
450
                                this.retCode = result;
451
                                updateTokenObject();
452
                                return errorCodeConversion(result);
453
                        }
454
                        catch (Exception e)
455
                        {
456
                                e.printStackTrace();
457
                        }
458
                }
459
460
                return Constants.ERR_SUCCESS;
461
        }
462
463
        /**
464
         * In order to perform blob synchronization, 2 token verifications shall be performed .
465
         * First token verification must have larger time drift windows then the second's.
466
         * First token verification must be executed first before execute the second.
467
         * Second token verification must use new password (OTP) and lesser time drift window.
468
         * If the returned result of first verification is successful or 0, then second verification will be executed.
469
         * If the returned results of both first and second verifications are successful or 0, then blobSynchronization is successful,
470
         * otherwise, it is failed.
471
         *
472
         *
473
         * @param timeDriftWindow
474
         * @param password
475
         * @return
476
         */
477
        public int blobSynchronization(int timeDriftWindow1, String password1, int timeDriftWindow2, String password2)
478
        {
479
                int result = blobSynchronizationTokenVerification(timeDriftWindow1, password1);
480
481
                if(result == 0)
482
                {
483
                        result = blobSynchronizationTokenVerification(timeDriftWindow2, password2);
484
485
                        if(result == 0)
486
                        {
487
                                this.retCode = result;
488
                                updateTokenObject();
489
                        }
490
                        else
491
                        {
492
                                try
493
                                {
494
                                        this.errorCount++;
495
                                        this.retCode = result;
496
                                        updateTokenObject();
497
                                        return errorCodeConversion(result);
498
                                }
499
                                catch (Exception e)
500
                                {
501
                                        e.printStackTrace();
502
                                }
503
                        }
504
                }
505
                else
506
                {
507
                        try
508
                        {
509
                                this.retCode = result;
510
                                return errorCodeConversion(result);
511
                        }
512
                        catch (Exception e)
513
                        {
514
                                e.printStackTrace();
515
                        }
516
                }
517
518
                return Constants.ERR_SUCCESS;
519
        }
520
521
        /**
522
         * This method will be used in blobSynchronization to verify the token and blob synchronization
523
         *
524
         * @param timeDriftWindow
525
         * @param password
526
         * @return
527
         */
528
        private int blobSynchronizationTokenVerification(int timeDriftWindow, String password)
529
        {
530
                if(this.retCode == 0)
531
                {
532
                        int[] blobLen = new int[1];
533
                        blobLen[0]=500;
534
535
                        String[] blobInString = new String[1];
536
                        blobInString[0] = new String(this.blob);
537
538
                        //Time based OTP verification
539
                        //Authentication window need to be bigger for first OTP verification.
540
                        int result = myocra.comAuthBlob(0, 0, this.serialNumber, Constants.getAuthenticationMode(this.authMode), timeDriftWindow, 1, 100,
541
                                                                new byte[0], 0,
542
                                                                new byte[0], 0,
543
                                                                new byte[0], 0,
544
                                                                6, password,
545
                                                                blobInString, blobLen);
546
547
                        this.useCount++;
548
                        this.firstTimeUsed = new Date();
549
                        this.lastTimeUsed = new Date();
550
551
                        if(result == 0)
552
                        {
553
                                this.blob = blobInString[0].getBytes();
554
                                this.retCode = result;
555
                                updateTokenObject();
556
                        }
557
                        else
558
                        {
559
                                try
560
                                {
561
                                        this.errorCount++;
562
                                        this.retCode = result;
563
                                        updateTokenObject();
564
                                        return errorCodeConversion(result);
565
                                }
566
                                catch (Exception e)
567
                                {
568
                                        e.printStackTrace();
569
                                }
570
                        }
571
572
                }
573
574
                return Constants.ERR_SUCCESS;
575
        }
576
577
        /**
578
         * This will reset the token back to the initial state
579
         * The blob will be regenerated with the backup blob which is initially generated when it is imported from the pskc file.
580
         *
581
         */
582
        public int resetToken()
583
        {
584
                this.retCode = 0;
585
                this.blob = tb.getVbkCipherText();
586
                this.useCount = 0;
587
                this.errorCount = 0;
588
                this.lastTimeUsed = null;
589
                this.firstTimeUsed = null;
590
                this.lastAuthentication = null;
591
                this.tokenExpectedDateTime = null;
592
                updateTokenObject();
593
594
                return Constants.ERR_SUCCESS;
595
        }
596
597
        public HashMap<String, String> getTokenBlobInfo()
598
        {
599
                HashMap<String,String>  map = new HashMap<String,String>();
600
601
                map.put("TOKEN_MODEL", tb.getVdpModel());
602
                map.put("USE_COUNT",  Integer.toString(tb.getVuseCount()));
603
                map.put("ERROR_COUNT",  Integer.toString(tb.getVerrorCount()));
604
                map.put("LAST_TIME_USED", String.valueOf (tb.getVdateLastUsed()));
605
                map.put("TIME_STEP_USED", Integer.toString(Constants.TIMESTEPUSED));
606
607
                return map;
608
        }
609
610
        /**
611
         * display gemalto token information
612
         * In comparion with vasco, only limited information will be displayed.
613
         *
614
         */
615
        public void displayTokenInfo()
616
        {
617
                System.out.println("--Info----------------------------------------------");
618
                System.out.println("TOKEN_MODEL......." + tb.getVdpModel());
619
                System.out.println("USE_COUNT........." + tb.getVuseCount());
620
                System.out.println("ERR_COUNT........." + tb.getVerrorCount());
621
                System.out.println("LAST_TIME_USED...." + tb.getVdateLastUsed());
622
                System.out.println("TIME_STEP_USED...." + Constants.TIMESTEPUSED);
623
                System.out.println("----------------------------------------------------");
624
        }
625
626
        /**
627
         * This will override the existing tokenBean object
628
         *
629
         */
630
        private void updateTokenObject()
631
        {
632
                tb.setVuseCount(this.useCount );
633
                tb.setVerrorCount(this.errorCount );
634
                tb.setVdpCipherText(this.blob);
635
                tb.setVdateFirstUsed(this.firstTimeUsed);
636
                tb.setVdateLastUsed(this.lastTimeUsed);
637
        }
638
639
640
641
        /*
642
         * Code the gemalto returned error code to match with vasco's
643
         *
644
         */
645
        private int errorCodeConversion(int errorCode) throws Exception
646
        {
647
                switch(errorCode)
648
                {
649
                        case 0: return Constants.ERR_SUCCESS;
650
                        case 1: return Constants.ERR_INVALID_CREDENTIAL;
651
                        case 2: return Constants.ERR_BLOBINVALID;
652
                        case 3: return Constants.ERR_BUFFER;
653
                        case 4: return Constants.ERR_PARAM;
654
                        case 5: return Constants.ERR_SNOINVALID;
655
                        case 6: return Constants.ERR_OTPINVALID;
656
                        case 7: return Constants.ERR_REUSED_PASSWD;
657
                        case 8: return Constants.ERR_BLOBOTINIT;
658
                        case 9: return Constants.ERR_FAILED;
659
                        case 10: return Constants.ERR_REQINVALID;
660
                        case 11: return Constants.ERR_AUTH_MODE;
661
                        default: throw new Exception("Invalid error code.");
662
                }
663
        }
664
665
        public int syncToken(String userAlias, String otp1, String otp2) {
666
                // TODO Auto-generated method stub
667
                return 0;
668
        }
669
}