@@ -12,6 +12,7 @@ import (
12
12
"io"
13
13
"math/big"
14
14
"strconv"
15
+ "strings"
15
16
"time"
16
17
17
18
"github.com/digitorus/pkcs7"
@@ -22,6 +23,8 @@ import (
22
23
type FailureInfo int
23
24
24
25
const (
26
+ // UnkownFailureInfo mean that no known failure info was provided
27
+ UnkownFailureInfo FailureInfo = - 1
25
28
// BadAlgorithm defines an unrecognized or unsupported Algorithm Identifier
26
29
BadAlgorithm FailureInfo = 0
27
30
// BadRequest indicates that the transaction not permitted or supported
@@ -63,35 +66,32 @@ func (f FailureInfo) String() string {
63
66
case SystemFailure :
64
67
return "the request cannot be handled due to system failure"
65
68
default :
66
- return "unknown failure: " + strconv . Itoa ( int ( f ))
69
+ return "unknown failure"
67
70
}
68
71
}
69
72
70
- // PKIStatus contains the status of an Time-Stamp request. See
73
+ // Status contains the status of an Time-Stamp request. See
71
74
// https://tools.ietf.org/html/rfc3161#section-2.4.2
72
- type PKIStatus int
75
+ type Status int
73
76
74
77
const (
75
- // Granted PKIStatus contains the value zero a TimeStampToken, as requested, is present.
76
- Granted PKIStatus = 0
77
-
78
- // GrantedWithMods PKIStatus contains the value one a TimeStampToken, with modifications, is present.
79
- GrantedWithMods PKIStatus = 1
80
-
78
+ // Granted PKIStatus contains the value zero a TimeStampToken, as requested,
79
+ // is present.
80
+ Granted Status = 0
81
+ // GrantedWithMods PKIStatus contains the value one a TimeStampToken, with
82
+ // modifications, is present.
83
+ GrantedWithMods Status = 1
81
84
// Rejection PKIStatus
82
- Rejection PKIStatus = 2
83
-
85
+ Rejection Status = 2
84
86
// Waiting PKIStatus
85
- Waiting PKIStatus = 3
86
-
87
+ Waiting Status = 3
87
88
// RevocationWarning PKIStatus
88
- RevocationWarning PKIStatus = 4
89
-
89
+ RevocationWarning Status = 4
90
90
// RevocationNotification PKIStatus
91
- RevocationNotification PKIStatus = 5
91
+ RevocationNotification Status = 5
92
92
)
93
93
94
- func (s PKIStatus ) String () string {
94
+ func (s Status ) String () string {
95
95
switch s {
96
96
case Granted :
97
97
return "the request is granted"
@@ -215,6 +215,9 @@ func (req *Request) Marshal() ([]byte, error) {
215
215
// Timestamp represents an Time-Stamp. See:
216
216
// https://tools.ietf.org/html/rfc3161#section-2.4.1
217
217
type Timestamp struct {
218
+ // Timestamp token part of raw ASN.1 DER content.
219
+ RawToken []byte
220
+
218
221
HashAlgorithm crypto.Hash
219
222
HashedMessage []byte
220
223
@@ -263,8 +266,15 @@ func ParseResponse(bytes []byte) (*Timestamp, error) {
263
266
}
264
267
265
268
if resp .Status .Status > 0 {
266
- return nil , ParseError (fmt .Sprintf ("%s: %s" ,
267
- FailureInfo (int (resp .Status .FailInfo .Bytes [0 ])).String (), resp .Status .StatusString ))
269
+ var fis string
270
+ fi := resp .Status .FailureInfo ()
271
+ if fi != UnkownFailureInfo {
272
+ fis = fi .String ()
273
+ }
274
+ return nil , fmt .Errorf ("%s: %s (%v)" ,
275
+ resp .Status .Status .String (),
276
+ strings .Join (resp .Status .StatusString , "," ),
277
+ fis )
268
278
}
269
279
270
280
if len (resp .TimeStampToken .Bytes ) == 0 {
@@ -305,6 +315,7 @@ func Parse(bytes []byte) (*Timestamp, error) {
305
315
}
306
316
307
317
ret := & Timestamp {
318
+ RawToken : bytes ,
308
319
HashedMessage : inf .MessageImprint .HashedMessage ,
309
320
Time : inf .Time ,
310
321
Accuracy : time .Duration ((time .Second * time .Duration (inf .Accuracy .Seconds )) +
@@ -427,12 +438,15 @@ func (t *Timestamp) CreateResponse(signingCert *x509.Certificate, priv crypto.Si
427
438
return tspResponseBytes , nil
428
439
}
429
440
430
- //CreateErrorResponse is used to create response other than granted and granted with mod status
431
- func CreateErrorResponse (pkiStatus PKIStatus , pkiFailureInfo FailureInfo ) ([]byte , error ) {
441
+ // CreateErrorResponse is used to create response other than granted and granted with mod status
442
+ func CreateErrorResponse (pkiStatus Status , pkiFailureInfo FailureInfo ) ([]byte , error ) {
443
+ var bs asn1.BitString
444
+ setFlag (& bs , int (pkiFailureInfo ))
445
+
432
446
timestampRes := response {
433
447
Status : pkiStatusInfo {
434
448
Status : pkiStatus ,
435
- FailInfo : asn1. BitString { Bytes : [] byte { byte ( pkiFailureInfo )}, BitLength : 8 } ,
449
+ FailInfo : bs ,
436
450
},
437
451
}
438
452
tspResponseBytes , err := asn1 .Marshal (timestampRes )
@@ -442,6 +456,18 @@ func CreateErrorResponse(pkiStatus PKIStatus, pkiFailureInfo FailureInfo) ([]byt
442
456
return tspResponseBytes , nil
443
457
}
444
458
459
+ func setFlag (bs * asn1.BitString , i int ) {
460
+ for l := len (bs .Bytes ); l < 4 ; l ++ {
461
+ (* bs ).Bytes = append ((* bs ).Bytes , byte (0 ))
462
+ (* bs ).BitLength = len ((* bs ).Bytes ) * 8
463
+ }
464
+ b := i / 8
465
+ p := uint (7 - (i - 8 * b ))
466
+ (* bs ).Bytes [b ] = (* bs ).Bytes [b ] | (1 << p )
467
+ bs .BitLength = asn1BitLength (bs .Bytes )
468
+ bs .Bytes = bs .Bytes [0 : (bs .BitLength / 8 )+ 1 ]
469
+ }
470
+
445
471
func getMessageImprint (hashAlgorithm crypto.Hash , hashedMessage []byte ) messageImprint {
446
472
messageImprint := messageImprint {
447
473
HashAlgorithm : pkix.AlgorithmIdentifier {
0 commit comments