The OpenOffice.org XML Security Framework

Version 1.2.1, March 2005

Michael Mi

Table of Contents

1. Component Overview	4

1.1 SAXWriter	4

1.2 SAXParser	4

1.3 XMLDocumentWrapper	4

1.4 XMLExporter	4

1.5 XMLImporter	5

1.6 SignatureCreator	5

1.7 SignatureVerifier	5

1.8 Encryptor	5

1.9 Decryptor	5

1.10 SAXEventKeeper	5

1.11 XMLSignature	6

1.12 XMLEncryption	6

2. Use Cases	7

2.1 Generate A Signature (signature before the signed data)	7

2.2 Generate A Signature (signature after the signed data)	7

2.3 Generate A Signature (sign detached content)	8

2.4 Generate An Encryption	9

2.5 Verify A Signature (signature before the signed data)	9

2.6 Verify A Signature (signature after the signed data)	9

2.7 Verify A Signature (verify detached signature)	10

2.8 Do a decryption	10

3. Unsupported Features	12

4. Work Flow	14

4.1 Export a Document	14

4.1.1 Preparation	14

4.1.2 Export non-security related content	14

4.1.3 Export security related content	14

4.1.4 Export a new signature	14

4.1.5 Export a new encryption	15

4.1.6 Export a referenced element	15

4.1.7 Buffer SAX events	15

4.1.8 Convert SAX events into DOM	16

4.1.9 Generate signature	16

4.1.10 Generate encryption	16

4.1.11 Status feedback	16

4.1.12 Clear up	17

4.2 Import a Document	18

4.2.1 Preparation	18

4.2.2 Import non-security related content	18

4.2.3 Import security related content	18

4.2.4 Import a new signature	18

4.2.5 Import a new encryption	19

4.2.6 Import a referenced element	19

4.2.7 Buffer SAX events	19

4.2.8 Verify signature	19

4.2.9 Decryption	19

4.2.10 Status feedback	19

4.2.11 Clear up	19

5. Interfaces	20

5.1 Existing Interfaces	20

5.1.1 XDocumentHandler	20

5.1.2 XExporter	20

5.1.3 XFilter	20

5.1.4 XImporter	20

5.1.5 XInitialization	20

5.1.6 XParser	20

5.2 New Interfaces	20

5.2.1 XReferenceResolvedListener	20

5.2.2 XReferenceResolvedBroadcaster	21

5.2.3 XKeyCollector	21

5.2.4 XBlockerMonitor	21

5.2.5 XSignatureCollector	21

5.2.6 XXMLElementWrapperWrapper	21

5.2.7 XXMLDocumentWrapper	22

5.2.8 XCompressedDocumentHandler	23

5.2.9 XSAXEventKeeper	23

5.2.10 XSecuritySAXEventKeeper	24

5.2.11 XSignatureCreationResultListener	24

5.2.12 XSignatureCreationResultBroadcaster	25

5.2.13 XSignatureVerifyResultListener	25

5.2.14 XSignatureVerifyResultBroadcaster	25

5.2.15 XEncryptionResultListener	25

5.2.16 XEncryptionResultBroadcaster	25

5.2.17 XDecryptionResultListener	26

5.2.18 XDecryptionResultBroadcaster	26

5.2.19 XSAXEventKeeperStatusChangeListener	26

5.2.20 XSAXEventKeeperStatusChangeBroadcaster	26

5.2.21 XMissionTaker	27

6. Components	28

6.1 XMLDocumentWrapper	28

6.2 XMLExporter	28

6.3 XMLImporter	28

6.4 SAXEventKeeper	29

6.5 SignatureCreator	29

6.6 SignatureVerifier	30

6.7 Encryptor	30

6.8 Decryptor	30

6.9 XMLSignature	30

6.10 XMLEncryption	31

7. Solutions	32

7.1 Notify Sequence	32

7.2 Transfer DOM data	32

8. Helper Components	33

8.1 SAXHelper	33

9. Prototype	34

9.1 Program overview	34

9.2 File format	35

Component Overview

UNO XMLExporter SignatureVerifier SAXEventKeeper XMLDocumentWrapper Imp. XML Sec Imp. JSR 105 XMLSignature Imp. XML Sec Imp. JSR 105 SignatureCreator XMLImporter Decryptor Encryptor XMLEncryption Imp. XML Sec Imp. JSR 105 SAXParser SAXWriter

SAXWriter

The SAXWriter receives SAX events and writes them into an XML file.

SAXParser

The SAXParser reads an XML file and convert it into SAX events.

XMLDocumentWrapper

The XMLDocumentWrapper is mainly used to buffer SAX events into one of implementation related DOM formats. These resulting buffers will be used to generate/verify signatures and to encrypt/decrypt.

Currently, the XMLDocumentWrapper has two implementations: one is based on XMLSec library, its internal DOM data format is XMLDocPtr. The other implementation is based on JSR105, the internal DOM data format is w3c.dom.DOM. More implementations can be added when necessary.

The XMLDocumentWrapper's primary controller is the SAXEventKeeper. The SAXEventKeeper can decide whether a SAX event should be buffered, whether a buffer should be released, etc..

XMLExporter

The XMLExporter creates a SAXWriter and converts the document into SAX events.

When there is no security related content, the XMLExporter exports the SAX events directly to the SAXWriter. There are two components on the SAX chain, the XMLExporter, followed by the SAXWriter.

When some security related content (signature or encryption) needs to be generated, the XMLExporter reads the configuration file, and finds out what security library the user currently is using.

The XMLExporter creates XMLSec based or JSR105 based an XMLDocumentWrapper component, an XMLSignature component and an XMLEncryption component.

(Annotation MT 2005/04: There is no configuration file or JSR105 implementation anymore...)

Then the XMLExporter creates a SAXEventKeeper and inserts the SAXEventKeeper into the middle of the SAX chain. Now, all SAX events generated by the XMLExporter will be transferred to the SAXEventKeeper first.

When a signature needs to be generated, the XMLExporter creates a SignatureCreator and informs the SAXEventKeeper to collect all data, including signed elements, the signature template and the key materials. When an encryption need to be generated, the XMLExporter creates an Encryptor and informs the SAXEventKeeper to collect all data which will be encrypted.

When all security related content is generated, the XMLExporter removes the SAXEventKeeper from the SAX chain.

XMLImporter

The XMLImporter creates a SAXParser to parse a XML file into SAX events, then the XMLImporter converts those SAX events into a document.

When there is no security related content, the XMLImporter directly receives SAX events generated by the SAXParser. There are two components on the SAX chain, the SAXParser, followed by the XMLImporter.

When some security related content (signature or encryption) needs to be handled, the XMLImporter creates a XMLDocumentWrapper component, an XMLSignature component, an XMLEncryption component and a SAXEventKeeper component as the XMLExporter does.

Now, all SAX events parsed out by the SAXParser will be transferred to the SAXEventKeeper first, then to the XMLImporter.

When a signature needs to be verified, the XMLImporter creates a SignatureVerifier and informs the SAXEventKeeper to collect all related data. When an encryption need to decrypt, the XMLImporter creates an Decryptor and informs the SAXEventKeeper to collect all related data.

When all security related contents are solved, the XMLImporter removes the SAXEventKeeper from the SAX chain.

SignatureCreator

The SignatureCreator monitors the collecting processes for the signed elements, the signature template and the key material. When the collection is done, it invokes a XMLSignature to generate the signature element.

SignatureVerifier

The SignatureVerifier monitors the collecting processes for the signed elements, the signature template and the key material. When finished, it invokes a XMLSignature to verify the signature element.

Encryptor

The Encryptor monitors the collecting processes for both the encryption template and the key material. When finished, it invokes a XMLEncryption to generate the encryption.

Decryptor

The Decryptor monitors the collecting processes for both the encryption template and its key material. When finished, it invokes a XMLEncryption to do the decryption.

SAXEventKeeper

The SAXEventKeeper is a component located in the SAX chain. It receives SAX events from the previous component and forwards them to the next component in the SAX chain.

Meanwhile, the SAXEventKeeper is also in charge of controlling the XMLDocumentWrapper to buffer/release XML data. For example, to generate a new signature, the SAXEventKeeper will transfer SAX events of the signature template, all signed elements, and the key material element to the XMLDocumentWrapper, and asks the XMLDocumentWrapper to buffer them. When the signature is generated, the SAXEventKeeper asks the XMLDocumentWrapper to release all these buffers.

When some element is not in the final shape, such as a signature template before generated, the SAXEventKeeper will stop forwarding any SAX events starting from that element to the next component in the SAX chain, instead, all these SAX events are transferred to the XMLDocumentWrapper to be buffered temporarily. When this element enters its final shape, all buffered SAX events are forwarded out again.

XMLSignature

The XMLSignature component manipulates the buffered data in XMLDocumentWrapper to do signature calculation and verification.

The XMLSignature component accesses the buffered data by using native DOM methods provided by another component.

These methods are not UNO based, so this needs the XMLSignature can access the class reference of a particular UNO interface. This problem can be solved through using XUNOTunnel interface. Native calling can save a lot of time, especially when thinking of the Java/C++ UNO bridge.

The XMLSignature has two implementations: One is based on XMLSec library, the other is based on JSR105.

The XMLSec based implementation is a C implementation, which can directly manipulate the data buffer inside of the XMLSec based XMLDocumentWrapper component.

The JSR105 based implementation is a Java one, it can directly manipulate the data buffer in the JSR105 based XMLDocumentWrapper component.

XMLEncryption

The XMLEncryption component is similar to the XMLSignature component, which its functionality is to encrypt and decrypt instead of manipulating signature.

The XMLEncryption component accesses the buffered data by using native DOM methods too.

The XMLEncryption also has two implementation: One is based on XMLSec library, the other is based on JSR106.

Use Cases

Generate A Signature (signature before the signed data)

The XMLExporter transfers SAX events locating before the signature directly to the SAXWriter. There are two components in the SAX chain: the XMLExporter and the SAXWriter.

When the XMLExporter needs to export the Signature element,it creates a SAXEventKeeper, and insert it between the XMLExporter and the SAXWriter as a filter. Now, there are three components in the SAX chain: the XMLExporter, the SAXEvenetKeeper and the SAXWriter.

The XMLExporter constructs the signature template. This template is almost a Signature element, but with empty DigestValue elements and empty SignatureValue element.

The XMLExporter creates a SignatureCreator for this Signature template. Then it ask the SAXEventKeeper to buffer the following element. Moreover, the XMLExporter asks the SAXEventKeeper to create a blocker on the same element, which prevents the SAXEventKeeper from forwarding the following SAX events to the SAXWriter.

The XMLExporter transfers the signature template to the SAXEventKeeper as SAX events.

The SAXEventKeeper stop forwarding any SAX event to the SAXWriter.

The SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper and asks the XMLDocumentWrapper to buffer this signature template.

When the signature template element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureCreator.

SAX events after the signature element are still transferred to the SAXEventKeeper to be buffered.

Before the XMLExporter transfers the signed element, it ask the SAXEventKeeper to buffer the following element. Then the XMLExporter transfers this element to the SAXEventKeeper.

The SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper and asks the XMLDocumentWrapper to buffer this element. If multiple buffered elements include same data, the SAXEventKeeper will make sure the event is kept in memory once only.

When this element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureCreator. There might be several notifications for a single signature if the signature contains more than one reference.

At the time the SignatureCreator knows both the signed elements and the signature template are collected, it invokes the XMLSignature to do the signature generation.

Inside of the XMLSignature, the DOM tree in the XMLDocumentWrapper is read, and the signature is calculated out. Then the template is filled in with DigestValue content and SignatureValue content.

The SignatureCreator asks the SAXEventKeeper to release all buffer data, and also removes the blocker.

Because the blocker is removed, the SAXEventKeeper asks the XMLDocumentWrapper to forward all SAX events starting from the signature template to the SAXWriter.

The XMLExporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events generated by the XMLExporter are transferred directly to the SAXWriter again.

Generate A Signature (signature after the signed data)

The XMLExporter transfers SAX events locating before the signed element directly to the SAXWriter. There are two components in the SAX chain: the XMLExporter and the SAXWriter.

Before the XMLExporter transfers the signed element, it creates a SAXEventKeeper, and insert it between the XMLExporter and the SAXWriter as a filter. Now, there are three components in the SAX chain: the XMLExporter, the SAXEvenetKeeper and the SAXWriter.

it ask the SAXEventKeeper to buffer the following element. Then the XMLExporter transfers the signed element to the SAXEventKeeper.

The SAXEventKeeper tramsfers these SAX events to the XMLDocumentWrapper and asks the XMLDocumentWrapper to buffer this element.

When this element is buffered completely, the SAXEventKeeper hold the collection end notification, because by now, there is no notification listener yet.

The XMLExporter removes the SAXEventKeeper from the SAX chain, so SAX events after the signed element are transferred directly to the SAXWriter.

When need to export the Signature element, the XMLExporter connect the SAXEventKeeper to the SAX chain again.

The XMLExporter constructs a signature template and creates a SignatureCreator for this Signature template. Then it asks the SAXEventKeeper to buffer the following element, and to create a blocker as well, which prevents the SAXEventKeeper from forwarding the following SAX events to the SAXWriter.

The SAXEventKeeper notifies the signed element's collection end to the SignatureCreator.

The XMLExporter transfers the signature template to the SAXEventKeeper as SAX events.

The SAXEventKeeper stops forwarding any SAX event to the SAXWriter.

The SAXEventKeeper transfers SAX events to the XMLDocumentWrapper and asks the XMLDocumentWrapper to buffer this signature template.

When the signature template element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureCreator.

At the time the SignatureCreator knows both the signed elements and the signature template are collected, it invokes the XMLSignature to do the signature generation.

Inside of the XMLSignature, the DOM tree in the XMLDocumentWrapper is read, and the signature is calculated out. Then the template is filled in with DigestValue content and SignatureValue content.

The SignatureCreator asks the SAXEventKeeper to release all buffer data, and also removes the blocker.

Because the blocker is removed, the SAXEventKeeper asks the XMLDocumentWrapper to forward all SAX events starting from the signature template to the SAXWriter.

The XMLExporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events generated by the XMLExporter are transferred directly to the SAXWriter again.

Generate A Signature (sign detached content)

The XMLExporter transfers SAX events locating before the signature directly to the SAXWriter. There are two components in the SAX chain: the XMLExporter and the SAXWriter.

When the XMLExporter needs to export the Signature element,it creates a SAXEventKeeper, and insert it between the XMLExporter and the SAXWriter as a filter. Now, there are three components in the SAX chain: the XMLExporter, the SAXEvenetKeeper and the SAXWriter.

The XMLExporter constructs the signature template. This template is almost a Signature element, but with empty DigestValue elements and empty SignatureValue element.

The XMLExporter creates a SignatureCreator for this Signature template. Then it ask the SAXEventKeeper to buffer the following element. Moreover, the XMLExporter asks the SAXEventKeeper to create a blocker on the same element, which prevents the SAXEventKeeper from forwarding the following SAX events to the SAXWriter.

The XMLExporter transfers the signature template to the SAXEventKeeper as SAX events.

The SAXEventKeeper stop forwarding any SAX event to the SAXWriter.

The SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper and asks the XMLDocumentWrapper to buffer this signature template.

When the signature template element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureCreator.

Now the SignatureCreator invokes the XMLSignature to do the signature generation.

Inside of the XMLSignature, all detached contents are retrieved according their URI attributes, the DOM tree in the XMLDocumentWrapper is also read, and the signature is calculated out. Then the template is filled in with DigestValue content and SignatureValue content.

The SignatureCreator asks the SAXEventKeeper to release the buffer data, and also removes the blocker.

Because the blocker is removed, the SAXEventKeeper asks the XMLDocumentWrapper to forward all SAX events of the signature template to the SAXWriter.

The XMLExporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events generated by the XMLExporter are transferred directly to the SAXWriter again.

Generate An Encryption

“Generating an encryption” has the same procedure with “generating a signature”, except that:

the signature template is replaced by a encryption template;an encryption template is similar with an EncryptedData element, but the content in the CipherValue element is the plain XML data need to be encrypted, instead of cipher data.

the SignatureCreator is replaced by Encryptor.

A blocker is created at the start tag of the EncryptedData element, instead of on the signature template.

Verify A Signature (signature before the signed data)

The XMLImporter gets SAX events locating before the signature directly from the SAXParser. There are two components in the SAX chain: the SAXParser and the XMLImporter.

When the XMLImporter meets a start tag of a Signature element, it creates a SAXEventKeeper, and insert it between the SAXParser and the XMLImporter as a filter. Now, there are three components in the SAX chain: the SAXParser, the SAXEvenetKeeper and the XMLImporter.

The XMLImporter creates a SignatureVerifier. Then it informs the SAXEventKeeper to buffer this signature element starting with current SAX event, which in turn will be used as a signature template.

During receiving the signature element from the SAXParser, the SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper, and asks it to buffer them. Meanwhile, the SAXEvenetKeeper forwards this signature element to the XMLImporter.

During analyzing the Signature element, the XMLImporter gets all references' URIs.

The XMLImporter tells the SignatureVerifier how many references inside of that signature.

When the signature template element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureVerifier.

The XMLImporter removes the SAXEventKeeper from the SAX chain, so SAX events after the signature element are transferred from the SAXParser directly to the XMLImporter.

The XMLImporter detects the signed element in the SAX events stream according to the reference's URI.

When find the start tag of the signed element, the XMLExporter connect the SAXEventKeeper to the SAX chain again.

The XMLImporter asks the SAXEventKeeper to buffer the element starting with the current SAX event.

During receiving the signed element from the SAXParser, the SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper, and asks it to buffer them. Meanwhile, the SAXEvenetKeeper forwards these SAX events to the XMLImporter.

When this element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureVerifier.

At the time the SignatureVerifier knows both the signed elements and the signature template are collected, it invokes the XMLSignature to do the signature verification.

Inside of the XMLSignature, the DOM tree in the XMLDocumentWrapper is read, and the signature is verified.

The SignatureVerifier gives the verify result to the XMLImporter, then asks the SAXEventKeeper to release all buffer data.

The XMLImporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events are transferred from the SAXParser to the XMLImporter directly again.

Verify A Signature (signature after the signed data)

The XMLImporter gets SAX events locating before the signed element directly from the SAXParser. There are two components in the SAX chain: the SAXParser and the XMLImporter.

When the XMLImporter meets a start tag of a signed element, it creates a SAXEventKeeper, and insert it between the SAXParser and the XMLImporter as a filter. Now, there are three components in the SAX chain: the SAXParser, the SAXEvenetKeeper and the XMLImporter.

The XMLImporter asks the SAXEventKeeper to buffer the element starting with the current SAX event.

During receiving the signed element from the SAXParser, the SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper, and asks it to buffer them. Meanwhile, the SAXEvenetKeeper forwards these SAX events to the XMLImporter.

When this element is buffered completely, the SAXEventKeeper hold the collection end notification, because by now, there is no notification listener yet.

The XMLImporter removes the SAXEventKeeper from the SAX chain, so SAX events after the signed element are transferred from the SAXParser directly to the XMLImporter.

When find the start tag of the signature element, the XMLExporter connect the SAXEventKeeper to the SAX chain again.

The XMLImporter creates a SignatureVerifier. Then it informs the SAXEventKeeper to buffer this signature element starting with this SAX event.

During receiving the signature element from the SAXParser, the SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper, and asks it to buffer them. Meanwhile, the SAXEvenetKeeper forwards this signature element to the XMLImporter.

During analyzing the Signature element, the XMLImporter gets all references' URIs. And the XMLImporter make the SignatureVerifier as the signed element' collection end listener. The SAXEventKeeper notifies the signed element's collection end to the SignatureVerifier.

The XMLImporter tells the SignatureVerifier how many references inside of that signature.

When the signature element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureVerifier.

At the time the SignatureVerifier knows both the signed elements and the signature template are collected, it invokes the XMLSignature to do the signature verification.

Inside of the XMLSignature, the DOM tree in the XMLDocumentWrapper is read, and the signature is verified.

The SignatureVerifier gives the verify result to the XMLImporter, then asks the SAXEventKeeper to release all buffer data.

The XMLImporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events are transferred from the SAXParser to the XMLImporter directly again.

Verify A Signature (verify detached signature)

The XMLImporter gets SAX events locating before the signature directly from the SAXParser. There are two components in the SAX chain: the SAXParser and the XMLImporter.

When the XMLImporter meets a start tag of a Signature element, it creates a SAXEventKeeper, and insert it between the SAXParser and the XMLImporter as a filter. Now, there are three components in the SAX chain: the SAXParser, the SAXEvenetKeeper and the XMLImporter.

The XMLImporter creates a SignatureVerifier. Then it informs the SAXEventKeeper to buffer this signature element starting with current SAX event, which in turn will be used as a signature template.

During receiving the signature element from the SAXParser, the SAXEventKeeper transfers these SAX events to the XMLDocumentWrapper, and asks it to buffer them. Meanwhile, the SAXEvenetKeeper forwards this signature element to the XMLImporter.

During analyzing the Signature element, the XMLImporter gets all references' URIs. Then the XMLImporter notifies the SignatureVerfier that all references are detached contents, instead of same-document elements.

When the signature template element is buffered completely, the SAXEventKeeper notifies the collection end to the SignatureVerifier.

Now the SignatureVerifier invokes the XMLSignature to do the signature verification.

Inside of the XMLSignature, all detached contents are retrieved according their URI attributes, the DOM tree in the XMLDocumentWrapper is also read, and the signature is verified.

The SignatureVerifier gives the verify result to the XMLImporter, then asks the SAXEventKeeper to release all buffer data.

The XMLImporter removes the SAXEventKeeper from the SAX chain, and destroy the SAXEventKeeper. Now the SAX events are transferred from the SAXParser to the XMLImporter directly again.

Do a decryption

“Doing a decryption” has the same procedure with “verifying a signature”, except that:

the signature template is replaced by a encryption template;

the SignatureVerifier is replaced by Decryptor

a blocker is created at the EncryptedData element, which is used to prevent the SAXEventKeeper from forwarding the EncryptedData element to the XMLImporter; After the decryption, the EncryptedData element is replaced by the encrypted data, then the blocker is released, all new SAX events can be forwarded.

when the Decryptor releases the buffered data, it also needs to remove the blocker.

Unsupported Features

When importing, the SAXEventKeeper is between the SAXParser and the XMLImporter in the SAX chain, so logically, any SAX event first reaches the SAXEventKeeper, then the XMLImporter. So when the SAXEventKeeper is blocked, the XMLImporter can't get any SAX event behind the blocking point until the block is released.

So the SAXEventKeeper has to know enough information before the blocking's happening to finish the work without the XMLImporter's assisstant. Otherwise, a deadlock status will be reached. For example

...

<EncryptedData>
<KeyInfo RetrieveMethod="#key1"/>
<CipherData>

</CipherValue>
ABV$%AZXS2345RS
</CipherValue>

</CipherData>
</EncryptedData>
...
<EncryptedKey>
<KeyValue>abcd</KeyValue>
<CipherData>

</CipherValue>
@3XXSFSFS
</CipherValue>

</CipherData>
</EncryptedKey>
...

When importing this document, the SAXEventKeeper blocks at the EncryptedData element. The Decryptor waits for the XMLImporter to tell it the key element to decrypt, then the blocking can be released. On the other hand, the XMLImporter will never receive the EncryptedKey element, because the SAX event stream is blocked at the start point of the EncryptoedData element, so the XMLImporter has also no idea about the key.

Because of that trouble blocker, the above example can't be supported by current design.

When importing, all unsupported features caused by a trouble blocker include:

An encryption with external key material, and the encryption locates before the key material in the XML file.
This feature is illustrated by above example.

An encryption is signed by a signature, and the encryption locates before the signature in the XML file.
In following example, the SAX event stream will be blocked at the CipherData element, because that element needs to be decrypted before forwarded to the XMLImporter. While, the decryption can't be preformed, because this EncryptedData element also signed by the signature, and the signature verification has to be done before any change happens inside the signed element. And the signature verification will never start because the XMLImporter will not create the SignatureVerifier if it can't receive the SAX events of the signature element.

...

<EncryptedData id=”signed”>
<KeyValue>abcd</KeyValue>
<CipherData>

</CipherValue>
ABV$%AZXS2345RS
</CipherValue>

</CipherData>
</EncryptedData>
...
<Signature>

...
<Refrence URI=”#signed”/>

...

</Signature>

...

An signature signs on multiple elements, an encryption is included in one signed elements and will be read before at least one signed element.
In following example, the signature signs on element A and element B. There is an encryption inside the element A, so the SAX events stream will be blocked at the CipherData element, because that element needs to be decrypted before forwarded to the XMLImporter. But the decryption can't be preformed, because this EncryptedData element is inside a signed element, that signature should be verified first. While that signature will never be verified because the XMLImporter can't collect the last signed element.

...

<Signature>

...
<Refrence URI=”#signed1”/>

<Refrence URI=”#signed2”/>

...

</Signature>

...

<A id=”signed1”>

<EncryptedData id=”signed”>
<KeyValue>abcd</KeyValue>
<CipherData>

...

</CipherData>
</EncryptedData>
</A>

...

<B id=”signed2”>

...

</B>

...

When any above situation happens, the SAXEventKeeper will buffer all SAX events from the trouble blocker to the end of the document. The trouble blocker will be released when the XMLImporter performs the clearing up function. In this case, no promise can be made for other security related content to be handled correctly.

Work Flow

Export a Document

XMLExporter SignatureCreator Encryptor XMLSignature XMLEncryption SAXEventKeeper SAXWriter XMLDocumentWrapper SAX Events Controll Data Manipulation . . .

Preparation

Before export a document, the XMLExporter create a SAXWriter, which is used to write SAX events in to an XML file.

Export non-security related content

For the non-security related content, the XMLExporter generates SAX events and transfers them directly to the SAXWriter. The current SAX chain includes two components, the XMLExporter and the SAXWriter.

Security related contents include

new signature,

new encryption,

referenced elements, including the signed element for new signature, and the key material element for new signature or new encryption.

Export security related content

When security related content met, the XMLExporter creates a SAXEventKeeper and inserts it before the SAXWriter. Now the SAX chain includes three components, the XMLExporter, the SAXEventKeeper and the SAXWriter.

Export a new signature

For a new signature, the XMLExporter constructs a signature template. This template is similar with a signature element, but it's DigestValue sub-elements and SignatureValue sub-element are dummy, or with no value inside.

The Reference sub-elements of the template include all signed element' Ids. If the signature uses an external key, then the KeyInfo sub-element includes the key material element's Id.

Before export the template to the SAXEvenetKeeper, the XMLExporter creates a SignatureCreator.

Then the XMLExporter asks the SAXEventKeeper to collect following element in the SAX events, or to create a Element Collector (EC). (we call the collected element as the EC's working element.) The EC's owner is set to the SignatureCreator. Here the owner represents the component which the SAXEventKeeper sends collection end notification to.

Because the digest values and the signature value are missed in the signature template, the XMLExporter also asks the SAXEventKeeper to stop forwarding following SAX events to the SAXWriter, that is, the XMLExporter creates a blocker in the SAXEventKeeper. (we call the first blocked element, the signature template element in this case, as the blocker's working element.) The blocker's owner is also set to the SignatureCreator. That is to say, the SignatureCreator is responsible for remove the blocker after the new signature generated, then all blocked SAX events are forwarded.

Then the XMLExporter transfers the signature template to the SAXEventKeeper.

The XMLExporter knows exactly whether this signature template takes its key material with itself, or has an external key material. If the key material is inside the template, the XMLExporter informs the SignatureCreator that the key material is included internally. Otherwise, it will create a new EC when exporting that key material, the EC's owner is also set to the SignatureCreator.

The XMLExporter is aware on every signed element of this signature. Before exporting these elements, it needs to make additional EC for the SignatureCreator. Moreover, the XMLExporter is responsible to tell the SignatureCreator how many references it will have.

Export a new encryption

For a new encryption, the XMLExporter constructs a encryption template. This template is similar with a EncryptedData element, but the content in the CipherValue element is the plain XML data need to be encrypted, instead of cipher data.

If the encryption uses an external key, then the KeyInfo sub-element includes the key material element's Id.

Similar with transferring a signature template, before exporting the template, the XMLExporter creates an Encryptor, and an EC for the Encryptor as well.

The XMLExporter needs also inform the Encryptor its key material information as to the SignatureCreator.

A blocker is created right before the EncryptedData element. The content in the CipherData element are the plain XML data which need to be encrypted. This blocker will be released when the encryption is generated.

Export a referenced element

For a referenced element, before exporting them, the XMLExporter creates an EC for every already created SignatureCreator or Encryptor, which has reference on this element.

If the XMLExporter thinks there will be some further SignatureCreator/Encryptor, which has reference on this element, in the future SAX events, the XMLExporter will create a EC owned by itself. When that SignatureCreator/Encryptor is met, the XMLExporter will clone its own EC for that SignatureCreator/Encryptor. The reason why doing this is very simple, to ask the SAXEventKeeper to buffer some element, an EC must be created before that element is transferred to the SAXEventKeeper, or else, it will be late. The XMLExporter will release its own EC whenever it thinks there is no further SignatureCreator/Encryptor will reference on that element.

Next, the XMLExporter transfers the referenced element to the SAXEvenetKeeper.

Buffer SAX events

The SAXEventKeeper Receives SAX events from the XMLExporter. Meanwhile, the SAXEventKeeper will do following actions based on the instructions from the XMLExporter and the current status:

If the current received element is asked to be buffered by the XMLExporter, the SAXEventKeeper transfers the SAX events to the XMLDocumentWrapper to buffer them.

If the current SAX event stream is blocked, the SAXEventKeeper transfers the SAX events to the XMLDocumentWrapper to buffer them.

If neither the stream is blocked nor inside any element's collection, the SAXEventKeeper transfers the SAX events to the next component on the SAX chain without buffering them.

There are four kinds of instructions from the XMLExporter, they are:

add a element collector (EC):
when the SAXEventKeeper receives this instruction, it will ask the XMLDocumentWrapper buffer all SAX events of following element.
When the element is buffered, the SAXEventKeeper will notify the collection end to the EC's owner.

remove a element collector:
when the SAXEventKeeper receives this instruction, that means a previous buffered element is not useful any longer, so the SAXEventKeeper informs the XMLDocumentWrapper to release that data.

Add a blocker:
when the SAXEventKeeper receives this instruction, it knows that the following element in the SAX events stream can't be forwarded to the next component in the SAX chain. So all SAX events starting from this element need to be blocked in buffer.

Remove a blocker:
when the SAXEventKeeper receives this instruction, that means a blocker is removed. All buffered SAX events for that blocker can be forwarded to the next component in the SAX chain now.

When several instructions need to buffer the same part of data, the SAXEventKeeper can promise only one copy of data existing in memory.

Convert SAX events into DOM

When an element needs to be bufferred, the SAXEventKeeper transfer this element to the XMLDocumentWrapper as SAX events. The XMLDocumentWrapper is responsible for converting these SAX events into a DOM tree.

When the XMLDocumentWrapper is initialized, it creates an empty DOM tree, and the root element is the “current element”.

When a startElement event received, the XMLDocumentWrapper creates a new element, and this element becomes the “current element”, all following SAX events should be under this element.

When a endElement event received, the “current element” changes to its parent element.

When other events received, new nodes will be created under the “current element”.

So, the XMLDocumentWrapper will always hold a “complete” DOM tree no matter what segment of SAX events have been received.

Generate signature

When the SignatureCreator gets all signed elements, key material and signature template are buffered, it invokes the XMLSignature component to generate the signature.

The XMLSignature directly access the DOM tree inside of the XMLDocumentWrapper component, and fills in the DigestValue elements and the SignatureValue element in the signature.

After that, the SignatureCreator asks the SAXEventKeeper to release all EC and blocker.

Generate encryption

When the Encryptor gets both the encryption template and the key material bufferred, it invokes the XMLEncryption component to generate the encryption.

The XMLEncryption directly access the DOM tree inside of the XMLDocumentWrapper component, and encrypt the plain XML data in the CipherData element into cipher data.

After that, the Encryptor asks the SAXEventKeeper to release all EC and blocker.

Status feedback

The SAXEventKeeper will give the XMLExporter its current status, based on the status, the XMLExporter can adopt different actions.

The feedback status includes:

Enter element collection. It tells the XMLExporter that the SAXEventKeeper just began to collect an element, so following SAX events are required by the SAXEventKeeper for this element's collection.

Leave element collection. It tells the XMLExporter that the SAXEventKeeper just left any element collection, following SAX events don't belong to any element need to be collected.

Enter blocking. It tells the XMLExporter that a blocker is just created, so all SAX events starting from that blocker's working element can't be forwarded and have to be buffered temporarily. That blocker's working element is also called the blocking element.

Leave blocking. It tells the XMLExporter that the last blocker is just removed, and all temporarily buffered SAX events have been forwarded.

Buffer empty. It tells the XMLExporter that all buffered data are released in the SAXEventKeeper, that is to say, the SAXEventKeeper is meaningless for existing.

When receiving above notification, the XMLExporter will adopt different actions.

When the XMLExporter receives the buffer empty notification, it removes the SAXEventKeeper from the SAX chain and destroys it. Following SAX events will be transferred to the SAXWriter. Everything looks like before no security related contents happened.

If neither in blocking status nor in element collection status, the XMLExporter will transfer following SAX events to the SAXWriter, otherwise, to the SAXEventKeeper.

After change transfer to the SAXWriter, when the XMLExporter finds any security related content again, it has to change its transfer back to the SAXEventKeeper again.

Clear up

Although it is rarely to happen, the SAX events exported by the XMLExporter may include error. For instance, the signed element doesn't exist in the SAX events. The direct result from this kind of error is that the SAXEventKeeper can still buffer or block something after all SAX events are passed. So in this situation, there must be some mechanism to promise the SAXEventKeeper can reach empty status in the end.

When the XMLExporter finished transferring all SAX events, it asks every SignatrueCreator and Encryptor to do clear-up function.

When a SignatureCreator or Encryptor receives the clear-up message, it will release all unreleased ECs or blocker if there is any.

The XMLExporter will also release all ECs owned by itself.

In this way, the SAXEventKeeper will reach the buffer empty status finally.

Import a Document

SAXParser SignatureCreator Encryptor XMLSignature XMLEncryption SAXEventKeeper XMLImporter XMLDocumentWrapper SAX Events Controll Data Manipulation . . .

Preparation

Before importing a document, the XMLImporter creates a SAXParser, which is used to parse an XML file into SAX events.

Import non-security related content

For the non-security related content, the XMLImporter receives SAX events directly from the SAXParser. The current SAX chain includes two components, the SAXParser and the XMLImporter.

Security related contents include

signature, i.e., the Signature element,

encryption, i.e., the EncryptedData element,

referenced elements, including the signed element for any signature, and the key material element for signature and encryption.

Import security related content

When security related content met, the XMLImporter creates a SAXEventKeeper and inserts it behind the SAXParser. Now the SAX chain includes three components, the SAXParser, the SAXEvenetKeeper and the XMLImporter.

Import a new signature

When the XMLImporter receives the start tag of a Signature element, it create a SignatureVerifier. Then the XMLImporter asks the SAXEventKeeper to create an EC for the current element, the EC's owner is set to the SignatureVerifier.

The XMLImporter analyzes the signature during receiving its SAX events. Through which, it can figure out the reference number, every reference's URI, and ,if there is, the external key material's URI.

The XMLImporter tells the SignatureVerifier how many references it will have and the key material's information.

After the XMLImporter gets all reference's URI and the key's URI, it will detect them in the SAX event stream.

Import a new encryption

When the XMLImporter receives the start tag of a EncryptedData element, it create a Decryptor. Then the XMLImporter asks the SAXEventKeeper to create an EC for the current element, the EC's owner is set to the Decryptor.

The XMLImporter asks the SAXEventKeeper to create a blocker before the EncryptedData element. The content in the CipherData sub-element are the cipher data which need to be decrypted. This blocker will be removed when the cipher data is decrypted.

The XMLImporter analyzes the encryption during receiving it. Through which, it can figure out the key material the encryption uses. The XMLImporter tells the Decryptor the key material's information, and moreover, if this encryption uses an external key material, the XMLImporter will detect it in the SAX event stream by its URI.

Import a referenced element

When the XMLImporter receives the start tag of any element, it will first evaluate whether this element is referenced or not.

If this element is already referenced by some received signature or encryption, or if this element, the XMLImporter thinks, will be referenced by any further signature or encryption, ECs will be created.

For each received signature or encryption, an EC is created for it. If the XMLImporter thinks this element will be further referenced, the XMLImporter will create an EC owned by itself. When any further SignatureCreator/Encryptor referencing on this element is found, the XMLImporter will clone its own EC for that SignatureCreator/Encryptor.

The XMLImporter will release its own EC whenever it thinks there will be no further reference on it.

Buffer SAX events

The SAXEventKeeper receives SAX events from the SAXParser. It will manipulate EC and blocker as in the exporting case. The XMLImporter will give the SAXEventKeeper instructions.

Verify signature

When the SignatureVerifier knows all the Signature element, signed elements and its key material are buffered, it invokes the XMLSignature to verify the signature.

The XMLSignature directly accesses the DOM tree inside of the XMLDocumentWrapper and verifies the signature.

After that, the SignatureVerifier asks the SAXEventKeeper to release all ECs.

Then, the SignatureVerifier informs the XMLImporter about the verify result.

Decryption

When the Decryptor knows both the EncryptedData element and its key material are buffered, it invokes the XMLEncryption to decrypt the encryption.

The XMLEncryption directly accesses the DOM tree inside of the XMLDocumentWrapper and replaces the whole EncryptedData element with the plain decrypted data.

After that, the Decryptor asks the SAXEventKeeper to destroy all EC and blocker.

Then, the Decryptor informs the XMLImporter about the decryption result.

Status feedback

Same with exporting case, the SAXEventKeeper will give the XMLImporter its current status, and based on the status, the XMLImporter adopts corresponding actions.

Clear up

When it knows the SAXParser has transferred all SAX events, the XMLImporter asks every SignatrueVerifier and Decryptor to do clear-up function.

Every SignatureVerifier and Decryptor will release its unreleased ECs or blocker if there is any.

The XMLImporter will also release all ECs owned by itself.

Interfaces

Existing Interfaces

XDocumentHandler

void startDocument()

void endDocument()

void startElement( string aName, XAttributeList xAttribs )

void endElement( string aName )

void characters( string aChars )

void ignorableWhitespace( string aWhitespaces )

void processingInstruction( string aTarget, string aData )

void setDocumentLocator( XLocator xLocator )

XExporter

void setSourceDocument(XComponent xDoc)

XFilter

boolean filter(sequence<PorpertyValue> aDescriptor)

void cancel()

XImporter

void setTargetDocument(XComponent xDoc)

XInitialization

void initialize(any[] aArguments)

XParser

void parseStream(InputSource strucInputSource )

void setDocumentHandler(XDocumentHandler xHandler )

void setErrorHandler(XErrorHandler xHandler )

void setDTDHandler(XDTDHandler xHandler )

void setEntityResolver(XEntityResolver xResolver )

void setLocale(Locale locale )

New Interfaces

XReferenceResolvedListener

The XReferenceResolvedListener interface is supported by the SignatureCreator component, the SignatureVerifier component, the Encryptor component and the Decryptor component. It is used to get notification when a particular element is collected.

The referenceResolved method is used to notify an element's collection end.

Method list:

void referenceResolved(long id)
the id parameter is id of the EC working on the collected element.

XReferenceResolvedBroadcaster

The XReferenceResolvedBroadcaster interface is supported by the SAXEventKeeper component, which is used to add/remove reference resolved listener on particular element collector.

The addReferenceResolvedListener method adds a reference resolved listener on an EC.

The removeReferenceResolvedListener method remove a reference resolved listener from an EC.

By now, one EC can has only one reference resolved listener on it.

Method list:

void addReferenceResolvedListener(long referenceId, XReferenceResolvedListener listener)

void removeReferenceResolvedListener(long referenceId, XReferenceResolvedListener listener)

XKeyCollector

The XKeyCollector interface is supported by the SignatureCreator component, the SignatureVerifier component, the Encryptor component and the Decryptor component. It is used to tell the interface provider whether or not there is an independent key element's EC for it.

Method list:

void setKeyId(long id)
The setKeyId method is used to tell the key element EC's id, if the id parameter is set to 0, it represents there is no independent key for the interface provider, and the key information has been already involved in the Signature or EncryptedData element, otherwise, the id parameter is the key element EC's id.

XBlockerMonitor

The XBlockerMonitor interface is supported by the SignatureCreator component, the Encryptor component and the Decryptor component. It is used to tell the interface provider which blocker is helping to block the SAX event stream, and in turn, the interface provider will be responsible for remove this blocker.

The setBlockerId method is used to configure the id of the blocker.

Method list:

void setBlockerId(long id)

XSignatureCollector

The XSignatureCollector interface is supported by the SignatureCreator component and the SignatureVerifier component, which is used to receive information about the signature element.

The setReferenceNumber method is used to tell the interface provider the reference number in this signature element.

The setReferenceId method is used to tell the interface provider every reference EC's id.

Method list:

void setReferenceCount(long count)

void setReferenceId(long id)

XXMLElementWrapperWrapper

The XXMLElementWrapperWrapper interface is supported by the XMLElementWrapper component, which is used to encapsulate an native element data, such as w3c.dom.DOM, or xmlNodePtr.

There is no method in this interface, the component supporting this interface can only be used as an object after conversion from interface to class instance.

XXMLDocumentWrapper

The XXMLDocumentWrapper interface is supported by the XMLDocumentWrapper component, which is used to manipulate the buffered SAX events.

Some methods are used to convert a SAX event into a DOM format, including all inherited methods from the XDocumentHandler interface.

Some methods are used to get particular information from the XML tree.

The getCurrentElement return the current element node.

The setCurrentElement method is used to set the current element if it is changed outside the interface provider.

The removeCurrentElement method is used to remove the current element, and set the current element to its parent element.

The isCurrent method judges whether a particular node is the current element node.

The isCurrentElementEmpty method judges whether the current element has no children.

The getNodeName method returns name of the particular element.

A few methods can perform more complex functions, which in fact is only meaningful for the SAXEvenetKeeper component to operate the buffered data. These methods include:

the clearUselessData method: this method remove all content inside a particular element, except reserving some assigned children along with their ancestor path. Moreover, a stop point can be specified to stop the removal.

the collapse method: this method delete a particular element, if this node has no content inside, after that, that node's parent node will be processed in the same way until an non-empty element is met.

the getTree method: this method export the whole dom tree through an assigned XdocumentHandler interface. This methods is only for debug purpose.

The generateSAXEvent method is used to convert part of the XML tree into SAX events stream.

Method list:

XXMLElementWrapperWrapper getCurrentElement()

void setCurrentElement(XXMLElementWrapperWrapper element)

void removeCurrentElement()

boolean isCurrent(XXMLElementWrapperWrapper node)

boolean isCurrentElementEmpty();

String getNodeName(XXMLElementWrapperWrapper node);

void clearUselessData(XXMLElementWrapperWrapper node, sequence<XXMLElementWrapperWrapper> reservedDescendants, XXMLElementWrapperWrapper stopAtNode)
The node parameter is the element to be cleared.
The stopAt parameter is the node before whose path information will be deleted the removal should stop.
The reservedDescendants parameter is all nodes sorted in tree order which need to reserved along with their ancestor path.
When the stopAt parameter is null, then the removal will spread all through the element.
A typical example is after some EC/blocker is removed, this method is called with the node is set to that EC/blocker's working element, and the stopAt is set to the current blocker's working element, and the reservedDescendants includes all working element inside the node. After this call, all useless buffer data generated by the EC/blocker's removal are deleted from the buffer tree.

void collapse(XXMLElementWrapperWrapper node)

void generateSAXEvents(XDocumentHandler handler, XSAXEventKeeper saxEventKeeper, XXMLElementWrapperWrapper startNode, XXMLElementWrapperWrapper endNode)
the handler parameter is the document handler to receive SAX events.
The startNode and the endNode parameters are the two boundary nodes along tree order, between which SAX events need to be generated on.
The saxEventKeeper is the SAXEventKeeper who calls this method. Some SAXEventKeeper's methods need to be called during generating SAX events.

void getTree(XDocumentHandler handler)

XCompressedDocumentHandler

The XCompressedDocumentHandler interface is supported by XMLDocumentWrapper component, which is used to receive SAX events in a relativly efficient way.

Actually, this interface has the same functionality with the XDocumentHandler interface, the only difference is that there is less data transfer when using this interface instead of the standard XDocumentHandler. This is very pratical when considering Java/C++ calling.

void _startDocument()

void _endDocument()

void _startElement( String aName, sequence< XMLAttribute > aAttributes)
the parameters name is the same with startElement method in XDocumentHandler method, while the aAttributes parameter is an attribute array instead of an interface.
When this method is called, a new element is created under the current element node, then the new element become the new current element node.

void _endElement(String localName)
the parameters are the same with endElement method in XDocumentHandler method.
When this method is called, the current element's parent become the new current element.

void _characters(String aChars)
the parameters are the same with startElement method in XDocumentHandler method.
When this method is called, a new text node is created under the current element node.

void _processingInstruction(String target, String data)
the parameters are the same with startElement method in XDocumentHandler method.
When this method is called, a new PI node is created under the current element node.

void _ignorableWhitespace(String aWhitespaces )
the parameters are the same with startElement method in XDocumentHandler method.
When this method is called, the aWhitespaces is processed as standard characters.

void _setDocumentLocator( long columnNumber, long lineNumber, string publicId, string systemId)
four parameters are used to replace the Xlocator interface parameter in the original setDocumentLocator method of the XdocumentHandler interface.

XSAXEventKeeper

The XSAXEventKeeper interface is supported by SAXEventKeeper component, which is used to implement element collection and blocking.

There are two method categories.

One category is for EC, including:

the addElementCollector method is used to create a EC on the current element.

The removeElementCollector method is used to remove an EC.

The getElement method is used to get the buffered element.

The setElement method is used to update an element if that element is modified outside of the interface provider's control.
A tapical example is that when an decryption is finished, the EncryptedData element has already been removed, and a new decrypted element is added to the original position. Then this method is called to synchornize all pointer pointing to the EncryptedData element to the new element.

The other category is for blocker, including:

the addBlocker method is used to create a blocker on the current element. This blocker will prevent the SAXEventKeeper from forwarding following SAX events to the downstream component.

The removeBlocker method is used to remove a blocker. Now all blocked SAX events by this blocker can be forwarded again.

The isBlocking method returns whether or not the SAXEventKeeper is blocked currently.

The getCurrentBlockingNode method returns the node which it is currently blocking at.

The setNextHandler method is used to configure the next component in the SAX chain, all following SAX events will be forwarded to the new configured handler.

The printBufferNodeTree method is used to convert internal data into a string. This method is only for debug purpose.

Method list:

long addElementCollector()
The return value is the EC's id, which can be used in following functions.

removeElementCollector(long id)
the id parameter is the id of the EC to be destroyed.

Any getElement(long id)

void setElement(long id, XXMLElementWrapperWrapper aElement)

long addBlocker()

void removeBlocker(long id)

boolean isBlocking()

XXMLElementWrapperWrapper getCurrentBlockingNode()

XDocumentHandler setNextHandler(XDocumentHandler nextHandler)
the return value is the old handler.

String printBufferNodeTree()

XSecuritySAXEventKeeper

The XSecuritySAXEventKeeper interface is derived from the XSAXEventKeeper interface, and more security related methods are added.

The XSecuritySAXEventKeeper interface is supported by the SAXEventKeeper component.

The addElementCollector method is used to add a EC with specified priority and the suppressInternalNotification flag.

The cloneElementCollector method is used to clone a already created EC.

The setSecurityId method is used to configure the security id to a EC or blocker. The security id is used to detect whether different EC/blocker belongs to the same signature or encryption. (this is specially useful when check enveloped signature.)

Method list:

long addElementCollector(long priority, boolean suppressInternalNotification)
the priority parameter represents this EC's priority. When more than one EC working on the same element, it needs a priority to arrange the notify sequence. For example, when exporting, if an EncryptedData element is also signed by a signature, then the EC for the encryption template must be first notified, the EC for the signed element can only be notified after the encryption template is released (which means the encryption is generated).
The “suppressInternalNotification” flag represents whether this EC “suppresses Internal EC's notification”. For example, when exporting, a key material's EC should has this flag with true, because some key material's EC includes another key string inside as another encryption template EC, so the outer key material's EC must be notified first before the internal key string is ciphered.

long cloneElementCollector(long referenceId, long priority, boolean suppressInternalNotification)
the referenceId parameter is the id of an already created EC, the return value is the id of a new cloned EC.
The priority and suppresInternalNotification parameters are the same with the addElementCollector method.

void setSecurityId(long id, long securityId)
the id parameter is the id of the EC to be configured.

XSignatureCreationResultListener

The XSignatureCreationResultListener interface is supported by the XMLExporter component, which is used to get the result of signature creation.

The signatureCreated method give the creation result for a particular signature.

Method list:

void signatureCreated(long signatureId, SecurityOperationStatus creationResult)
the signatureId parameter is the security id, and the creationResult parameter is the creation result.

XSignatureCreationResultBroadcaster

The XSignatureCreationResultBroadcaster interface is supported by the SignatureCreator component, which is used to add/remove signature creation result listener.

The addSignatureCreationResultListener method adds a signature creation result listener.

The removeSignatureCreationResultListener method remove a signature creation result listener.

By now, one SignatureCreator can has only one signature verify result listener.

Method list:

void addSignatureCreationResultListener(XSignatureCreationResultListener listener)

void removeSignatureCreationResultListener(XSignatureCreationResultListener listener)

XSignatureVerifyResultListener

The XSignatureVerifyResultListener interface is supported by the XMLImporter component, which is used to get signature verify result.

The signatureVerified method give the verify result for a particular signature.

Method list:

void signatureVerified(long signatureId, SecurityOperationStatus verifyResult)
the signatureId parameter is the security id, and the verifyResult parameter is the verify result.

XSignatureVerifyResultBroadcaster

The XSignatureVerifyResultBroadcaster interface is supported by the SignatureVerifier component, which is used to add/remove signature verify result listener.

The addSignatureVerifyResultListener method adds a signature verify result listener.

The removeSignatureVerifyResultListener method remove a signature verify result listener.

By now, one SignatureVerifier can has only one signature verify result listener.

Method list:

void addSignatureVerifyResultListener(XSignatureVerifyResultListener listener)

void removeSignatureVerifyResultListener(XSignatureVerifyResultListener listener)

XEncryptionResultListener

The XEncryptionResultListener interface is supported by the XMLExporter component, which is used to get decryption result.

The encrypted method give the encryption result for a particular encryption.

Method list:

void encrypted(long securityId, SecurityOperationStatus encryptionResult)
the securityId parameter is the security id, and the encryptionResult parameter is the encryption result.

XEncryptionResultBroadcaster

The XEncryptionResultBroadcaster interface is supported by the Encryptor component, which is used to add/remove encryption result listener.

The addEncryptionResultListener method adds a encryption result listener.

The removeEncryptionResultListener method remove a encryption result listener.

By now, one Encryptor can has only one encryption result listener.

Method list:

void addEncryptionResultListener(XEncryptionResultListener listener)

void removeEncryptionResultListener(XEncryptionResultListener listener)

XDecryptionResultListener

The XDecryptionResultListener interface is supported by the XMLImporter component, which is used to get decryption result.

The decrypted method give the decryption result for a particular encryption.

Method list:

void decrypted(long securityId, SecurityOperationStatus decryptionResult)
the securityId parameter is the security id, and the decryptionResult parameter is the verify result.

XDecryptionResultBroadcaster

The XDecryptionResultBroadcaster interface is supported by the Decryptor component, which is used to add/remove decryption result listener.

The addDecryptionResultListener method adds a decryption result listener.

The removeSignatureVerifyResultListener method remove a decryption result listener.

By now, one Decryptor can has only one decryption result listener.

Method list:

void addDecryptionResultListener(XDecryptionResultListener listener)

void removeDecryptionResultListener(XDecryptionResultListener listener)

XSAXEventKeeperStatusChangeListener

The XSAXEventKeeperStatusChangeListener interface is supported by the XMLExporter and the XMLImporter component, which is used to notify the SAXEventKeeper's status.

The blockingStatusChanged method informs the switch of the blocking status.

The collectionStatusChanged method informs the switch of the collection status.

The bufferStatusChanged method informs whether or not the current SAXEventKeeper's buffer is empty.

Method list:

void blockingStatusChanged(boolean isBlocking)
if the isBlocking parameter is true, that represents the SAXEventKeeper just became blocking; otherwise, the SAXEvenetKeeper just leave blocking.

void collectionStatusChanged(boolean isInsideCollectedElement)
if the isInsideCollectedElement is true, that represents the SAXEvenetKeeper just entered element collection;otherwise, the SAXEventKeeper just left element collection.

void bufferStatusChanged(boolean isBufferEmpty)
if the isBufferEmpty is true, that represents the SAXEventKeeper just delete its last buffer data, now the SAXEventKeeper includes nothing.

XSAXEventKeeperStatusChangeBroadcaster

The XSAXEventKeeperStatusChangeBroadcaster interface is supported by the SAXEventKeeper component, which is used to add/remove SAXEventKeeper status change listener.

The addXSAXEventKeeperStatusChangeListener method adds a SAXEventKeeper status change listener.

The removeXSAXEventKeeperStatusChangeListener method remove a SAXEventKeeper status change listener.

By now, one SAXEventKeeper can has only one status change listener.

Method list:

void addXSAXEventKeeperStatusChangeListener(XSAXEventKeeperStatusChangeListener listener)

void removeXSAXEventKeeperStatusChangeListener(XSAXEventKeeperStatusChangeListener listener)

XMissionTaker

The XMissionTaker interface is supported by the SignatureCreator component, the SignatureVerifier component, the Encryptor component and the Decryptor component. It is used to force to end a mission.

The endMission method is used to force the interface provider to end its mission. Because there is possibility that a Signature element can't be verified, or a encryption data can't be decrypted, so this method is used to stop current mission and release all related resources, including EC and blocker.

Method list:

boolean endMission()
the return value represents whether or not the mission is accomplished successfully.

Components

XMLDocumentWrapper

Functions

Convert SAX events into DOM format.

Manipulate buffered data according to SAXEventKeeper's instruction.

Convert DOM format back to SAX events on demand.

Interfaces

XXMLDocumentWrapper

XMLExporter

Functions

Create a XMLDocumentWrapper according to configuration.

Create a XMLSignature according to configuration.

Create a XMLEncryption according to configuration.

Receive the status change of the SAXEventKeeper

Adjust the SAX chain to include or exclude the SAXEventKeeper as a output filter.

Convert an internal document into SAX event stream.

Create a SignatureCreator for new Signature elements to be created.

Create a Encryptor for new EncryptedData elements to be created.

Ask the SAXEventKeeper to create ECs.

Ask the SAXEventKeeper to create blocker.

Assign owner for EC.

Assign owner for blocker.

Reserve signature creation results.

Reserve encryption result.

Interfaces

XInitialization

XExporter

XFilter

XSAXEventKeeperStatusChangeListener

XSignatureCreationResultListener

XEncryptionResultListener

XMLImporter

Functions

Create a XMLDocumentWrapper according to configuration.

Create a XMLSignature according to configuration.

Create a XMLEncryption according to configuration.

Receive the status change of the SAXEventKeeper

Adjust the SAX chain to include or exclude the SAXEventKeeper as a output filter.

Convert SAX event stream into an internal document.

Judge whether an element should be signed somewhere or not.

Judge whether an element should be key material for other stuff.

Create SignatureVerifier objects to verify Signature element.

Create Decryptor objects to do decryption.

Ask the SAXEventKeeper to create ECs.

Ask the SAXEventKeeper to create blocker.

Assign owner for EC.

Assign owner for blocker.

Reserve verify results.

Reserve decryption result.

Interfaces

XImporter

XDocumentHandler

XSignatureVerifyResultListener

XDecryptionResultListener

XSAXEventKeeperStatusChangeListener

SAXEventKeeper

Functions

Control the XMLDocumentWrapper to manipulate the buffer data.

Manipulate ECs.

Manipulate blockers.

Notify EC's collection end.

Broadcast SAXEvenetKeeper's status change.

Interfaces

XDocumentHandler

XSAXEventKeeper

XSecuritySAXEventKeeper

XReferenceResolvedBroadcaster

XSAXEventKeeperStatusChangeBroadcaster

SignatureCreator

Functions

Monitor the collection of signed elements, key material and signature template.

Invoke signature generation.

Clear up involved EC and blocker.

Interfaces

XReferenceResolvedListener

XSignatureCollector

XBlockerMonitor

XKeyCollector

XMissionTaker

SignatureVerifier

Functions

Monitor the collection of signed elements, key material and signature template.

Invoke signature verification.

Clear up involved EC.

Broadcast verify result.

Interfaces

XReferenceResolvedListener

XSignatureCollector

XKeyCollector

XMissionTaker

XSignatureVerifyResultBroadcaster

Encryptor

Functions

Monitor the collection of key material and encryption template.

Invoke encryption.

Clear up involved EC and blocker.

Interfaces

XReferenceResolvedListener

XBlockerMonitor

XKeyCollector

XMissionTaker

Decryptor

Functions

Monitor the collection of key material and encryption template.

Invoke decryption.

Clear up involved EC and blocker.

Broadcast decryption result.

Interfaces

XReferenceResolvedListener

XBlockerMonitor

XKeyCollector

XMissionTaker

XDecryptionResultBroadcaster

XMLSignature

Functions

Generate signature.

Verify signature.

Interfaces

See XMLSignature design document.

XMLEncryption

Functions

Encrypt.

Decrypt.

Interfaces

See XMLEncryption design document.

Solutions

Notify Sequence

An element can be buffered for more than one purpose, each purpose needs one independent EC. When this element is completely buffered, in what sequence these ECs are notified collection end? If a blocker is working inside the element of the EC, should the EC be notified before or after the blocker is released?

The following paragraph will describe the notify sequence issue.

When exporting, a EC can be used for a signed element, a signature template, an encryption template, a key material. When different type of ECs working on the same element, the notify sequence should be:

key material's EC

encryption template's EC

signature template's EC

signed element's EC

The key material's EC should be notified before any encryption is performed, because any internal encryption may cause the key value become invisible.

The signed element's EC must be notified in the end. Because the message digest's calculation need the signed element's final shape as input, that is to say, all internal changes have been finished before that calculation.

Moreover, inside a signed element's EC, if there is any blocker with different security id, this EC can't be notified until all this kind of blocker is removed.

When importing, the notify sequence should be:

signed element's EC

signature template's EC

encryption template's EC

key material's EC

the sequence is reversed from the one for exporting, the reason is so obvious.

Transfer DOM data

The JSR105 based XMLDocumentWrapper implementation (XMLDocumentWrapper_Impl_JSR105) will have a native method as following (Java code):

Document getDocument();

which will return the whole buffered data as a Document interface. While, the XMLSecurity based XMLDocumentWrapper (XMLDocumentWrapper_Impl_XMLSec) will have following native method (c++ code):

XMLDocPtr * getDocument();

this method will return a XMLDocPtr pointer which represents the whole buffered document.

Both of these two methods don't belong to any UNO interface, mostly because their return type.

When creating/verifying signatures, the XMLSignature component will get buffered SAX events as native data format from the XMLDocumentWrapper component through above methods, i.e., the JSR105 based XMLSignature (XMLSignature_Impl_JSR105) should get a DOM representing data by calling getDocument method (Java), and the XMLSecurity based XMLSignature (XMLSignature_Impl_XMLSec)will get a XMLDocPtr by calling getDocument method (c++).

To achieve this point, we will use the XUNOTunnel interface.

The two XMLSignature components will use the XUNOTunnel interface to get the native class instance (non-UNO instance) of XMLDocumentWrapper implementation.

Helper Components

SAXHelper

This class can translate UNO based SAX events into SAX events in the libxml2 format.

Prototype

The chapter will describe how to use the prototype Java program.

Program overview

The prototype program is used to demonstrate the functionality of the XML Security Framework Components. its UI looks like following:

This is the original document which needs to be exported or imported. This document actually is a xml file. You can use command line “Java TestTool xxx.xml” to open a file directly, or use the “Open...” button to open a file interactively.
Because no DTD to assist analyzing, any signature template and encryption template need to be directly included in this xml file. When export, a signature template should have empty DigestValue elements and empty SignatureValue element, a encryption template should include a CipherData element with plain XML data to be encrypted. When import, both a signature template and a encryption template should have complete data.

This text field shows the SAX event which is just sent out by the first component in the SAX chain. The first component is the XMLExporter in exporting, or the SAXParser in importing.

This table area shows the ECs owned by the application, which simulates the XMLImporter or XMLExporter holding ECs which will have further reference on.
To make it simple, this application use a RefNum attribute to estimate the referencing number on a EC.
There are three columns, the first column is the element's Id attribute, the second column is the leftover reference number, the third column is the EC's id.

This is the DOM tree inside of the XMLDocumentWrapper. A star mark represents the current blocking element.

This is the information of EC and blocker in the SAXEventKeeper.
All EC and blocker are organized in a tree, which represents the relationship between their working elements.
Each item starts with an element name, followed by name of its parent element in a square bracket pair.
The string following “EC=” is EC's information:
[EC's id] – [priority] ([security id])
the security id equals to -1 means no signature id assignment yet.
The stirng number following “BR=” is a blocker's information:
[blocker's id]([security id])

This is the current SAX chain representative.

This is the result tree. When export, this is what received by the SAXWriter; when import, this is what received by the XMLImporter.

These are all function button.
The “Open...” button is used to open an xml file as the original document.
The “Start” button is used to start the export/import.
When “Start” button is pressed, the “Go” button and the “Step” button are enabled.
The “Go” button is used to export/import the original document continuously. While the “Step” button is used to export/import event by event.
The “export, not import” check box indicates whether exporting or importing is in progress, when checked, it means exporting.
The “java, not c++” check box indicates whether using the java based components or c++ based components. when checked, it means java.
The “Save...” button is used to save the result tree to an xml file.

File format

When a xml file is read, it needs some particular format for the application to recognize.

Because there is no DTD for the xml file, so all blank text will be ignored for briefness.

When an element is signed, it should has an “id” attribute. Meanwhile, it needs an additional attribute named “refNum” which represents how many times this element is referenced by signature element. If the “refNum” attribute is ignored, the default value is 999, that is to say, this element will be kept in buffer till the end of the exporting/importing process.

The following is an example of a signed element.

<Data_C id="C" refNum="3">

This is Data_C

</Data_C>

the signature template format is similar with w3c's definition, some untouched fields are ignored for briefness, as following.

<Signature>

<KeyInfo>

<RetrievalMethod URI="...">

</RetrievalMethod>

<KeyValue>...</KeyValue>

</KeyInfo>

<SignedInfo>

<Reference URI="C">

<DigestValue>

d.i.g.e.s.t.V.a.l.u.e

</DigestValue>

</Reference>

...

</SignedInfo>

<SignatureValue>

s.i.g.n.a.t.u.r.e.v.l.a.u.e

</SignatureValue>

<Object>

...

</Object>

</Signature>

The KeyInfo can include either KeyValue or RetrievalMethod, not both. When the KeyValue included, this signature has its key material by its own, otherwise, the URI attribute points to the external key material element.

There can be several Reference elements under the signedInfo element. The URI attribute in the Reference element can be either an Id, which refer a same-document element, or an external URI, which refer a detached content. When using external URI, there must be some mechanism to retrieve the content of the URI.

When export, the content inside digestvalue and signaturevalue needs to be empty.

The Object element is optional, it can be used to store some additonal information about the signature, for instance, we can use the Object element to reserve the time of the signature, as the following:

<Object>

<SignatureProperties>

<SignatureProperty Id="ID_XXXX" Target="#ID_XXX">

<dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">

...

</dc:date>

</SignatureProperty>

</SignatureProperties>

</Object>

Because the SignatureProperty element has an Id attribute, so it is possible to sign the date by adding into the signature a new reference whose URI attribute points to this SignatureProperty element.

The encryption template format is similar with w3c's definition, some untouched fields are ignored for briefness, as following.

<EncryptedData|Encryptedkey>

<KeyInfo>

<RetrievalMethod URI="...">

</RetrievalMethod>

<KeyValue>...</KeyValue>

</KeyInfo>

<CipherData>

<CipherValue>

...

</CipherValue>

</CipherData>

</EncryptedData|Encryptedkey>

The KeyInfo is the same with the signature template.

When import, the content inside CipherValue is the cipher data; when export, the CipherValue element is replaced with plain XML data to be encrypted.

Use Cases	9/36

1995-11-21T17:41:00

Malte Timmermann