1
1
using System ;
2
2
using System . Collections ;
3
3
using System . IO ;
4
+ using System . Text ;
4
5
using Org . BouncyCastle . Asn1 ;
6
+ using Org . BouncyCastle . Asn1 . Cms ;
5
7
using Org . BouncyCastle . Asn1 . Ess ;
6
8
using Org . BouncyCastle . Asn1 . Oiw ;
7
9
using Org . BouncyCastle . Asn1 . Pkcs ;
17
19
18
20
namespace Org . BouncyCastle . Tsp
19
21
{
22
+ public enum Resolution
23
+ {
24
+ R_SECONDS , R_TENTHS_OF_SECONDS , R_HUNDREDTHS_OF_SECONDS , R_MILLISECONDS
25
+ }
26
+
20
27
public class TimeStampTokenGenerator
21
28
{
22
29
private int accuracySeconds = - 1 ;
@@ -31,6 +38,14 @@ public class TimeStampTokenGenerator
31
38
private SignerInfoGenerator signerInfoGenerator ;
32
39
IDigestFactory digestCalculator ;
33
40
41
+ private Resolution resolution = Resolution . R_SECONDS ;
42
+
43
+ public Resolution Resolution
44
+ {
45
+ get { return resolution ; }
46
+ set { resolution = value ; }
47
+ }
48
+
34
49
/**
35
50
* basic creation - only the default attributes will be included here.
36
51
*/
@@ -289,8 +304,18 @@ public TimeStampToken Generate(
289
304
tsaPolicy = new DerObjectIdentifier ( request . ReqPolicy ) ;
290
305
}
291
306
307
+ DerGeneralizedTime generalizedTime ;
308
+ if ( resolution != Resolution . R_SECONDS )
309
+ {
310
+ generalizedTime = new DerGeneralizedTime ( createGeneralizedTime ( genTime ) ) ;
311
+ } else
312
+ {
313
+ generalizedTime = new DerGeneralizedTime ( genTime ) ;
314
+ }
315
+
316
+
292
317
TstInfo tstInfo = new TstInfo ( tsaPolicy , messageImprint ,
293
- new DerInteger ( serialNumber ) , new DerGeneralizedTime ( genTime ) , accuracy ,
318
+ new DerInteger ( serialNumber ) , generalizedTime , accuracy ,
294
319
derOrdering , nonce , tsa , request . Extensions ) ;
295
320
296
321
try
@@ -333,6 +358,56 @@ public TimeStampToken Generate(
333
358
// }
334
359
}
335
360
361
+ private string createGeneralizedTime ( DateTime genTime )
362
+ {
363
+ String format = "yyyyMMddHHmmss.fff" ;
364
+
365
+ StringBuilder sBuild = new StringBuilder ( genTime . ToString ( format ) ) ;
366
+ int dotIndex = sBuild . ToString ( ) . IndexOf ( "." ) ;
367
+
368
+ if ( dotIndex < 0 )
369
+ {
370
+ sBuild . Append ( "Z" ) ;
371
+ return sBuild . ToString ( ) ;
372
+ }
373
+
374
+ switch ( resolution )
375
+ {
376
+ case Resolution . R_TENTHS_OF_SECONDS :
377
+ if ( sBuild . Length > dotIndex + 2 )
378
+ {
379
+ sBuild . Remove ( dotIndex + 2 , sBuild . Length - ( dotIndex + 2 ) ) ;
380
+ }
381
+ break ;
382
+ case Resolution . R_HUNDREDTHS_OF_SECONDS :
383
+ if ( sBuild . Length > dotIndex + 3 )
384
+ {
385
+ sBuild . Remove ( dotIndex + 3 , sBuild . Length - ( dotIndex + 3 ) ) ;
386
+ }
387
+ break ;
388
+
389
+
390
+ case Resolution . R_SECONDS :
391
+ case Resolution . R_MILLISECONDS :
392
+ // do nothing.
393
+ break ;
394
+
395
+ }
396
+
397
+
398
+ while ( sBuild [ sBuild . Length - 1 ] == '0' )
399
+ {
400
+ sBuild . Remove ( sBuild . Length - 1 , 1 ) ;
401
+ }
402
+
403
+ if ( sBuild . Length - 1 == dotIndex )
404
+ {
405
+ sBuild . Remove ( sBuild . Length - 1 , 1 ) ;
406
+ }
407
+
408
+ sBuild . Append ( "Z" ) ;
409
+ return sBuild . ToString ( ) ;
410
+ }
336
411
337
412
private class TableGen : CmsAttributeTableGenerator
338
413
{
0 commit comments