2
2
* Author : Francesco
3
3
* Created at: 2023-12-09 17:52
4
4
* Edited by : Francesco
5
- * Edited at : 2023-12-10 10:06
5
+ * Edited at : 2023-12-13 20:41
6
6
*
7
7
* Copyright (c) 2023 Xevolab S.R.L.
8
8
*/
@@ -23,14 +23,18 @@ export class TimeStampResp {
23
23
public certReq ?: boolean ;
24
24
25
25
// Credentials
26
- private key : KeyObject ;
26
+ private key ? : KeyObject ;
27
27
public certs ?: X509Certificate [ ] ;
28
28
29
29
// Response
30
30
public signingTime ! : Date ;
31
31
public serialNumber ! : Buffer ;
32
32
public buffer ! : Buffer ;
33
33
34
+ // Signature
35
+ public payloadDigest ?: Buffer ;
36
+ public signedDigest ?: Buffer ;
37
+
34
38
/**
35
39
* Creates an instance of TimeStampResp.
36
40
* This class is used to generate a response
@@ -62,16 +66,16 @@ export class TimeStampResp {
62
66
nonce ?: number | Buffer | Uint8Array ,
63
67
certReq ?: boolean ,
64
68
65
- key : KeyObject ,
69
+ key ? : KeyObject ,
66
70
certs ?: X509Certificate [ ] ,
67
71
68
72
signingOptions ?: SignOptions ,
69
73
} ) {
70
74
this . hashedMessage = hashedMessage ;
71
75
this . hashAlgorithm = hashAlgorithm ;
72
76
73
- this . version = version || 2 ;
74
- this . reqPolicy = reqPolicy ;
77
+ this . version = version || 1 ;
78
+ this . reqPolicy = reqPolicy || "1.2.3.4" ;
75
79
this . nonce = nonce ;
76
80
this . certReq = certReq ;
77
81
@@ -110,7 +114,8 @@ export class TimeStampResp {
110
114
111
115
// --> Loading the key(s)
112
116
113
- if ( ! key || ! ( key instanceof KeyObject ) ) throw new Error ( "Invalid key; needs to be a KeyObject." ) ;
117
+ if ( key && ! ( key instanceof KeyObject ) ) throw new Error ( "Invalid key; needs to be a KeyObject." ) ;
118
+ if ( ! key && ! opts ?. externalSignature ) throw new Error ( "Missing key. Please, provide a key or enable external signature function." ) ;
114
119
115
120
// --> Loading the certificates
116
121
@@ -145,7 +150,7 @@ export class TimeStampResp {
145
150
// version
146
151
// TODO: support v1 and get version from request
147
152
// NOTE: is it really needed?
148
- new asn1js . Integer ( { value : 2 } ) ,
153
+ new asn1js . Integer ( { value : this . version } ) ,
149
154
150
155
/**
151
156
* TSAPolicyId ::= OBJECT IDENTIFIER
@@ -244,15 +249,24 @@ export class TimeStampResp {
244
249
]
245
250
} ) ;
246
251
247
- const messageDigest = createHash ( "SHA-512" ) . update ( Buffer . from ( payload . toBER ( false ) ) ) . digest ( "hex" ) ;
252
+ this . payloadDigest = createHash ( signingHashAlgorithm ) . update ( Buffer . from ( payload . toBER ( false ) ) ) . digest ( ) ;
248
253
249
254
// --> Generating the signature
250
255
251
256
// The signature is generated using the private key of the TSA, by signing the DER encoded
252
257
// payload and, if present, the signed attributes.
253
- const signature = sign ( "SHA512" , Buffer . from ( ( new asn1js . Set ( {
254
- value : getSignedAttributes ( messageDigest , this . signingTime , certs ) ,
255
- } ) . toBER ( false ) ) ) , keyForAlg ( key ) ) ;
258
+ let signature = Buffer . from ( ( new asn1js . Set ( {
259
+ value : getSignedAttributes ( this . payloadDigest , this . signingTime , certs ) ,
260
+ } ) . toBER ( false ) ) ) ;
261
+ this . signedDigest = createHash ( signingHashAlgorithm ) . update ( signature ) . digest ( )
262
+
263
+ // If the signature is generated using an external signer, the signature is filled with only
264
+ // the hash of the payload.
265
+ if ( opts ?. externalSignature || ! key ) {
266
+ signature = Buffer . from ( "00" , "hex" ) ;
267
+ } else {
268
+ signature = sign ( signingHashAlgorithm , signature , keyForAlg ( key ) ) ;
269
+ }
256
270
257
271
/**
258
272
* TimeStampResp ::= SEQUENCE {
@@ -506,7 +520,7 @@ export class TimeStampResp {
506
520
*/
507
521
new asn1js . Constructed ( {
508
522
idBlock : { tagClass : 3 , tagNumber : 0 } ,
509
- value : getSignedAttributes ( messageDigest , this . signingTime , certs ) ,
523
+ value : getSignedAttributes ( this . payloadDigest , this . signingTime , certs ) ,
510
524
} ) ,
511
525
512
526
/**
@@ -525,7 +539,7 @@ export class TimeStampResp {
525
539
* SignatureValue ::= OCTET STRING
526
540
*/
527
541
new asn1js . OctetString ( {
528
- valueHex : signature . buffer
542
+ valueHex : signature
529
543
} ) ,
530
544
531
545
]
@@ -541,10 +555,24 @@ export class TimeStampResp {
541
555
return Buffer . from ( TimeStampResp . toBER ( false ) ) ;
542
556
}
543
557
558
+ public setSignature ( signature : Buffer ) {
559
+ const tmp = asn1js . fromBER ( this . buffer ) ;
560
+ // @ts -ignore
561
+ let ref = tmp . result . valueBlock . value [ 1 ] . valueBlock . value [ 1 ] . valueBlock . value [ 0 ] . valueBlock . value ;
562
+ ref = ref . at ( - 1 ) . valueBlock . value [ 0 ] . valueBlock . value . at ( - 1 ) ;
563
+ console . log ( Buffer . from ( ref . valueBlock . valueHexView ) ) ;
564
+
565
+ ref . valueBlock . valueHexView = signature
566
+
567
+ this . buffer = Buffer . from ( tmp . result . toBER ( false ) ) ;
568
+ }
569
+
544
570
}
545
571
546
- type SignOptions = {
547
- signingHashAlgorithm : "SHA512" ,
572
+ export type SignOptions = {
573
+ signingHashAlgorithm ?: "SHA256" | "SHA384" | "SHA512" ,
574
+
575
+ externalSignature ?: boolean
548
576
}
549
577
550
578
// ---------------------------------------------------------------------------------------------
@@ -561,7 +589,7 @@ function keyForAlg(key: KeyObject): KeyObject | SignKeyObjectInput {
561
589
throw new TypeError ( `key is is not supported` ) ;
562
590
}
563
591
564
- function getSignedAttributes ( messageHash : string , signingTime : Date , certs : X509Certificate [ ] = [ ] ) {
592
+ function getSignedAttributes ( messageHash : Buffer , signingTime : Date , certs : X509Certificate [ ] = [ ] ) {
565
593
return [
566
594
// contentType
567
595
new asn1js . Sequence ( {
@@ -601,7 +629,7 @@ function getSignedAttributes(messageHash: string, signingTime: Date, certs: X509
601
629
} ) ,
602
630
new asn1js . Set ( {
603
631
value : [
604
- new asn1js . OctetString ( { valueHex : Buffer . from ( messageHash , "hex" ) } )
632
+ new asn1js . OctetString ( { valueHex : messageHash } )
605
633
]
606
634
} )
607
635
]
0 commit comments