BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Security   |   Topic List   |   Previous   |   Next   |   Contents

   Using BEA Tuxedo Security

Sending and Receiving Signed Messages

Message-based digital signature provides end-to-end authentication and message integrity protection. For a diagram that illustrates how it works, see the figure BEA Tuxedo PKCS-7 End-to-End Digital Signing.

To add a digital signature to a BEA Tuxedo message buffer, the originating process or user signs the message buffer. This signature contains a cryptographically secure checksum of the message buffer's content and a timestamp based on the signer's local clock.

Any party with access to the message buffer can verify that the signing party's signature is authentic, that the message buffer content is unchanged, and that the timestamp is within a configured tolerance of the verifier's local clock. In addition, time-independent verification by a third party guarantees non-repudiation: the originating process or user cannot later deny authorship or claim the message was altered.

Writing Code to Send Signed Messages

The following flowchart provides the procedure for writing code to send signed messages.

Procedure for Sending Signed Messages

For details about these steps and insight into how the system signs a message buffer, see the following topics.

Step 1: Opening a Key Handle for Digital Signature

Call the tpkey_open(3c) function or TPKEYOPEN(3cbl) routine to make the private key and the associated digital certificate of the signer available to the originating process. The private key is highly protected, and possession of it is equivalent to possessing the signer's identity.

In order to access the signer's private key, the originating process must prove its right to act as the signer. Proof requirements depend on the implementation of the public key plug-in interface. The default public key implementation requires a secret password from the calling process.

When the originating process calls tpkey_open() to open the key handle, it specifies either the TPKEY_SIGNATURE or TPKEY_AUTOSIGN flag to indicate that the handle will be used to digitally sign a message buffer. Typically, a client makes this call after calling tpinit(), and a server makes this call as part of initializing through tpsvrinit().

Opening a key handle with the TPKEY_AUTOSIGN flag enables automatic signature generation: subsequently, the originating process signs message buffers automatically whenever they are sent. Using the TPKEY_AUTOSIGN flag is beneficial for three reasons:

The following example code shows how to open a signer's key handle. TPKEY is a special data type defined in the atmi.h header file.

Opening a Signer's Key Handle-Example


main(argc, argv)
int argc;
char *argv[];
#endif

{
TPKEY sdo_key;
char *sdo_location;
.
.
.
if (tpkey_open(&sdo_key, "sdo", sdo_location,
NULL, 0, TPKEY_SIGNATURE) == -1) {
(void) fprintf(stderr, "tpkey_open sdo failed
tperrno=%d(%s)\n", tperrno, tpstrerror(tperrno));
exit(1);
}
.
.
.
}


Step 2 (Optional): Getting Key Handle Information

You may want to get information about a signer's key handle to establish the validity of the key. To do so, call the tpkey_getinfo(3c) function or TPKEYGETINFO(3cbl) routine. While some of the information returned may be specific to a cryptographic service provider, a core set of attributes is common to all providers.

The default public key implementation supports the following signature modes for computing signatures on a message buffer:

The message digest algorithm is controlled by the DIGEST_ALG key attribute, and the public key signature is controlled by the SIGNATURE_ALG key attribute. Public key sizes from 512 to 2048 bits are supported, to allow a wide range of safety and performance options. The public key size is controlled by the SIGNATURE_BITS key attribute.

The default public key implementation recognizes only those digital certificate signatures that are created with these algorithm and key size choices.

The following example code shows how to get information about a signer's key handle.

Getting Information About a Signer's Key Handle-Example


main(argc, argv)
int argc;
char *argv[];
#endif

{
TPKEY sdo_key;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(sdo_key, "PRINCIPAL",
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, "Unable to get information
about principal: %d(%s)\n",
tperrno, tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}


Step 3 (Optional): Changing Key Handle Information

To set optional attributes associated with a signer's key handle, call the tpkey_setinfo(3c) function or TPKEYSETINFO(3cbl) routine. Key handle attributes vary, depending on the cryptographic service provider.

The following example code shows how to change information associated with a signer's key handle.

Changing Information Associated with a Signer's Key Handle-Example


main(argc, argv)
int argc;
char *argv[];
#endif

{
TPKEY sdo_key;
static const unsigned char sha1_objid[] = {
0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
};
.
.
.
if (tpkey_setinfo(sdo_key, "DIGEST_ALG", (void *) sha1_objid,
sizeof(sha1_objid), 0) == -1) {
(void) fprintf(stderr, "tpkey_setinfo failed
tperrno=%d(%s)\n",
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}


Step 4: Allocating a Buffer and Putting a Message in the Buffer

To allocate a typed message buffer, call the tpalloc(3c) function. Then put a message in the buffer.

Step 5: Marking the Buffer for Digital Signature

To mark, or register, the message buffer for digital signature, call the tpsign(3c) function. By calling this function, you attach a copy of the signer's key handle to the message buffer. If you open the key with the TPKEY_AUTOSIGN flag, each message that you send is automatically marked for digital signature without an explicit call to tpsign(); signature parameters are stored and associated with the buffer for later use.

Note: In COBOL applications, use the AUTOSIGN settings member to create a digital signature. See TPKEYOPEN(3cbl).

The following example code shows how to mark a message buffer for digital signature.

Marking a Message Buffer For Digital Signature-Example


main(argc, argv)
int argc;
char *argv[];
#endif

{
TPKEY sdo_key;
char *sendbuf, *rcvbuf;
.
.
.
if (tpsign(sendbuf, sdo_key, 0) == -1) {
(void) fprintf(stderr, "tpsign failed tperrno=%d(%s)\n",
tperrno, tpstrerror(tperrno));
tpfree(rcvbuf);
tpfree(sendbuf);
tpterm();
(void) tpkey_close(sdo_key, 0);
exit(1);
}
.
.
.
}


Step 6: Sending the Message

After the message buffer has been marked for digital signature, transmit the message buffer using one of the following C functions or COBOL routines:

Step 7: Closing the Signer's Key Handle

Call the tpkey_close(3c) function or TPKEYCLOSE(3cbl) routine to release the signer's key handle and all resources associated with it.

How the System Generates a Digital Signature

Just before a message buffer is sent, the public key software digitally signs the message. If a signed buffer is transmitted more than once, the software generates a new signature for each communication. This process makes it possible to modify a message buffer after marking the buffer to be digitally signed.

The public key software generates a digital signature by performing the following three-step procedure.

  1. digest[message_buffer_data + buffer_type_string + buffer_subtype_string] = hash1

  2. digest[hash1 + local_timestamp + PKCS-7_message_type] = hash2

  3. {hash2}signer's_private_key = encrypted_hash2 = digital_signature

The notation digest[something] means that a hash value has been computed for something using a message digest algorithm-in this case, MD5 or SHA-1. The notation {something}key means that something has been encrypted or decrypted using key. In this case, the computed hash value is encrypted using the signer's private key.

Signature Timestamp

A digital signature includes a timestamp from the local system's clock. Inclusion of such a timestamp ensures that any tampering with the timestamp value will be detected when the recipient verifies the signature. In addition, a copy of the timestamp accompanies the digitally signed message when the message is routed to its destination.

Time resolution is to the second. Timestamps are stored in PKCS-9 SigningTime format.

Multiple Signatures

More than one signature can be associated with a message buffer, which means that any number of signers can sign a message buffer in parallel. A signer can be a person or a process. Each signer signs the message buffer using his, her, or its private key.

Different signatures may be based on different message digest or digital signature algorithms. If two signers use the same message digest and digital signature algorithm, the hash value is computed for only one of them.

Signed Message Content

A digitally signed message buffer is represented in the PKCS-7 format as a version 1 SignedData content type. The SignedData content type, as used by the BEA Tuxedo system, consists of the following items:

As shown in the following figure, the message content is enveloped by SignedData content type.

SignedData Content Type

How a Signed Message Is Received

No application code is needed to receive a signed message buffer. The public key software automatically verifies the attached digital signatures and passes the message to the receiving process.

Upon receiving a signed message buffer, the public key software, operating on behalf of the receiving process, performs the following tasks.

  1. Reads the digital signature information attached to the received message, including the signer's digital certificate, message digest algorithm, digital signature algorithm, and signature timestamp.

  2. Decrypts the attached digital signature (encrypted hash value) using the signer's public key (found in the signer's digital certificate) and the digital signature algorithm.

  3. Re-computes the hash value for the received message, as shown in the following two-step procedure.

    1. digest[message_buffer_data + buffer_type_string + buffer_subtype_string] = hash1

    2. digest[hash1 + received_timestamp + PKCS-7_message_type] = hash2

      The notation digest[something] means that a hash value has been computed for something using a message digest algorithm-in this case, MD5 or SHA-1.

  4. Compares the re-computed hash value with the received hash value; if the two are not identical, discards the message buffer.

  5. Compares the received timestamp with the local system's clock; if the timestamp is not within a configured tolerance, discards the message buffer.

  6. If the message buffer successfully passes the checks performed in Steps 4 and 5, the public key software decodes the message buffer data, buffer type string, and buffer subtype string, and then passes the message to the receiving process. This step reverses the encoding performed by the originating process. (The BEA Tuxedo encoded format allows a message buffer's signature to be verified on any machine architecture.)

    Note: If none of the attached digital signatures can be verified, the receiving process does not receive the message buffer. Moreover, the receiving process has no knowledge of the message buffer.

Verifying Digital Signatures

The public key software automatically verifies digital signatures whenever a signed message buffer enters a client process, server process, or any system process that needs to access the content of the message buffer. If a system process is acting as a conduit (that is, if it is not reading the content of the message), then the attached digital signatures need not be verified. Bridges and Workstation Handlers (WSHs) are examples of system processes acting as conduits.

The signature timestamp is based on an unsynchronized clock, and therefore cannot be fully trusted, especially if the signature is performed on a PC or personal workstation. However, a server may reject requests with timestamps that are too old or dated too far into the future. The capability to reject a request based on the timestamp provides a measure of protection against replay attacks.

Verifying and Transmitting an Input Buffer's Signatures

If a message buffer is passed to an ATMI function (such as tpacall()) as an input parameter, the public key software verifies any signatures previously attached to the message and then forwards the message. This behavior enables a secure, verified transfer of information with signatures from multiple processes.

If a server modifies a received message buffer and then forwards the buffer, the original signature is no longer valid. In this case, the public key software detects the invalid signature and silently discards it. For an example of the process, see Discarding an Input Buffer's Encryption Envelopes.

Replacing an Output Buffer's Signatures

If a message buffer is passed to an ATMI function (such as tpgetreply()) as an output parameter, the public key software deletes any signature information associated with the buffer. This information includes any pending signatures and signatures from previous uses of the buffer. (A pending signature is a signature that is registered with a message buffer.)

New signature information might be associated with the new buffer content after successful completion of this operation.

See Also