@@ -229,6 +229,288 @@ describe("Object support in XML signatures", function () {
229
229
expect ( isValid ) . to . be . true ;
230
230
} ) ;
231
231
232
+ it ( "should sign Object with SHA256 digest algorithm" , function ( ) {
233
+ // Create a simple XML document to sign
234
+ const xml = '<root><x xmlns="ns"></x><y attr="value"></y><z><w></w></z></root>' ;
235
+
236
+ // Create a SignedXml instance with custom getObjectContent
237
+ const sig = new SignedXml ( {
238
+ getObjectContent : ( ) => [
239
+ {
240
+ content : "<Data>Test data for SHA256 digest</Data>" ,
241
+ attributes : {
242
+ Id : "object1" ,
243
+ MimeType : "text/xml" ,
244
+ } ,
245
+ } ,
246
+ ] ,
247
+ } ) ;
248
+
249
+ // Set up the signature
250
+ sig . privateKey = fs . readFileSync ( "./test/static/client.pem" ) ;
251
+
252
+ // Add a reference to the document element
253
+ sig . addReference ( {
254
+ xpath : "//*[local-name(.)='x']" ,
255
+ digestAlgorithm : "http://www.w3.org/2001/04/xmlenc#sha256" ,
256
+ transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
257
+ } ) ;
258
+
259
+ // Add a reference to the Object element with SHA256
260
+ sig . addReference ( {
261
+ xpath : "//*[@Id='object1']" ,
262
+ digestAlgorithm : "http://www.w3.org/2001/04/xmlenc#sha256" ,
263
+ transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
264
+ isSignatureReference : true ,
265
+ } ) ;
266
+
267
+ // Set required algorithms
268
+ sig . canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" ;
269
+ sig . signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" ;
270
+
271
+ // Compute the signature
272
+ sig . computeSignature ( xml ) ;
273
+
274
+ // Get the signed XML
275
+ const signedXml = sig . getSignedXml ( ) ;
276
+
277
+ // Parse the signed XML
278
+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
279
+
280
+ // Verify that the ds:Object element exists
281
+ const objectNodes = xpath . select ( "//*[local-name(.)='Object']" , doc ) ;
282
+ isDomNode . assertIsArrayOfNodes ( objectNodes ) ;
283
+ expect ( objectNodes . length ) . to . equal ( 1 ) ;
284
+
285
+ // Verify that there are two Reference elements
286
+ const referenceNodes = xpath . select ( "//*[local-name(.)='Reference']" , doc ) ;
287
+ isDomNode . assertIsArrayOfNodes ( referenceNodes ) ;
288
+ expect ( referenceNodes . length ) . to . equal ( 2 ) ;
289
+
290
+ // Verify that the references use SHA256
291
+ const digestMethodNodes = xpath . select ( "//*[local-name(.)='DigestMethod']" , doc ) ;
292
+ isDomNode . assertIsArrayOfNodes ( digestMethodNodes ) ;
293
+
294
+ for ( const digestMethod of digestMethodNodes ) {
295
+ isDomNode . assertIsElementNode ( digestMethod ) ;
296
+ expect ( digestMethod . getAttribute ( "Algorithm" ) ) . to . equal (
297
+ "http://www.w3.org/2001/04/xmlenc#sha256" ,
298
+ ) ;
299
+ }
300
+
301
+ // Verify that the signature method is RSA-SHA256
302
+ const signatureMethod = xpath . select1 ( "//*[local-name(.)='SignatureMethod']" , doc ) ;
303
+ isDomNode . assertIsElementNode ( signatureMethod ) ;
304
+ expect ( signatureMethod . getAttribute ( "Algorithm" ) ) . to . equal (
305
+ "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" ,
306
+ ) ;
307
+
308
+ // Verify that the signature is still valid
309
+ const verifier = new SignedXml ( ) ;
310
+ verifier . publicCert = fs . readFileSync ( "./test/static/client_public.pem" ) ;
311
+
312
+ // First load the signature
313
+ const signatureNode = xpath . select1 (
314
+ "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']" ,
315
+ doc ,
316
+ ) ;
317
+ isDomNode . assertIsNodeLike ( signatureNode ) ;
318
+ verifier . loadSignature ( signatureNode ) ;
319
+
320
+ // Then check the signature
321
+ const isValid = verifier . checkSignature ( signedXml ) ;
322
+ expect ( isValid ) . to . be . true ;
323
+ } ) ;
324
+
325
+ it ( "should sign Object with SHA512 digest algorithm and RSA-SHA512 signature" , function ( ) {
326
+ // Create a simple XML document to sign
327
+ const xml = '<root><x xmlns="ns"></x><y attr="value"></y><z><w></w></z></root>' ;
328
+
329
+ // Create a SignedXml instance with custom getObjectContent
330
+ const sig = new SignedXml ( {
331
+ getObjectContent : ( ) => [
332
+ {
333
+ content : "<Data>Test data for SHA512 digest</Data>" ,
334
+ attributes : {
335
+ Id : "object1" ,
336
+ MimeType : "text/xml" ,
337
+ } ,
338
+ } ,
339
+ ] ,
340
+ } ) ;
341
+
342
+ // Set up the signature
343
+ sig . privateKey = fs . readFileSync ( "./test/static/client.pem" ) ;
344
+
345
+ // Add a reference to the document element
346
+ sig . addReference ( {
347
+ xpath : "//*[local-name(.)='x']" ,
348
+ digestAlgorithm : "http://www.w3.org/2001/04/xmlenc#sha512" ,
349
+ transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
350
+ } ) ;
351
+
352
+ // Add a reference to the Object element with SHA512
353
+ sig . addReference ( {
354
+ xpath : "//*[@Id='object1']" ,
355
+ digestAlgorithm : "http://www.w3.org/2001/04/xmlenc#sha512" ,
356
+ transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
357
+ isSignatureReference : true ,
358
+ } ) ;
359
+
360
+ // Set required algorithms
361
+ sig . canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" ;
362
+ sig . signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" ;
363
+
364
+ // Compute the signature
365
+ sig . computeSignature ( xml ) ;
366
+
367
+ // Get the signed XML
368
+ const signedXml = sig . getSignedXml ( ) ;
369
+
370
+ // Parse the signed XML
371
+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
372
+
373
+ // Verify that the ds:Object element exists
374
+ const objectNodes = xpath . select ( "//*[local-name(.)='Object']" , doc ) ;
375
+ isDomNode . assertIsArrayOfNodes ( objectNodes ) ;
376
+ expect ( objectNodes . length ) . to . equal ( 1 ) ;
377
+
378
+ // Verify that there are two Reference elements
379
+ const referenceNodes = xpath . select ( "//*[local-name(.)='Reference']" , doc ) ;
380
+ isDomNode . assertIsArrayOfNodes ( referenceNodes ) ;
381
+ expect ( referenceNodes . length ) . to . equal ( 2 ) ;
382
+
383
+ // Verify that the references use SHA512
384
+ const digestMethodNodes = xpath . select ( "//*[local-name(.)='DigestMethod']" , doc ) ;
385
+ isDomNode . assertIsArrayOfNodes ( digestMethodNodes ) ;
386
+
387
+ for ( const digestMethod of digestMethodNodes ) {
388
+ isDomNode . assertIsElementNode ( digestMethod ) ;
389
+ expect ( digestMethod . getAttribute ( "Algorithm" ) ) . to . equal (
390
+ "http://www.w3.org/2001/04/xmlenc#sha512" ,
391
+ ) ;
392
+ }
393
+
394
+ // Verify that the signature method is RSA-SHA512
395
+ const signatureMethod = xpath . select1 ( "//*[local-name(.)='SignatureMethod']" , doc ) ;
396
+ isDomNode . assertIsElementNode ( signatureMethod ) ;
397
+ expect ( signatureMethod . getAttribute ( "Algorithm" ) ) . to . equal (
398
+ "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" ,
399
+ ) ;
400
+
401
+ // Verify that the signature is still valid
402
+ const verifier = new SignedXml ( ) ;
403
+ verifier . publicCert = fs . readFileSync ( "./test/static/client_public.pem" ) ;
404
+
405
+ // First load the signature
406
+ const signatureNode = xpath . select1 (
407
+ "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']" ,
408
+ doc ,
409
+ ) ;
410
+ isDomNode . assertIsNodeLike ( signatureNode ) ;
411
+ verifier . loadSignature ( signatureNode ) ;
412
+
413
+ // Then check the signature
414
+ const isValid = verifier . checkSignature ( signedXml ) ;
415
+ expect ( isValid ) . to . be . true ;
416
+ } ) ;
417
+
418
+ it ( "should sign Object with C14N canonicalization algorithm" , function ( ) {
419
+ // Create a simple XML document to sign
420
+ const xml = '<root><x xmlns="ns"></x><y attr="value"></y><z><w></w></z></root>' ;
421
+
422
+ // Create a SignedXml instance with custom getObjectContent
423
+ const sig = new SignedXml ( {
424
+ getObjectContent : ( ) => [
425
+ {
426
+ content : "<Data>Test data for C14N canonicalization</Data>" ,
427
+ attributes : {
428
+ Id : "object1" ,
429
+ MimeType : "text/xml" ,
430
+ } ,
431
+ } ,
432
+ ] ,
433
+ } ) ;
434
+
435
+ // Set up the signature
436
+ sig . privateKey = fs . readFileSync ( "./test/static/client.pem" ) ;
437
+
438
+ // Add a reference to the document element
439
+ sig . addReference ( {
440
+ xpath : "//*[local-name(.)='x']" ,
441
+ digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
442
+ transforms : [ "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ] ,
443
+ } ) ;
444
+
445
+ // Add a reference to the Object element
446
+ sig . addReference ( {
447
+ xpath : "//*[@Id='object1']" ,
448
+ digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
449
+ transforms : [ "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ] ,
450
+ isSignatureReference : true ,
451
+ } ) ;
452
+
453
+ // Set required algorithms
454
+ sig . canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ;
455
+ sig . signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" ;
456
+
457
+ // Compute the signature
458
+ sig . computeSignature ( xml ) ;
459
+
460
+ // Get the signed XML
461
+ const signedXml = sig . getSignedXml ( ) ;
462
+
463
+ // Parse the signed XML
464
+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
465
+
466
+ // Verify that the ds:Object element exists
467
+ const objectNodes = xpath . select ( "//*[local-name(.)='Object']" , doc ) ;
468
+ isDomNode . assertIsArrayOfNodes ( objectNodes ) ;
469
+ expect ( objectNodes . length ) . to . equal ( 1 ) ;
470
+
471
+ // Verify that there are two Reference elements
472
+ const referenceNodes = xpath . select ( "//*[local-name(.)='Reference']" , doc ) ;
473
+ isDomNode . assertIsArrayOfNodes ( referenceNodes ) ;
474
+ expect ( referenceNodes . length ) . to . equal ( 2 ) ;
475
+
476
+ // Verify that the transforms use C14N
477
+ const transforms = xpath . select (
478
+ "//*[local-name(.)='Reference']/*[local-name(.)='Transforms']/*[local-name(.)='Transform']" ,
479
+ doc ,
480
+ ) ;
481
+ isDomNode . assertIsArrayOfNodes ( transforms ) ;
482
+
483
+ for ( const transform of transforms ) {
484
+ isDomNode . assertIsElementNode ( transform ) ;
485
+ expect ( transform . getAttribute ( "Algorithm" ) ) . to . equal (
486
+ "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ,
487
+ ) ;
488
+ }
489
+
490
+ // Verify that the CanonicalizationMethod is C14N
491
+ const canonMethod = xpath . select1 ( "//*[local-name(.)='CanonicalizationMethod']" , doc ) ;
492
+ isDomNode . assertIsElementNode ( canonMethod ) ;
493
+ expect ( canonMethod . getAttribute ( "Algorithm" ) ) . to . equal (
494
+ "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ,
495
+ ) ;
496
+
497
+ // Verify that the signature is still valid
498
+ const verifier = new SignedXml ( ) ;
499
+ verifier . publicCert = fs . readFileSync ( "./test/static/client_public.pem" ) ;
500
+
501
+ // First load the signature
502
+ const signatureNode = xpath . select1 (
503
+ "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']" ,
504
+ doc ,
505
+ ) ;
506
+ isDomNode . assertIsNodeLike ( signatureNode ) ;
507
+ verifier . loadSignature ( signatureNode ) ;
508
+
509
+ // Then check the signature
510
+ const isValid = verifier . checkSignature ( signedXml ) ;
511
+ expect ( isValid ) . to . be . true ;
512
+ } ) ;
513
+
232
514
it ( "should add a reference to an Object element" , function ( ) {
233
515
// Create a simple XML document to sign
234
516
const xml = '<root><x xmlns="ns"></x><y attr="value"></y><z><w></w></z></root>' ;
@@ -259,7 +541,6 @@ describe("Object support in XML signatures", function () {
259
541
// Add a reference to the Object element by its ID
260
542
sig . addReference ( {
261
543
xpath : "//*[@Id='object1']" ,
262
- uri : "#object1" ,
263
544
digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
264
545
transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
265
546
isSignatureReference : true ,
@@ -347,7 +628,7 @@ describe("Object support in XML signatures", function () {
347
628
348
629
// Add a reference to the Object element by its ID only, marking it as a signature reference
349
630
sig . addReference ( {
350
- uri : "# object1" ,
631
+ xpath : "//*[@Id=' object1'] " ,
351
632
digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
352
633
transforms : [ "http://www.w3.org/2001/10/xml-exc-c14n#" ] ,
353
634
isSignatureReference : true ,
0 commit comments