Skip to content

Commit d0a19ae

Browse files
cjbarthshunkica
authored andcommitted
Remove wasProcessed property
1 parent 5a8c058 commit d0a19ae

File tree

5 files changed

+42
-18
lines changed

5 files changed

+42
-18
lines changed

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
"codecov",
77
"feide",
88
"HMAC",
9+
"posteb",
10+
"preeb",
911
"reserialization",
12+
"stricttextualmsg",
1013
"wsfederation",
11-
"wssecurity"
14+
"wssecurity",
15+
"xades"
1216
]
1317
}

src/signed-xml.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class SignedXml {
7272
* Contains the references that were signed.
7373
* @see {@link Reference}
7474
*/
75-
private references: (Reference & { wasProcessed: boolean })[] = [];
75+
private references: Reference[] = [];
7676

7777
/**
7878
* Contains the canonicalized XML of the references that were validly signed.
@@ -833,7 +833,6 @@ export class SignedXml {
833833
isEmptyUri,
834834
id,
835835
type,
836-
wasProcessed: false,
837836
getValidatedNode: () => {
838837
throw new Error(
839838
"Reference has not been validated yet; Did you call `sig.checkSignature()`?",
@@ -1182,7 +1181,6 @@ export class SignedXml {
11821181
`<${prefix}DigestValue>${digestAlgorithm.getHash(canonXml)}</${prefix}DigestValue>` +
11831182
`</${prefix}Reference>`;
11841183
}
1185-
ref.wasProcessed = true;
11861184
}
11871185

11881186
return res;
@@ -1328,9 +1326,8 @@ export class SignedXml {
13281326
* This is called after the initial signature has been created to handle references to signature elements
13291327
*/
13301328
private processSignatureReferences(doc: Document, signatureElem: Element, prefix?: string) {
1331-
// Get unprocessed references
1332-
const unprocessedReferences = this.references.filter((ref) => !ref.wasProcessed);
1333-
if (unprocessedReferences.length === 0) {
1329+
const pendingRefs = this.references;
1330+
if (!utils.isArrayHasLength(pendingRefs)) {
13341331
return;
13351332
}
13361333

@@ -1352,7 +1349,7 @@ export class SignedXml {
13521349
const signatureDoc = signatureElem.ownerDocument;
13531350

13541351
// Process each unprocessed reference
1355-
for (const ref of unprocessedReferences) {
1352+
for (const ref of pendingRefs) {
13561353
const nodes = xpath.selectWithResolver(ref.xpath ?? "", doc, this.namespaceResolver);
13571354

13581355
if (!utils.isArrayHasLength(nodes)) {
@@ -1374,19 +1371,28 @@ export class SignedXml {
13741371
);
13751372
}
13761373

1377-
// Create the reference element directly using DOM methods to avoid namespace issues
1378-
const referenceElem = signatureDoc.createElementNS(
1379-
signatureNamespace,
1380-
`${prefix}Reference`,
1381-
);
1374+
// Compute the target URI we intend to add
1375+
let targetUri: string;
13821376
if (ref.isEmptyUri) {
1383-
referenceElem.setAttribute("URI", "");
1377+
targetUri = "";
13841378
} else {
13851379
const id = this.ensureHasId(node);
13861380
ref.uri = id;
1387-
referenceElem.setAttribute("URI", `#${id}`);
1381+
targetUri = `#${id}`;
1382+
}
1383+
1384+
// Skip if a Reference with this URI already exists
1385+
if (utils.hasReferenceWithUri(signedInfoNode, targetUri, signatureNamespace)) {
1386+
continue;
13881387
}
13891388

1389+
// Create the reference element directly using DOM methods to avoid namespace issues
1390+
const referenceElem = signatureDoc.createElementNS(
1391+
signatureNamespace,
1392+
`${prefix}Reference`,
1393+
);
1394+
referenceElem.setAttribute("URI", targetUri);
1395+
13901396
if (ref.id) {
13911397
referenceElem.setAttribute("Id", ref.id);
13921398
}
@@ -1448,7 +1454,6 @@ export class SignedXml {
14481454
// Append the reference element to SignedInfo
14491455
signedInfoNode.appendChild(referenceElem);
14501456
}
1451-
ref.wasProcessed = true;
14521457
}
14531458
}
14541459

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface GetKeyInfoContentArgs {
4545
}
4646

4747
/**
48-
* Object attributes as defined in XMLDSig spec
48+
* Object attributes as defined in XMLDSig spec and are emitted verbatim
4949
* @see https://www.w3.org/TR/xmldsig-core/#sec-Object
5050
*/
5151
export interface ObjectAttributes {

src/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,18 @@ export function isDescendantOf(node: Node, parent: Node): boolean {
331331

332332
return false;
333333
}
334+
335+
export function hasReferenceWithUri(
336+
signedInfoNode: Element,
337+
uri: string,
338+
signatureNamespace: string,
339+
): boolean {
340+
const refs = findChildren(signedInfoNode, "Reference", signatureNamespace);
341+
for (const el of refs) {
342+
const uriAttr = findAttr(el, "URI"); // attribute is un-namespaced in xmldsig
343+
if (uriAttr && uriAttr.value === uri) {
344+
return true;
345+
}
346+
}
347+
return false;
348+
}

test/signature-object-tests.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ describe("ds:Object support in XML signatures", function () {
203203
expect(objectNodesWithEmpty.length).to.equal(0);
204204
});
205205

206-
it("should handle Rerefence to Object", function () {
206+
it("should handle Reference to Object", function () {
207207
const xml = "<root></root>";
208208

209209
const sig = new SignedXml({

0 commit comments

Comments
 (0)