Without a firm grounding on digital signature basics, it is difficult to understand the SOAP message signature and how Apache Rampart/C supports it. Hence we are going to tell you a simple story that explains digital signature. In our story, there are two people named Peter and Johanna. Peter needs to send a message to Johanna. For example to say, "Hi, The party is at 7 today. I'll be there. Love you - Peter". The message is simple and they use computers to communicate. The bad news is that there is another person called Martino, who doesn't like the relationship between Peter and Johanna and is always trying to create trouble between them.
Now let's analyze the possibilities of Martino's actions.
- He can send a completely new message to Johanna pretending that it's from Peter. (e.g.,- It's over between us - Peter)
- He can alter the message (e.g. date/time), and have some fun.
Now Peter and Johanna have three problems as far as this message delivery is concerned.
- Johanna has to be sure that the person who sent this message is Peter.
- Johanna has to be sure that the message is not altered in transit.
- However, there is another problem. If Peter denies sending this message, Johanna should be able to produce the message as evidence.
Digital Signature Overview
The above mentioned problems are analogous to the security threats that are to be solved using digital signatures. If we express these problems in computer security terminology, they are known as.
- Authenticity (Who sent this?)
- Data integrity (Is the message modified in transit?)
- Non-repudiation (Can the sender deny?)
A digital signature provides mathematical algorithms that binds the data to be protected with the party that signs it. The algorithm should be capable of signing data as well as verifying it later. For this, we use two mathematically related keys known as the Public Key and the Private Key. Even though these two keys are related to each other, one cannot be derived from the other. One key (Public Key) can be accessed by the parties who are wishing to communicate, whilst the other (Private Key) should be protected. Mapping this to our example, the private key of Peter should not compromised and the public key should be made available to other parties (e.g., Peter's friends including Johanna, and even Martino).
To send the most important message to Johanna, Peter has to sign the message. He signs it by providing his private key along with the data to a desired algorithm. Then he sends the message plus the digital signature. Upon arrival of the message, Johanna will use Peter's public key to verify whether the message and the digital signature matches. If Martino tried to alter the message or tried to sign a new message using his own private key, the verification will fail. That solves the first two problems. For the third, that is, if Peter actually sends this message expecting to deny it the next day, Johanna can use Peter's public key and the signed message to prove that no one but only Peter can send this message. The private key is meant to be protected by Peter.
Signature Requirements for Web Services
In the distribution computing world, Web services play a crucial role. The capability of being protocol and programming language independent, attracts many client/server applications to Web services. Existing technologies like HTTPS cannot answer the security requirements of SOAP/XML technologies. For example, HTTPS can be used to prevent possible attacks during the message transition time. However, it cannot be used for non-repudiation. It cannot be used to verify the integrity/authentication of the messages received at a different time.
Web services security is not about P2P security. It should provide message level security. This means that the message should be secured even after the transition time. Also, a SOAP message can travel via multiple intermediaries before coming to its destination. These intermediaries should be able to secure messages for the portion they are responsible for in the SOAP message. A typical example would be adding timestamps and signing them so that the end service can verify the route, which the message travelled.
XML Signature Overview
The XML signature specification provides a method to use digital signatures in XML documents. This includes a provision of a structure to keep the original message with the signature, and other various elements to specify the algorithms, keys, and other transformations applied during the signing process. The following shows the structure of a signed XML document.
(<Reference URI? >
(Here ? denotes 0 or 1 occurrences, + denotes 1 or more occurrences,
* denotes zero or more occurrences )
Rampart/C Support in SOAP Message Signature
Rampart/C supports SOAP message signature as per the WS-Security specification. With a simple configuration setup, an Axis2/C user can sign the SOAP messages that are exchanged. The configurations required will be discussed later. Before that, an understanding of the signature process will be useful.
The Signature Process
Suppose we need to sign two parts in a SOAP message. For brevity, let's assume two elements called <a:foo> and <b:bar> When the user specifies that these parts need to be signed, Rampart/C tries to locate them in the SOAP message. Once found, Rampart/C performs the following actions.
- Do the transformations required on the element. e.g., C14N
- Make the digest. e.g., SHA-1
- Create a reference to the signed part.
In our example, we need to perform the above actions to create two references for <a:foo> and <b:bar> Once we have done this, we enclose these references into one element called <ds:SignedInfo> Then we add the elements to inform the signature method and the canonicalization method as specified by the XML-Signature specification.
At this moment, we have a ready to be signed <ds:SignedInfo> element. Then Rampart/C will sign the <ds:SignedInfo> element and place the signature in the <ds:SignatureValue> element. The relevant key information will be placed in the <ds:KeyInfo> element. All three elements will be placed inside a <ds:Signature> element. See such a signed SOAP message.
The Verification Process
The verification is carried out in two steps.
- The digest level verification
- The signature verification
The digest level verification is carried out to ensure the integrity of the signed parts. Rampart/C re-calculates the digest of the signed part and compares it with the received. If the signed part is altered, then the verification fails. The digest level verification will be carried out for all the references enclosed in the <SignedInfo> element.
Upon successful completion of the digest level verification, Rampart/C tries to verify the signature of the message. The key information and the algorithm used will be extracted from the message. If the signature fails, a fault will be thrown back.
The Configuration Set up
Rampart configurations are based on WS-Security Policy specifications. A configuration file is an XML file which carries policy assertions. (Sample) The client side policies are specified in the policy.xml that must reside in the same directory as the client's axis2.xml file. The server side policies are located in the services.xml file. Please find a number of sample policy files available under samples/secpolicy.
The configuration allows the user to specify the following.
- What parts of the message need to be signed
- The algorithm suite to be used
- How to get the keys to sign/verify the message
- How to send key information to the other party
For brevity, we are not going to discuss assertions defined in WS-Security Policy. Instead, we will discuss assertions that are needed to set up Rampart/C to sign a SOAP message. Note that some of the assertions are specially defined for Rampart/C. For example, to specify the certificate we have the assertion rampc:Certificate.
What parts of the message should be signed?
To sign the message, the user needs to specify which parts of the message need to be signed. For example, if a user wants to sign the body of the SOAP message and some headers, he has to specify the following.
<sp:Header Name="LocalName" Namespace="NamespaceURI" ... />
Which algorithm suite should be used?
WS-Security Policy defines different algorithm suites. These suites specify the symmetric/asymmetric algorithms, key lengths, etc. The user can specify which is to be used as follows.
For the moment, Rampart/C supports Basic128Rsa15, Basic192Rsa15, and Basic256Rsa15.
How do we get the keys to sign/verify the messages?
SOAP messages are signed using the private key. This will be verified later with the public key, which is freely available. Thus, for an initiator, there should be a way to specify his own Public/Private keys. Rampart has come up with its own policy assertions for this as follows.
If the other party's public key needs to be configured, it's done by using the following assertion.
How do we send key information to the other party?
One important aspect of SOAP message signing is the ability to send details about the public key that should be used for verification. This enables the receiving party to identify the key and verify the message on arrival or even later. The syntax is as follows.
<sp:Wss11 xmlns:sp=http://schemas.xmlsoap.org/... >
Sample one and two show how to set up these configurations. You may find more of such samples under rampart/samples/secpolicy. Please run those scenarios and see the <ds:KeyInfo> element and the security header.
A SOAP message signature provides authenticity, data integrity, and non-repudiation of messages exchanged via open channels that are vulnerable to attacks. Being the security module of the Axis2/C engine, Rampart/C supports SOAP message signature as per the WS-Security specification 1.0. For the configuration setup, Rampart/C uses policy assertions as per the WS-Security policy specification 1.1. Thus, with a minimum effort in configurations, Axis2/C users can secure their SOAP messages using Rampart/C.
Malinda Kaushalye Kapuruge, Software Engineer, WSO2 Inc. kaushalye at wso2 dot com