As shown in Figure 3‑1, application programmers have access to the ATMI functions for authenticating users and controlling user access, and for incorporating public key encryption techniques into their applications. Also shown is the absence, at the application level, of ATMI functions for auditing or link-level encryption. Auditing is accessed at the Oracle Tuxedo system level, and link-level encryption is configured by the application administrator.
main()
{
call tpchkauth() to check security level of ATMI application
get usrname, cltname
prompt for application password
prompt for per-user password
allocate a TPINIT buffer
place initial client identification into TPINIT buffer
call tpinit() to enroll as a client of the ATMI application
allocate buffer
do while true {
place user input in buffer
send service request
receive reply
pass reply to user }
leave application
}
A client program written in C uses tpinit(3c) to comply with the level of security set for the ATMI application and to join the application. The argument to
tpinit() is a pointer to a
TPINIT buffer. To perform the same tasks in a COBOL application, a client program calls
TPINITIALIZE(3cbl), specifying a pointer to a
TPINFDEF-REC record as an argument.
•
|
“Writing Clients” on page 4‑1 in Programming an Oracle Tuxedo ATMI Application Using C and Programming an Oracle Tuxedo ATMI Application Using COBOL
|
•
|
tpinit(3c) in Oracle Tuxedo ATMI C Function Reference
|
An application programmer writing in C uses tpchkauth() to check the ATMI application’s security level before calling
tpinit(3c), so that the client program can prompt for the application password and the user authentication data needed for the
tpinit() call;
tpchkauth() is called without arguments.
The tpchkauth() function (or
TPCHKAUTH() routine) returns one of the following values.
•
|
“Writing Clients” on page 4‑1 in Programming an Oracle Tuxedo ATMI Application Using C and Programming an Oracle Tuxedo ATMI Application Using COBOL
|
TPINIT is defined in the
atmi.h header file, and
TPINFDEF-REC is defined in the COBOL
COPY file. They have the following structures.
|
|
Note: MAXTIDENT may contain up to 30 characters.
|
|
|
|
|
|
|
|
|
|
|
|
|
tpinit() or TPINITIALIZE() validates this password by comparing it to the configured application password stored in the TUXCONFIG file.**
|
|
|
|
|
|
|
|
|
To get a size value for this field, writers of client programs written in C can call TPINITNEED with the number of bytes of user-specific data expected to be sent. TPINITNEED is a macro provided in the atmi.h header file.
|
|
|
tpinit() or TPINITIALIZE() forwards the user-specific data to the authentication server for validation. For default authentication, the authentication server is AUTHSVR.
|
* This field is required for the USER_AUTH, ACL, and MANDATORY_ACL security levels provided by default authentication and authorization.
** The binary equivalent of the UBBCONFIG file; created using tmloadcf(1).
*** Usually a user password.
|
1.
|
The initiator Workstation client and the target workstation listener (WSL) exchange link-level encryption (LLE) min- max values to be used to set up LLE on the link between the initiator Workstation client and the target WSH. LLE is described in “Link-Level Encryption” on page 1‑22.
|
When a native client calls the tpinit() function or the
TPINITIALIZE() routine to join an ATMI application, only authentication occurs. In essence, the native client authenticates with itself.
Listing 3‑2 demonstrate the transfer of data from the
TPINIT buffer for a Workstation client. The transfer of data from the
TPINFDEF-REC record is similar to what is shown in the figure.
For a Workstation client and assuming default authentication, the authentication plug-in at the Workstation client uses the
passwd/
PASSWD field to encrypt the information when transmitting the information over the network. The encryption algorithm used is 56-bit DES, where DES is an acronym for the Data Encryption Standard. The authentication plug-in at the target WSH uses the application password stored in the
TUXCONFIG file to decrypt the information. For a native client, the system simply compares the
passwd/
PASSWD field with the application password stored in the
TUXCONFIG file.
Note:
|
At the Workstation client, the passwd/ PASSWD field is delivered to the authentication plug-in by a means other than through the authentication plug-in interface. At the WSH, the application password in the TUXCONFIG file is delivered to the authentication plug-in through the authentication plug-in interface during application booting.
|
After a successful authentication of a Workstation client, the tpinit() function ends with the sending of another buffer to the WSH containing the values of the
usrname,
cltname, and
flags fields, to ensure that the WSH receives this information for the authenticated Workstation client. Similarly, the
TPINITIALIZE() routine ends with the sending of another buffer containing the same information. A custom authentication plug-in might not send this information to the WSH during the authentication procedure, and the WSH needs this information for reporting purposes, that is, during an invocation of the
tmadmin(1) printclient (
pclt) command.
•
|
The TPINIT/ TPINFDEF-REC feature cannot be used.
|
•
|
“Writing Clients” on page 4‑1 in Programming an Oracle Tuxedo ATMI Application Using C and Programming an Oracle Tuxedo ATMI Application Using COBOL
|
Note:
|
The COBOL TPKEYDEF record is used to manage public-private keys for performing message-based digital signature and encryption operations. See “COBOL Language ATMI Return Codes and Other Definitions” in the introduction part of the Oracle Tuxedo ATMI COBOL Function Reference for a description of the TPKEYDEF record.
|
Table 3‑2 and
Table 3‑3 summarize the ATMI interfaces for public key security. Each function is also documented in the
Oracle Tuxedo ATMI C Function Reference and the
Oracle Tuxedo ATMI COBOL Function Reference.
|
|
|
•
|
Signature Generation
The key identifies the calling process as being authorized to generate a digital signature under the principal’s identity. (A principal may be a person or a process.) Calling tpkey_open() with the principal’s name and either the TPKEY_SIGNATURE or TPKEY_AUTOSIGN flag returns a handle to the principal’s private key and digital certificate.
|
•
|
Signature Verification
The key represents the principal associated with a digital signature. Signature verification does not require a call to tpkey_open(); the verifying process uses the public key specified in the digital certificate accompanying the digitally signed message to verify the signature.
|
•
|
Encryption
The key represents the intended principal of an encrypted message. Calling tpkey_open() with the principal’s name and either the TPKEY_ENCRYPT or TPKEY_AUTOENCRYPT flag returns a handle to the principal’s public key via the principal’s digital certificate.
|
•
|
Decryption
The key identifies the calling process as being authorized to decrypt a private message for the intended principal. Calling tpkey_open() with the principal’s name and the TPKEY_DECRYPT flag returns a handle to the principal’s private key and digital certificate.
|
|
|
•
|
PRINCIPAL
The name of the principal associated with the specified key (key handle). A principal may be a person or a process, depending on how an application developer sets up public key security. Any principal specified in an ATMI application’s UBBCONFIG file using the SEC_PRINCIPAL_NAME parameter become the identity of one or more system processes. (See “Specifying Principal Names” on page 2‑11 and “Initializing Decryption Keys Through the Plug-ins” on page 2‑56 for more detail.)
|
•
|
PKENCRYPT_ALG
An ASN.1 Distinguished Encoding Rules (DER) object identifier of the public key algorithm used by the key for public key encryption. See the tpkey_getinfo(3c) reference page for details.
|
•
|
PKENCRYPT_BITS
The key length of the public key algorithm (RSA modulus size). The value must be within the range of 512 to 2048 bits, inclusive.
|
•
|
SIGNATURE_ALG
An ASN.1 DER object identifier of the digital signature algorithm used by the key for digital signature. See the tpkey_getinfo(3c) reference page for details.
|
•
|
SIGNATURE_BITS
The key length of the digital signature algorithm (RSA modulus size). The value must be within the range of 512 to 2048 bits, inclusive.
|
•
|
ENCRYPT_ALG
An ASN.1 DER object identifier of the symmetric key algorithm used by the key for bulk data encryption. See the tpkey_getinfo(3c) reference page for details.
|
•
|
ENCRYPT_BITS
The key length of the symmetric key algorithm. The value must be within the range of 40 to 128 bits, inclusive.
|
•
|
DIGEST_ALG
An ASN.1 DER object identifier of the message digest algorithm used by the key for digital signature. See the tpkey_getinfo(3c) reference page for details.
|
•
|
PROVIDER
The name of the cryptographic service provider.
|
•
|
VERSION
The version number of the cryptographic service provider’s software.
|
|
|
|
|
|
|
|
|
|
|
Access the digital signature and encryption information associated with a typed message buffer. tpenvelope() returns status information about the digital signatures and encryption envelopes attached to a particular message buffer. It also returns the key handle associated with each digital signature or encryption envelope. The key handle for a digital signature identifies the signer, and the key handle for an encryption envelope identifies the recipient of the message.
|
|
Convert a typed message buffer into an exportable, machine-independent (externalized) string representation. tpexport() generates any digital signatures or encryption envelopes associated with a typed message buffer just before it converts that buffer into an externalized string representation.
|
|
|
|
|
|
•
|
Signature Generation
The key identifies the calling process as being authorized to generate a digital signature under the principal’s identity. (A principal can be a person or a process.) Calling TPKEYOPEN() with the principal’s name and the TPKEY-SIGNATURE and TPKEY-AUTOSIGN settings returns a handle to the principal’s public key and enables signature generation in AUTOSIGN mode. The public key software generates and attaches the digital signature to the message just before the message is sent.
|
•
|
Signature Verification
The key represents the principal associated with a digital signature. Signature verification does not require a call to TPKEYOPEN(); the verifying process uses the public key specified in the digital certificate accompanying the digitally signed message to verify the signature.
|
•
|
Encryption
The key represents the intended principal of an encrypted message. Calling TPKEYOPEN() with the principal’s name and the TPKEY-ENCRYPT and TPKEY-AUTOENCRYPT settings returns a handle to the principal’s public key (via the principal’s digital certificate) and enables encryption in AUTOENCRYPT mode. The public key software encrypts the message and attaches an encryption envelope to the message; the encryption envelope enables the receiving process to decrypt the message.
|
•
|
Decryption
The key identifies the calling process as being authorized to decrypt a private message for the intended principal. Calling TPKEYOPEN() with the principal’s name and the TPKEY-DECRYPT setting returns a handle to the principal’s private key and digital certificate.
|
|
|
•
|
PRINCIPAL
The name of the principal associated with the specified key (key handle). A principal may be a person or a process, depending on how an ATMI application developer sets up public key security. Any principal specified in an ATMI application’s UBBCONFIG file using the SEC_PRINCIPAL_NAME parameter become the identity of one or more system processes. (See “Specifying Principal Names” on page 2‑11 and “Initializing Decryption Keys Through the Plug-ins” on page 2‑56 for more detail.)
|
•
|
PKENCRYPT_ALG
An ASN.1 Distinguished Encoding Rules (DER) object identifier of the public key algorithm used by the key for public key encryption. See the TPKEYGETINFO(3cbl) reference page for details.
|
•
|
PKENCRYPT_BITS
The key length of the public key algorithm (RSA modulus size). The value must be within the range of 512 to 2048 bits, inclusive.
|
•
|
SIGNATURE_ALG
An ASN.1 DER object identifier of the digital signature algorithm used by the key for digital signature. See the TPKEYGETINFO(3cbl) reference page for details.
|
•
|
SIGNATURE_BITS
The key length of the digital signature algorithm (RSA modulus size). The value must be within the range of 512 to 2048 bits, inclusive.
|
•
|
ENCRYPT_ALG
An ASN.1 DER object identifier of the symmetric key algorithm used by the key for bulk data encryption. See the TPKEYGETINFO(3cbl) reference page for details.
|
•
|
ENCRYPT_BITS
The key length of the symmetric key algorithm. The value must be within the range of 40 to 128 bits, inclusive.
|
•
|
DIGEST_ALG
An ASN.1 DER object identifier of the message digest algorithm used by the key for digital signature. See the TPKEYGETINFO(3cbl) reference page for details.
|
•
|
PROVIDER
The name of the cryptographic service provider.
|
•
|
VERSION
The version number of the cryptographic service provider’s software.
|
|
|
|
|
|
•
|
Use tpkey_close() to release key handles used for digital signature generation or for data decryption as soon as they are no longer needed.
|
Figure 3‑3 provides the procedure for writing code to send signed messages.
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.
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:
Listing 3‑3 shows how to open a signer’s key handle.
TPKEY is a special data type defined in the
atmi.h header file.
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.
Listing 3‑4 shows how to get information about a signer’s key handle.
{
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);
}
.
.
.
}
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.
Call the tpkey_close(3c) function or
TPKEYCLOSE(3cbl) routine to release the signer’s key handle and all resources associated with it.
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
.
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.
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 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.)
Figure 3‑5 provides the procedure for writing code to send encrypted messages.
Call the tpkey_open(3c) function or
TPKEYOPEN(3cbl) routine to make the digital certificate of the target recipient available to the originating process. The target recipient might be a client, a service, a server group, a gateway group, a server machine, or an entire domain of servers.
When the originating process calls tpkey_open() to open the key handle, it specifies either the
TPKEY_ENCRYPT or
TPKEY_AUTOENCRYPT flag to indicate that the handle will be used to encrypt 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_AUTOENCRYPT flag enables automatic encryption: subsequently, the originating process encrypts message buffers automatically whenever they are sent. Using the
TPKEY_AUTOENCRYPT flag is beneficial for three reasons:
Listing 3‑7 shows how to open an encryption key handle.
TPKEY is a special data type defined in the
atmi.h header file.
Encryption strength is controlled by the ENCRYPT_BITS key attribute, and the algorithm is controlled by the
ENCRYPT_ALG key attribute. When an algorithm with fixed key length is set in
ENCRYPT_ALG, the value of
ENCRYPT_BITS is automatically adjusted to match.
Listing 3‑8 shows how to get information about an encryption key handle.
Listing 3‑9 shows how to change information associated with an encryption key handle.
{
TPKEY tu_key;
static const unsigned char rc2_objid[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02
};
.
.
.
if (tpkey_setinfo(tu_key, “ENCRYPT_ALG”, (void *) rc2_objid,
sizeof(rc2_objid), 0) == -1) {
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)\n”,
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
Listing 3‑10 shows how to mark a message buffer for encryption.
Call the tpkey_close(3c) function or
TPKEYCLOSE(3cbl) routine to release the encryption key handle and all resources associated with it.
The notation {something}
key means that
something has been encrypted or decrypted using
key. In Step 1, a message buffer is encrypted using the session key, and in step 2, the session key is encrypted using the recipient’s public key.
Figure 3‑6 shows the envelope hierarchy for the
EnvelopedData content type. The
SignedData content type is part of the hierarchy
only if the message to which it belongs has one or more associated digital signatures.
1.
|
Call tpkey_open() to open a key handle for the target recipient. tpkey_open returns a key handle to the recipient’s private key and digital certificate.
|
2.
|
(Optional): Call tpkey_getinfo() to get information about the decryption key handle.
|
3.
|
(Optional): Call tpkey_setinfo() to change information associated with the decryption key handle.
|
4.
|
Call tpkey_close() to close the decryption key handle. tpkey_close() releases the key handle and all resources associated with it.
|
Call the tpkey_open(3c) function or
TPKEYOPEN(3cbl) routine to make the private key and the associated digital certificate of the target recipient available to the receiving process. The receiving process might be a client, a service, a server group, a gateway group, a server machine, or an entire domain of servers.
An application administrator can configure the ATMI application’s UBBCONFIG file such that decryption key handles are opened automatically when the ATMI application is booted. No more than one decryption key handle per server may be used with this method. See
“Initializing Decryption Keys Through the Plug-ins” on page 2‑56 for details.
When the receiving process calls tpkey_open() to open the key handle, it specifies the
TPKEY_DECRYPT flag to indicate that the handle will be used to decrypt a message buffer. Typically, a client makes this call after calling
tpinit(), and a server makes this call as part of initializing through
tpsvrinit().
Listing 3‑11 shows how to open a decryption key handle.
TPKEY is a special data type defined in the
atmi.h header file.
Listing 3‑12 shows how to get information about a decryption key handle.
Listing 3‑13 shows how to change information associated with a decryption key handle.
Call the tpkey_close(3c) function or
TPKEYCLOSE(3cbl) routine to release the decryption key handle and all resources associated with it.
If a system process is acting as a conduit (that is, if it is not reading the content of the message), then the message need not be decrypted. Bridges and workstation handlers (WSHs) are examples of system processes acting as conduits.
If a message buffer is passed to an ATMI function (such as tpacall()) as an input parameter, the public key software discards any encryption envelopes previously attached to the message. This behavior prevents the target recipients for the original message from receiving any modifications made by an intermediate process.
A server process named Manager receives a signed and encrypted message buffer from a client process named
Employee, decrypts and reads the received message buffer, signs and seals it for a service named
Purchasing, and then forwards the message to
Purchasing.
If the WSH process is not configured for data-dependent routing, the
Employee process does not need to
tpseal() the message buffer for the WSH process, and the WSH process does not need to open a decryption key.
3.
|
The Manager calls tpenvelope() repeatedly to find out about the digital signature and encryption information associated with the message buffer. tpenvelope() returns:
|
4.
|
The Manager calls tpkey_getinfo() with the signer’s public key as an argument, to obtain more information about the signer, including the signer’s principal name.
|
5.
|
If the Manager determines that the signer is a known employee and that the employee’s request (as stated in the message content) is valid, the Manager proceeds as follows.
|
a.
|
Calls tpsign() to mark the message buffer for digital signature by the Manager.
|
a.
|
Calls tpseal() to mark the message buffer to be encrypted for Purchasing.
|
b.
|
Calls tpforward() (or some other function used to transmit data) to send the message to Purchasing.
|
If a message buffer is passed to an ATMI function (such as tpgetrply()) as an output parameter, the public key software deletes any encryption information associated with the buffer. This information includes any
pending seals, or seals from previous uses of the buffer. (A pending seal is a recipient’s seal that is registered with a message buffer.)
•
|
Any digital signature request explicitly registered with the message buffer as being in the TPSIGN_PENDING state. The originating process explicitly registers a digital signature request by calling the tpsign(3c) function.
|
•
|
Any digital signature request implicitly registered with the message buffer as also being in the TPSIGN_PENDING state. The originating process implicitly registers a digital signature request by calling tpkey_open(3c) with the TPKEY_AUTOSIGN flag specified.
|
•
|
Any encryption (seal) request explicitly registered with the message buffer as being in the TPSEAL_PENDING state. The originating process explicitly registers an encryption request by calling the tpseal(3c) function.
|
•
|
Any encryption (seal) request implicitly registered with the message buffer as also being in the TPSEAL_PENDING state. The originating process implicitly registers an encryption request by calling tpkey_open() with the TPKEY_AUTOENCRYPT flag specified.
|
In addition to the status, tpenvelope() returns the key handle associated with a digital signature or encryption registration request. A process can call the
tpkey_getinfo(3c) function with the key handle as an argument, to get more information about the key handle.
When a process receives a message buffer, it receives only the message content. Any digital signatures or encryption envelopes associated with the message buffer are not included. The receiving process must call
tpenvelope() to obtain information about any attached digital signatures or encryption envelopes.
In addition to the status, tpenvelope() returns the key handle associated with a digital signature or encryption envelope. A process can call the
tpkey_getinfo(3c) function with the key handle as an argument, to get more information about the key handle.
If a receiving process calls tpsign() to register a digital signature request after receiving the message buffer,
tpenvelope() reports the status of the registration as
TPSIGN_PENDING. Similarly, if a receiving process calls
tpseal() to register an encryption (seal) request after receiving the message buffer,
tpenvelope() reports the status of the registration as
TPSEAL_PENDING.
If a receiving process modifies the content of a signed message buffer after receiving it, the attached signatures are no longer valid. As a result,
tpenvelope() cannot verify the signatures, and reports a signature status of
TPSIGN_TAMPERED_MESSAGE.
Any incoming message buffer without a composite signature status of
TPSIGN_OK or
TPSIGN_UNKNOWN is discarded as if it were never received. If the
SIGNATURE_REQUIRED parameter is set to
Y (yes) in the ATMI application’s
UBBCONFIG file, then any incoming message buffer
without a composite signature status of
TPSIGN_OK is discarded as if it were never received. See
“Enforcing the Signature Policy for Incoming Messages” on page 2‑50 for more detail.
Listing 3‑14 shows how to use
tpenvelope() to examine the digital signature and encryption information associated with a message buffer.
{
TPKEY tu_key;
TPKEY sdo_key;
TPKEY output_key;
char *sendbuf, *rcvbuf;
int ret;
int occurrence = 0;
long status;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
int found = 0;
.
.
.
output_key = NULL;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
while (ret != -1) {
if (status == TPSIGN_OK) {
if (tpkey_getinfo(output_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)\n”,
tperrno, tpstrerror(tperrno));
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
(void) tpkey_close(tu_key, 0);
(void) tpkey_close(sdo_key, 0);
(void) tpkey_close(output_key, 0);
exit(1);
}
/* Do not forget to free resources */
(void) tpkey_close(output_key, 0);
output_key = NULL;
found = 1;
break;
}
/* Do not forget to free resources */
(void) tpkey_close(output_key, 0);
output_key = NULL;
occurrence++;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
}
.
.
.
}
An externalized representation is a message buffer that does not include any ATMI header information that is normally added to a message buffer just before the buffer is transmitted. An externalized representation of a signed message buffer enables “pass through” transmission of signed data and long-term storage of the signed buffer for non-repudiation. It also enables an encrypted message buffer to be transported through intermediate processes without access to a decryption key.
A receiving process calls the tpimport(3c) function to convert the externalized representation of a message buffer into a typed message buffer. The
tpimport() function also performs decryption, if necessary, and verifies any associated digital signatures.
Listing 3‑15 shows how to use
tpexport() to convert a typed message buffer into an externalized representation, and how to use
tpimport() to convert the externalized representation back into a typed message buffer.
static void hexdump _((unsigned char *, long));
#define MAX_BUFFER 80000
main(argc, argv)
int argc;
char *argv[];
#endif
{
char *databuf;
char exportbuf[MAX_BUFFER];
long exportbuf_size = 0;
char *importbuf = NULL;
long importbuf_size = 0;
int go_on = 1;
.
.
.
exportbuf_size = 0;
while (go_on == 1) {
if (tpexport(databuf, 0, exportbuf, &exportbuf_size, 0)
== -1) {
if (tperrno == TPELIMIT) {
printf(“%d tperrno is TPELIMIT, exportbuf_size=%ld\n”,
__LINE__, exportbuf_size);
if (exportbuf_size > MAX_BUFFER) {
return(1);
}
}
else {
printf(“tpexport(%d) failed: tperrno=%d(%s)\n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
}
else {
go_on = 0;
}
}
.
.
.
hexdump((unsigned char *) exportbuf, (long) exportbuf_size);
if (tpimport(exportbuf, exportbuf_size, &importbuf,
&importbuf_size, 0) == -1) {
printf(“tpimport(%d) failed: tperrno=%d(%s)\n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}