@@ -366,6 +366,130 @@ describe("Valid signatures with ds:Object elements", function () {
366366 const { valid, errorMessage } = checkSignature ( signedXml , doc ) ;
367367 expect ( valid , errorMessage ) . to . be . true ;
368368 } ) ;
369+
370+ it ( "should create valid signature and generate Id attribute for ds:Object when not provided" , function ( ) {
371+ const xml = "<root></root>" ;
372+ const sig = new SignedXml ( {
373+ privateKey,
374+ canonicalizationAlgorithm : "http://www.w3.org/2001/10/xml-exc-c14n#" ,
375+ signatureAlgorithm : "http://www.w3.org/2000/09/xmldsig#rsa-sha1" ,
376+ objects : [
377+ {
378+ content : "<Data>Test data in Object element</Data>" ,
379+ } ,
380+ ] ,
381+ } ) ;
382+
383+ sig . addReference ( {
384+ xpath : "//*[local-name(.)='Data']" ,
385+ digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
386+ transforms : [
387+ "http://www.w3.org/2000/09/xmldsig#enveloped-signature" ,
388+ "http://www.w3.org/2001/10/xml-exc-c14n#" ,
389+ ] ,
390+ } ) ;
391+
392+ sig . computeSignature ( xml , { prefix : "ds" } ) ;
393+ const signedXml = sig . getSignedXml ( ) ;
394+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
395+
396+ // Find the ds:Object/Data element and get the value of its Id attribute (ensuring it was generated)
397+ const dataEl = select1Ns ( "/root/ds:Signature/ds:Object/Data[@Id]" , doc ) ;
398+ isDomNode . assertIsElementNode ( dataEl ) ;
399+ const idValue = dataEl . getAttribute ( "Id" ) ;
400+ expect ( idValue ) . to . be . a ( "string" ) . that . is . not . empty ;
401+
402+ // Verify that there is a Reference pointing to the generated Id
403+ const uri = `#${ idValue } ` ;
404+ const refEl = select1Ns ( `/root/ds:Signature/ds:SignedInfo/ds:Reference[@URI='${ uri } ']` , doc ) ;
405+ isDomNode . assertIsElementNode ( refEl ) ;
406+
407+ // Verify that the signature is valid
408+ const { valid, errorMessage } = checkSignature ( signedXml , doc ) ;
409+ expect ( valid , errorMessage ) . to . be . true ;
410+ } ) ;
411+ } ) ;
412+
413+ describe ( "Should successfuly sign references to ds:KeyInfo elements" , function ( ) {
414+ it ( "should create valid signatures with references to ds:KeyInfo when the Id attribute is provided" , function ( ) {
415+ const xml = "<root><x /></root>" ;
416+ const sig = new SignedXml ( {
417+ privateKey,
418+ canonicalizationAlgorithm : "http://www.w3.org/2001/10/xml-exc-c14n#" ,
419+ signatureAlgorithm : "http://www.w3.org/2000/09/xmldsig#rsa-sha1" ,
420+ keyInfoAttributes : {
421+ Id : "key-info-1" ,
422+ } ,
423+ getKeyInfoContent : ( ) => "<dummy></dummy>" ,
424+ } ) ;
425+
426+ sig . addReference ( {
427+ xpath : "//*[local-name(.)='KeyInfo']" ,
428+ digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
429+ transforms : [
430+ "http://www.w3.org/2000/09/xmldsig#enveloped-signature" ,
431+ "http://www.w3.org/2001/10/xml-exc-c14n#" ,
432+ ] ,
433+ } ) ;
434+
435+ sig . computeSignature ( xml ) ;
436+ const signedXml = sig . getSignedXml ( ) ;
437+
438+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
439+
440+ // Verify that there is a Reference to KeyInfo
441+ const referenceEl = select1Ns (
442+ "/root/ds:Signature/ds:SignedInfo/ds:Reference[@URI='#key-info-1']" ,
443+ doc ,
444+ ) ;
445+ isDomNode . assertIsElementNode ( referenceEl ) ;
446+
447+ // Verify that the signature is valid
448+ const { valid, errorMessage } = checkSignature ( signedXml , doc ) ;
449+ expect ( valid , errorMessage ) . to . be . true ;
450+ } ) ;
451+
452+ it ( "should create valid signatures with references to ds:KeyInfo when the Id attribute is autogenerated" , function ( ) {
453+ const xml = "<root><x /></root>" ;
454+ const sig = new SignedXml ( {
455+ privateKey,
456+ canonicalizationAlgorithm : "http://www.w3.org/2001/10/xml-exc-c14n#" ,
457+ signatureAlgorithm : "http://www.w3.org/2000/09/xmldsig#rsa-sha1" ,
458+ getKeyInfoContent : ( ) => "<dummy></dummy>" ,
459+ } ) ;
460+
461+ sig . addReference ( {
462+ xpath : "//*[local-name(.)='KeyInfo']" ,
463+ digestAlgorithm : "http://www.w3.org/2000/09/xmldsig#sha1" ,
464+ transforms : [
465+ "http://www.w3.org/2000/09/xmldsig#enveloped-signature" ,
466+ "http://www.w3.org/2001/10/xml-exc-c14n#" ,
467+ ] ,
468+ } ) ;
469+
470+ sig . computeSignature ( xml ) ;
471+ const signedXml = sig . getSignedXml ( ) ;
472+
473+ const doc = new xmldom . DOMParser ( ) . parseFromString ( signedXml ) ;
474+
475+ // Find the KeyInfo element and get the value of its Id attribute (ensuring it was generated)
476+ const keyInfoEl = select1Ns ( "/root/ds:Signature/ds:KeyInfo[@Id]" , doc ) ;
477+ isDomNode . assertIsElementNode ( keyInfoEl ) ;
478+ const idValue = keyInfoEl . getAttribute ( "Id" ) ;
479+ expect ( idValue ) . to . be . a ( "string" ) . that . is . not . empty ;
480+
481+ // Find a Reference with URI=`#${idValue}`
482+ const uri = `#${ idValue } ` ;
483+ const referenceEl = select1Ns (
484+ `/root/ds:Signature/ds:SignedInfo/ds:Reference[@URI='${ uri } ']` ,
485+ doc ,
486+ ) ;
487+ isDomNode . assertIsElementNode ( referenceEl ) ;
488+
489+ // Verify that the signature is valid
490+ const { valid, errorMessage } = checkSignature ( signedXml , doc ) ;
491+ expect ( valid , errorMessage ) . to . be . true ;
492+ } ) ;
369493} ) ;
370494
371495describe ( "XAdES Object support in XML signatures" , function ( ) {
0 commit comments